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

Side by Side Diff: test/cctest/compiler/test-osr.cc

Issue 920573004: [turbofan] Fix control reducer for dead loops. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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 | « test/cctest/compiler/test-control-reducer.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/codegen.h" 5 #include "src/codegen.h"
6 #include "src/compiler/all-nodes.h"
6 #include "src/compiler/common-operator.h" 7 #include "src/compiler/common-operator.h"
7 #include "src/compiler/diamond.h" 8 #include "src/compiler/diamond.h"
8 #include "src/compiler/graph.h" 9 #include "src/compiler/graph.h"
9 #include "src/compiler/js-graph.h" 10 #include "src/compiler/js-graph.h"
10 #include "src/compiler/js-operator.h" 11 #include "src/compiler/js-operator.h"
11 #include "src/compiler/operator.h" 12 #include "src/compiler/operator.h"
12 #include "src/compiler/osr.h" 13 #include "src/compiler/osr.h"
13 #include "test/cctest/cctest.h" 14 #include "test/cctest/cctest.h"
14 15
15 using namespace v8::internal; 16 using namespace v8::internal;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 for (int i = 0; i < loop->InputCount(); i++) { 106 for (int i = 0; i < loop->InputCount(); i++) {
106 if (loop->InputAt(i) == self) loop->ReplaceInput(i, loop); 107 if (loop->InputAt(i) == self) loop->ReplaceInput(i, loop);
107 } 108 }
108 109
109 return loop; 110 return loop;
110 } 111 }
111 112
112 Node* NewOsrLoop(int num_backedges, Node* entry = NULL) { 113 Node* NewOsrLoop(int num_backedges, Node* entry = NULL) {
113 return NewLoop(true, num_backedges, entry); 114 return NewLoop(true, num_backedges, entry);
114 } 115 }
116
117 void DeconstructOsr() {
118 OsrHelper helper(0, 0);
119 helper.Deconstruct(&jsgraph, &common, main_zone());
120 AllNodes nodes(main_zone(), &graph);
121 // Should be edited out.
122 CHECK(!nodes.IsLive(osr_normal_entry));
123 CHECK(!nodes.IsLive(osr_loop_entry));
124 // No dangling nodes should be left over.
125 CHECK_EQ(0u, nodes.gray.size());
126 }
115 }; 127 };
116 128
117 129
118 TEST(Deconstruct_osr0) { 130 TEST(Deconstruct_osr0) {
119 OsrDeconstructorTester T(0); 131 OsrDeconstructorTester T(0);
120 132
121 Node* loop = T.NewOsrLoop(1); 133 Node* loop = T.NewOsrLoop(1);
122 134
123 T.graph.SetEnd(loop); 135 T.graph.SetEnd(loop);
124 136
125 OsrHelper helper(0, 0); 137 T.DeconstructOsr();
126 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
127 138
128 CheckInputs(loop, T.start, loop); 139 CheckInputs(loop, T.start, loop);
129 } 140 }
130 141
131 142
132 TEST(Deconstruct_osr1) { 143 TEST(Deconstruct_osr1) {
133 OsrDeconstructorTester T(1); 144 OsrDeconstructorTester T(1);
134 145
135 Node* loop = T.NewOsrLoop(1); 146 Node* loop = T.NewOsrLoop(1);
136 Node* osr_phi = 147 Node* osr_phi =
137 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant()); 148 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
138 149
139 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop); 150 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop);
140 T.graph.SetEnd(ret); 151 T.graph.SetEnd(ret);
141 152
142 OsrHelper helper(0, 0); 153 T.DeconstructOsr();
143 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
144 154
145 CheckInputs(loop, T.start, loop); 155 CheckInputs(loop, T.start, loop);
146 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop); 156 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
147 CheckInputs(ret, osr_phi, T.start, loop); 157 CheckInputs(ret, osr_phi, T.start, loop);
148 } 158 }
149 159
150 160
151 TEST(Deconstruct_osr_remove_prologue) { 161 TEST(Deconstruct_osr_remove_prologue) {
152 OsrDeconstructorTester T(1); 162 OsrDeconstructorTester T(1);
153 Diamond d(&T.graph, &T.common, T.p0); 163 Diamond d(&T.graph, &T.common, T.p0);
154 d.Chain(T.osr_normal_entry); 164 d.Chain(T.osr_normal_entry);
155 165
156 Node* loop = T.NewOsrLoop(1, d.merge); 166 Node* loop = T.NewOsrLoop(1, d.merge);
157 Node* osr_phi = 167 Node* osr_phi =
158 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant()); 168 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
159 169
160 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop); 170 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop);
161 T.graph.SetEnd(ret); 171 T.graph.SetEnd(ret);
162 172
163 OsrHelper helper(0, 0); 173 T.DeconstructOsr();
164 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
165 174
166 CheckInputs(loop, T.start, loop); 175 CheckInputs(loop, T.start, loop);
167 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop); 176 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
168 CheckInputs(ret, osr_phi, T.start, loop); 177 CheckInputs(ret, osr_phi, T.start, loop);
169 178
170 // The control before the loop should have been removed. 179 // The control before the loop should have been removed.
171 CHECK(d.branch->IsDead()); 180 AllNodes nodes(T.main_zone(), &T.graph);
172 CHECK(d.if_true->IsDead()); 181 CHECK(!nodes.IsLive(d.branch));
173 CHECK(d.if_false->IsDead()); 182 CHECK(!nodes.IsLive(d.if_true));
174 CHECK(d.merge->IsDead()); 183 CHECK(!nodes.IsLive(d.if_false));
184 CHECK(!nodes.IsLive(d.merge));
175 } 185 }
176 186
177 187
178 TEST(Deconstruct_osr_with_body1) { 188 TEST(Deconstruct_osr_with_body1) {
179 OsrDeconstructorTester T(1); 189 OsrDeconstructorTester T(1);
180 190
181 Node* loop = T.NewOsrLoop(1); 191 Node* loop = T.NewOsrLoop(1);
182 192
183 Node* branch = T.graph.NewNode(T.common.Branch(), T.p0, loop); 193 Node* branch = T.graph.NewNode(T.common.Branch(), T.p0, loop);
184 Node* if_true = T.graph.NewNode(T.common.IfTrue(), branch); 194 Node* if_true = T.graph.NewNode(T.common.IfTrue(), branch);
185 Node* if_false = T.graph.NewNode(T.common.IfFalse(), branch); 195 Node* if_false = T.graph.NewNode(T.common.IfFalse(), branch);
186 loop->ReplaceInput(2, if_true); 196 loop->ReplaceInput(2, if_true);
187 197
188 Node* osr_phi = 198 Node* osr_phi =
189 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant()); 199 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
190 200
191 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, if_false); 201 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, if_false);
192 T.graph.SetEnd(ret); 202 T.graph.SetEnd(ret);
193 203
194 OsrHelper helper(0, 0); 204 T.DeconstructOsr();
195 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
196 205
197 CheckInputs(loop, T.start, if_true); 206 CheckInputs(loop, T.start, if_true);
198 CheckInputs(branch, T.p0, loop); 207 CheckInputs(branch, T.p0, loop);
199 CheckInputs(if_true, branch); 208 CheckInputs(if_true, branch);
200 CheckInputs(if_false, branch); 209 CheckInputs(if_false, branch);
201 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop); 210 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
202 CheckInputs(ret, osr_phi, T.start, if_false); 211 CheckInputs(ret, osr_phi, T.start, if_false);
203 } 212 }
204 213
205 214
(...skipping 12 matching lines...) Expand all
218 Node* if_false2 = T.graph.NewNode(T.common.IfFalse(), branch2); 227 Node* if_false2 = T.graph.NewNode(T.common.IfFalse(), branch2);
219 loop->ReplaceInput(2, if_true2); 228 loop->ReplaceInput(2, if_true2);
220 229
221 Node* osr_phi = 230 Node* osr_phi =
222 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant()); 231 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
223 232
224 Node* merge = T.graph.NewNode(T.common.Merge(2), if_false1, if_false2); 233 Node* merge = T.graph.NewNode(T.common.Merge(2), if_false1, if_false2);
225 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, merge); 234 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, merge);
226 T.graph.SetEnd(ret); 235 T.graph.SetEnd(ret);
227 236
228 OsrHelper helper(0, 0); 237 T.DeconstructOsr();
229 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
230 238
231 CheckInputs(loop, T.start, if_true2); 239 CheckInputs(loop, T.start, if_true2);
232 CheckInputs(branch1, T.p0, loop); 240 CheckInputs(branch1, T.p0, loop);
233 CheckInputs(branch2, T.p0, if_true1); 241 CheckInputs(branch2, T.p0, if_true1);
234 CheckInputs(if_true1, branch1); 242 CheckInputs(if_true1, branch1);
235 CheckInputs(if_false1, branch1); 243 CheckInputs(if_false1, branch1);
236 CheckInputs(if_true2, branch2); 244 CheckInputs(if_true2, branch2);
237 CheckInputs(if_false2, branch2); 245 CheckInputs(if_false2, branch2);
238 246
239 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop); 247 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
(...skipping 18 matching lines...) Expand all
258 loop->ReplaceInput(2, if_false1); 266 loop->ReplaceInput(2, if_false1);
259 loop->ReplaceInput(3, if_true2); 267 loop->ReplaceInput(3, if_true2);
260 268
261 Node* osr_phi = 269 Node* osr_phi =
262 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant(), 270 T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant(),
263 T.jsgraph.ZeroConstant()); 271 T.jsgraph.ZeroConstant());
264 272
265 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, if_false2); 273 Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, if_false2);
266 T.graph.SetEnd(ret); 274 T.graph.SetEnd(ret);
267 275
268 OsrHelper helper(0, 0); 276 T.DeconstructOsr();
269 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
270 277
271 CheckInputs(loop, T.start, if_false1, if_true2); 278 CheckInputs(loop, T.start, if_false1, if_true2);
272 CheckInputs(branch1, T.p0, loop); 279 CheckInputs(branch1, T.p0, loop);
273 CheckInputs(branch2, T.p0, if_true1); 280 CheckInputs(branch2, T.p0, if_true1);
274 CheckInputs(if_true1, branch1); 281 CheckInputs(if_true1, branch1);
275 CheckInputs(if_false1, branch1); 282 CheckInputs(if_false1, branch1);
276 CheckInputs(if_true2, branch2); 283 CheckInputs(if_true2, branch2);
277 CheckInputs(if_false2, branch2); 284 CheckInputs(if_false2, branch2);
278 285
279 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), 286 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(),
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 Node* osr_phi = inner.Phi(T.jsgraph.OneConstant(), T.osr_values[0], 342 Node* osr_phi = inner.Phi(T.jsgraph.OneConstant(), T.osr_values[0],
336 T.jsgraph.ZeroConstant()); 343 T.jsgraph.ZeroConstant());
337 inner.branch->ReplaceInput(0, osr_phi); 344 inner.branch->ReplaceInput(0, osr_phi);
338 outer_phi->ReplaceInput(1, osr_phi); 345 outer_phi->ReplaceInput(1, osr_phi);
339 346
340 Node* ret = 347 Node* ret =
341 T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit); 348 T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
342 Node* end = T.graph.NewNode(T.common.End(), ret); 349 Node* end = T.graph.NewNode(T.common.End(), ret);
343 T.graph.SetEnd(end); 350 T.graph.SetEnd(end);
344 351
345 OsrHelper helper(0, 0); 352 T.DeconstructOsr();
346 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
347 353
348 // Check structure of deconstructed graph. 354 // Check structure of deconstructed graph.
349 // Check inner OSR loop is directly connected to start. 355 // Check inner OSR loop is directly connected to start.
350 CheckInputs(inner.loop, T.start, inner.if_true); 356 CheckInputs(inner.loop, T.start, inner.if_true);
351 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop); 357 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop);
352 358
353 // Check control transfer to copy of outer loop. 359 // Check control transfer to copy of outer loop.
354 Node* new_outer_loop = FindSuccessor(inner.exit, IrOpcode::kLoop); 360 Node* new_outer_loop = FindSuccessor(inner.exit, IrOpcode::kLoop);
355 Node* new_outer_phi = FindSuccessor(new_outer_loop, IrOpcode::kPhi); 361 Node* new_outer_phi = FindSuccessor(new_outer_loop, IrOpcode::kPhi);
356 CHECK_NE(new_outer_loop, outer.loop); 362 CHECK_NE(new_outer_loop, outer.loop);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 Node* x_false = T.graph.NewNode(T.common.IfFalse(), x_branch); 409 Node* x_false = T.graph.NewNode(T.common.IfFalse(), x_branch);
404 410
405 outer.loop->ReplaceInput(1, x_true); 411 outer.loop->ReplaceInput(1, x_true);
406 outer.loop->ReplaceInput(2, x_false); 412 outer.loop->ReplaceInput(2, x_false);
407 413
408 Node* ret = 414 Node* ret =
409 T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit); 415 T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
410 Node* end = T.graph.NewNode(T.common.End(), ret); 416 Node* end = T.graph.NewNode(T.common.End(), ret);
411 T.graph.SetEnd(end); 417 T.graph.SetEnd(end);
412 418
413 OsrHelper helper(0, 0); 419 T.DeconstructOsr();
414 helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
415 420
416 // Check structure of deconstructed graph. 421 // Check structure of deconstructed graph.
417 // Check inner OSR loop is directly connected to start. 422 // Check inner OSR loop is directly connected to start.
418 CheckInputs(inner.loop, T.start, inner.if_true); 423 CheckInputs(inner.loop, T.start, inner.if_true);
419 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop); 424 CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop);
420 425
421 // Check control transfer to copy of outer loop. 426 // Check control transfer to copy of outer loop.
422 Node* new_merge = FindSuccessor(x_true, IrOpcode::kMerge); 427 Node* new_merge = FindSuccessor(x_true, IrOpcode::kMerge);
423 CHECK_EQ(new_merge, FindSuccessor(x_false, IrOpcode::kMerge)); 428 CHECK_EQ(new_merge, FindSuccessor(x_false, IrOpcode::kMerge));
424 CheckInputs(new_merge, x_true, x_false); 429 CheckInputs(new_merge, x_true, x_false);
(...skipping 23 matching lines...) Expand all
448 453
449 // Check structure of inner loop. 454 // Check structure of inner loop.
450 Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop); 455 Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
451 Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi); 456 Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
452 457
453 CheckInputs(new_inner_phi, T.jsgraph.OneConstant(), T.jsgraph.ZeroConstant(), 458 CheckInputs(new_inner_phi, T.jsgraph.OneConstant(), T.jsgraph.ZeroConstant(),
454 new_inner_loop); 459 new_inner_loop);
455 CheckInputs(new_outer_phi, new_entry_phi, new_inner_phi, 460 CheckInputs(new_outer_phi, new_entry_phi, new_inner_phi,
456 T.jsgraph.ZeroConstant(), new_outer_loop); 461 T.jsgraph.ZeroConstant(), new_outer_loop);
457 } 462 }
OLDNEW
« no previous file with comments | « test/cctest/compiler/test-control-reducer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698