[turbofan] Factor out common code between ReduceSelect and ReduceBranch in ControlRed...
authorBen L. Titzer <titzer@chromium.org>
Mon, 17 Nov 2014 11:34:53 +0000 (12:34 +0100)
committerBen L. Titzer <titzer@chromium.org>
Mon, 17 Nov 2014 11:35:04 +0000 (11:35 +0000)
R=bmeurer@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#25375}

src/compiler/control-reducer.cc

index 1d83103..b5acbb2 100644 (file)
@@ -16,6 +16,7 @@ namespace compiler {
 
 enum VisitState { kUnvisited = 0, kOnStack = 1, kRevisit = 2, kVisited = 3 };
 enum Reachability { kFromStart = 8 };
+enum Decision { kFalse, kUnknown, kTrue };
 
 #define TRACE(x) \
   if (FLAG_trace_turbo_reduction) PrintF x
@@ -340,29 +341,37 @@ class ControlReducerImpl {
     }
   }
 
-  // Reduce redundant selects.
-  Node* ReduceSelect(Node* const node) {
-    Node* const cond = node->InputAt(0);
-    Node* const tvalue = node->InputAt(1);
-    Node* const fvalue = node->InputAt(2);
-    if (tvalue == fvalue) return tvalue;
+  // Try to statically fold a condition.
+  Decision DecideCondition(Node* cond) {
     switch (cond->opcode()) {
       case IrOpcode::kInt32Constant:
-        return Int32Matcher(cond).Is(0) ? fvalue : tvalue;
+        return Int32Matcher(cond).Is(0) ? kFalse : kTrue;
       case IrOpcode::kInt64Constant:
-        return Int64Matcher(cond).Is(0) ? fvalue : tvalue;
+        return Int64Matcher(cond).Is(0) ? kFalse : kTrue;
       case IrOpcode::kNumberConstant:
-        return NumberMatcher(cond).Is(0) ? fvalue : tvalue;
+        return NumberMatcher(cond).Is(0) ? kFalse : kTrue;
       case IrOpcode::kHeapConstant: {
         Handle<Object> object =
             HeapObjectMatcher<Object>(cond).Value().handle();
-        if (object->IsTrue()) return tvalue;
-        if (object->IsFalse()) return fvalue;
+        if (object->IsTrue()) return kTrue;
+        if (object->IsFalse()) return kFalse;
+        // TODO(turbofan): decide more conditions for heap constants.
         break;
       }
       default:
         break;
     }
+    return kUnknown;
+  }
+
+  // Reduce redundant selects.
+  Node* ReduceSelect(Node* const node) {
+    Node* const tvalue = node->InputAt(1);
+    Node* const fvalue = node->InputAt(2);
+    if (tvalue == fvalue) return tvalue;
+    Decision result = DecideCondition(node->InputAt(0));
+    if (result == kTrue) return tvalue;
+    if (result == kFalse) return fvalue;
     return node;
   }
 
@@ -436,35 +445,11 @@ class ControlReducerImpl {
 
   // Reduce branches if they have constant inputs.
   Node* ReduceBranch(Node* node) {
-    Node* cond = node->InputAt(0);
-    bool is_true;
-    switch (cond->opcode()) {
-      case IrOpcode::kInt32Constant:
-        is_true = !Int32Matcher(cond).Is(0);
-        break;
-      case IrOpcode::kInt64Constant:
-        is_true = !Int64Matcher(cond).Is(0);
-        break;
-      case IrOpcode::kNumberConstant:
-        is_true = !NumberMatcher(cond).Is(0);
-        break;
-      case IrOpcode::kHeapConstant: {
-        Handle<Object> object =
-            HeapObjectMatcher<Object>(cond).Value().handle();
-        if (object->IsTrue())
-          is_true = true;
-        else if (object->IsFalse())
-          is_true = false;
-        else
-          return node;  // TODO(turbofan): fold branches on strings, objects.
-        break;
-      }
-      default:
-        return node;
-    }
+    Decision result = DecideCondition(node->InputAt(0));
+    if (result == kUnknown) return node;
 
     TRACE(("BranchReduce: #%d:%s = %s\n", node->id(), node->op()->mnemonic(),
-           is_true ? "true" : "false"));
+           (result == kTrue) ? "true" : "false"));
 
     // Replace IfTrue and IfFalse projections from this branch.
     Node* control = NodeProperties::GetControlInput(node);
@@ -473,11 +458,11 @@ class ControlReducerImpl {
       if (to->opcode() == IrOpcode::kIfTrue) {
         TRACE(("  IfTrue: #%d:%s\n", to->id(), to->op()->mnemonic()));
         i.UpdateToAndIncrement(NULL);
-        ReplaceNode(to, is_true ? control : dead());
+        ReplaceNode(to, (result == kTrue) ? control : dead());
       } else if (to->opcode() == IrOpcode::kIfFalse) {
         TRACE(("  IfFalse: #%d:%s\n", to->id(), to->op()->mnemonic()));
         i.UpdateToAndIncrement(NULL);
-        ReplaceNode(to, is_true ? dead() : control);
+        ReplaceNode(to, (result == kTrue) ? dead() : control);
       } else {
         ++i;
       }