| 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 |