OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/control-reducer.h" | 5 #include "src/compiler/control-reducer.h" |
6 #include "src/compiler/graph-visualizer.h" | |
6 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" |
9 #include "src/compiler/node.h" | 10 #include "src/compiler/node.h" |
10 #include "test/unittests/compiler/graph-unittest.h" | 11 #include "test/unittests/compiler/graph-unittest.h" |
11 #include "test/unittests/compiler/node-test-utils.h" | 12 #include "test/unittests/compiler/node-test-utils.h" |
12 #include "testing/gmock-support.h" | 13 #include "testing/gmock-support.h" |
13 | 14 |
14 using testing::_; | 15 using testing::_; |
15 using testing::AllOf; | 16 using testing::AllOf; |
16 using testing::Capture; | 17 using testing::Capture; |
17 using testing::CaptureEq; | 18 using testing::CaptureEq; |
18 | 19 |
19 namespace v8 { | 20 namespace v8 { |
20 namespace internal { | 21 namespace internal { |
21 namespace compiler { | 22 namespace compiler { |
22 | 23 |
23 class ControlReducerTest : public GraphTest { | 24 class ControlReducerTest : public GraphTest { |
25 public: | |
26 ControlReducerTest() | |
27 : GraphTest(), | |
Michael Starzinger
2015/04/02 11:59:34
nit: The default constructor should be implicitly
titzer
2015/04/02 12:35:48
I've taken your suggestion of extending TypeGraphT
| |
28 machine_(zone()), | |
29 javascript_(zone()), | |
30 jsgraph_(isolate(), graph(), common(), &javascript_, &machine_) {} | |
31 | |
24 protected: | 32 protected: |
33 MachineOperatorBuilder machine_; | |
34 JSOperatorBuilder javascript_; | |
35 JSGraph jsgraph_; | |
36 | |
25 void ReduceGraph() { | 37 void ReduceGraph() { |
26 JSOperatorBuilder javascript(zone()); | 38 if (FLAG_trace_turbo_graph) { |
27 MachineOperatorBuilder machine(zone()); | 39 OFStream os(stdout); |
28 JSGraph jsgraph(isolate(), graph(), common(), &javascript, &machine); | 40 os << "-- Graph before control reduction" << std::endl; |
29 ControlReducer::ReduceGraph(zone(), &jsgraph, common()); | 41 os << AsRPO(*graph()); |
42 } | |
43 ControlReducer::ReduceGraph(zone(), jsgraph(), common()); | |
44 if (FLAG_trace_turbo_graph) { | |
45 OFStream os(stdout); | |
46 os << "-- Graph after control reduction" << std::endl; | |
47 os << AsRPO(*graph()); | |
48 } | |
30 } | 49 } |
50 | |
51 JSGraph* jsgraph() { return &jsgraph_; } | |
31 }; | 52 }; |
32 | 53 |
33 | 54 |
34 TEST_F(ControlReducerTest, NonTerminatingLoop) { | 55 TEST_F(ControlReducerTest, NonTerminatingLoop) { |
35 Node* loop = graph()->NewNode(common()->Loop(2), graph()->start()); | 56 Node* loop = graph()->NewNode(common()->Loop(2), graph()->start()); |
36 loop->AppendInput(graph()->zone(), loop); | 57 loop->AppendInput(graph()->zone(), loop); |
37 ReduceGraph(); | 58 ReduceGraph(); |
38 Capture<Node*> branch; | 59 Capture<Node*> branch; |
39 EXPECT_THAT( | 60 EXPECT_THAT( |
40 graph()->end(), | 61 graph()->end(), |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 graph()->end(), | 133 graph()->end(), |
113 IsEnd(IsReturn( | 134 IsEnd(IsReturn( |
114 IsUndefinedConstant(), graph()->start(), | 135 IsUndefinedConstant(), graph()->start(), |
115 IsIfFalse(AllOf( | 136 IsIfFalse(AllOf( |
116 CaptureEq(&branch), | 137 CaptureEq(&branch), |
117 IsBranch(IsAlways(), | 138 IsBranch(IsAlways(), |
118 AllOf(loop, IsLoop(graph()->start(), | 139 AllOf(loop, IsLoop(graph()->start(), |
119 IsIfTrue(CaptureEq(&branch)))))))))); | 140 IsIfTrue(CaptureEq(&branch)))))))))); |
120 } | 141 } |
121 | 142 |
143 | |
144 TEST_F(ControlReducerTest, PhiAsInputToBranch_true) { | |
145 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
146 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
147 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
148 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
149 Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
150 Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
151 jsgraph()->Int32Constant(1), | |
152 jsgraph()->Int32Constant(2), merge1); | |
153 | |
154 Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1); | |
155 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
156 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
157 Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
158 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
159 jsgraph()->Int32Constant(11), | |
160 jsgraph()->Int32Constant(22), merge2); | |
161 | |
162 Node* ret = | |
163 graph()->NewNode(common()->Return(), result, graph()->start(), merge2); | |
164 graph()->end()->ReplaceInput(0, ret); | |
165 | |
166 ReduceGraph(); | |
167 | |
168 // First diamond is not reduced. | |
169 EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))); | |
170 | |
171 // Second diamond should be folded away. | |
172 EXPECT_THAT(graph()->end(), | |
173 IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), merge1))); | |
174 } | |
175 | |
176 | |
177 TEST_F(ControlReducerTest, PhiAsInputToBranch_false) { | |
178 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
179 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
180 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
181 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
182 Node* merge1 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
183 Node* phi1 = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
184 jsgraph()->Int32Constant(0), | |
185 jsgraph()->BooleanConstant(false), merge1); | |
186 | |
187 Node* branch2 = graph()->NewNode(common()->Branch(), phi1, merge1); | |
188 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); | |
189 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); | |
190 Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); | |
191 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
192 jsgraph()->Int32Constant(11), | |
193 jsgraph()->Int32Constant(22), merge2); | |
194 | |
195 Node* ret = | |
196 graph()->NewNode(common()->Return(), result, graph()->start(), merge2); | |
197 graph()->end()->ReplaceInput(0, ret); | |
198 | |
199 ReduceGraph(); | |
200 | |
201 // First diamond is not reduced. | |
202 EXPECT_THAT(merge1, IsMerge(IsIfTrue(branch1), IsIfFalse(branch1))); | |
203 | |
204 // Second diamond should be folded away. | |
205 EXPECT_THAT(graph()->end(), | |
206 IsEnd(IsReturn(IsInt32Constant(22), graph()->start(), merge1))); | |
207 } | |
208 | |
209 | |
210 TEST_F(ControlReducerTest, RangeAsInputToBranch_true1) { | |
211 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
Michael Starzinger
2015/04/02 11:59:34
nit: If ControlReducerTest would inherit form Type
titzer
2015/04/02 12:35:48
Done.
| |
212 NodeProperties::SetBounds(p0, Bounds(Type::Range(1, 2, zone()))); | |
213 | |
214 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
215 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
216 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
217 Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1); | |
218 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
219 jsgraph()->Int32Constant(11), | |
220 jsgraph()->Int32Constant(44), merge1); | |
221 | |
222 Node* ret = | |
223 graph()->NewNode(common()->Return(), result, graph()->start(), merge1); | |
224 graph()->end()->ReplaceInput(0, ret); | |
225 | |
226 ReduceGraph(); | |
227 | |
228 // Diamond should be folded away. | |
229 EXPECT_THAT( | |
230 graph()->end(), | |
231 IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start()))); | |
232 } | |
233 | |
234 | |
235 TEST_F(ControlReducerTest, RangeAsInputToBranch_true2) { | |
236 Node* p0 = graph()->NewNode(common()->Parameter(0), graph()->start()); | |
Michael Starzinger
2015/04/02 11:59:34
nit: Likewise.
titzer
2015/04/02 12:35:48
Done.
| |
237 NodeProperties::SetBounds(p0, Bounds(Type::Range(-2, -1, zone()))); | |
238 | |
239 Node* branch1 = graph()->NewNode(common()->Branch(), p0, graph()->start()); | |
240 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
241 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
242 Node* merge1 = graph()->NewNode(common()->Merge(1), if_true1, if_false1); | |
243 Node* result = graph()->NewNode(common()->Phi(kMachInt32, 2), | |
244 jsgraph()->Int32Constant(11), | |
245 jsgraph()->Int32Constant(44), merge1); | |
246 | |
247 Node* ret = | |
248 graph()->NewNode(common()->Return(), result, graph()->start(), merge1); | |
249 graph()->end()->ReplaceInput(0, ret); | |
250 | |
251 ReduceGraph(); | |
252 | |
253 // Diamond should be folded away. | |
254 EXPECT_THAT( | |
255 graph()->end(), | |
256 IsEnd(IsReturn(IsInt32Constant(11), graph()->start(), graph()->start()))); | |
257 } | |
258 | |
259 | |
122 } // namespace compiler | 260 } // namespace compiler |
123 } // namespace internal | 261 } // namespace internal |
124 } // namespace v8 | 262 } // namespace v8 |
OLD | NEW |