11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/compiler/dead-code-elimination.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h" 81cb0ef41Sopenharmony_ci#include "src/compiler/graph.h" 91cb0ef41Sopenharmony_ci#include "src/compiler/js-operator.h" 101cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h" 111cb0ef41Sopenharmony_ci#include "src/compiler/operator-properties.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cinamespace v8 { 141cb0ef41Sopenharmony_cinamespace internal { 151cb0ef41Sopenharmony_cinamespace compiler { 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciDeadCodeElimination::DeadCodeElimination(Editor* editor, Graph* graph, 181cb0ef41Sopenharmony_ci CommonOperatorBuilder* common, 191cb0ef41Sopenharmony_ci Zone* temp_zone) 201cb0ef41Sopenharmony_ci : AdvancedReducer(editor), 211cb0ef41Sopenharmony_ci graph_(graph), 221cb0ef41Sopenharmony_ci common_(common), 231cb0ef41Sopenharmony_ci dead_(graph->NewNode(common->Dead())), 241cb0ef41Sopenharmony_ci zone_(temp_zone) { 251cb0ef41Sopenharmony_ci NodeProperties::SetType(dead_, Type::None()); 261cb0ef41Sopenharmony_ci} 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_cinamespace { 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci// True if we can guarantee that {node} will never actually produce a value or 311cb0ef41Sopenharmony_ci// effect. 321cb0ef41Sopenharmony_cibool NoReturn(Node* node) { 331cb0ef41Sopenharmony_ci return node->opcode() == IrOpcode::kDead || 341cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kUnreachable || 351cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kDeadValue || 361cb0ef41Sopenharmony_ci NodeProperties::GetTypeOrAny(node).IsNone(); 371cb0ef41Sopenharmony_ci} 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciNode* FindDeadInput(Node* node) { 401cb0ef41Sopenharmony_ci for (Node* input : node->inputs()) { 411cb0ef41Sopenharmony_ci if (NoReturn(input)) return input; 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci return nullptr; 441cb0ef41Sopenharmony_ci} 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci} // namespace 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciReduction DeadCodeElimination::Reduce(Node* node) { 491cb0ef41Sopenharmony_ci switch (node->opcode()) { 501cb0ef41Sopenharmony_ci case IrOpcode::kEnd: 511cb0ef41Sopenharmony_ci return ReduceEnd(node); 521cb0ef41Sopenharmony_ci case IrOpcode::kLoop: 531cb0ef41Sopenharmony_ci case IrOpcode::kMerge: 541cb0ef41Sopenharmony_ci return ReduceLoopOrMerge(node); 551cb0ef41Sopenharmony_ci case IrOpcode::kLoopExit: 561cb0ef41Sopenharmony_ci return ReduceLoopExit(node); 571cb0ef41Sopenharmony_ci case IrOpcode::kUnreachable: 581cb0ef41Sopenharmony_ci case IrOpcode::kIfException: 591cb0ef41Sopenharmony_ci return ReduceUnreachableOrIfException(node); 601cb0ef41Sopenharmony_ci case IrOpcode::kPhi: 611cb0ef41Sopenharmony_ci return ReducePhi(node); 621cb0ef41Sopenharmony_ci case IrOpcode::kEffectPhi: 631cb0ef41Sopenharmony_ci return ReduceEffectPhi(node); 641cb0ef41Sopenharmony_ci case IrOpcode::kDeoptimize: 651cb0ef41Sopenharmony_ci case IrOpcode::kReturn: 661cb0ef41Sopenharmony_ci case IrOpcode::kTerminate: 671cb0ef41Sopenharmony_ci case IrOpcode::kTailCall: 681cb0ef41Sopenharmony_ci return ReduceDeoptimizeOrReturnOrTerminateOrTailCall(node); 691cb0ef41Sopenharmony_ci case IrOpcode::kThrow: 701cb0ef41Sopenharmony_ci return PropagateDeadControl(node); 711cb0ef41Sopenharmony_ci case IrOpcode::kBranch: 721cb0ef41Sopenharmony_ci case IrOpcode::kSwitch: 731cb0ef41Sopenharmony_ci return ReduceBranchOrSwitch(node); 741cb0ef41Sopenharmony_ci default: 751cb0ef41Sopenharmony_ci return ReduceNode(node); 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci UNREACHABLE(); 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ciReduction DeadCodeElimination::PropagateDeadControl(Node* node) { 811cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->op()->ControlInputCount()); 821cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node); 831cb0ef41Sopenharmony_ci if (control->opcode() == IrOpcode::kDead) return Replace(control); 841cb0ef41Sopenharmony_ci return NoChange(); 851cb0ef41Sopenharmony_ci} 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceEnd(Node* node) { 881cb0ef41Sopenharmony_ci DCHECK_EQ(IrOpcode::kEnd, node->opcode()); 891cb0ef41Sopenharmony_ci Node::Inputs inputs = node->inputs(); 901cb0ef41Sopenharmony_ci DCHECK_LE(1, inputs.count()); 911cb0ef41Sopenharmony_ci int live_input_count = 0; 921cb0ef41Sopenharmony_ci for (int i = 0; i < inputs.count(); ++i) { 931cb0ef41Sopenharmony_ci Node* const input = inputs[i]; 941cb0ef41Sopenharmony_ci // Skip dead inputs. 951cb0ef41Sopenharmony_ci if (input->opcode() == IrOpcode::kDead) continue; 961cb0ef41Sopenharmony_ci // Compact live inputs. 971cb0ef41Sopenharmony_ci if (i != live_input_count) node->ReplaceInput(live_input_count, input); 981cb0ef41Sopenharmony_ci ++live_input_count; 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci if (live_input_count == 0) { 1011cb0ef41Sopenharmony_ci return Replace(dead()); 1021cb0ef41Sopenharmony_ci } else if (live_input_count < inputs.count()) { 1031cb0ef41Sopenharmony_ci node->TrimInputCount(live_input_count); 1041cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->End(live_input_count)); 1051cb0ef41Sopenharmony_ci return Changed(node); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci DCHECK_EQ(inputs.count(), live_input_count); 1081cb0ef41Sopenharmony_ci return NoChange(); 1091cb0ef41Sopenharmony_ci} 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceLoopOrMerge(Node* node) { 1121cb0ef41Sopenharmony_ci DCHECK(IrOpcode::IsMergeOpcode(node->opcode())); 1131cb0ef41Sopenharmony_ci Node::Inputs inputs = node->inputs(); 1141cb0ef41Sopenharmony_ci DCHECK_LE(1, inputs.count()); 1151cb0ef41Sopenharmony_ci // Count the number of live inputs to {node} and compact them on the fly, also 1161cb0ef41Sopenharmony_ci // compacting the inputs of the associated {Phi} and {EffectPhi} uses at the 1171cb0ef41Sopenharmony_ci // same time. We consider {Loop}s dead even if only the first control input 1181cb0ef41Sopenharmony_ci // is dead. 1191cb0ef41Sopenharmony_ci int live_input_count = 0; 1201cb0ef41Sopenharmony_ci if (node->opcode() != IrOpcode::kLoop || 1211cb0ef41Sopenharmony_ci node->InputAt(0)->opcode() != IrOpcode::kDead) { 1221cb0ef41Sopenharmony_ci for (int i = 0; i < inputs.count(); ++i) { 1231cb0ef41Sopenharmony_ci Node* const input = inputs[i]; 1241cb0ef41Sopenharmony_ci // Skip dead inputs. 1251cb0ef41Sopenharmony_ci if (input->opcode() == IrOpcode::kDead) continue; 1261cb0ef41Sopenharmony_ci // Compact live inputs. 1271cb0ef41Sopenharmony_ci if (live_input_count != i) { 1281cb0ef41Sopenharmony_ci node->ReplaceInput(live_input_count, input); 1291cb0ef41Sopenharmony_ci for (Node* const use : node->uses()) { 1301cb0ef41Sopenharmony_ci if (NodeProperties::IsPhi(use)) { 1311cb0ef41Sopenharmony_ci DCHECK_EQ(inputs.count() + 1, use->InputCount()); 1321cb0ef41Sopenharmony_ci use->ReplaceInput(live_input_count, use->InputAt(i)); 1331cb0ef41Sopenharmony_ci } 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci ++live_input_count; 1371cb0ef41Sopenharmony_ci } 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci if (live_input_count == 0) { 1401cb0ef41Sopenharmony_ci return Replace(dead()); 1411cb0ef41Sopenharmony_ci } else if (live_input_count == 1) { 1421cb0ef41Sopenharmony_ci NodeVector loop_exits(zone_); 1431cb0ef41Sopenharmony_ci // Due to compaction above, the live input is at offset 0. 1441cb0ef41Sopenharmony_ci for (Node* const use : node->uses()) { 1451cb0ef41Sopenharmony_ci if (NodeProperties::IsPhi(use)) { 1461cb0ef41Sopenharmony_ci Replace(use, use->InputAt(0)); 1471cb0ef41Sopenharmony_ci } else if (use->opcode() == IrOpcode::kLoopExit && 1481cb0ef41Sopenharmony_ci use->InputAt(1) == node) { 1491cb0ef41Sopenharmony_ci // Remember the loop exits so that we can mark their loop input dead. 1501cb0ef41Sopenharmony_ci // This has to be done after the use list iteration so that we do 1511cb0ef41Sopenharmony_ci // not mutate the use list while it is being iterated. 1521cb0ef41Sopenharmony_ci loop_exits.push_back(use); 1531cb0ef41Sopenharmony_ci } else if (use->opcode() == IrOpcode::kTerminate) { 1541cb0ef41Sopenharmony_ci DCHECK_EQ(IrOpcode::kLoop, node->opcode()); 1551cb0ef41Sopenharmony_ci Replace(use, dead()); 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci } 1581cb0ef41Sopenharmony_ci for (Node* loop_exit : loop_exits) { 1591cb0ef41Sopenharmony_ci loop_exit->ReplaceInput(1, dead()); 1601cb0ef41Sopenharmony_ci Revisit(loop_exit); 1611cb0ef41Sopenharmony_ci } 1621cb0ef41Sopenharmony_ci return Replace(node->InputAt(0)); 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci DCHECK_LE(2, live_input_count); 1651cb0ef41Sopenharmony_ci DCHECK_LE(live_input_count, inputs.count()); 1661cb0ef41Sopenharmony_ci // Trim input count for the {Merge} or {Loop} node. 1671cb0ef41Sopenharmony_ci if (live_input_count < inputs.count()) { 1681cb0ef41Sopenharmony_ci // Trim input counts for all phi uses and revisit them. 1691cb0ef41Sopenharmony_ci for (Node* const use : node->uses()) { 1701cb0ef41Sopenharmony_ci if (NodeProperties::IsPhi(use)) { 1711cb0ef41Sopenharmony_ci use->ReplaceInput(live_input_count, node); 1721cb0ef41Sopenharmony_ci TrimMergeOrPhi(use, live_input_count); 1731cb0ef41Sopenharmony_ci Revisit(use); 1741cb0ef41Sopenharmony_ci } 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci TrimMergeOrPhi(node, live_input_count); 1771cb0ef41Sopenharmony_ci return Changed(node); 1781cb0ef41Sopenharmony_ci } 1791cb0ef41Sopenharmony_ci return NoChange(); 1801cb0ef41Sopenharmony_ci} 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ciReduction DeadCodeElimination::RemoveLoopExit(Node* node) { 1831cb0ef41Sopenharmony_ci DCHECK_EQ(IrOpcode::kLoopExit, node->opcode()); 1841cb0ef41Sopenharmony_ci for (Node* const use : node->uses()) { 1851cb0ef41Sopenharmony_ci if (use->opcode() == IrOpcode::kLoopExitValue || 1861cb0ef41Sopenharmony_ci use->opcode() == IrOpcode::kLoopExitEffect) { 1871cb0ef41Sopenharmony_ci Replace(use, use->InputAt(0)); 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node, 0); 1911cb0ef41Sopenharmony_ci Replace(node, control); 1921cb0ef41Sopenharmony_ci return Replace(control); 1931cb0ef41Sopenharmony_ci} 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceNode(Node* node) { 1961cb0ef41Sopenharmony_ci DCHECK(!IrOpcode::IsGraphTerminator(node->opcode())); 1971cb0ef41Sopenharmony_ci int const effect_input_count = node->op()->EffectInputCount(); 1981cb0ef41Sopenharmony_ci int const control_input_count = node->op()->ControlInputCount(); 1991cb0ef41Sopenharmony_ci DCHECK_LE(control_input_count, 1); 2001cb0ef41Sopenharmony_ci if (control_input_count == 1) { 2011cb0ef41Sopenharmony_ci Reduction reduction = PropagateDeadControl(node); 2021cb0ef41Sopenharmony_ci if (reduction.Changed()) return reduction; 2031cb0ef41Sopenharmony_ci } 2041cb0ef41Sopenharmony_ci if (effect_input_count == 0 && 2051cb0ef41Sopenharmony_ci (control_input_count == 0 || node->op()->ControlOutputCount() == 0)) { 2061cb0ef41Sopenharmony_ci return ReducePureNode(node); 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci if (effect_input_count > 0) { 2091cb0ef41Sopenharmony_ci return ReduceEffectNode(node); 2101cb0ef41Sopenharmony_ci } 2111cb0ef41Sopenharmony_ci return NoChange(); 2121cb0ef41Sopenharmony_ci} 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReducePhi(Node* node) { 2151cb0ef41Sopenharmony_ci DCHECK_EQ(IrOpcode::kPhi, node->opcode()); 2161cb0ef41Sopenharmony_ci Reduction reduction = PropagateDeadControl(node); 2171cb0ef41Sopenharmony_ci if (reduction.Changed()) return reduction; 2181cb0ef41Sopenharmony_ci MachineRepresentation rep = PhiRepresentationOf(node->op()); 2191cb0ef41Sopenharmony_ci if (rep == MachineRepresentation::kNone || 2201cb0ef41Sopenharmony_ci NodeProperties::GetTypeOrAny(node).IsNone()) { 2211cb0ef41Sopenharmony_ci return Replace(DeadValue(node, rep)); 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci int input_count = node->op()->ValueInputCount(); 2241cb0ef41Sopenharmony_ci for (int i = 0; i < input_count; ++i) { 2251cb0ef41Sopenharmony_ci Node* input = NodeProperties::GetValueInput(node, i); 2261cb0ef41Sopenharmony_ci if (input->opcode() == IrOpcode::kDeadValue && 2271cb0ef41Sopenharmony_ci DeadValueRepresentationOf(input->op()) != rep) { 2281cb0ef41Sopenharmony_ci NodeProperties::ReplaceValueInput(node, DeadValue(input, rep), i); 2291cb0ef41Sopenharmony_ci } 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci return NoChange(); 2321cb0ef41Sopenharmony_ci} 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceEffectPhi(Node* node) { 2351cb0ef41Sopenharmony_ci DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); 2361cb0ef41Sopenharmony_ci Reduction reduction = PropagateDeadControl(node); 2371cb0ef41Sopenharmony_ci if (reduction.Changed()) return reduction; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci Node* merge = NodeProperties::GetControlInput(node); 2401cb0ef41Sopenharmony_ci DCHECK(merge->opcode() == IrOpcode::kMerge || 2411cb0ef41Sopenharmony_ci merge->opcode() == IrOpcode::kLoop); 2421cb0ef41Sopenharmony_ci int input_count = node->op()->EffectInputCount(); 2431cb0ef41Sopenharmony_ci for (int i = 0; i < input_count; ++i) { 2441cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node, i); 2451cb0ef41Sopenharmony_ci if (effect->opcode() == IrOpcode::kUnreachable) { 2461cb0ef41Sopenharmony_ci // If Unreachable hits an effect phi, we can re-connect the effect chain 2471cb0ef41Sopenharmony_ci // to the graph end and delete the corresponding inputs from the merge and 2481cb0ef41Sopenharmony_ci // phi nodes. 2491cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(merge, i); 2501cb0ef41Sopenharmony_ci Node* throw_node = graph_->NewNode(common_->Throw(), effect, control); 2511cb0ef41Sopenharmony_ci NodeProperties::MergeControlToEnd(graph_, common_, throw_node); 2521cb0ef41Sopenharmony_ci NodeProperties::ReplaceEffectInput(node, dead_, i); 2531cb0ef41Sopenharmony_ci NodeProperties::ReplaceControlInput(merge, dead_, i); 2541cb0ef41Sopenharmony_ci Revisit(merge); 2551cb0ef41Sopenharmony_ci Revisit(graph_->end()); 2561cb0ef41Sopenharmony_ci reduction = Changed(node); 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci } 2591cb0ef41Sopenharmony_ci return reduction; 2601cb0ef41Sopenharmony_ci} 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReducePureNode(Node* node) { 2631cb0ef41Sopenharmony_ci DCHECK_EQ(0, node->op()->EffectInputCount()); 2641cb0ef41Sopenharmony_ci if (node->opcode() == IrOpcode::kDeadValue) return NoChange(); 2651cb0ef41Sopenharmony_ci if (Node* input = FindDeadInput(node)) { 2661cb0ef41Sopenharmony_ci return Replace(DeadValue(input)); 2671cb0ef41Sopenharmony_ci } 2681cb0ef41Sopenharmony_ci return NoChange(); 2691cb0ef41Sopenharmony_ci} 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceUnreachableOrIfException(Node* node) { 2721cb0ef41Sopenharmony_ci DCHECK(node->opcode() == IrOpcode::kUnreachable || 2731cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kIfException); 2741cb0ef41Sopenharmony_ci Reduction reduction = PropagateDeadControl(node); 2751cb0ef41Sopenharmony_ci if (reduction.Changed()) return reduction; 2761cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node, 0); 2771cb0ef41Sopenharmony_ci if (effect->opcode() == IrOpcode::kDead) { 2781cb0ef41Sopenharmony_ci return Replace(effect); 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci if (effect->opcode() == IrOpcode::kUnreachable) { 2811cb0ef41Sopenharmony_ci return Replace(effect); 2821cb0ef41Sopenharmony_ci } 2831cb0ef41Sopenharmony_ci return NoChange(); 2841cb0ef41Sopenharmony_ci} 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceEffectNode(Node* node) { 2871cb0ef41Sopenharmony_ci DCHECK_EQ(1, node->op()->EffectInputCount()); 2881cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node, 0); 2891cb0ef41Sopenharmony_ci if (effect->opcode() == IrOpcode::kDead) { 2901cb0ef41Sopenharmony_ci return Replace(effect); 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci if (Node* input = FindDeadInput(node)) { 2931cb0ef41Sopenharmony_ci if (effect->opcode() == IrOpcode::kUnreachable) { 2941cb0ef41Sopenharmony_ci RelaxEffectsAndControls(node); 2951cb0ef41Sopenharmony_ci return Replace(DeadValue(input)); 2961cb0ef41Sopenharmony_ci } 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci Node* control = node->op()->ControlInputCount() == 1 2991cb0ef41Sopenharmony_ci ? NodeProperties::GetControlInput(node, 0) 3001cb0ef41Sopenharmony_ci : graph()->start(); 3011cb0ef41Sopenharmony_ci Node* unreachable = 3021cb0ef41Sopenharmony_ci graph()->NewNode(common()->Unreachable(), effect, control); 3031cb0ef41Sopenharmony_ci NodeProperties::SetType(unreachable, Type::None()); 3041cb0ef41Sopenharmony_ci ReplaceWithValue(node, DeadValue(input), node, control); 3051cb0ef41Sopenharmony_ci return Replace(unreachable); 3061cb0ef41Sopenharmony_ci } 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci return NoChange(); 3091cb0ef41Sopenharmony_ci} 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceDeoptimizeOrReturnOrTerminateOrTailCall( 3121cb0ef41Sopenharmony_ci Node* node) { 3131cb0ef41Sopenharmony_ci DCHECK(node->opcode() == IrOpcode::kDeoptimize || 3141cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kReturn || 3151cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kTerminate || 3161cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kTailCall); 3171cb0ef41Sopenharmony_ci Reduction reduction = PropagateDeadControl(node); 3181cb0ef41Sopenharmony_ci if (reduction.Changed()) return reduction; 3191cb0ef41Sopenharmony_ci // Terminate nodes are not part of actual control flow, so they should never 3201cb0ef41Sopenharmony_ci // be replaced with Throw. 3211cb0ef41Sopenharmony_ci if (node->opcode() != IrOpcode::kTerminate && 3221cb0ef41Sopenharmony_ci FindDeadInput(node) != nullptr) { 3231cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node, 0); 3241cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node, 0); 3251cb0ef41Sopenharmony_ci if (effect->opcode() != IrOpcode::kUnreachable) { 3261cb0ef41Sopenharmony_ci effect = graph()->NewNode(common()->Unreachable(), effect, control); 3271cb0ef41Sopenharmony_ci NodeProperties::SetType(effect, Type::None()); 3281cb0ef41Sopenharmony_ci } 3291cb0ef41Sopenharmony_ci node->TrimInputCount(2); 3301cb0ef41Sopenharmony_ci node->ReplaceInput(0, effect); 3311cb0ef41Sopenharmony_ci node->ReplaceInput(1, control); 3321cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Throw()); 3331cb0ef41Sopenharmony_ci return Changed(node); 3341cb0ef41Sopenharmony_ci } 3351cb0ef41Sopenharmony_ci return NoChange(); 3361cb0ef41Sopenharmony_ci} 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceLoopExit(Node* node) { 3391cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node, 0); 3401cb0ef41Sopenharmony_ci Node* loop = NodeProperties::GetControlInput(node, 1); 3411cb0ef41Sopenharmony_ci if (control->opcode() == IrOpcode::kDead || 3421cb0ef41Sopenharmony_ci loop->opcode() == IrOpcode::kDead) { 3431cb0ef41Sopenharmony_ci return RemoveLoopExit(node); 3441cb0ef41Sopenharmony_ci } 3451cb0ef41Sopenharmony_ci return NoChange(); 3461cb0ef41Sopenharmony_ci} 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ciReduction DeadCodeElimination::ReduceBranchOrSwitch(Node* node) { 3491cb0ef41Sopenharmony_ci DCHECK(node->opcode() == IrOpcode::kBranch || 3501cb0ef41Sopenharmony_ci node->opcode() == IrOpcode::kSwitch); 3511cb0ef41Sopenharmony_ci Reduction reduction = PropagateDeadControl(node); 3521cb0ef41Sopenharmony_ci if (reduction.Changed()) return reduction; 3531cb0ef41Sopenharmony_ci Node* condition = NodeProperties::GetValueInput(node, 0); 3541cb0ef41Sopenharmony_ci if (condition->opcode() == IrOpcode::kDeadValue) { 3551cb0ef41Sopenharmony_ci // Branches or switches on {DeadValue} must originate from unreachable code 3561cb0ef41Sopenharmony_ci // and cannot matter. Due to schedule freedom between the effect and the 3571cb0ef41Sopenharmony_ci // control chain, they might still appear in reachable code. Remove them by 3581cb0ef41Sopenharmony_ci // always choosing the first projection. 3591cb0ef41Sopenharmony_ci size_t const projection_cnt = node->op()->ControlOutputCount(); 3601cb0ef41Sopenharmony_ci Node** projections = zone_->NewArray<Node*>(projection_cnt); 3611cb0ef41Sopenharmony_ci NodeProperties::CollectControlProjections(node, projections, 3621cb0ef41Sopenharmony_ci projection_cnt); 3631cb0ef41Sopenharmony_ci Replace(projections[0], NodeProperties::GetControlInput(node)); 3641cb0ef41Sopenharmony_ci return Replace(dead()); 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci return NoChange(); 3671cb0ef41Sopenharmony_ci} 3681cb0ef41Sopenharmony_ci 3691cb0ef41Sopenharmony_civoid DeadCodeElimination::TrimMergeOrPhi(Node* node, int size) { 3701cb0ef41Sopenharmony_ci const Operator* const op = common()->ResizeMergeOrPhi(node->op(), size); 3711cb0ef41Sopenharmony_ci node->TrimInputCount(OperatorProperties::GetTotalInputCount(op)); 3721cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, op); 3731cb0ef41Sopenharmony_ci} 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ciNode* DeadCodeElimination::DeadValue(Node* node, MachineRepresentation rep) { 3761cb0ef41Sopenharmony_ci if (node->opcode() == IrOpcode::kDeadValue) { 3771cb0ef41Sopenharmony_ci if (rep == DeadValueRepresentationOf(node->op())) return node; 3781cb0ef41Sopenharmony_ci node = NodeProperties::GetValueInput(node, 0); 3791cb0ef41Sopenharmony_ci } 3801cb0ef41Sopenharmony_ci Node* dead_value = graph()->NewNode(common()->DeadValue(rep), node); 3811cb0ef41Sopenharmony_ci NodeProperties::SetType(dead_value, Type::None()); 3821cb0ef41Sopenharmony_ci return dead_value; 3831cb0ef41Sopenharmony_ci} 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci} // namespace compiler 3861cb0ef41Sopenharmony_ci} // namespace internal 3871cb0ef41Sopenharmony_ci} // namespace v8 388