Commit 1f44e726 authored by machenbach's avatar machenbach Committed by Commit bot

Revert of [turbofan] simplify gap ordering (patchset #2 id:20001 of...

Revert of [turbofan] simplify gap ordering (patchset #2 id:20001 of https://codereview.chromium.org/810013002/)

Reason for revert:
Revert for breaking emscripten bullet with turbofan on android arm64.

Original issue's description:
> [turbofan] simplify gap ordering
>
> BUG=
>
> Committed: https://crrev.com/70b5eb47b39acbf31746f4a116a9b3ce2730218a
> Cr-Commit-Position: refs/heads/master@{#25865}

TBR=bmeurer@chromium.org,dcarney@chromium.org
NOTREECHECKS=true
NOTRY=true
BUG=

Review URL: https://codereview.chromium.org/815743002

Cr-Commit-Position: refs/heads/master@{#25888}
parent 2bc756e4
...@@ -287,7 +287,7 @@ std::ostream& operator<<(std::ostream& os, ...@@ -287,7 +287,7 @@ std::ostream& operator<<(std::ostream& os,
if (instr.IsGapMoves()) { if (instr.IsGapMoves()) {
const GapInstruction* gap = GapInstruction::cast(&instr); const GapInstruction* gap = GapInstruction::cast(&instr);
os << "gap "; os << (instr.IsBlockStart() ? " block-start" : "gap ");
for (int i = GapInstruction::FIRST_INNER_POSITION; for (int i = GapInstruction::FIRST_INNER_POSITION;
i <= GapInstruction::LAST_INNER_POSITION; i++) { i <= GapInstruction::LAST_INNER_POSITION; i++) {
os << "("; os << "(";
...@@ -458,10 +458,10 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone, ...@@ -458,10 +458,10 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone,
} }
GapInstruction* InstructionSequence::GetBlockStart( BlockStartInstruction* InstructionSequence::GetBlockStart(
BasicBlock::RpoNumber rpo) const { BasicBlock::RpoNumber rpo) const {
const InstructionBlock* block = InstructionBlockAt(rpo); const InstructionBlock* block = InstructionBlockAt(rpo);
return GapInstruction::cast(InstructionAt(block->code_start())); return BlockStartInstruction::cast(InstructionAt(block->code_start()));
} }
...@@ -471,26 +471,26 @@ void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) { ...@@ -471,26 +471,26 @@ void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) {
int code_start = static_cast<int>(instructions_.size()); int code_start = static_cast<int>(instructions_.size());
block->set_code_start(code_start); block->set_code_start(code_start);
block_starts_.push_back(code_start); block_starts_.push_back(code_start);
BlockStartInstruction* block_start = BlockStartInstruction::New(zone());
AddInstruction(block_start);
} }
void InstructionSequence::EndBlock(BasicBlock::RpoNumber rpo) { void InstructionSequence::EndBlock(BasicBlock::RpoNumber rpo) {
int end = static_cast<int>(instructions_.size()); int end = static_cast<int>(instructions_.size());
InstructionBlock* block = InstructionBlockAt(rpo); InstructionBlock* block = InstructionBlockAt(rpo);
if (block->code_start() == end) { // Empty block. Insert a nop.
AddInstruction(Instruction::New(zone(), kArchNop));
end = static_cast<int>(instructions_.size());
}
DCHECK(block->code_start() >= 0 && block->code_start() < end); DCHECK(block->code_start() >= 0 && block->code_start() < end);
block->set_code_end(end); block->set_code_end(end);
} }
int InstructionSequence::AddInstruction(Instruction* instr) { int InstructionSequence::AddInstruction(Instruction* instr) {
// TODO(titzer): the order of these gaps is a holdover from Lithium.
GapInstruction* gap = GapInstruction::New(zone()); GapInstruction* gap = GapInstruction::New(zone());
instructions_.push_back(gap); if (instr->IsControl()) instructions_.push_back(gap);
int index = static_cast<int>(instructions_.size()); int index = static_cast<int>(instructions_.size());
instructions_.push_back(instr); instructions_.push_back(instr);
if (!instr->IsControl()) instructions_.push_back(gap);
if (instr->NeedsPointerMap()) { if (instr->NeedsPointerMap()) {
DCHECK(instr->pointer_map() == NULL); DCHECK(instr->pointer_map() == NULL);
PointerMap* pointer_map = new (zone()) PointerMap(zone()); PointerMap* pointer_map = new (zone()) PointerMap(zone());
......
...@@ -25,7 +25,8 @@ namespace compiler { ...@@ -25,7 +25,8 @@ namespace compiler {
// A couple of reserved opcodes are used for internal use. // A couple of reserved opcodes are used for internal use.
const InstructionCode kGapInstruction = -1; const InstructionCode kGapInstruction = -1;
const InstructionCode kSourcePositionInstruction = -2; const InstructionCode kBlockStartInstruction = -2;
const InstructionCode kSourcePositionInstruction = -3;
#define INSTRUCTION_OPERAND_LIST(V) \ #define INSTRUCTION_OPERAND_LIST(V) \
V(Constant, CONSTANT, 0) \ V(Constant, CONSTANT, 0) \
...@@ -491,7 +492,10 @@ class Instruction : public ZoneObject { ...@@ -491,7 +492,10 @@ class Instruction : public ZoneObject {
bool NeedsPointerMap() const { return IsCall(); } bool NeedsPointerMap() const { return IsCall(); }
bool HasPointerMap() const { return pointer_map_ != NULL; } bool HasPointerMap() const { return pointer_map_ != NULL; }
bool IsGapMoves() const { return opcode() == kGapInstruction; } bool IsGapMoves() const {
return opcode() == kGapInstruction || opcode() == kBlockStartInstruction;
}
bool IsBlockStart() const { return opcode() == kBlockStartInstruction; }
bool IsSourcePosition() const { bool IsSourcePosition() const {
return opcode() == kSourcePositionInstruction; return opcode() == kSourcePositionInstruction;
} }
...@@ -637,6 +641,30 @@ class GapInstruction : public Instruction { ...@@ -637,6 +641,30 @@ class GapInstruction : public Instruction {
}; };
// This special kind of gap move instruction represents the beginning of a
// block of code.
class BlockStartInstruction FINAL : public GapInstruction {
public:
static BlockStartInstruction* New(Zone* zone) {
void* buffer = zone->New(sizeof(BlockStartInstruction));
return new (buffer) BlockStartInstruction();
}
static BlockStartInstruction* cast(Instruction* instr) {
DCHECK(instr->IsBlockStart());
return static_cast<BlockStartInstruction*>(instr);
}
static const BlockStartInstruction* cast(const Instruction* instr) {
DCHECK(instr->IsBlockStart());
return static_cast<const BlockStartInstruction*>(instr);
}
private:
BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {}
};
class SourcePositionInstruction FINAL : public Instruction { class SourcePositionInstruction FINAL : public Instruction {
public: public:
static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { static SourcePositionInstruction* New(Zone* zone, SourcePosition position) {
...@@ -953,7 +981,7 @@ class InstructionSequence FINAL : public ZoneObject { ...@@ -953,7 +981,7 @@ class InstructionSequence FINAL : public ZoneObject {
void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
GapInstruction* GetBlockStart(BasicBlock::RpoNumber rpo) const; BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo) const;
typedef InstructionDeque::const_iterator const_iterator; typedef InstructionDeque::const_iterator const_iterator;
const_iterator begin() const { return instructions_.begin(); } const_iterator begin() const { return instructions_.begin(); }
......
...@@ -1078,7 +1078,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( ...@@ -1078,7 +1078,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
for (auto succ : block->successors()) { for (auto succ : block->successors()) {
const InstructionBlock* successor = code()->InstructionBlockAt(succ); const InstructionBlock* successor = code()->InstructionBlockAt(succ);
DCHECK(successor->PredecessorCount() == 1); DCHECK(successor->PredecessorCount() == 1);
int gap_index = successor->first_instruction_index(); int gap_index = successor->first_instruction_index() + 1;
DCHECK(code()->IsGapAt(gap_index)); DCHECK(code()->IsGapAt(gap_index));
// Create an unconstrained operand for the same virtual register // Create an unconstrained operand for the same virtual register
...@@ -1095,7 +1095,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( ...@@ -1095,7 +1095,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
for (auto succ : block->successors()) { for (auto succ : block->successors()) {
const InstructionBlock* successor = code()->InstructionBlockAt(succ); const InstructionBlock* successor = code()->InstructionBlockAt(succ);
DCHECK(successor->PredecessorCount() == 1); DCHECK(successor->PredecessorCount() == 1);
int gap_index = successor->first_instruction_index(); int gap_index = successor->first_instruction_index() + 1;
range->SpillAtDefinition(local_zone(), gap_index, output); range->SpillAtDefinition(local_zone(), gap_index, output);
range->SetSpillStartIndex(gap_index); range->SetSpillStartIndex(gap_index);
} }
...@@ -2376,8 +2376,7 @@ void RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) { ...@@ -2376,8 +2376,7 @@ void RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) {
bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) {
return pos.IsInstructionStart() && return pos.IsInstructionStart() &&
code()->GetInstructionBlock(pos.InstructionIndex())->code_start() == InstructionAt(pos.InstructionIndex())->IsBlockStart();
pos.InstructionIndex();
} }
...@@ -2475,13 +2474,9 @@ void RegisterAllocator::SpillBetweenUntil(LiveRange* range, ...@@ -2475,13 +2474,9 @@ void RegisterAllocator::SpillBetweenUntil(LiveRange* range,
// The split result intersects with [start, end[. // The split result intersects with [start, end[.
// Split it at position between ]start+1, end[, spill the middle part // Split it at position between ]start+1, end[, spill the middle part
// and put the rest to unhandled. // and put the rest to unhandled.
auto third_part_end = end.PrevInstruction().InstructionEnd();
if (IsBlockBoundary(end.InstructionStart())) {
third_part_end = end.InstructionStart();
}
auto third_part = SplitBetween( auto third_part = SplitBetween(
second_part, Max(second_part->Start().InstructionEnd(), until), second_part, Max(second_part->Start().InstructionEnd(), until),
third_part_end); end.PrevInstruction().InstructionEnd());
if (!AllocationOk()) return; if (!AllocationOk()) return;
DCHECK(third_part != second_part); DCHECK(third_part != second_part);
......
...@@ -214,10 +214,14 @@ TEST(InstructionIsGapAt) { ...@@ -214,10 +214,14 @@ TEST(InstructionIsGapAt) {
R.code->AddInstruction(g); R.code->AddInstruction(g);
R.code->EndBlock(b0->GetRpoNumber()); R.code->EndBlock(b0->GetRpoNumber());
CHECK(R.code->instructions().size() == 4); CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
for (size_t i = 0; i < R.code->instructions().size(); ++i) {
CHECK_EQ(i % 2 == 0, R.code->instructions()[i]->IsGapMoves()); CHECK_EQ(true, R.code->IsGapAt(0)); // Label
} CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
CHECK_EQ(false, R.code->IsGapAt(2)); // i0
CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
CHECK_EQ(false, R.code->IsGapAt(5)); // g
} }
...@@ -244,10 +248,23 @@ TEST(InstructionIsGapAt2) { ...@@ -244,10 +248,23 @@ TEST(InstructionIsGapAt2) {
R.code->AddInstruction(g1); R.code->AddInstruction(g1);
R.code->EndBlock(b1->GetRpoNumber()); R.code->EndBlock(b1->GetRpoNumber());
CHECK(R.code->instructions().size() == 8); CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
for (size_t i = 0; i < R.code->instructions().size(); ++i) {
CHECK_EQ(i % 2 == 0, R.code->instructions()[i]->IsGapMoves()); CHECK_EQ(true, R.code->IsGapAt(0)); // Label
} CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
CHECK_EQ(false, R.code->IsGapAt(2)); // i0
CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
CHECK_EQ(false, R.code->IsGapAt(5)); // g
CHECK_EQ(true, R.code->InstructionAt(6)->IsBlockStart());
CHECK_EQ(true, R.code->IsGapAt(6)); // Label
CHECK_EQ(true, R.code->IsGapAt(7)); // Gap
CHECK_EQ(false, R.code->IsGapAt(8)); // i1
CHECK_EQ(true, R.code->IsGapAt(9)); // Gap
CHECK_EQ(true, R.code->IsGapAt(10)); // Gap
CHECK_EQ(false, R.code->IsGapAt(11)); // g1
} }
...@@ -265,12 +282,16 @@ TEST(InstructionAddGapMove) { ...@@ -265,12 +282,16 @@ TEST(InstructionAddGapMove) {
R.code->AddInstruction(g); R.code->AddInstruction(g);
R.code->EndBlock(b0->GetRpoNumber()); R.code->EndBlock(b0->GetRpoNumber());
CHECK(R.code->instructions().size() == 4); CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
for (size_t i = 0; i < R.code->instructions().size(); ++i) {
CHECK_EQ(i % 2 == 0, R.code->instructions()[i]->IsGapMoves()); CHECK_EQ(true, R.code->IsGapAt(0)); // Label
} CHECK_EQ(true, R.code->IsGapAt(1)); // Gap
CHECK_EQ(false, R.code->IsGapAt(2)); // i0
CHECK_EQ(true, R.code->IsGapAt(3)); // Gap
CHECK_EQ(true, R.code->IsGapAt(4)); // Gap
CHECK_EQ(false, R.code->IsGapAt(5)); // g
int indexes[] = {0, 2, -1}; int indexes[] = {0, 1, 3, 4, -1};
for (int i = 0; indexes[i] >= 0; i++) { for (int i = 0; indexes[i] >= 0; i++) {
int index = indexes[i]; int index = indexes[i];
......
...@@ -60,14 +60,14 @@ class TestCode : public HandleAndZoneScope { ...@@ -60,14 +60,14 @@ class TestCode : public HandleAndZoneScope {
void RedundantMoves() { void RedundantMoves() {
Start(); Start();
sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop)); sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
int index = static_cast<int>(sequence_.instructions().size()) - 2; int index = static_cast<int>(sequence_.instructions().size()) - 1;
sequence_.AddGapMove(index, RegisterOperand::Create(13, main_zone()), sequence_.AddGapMove(index, RegisterOperand::Create(13, main_zone()),
RegisterOperand::Create(13, main_zone())); RegisterOperand::Create(13, main_zone()));
} }
void NonRedundantMoves() { void NonRedundantMoves() {
Start(); Start();
sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop)); sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
int index = static_cast<int>(sequence_.instructions().size()) - 2; int index = static_cast<int>(sequence_.instructions().size()) - 1;
sequence_.AddGapMove(index, ImmediateOperand::Create(11, main_zone()), sequence_.AddGapMove(index, ImmediateOperand::Create(11, main_zone()),
RegisterOperand::Create(11, main_zone())); RegisterOperand::Create(11, main_zone()));
} }
......
...@@ -167,7 +167,7 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnFloat32Constant) { ...@@ -167,7 +167,7 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnFloat32Constant) {
StreamBuilder m(this, kMachFloat32); StreamBuilder m(this, kMachFloat32);
m.Return(m.Float32Constant(kValue)); m.Return(m.Float32Constant(kValue));
Stream s = m.Build(kAllInstructions); Stream s = m.Build(kAllInstructions);
ASSERT_EQ(3U, s.size()); ASSERT_EQ(2U, s.size());
EXPECT_EQ(kArchNop, s[0]->arch_opcode()); EXPECT_EQ(kArchNop, s[0]->arch_opcode());
ASSERT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); ASSERT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
EXPECT_FLOAT_EQ(kValue, s.ToFloat32(s[0]->OutputAt(0))); EXPECT_FLOAT_EQ(kValue, s.ToFloat32(s[0]->OutputAt(0)));
...@@ -180,7 +180,7 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) { ...@@ -180,7 +180,7 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) {
StreamBuilder m(this, kMachInt32, kMachInt32); StreamBuilder m(this, kMachInt32, kMachInt32);
m.Return(m.Parameter(0)); m.Return(m.Parameter(0));
Stream s = m.Build(kAllInstructions); Stream s = m.Build(kAllInstructions);
ASSERT_EQ(3U, s.size()); ASSERT_EQ(2U, s.size());
EXPECT_EQ(kArchNop, s[0]->arch_opcode()); EXPECT_EQ(kArchNop, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->OutputCount()); ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kArchRet, s[1]->arch_opcode()); EXPECT_EQ(kArchRet, s[1]->arch_opcode());
...@@ -192,7 +192,7 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnZero) { ...@@ -192,7 +192,7 @@ TARGET_TEST_F(InstructionSelectorTest, ReturnZero) {
StreamBuilder m(this, kMachInt32); StreamBuilder m(this, kMachInt32);
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
Stream s = m.Build(kAllInstructions); Stream s = m.Build(kAllInstructions);
ASSERT_EQ(3U, s.size()); ASSERT_EQ(2U, s.size());
EXPECT_EQ(kArchNop, s[0]->arch_opcode()); EXPECT_EQ(kArchNop, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->OutputCount()); ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
...@@ -210,7 +210,7 @@ TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) { ...@@ -210,7 +210,7 @@ TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) {
StreamBuilder m(this, kMachInt32, kMachFloat64); StreamBuilder m(this, kMachInt32, kMachFloat64);
m.Return(m.TruncateFloat64ToInt32(m.Parameter(0))); m.Return(m.TruncateFloat64ToInt32(m.Parameter(0)));
Stream s = m.Build(kAllInstructions); Stream s = m.Build(kAllInstructions);
ASSERT_EQ(4U, s.size()); ASSERT_EQ(3U, s.size());
EXPECT_EQ(kArchNop, s[0]->arch_opcode()); EXPECT_EQ(kArchNop, s[0]->arch_opcode());
EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode()); EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode());
EXPECT_EQ(1U, s[1]->InputCount()); EXPECT_EQ(1U, s[1]->InputCount());
...@@ -251,7 +251,7 @@ TARGET_TEST_F(InstructionSelectorTest, Finish) { ...@@ -251,7 +251,7 @@ TARGET_TEST_F(InstructionSelectorTest, Finish) {
Node* finish = m.NewNode(m.common()->Finish(1), param, m.graph()->start()); Node* finish = m.NewNode(m.common()->Finish(1), param, m.graph()->start());
m.Return(finish); m.Return(finish);
Stream s = m.Build(kAllInstructions); Stream s = m.Build(kAllInstructions);
ASSERT_EQ(4U, s.size()); ASSERT_EQ(3U, s.size());
EXPECT_EQ(kArchNop, s[0]->arch_opcode()); EXPECT_EQ(kArchNop, s[0]->arch_opcode());
ASSERT_EQ(1U, s[0]->OutputCount()); ASSERT_EQ(1U, s[0]->OutputCount());
ASSERT_TRUE(s[0]->Output()->IsUnallocated()); ASSERT_TRUE(s[0]->Output()->IsUnallocated());
......
...@@ -12,7 +12,11 @@ namespace compiler { ...@@ -12,7 +12,11 @@ namespace compiler {
class MoveOptimizerTest : public InstructionSequenceTest { class MoveOptimizerTest : public InstructionSequenceTest {
public: public:
GapInstruction* LastGap() { GapInstruction* LastGap() {
return GapInstruction::cast(*(sequence()->instructions().rbegin() + 1)); auto instruction = sequence()->instructions().back();
if (!instruction->IsGapMoves()) {
instruction = *(sequence()->instructions().rbegin() + 1);
}
return GapInstruction::cast(instruction);
} }
void AddMove(GapInstruction* gap, TestOperand from, TestOperand to, void AddMove(GapInstruction* gap, TestOperand from, TestOperand to,
...@@ -86,10 +90,10 @@ class MoveOptimizerTest : public InstructionSequenceTest { ...@@ -86,10 +90,10 @@ class MoveOptimizerTest : public InstructionSequenceTest {
TEST_F(MoveOptimizerTest, RemovesRedundant) { TEST_F(MoveOptimizerTest, RemovesRedundant) {
StartBlock(); StartBlock();
EmitNop();
AddMove(LastGap(), Reg(0), Reg(1)); AddMove(LastGap(), Reg(0), Reg(1));
EmitNop(); EmitNop();
AddMove(LastGap(), Reg(1), Reg(0)); AddMove(LastGap(), Reg(1), Reg(0));
EmitNop();
EndBlock(Last()); EndBlock(Last());
Optimize(); Optimize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment