Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / v8 / src / hydrogen-gvn.cc
index 3ad9312..bc83689 100644 (file)
@@ -364,35 +364,48 @@ void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) {
 
 
 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph)
-      : HPhase("H_Global value numbering", graph),
-        removed_side_effects_(false),
-        block_side_effects_(graph->blocks()->length(), zone()),
-        loop_side_effects_(graph->blocks()->length(), zone()),
-        visited_on_paths_(graph->blocks()->length(), zone()) {
-    ASSERT(!AllowHandleAllocation::IsAllowed());
-    block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
-                                 zone());
-    loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
+    : HPhase("H_Global value numbering", graph),
+      removed_side_effects_(false),
+      block_side_effects_(graph->blocks()->length(), zone()),
+      loop_side_effects_(graph->blocks()->length(), zone()),
+      visited_on_paths_(graph->blocks()->length(), zone()) {
+  ASSERT(!AllowHandleAllocation::IsAllowed());
+  block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
                                 zone());
-  }
+  loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
+                              zone());
+}
+
+
+void HGlobalValueNumberingPhase::Run() {
+  ASSERT(!removed_side_effects_);
+  for (int i = FLAG_gvn_iterations; i > 0; --i) {
+    // Compute the side effects.
+    ComputeBlockSideEffects();
+
+    // Perform loop invariant code motion if requested.
+    if (FLAG_loop_invariant_code_motion) LoopInvariantCodeMotion();
+
+    // Perform the actual value numbering.
+    AnalyzeGraph();
 
-void HGlobalValueNumberingPhase::Analyze() {
-  removed_side_effects_ = false;
-  ComputeBlockSideEffects();
-  if (FLAG_loop_invariant_code_motion) {
-    LoopInvariantCodeMotion();
+    // Continue GVN if we removed any side effects.
+    if (!removed_side_effects_) break;
+    removed_side_effects_ = false;
+
+    // Clear all side effects.
+    ASSERT_EQ(block_side_effects_.length(), graph()->blocks()->length());
+    ASSERT_EQ(loop_side_effects_.length(), graph()->blocks()->length());
+    for (int i = 0; i < graph()->blocks()->length(); ++i) {
+      block_side_effects_[i].RemoveAll();
+      loop_side_effects_[i].RemoveAll();
+    }
+    visited_on_paths_.Clear();
   }
-  AnalyzeGraph();
 }
 
 
 void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
-  // The Analyze phase of GVN can be called multiple times. Clear loop side
-  // effects before computing them to erase the contents from previous Analyze
-  // passes.
-  for (int i = 0; i < loop_side_effects_.length(); ++i) {
-    loop_side_effects_[i].RemoveAll();
-  }
   for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
     // Compute side effects for the block.
     HBasicBlock* block = graph()->blocks()->at(i);
@@ -426,7 +439,7 @@ void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
 
 
 SmartArrayPointer<char> GetGVNFlagsString(GVNFlagSet flags) {
-  char underlying_buffer[kLastFlag * 128];
+  char underlying_buffer[kNumberOfFlags * 128];
   Vector<char> buffer(underlying_buffer, sizeof(underlying_buffer));
 #if DEBUG
   int offset = 0;
@@ -435,7 +448,7 @@ SmartArrayPointer<char> GetGVNFlagsString(GVNFlagSet flags) {
   buffer[0] = 0;
   uint32_t set_depends_on = 0;
   uint32_t set_changes = 0;
-  for (int bit = 0; bit < kLastFlag; ++bit) {
+  for (int bit = 0; bit < kNumberOfFlags; ++bit) {
     if (flags.Contains(static_cast<GVNFlag>(bit))) {
       if (bit % 2 == 0) {
         set_changes++;
@@ -444,15 +457,15 @@ SmartArrayPointer<char> GetGVNFlagsString(GVNFlagSet flags) {
       }
     }
   }
-  bool positive_changes = set_changes < (kLastFlag / 2);
-  bool positive_depends_on = set_depends_on < (kLastFlag / 2);
+  bool positive_changes = set_changes < (kNumberOfFlags / 2);
+  bool positive_depends_on = set_depends_on < (kNumberOfFlags / 2);
   if (set_changes > 0) {
     if (positive_changes) {
       offset += OS::SNPrintF(buffer + offset, "changes [");
     } else {
       offset += OS::SNPrintF(buffer + offset, "changes all except [");
     }
-    for (int bit = 0; bit < kLastFlag; ++bit) {
+    for (int bit = 0; bit < kNumberOfFlags; ++bit) {
       if (flags.Contains(static_cast<GVNFlag>(bit)) == positive_changes) {
         switch (static_cast<GVNFlag>(bit)) {
 #define DECLARE_FLAG(type)                                       \
@@ -481,7 +494,7 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
     } else {
       offset += OS::SNPrintF(buffer + offset, "depends on all except [");
     }
-    for (int bit = 0; bit < kLastFlag; ++bit) {
+    for (int bit = 0; bit < kNumberOfFlags; ++bit) {
       if (flags.Contains(static_cast<GVNFlag>(bit)) == positive_depends_on) {
         switch (static_cast<GVNFlag>(bit)) {
 #define DECLARE_FLAG(type)                                       \
@@ -522,13 +535,9 @@ void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() {
                   block->block_id(),
                   GetGVNFlagsString(side_effects).get());
 
-      GVNFlagSet accumulated_first_time_depends;
-      GVNFlagSet accumulated_first_time_changes;
       HBasicBlock* last = block->loop_information()->GetLastBackEdge();
       for (int j = block->block_id(); j <= last->block_id(); ++j) {
-        ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects,
-                         &accumulated_first_time_depends,
-                         &accumulated_first_time_changes);
+        ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects);
       }
     }
   }
@@ -538,9 +547,7 @@ void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() {
 void HGlobalValueNumberingPhase::ProcessLoopBlock(
     HBasicBlock* block,
     HBasicBlock* loop_header,
-    GVNFlagSet loop_kills,
-    GVNFlagSet* first_time_depends,
-    GVNFlagSet* first_time_changes) {
+    GVNFlagSet loop_kills) {
   HBasicBlock* pre_header = loop_header->predecessors()->at(0);
   GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
   TRACE_GVN_2("Loop invariant motion for B%d %s\n",
@@ -549,7 +556,6 @@ void HGlobalValueNumberingPhase::ProcessLoopBlock(
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
-    bool hoisted = false;
     if (instr->CheckFlag(HValue::kUseGVN)) {
       TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n",
                   instr->id(),
@@ -576,26 +582,9 @@ void HGlobalValueNumberingPhase::ProcessLoopBlock(
           instr->Unlink();
           instr->InsertBefore(pre_header->end());
           if (instr->HasSideEffects()) removed_side_effects_ = true;
-          hoisted = true;
         }
       }
     }
-    if (!hoisted) {
-      // If an instruction is not hoisted, we have to account for its side
-      // effects when hoisting later HTransitionElementsKind instructions.
-      GVNFlagSet previous_depends = *first_time_depends;
-      GVNFlagSet previous_changes = *first_time_changes;
-      first_time_depends->Add(instr->DependsOnFlags());
-      first_time_changes->Add(instr->ChangesFlags());
-      if (!(previous_depends == *first_time_depends)) {
-        TRACE_GVN_1("Updated first-time accumulated %s\n",
-                    GetGVNFlagsString(*first_time_depends).get());
-      }
-      if (!(previous_changes == *first_time_changes)) {
-        TRACE_GVN_1("Updated first-time accumulated %s\n",
-                    GetGVNFlagsString(*first_time_changes).get());
-      }
-    }
     instr = next;
   }
 }
@@ -791,7 +780,9 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() {
                         instr->Mnemonic(),
                         other->id(),
                         other->Mnemonic());
-            instr->HandleSideEffectDominator(changes_flag, other);
+            if (instr->HandleSideEffectDominator(changes_flag, other)) {
+              removed_side_effects_ = true;
+            }
           }
         }
       }