Reduce queue size in dead code elimination by eagerly processing live instructions.
authortitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 14 Oct 2013 13:32:02 +0000 (13:32 +0000)
committertitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 14 Oct 2013 13:32:02 +0000 (13:32 +0000)
BUG=
R=rmcilroy@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17196 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen-dce.cc
src/hydrogen-dce.h

index 0e7253d5a4869d44ee137129bd4c037eb8774dfd..cba9e42b67a560f11e65ecc092ac73cdd07534df 100644 (file)
 namespace v8 {
 namespace internal {
 
-bool HDeadCodeEliminationPhase::MarkLive(HValue* ref, HValue* instr) {
-  if (instr->CheckFlag(HValue::kIsLive)) return false;
-  instr->SetFlag(HValue::kIsLive);
-
-  if (FLAG_trace_dead_code_elimination) {
-    HeapStringAllocator allocator;
-    StringStream stream(&allocator);
-    if (ref != NULL) {
-      ref->PrintTo(&stream);
-    } else {
-      stream.Add("root ");
+void HDeadCodeEliminationPhase::MarkLive(
+    HValue* instr, ZoneList<HValue*>* worklist) {
+  if (instr->CheckFlag(HValue::kIsLive)) return;  // Already live.
+
+  if (FLAG_trace_dead_code_elimination) PrintLive(NULL, instr);
+
+  // Transitively mark all inputs of live instructions live.
+  worklist->Add(instr, zone());
+  while (!worklist->is_empty()) {
+    HValue* instr = worklist->RemoveLast();
+    instr->SetFlag(HValue::kIsLive);
+    for (int i = 0; i < instr->OperandCount(); ++i) {
+      HValue* input = instr->OperandAt(i);
+      if (!input->CheckFlag(HValue::kIsLive)) {
+        input->SetFlag(HValue::kIsLive);
+        worklist->Add(input, zone());
+        if (FLAG_trace_dead_code_elimination) PrintLive(instr, input);
+      }
     }
-    stream.Add(" -> ");
-    instr->PrintTo(&stream);
-    PrintF("[MarkLive %s]\n", *stream.ToCString());
   }
+}
+
 
-  return true;
+void HDeadCodeEliminationPhase::PrintLive(HValue* ref, HValue* instr) {
+  HeapStringAllocator allocator;
+  StringStream stream(&allocator);
+  if (ref != NULL) {
+    ref->PrintTo(&stream);
+  } else {
+    stream.Add("root ");
+  }
+  stream.Add(" -> ");
+  instr->PrintTo(&stream);
+  PrintF("[MarkLive %s]\n", *stream.ToCString());
 }
 
 
 void HDeadCodeEliminationPhase::MarkLiveInstructions() {
-  ZoneList<HValue*> worklist(graph()->blocks()->length(), zone());
+  ZoneList<HValue*> worklist(10, zone());
 
-  // Mark initial root instructions for dead code elimination.
+  // Transitively mark all live instructions, starting from roots.
   for (int i = 0; i < graph()->blocks()->length(); ++i) {
     HBasicBlock* block = graph()->blocks()->at(i);
     for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
       HInstruction* instr = it.Current();
-      if (instr->CannotBeEliminated() && MarkLive(NULL, instr)) {
-        worklist.Add(instr, zone());
-      }
+      if (instr->CannotBeEliminated()) MarkLive(instr, &worklist);
     }
     for (int j = 0; j < block->phis()->length(); j++) {
       HPhi* phi = block->phis()->at(j);
-      if (phi->CannotBeEliminated() && MarkLive(NULL, phi)) {
-        worklist.Add(phi, zone());
-      }
+      if (phi->CannotBeEliminated()) MarkLive(phi, &worklist);
     }
   }
 
-  // Transitively mark all inputs of live instructions live.
-  while (!worklist.is_empty()) {
-    HValue* instr = worklist.RemoveLast();
-    for (int i = 0; i < instr->OperandCount(); ++i) {
-      if (MarkLive(instr, instr->OperandAt(i))) {
-        worklist.Add(instr->OperandAt(i), zone());
-      }
-    }
-  }
+  ASSERT(worklist.is_empty());  // Should have processed everything.
 }
 
 
index 19749f279a2e1cb632ba5a300033e5a9f038638f..2d73b380e40831147e5b5e586f0c805d9c45f877 100644 (file)
@@ -45,7 +45,8 @@ class HDeadCodeEliminationPhase : public HPhase {
   }
 
  private:
-  bool MarkLive(HValue* ref, HValue* instr);
+  void MarkLive(HValue* instr, ZoneList<HValue*>* worklist);
+  void PrintLive(HValue* ref, HValue* instr);
   void MarkLiveInstructions();
   void RemoveDeadInstructions();
 };