| Index: src/compiler/common-operator-reducer.cc
|
| diff --git a/src/compiler/common-operator-reducer.cc b/src/compiler/common-operator-reducer.cc
|
| index 2334541f8adae64c18b45c8676eff1b041aef4f0..22e16a27f266e2e4c8f363c8d9943de2f4077718 100644
|
| --- a/src/compiler/common-operator-reducer.cc
|
| +++ b/src/compiler/common-operator-reducer.cc
|
| @@ -57,6 +57,9 @@ Reduction CommonOperatorReducer::Reduce(Node* node) {
|
| switch (node->opcode()) {
|
| case IrOpcode::kBranch:
|
| return ReduceBranch(node);
|
| + case IrOpcode::kDeoptimizeIf:
|
| + case IrOpcode::kDeoptimizeUnless:
|
| + return ReduceDeoptimizeConditional(node);
|
| case IrOpcode::kMerge:
|
| return ReduceMerge(node);
|
| case IrOpcode::kEffectPhi:
|
| @@ -123,6 +126,37 @@ Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
|
| return Replace(dead());
|
| }
|
|
|
| +Reduction CommonOperatorReducer::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);
|
| + // Swap DeoptimizeIf/DeoptimizeUnless on {node} if {cond} is a BooleaNot
|
| + // and use the input to BooleanNot as new condition for {node}. Note we
|
| + // assume that {cond} was already properly optimized before we get here
|
| + // (as guaranteed by the graph reduction logic).
|
| + if (condition->opcode() == IrOpcode::kBooleanNot) {
|
| + NodeProperties::ReplaceValueInput(node, condition->InputAt(0), 0);
|
| + NodeProperties::ChangeOp(node, condition_is_true
|
| + ? common()->DeoptimizeIf()
|
| + : common()->DeoptimizeUnless());
|
| + return Changed(node);
|
| + }
|
| + Decision const decision = DecideCondition(condition);
|
| + if (decision == Decision::kUnknown) return NoChange();
|
| + if (condition_is_true == (decision == Decision::kTrue)) {
|
| + return Replace(control);
|
| + }
|
| + 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());
|
| +}
|
|
|
| Reduction CommonOperatorReducer::ReduceMerge(Node* node) {
|
| DCHECK_EQ(IrOpcode::kMerge, node->opcode());
|
|
|