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 |