| Index: src/compiler/control-reducer.cc
|
| diff --git a/src/compiler/control-reducer.cc b/src/compiler/control-reducer.cc
|
| index 1d8310316e7219bdc518fd465c9eab43052b7b43..b5acbb23e7abb6e19d509f6996b37e7930102823 100644
|
| --- a/src/compiler/control-reducer.cc
|
| +++ b/src/compiler/control-reducer.cc
|
| @@ -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;
|
| }
|
|
|