| Index: src/compiler/branch-elimination.cc
|
| diff --git a/src/compiler/branch-elimination.cc b/src/compiler/branch-elimination.cc
|
| index bc56e73a0813ffd3795f6e41ead8f735a38f18fe..427612c36e1152f916750d71336f560d88795309 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,41 @@ 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()) {
|
| + // We don't to update the conditions here, because we're replacing with
|
| + // the {control} node that already contains the right information.
|
| + return Replace(control);
|
| + } 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 +302,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
|
|
|