diff --git a/src/compiler/dead-code-elimination.cc b/src/compiler/dead-code-elimination.cc index 2251121c7f..f39e6cabfb 100644 --- a/src/compiler/dead-code-elimination.cc +++ b/src/compiler/dead-code-elimination.cc @@ -61,7 +61,7 @@ Reduction DeadCodeElimination::Reduce(Node* node) { case IrOpcode::kPhi: return ReducePhi(node); case IrOpcode::kEffectPhi: - return PropagateDeadControl(node); + return ReduceEffectPhi(node); case IrOpcode::kDeoptimize: case IrOpcode::kReturn: case IrOpcode::kTerminate: @@ -109,7 +109,6 @@ Reduction DeadCodeElimination::ReduceEnd(Node* node) { return NoChange(); } - Reduction DeadCodeElimination::ReduceLoopOrMerge(Node* node) { DCHECK(IrOpcode::IsMergeOpcode(node->opcode())); Node::Inputs inputs = node->inputs(); @@ -233,6 +232,34 @@ Reduction DeadCodeElimination::ReducePhi(Node* node) { return NoChange(); } +Reduction DeadCodeElimination::ReduceEffectPhi(Node* node) { + DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); + Reduction reduction = PropagateDeadControl(node); + if (reduction.Changed()) return reduction; + + Node* merge = NodeProperties::GetControlInput(node); + DCHECK(merge->opcode() == IrOpcode::kMerge || + merge->opcode() == IrOpcode::kLoop); + int input_count = node->op()->EffectInputCount(); + for (int i = 0; i < input_count; ++i) { + Node* effect = NodeProperties::GetEffectInput(node, i); + if (effect->opcode() == IrOpcode::kUnreachable) { + // If Unreachable hits an effect phi, we can re-connect the effect chain + // to the graph end and delete the corresponding inputs from the merge and + // phi nodes. + Node* control = NodeProperties::GetControlInput(merge, i); + Node* throw_node = graph_->NewNode(common_->Throw(), effect, control); + NodeProperties::MergeControlToEnd(graph_, common_, throw_node); + NodeProperties::ReplaceEffectInput(node, dead_, i); + NodeProperties::ReplaceControlInput(merge, dead_, i); + Revisit(merge); + Revisit(graph_->end()); + reduction = Changed(node); + } + } + return reduction; +} + Reduction DeadCodeElimination::ReducePureNode(Node* node) { DCHECK_EQ(0, node->op()->EffectInputCount()); if (node->opcode() == IrOpcode::kDeadValue) return NoChange(); diff --git a/src/compiler/dead-code-elimination.h b/src/compiler/dead-code-elimination.h index 95b9179595..17f9a3716c 100644 --- a/src/compiler/dead-code-elimination.h +++ b/src/compiler/dead-code-elimination.h @@ -53,6 +53,7 @@ class V8_EXPORT_PRIVATE DeadCodeElimination final Reduction ReduceLoopExit(Node* node); Reduction ReduceNode(Node* node); Reduction ReducePhi(Node* node); + Reduction ReduceEffectPhi(Node* node); Reduction ReducePureNode(Node* node); Reduction ReduceUnreachableOrIfException(Node* node); Reduction ReduceEffectNode(Node* node);