Chromium Code Reviews| Index: src/compiler/branch-elimination.cc |
| diff --git a/src/compiler/branch-elimination.cc b/src/compiler/branch-elimination.cc |
| index bc56e73a0813ffd3795f6e41ead8f735a38f18fe..752e3fa0aaf79d6c6cd8491a6d422b34913eec62 100644 |
| --- a/src/compiler/branch-elimination.cc |
| +++ b/src/compiler/branch-elimination.cc |
| @@ -15,11 +15,11 @@ namespace compiler { |
| BranchElimination::BranchElimination(Editor* editor, JSGraph* js_graph, |
| Zone* zone) |
| : AdvancedReducer(editor), |
| + jsgraph_(js_graph), |
| node_conditions_(zone, js_graph->graph()->NodeCount()), |
| zone_(zone), |
| dead_(js_graph->graph()->NewNode(js_graph->common()->Dead())) {} |
| - |
| BranchElimination::~BranchElimination() {} |
| @@ -27,6 +27,9 @@ Reduction BranchElimination::Reduce(Node* node) { |
| switch (node->opcode()) { |
| case IrOpcode::kDead: |
| return NoChange(); |
| + case IrOpcode::kDeoptimizeIf: |
| + case IrOpcode::kDeoptimizeUnless: |
| + return ReduceDeoptimizeConditional(node); |
| case IrOpcode::kMerge: |
| return ReduceMerge(node); |
| case IrOpcode::kLoop: |
| @@ -76,6 +79,39 @@ Reduction BranchElimination::ReduceBranch(Node* node) { |
| return TakeConditionsFromFirstControl(node); |
| } |
| +Reduction BranchElimination::ReduceDeoptimizeConditional(Node* node) { |
| + DCHECK(node->opcode() == IrOpcode::kDeoptimizeIf || |
| + node->opcode() == IrOpcode::kDeoptimizeUnless); |
| + bool condition_is_true = node->opcode() == IrOpcode::kDeoptimizeUnless; |
| + Node* condition = NodeProperties::GetValueInput(node, 0); |
| + Node* frame_state = NodeProperties::GetValueInput(node, 1); |
| + Node* effect = NodeProperties::GetEffectInput(node); |
| + Node* control = NodeProperties::GetControlInput(node); |
| + ControlPathConditions const* conditions = node_conditions_.Get(control); |
| + // If we do not know anything about the predecessor, do not propagate just |
| + // yet because we will have to recompute anyway once we compute the |
| + // predecessor. |
| + if (conditions == nullptr) { |
| + DCHECK_NULL(node_conditions_.Get(node)); |
| + return NoChange(); |
| + } |
| + Maybe<bool> condition_value = conditions->LookupCondition(condition); |
| + if (condition_value.IsJust()) { |
| + // If we know the condition we can discard the branch. |
| + if (condition_is_true == condition_value.FromJust()) { |
| + return Replace(control); |
|
Jarin
2016/02/24 08:56:38
Perhaps add a comment saying that we do not need t
Benedikt Meurer
2016/02/24 09:04:56
Done.
|
| + } else { |
| + control = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), |
| + frame_state, effect, control); |
| + // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| + NodeProperties::MergeControlToEnd(graph(), common(), control); |
| + Revisit(graph()->end()); |
| + return Replace(dead()); |
| + } |
| + } |
| + return UpdateConditions( |
| + node, conditions->AddCondition(zone_, condition, condition_is_true)); |
| +} |
| Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) { |
| // Add the condition to the list arriving from the input branch. |
| @@ -264,6 +300,12 @@ bool BranchElimination::ControlPathConditions::operator==( |
| return false; |
| } |
| +Graph* BranchElimination::graph() const { return jsgraph()->graph(); } |
| + |
| +CommonOperatorBuilder* BranchElimination::common() const { |
| + return jsgraph()->common(); |
| +} |
| + |
| } // namespace compiler |
| } // namespace internal |
| } // namespace v8 |