Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: src/compiler/common-operator-reducer.cc

Issue 1193833002: [turbofan] Proper dead code elimination as regular reducer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Renamed DeadControl to Dead. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/common-operator-reducer.h ('k') | src/compiler/control-reducer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/common-operator-reducer.h" 5 #include "src/compiler/common-operator-reducer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/compiler/common-operator.h" 9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph.h" 10 #include "src/compiler/graph.h"
11 #include "src/compiler/machine-operator.h" 11 #include "src/compiler/machine-operator.h"
12 #include "src/compiler/node.h" 12 #include "src/compiler/node.h"
13 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/node-matchers.h"
14 14
15 namespace v8 { 15 namespace v8 {
16 namespace internal { 16 namespace internal {
17 namespace compiler { 17 namespace compiler {
18 18
19 namespace {
20
21 enum class Decision { kUnknown, kTrue, kFalse };
22
23 Decision DecideCondition(Node* const cond) {
24 switch (cond->opcode()) {
25 case IrOpcode::kInt32Constant: {
26 Int32Matcher mcond(cond);
27 return mcond.Value() ? Decision::kTrue : Decision::kFalse;
28 }
29 case IrOpcode::kInt64Constant: {
30 Int64Matcher mcond(cond);
31 return mcond.Value() ? Decision::kTrue : Decision::kFalse;
32 }
33 case IrOpcode::kHeapConstant: {
34 HeapObjectMatcher<HeapObject> mcond(cond);
35 return mcond.Value().handle()->BooleanValue() ? Decision::kTrue
36 : Decision::kFalse;
37 }
38 default:
39 return Decision::kUnknown;
40 }
41 }
42
43 } // namespace
44
45
19 Reduction CommonOperatorReducer::Reduce(Node* node) { 46 Reduction CommonOperatorReducer::Reduce(Node* node) {
20 switch (node->opcode()) { 47 switch (node->opcode()) {
48 case IrOpcode::kBranch:
49 return ReduceBranch(node);
50 case IrOpcode::kMerge:
51 return ReduceMerge(node);
21 case IrOpcode::kEffectPhi: 52 case IrOpcode::kEffectPhi:
22 return ReduceEffectPhi(node); 53 return ReduceEffectPhi(node);
23 case IrOpcode::kPhi: 54 case IrOpcode::kPhi:
24 return ReducePhi(node); 55 return ReducePhi(node);
25 case IrOpcode::kSelect: 56 case IrOpcode::kSelect:
26 return ReduceSelect(node); 57 return ReduceSelect(node);
27 default: 58 default:
28 break; 59 break;
29 } 60 }
30 return NoChange(); 61 return NoChange();
31 } 62 }
32 63
33 64
65 Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
66 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
67 Node* const cond = node->InputAt(0);
68 Decision const decision = DecideCondition(cond);
69 if (decision == Decision::kUnknown) return NoChange();
70 Node* const control = node->InputAt(1);
71 node->set_op(common()->Dead());
72 node->TrimInputCount(0);
73 for (Node* const use : node->uses()) {
74 switch (use->opcode()) {
75 case IrOpcode::kIfTrue:
76 Replace(use, (decision == Decision::kTrue) ? control : node);
77 break;
78 case IrOpcode::kIfFalse:
79 Replace(use, (decision == Decision::kFalse) ? control : node);
80 break;
81 default:
82 UNREACHABLE();
83 }
84 }
85 return Changed(node);
86 }
87
88
89 Reduction CommonOperatorReducer::ReduceMerge(Node* node) {
90 DCHECK_EQ(IrOpcode::kMerge, node->opcode());
91 //
92 // Check if this is a merge that belongs to an unused diamond, which means
93 // that:
94 //
95 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and
96 // b) the {Merge} has two inputs, one {IfTrue} and one {IfFalse}, which are
97 // both owned by the Merge, and
98 // c) and the {IfTrue} and {IfFalse} nodes point to the same {Branch}.
99 //
100 if (node->InputCount() == 2) {
101 for (Node* const use : node->uses()) {
102 if (IrOpcode::IsPhiOpcode(use->opcode())) return NoChange();
103 }
104 Node* if_true = node->InputAt(0);
105 Node* if_false = node->InputAt(1);
106 if (if_true->opcode() != IrOpcode::kIfTrue) std::swap(if_true, if_false);
107 if (if_true->opcode() == IrOpcode::kIfTrue &&
108 if_false->opcode() == IrOpcode::kIfFalse &&
109 if_true->InputAt(0) == if_false->InputAt(0) && if_true->OwnedBy(node) &&
110 if_false->OwnedBy(node)) {
111 Node* const branch = if_true->InputAt(0);
112 DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
113 DCHECK(branch->OwnedBy(if_true, if_false));
114 Node* const control = branch->InputAt(1);
115 // Mark the {branch} as {Dead}.
116 branch->set_op(common()->Dead());
117 branch->TrimInputCount(0);
118 return Replace(control);
119 }
120 }
121 return NoChange();
122 }
123
124
34 Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { 125 Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) {
35 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); 126 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
36 int const input_count = node->InputCount() - 1; 127 int const input_count = node->InputCount() - 1;
37 DCHECK_LE(1, input_count); 128 DCHECK_LE(1, input_count);
38 Node* const merge = node->InputAt(input_count); 129 Node* const merge = node->InputAt(input_count);
39 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); 130 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
40 DCHECK_EQ(input_count, merge->InputCount()); 131 DCHECK_EQ(input_count, merge->InputCount());
41 Node* const effect = node->InputAt(0); 132 Node* const effect = node->InputAt(0);
42 DCHECK_NE(node, effect); 133 DCHECK_NE(node, effect);
43 for (int i = 1; i < input_count; ++i) { 134 for (int i = 1; i < input_count; ++i) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 return Replace(value); 230 return Replace(value);
140 } 231 }
141 232
142 233
143 Reduction CommonOperatorReducer::ReduceSelect(Node* node) { 234 Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
144 DCHECK_EQ(IrOpcode::kSelect, node->opcode()); 235 DCHECK_EQ(IrOpcode::kSelect, node->opcode());
145 Node* const cond = node->InputAt(0); 236 Node* const cond = node->InputAt(0);
146 Node* const vtrue = node->InputAt(1); 237 Node* const vtrue = node->InputAt(1);
147 Node* const vfalse = node->InputAt(2); 238 Node* const vfalse = node->InputAt(2);
148 if (vtrue == vfalse) return Replace(vtrue); 239 if (vtrue == vfalse) return Replace(vtrue);
240 switch (DecideCondition(cond)) {
241 case Decision::kTrue:
242 return Replace(vtrue);
243 case Decision::kFalse:
244 return Replace(vfalse);
245 case Decision::kUnknown:
246 break;
247 }
149 switch (cond->opcode()) { 248 switch (cond->opcode()) {
150 case IrOpcode::kHeapConstant: {
151 HeapObjectMatcher<HeapObject> mcond(cond);
152 return Replace(mcond.Value().handle()->BooleanValue() ? vtrue : vfalse);
153 }
154 case IrOpcode::kFloat32LessThan: { 249 case IrOpcode::kFloat32LessThan: {
155 Float32BinopMatcher mcond(cond); 250 Float32BinopMatcher mcond(cond);
156 if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) && 251 if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) &&
157 vfalse->opcode() == IrOpcode::kFloat32Sub) { 252 vfalse->opcode() == IrOpcode::kFloat32Sub) {
158 Float32BinopMatcher mvfalse(vfalse); 253 Float32BinopMatcher mvfalse(vfalse);
159 if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { 254 if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
160 return Change(node, machine()->Float32Abs(), vtrue); 255 return Change(node, machine()->Float32Abs(), vtrue);
161 } 256 }
162 } 257 }
163 if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && 258 if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 node->set_op(op); 303 node->set_op(op);
209 node->ReplaceInput(0, a); 304 node->ReplaceInput(0, a);
210 node->ReplaceInput(1, b); 305 node->ReplaceInput(1, b);
211 node->TrimInputCount(2); 306 node->TrimInputCount(2);
212 return Changed(node); 307 return Changed(node);
213 } 308 }
214 309
215 } // namespace compiler 310 } // namespace compiler
216 } // namespace internal 311 } // namespace internal
217 } // namespace v8 312 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/common-operator-reducer.h ('k') | src/compiler/control-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698