| 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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 // 2. All loops are contiguous in the order (i.e. no intervening blocks that | 520 // 2. All loops are contiguous in the order (i.e. no intervening blocks that |
| 521 // do not belong to the loop.) | 521 // do not belong to the loop.) |
| 522 // Note a simple RPO traversal satisfies (1) but not (2). | 522 // Note a simple RPO traversal satisfies (1) but not (2). |
| 523 class SpecialRPONumberer : public ZoneObject { | 523 class SpecialRPONumberer : public ZoneObject { |
| 524 public: | 524 public: |
| 525 SpecialRPONumberer(Zone* zone, Schedule* schedule) | 525 SpecialRPONumberer(Zone* zone, Schedule* schedule) |
| 526 : zone_(zone), | 526 : zone_(zone), |
| 527 schedule_(schedule), | 527 schedule_(schedule), |
| 528 order_(NULL), | 528 order_(NULL), |
| 529 loops_(zone), | 529 loops_(zone), |
| 530 beyond_end_(NULL), | |
| 531 backedges_(1, zone), | 530 backedges_(1, zone), |
| 532 stack_(zone), | 531 stack_(zone), |
| 533 previous_block_count_(0) {} | 532 previous_block_count_(0) {} |
| 534 | 533 |
| 535 // Computes the special reverse-post-order for the main control flow graph, | 534 // Computes the special reverse-post-order for the main control flow graph, |
| 536 // that is for the graph spanned between the schedule's start and end blocks. | 535 // that is for the graph spanned between the schedule's start and end blocks. |
| 537 void ComputeSpecialRPO() { | 536 void ComputeSpecialRPO() { |
| 537 DCHECK(schedule_->end()->SuccessorCount() == 0); |
| 538 DCHECK_EQ(NULL, order_); // Main order does not exist yet. | 538 DCHECK_EQ(NULL, order_); // Main order does not exist yet. |
| 539 // TODO(mstarzinger): Should use Schedule::end() after tests are fixed. | 539 ComputeAndInsertSpecialRPO(schedule_->start(), schedule_->end()); |
| 540 ComputeAndInsertSpecialRPO(schedule_->start(), NULL); | |
| 541 } | 540 } |
| 542 | 541 |
| 543 // Computes the special reverse-post-order for a partial control flow graph, | 542 // Computes the special reverse-post-order for a partial control flow graph, |
| 544 // that is for the graph spanned between the given {entry} and {end} blocks, | 543 // that is for the graph spanned between the given {entry} and {end} blocks, |
| 545 // then updates the existing ordering with this new information. | 544 // then updates the existing ordering with this new information. |
| 546 void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) { | 545 void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) { |
| 547 DCHECK_NE(NULL, order_); // Main order to be updated is present. | 546 DCHECK_NE(NULL, order_); // Main order to be updated is present. |
| 548 ComputeAndInsertSpecialRPO(entry, end); | 547 ComputeAndInsertSpecialRPO(entry, end); |
| 549 } | 548 } |
| 550 | 549 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 563 } | 562 } |
| 564 | 563 |
| 565 // Serialize the previously computed order as a special reverse-post-order | 564 // Serialize the previously computed order as a special reverse-post-order |
| 566 // numbering for basic blocks into the final schedule. | 565 // numbering for basic blocks into the final schedule. |
| 567 void SerializeRPOIntoSchedule() { | 566 void SerializeRPOIntoSchedule() { |
| 568 int32_t number = 0; | 567 int32_t number = 0; |
| 569 for (BlockList* l = order_; l != NULL; l = l->next) { | 568 for (BlockList* l = order_; l != NULL; l = l->next) { |
| 570 l->block->set_rpo_number(number++); | 569 l->block->set_rpo_number(number++); |
| 571 schedule_->rpo_order()->push_back(l->block); | 570 schedule_->rpo_order()->push_back(l->block); |
| 572 } | 571 } |
| 573 BeyondEndSentinel()->set_rpo_number(number); | 572 if (schedule_->end()->rpo_number() < 0) { |
| 573 schedule_->end()->set_rpo_number(number); |
| 574 } |
| 574 } | 575 } |
| 575 | 576 |
| 576 // Print and verify the special reverse-post-order. | 577 // Print and verify the special reverse-post-order. |
| 577 void PrintAndVerifySpecialRPO() { | 578 void PrintAndVerifySpecialRPO() { |
| 578 #if DEBUG | 579 #if DEBUG |
| 579 if (FLAG_trace_turbo_scheduler) PrintRPO(); | 580 if (FLAG_trace_turbo_scheduler) PrintRPO(); |
| 580 VerifySpecialRPO(); | 581 VerifySpecialRPO(); |
| 581 #endif | 582 #endif |
| 582 } | 583 } |
| 583 | 584 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that | 649 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that |
| 649 // these numbers are only valid within this class. | 650 // these numbers are only valid within this class. |
| 650 static int GetLoopNumber(BasicBlock* block) { return block->ao_number(); } | 651 static int GetLoopNumber(BasicBlock* block) { return block->ao_number(); } |
| 651 static void SetLoopNumber(BasicBlock* block, int loop_number) { | 652 static void SetLoopNumber(BasicBlock* block, int loop_number) { |
| 652 return block->set_ao_number(loop_number); | 653 return block->set_ao_number(loop_number); |
| 653 } | 654 } |
| 654 static bool HasLoopNumber(BasicBlock* block) { | 655 static bool HasLoopNumber(BasicBlock* block) { |
| 655 return block->ao_number() >= 0; | 656 return block->ao_number() >= 0; |
| 656 } | 657 } |
| 657 | 658 |
| 658 // TODO(mstarzinger): We only need this special sentinel because some tests | |
| 659 // use the schedule's end block in actual control flow (e.g. with end having | |
| 660 // successors). Once this has been cleaned up we can use the end block here. | |
| 661 BasicBlock* BeyondEndSentinel() { | |
| 662 if (beyond_end_ == NULL) { | |
| 663 BasicBlock::Id id = BasicBlock::Id::FromInt(-1); | |
| 664 beyond_end_ = new (schedule_->zone()) BasicBlock(schedule_->zone(), id); | |
| 665 } | |
| 666 return beyond_end_; | |
| 667 } | |
| 668 | |
| 669 // Compute special RPO for the control flow graph between {entry} and {end}, | 659 // Compute special RPO for the control flow graph between {entry} and {end}, |
| 670 // mutating any existing order so that the result is still valid. | 660 // mutating any existing order so that the result is still valid. |
| 671 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) { | 661 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) { |
| 672 // RPO should not have been serialized for this schedule yet. | 662 // RPO should not have been serialized for this schedule yet. |
| 673 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number()); | 663 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number()); |
| 674 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); | 664 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); |
| 675 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); | 665 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); |
| 676 | 666 |
| 677 // Find correct insertion point within existing order. | 667 // Find correct insertion point within existing order. |
| 678 BlockList* insert_before = order_->FindForBlock(entry); | 668 BlockList* insert_before = order_->FindForBlock(entry); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 current_header = current_loop == NULL ? NULL : current_loop->header; | 831 current_header = current_loop == NULL ? NULL : current_loop->header; |
| 842 --loop_depth; | 832 --loop_depth; |
| 843 } | 833 } |
| 844 current->set_loop_header(current_header); | 834 current->set_loop_header(current_header); |
| 845 | 835 |
| 846 // Push a new loop onto the stack if this loop is a loop header. | 836 // Push a new loop onto the stack if this loop is a loop header. |
| 847 if (HasLoopNumber(current)) { | 837 if (HasLoopNumber(current)) { |
| 848 ++loop_depth; | 838 ++loop_depth; |
| 849 current_loop = &loops_[GetLoopNumber(current)]; | 839 current_loop = &loops_[GetLoopNumber(current)]; |
| 850 BlockList* end = current_loop->end; | 840 BlockList* end = current_loop->end; |
| 851 current->set_loop_end(end == NULL ? BeyondEndSentinel() : end->block); | 841 current->set_loop_end(end == NULL ? schedule_->end() : end->block); |
| 852 current_header = current_loop->header; | 842 current_header = current_loop->header; |
| 853 Trace("B%d is a loop header, increment loop depth to %d\n", | 843 Trace("B%d is a loop header, increment loop depth to %d\n", |
| 854 current->id().ToInt(), loop_depth); | 844 current->id().ToInt(), loop_depth); |
| 855 } | 845 } |
| 856 | 846 |
| 857 current->set_loop_depth(loop_depth); | 847 current->set_loop_depth(loop_depth); |
| 858 | 848 |
| 859 if (current->loop_header() == NULL) { | 849 if (current->loop_header() == NULL) { |
| 860 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(), | 850 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(), |
| 861 current->loop_depth()); | 851 current->loop_depth()); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 } | 1001 } |
| 1012 DCHECK(links == count); | 1002 DCHECK(links == count); |
| 1013 } | 1003 } |
| 1014 } | 1004 } |
| 1015 #endif // DEBUG | 1005 #endif // DEBUG |
| 1016 | 1006 |
| 1017 Zone* zone_; | 1007 Zone* zone_; |
| 1018 Schedule* schedule_; | 1008 Schedule* schedule_; |
| 1019 BlockList* order_; | 1009 BlockList* order_; |
| 1020 ZoneVector<LoopInfo> loops_; | 1010 ZoneVector<LoopInfo> loops_; |
| 1021 BasicBlock* beyond_end_; | |
| 1022 ZoneList<Backedge> backedges_; | 1011 ZoneList<Backedge> backedges_; |
| 1023 ZoneVector<SpecialRPOStackFrame> stack_; | 1012 ZoneVector<SpecialRPOStackFrame> stack_; |
| 1024 size_t previous_block_count_; | 1013 size_t previous_block_count_; |
| 1025 }; | 1014 }; |
| 1026 | 1015 |
| 1027 | 1016 |
| 1028 BasicBlockVector* Scheduler::ComputeSpecialRPO(ZonePool* zone_pool, | 1017 BasicBlockVector* Scheduler::ComputeSpecialRPO(ZonePool* zone_pool, |
| 1029 Schedule* schedule) { | 1018 Schedule* schedule) { |
| 1030 ZonePool::Scope zone_scope(zone_pool); | 1019 ZonePool::Scope zone_scope(zone_pool); |
| 1031 Zone* zone = zone_scope.zone(); | 1020 Zone* zone = zone_scope.zone(); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1474 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { | 1463 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { |
| 1475 schedule_->SetBlockForNode(to, *i); | 1464 schedule_->SetBlockForNode(to, *i); |
| 1476 scheduled_nodes_[to->id().ToSize()].push_back(*i); | 1465 scheduled_nodes_[to->id().ToSize()].push_back(*i); |
| 1477 } | 1466 } |
| 1478 nodes->clear(); | 1467 nodes->clear(); |
| 1479 } | 1468 } |
| 1480 | 1469 |
| 1481 } // namespace compiler | 1470 } // namespace compiler |
| 1482 } // namespace internal | 1471 } // namespace internal |
| 1483 } // namespace v8 | 1472 } // namespace v8 |
| OLD | NEW |