22 dead_(graph->NewNode(common->Dead())),
31bool NoReturn(
Node* node) {
32 return node->opcode() == IrOpcode::kDead ||
33 node->opcode() == IrOpcode::kUnreachable ||
34 node->opcode() == IrOpcode::kDeadValue ||
38Node* FindDeadInput(Node* node) {
39 for (Node* input : node->inputs()) {
40 if (NoReturn(input))
return input;
48 switch (node->opcode()) {
52 case IrOpcode::kMerge:
54 case IrOpcode::kLoopExit:
56 case IrOpcode::kUnreachable:
57 case IrOpcode::kIfException:
61 case IrOpcode::kEffectPhi:
63 case IrOpcode::kDeoptimize:
64 case IrOpcode::kReturn:
65 case IrOpcode::kTerminate:
66 case IrOpcode::kTailCall:
68 case IrOpcode::kThrow:
70 case IrOpcode::kBranch:
71 case IrOpcode::kSwitch:
80 DCHECK_EQ(1, node->op()->ControlInputCount());
82 if (control->
opcode() == IrOpcode::kDead)
return Replace(control);
87 DCHECK_EQ(IrOpcode::kEnd, node->opcode());
90 int live_input_count = 0;
91 for (
int i = 0;
i < inputs.
count(); ++
i) {
92 Node*
const input = inputs[
i];
94 if (input->opcode() == IrOpcode::kDead)
continue;
96 if (
i != live_input_count) node->ReplaceInput(live_input_count, input);
99 if (live_input_count == 0) {
100 return Replace(
dead());
101 }
else if (live_input_count < inputs.
count()) {
102 node->TrimInputCount(live_input_count);
104 return Changed(node);
118 int live_input_count = 0;
119 if (node->opcode() != IrOpcode::kLoop ||
120 node->InputAt(0)->opcode() != IrOpcode::kDead) {
121 for (
int i = 0;
i < inputs.
count(); ++
i) {
122 Node*
const input = inputs[
i];
124 if (input->opcode() == IrOpcode::kDead)
continue;
126 if (live_input_count !=
i) {
127 node->ReplaceInput(live_input_count, input);
128 for (
Node*
const use : node->
uses()) {
131 use->ReplaceInput(live_input_count, use->InputAt(
i));
138 if (live_input_count == 0) {
139 return Replace(
dead());
140 }
else if (live_input_count == 1) {
143 for (
Node*
const use : node->
uses()) {
145 Replace(use, use->InputAt(0));
146 }
else if (use->opcode() == IrOpcode::kLoopExit &&
147 use->InputAt(1) == node) {
152 }
else if (use->opcode() == IrOpcode::kTerminate) {
153 DCHECK_EQ(IrOpcode::kLoop, node->opcode());
154 Replace(use,
dead());
157 for (
Node* loop_exit : loop_exits) {
158 loop_exit->ReplaceInput(1,
dead());
161 return Replace(node->InputAt(0));
166 if (live_input_count < inputs.
count()) {
168 for (
Node*
const use : node->
uses()) {
170 use->ReplaceInput(live_input_count, node);
176 return Changed(node);
182 DCHECK_EQ(IrOpcode::kLoopExit, node->opcode());
183 for (
Node*
const use : node->
uses()) {
184 if (use->opcode() == IrOpcode::kLoopExitValue ||
185 use->opcode() == IrOpcode::kLoopExitEffect) {
186 Replace(use, use->InputAt(0));
190 Replace(node, control);
191 return Replace(control);
196 int const effect_input_count = node->op()->EffectInputCount();
197 int const control_input_count = node->op()->ControlInputCount();
199 if (control_input_count == 1) {
201 if (reduction.Changed())
return reduction;
203 if (effect_input_count == 0 &&
204 (control_input_count == 0 || node->op()->ControlOutputCount() == 0)) {
207 if (effect_input_count > 0) {
214 DCHECK_EQ(IrOpcode::kPhi, node->opcode());
216 if (reduction.Changed())
return reduction;
222 int input_count = node->op()->ValueInputCount();
223 for (
int i = 0;
i < input_count; ++
i) {
225 if (input->opcode() == IrOpcode::kDeadValue &&
234 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
236 if (reduction.Changed())
return reduction;
240 merge->
opcode() == IrOpcode::kLoop);
241 int input_count = node->op()->EffectInputCount();
242 for (
int i = 0;
i < input_count; ++
i) {
244 if (effect->opcode() == IrOpcode::kUnreachable) {
254 reduction = Changed(node);
261 DCHECK_EQ(0, node->op()->EffectInputCount());
262 if (node->opcode() == IrOpcode::kDeadValue)
return NoChange();
263 if (
Node* input = FindDeadInput(node)) {
270 DCHECK(node->opcode() == IrOpcode::kUnreachable ||
271 node->opcode() == IrOpcode::kIfException);
273 if (reduction.Changed())
return reduction;
275 if (effect->opcode() == IrOpcode::kDead) {
276 return Replace(effect);
278 if (effect->opcode() == IrOpcode::kUnreachable) {
279 return Replace(effect);
285 DCHECK_EQ(1, node->op()->EffectInputCount());
287 if (effect->opcode() == IrOpcode::kDead) {
288 return Replace(effect);
290 if (
Node* input = FindDeadInput(node)) {
291 if (effect->opcode() == IrOpcode::kUnreachable) {
292 RelaxEffectsAndControls(node);
296 Node* control = node->
op()->ControlInputCount() == 1
302 ReplaceWithValue(node,
DeadValue(input), node, control);
303 return Replace(unreachable);
311 DCHECK(node->opcode() == IrOpcode::kDeoptimize ||
312 node->opcode() == IrOpcode::kReturn ||
313 node->opcode() == IrOpcode::kTerminate ||
314 node->opcode() == IrOpcode::kTailCall);
316 if (reduction.Changed())
return reduction;
319 if (node->opcode() != IrOpcode::kTerminate &&
320 FindDeadInput(node) !=
nullptr) {
323 if (effect->opcode() != IrOpcode::kUnreachable) {
327 node->TrimInputCount(2);
328 node->ReplaceInput(0, effect);
329 node->ReplaceInput(1, control);
331 return Changed(node);
339 if (control->
opcode() == IrOpcode::kDead ||
340 loop->
opcode() == IrOpcode::kDead) {
347 DCHECK(node->opcode() == IrOpcode::kBranch ||
348 node->opcode() == IrOpcode::kSwitch);
350 if (reduction.Changed())
return reduction;
352 if (
condition->opcode() == IrOpcode::kDeadValue) {
357 size_t const projection_cnt = node->op()->ControlOutputCount();
362 return Replace(
dead());
374 if (node->opcode() == IrOpcode::kDeadValue) {
void push_back(const T &value)
T * AllocateArray(size_t length)
const Operator * ResizeMergeOrPhi(const Operator *op, int size)
Node * DeadValue(Node *none_node, MachineRepresentation rep=MachineRepresentation::kNone)
Reduction ReducePureNode(Node *node)
Reduction ReduceBranchOrSwitch(Node *node)
Reduction ReduceEffectNode(Node *node)
Reduction ReduceDeoptimizeOrReturnOrTerminateOrTailCall(Node *node)
Reduction ReduceLoopOrMerge(Node *node)
void TrimMergeOrPhi(Node *node, int size)
Reduction ReduceEnd(Node *node)
Reduction ReduceLoopExit(Node *node)
CommonOperatorBuilder *const common_
Reduction ReducePhi(Node *node)
Reduction ReduceUnreachableOrIfException(Node *node)
CommonOperatorBuilder * common() const
Reduction PropagateDeadControl(Node *node)
Reduction ReduceNode(Node *node)
Reduction Reduce(Node *node) final
Reduction ReduceEffectPhi(Node *node)
Reduction RemoveLoopExit(Node *node)
DeadCodeElimination(Editor *editor, TFGraph *graph, CommonOperatorBuilder *common, Zone *temp_zone)
static bool IsMergeOpcode(Value value)
static bool IsGraphTerminator(Value value)
static void ChangeOp(Node *node, const Operator *new_op)
static void ReplaceEffectInput(Node *node, Node *effect, int index=0)
static void ReplaceControlInput(Node *node, Node *control, int index=0)
static Type GetTypeOrAny(const Node *node)
static Node * GetEffectInput(Node *node, int index=0)
static void CollectControlProjections(Node *node, Node **proj, size_t count)
static Node * GetValueInput(Node *node, int index)
static void SetType(Node *node, Type type)
static void ReplaceValueInput(Node *node, Node *value, int index)
static bool IsPhi(Node *node)
static Node * GetControlInput(Node *node, int index=0)
constexpr IrOpcode::Value opcode() const
const Operator * op() const
static int GetTotalInputCount(const Operator *op)
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
MachineRepresentation PhiRepresentationOf(const Operator *const op)
MachineRepresentation DeadValueRepresentationOf(Operator const *op)
bool IsNone(Tagged< FieldType > obj)
#define DCHECK_LE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)