Commit a0627084 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Change handling of empty basic blocks

This CL inserts NOP instructions a little bit earlier into empty
blocks; this ensures that instructions keep their initial position.

Bug: v8:7327
Change-Id: Idee5269f4fd7fc15c44bda83a2be74e8cff62df8
Reviewed-on: https://chromium-review.googlesource.com/1097078
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53672}
parent fb450de7
...@@ -1104,7 +1104,11 @@ void InstructionSelector::VisitBlock(BasicBlock* block) { ...@@ -1104,7 +1104,11 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
// We're done with the block. // We're done with the block.
InstructionBlock* instruction_block = InstructionBlock* instruction_block =
sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
instruction_block->set_code_start(static_cast<int>(instructions_.size())); if (current_num_instructions() == current_block_end) {
// Avoid empty block: insert a {kArchNop} instruction.
Emit(Instruction::New(sequence()->zone(), kArchNop));
}
instruction_block->set_code_start(current_num_instructions());
instruction_block->set_code_end(current_block_end); instruction_block->set_code_end(current_block_end);
current_block_ = nullptr; current_block_ = nullptr;
......
...@@ -869,12 +869,8 @@ void InstructionSequence::StartBlock(RpoNumber rpo) { ...@@ -869,12 +869,8 @@ void InstructionSequence::StartBlock(RpoNumber rpo) {
void InstructionSequence::EndBlock(RpoNumber rpo) { void InstructionSequence::EndBlock(RpoNumber rpo) {
int end = static_cast<int>(instructions_.size()); int end = static_cast<int>(instructions_.size());
DCHECK_EQ(current_block_->rpo_number(), rpo); DCHECK_EQ(current_block_->rpo_number(), rpo);
if (current_block_->code_start() == end) { // Empty block. Insert a nop. CHECK(current_block_->code_start() >= 0 &&
AddInstruction(Instruction::New(zone(), kArchNop)); current_block_->code_start() < end);
end = static_cast<int>(instructions_.size());
}
DCHECK(current_block_->code_start() >= 0 &&
current_block_->code_start() < end);
current_block_->set_code_end(end); current_block_->set_code_end(end);
current_block_ = nullptr; current_block_ = nullptr;
} }
......
...@@ -82,6 +82,11 @@ class InstructionTester : public HandleAndZoneScope { ...@@ -82,6 +82,11 @@ class InstructionTester : public HandleAndZoneScope {
return code->AddInstruction(instr); return code->AddInstruction(instr);
} }
int NewNop() {
TestInstr* instr = TestInstr::New(zone(), kArchNop);
return code->AddInstruction(instr);
}
UnallocatedOperand Unallocated(int vreg) { UnallocatedOperand Unallocated(int vreg) {
return UnallocatedOperand(UnallocatedOperand::REGISTER_OR_SLOT, vreg); return UnallocatedOperand(UnallocatedOperand::REGISTER_OR_SLOT, vreg);
} }
...@@ -163,6 +168,7 @@ TEST(InstructionGetBasicBlock) { ...@@ -163,6 +168,7 @@ TEST(InstructionGetBasicBlock) {
int i8 = R.NewInstr(); int i8 = R.NewInstr();
R.code->EndBlock(R.RpoFor(b2)); R.code->EndBlock(R.RpoFor(b2));
R.code->StartBlock(R.RpoFor(b3)); R.code->StartBlock(R.RpoFor(b3));
R.NewNop();
R.code->EndBlock(R.RpoFor(b3)); R.code->EndBlock(R.RpoFor(b3));
CHECK_EQ(b0, R.GetBasicBlock(i0)); CHECK_EQ(b0, R.GetBasicBlock(i0));
......
...@@ -77,6 +77,10 @@ class TestCode : public HandleAndZoneScope { ...@@ -77,6 +77,10 @@ class TestCode : public HandleAndZoneScope {
} }
void End() { void End() {
Start(); Start();
int end = static_cast<int>(sequence_.instructions().size());
if (current_->code_start() == end) { // Empty block. Insert a nop.
sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
}
sequence_.EndBlock(current_->rpo_number()); sequence_.EndBlock(current_->rpo_number());
current_ = nullptr; current_ = nullptr;
rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1); rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
......
...@@ -159,6 +159,10 @@ Instruction* InstructionSequenceTest::EndBlock(BlockCompletion completion) { ...@@ -159,6 +159,10 @@ Instruction* InstructionSequenceTest::EndBlock(BlockCompletion completion) {
} }
completions_.push_back(completion); completions_.push_back(completion);
CHECK_NOT_NULL(current_block_); CHECK_NOT_NULL(current_block_);
int end = static_cast<int>(sequence()->instructions().size());
if (current_block_->code_start() == end) { // Empty block. Insert a nop.
sequence()->AddInstruction(Instruction::New(zone(), kArchNop));
}
sequence()->EndBlock(current_block_->rpo_number()); sequence()->EndBlock(current_block_->rpo_number());
current_block_ = nullptr; current_block_ = nullptr;
return result; return result;
...@@ -507,6 +511,7 @@ void InstructionSequenceTest::WireBlocks() { ...@@ -507,6 +511,7 @@ void InstructionSequenceTest::WireBlocks() {
CHECK(loop_blocks_.empty()); CHECK(loop_blocks_.empty());
// Wire in end block to look like a scheduler produced cfg. // Wire in end block to look like a scheduler produced cfg.
auto end_block = NewBlock(); auto end_block = NewBlock();
Emit(kArchNop);
current_block_ = nullptr; current_block_ = nullptr;
sequence()->EndBlock(end_block->rpo_number()); sequence()->EndBlock(end_block->rpo_number());
size_t offset = 0; size_t offset = 0;
......
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