OLD | NEW |
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/v8.h" | 5 #include "src/v8.h" |
6 #include "test/cctest/cctest.h" | 6 #include "test/cctest/cctest.h" |
7 | 7 |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
10 #include "src/compiler/generic-node-inl.h" | 10 #include "src/compiler/generic-node-inl.h" |
11 #include "src/compiler/generic-node.h" | 11 #include "src/compiler/generic-node.h" |
12 #include "src/compiler/graph.h" | 12 #include "src/compiler/graph.h" |
13 #include "src/compiler/graph-visualizer.h" | 13 #include "src/compiler/graph-visualizer.h" |
14 #include "src/compiler/js-operator.h" | 14 #include "src/compiler/js-operator.h" |
15 #include "src/compiler/machine-operator.h" | 15 #include "src/compiler/machine-operator.h" |
16 #include "src/compiler/node.h" | 16 #include "src/compiler/node.h" |
17 #include "src/compiler/operator.h" | 17 #include "src/compiler/operator.h" |
18 #include "src/compiler/schedule.h" | 18 #include "src/compiler/schedule.h" |
19 #include "src/compiler/scheduler.h" | 19 #include "src/compiler/scheduler.h" |
20 #include "src/compiler/simplified-operator.h" | 20 #include "src/compiler/simplified-operator.h" |
21 #include "src/compiler/verifier.h" | 21 #include "src/compiler/verifier.h" |
22 | 22 |
23 using namespace v8::internal; | 23 using namespace v8::internal; |
24 using namespace v8::internal::compiler; | 24 using namespace v8::internal::compiler; |
25 | 25 |
26 // TODO(titzer): pull RPO tests out to their own file. | 26 // TODO(titzer): pull RPO tests out to their own file. |
| 27 static void CheckRPONumbers(BasicBlockVector* order, size_t expected, |
| 28 bool loops_allowed) { |
| 29 CHECK(expected == order->size()); |
| 30 for (int i = 0; i < static_cast<int>(order->size()); i++) { |
| 31 CHECK(order->at(i)->rpo_number() == i); |
| 32 if (!loops_allowed) { |
| 33 CHECK_LT(order->at(i)->loop_end(), 0); |
| 34 CHECK_EQ(NULL, order->at(i)->loop_header()); |
| 35 } |
| 36 } |
| 37 } |
| 38 |
| 39 |
| 40 static void CheckLoop(BasicBlockVector* order, BasicBlock** blocks, |
| 41 int body_size) { |
| 42 BasicBlock* header = blocks[0]; |
| 43 CHECK_GT(header->loop_end(), 0); |
| 44 CHECK_EQ(body_size, (header->loop_end() - header->rpo_number())); |
| 45 for (int i = 0; i < body_size; i++) { |
| 46 int num = blocks[i]->rpo_number(); |
| 47 CHECK(num >= header->rpo_number() && num < header->loop_end()); |
| 48 CHECK(header->LoopContains(blocks[i])); |
| 49 CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header); |
| 50 } |
| 51 if (header->rpo_number() > 0) { |
| 52 CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header); |
| 53 } |
| 54 if (header->loop_end() < static_cast<int>(order->size())) { |
| 55 CHECK_NE(order->at(header->loop_end())->loop_header(), header); |
| 56 } |
| 57 } |
| 58 |
| 59 |
27 struct TestLoop { | 60 struct TestLoop { |
28 int count; | 61 int count; |
29 BasicBlock** nodes; | 62 BasicBlock** nodes; |
30 BasicBlock* header() { return nodes[0]; } | 63 BasicBlock* header() { return nodes[0]; } |
31 BasicBlock* last() { return nodes[count - 1]; } | 64 BasicBlock* last() { return nodes[count - 1]; } |
32 ~TestLoop() { delete[] nodes; } | 65 ~TestLoop() { delete[] nodes; } |
| 66 |
| 67 void Check(BasicBlockVector* order) { CheckLoop(order, nodes, count); } |
33 }; | 68 }; |
34 | 69 |
35 | 70 |
36 static TestLoop* CreateLoop(Schedule* schedule, int count) { | 71 static TestLoop* CreateLoop(Schedule* schedule, int count) { |
37 TestLoop* loop = new TestLoop(); | 72 TestLoop* loop = new TestLoop(); |
38 loop->count = count; | 73 loop->count = count; |
39 loop->nodes = new BasicBlock* [count]; | 74 loop->nodes = new BasicBlock* [count]; |
40 for (int i = 0; i < count; i++) { | 75 for (int i = 0; i < count; i++) { |
41 loop->nodes[i] = schedule->NewBasicBlock(); | 76 loop->nodes[i] = schedule->NewBasicBlock(); |
42 if (i > 0) schedule->AddSuccessor(loop->nodes[i - 1], loop->nodes[i]); | 77 if (i > 0) schedule->AddSuccessor(loop->nodes[i - 1], loop->nodes[i]); |
43 } | 78 } |
44 schedule->AddSuccessor(loop->nodes[count - 1], loop->nodes[0]); | 79 schedule->AddSuccessor(loop->nodes[count - 1], loop->nodes[0]); |
45 return loop; | 80 return loop; |
46 } | 81 } |
47 | 82 |
48 | 83 |
49 static void CheckRPONumbers(BasicBlockVector* order, size_t expected, | |
50 bool loops_allowed) { | |
51 CHECK(expected == order->size()); | |
52 for (int i = 0; i < static_cast<int>(order->size()); i++) { | |
53 CHECK(order->at(i)->rpo_number() == i); | |
54 if (!loops_allowed) CHECK_LT(order->at(i)->loop_end(), 0); | |
55 } | |
56 } | |
57 | |
58 | |
59 static void CheckLoopContains(BasicBlock** blocks, int body_size) { | |
60 BasicBlock* header = blocks[0]; | |
61 CHECK_GT(header->loop_end(), 0); | |
62 CHECK_EQ(body_size, (header->loop_end() - header->rpo_number())); | |
63 for (int i = 0; i < body_size; i++) { | |
64 int num = blocks[i]->rpo_number(); | |
65 CHECK(num >= header->rpo_number() && num < header->loop_end()); | |
66 CHECK(header->LoopContains(blocks[i])); | |
67 CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header); | |
68 } | |
69 } | |
70 | |
71 | |
72 static int GetScheduledNodeCount(Schedule* schedule) { | 84 static int GetScheduledNodeCount(Schedule* schedule) { |
73 int node_count = 0; | 85 int node_count = 0; |
74 for (BasicBlockVectorIter i = schedule->rpo_order()->begin(); | 86 for (BasicBlockVectorIter i = schedule->rpo_order()->begin(); |
75 i != schedule->rpo_order()->end(); ++i) { | 87 i != schedule->rpo_order()->end(); ++i) { |
76 BasicBlock* block = *i; | 88 BasicBlock* block = *i; |
77 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); | 89 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); |
78 ++j) { | 90 ++j) { |
79 ++node_count; | 91 ++node_count; |
80 } | 92 } |
81 BasicBlock::Control control = block->control(); | 93 BasicBlock::Control control = block->control(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 | 170 |
159 | 171 |
160 TEST(RPOSelfLoop) { | 172 TEST(RPOSelfLoop) { |
161 HandleAndZoneScope scope; | 173 HandleAndZoneScope scope; |
162 Schedule schedule(scope.main_zone()); | 174 Schedule schedule(scope.main_zone()); |
163 schedule.AddSuccessor(schedule.start(), schedule.start()); | 175 schedule.AddSuccessor(schedule.start(), schedule.start()); |
164 ZonePool zone_pool(scope.main_isolate()); | 176 ZonePool zone_pool(scope.main_isolate()); |
165 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 177 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
166 CheckRPONumbers(order, 1, true); | 178 CheckRPONumbers(order, 1, true); |
167 BasicBlock* loop[] = {schedule.start()}; | 179 BasicBlock* loop[] = {schedule.start()}; |
168 CheckLoopContains(loop, 1); | 180 CheckLoop(order, loop, 1); |
169 } | 181 } |
170 | 182 |
171 | 183 |
172 TEST(RPOEntryLoop) { | 184 TEST(RPOEntryLoop) { |
173 HandleAndZoneScope scope; | 185 HandleAndZoneScope scope; |
174 Schedule schedule(scope.main_zone()); | 186 Schedule schedule(scope.main_zone()); |
175 schedule.AddSuccessor(schedule.start(), schedule.end()); | 187 schedule.AddSuccessor(schedule.start(), schedule.end()); |
176 schedule.AddSuccessor(schedule.end(), schedule.start()); | 188 schedule.AddSuccessor(schedule.end(), schedule.start()); |
177 ZonePool zone_pool(scope.main_isolate()); | 189 ZonePool zone_pool(scope.main_isolate()); |
178 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 190 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
179 CheckRPONumbers(order, 2, true); | 191 CheckRPONumbers(order, 2, true); |
180 BasicBlock* loop[] = {schedule.start(), schedule.end()}; | 192 BasicBlock* loop[] = {schedule.start(), schedule.end()}; |
181 CheckLoopContains(loop, 2); | 193 CheckLoop(order, loop, 2); |
182 } | 194 } |
183 | 195 |
184 | 196 |
185 TEST(RPOEndLoop) { | 197 TEST(RPOEndLoop) { |
186 HandleAndZoneScope scope; | 198 HandleAndZoneScope scope; |
187 Schedule schedule(scope.main_zone()); | 199 Schedule schedule(scope.main_zone()); |
188 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); | 200 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); |
189 schedule.AddSuccessor(schedule.start(), loop1->header()); | 201 schedule.AddSuccessor(schedule.start(), loop1->header()); |
190 ZonePool zone_pool(scope.main_isolate()); | 202 ZonePool zone_pool(scope.main_isolate()); |
191 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 203 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
192 CheckRPONumbers(order, 3, true); | 204 CheckRPONumbers(order, 3, true); |
193 CheckLoopContains(loop1->nodes, loop1->count); | 205 loop1->Check(order); |
194 } | 206 } |
195 | 207 |
196 | 208 |
197 TEST(RPOEndLoopNested) { | 209 TEST(RPOEndLoopNested) { |
198 HandleAndZoneScope scope; | 210 HandleAndZoneScope scope; |
199 Schedule schedule(scope.main_zone()); | 211 Schedule schedule(scope.main_zone()); |
200 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); | 212 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); |
201 schedule.AddSuccessor(schedule.start(), loop1->header()); | 213 schedule.AddSuccessor(schedule.start(), loop1->header()); |
202 schedule.AddSuccessor(loop1->last(), schedule.start()); | 214 schedule.AddSuccessor(loop1->last(), schedule.start()); |
203 ZonePool zone_pool(scope.main_isolate()); | 215 ZonePool zone_pool(scope.main_isolate()); |
204 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 216 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
205 CheckRPONumbers(order, 3, true); | 217 CheckRPONumbers(order, 3, true); |
206 CheckLoopContains(loop1->nodes, loop1->count); | 218 loop1->Check(order); |
207 } | 219 } |
208 | 220 |
209 | 221 |
210 TEST(RPODiamond) { | 222 TEST(RPODiamond) { |
211 HandleAndZoneScope scope; | 223 HandleAndZoneScope scope; |
212 Schedule schedule(scope.main_zone()); | 224 Schedule schedule(scope.main_zone()); |
213 | 225 |
214 BasicBlock* A = schedule.start(); | 226 BasicBlock* A = schedule.start(); |
215 BasicBlock* B = schedule.NewBasicBlock(); | 227 BasicBlock* B = schedule.NewBasicBlock(); |
216 BasicBlock* C = schedule.NewBasicBlock(); | 228 BasicBlock* C = schedule.NewBasicBlock(); |
(...skipping 26 matching lines...) Expand all Loading... |
243 | 255 |
244 schedule.AddSuccessor(A, B); | 256 schedule.AddSuccessor(A, B); |
245 schedule.AddSuccessor(B, C); | 257 schedule.AddSuccessor(B, C); |
246 schedule.AddSuccessor(C, B); | 258 schedule.AddSuccessor(C, B); |
247 schedule.AddSuccessor(C, D); | 259 schedule.AddSuccessor(C, D); |
248 | 260 |
249 ZonePool zone_pool(scope.main_isolate()); | 261 ZonePool zone_pool(scope.main_isolate()); |
250 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 262 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
251 CheckRPONumbers(order, 4, true); | 263 CheckRPONumbers(order, 4, true); |
252 BasicBlock* loop[] = {B, C}; | 264 BasicBlock* loop[] = {B, C}; |
253 CheckLoopContains(loop, 2); | 265 CheckLoop(order, loop, 2); |
254 } | 266 } |
255 | 267 |
256 | 268 |
257 TEST(RPOLoop2) { | 269 TEST(RPOLoop2) { |
258 HandleAndZoneScope scope; | 270 HandleAndZoneScope scope; |
259 Schedule schedule(scope.main_zone()); | 271 Schedule schedule(scope.main_zone()); |
260 | 272 |
261 BasicBlock* A = schedule.start(); | 273 BasicBlock* A = schedule.start(); |
262 BasicBlock* B = schedule.NewBasicBlock(); | 274 BasicBlock* B = schedule.NewBasicBlock(); |
263 BasicBlock* C = schedule.NewBasicBlock(); | 275 BasicBlock* C = schedule.NewBasicBlock(); |
264 BasicBlock* D = schedule.end(); | 276 BasicBlock* D = schedule.end(); |
265 | 277 |
266 schedule.AddSuccessor(A, B); | 278 schedule.AddSuccessor(A, B); |
267 schedule.AddSuccessor(B, C); | 279 schedule.AddSuccessor(B, C); |
268 schedule.AddSuccessor(C, B); | 280 schedule.AddSuccessor(C, B); |
269 schedule.AddSuccessor(B, D); | 281 schedule.AddSuccessor(B, D); |
270 | 282 |
271 ZonePool zone_pool(scope.main_isolate()); | 283 ZonePool zone_pool(scope.main_isolate()); |
272 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 284 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
273 CheckRPONumbers(order, 4, true); | 285 CheckRPONumbers(order, 4, true); |
274 BasicBlock* loop[] = {B, C}; | 286 BasicBlock* loop[] = {B, C}; |
275 CheckLoopContains(loop, 2); | 287 CheckLoop(order, loop, 2); |
276 } | 288 } |
277 | 289 |
278 | 290 |
279 TEST(RPOLoopN) { | 291 TEST(RPOLoopN) { |
280 HandleAndZoneScope scope; | 292 HandleAndZoneScope scope; |
281 | 293 |
282 for (int i = 0; i < 11; i++) { | 294 for (int i = 0; i < 11; i++) { |
283 Schedule schedule(scope.main_zone()); | 295 Schedule schedule(scope.main_zone()); |
284 BasicBlock* A = schedule.start(); | 296 BasicBlock* A = schedule.start(); |
285 BasicBlock* B = schedule.NewBasicBlock(); | 297 BasicBlock* B = schedule.NewBasicBlock(); |
(...skipping 23 matching lines...) Expand all Loading... |
309 if (i == 7) schedule.AddSuccessor(C, G); | 321 if (i == 7) schedule.AddSuccessor(C, G); |
310 if (i == 8) schedule.AddSuccessor(D, G); | 322 if (i == 8) schedule.AddSuccessor(D, G); |
311 if (i == 9) schedule.AddSuccessor(E, G); | 323 if (i == 9) schedule.AddSuccessor(E, G); |
312 if (i == 10) schedule.AddSuccessor(F, G); | 324 if (i == 10) schedule.AddSuccessor(F, G); |
313 | 325 |
314 ZonePool zone_pool(scope.main_isolate()); | 326 ZonePool zone_pool(scope.main_isolate()); |
315 BasicBlockVector* order = | 327 BasicBlockVector* order = |
316 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 328 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
317 CheckRPONumbers(order, 7, true); | 329 CheckRPONumbers(order, 7, true); |
318 BasicBlock* loop[] = {B, C, D, E, F}; | 330 BasicBlock* loop[] = {B, C, D, E, F}; |
319 CheckLoopContains(loop, 5); | 331 CheckLoop(order, loop, 5); |
320 } | 332 } |
321 } | 333 } |
322 | 334 |
323 | 335 |
324 TEST(RPOLoopNest1) { | 336 TEST(RPOLoopNest1) { |
325 HandleAndZoneScope scope; | 337 HandleAndZoneScope scope; |
326 Schedule schedule(scope.main_zone()); | 338 Schedule schedule(scope.main_zone()); |
327 | 339 |
328 BasicBlock* A = schedule.start(); | 340 BasicBlock* A = schedule.start(); |
329 BasicBlock* B = schedule.NewBasicBlock(); | 341 BasicBlock* B = schedule.NewBasicBlock(); |
330 BasicBlock* C = schedule.NewBasicBlock(); | 342 BasicBlock* C = schedule.NewBasicBlock(); |
331 BasicBlock* D = schedule.NewBasicBlock(); | 343 BasicBlock* D = schedule.NewBasicBlock(); |
332 BasicBlock* E = schedule.NewBasicBlock(); | 344 BasicBlock* E = schedule.NewBasicBlock(); |
333 BasicBlock* F = schedule.end(); | 345 BasicBlock* F = schedule.end(); |
334 | 346 |
335 schedule.AddSuccessor(A, B); | 347 schedule.AddSuccessor(A, B); |
336 schedule.AddSuccessor(B, C); | 348 schedule.AddSuccessor(B, C); |
337 schedule.AddSuccessor(C, D); | 349 schedule.AddSuccessor(C, D); |
338 schedule.AddSuccessor(D, C); | 350 schedule.AddSuccessor(D, C); |
339 schedule.AddSuccessor(D, E); | 351 schedule.AddSuccessor(D, E); |
340 schedule.AddSuccessor(E, B); | 352 schedule.AddSuccessor(E, B); |
341 schedule.AddSuccessor(E, F); | 353 schedule.AddSuccessor(E, F); |
342 | 354 |
343 ZonePool zone_pool(scope.main_isolate()); | 355 ZonePool zone_pool(scope.main_isolate()); |
344 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 356 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
345 CheckRPONumbers(order, 6, true); | 357 CheckRPONumbers(order, 6, true); |
346 BasicBlock* loop1[] = {B, C, D, E}; | 358 BasicBlock* loop1[] = {B, C, D, E}; |
347 CheckLoopContains(loop1, 4); | 359 CheckLoop(order, loop1, 4); |
348 | 360 |
349 BasicBlock* loop2[] = {C, D}; | 361 BasicBlock* loop2[] = {C, D}; |
350 CheckLoopContains(loop2, 2); | 362 CheckLoop(order, loop2, 2); |
351 } | 363 } |
352 | 364 |
353 | 365 |
354 TEST(RPOLoopNest2) { | 366 TEST(RPOLoopNest2) { |
355 HandleAndZoneScope scope; | 367 HandleAndZoneScope scope; |
356 Schedule schedule(scope.main_zone()); | 368 Schedule schedule(scope.main_zone()); |
357 | 369 |
358 BasicBlock* A = schedule.start(); | 370 BasicBlock* A = schedule.start(); |
359 BasicBlock* B = schedule.NewBasicBlock(); | 371 BasicBlock* B = schedule.NewBasicBlock(); |
360 BasicBlock* C = schedule.NewBasicBlock(); | 372 BasicBlock* C = schedule.NewBasicBlock(); |
(...skipping 12 matching lines...) Expand all Loading... |
373 schedule.AddSuccessor(G, H); | 385 schedule.AddSuccessor(G, H); |
374 | 386 |
375 schedule.AddSuccessor(E, D); | 387 schedule.AddSuccessor(E, D); |
376 schedule.AddSuccessor(F, C); | 388 schedule.AddSuccessor(F, C); |
377 schedule.AddSuccessor(G, B); | 389 schedule.AddSuccessor(G, B); |
378 | 390 |
379 ZonePool zone_pool(scope.main_isolate()); | 391 ZonePool zone_pool(scope.main_isolate()); |
380 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 392 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
381 CheckRPONumbers(order, 8, true); | 393 CheckRPONumbers(order, 8, true); |
382 BasicBlock* loop1[] = {B, C, D, E, F, G}; | 394 BasicBlock* loop1[] = {B, C, D, E, F, G}; |
383 CheckLoopContains(loop1, 6); | 395 CheckLoop(order, loop1, 6); |
384 | 396 |
385 BasicBlock* loop2[] = {C, D, E, F}; | 397 BasicBlock* loop2[] = {C, D, E, F}; |
386 CheckLoopContains(loop2, 4); | 398 CheckLoop(order, loop2, 4); |
387 | 399 |
388 BasicBlock* loop3[] = {D, E}; | 400 BasicBlock* loop3[] = {D, E}; |
389 CheckLoopContains(loop3, 2); | 401 CheckLoop(order, loop3, 2); |
390 } | 402 } |
391 | 403 |
392 | 404 |
393 TEST(RPOLoopFollow1) { | 405 TEST(RPOLoopFollow1) { |
394 HandleAndZoneScope scope; | 406 HandleAndZoneScope scope; |
395 Schedule schedule(scope.main_zone()); | 407 Schedule schedule(scope.main_zone()); |
396 | 408 |
397 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | 409 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); |
398 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | 410 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); |
399 | 411 |
400 BasicBlock* A = schedule.start(); | 412 BasicBlock* A = schedule.start(); |
401 BasicBlock* E = schedule.end(); | 413 BasicBlock* E = schedule.end(); |
402 | 414 |
403 schedule.AddSuccessor(A, loop1->header()); | 415 schedule.AddSuccessor(A, loop1->header()); |
404 schedule.AddSuccessor(loop1->header(), loop2->header()); | 416 schedule.AddSuccessor(loop1->header(), loop2->header()); |
405 schedule.AddSuccessor(loop2->last(), E); | 417 schedule.AddSuccessor(loop2->last(), E); |
406 | 418 |
407 ZonePool zone_pool(scope.main_isolate()); | 419 ZonePool zone_pool(scope.main_isolate()); |
408 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 420 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
409 | 421 |
410 CheckLoopContains(loop1->nodes, loop1->count); | |
411 | |
412 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 422 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), |
413 static_cast<int>(order->size())); | 423 static_cast<int>(order->size())); |
414 CheckLoopContains(loop1->nodes, loop1->count); | 424 |
415 CheckLoopContains(loop2->nodes, loop2->count); | 425 loop1->Check(order); |
| 426 loop2->Check(order); |
416 } | 427 } |
417 | 428 |
418 | 429 |
419 TEST(RPOLoopFollow2) { | 430 TEST(RPOLoopFollow2) { |
420 HandleAndZoneScope scope; | 431 HandleAndZoneScope scope; |
421 Schedule schedule(scope.main_zone()); | 432 Schedule schedule(scope.main_zone()); |
422 | 433 |
423 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | 434 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); |
424 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | 435 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); |
425 | 436 |
426 BasicBlock* A = schedule.start(); | 437 BasicBlock* A = schedule.start(); |
427 BasicBlock* S = schedule.NewBasicBlock(); | 438 BasicBlock* S = schedule.NewBasicBlock(); |
428 BasicBlock* E = schedule.end(); | 439 BasicBlock* E = schedule.end(); |
429 | 440 |
430 schedule.AddSuccessor(A, loop1->header()); | 441 schedule.AddSuccessor(A, loop1->header()); |
431 schedule.AddSuccessor(loop1->header(), S); | 442 schedule.AddSuccessor(loop1->header(), S); |
432 schedule.AddSuccessor(S, loop2->header()); | 443 schedule.AddSuccessor(S, loop2->header()); |
433 schedule.AddSuccessor(loop2->last(), E); | 444 schedule.AddSuccessor(loop2->last(), E); |
434 | 445 |
435 ZonePool zone_pool(scope.main_isolate()); | 446 ZonePool zone_pool(scope.main_isolate()); |
436 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 447 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
437 | 448 |
438 CheckLoopContains(loop1->nodes, loop1->count); | |
439 | |
440 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 449 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), |
441 static_cast<int>(order->size())); | 450 static_cast<int>(order->size())); |
442 CheckLoopContains(loop1->nodes, loop1->count); | 451 loop1->Check(order); |
443 CheckLoopContains(loop2->nodes, loop2->count); | 452 loop2->Check(order); |
444 } | 453 } |
445 | 454 |
446 | 455 |
447 TEST(RPOLoopFollowN) { | 456 TEST(RPOLoopFollowN) { |
448 HandleAndZoneScope scope; | 457 HandleAndZoneScope scope; |
449 | 458 |
450 for (int size = 1; size < 5; size++) { | 459 for (int size = 1; size < 5; size++) { |
451 for (int exit = 0; exit < size; exit++) { | 460 for (int exit = 0; exit < size; exit++) { |
452 Schedule schedule(scope.main_zone()); | 461 Schedule schedule(scope.main_zone()); |
453 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 462 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
454 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); | 463 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); |
455 BasicBlock* A = schedule.start(); | 464 BasicBlock* A = schedule.start(); |
456 BasicBlock* E = schedule.end(); | 465 BasicBlock* E = schedule.end(); |
457 | 466 |
458 schedule.AddSuccessor(A, loop1->header()); | 467 schedule.AddSuccessor(A, loop1->header()); |
459 schedule.AddSuccessor(loop1->nodes[exit], loop2->header()); | 468 schedule.AddSuccessor(loop1->nodes[exit], loop2->header()); |
460 schedule.AddSuccessor(loop2->nodes[exit], E); | 469 schedule.AddSuccessor(loop2->nodes[exit], E); |
461 ZonePool zone_pool(scope.main_isolate()); | 470 ZonePool zone_pool(scope.main_isolate()); |
462 BasicBlockVector* order = | 471 BasicBlockVector* order = |
463 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 472 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
464 CheckLoopContains(loop1->nodes, loop1->count); | |
465 | 473 |
466 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 474 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), |
467 static_cast<int>(order->size())); | 475 static_cast<int>(order->size())); |
468 CheckLoopContains(loop1->nodes, loop1->count); | 476 loop1->Check(order); |
469 CheckLoopContains(loop2->nodes, loop2->count); | 477 loop2->Check(order); |
470 } | 478 } |
471 } | 479 } |
472 } | 480 } |
473 | 481 |
474 | 482 |
475 TEST(RPONestedLoopFollow1) { | 483 TEST(RPONestedLoopFollow1) { |
476 HandleAndZoneScope scope; | 484 HandleAndZoneScope scope; |
477 Schedule schedule(scope.main_zone()); | 485 Schedule schedule(scope.main_zone()); |
478 | 486 |
479 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); | 487 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); |
480 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); | 488 SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); |
481 | 489 |
482 BasicBlock* A = schedule.start(); | 490 BasicBlock* A = schedule.start(); |
483 BasicBlock* B = schedule.NewBasicBlock(); | 491 BasicBlock* B = schedule.NewBasicBlock(); |
484 BasicBlock* C = schedule.NewBasicBlock(); | 492 BasicBlock* C = schedule.NewBasicBlock(); |
485 BasicBlock* E = schedule.end(); | 493 BasicBlock* E = schedule.end(); |
486 | 494 |
487 schedule.AddSuccessor(A, B); | 495 schedule.AddSuccessor(A, B); |
488 schedule.AddSuccessor(B, loop1->header()); | 496 schedule.AddSuccessor(B, loop1->header()); |
489 schedule.AddSuccessor(loop1->header(), loop2->header()); | 497 schedule.AddSuccessor(loop1->header(), loop2->header()); |
490 schedule.AddSuccessor(loop2->last(), C); | 498 schedule.AddSuccessor(loop2->last(), C); |
491 schedule.AddSuccessor(C, E); | 499 schedule.AddSuccessor(C, E); |
492 schedule.AddSuccessor(C, B); | 500 schedule.AddSuccessor(C, B); |
493 | 501 |
494 ZonePool zone_pool(scope.main_isolate()); | 502 ZonePool zone_pool(scope.main_isolate()); |
495 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 503 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
496 | 504 |
497 CheckLoopContains(loop1->nodes, loop1->count); | |
498 | |
499 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), | 505 CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()), |
500 static_cast<int>(order->size())); | 506 static_cast<int>(order->size())); |
501 CheckLoopContains(loop1->nodes, loop1->count); | 507 loop1->Check(order); |
502 CheckLoopContains(loop2->nodes, loop2->count); | 508 loop2->Check(order); |
503 | 509 |
504 BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C}; | 510 BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C}; |
505 CheckLoopContains(loop3, 4); | 511 CheckLoop(order, loop3, 4); |
506 } | 512 } |
507 | 513 |
508 | 514 |
509 TEST(RPOLoopBackedges1) { | 515 TEST(RPOLoopBackedges1) { |
510 HandleAndZoneScope scope; | 516 HandleAndZoneScope scope; |
511 | 517 |
512 int size = 8; | 518 int size = 8; |
513 for (int i = 0; i < size; i++) { | 519 for (int i = 0; i < size; i++) { |
514 for (int j = 0; j < size; j++) { | 520 for (int j = 0; j < size; j++) { |
515 Schedule schedule(scope.main_zone()); | 521 Schedule schedule(scope.main_zone()); |
516 BasicBlock* A = schedule.start(); | 522 BasicBlock* A = schedule.start(); |
517 BasicBlock* E = schedule.end(); | 523 BasicBlock* E = schedule.end(); |
518 | 524 |
519 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 525 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
520 schedule.AddSuccessor(A, loop1->header()); | 526 schedule.AddSuccessor(A, loop1->header()); |
521 schedule.AddSuccessor(loop1->last(), E); | 527 schedule.AddSuccessor(loop1->last(), E); |
522 | 528 |
523 schedule.AddSuccessor(loop1->nodes[i], loop1->header()); | 529 schedule.AddSuccessor(loop1->nodes[i], loop1->header()); |
524 schedule.AddSuccessor(loop1->nodes[j], E); | 530 schedule.AddSuccessor(loop1->nodes[j], E); |
525 | 531 |
526 ZonePool zone_pool(scope.main_isolate()); | 532 ZonePool zone_pool(scope.main_isolate()); |
527 BasicBlockVector* order = | 533 BasicBlockVector* order = |
528 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 534 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
529 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 535 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
530 CheckLoopContains(loop1->nodes, loop1->count); | 536 loop1->Check(order); |
531 } | 537 } |
532 } | 538 } |
533 } | 539 } |
534 | 540 |
535 | 541 |
536 TEST(RPOLoopOutedges1) { | 542 TEST(RPOLoopOutedges1) { |
537 HandleAndZoneScope scope; | 543 HandleAndZoneScope scope; |
538 | 544 |
539 int size = 8; | 545 int size = 8; |
540 for (int i = 0; i < size; i++) { | 546 for (int i = 0; i < size; i++) { |
541 for (int j = 0; j < size; j++) { | 547 for (int j = 0; j < size; j++) { |
542 Schedule schedule(scope.main_zone()); | 548 Schedule schedule(scope.main_zone()); |
543 BasicBlock* A = schedule.start(); | 549 BasicBlock* A = schedule.start(); |
544 BasicBlock* D = schedule.NewBasicBlock(); | 550 BasicBlock* D = schedule.NewBasicBlock(); |
545 BasicBlock* E = schedule.end(); | 551 BasicBlock* E = schedule.end(); |
546 | 552 |
547 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 553 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
548 schedule.AddSuccessor(A, loop1->header()); | 554 schedule.AddSuccessor(A, loop1->header()); |
549 schedule.AddSuccessor(loop1->last(), E); | 555 schedule.AddSuccessor(loop1->last(), E); |
550 | 556 |
551 schedule.AddSuccessor(loop1->nodes[i], loop1->header()); | 557 schedule.AddSuccessor(loop1->nodes[i], loop1->header()); |
552 schedule.AddSuccessor(loop1->nodes[j], D); | 558 schedule.AddSuccessor(loop1->nodes[j], D); |
553 schedule.AddSuccessor(D, E); | 559 schedule.AddSuccessor(D, E); |
554 | 560 |
555 ZonePool zone_pool(scope.main_isolate()); | 561 ZonePool zone_pool(scope.main_isolate()); |
556 BasicBlockVector* order = | 562 BasicBlockVector* order = |
557 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 563 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
558 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 564 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
559 CheckLoopContains(loop1->nodes, loop1->count); | 565 loop1->Check(order); |
560 } | 566 } |
561 } | 567 } |
562 } | 568 } |
563 | 569 |
564 | 570 |
565 TEST(RPOLoopOutedges2) { | 571 TEST(RPOLoopOutedges2) { |
566 HandleAndZoneScope scope; | 572 HandleAndZoneScope scope; |
567 | 573 |
568 int size = 8; | 574 int size = 8; |
569 for (int i = 0; i < size; i++) { | 575 for (int i = 0; i < size; i++) { |
570 Schedule schedule(scope.main_zone()); | 576 Schedule schedule(scope.main_zone()); |
571 BasicBlock* A = schedule.start(); | 577 BasicBlock* A = schedule.start(); |
572 BasicBlock* E = schedule.end(); | 578 BasicBlock* E = schedule.end(); |
573 | 579 |
574 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 580 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
575 schedule.AddSuccessor(A, loop1->header()); | 581 schedule.AddSuccessor(A, loop1->header()); |
576 schedule.AddSuccessor(loop1->last(), E); | 582 schedule.AddSuccessor(loop1->last(), E); |
577 | 583 |
578 for (int j = 0; j < size; j++) { | 584 for (int j = 0; j < size; j++) { |
579 BasicBlock* O = schedule.NewBasicBlock(); | 585 BasicBlock* O = schedule.NewBasicBlock(); |
580 schedule.AddSuccessor(loop1->nodes[j], O); | 586 schedule.AddSuccessor(loop1->nodes[j], O); |
581 schedule.AddSuccessor(O, E); | 587 schedule.AddSuccessor(O, E); |
582 } | 588 } |
583 | 589 |
584 ZonePool zone_pool(scope.main_isolate()); | 590 ZonePool zone_pool(scope.main_isolate()); |
585 BasicBlockVector* order = | 591 BasicBlockVector* order = |
586 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 592 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
587 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 593 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
588 CheckLoopContains(loop1->nodes, loop1->count); | 594 loop1->Check(order); |
589 } | 595 } |
590 } | 596 } |
591 | 597 |
592 | 598 |
593 TEST(RPOLoopOutloops1) { | 599 TEST(RPOLoopOutloops1) { |
594 HandleAndZoneScope scope; | 600 HandleAndZoneScope scope; |
595 | 601 |
596 int size = 8; | 602 int size = 8; |
597 for (int i = 0; i < size; i++) { | 603 for (int i = 0; i < size; i++) { |
598 Schedule schedule(scope.main_zone()); | 604 Schedule schedule(scope.main_zone()); |
599 BasicBlock* A = schedule.start(); | 605 BasicBlock* A = schedule.start(); |
600 BasicBlock* E = schedule.end(); | 606 BasicBlock* E = schedule.end(); |
601 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); | 607 SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); |
602 schedule.AddSuccessor(A, loop1->header()); | 608 schedule.AddSuccessor(A, loop1->header()); |
603 schedule.AddSuccessor(loop1->last(), E); | 609 schedule.AddSuccessor(loop1->last(), E); |
604 | 610 |
605 TestLoop** loopN = new TestLoop* [size]; | 611 TestLoop** loopN = new TestLoop* [size]; |
606 for (int j = 0; j < size; j++) { | 612 for (int j = 0; j < size; j++) { |
607 loopN[j] = CreateLoop(&schedule, 2); | 613 loopN[j] = CreateLoop(&schedule, 2); |
608 schedule.AddSuccessor(loop1->nodes[j], loopN[j]->header()); | 614 schedule.AddSuccessor(loop1->nodes[j], loopN[j]->header()); |
609 schedule.AddSuccessor(loopN[j]->last(), E); | 615 schedule.AddSuccessor(loopN[j]->last(), E); |
610 } | 616 } |
611 | 617 |
612 ZonePool zone_pool(scope.main_isolate()); | 618 ZonePool zone_pool(scope.main_isolate()); |
613 BasicBlockVector* order = | 619 BasicBlockVector* order = |
614 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 620 Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
615 CheckRPONumbers(order, schedule.BasicBlockCount(), true); | 621 CheckRPONumbers(order, schedule.BasicBlockCount(), true); |
616 CheckLoopContains(loop1->nodes, loop1->count); | 622 loop1->Check(order); |
617 | 623 |
618 for (int j = 0; j < size; j++) { | 624 for (int j = 0; j < size; j++) { |
619 CheckLoopContains(loopN[j]->nodes, loopN[j]->count); | 625 loopN[j]->Check(order); |
620 delete loopN[j]; | 626 delete loopN[j]; |
621 } | 627 } |
622 delete[] loopN; | 628 delete[] loopN; |
623 } | 629 } |
624 } | 630 } |
625 | 631 |
626 | 632 |
627 TEST(RPOLoopMultibackedge) { | 633 TEST(RPOLoopMultibackedge) { |
628 HandleAndZoneScope scope; | 634 HandleAndZoneScope scope; |
629 Schedule schedule(scope.main_zone()); | 635 Schedule schedule(scope.main_zone()); |
(...skipping 10 matching lines...) Expand all Loading... |
640 schedule.AddSuccessor(B, E); | 646 schedule.AddSuccessor(B, E); |
641 schedule.AddSuccessor(C, B); | 647 schedule.AddSuccessor(C, B); |
642 schedule.AddSuccessor(D, B); | 648 schedule.AddSuccessor(D, B); |
643 schedule.AddSuccessor(E, B); | 649 schedule.AddSuccessor(E, B); |
644 | 650 |
645 ZonePool zone_pool(scope.main_isolate()); | 651 ZonePool zone_pool(scope.main_isolate()); |
646 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); | 652 BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); |
647 CheckRPONumbers(order, 5, true); | 653 CheckRPONumbers(order, 5, true); |
648 | 654 |
649 BasicBlock* loop1[] = {B, C, D, E}; | 655 BasicBlock* loop1[] = {B, C, D, E}; |
650 CheckLoopContains(loop1, 4); | 656 CheckLoop(order, loop1, 4); |
651 } | 657 } |
652 | 658 |
653 | 659 |
654 TEST(BuildScheduleEmpty) { | 660 TEST(BuildScheduleEmpty) { |
655 HandleAndZoneScope scope; | 661 HandleAndZoneScope scope; |
656 Graph graph(scope.main_zone()); | 662 Graph graph(scope.main_zone()); |
657 CommonOperatorBuilder builder(scope.main_zone()); | 663 CommonOperatorBuilder builder(scope.main_zone()); |
658 graph.SetStart(graph.NewNode(builder.Start(0))); | 664 graph.SetStart(graph.NewNode(builder.Start(0))); |
659 graph.SetEnd(graph.NewNode(builder.End(), graph.start())); | 665 graph.SetEnd(graph.NewNode(builder.End(), graph.start())); |
660 | 666 |
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1909 graph.SetEnd(end); | 1915 graph.SetEnd(end); |
1910 | 1916 |
1911 Schedule* schedule = ComputeAndVerifySchedule(5, &graph); | 1917 Schedule* schedule = ComputeAndVerifySchedule(5, &graph); |
1912 BasicBlock* block = schedule->block(loop); | 1918 BasicBlock* block = schedule->block(loop); |
1913 CHECK_NE(NULL, loop); | 1919 CHECK_NE(NULL, loop); |
1914 CHECK_EQ(block, schedule->block(effect)); | 1920 CHECK_EQ(block, schedule->block(effect)); |
1915 CHECK_GE(block->rpo_number(), 0); | 1921 CHECK_GE(block->rpo_number(), 0); |
1916 } | 1922 } |
1917 | 1923 |
1918 #endif | 1924 #endif |
OLD | NEW |