Reviewers: jarin,

Message:
PTAL

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

Please review this at https://codereview.chromium.org/958533002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+30, -14 lines):
  M src/compiler/scheduler.cc
  M test/unittests/compiler/scheduler-unittest.cc


Index: src/compiler/scheduler.cc
diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
index 674b89ef66762d0b5ffa5c5b052e094d3ac0d290..3e7d353cb7bf8e675b177b10f79079a71d09d536 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -587,7 +587,8 @@ class SpecialRPONumberer : public ZoneObject {
         loops_(zone),
         backedges_(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, // that is for the graph spanned between the schedule's start and end blocks.
@@ -624,6 +625,14 @@ class SpecialRPONumberer : public ZoneObject {
 #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:
   typedef std::pair<BasicBlock*, size_t> Backedge;

@@ -1046,6 +1055,7 @@ class SpecialRPONumberer : public ZoneObject {
   ZoneVector<Backedge> backedges_;
   ZoneVector<SpecialRPOStackFrame> stack_;
   size_t previous_block_count_;
+  ZoneList<BasicBlock*> const empty_;
 };


@@ -1346,7 +1356,7 @@ class ScheduleLateNodeVisitor {
// Hoist nodes out of loops if possible. Nodes can be hoisted iteratively // into enclosing loop pre-headers until they would preceed their schedule
     // early position.
-    BasicBlock* hoist_block = GetPreHeader(block);
+    BasicBlock* hoist_block = GetHoistBlock(block);
     if (hoist_block &&
         hoist_block->dominator_depth() >= min_block->dominator_depth()) {
       do {
@@ -1354,7 +1364,7 @@ class ScheduleLateNodeVisitor {
               node->op()->mnemonic(), hoist_block->id().ToInt());
         DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
         block = hoist_block;
-        hoist_block = GetPreHeader(hoist_block);
+        hoist_block = GetHoistBlock(hoist_block);
       } while (hoist_block &&
hoist_block->dominator_depth() >= min_block->dominator_depth());
     } else if (scheduler_->flags_ & Scheduler::kSplitNodes) {
@@ -1465,14 +1475,23 @@ class ScheduleLateNodeVisitor {
     return block;
   }

-  BasicBlock* GetPreHeader(BasicBlock* block) {
-    if (block->IsLoopHeader()) {
-      return block->dominator();
-    } else if (block->loop_header() != NULL) {
-      return block->loop_header()->dominator();
-    } else {
-      return NULL;
+  BasicBlock* GetHoistBlock(BasicBlock* block) {
+    if (block->IsLoopHeader()) return block->dominator();
+    // We have to check to make sure that the {block} dominates all
+    // of the outgoing blocks.  If it doesn't, then there is a path
+    // out of the loop which does not execute this {block}, so we
+    // can't hoist operations from this {block} out of the loop, as
+    // 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) {
Index: test/unittests/compiler/scheduler-unittest.cc
diff --git a/test/unittests/compiler/scheduler-unittest.cc b/test/unittests/compiler/scheduler-unittest.cc index afca98ca9b1fb109d0502886eeefea5dad168838..9ff6a63998b8eaa423cfe75c4879376b21baf757 100644
--- a/test/unittests/compiler/scheduler-unittest.cc
+++ b/test/unittests/compiler/scheduler-unittest.cc
@@ -1579,10 +1579,7 @@ TEST_F(SchedulerTest, BuildScheduleSimpleLoopWithCodeMotion) {
   graph()->SetStart(n0);
   graph()->SetEnd(n22);

-  Schedule* schedule = 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));
+  ComputeAndVerifySchedule(19);
 }




--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to