5 #include "src/compiler/control-flow-optimizer.h" 7 #include "src/compiler/common-operator.h" 8 #include "src/compiler/graph.h" 9 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-properties.h" 16 ControlFlowOptimizer::ControlFlowOptimizer(Graph* graph,
17 CommonOperatorBuilder* common,
18 MachineOperatorBuilder* machine,
28 void ControlFlowOptimizer::Optimize() {
29 Enqueue(graph()->start());
30 while (!queue_.empty()) {
31 Node* node = queue_.front();
33 if (node->IsDead())
continue;
34 switch (node->opcode()) {
35 case IrOpcode::kBranch:
46 void ControlFlowOptimizer::Enqueue(Node* node) {
47 DCHECK_NOT_NULL(node);
48 if (node->IsDead() || queued_.Get(node))
return;
49 queued_.Set(node,
true);
54 void ControlFlowOptimizer::VisitNode(Node* node) {
55 for (Edge edge : node->use_edges()) {
56 if (NodeProperties::IsControlEdge(edge)) {
63 void ControlFlowOptimizer::VisitBranch(Node* node) {
64 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
65 if (TryBuildSwitch(node))
return;
70 bool ControlFlowOptimizer::TryBuildSwitch(Node* node) {
71 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
74 if (BranchHintOf(branch->op()) != BranchHint::kNone)
return false;
75 Node* cond = NodeProperties::GetValueInput(branch, 0);
76 if (cond->opcode() != IrOpcode::kWord32Equal)
return false;
77 Int32BinopMatcher m(cond);
78 Node* index = m.left().node();
79 if (!m.right().HasValue())
return false;
80 int32_t value = m.right().Value();
81 ZoneSet<int32_t> values(zone());
88 BranchMatcher matcher(branch);
89 DCHECK(matcher.Matched());
91 if_true = matcher.IfTrue();
92 if_false = matcher.IfFalse();
94 auto it = if_false->uses().begin();
95 if (it == if_false->uses().end())
break;
96 Node* branch1 = *it++;
97 if (branch1->opcode() != IrOpcode::kBranch)
break;
98 if (BranchHintOf(branch1->op()) != BranchHint::kNone)
break;
99 if (it != if_false->uses().end())
break;
100 Node* cond1 = branch1->InputAt(0);
101 if (cond1->opcode() != IrOpcode::kWord32Equal)
break;
102 Int32BinopMatcher m1(cond1);
103 if (m1.left().node() != index)
break;
104 if (!m1.right().HasValue())
break;
105 int32_t value1 = m1.right().Value();
106 if (values.find(value1) != values.end())
break;
107 DCHECK_NE(value, value1);
109 if (branch != node) {
110 branch->NullAllInputs();
111 if_true->ReplaceInput(0, node);
113 NodeProperties::ChangeOp(if_true, common()->IfValue(value, order++));
114 if_false->NullAllInputs();
119 values.insert(value);
122 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
123 DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
124 if (branch == node) {
125 DCHECK_EQ(1u, values.size());
128 DCHECK_LT(1u, values.size());
129 node->ReplaceInput(0, index);
130 NodeProperties::ChangeOp(node, common()->Switch(values.size() + 1));
131 if_true->ReplaceInput(0, node);
132 NodeProperties::ChangeOp(if_true, common()->IfValue(value, order++));
134 if_false->ReplaceInput(0, node);
135 NodeProperties::ChangeOp(if_false, common()->IfDefault());
137 branch->NullAllInputs();