summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/compiler/test-gap-resolver.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/compiler/test-gap-resolver.cc')
-rw-r--r--deps/v8/test/cctest/compiler/test-gap-resolver.cc128
1 files changed, 126 insertions, 2 deletions
diff --git a/deps/v8/test/cctest/compiler/test-gap-resolver.cc b/deps/v8/test/cctest/compiler/test-gap-resolver.cc
index 998fa10f38..e79ccec7ec 100644
--- a/deps/v8/test/cctest/compiler/test-gap-resolver.cc
+++ b/deps/v8/test/cctest/compiler/test-gap-resolver.cc
@@ -41,6 +41,12 @@ void GetCanonicalOperands(const InstructionOperand& op,
}
}
+// Fake frame size. The test's stack operand indices should be below this value.
+// Stack slots above this value correspond to temporaries pushed by the gap
+// resolver to resolve move cycles, and are ignored when comparing interpreter
+// states.
+constexpr int kLastFrameSlotId = 1000;
+
// The state of our move interpreter is the mapping of operands to values. Note
// that the actual values don't really matter, all we care about is equality.
class InterpreterState {
@@ -73,6 +79,13 @@ class InterpreterState {
}
}
+ void ExecuteMove(Zone* zone, InstructionOperand* source,
+ InstructionOperand* dest) {
+ ParallelMove* moves = zone->New<ParallelMove>(zone);
+ moves->AddMove(*source, *dest);
+ ExecuteInParallel(moves);
+ }
+
void MoveToTempLocation(InstructionOperand& source) {
scratch_ = KeyFor(source);
}
@@ -103,6 +116,20 @@ class InterpreterState {
return values_ == other.values_;
}
+ // Clear stack operands above kLastFrameSlotId. They correspond to temporaries
+ // pushed by the gap resolver to break cycles.
+ void ClearTemps() {
+ auto it = values_.begin();
+ while (it != values_.end()) {
+ if (it->first.kind == LocationOperand::STACK_SLOT &&
+ it->first.index >= kLastFrameSlotId) {
+ it = values_.erase(it);
+ } else {
+ it++;
+ }
+ }
+ }
+
private:
// struct for mapping operands to a unique value, that makes it easier to
// detect illegal parallel moves, and to evaluate moves for equivalence. This
@@ -217,7 +244,33 @@ class MoveInterpreter : public GapResolver::Assembler {
public:
explicit MoveInterpreter(Zone* zone) : zone_(zone) {}
- void MoveToTempLocation(InstructionOperand* source) final {
+ AllocatedOperand Push(InstructionOperand* source) override {
+ auto rep = LocationOperand::cast(source)->representation();
+ int new_slots = ElementSizeInPointers(rep);
+ AllocatedOperand stack_slot(LocationOperand::STACK_SLOT, rep,
+ kLastFrameSlotId + sp_delta_ + new_slots);
+ ParallelMove* moves = zone_->New<ParallelMove>(zone_);
+ moves->AddMove(*source, stack_slot);
+ state_.ExecuteMove(zone_, source, &stack_slot);
+ sp_delta_ += new_slots;
+ return stack_slot;
+ }
+
+ void Pop(InstructionOperand* dest, MachineRepresentation rep) override {
+ int new_slots = ElementSizeInPointers(rep);
+ int temp_slot = kLastFrameSlotId + sp_delta_ + new_slots;
+ AllocatedOperand stack_slot(LocationOperand::STACK_SLOT, rep, temp_slot);
+ state_.ExecuteMove(zone_, &stack_slot, dest);
+ sp_delta_ -= new_slots;
+ }
+
+ void PopTempStackSlots() override {
+ sp_delta_ = 0;
+ state_.ClearTemps();
+ }
+
+ void MoveToTempLocation(InstructionOperand* source,
+ MachineRepresentation rep) final {
state_.MoveToTempLocation(*source);
}
void MoveTempLocationTo(InstructionOperand* dest,
@@ -247,6 +300,7 @@ class MoveInterpreter : public GapResolver::Assembler {
private:
Zone* const zone_;
InterpreterState state_;
+ int sp_delta_ = 0;
};
class ParallelMoveCreator : public HandleAndZoneScope {
@@ -419,7 +473,8 @@ void RunTest(ParallelMove* pm, Zone* zone) {
GapResolver resolver(&mi2);
resolver.Resolve(pm);
- CHECK_EQ(mi1.state(), mi2.state());
+ auto mi2_state = mi2.state();
+ CHECK_EQ(mi1.state(), mi2_state);
}
TEST(Aliasing) {
@@ -534,6 +589,75 @@ TEST(Aliasing) {
}
}
+// Test parallel moves that change the frame layout. These typically happen when
+// preparing tail-calls.
+TEST(ComplexParallelMoves) {
+ ParallelMoveCreator pmc;
+ Zone* zone = pmc.main_zone();
+
+ auto w64_2 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kWord64, 2);
+ auto w64_5 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kWord64, 5);
+ auto s128_1 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kSimd128, 1);
+ auto s128_4 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kSimd128, 4);
+ auto s128_5 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kSimd128, 5);
+ auto s128_2 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kSimd128, 2);
+ auto w64_3 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kWord64, 3);
+ auto w64_0 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kWord64, 0);
+ auto s128_6 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kSimd128, 6);
+ auto w64_6 = AllocatedOperand(LocationOperand::STACK_SLOT,
+ MachineRepresentation::kWord64, 6);
+ auto s128_reg = AllocatedOperand(LocationOperand::REGISTER,
+ MachineRepresentation::kSimd128, 0);
+
+ {
+ // A parallel move with multiple cycles that requires > 1 temporary
+ // location.
+ std::vector<InstructionOperand> moves = {
+ w64_2, w64_5, // -
+ s128_1, s128_4, // -
+ s128_5, s128_2, // -
+ w64_3, w64_0 // -
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // Regression test for https://crbug.com/1335537.
+ {
+ std::vector<InstructionOperand> moves = {
+ s128_5, s128_6, // -
+ s128_1, s128_6, // -
+ w64_6, w64_0 // -
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // A cycle with 2 moves that should not use a swap, because the
+ // interfering operands don't have the same base address.
+ {
+ std::vector<InstructionOperand> moves = {
+ s128_1, s128_reg, // -
+ s128_reg, s128_2 // -
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+ // Another cycle with 2 moves that should not use a swap, because the
+ // interfering operands don't have the same representation.
+ {
+ std::vector<InstructionOperand> moves = {
+ s128_2, s128_5, // -
+ w64_2, w64_5 // -
+ };
+ RunTest(pmc.Create(moves), zone);
+ }
+}
+
TEST(FuzzResolver) {
ParallelMoveCreator pmc;
for (int size = 0; size < 80; ++size) {