| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <deque> | 5 #include <deque> |
| 6 #include <queue> | 6 #include <queue> |
| 7 | 7 |
| 8 #include "src/compiler/scheduler.h" | 8 #include "src/compiler/scheduler.h" |
| 9 | 9 |
| 10 #include "src/bit-vector.h" | 10 #include "src/bit-vector.h" |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 } | 561 } |
| 562 | 562 |
| 563 // Computes the special reverse-post-order for a partial control flow graph, | 563 // Computes the special reverse-post-order for a partial control flow graph, |
| 564 // that is for the graph spanned between the given {entry} and {end} blocks, | 564 // that is for the graph spanned between the given {entry} and {end} blocks, |
| 565 // then updates the existing ordering with this new information. | 565 // then updates the existing ordering with this new information. |
| 566 void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) { | 566 void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) { |
| 567 DCHECK_NE(NULL, order_); // Main order to be updated is present. | 567 DCHECK_NE(NULL, order_); // Main order to be updated is present. |
| 568 ComputeAndInsertSpecialRPO(entry, end); | 568 ComputeAndInsertSpecialRPO(entry, end); |
| 569 } | 569 } |
| 570 | 570 |
| 571 // Serialize the previously computed order as an assembly order (non-deferred | |
| 572 // code first, deferred code afterwards) into the final schedule. | |
| 573 void SerializeAOIntoSchedule() { | |
| 574 int32_t number = 0; | |
| 575 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) { | |
| 576 if (b->deferred()) continue; | |
| 577 b->set_ao_number(number++); | |
| 578 } | |
| 579 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) { | |
| 580 if (!b->deferred()) continue; | |
| 581 b->set_ao_number(number++); | |
| 582 } | |
| 583 } | |
| 584 | |
| 585 // Serialize the previously computed order as a special reverse-post-order | 571 // Serialize the previously computed order as a special reverse-post-order |
| 586 // numbering for basic blocks into the final schedule. | 572 // numbering for basic blocks into the final schedule. |
| 587 void SerializeRPOIntoSchedule() { | 573 void SerializeRPOIntoSchedule() { |
| 588 int32_t number = 0; | 574 int32_t number = 0; |
| 589 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) { | 575 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) { |
| 590 b->set_rpo_number(number++); | 576 b->set_rpo_number(number++); |
| 591 schedule_->rpo_order()->push_back(b); | 577 schedule_->rpo_order()->push_back(b); |
| 592 } | 578 } |
| 593 BeyondEndSentinel()->set_rpo_number(number); | 579 BeyondEndSentinel()->set_rpo_number(number); |
| 594 } | 580 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 return depth + 1; | 627 return depth + 1; |
| 642 } | 628 } |
| 643 return depth; | 629 return depth; |
| 644 } | 630 } |
| 645 | 631 |
| 646 BasicBlock* PushFront(BasicBlock* head, BasicBlock* block) { | 632 BasicBlock* PushFront(BasicBlock* head, BasicBlock* block) { |
| 647 block->set_rpo_next(head); | 633 block->set_rpo_next(head); |
| 648 return block; | 634 return block; |
| 649 } | 635 } |
| 650 | 636 |
| 651 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that | 637 static int GetLoopNumber(BasicBlock* block) { return block->loop_number(); } |
| 652 // these numbers are only valid within this class. | |
| 653 static int GetLoopNumber(BasicBlock* block) { return block->ao_number(); } | |
| 654 static void SetLoopNumber(BasicBlock* block, int loop_number) { | 638 static void SetLoopNumber(BasicBlock* block, int loop_number) { |
| 655 return block->set_ao_number(loop_number); | 639 return block->set_loop_number(loop_number); |
| 656 } | 640 } |
| 657 static bool HasLoopNumber(BasicBlock* block) { | 641 static bool HasLoopNumber(BasicBlock* block) { |
| 658 return block->ao_number() >= 0; | 642 return block->loop_number() >= 0; |
| 659 } | 643 } |
| 660 | 644 |
| 661 // TODO(mstarzinger): We only need this special sentinel because some tests | 645 // TODO(mstarzinger): We only need this special sentinel because some tests |
| 662 // use the schedule's end block in actual control flow (e.g. with end having | 646 // use the schedule's end block in actual control flow (e.g. with end having |
| 663 // successors). Once this has been cleaned up we can use the end block here. | 647 // successors). Once this has been cleaned up we can use the end block here. |
| 664 BasicBlock* BeyondEndSentinel() { | 648 BasicBlock* BeyondEndSentinel() { |
| 665 if (beyond_end_ == NULL) { | 649 if (beyond_end_ == NULL) { |
| 666 BasicBlock::Id id = BasicBlock::Id::FromInt(-1); | 650 BasicBlock::Id id = BasicBlock::Id::FromInt(-1); |
| 667 beyond_end_ = new (schedule_->zone()) BasicBlock(schedule_->zone(), id); | 651 beyond_end_ = new (schedule_->zone()) BasicBlock(schedule_->zone(), id); |
| 668 } | 652 } |
| 669 return beyond_end_; | 653 return beyond_end_; |
| 670 } | 654 } |
| 671 | 655 |
| 672 // Compute special RPO for the control flow graph between {entry} and {end}, | 656 // Compute special RPO for the control flow graph between {entry} and {end}, |
| 673 // mutating any existing order so that the result is still valid. | 657 // mutating any existing order so that the result is still valid. |
| 674 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) { | 658 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) { |
| 675 // RPO should not have been serialized for this schedule yet. | 659 // RPO should not have been serialized for this schedule yet. |
| 676 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number()); | 660 CHECK_EQ(kBlockUnvisited1, schedule_->start()->loop_number()); |
| 677 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); | 661 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); |
| 678 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); | 662 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); |
| 679 | 663 |
| 680 // Find correct insertion point within existing order. | 664 // Find correct insertion point within existing order. |
| 681 BasicBlock* insertion_point = entry->rpo_next(); | 665 BasicBlock* insertion_point = entry->rpo_next(); |
| 682 BasicBlock* order = insertion_point; | 666 BasicBlock* order = insertion_point; |
| 683 | 667 |
| 684 // Perform an iterative RPO traversal using an explicit stack, | 668 // Perform an iterative RPO traversal using an explicit stack, |
| 685 // recording backedges that form cycles. O(|B|). | 669 // recording backedges that form cycles. O(|B|). |
| 686 DCHECK_LT(previous_block_count_, schedule_->BasicBlockCount()); | 670 DCHECK_LT(previous_block_count_, schedule_->BasicBlockCount()); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 ZoneVector<LoopInfo> loops_; | 1008 ZoneVector<LoopInfo> loops_; |
| 1025 ZoneVector<Backedge> backedges_; | 1009 ZoneVector<Backedge> backedges_; |
| 1026 ZoneVector<SpecialRPOStackFrame> stack_; | 1010 ZoneVector<SpecialRPOStackFrame> stack_; |
| 1027 size_t previous_block_count_; | 1011 size_t previous_block_count_; |
| 1028 }; | 1012 }; |
| 1029 | 1013 |
| 1030 | 1014 |
| 1031 BasicBlockVector* Scheduler::ComputeSpecialRPO(Zone* zone, Schedule* schedule) { | 1015 BasicBlockVector* Scheduler::ComputeSpecialRPO(Zone* zone, Schedule* schedule) { |
| 1032 SpecialRPONumberer numberer(zone, schedule); | 1016 SpecialRPONumberer numberer(zone, schedule); |
| 1033 numberer.ComputeSpecialRPO(); | 1017 numberer.ComputeSpecialRPO(); |
| 1034 numberer.SerializeAOIntoSchedule(); | |
| 1035 numberer.SerializeRPOIntoSchedule(); | 1018 numberer.SerializeRPOIntoSchedule(); |
| 1036 numberer.PrintAndVerifySpecialRPO(); | 1019 numberer.PrintAndVerifySpecialRPO(); |
| 1037 return schedule->rpo_order(); | 1020 return schedule->rpo_order(); |
| 1038 } | 1021 } |
| 1039 | 1022 |
| 1040 | 1023 |
| 1041 void Scheduler::ComputeSpecialRPONumbering() { | 1024 void Scheduler::ComputeSpecialRPONumbering() { |
| 1042 Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n"); | 1025 Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n"); |
| 1043 | 1026 |
| 1044 // Compute the special reverse-post-order for basic blocks. | 1027 // Compute the special reverse-post-order for basic blocks. |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 | 1388 |
| 1406 | 1389 |
| 1407 // ----------------------------------------------------------------------------- | 1390 // ----------------------------------------------------------------------------- |
| 1408 // Phase 6: Seal the final schedule. | 1391 // Phase 6: Seal the final schedule. |
| 1409 | 1392 |
| 1410 | 1393 |
| 1411 void Scheduler::SealFinalSchedule() { | 1394 void Scheduler::SealFinalSchedule() { |
| 1412 Trace("--- SEAL FINAL SCHEDULE ------------------------------------\n"); | 1395 Trace("--- SEAL FINAL SCHEDULE ------------------------------------\n"); |
| 1413 | 1396 |
| 1414 // Serialize the assembly order and reverse-post-order numbering. | 1397 // Serialize the assembly order and reverse-post-order numbering. |
| 1415 special_rpo_->SerializeAOIntoSchedule(); | |
| 1416 special_rpo_->SerializeRPOIntoSchedule(); | 1398 special_rpo_->SerializeRPOIntoSchedule(); |
| 1417 special_rpo_->PrintAndVerifySpecialRPO(); | 1399 special_rpo_->PrintAndVerifySpecialRPO(); |
| 1418 | 1400 |
| 1419 // Add collected nodes for basic blocks to their blocks in the right order. | 1401 // Add collected nodes for basic blocks to their blocks in the right order. |
| 1420 int block_num = 0; | 1402 int block_num = 0; |
| 1421 for (NodeVector& nodes : scheduled_nodes_) { | 1403 for (NodeVector& nodes : scheduled_nodes_) { |
| 1422 BasicBlock::Id id = BasicBlock::Id::FromInt(block_num++); | 1404 BasicBlock::Id id = BasicBlock::Id::FromInt(block_num++); |
| 1423 BasicBlock* block = schedule_->GetBlockById(id); | 1405 BasicBlock* block = schedule_->GetBlockById(id); |
| 1424 for (NodeVectorRIter i = nodes.rbegin(); i != nodes.rend(); ++i) { | 1406 for (NodeVectorRIter i = nodes.rbegin(); i != nodes.rend(); ++i) { |
| 1425 schedule_->AddNode(block, *i); | 1407 schedule_->AddNode(block, *i); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { | 1474 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { |
| 1493 schedule_->SetBlockForNode(to, *i); | 1475 schedule_->SetBlockForNode(to, *i); |
| 1494 scheduled_nodes_[to->id().ToSize()].push_back(*i); | 1476 scheduled_nodes_[to->id().ToSize()].push_back(*i); |
| 1495 } | 1477 } |
| 1496 nodes->clear(); | 1478 nodes->clear(); |
| 1497 } | 1479 } |
| 1498 | 1480 |
| 1499 } // namespace compiler | 1481 } // namespace compiler |
| 1500 } // namespace internal | 1482 } // namespace internal |
| 1501 } // namespace v8 | 1483 } // namespace v8 |
| OLD | NEW |