Revision: 8245
Author:   [email protected]
Date:     Thu Jun  9 08:49:21 2011
Log:      Simplify the check when to perform loop invariant code motion.

Allow HChange instructions to be hoisted out of loops. To avoid
unnecessary code motion we don't hoist instructions from blocks that
have been marked containing an unconditional deoptimization.
Review URL: http://codereview.chromium.org/7003087
http://code.google.com/p/v8/source/detail?r=8245

Modified:
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/hydrogen.h

=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Thu Jun  9 03:03:35 2011
+++ /branches/bleeding_edge/src/flag-definitions.h      Thu Jun  9 08:49:21 2011
@@ -137,8 +137,6 @@
 DEFINE_bool(trap_on_deopt, false, "put a break point before deoptimizing")
 DEFINE_bool(deoptimize_uncommon_cases, true, "deoptimize uncommon cases")
 DEFINE_bool(polymorphic_inlining, true, "polymorphic inlining")
-DEFINE_bool(aggressive_loop_invariant_motion, true,
-            "aggressive motion of instructions out of loops")
 DEFINE_bool(use_osr, true, "use on-stack replacement")

 DEFINE_bool(trace_osr, false, "trace on-stack replacement")
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Jun  9 08:19:37 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Thu Jun  9 08:49:21 2011
@@ -68,7 +68,8 @@
       last_instruction_index_(-1),
       deleted_phis_(4),
       parent_loop_header_(NULL),
-      is_inline_return_target_(false) { }
+      is_inline_return_target_(false),
+      is_deoptimizing_(false) { }


 void HBasicBlock::AttachLoopInformation() {
@@ -741,8 +742,20 @@
       }
     }
   }
+
+  // Propagate flag marking blocks containing unconditional deoptimize.
+  MarkAsDeoptimizingRecursively(entry_block());
 }

+
+// Mark all blocks that are dominated by an unconditional deoptimize.
+void HGraph::MarkAsDeoptimizingRecursively(HBasicBlock* block) {
+  for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
+    HBasicBlock* dominated = block->dominated_blocks()->at(i);
+    if (block->IsDeoptimizing()) dominated->MarkAsDeoptimizing();
+    MarkAsDeoptimizingRecursively(dominated);
+  }
+}

 void HGraph::EliminateRedundantPhis() {
   HPhase phase("Redundant phi elimination", this);
@@ -897,7 +910,7 @@

 void HRangeAnalysis::Analyze() {
   HPhase phase("Range analysis", graph_);
-  Analyze(graph_->blocks()->at(0));
+  Analyze(graph_->entry_block());
 }


@@ -1355,7 +1368,7 @@
     LoopInvariantCodeMotion();
   }
   HValueMap* map = new(zone()) HValueMap();
-  AnalyzeBlock(graph_->blocks()->at(0), map);
+  AnalyzeBlock(graph_->entry_block(), map);
 }


@@ -1447,37 +1460,9 @@

 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
                                       HBasicBlock* loop_header) {
-  // If we've disabled code motion, don't move any instructions.
-  if (!AllowCodeMotion()) return false;
-
-  // If --aggressive-loop-invariant-motion, move everything except change
-  // instructions.
-  if (FLAG_aggressive_loop_invariant_motion && !instr->IsChange()) {
-    return true;
-  }
-
-  // Otherwise only move instructions that postdominate the loop header
-  // (i.e. are always executed inside the loop). This is to avoid
-  // unnecessary deoptimizations assuming the loop is executed at least
-  // once.  TODO(fschneider): Better type feedback should give us
-  // information about code that was never executed.
-  HBasicBlock* block = instr->block();
-  bool result = true;
-  if (block != loop_header) {
-    for (int i = 1; i < loop_header->predecessors()->length(); ++i) {
-      bool found = false;
-      HBasicBlock* pred = loop_header->predecessors()->at(i);
-      while (pred != loop_header) {
-        if (pred == block) found = true;
-        pred = pred->dominator();
-      }
-      if (!found) {
-        result = false;
-        break;
-      }
-    }
-  }
-  return result;
+  // If we've disabled code motion or we're in a block that unconditionally
+  // deoptimizes, don't move any instructions.
+  return AllowCodeMotion() && !instr->block()->IsDeoptimizing();
 }


@@ -4854,6 +4839,7 @@
   TypeInfo info = oracle()->UnaryType(expr);
   if (info.IsUninitialized()) {
     AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
     info = TypeInfo::Unknown();
   }
   Representation rep = ToRepresentation(info);
@@ -4869,6 +4855,7 @@
   TypeInfo info = oracle()->UnaryType(expr);
   if (info.IsUninitialized()) {
     AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
   }
   HInstruction* instr = new(zone()) HBitNot(value);
   ast_context()->ReturnInstruction(instr, expr->id());
@@ -5104,6 +5091,7 @@
   TypeInfo info = oracle()->BinaryType(expr);
   if (info.IsUninitialized()) {
     AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
     info = TypeInfo::Unknown();
   }
   HInstruction* instr = NULL;
@@ -5373,6 +5361,7 @@
   // Check if this expression was ever executed according to type feedback.
   if (type_info.IsUninitialized()) {
     AddInstruction(new(zone()) HSoftDeoptimize);
+    current_block()->MarkAsDeoptimizing();
     type_info = TypeInfo::Unknown();
   }

=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Thu Jun  9 05:27:28 2011
+++ /branches/bleeding_edge/src/hydrogen.h      Thu Jun  9 08:49:21 2011
@@ -142,6 +142,9 @@
   // Goto (target block)
   bool IsInlineReturnTarget() const { return is_inline_return_target_; }
   void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
+
+  bool IsDeoptimizing() const { return is_deoptimizing_; }
+  void MarkAsDeoptimizing() { is_deoptimizing_ = true; }

   inline Zone* zone();

@@ -175,6 +178,7 @@
   ZoneList<int> deleted_phis_;
   HBasicBlock* parent_loop_header_;
   bool is_inline_return_target_;
+  bool is_deoptimizing_;
 };


@@ -225,6 +229,7 @@
   void OrderBlocks();
   void AssignDominators();
   void ReplaceCheckedValues();
+  void MarkAsDeoptimizingRecursively(HBasicBlock* block);

   // Returns false if there are phi-uses of the arguments-object
   // which are not supported by the optimizing compiler.

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to