Commit b1c2a349 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Don't introduce additional computation when hoisting out of loops.

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

Cr-Commit-Position: refs/heads/master@{#26841}
parent 1d56742a
...@@ -589,7 +589,8 @@ class SpecialRPONumberer : public ZoneObject { ...@@ -589,7 +589,8 @@ class SpecialRPONumberer : public ZoneObject {
loops_(zone), loops_(zone),
backedges_(zone), backedges_(zone),
stack_(zone), stack_(zone),
previous_block_count_(0) {} previous_block_count_(0),
empty_(0, zone) {}
// Computes the special reverse-post-order for the main control flow graph, // Computes the special reverse-post-order for the main control flow graph,
// that is for the graph spanned between the schedule's start and end blocks. // that is for the graph spanned between the schedule's start and end blocks.
...@@ -626,6 +627,14 @@ class SpecialRPONumberer : public ZoneObject { ...@@ -626,6 +627,14 @@ class SpecialRPONumberer : public ZoneObject {
#endif #endif
} }
const ZoneList<BasicBlock*>& GetOutgoingBlocks(BasicBlock* block) {
if (HasLoopNumber(block)) {
LoopInfo const& loop = loops_[GetLoopNumber(block)];
if (loop.outgoing) return *loop.outgoing;
}
return empty_;
}
private: private:
typedef std::pair<BasicBlock*, size_t> Backedge; typedef std::pair<BasicBlock*, size_t> Backedge;
...@@ -1045,6 +1054,7 @@ class SpecialRPONumberer : public ZoneObject { ...@@ -1045,6 +1054,7 @@ class SpecialRPONumberer : public ZoneObject {
ZoneVector<Backedge> backedges_; ZoneVector<Backedge> backedges_;
ZoneVector<SpecialRPOStackFrame> stack_; ZoneVector<SpecialRPOStackFrame> stack_;
size_t previous_block_count_; size_t previous_block_count_;
ZoneList<BasicBlock*> const empty_;
}; };
...@@ -1345,7 +1355,7 @@ class ScheduleLateNodeVisitor { ...@@ -1345,7 +1355,7 @@ class ScheduleLateNodeVisitor {
// Hoist nodes out of loops if possible. Nodes can be hoisted iteratively // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
// into enclosing loop pre-headers until they would preceed their schedule // into enclosing loop pre-headers until they would preceed their schedule
// early position. // early position.
BasicBlock* hoist_block = GetPreHeader(block); BasicBlock* hoist_block = GetHoistBlock(block);
if (hoist_block && if (hoist_block &&
hoist_block->dominator_depth() >= min_block->dominator_depth()) { hoist_block->dominator_depth() >= min_block->dominator_depth()) {
do { do {
...@@ -1353,7 +1363,7 @@ class ScheduleLateNodeVisitor { ...@@ -1353,7 +1363,7 @@ class ScheduleLateNodeVisitor {
node->op()->mnemonic(), hoist_block->id().ToInt()); node->op()->mnemonic(), hoist_block->id().ToInt());
DCHECK_LT(hoist_block->loop_depth(), block->loop_depth()); DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
block = hoist_block; block = hoist_block;
hoist_block = GetPreHeader(hoist_block); hoist_block = GetHoistBlock(hoist_block);
} while (hoist_block && } while (hoist_block &&
hoist_block->dominator_depth() >= min_block->dominator_depth()); hoist_block->dominator_depth() >= min_block->dominator_depth());
} else if (scheduler_->flags_ & Scheduler::kSplitNodes) { } else if (scheduler_->flags_ & Scheduler::kSplitNodes) {
...@@ -1464,14 +1474,23 @@ class ScheduleLateNodeVisitor { ...@@ -1464,14 +1474,23 @@ class ScheduleLateNodeVisitor {
return block; return block;
} }
BasicBlock* GetPreHeader(BasicBlock* block) { BasicBlock* GetHoistBlock(BasicBlock* block) {
if (block->IsLoopHeader()) { if (block->IsLoopHeader()) return block->dominator();
return block->dominator(); // We have to check to make sure that the {block} dominates all
} else if (block->loop_header() != NULL) { // of the outgoing blocks. If it doesn't, then there is a path
return block->loop_header()->dominator(); // out of the loop which does not execute this {block}, so we
} else { // can't hoist operations from this {block} out of the loop, as
return NULL; // that would introduce additional computations.
if (BasicBlock* header_block = block->loop_header()) {
for (BasicBlock* outgoing_block :
scheduler_->special_rpo_->GetOutgoingBlocks(header_block)) {
if (BasicBlock::GetCommonDominator(block, outgoing_block) != block) {
return nullptr;
}
}
return header_block->dominator();
} }
return nullptr;
} }
BasicBlock* GetCommonDominatorOfUses(Node* node) { BasicBlock* GetCommonDominatorOfUses(Node* node) {
......
...@@ -1579,10 +1579,7 @@ TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) { ...@@ -1579,10 +1579,7 @@ TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) {
graph()->SetStart(n0); graph()->SetStart(n0);
graph()->SetEnd(n22); graph()->SetEnd(n22);
Schedule* schedule = ComputeAndVerifySchedule(19); ComputeAndVerifySchedule(19);
// Make sure the integer-only add gets hoisted to a different block that the
// JSAdd.
EXPECT_NE(schedule->block(n19), schedule->block(n20));
} }
......
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