Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(484)

Side by Side Diff: src/compiler/scheduler.cc

Issue 762723004: Move linked list for RPO order into BasicBlock itself. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/schedule.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 // headed at A. 529 // headed at A.
530 // 2. All loops are contiguous in the order (i.e. no intervening blocks that 530 // 2. All loops are contiguous in the order (i.e. no intervening blocks that
531 // do not belong to the loop.) 531 // do not belong to the loop.)
532 // Note a simple RPO traversal satisfies (1) but not (2). 532 // Note a simple RPO traversal satisfies (1) but not (2).
533 class SpecialRPONumberer : public ZoneObject { 533 class SpecialRPONumberer : public ZoneObject {
534 public: 534 public:
535 SpecialRPONumberer(Zone* zone, Schedule* schedule) 535 SpecialRPONumberer(Zone* zone, Schedule* schedule)
536 : zone_(zone), 536 : zone_(zone),
537 schedule_(schedule), 537 schedule_(schedule),
538 order_(NULL), 538 order_(NULL),
539 beyond_end_(NULL),
539 loops_(zone), 540 loops_(zone),
540 beyond_end_(NULL),
541 backedges_(1, zone), 541 backedges_(1, zone),
542 stack_(zone), 542 stack_(zone),
543 previous_block_count_(0) {} 543 previous_block_count_(0) {}
544 544
545 // Computes the special reverse-post-order for the main control flow graph, 545 // Computes the special reverse-post-order for the main control flow graph,
546 // that is for the graph spanned between the schedule's start and end blocks. 546 // that is for the graph spanned between the schedule's start and end blocks.
547 void ComputeSpecialRPO() { 547 void ComputeSpecialRPO() {
548 DCHECK(schedule_->end()->SuccessorCount() == 0); 548 DCHECK(schedule_->end()->SuccessorCount() == 0);
549 DCHECK_EQ(NULL, order_); // Main order does not exist yet. 549 DCHECK_EQ(NULL, order_); // Main order does not exist yet.
550 ComputeAndInsertSpecialRPO(schedule_->start(), schedule_->end()); 550 ComputeAndInsertSpecialRPO(schedule_->start(), schedule_->end());
551 } 551 }
552 552
553 // Computes the special reverse-post-order for a partial control flow graph, 553 // Computes the special reverse-post-order for a partial control flow graph,
554 // that is for the graph spanned between the given {entry} and {end} blocks, 554 // that is for the graph spanned between the given {entry} and {end} blocks,
555 // then updates the existing ordering with this new information. 555 // then updates the existing ordering with this new information.
556 void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) { 556 void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) {
557 DCHECK_NE(NULL, order_); // Main order to be updated is present. 557 DCHECK_NE(NULL, order_); // Main order to be updated is present.
558 ComputeAndInsertSpecialRPO(entry, end); 558 ComputeAndInsertSpecialRPO(entry, end);
559 } 559 }
560 560
561 // Serialize the previously computed order as an assembly order (non-deferred 561 // Serialize the previously computed order as an assembly order (non-deferred
562 // code first, deferred code afterwards) into the final schedule. 562 // code first, deferred code afterwards) into the final schedule.
563 void SerializeAOIntoSchedule() { 563 void SerializeAOIntoSchedule() {
564 int32_t number = 0; 564 int32_t number = 0;
565 for (BlockList* l = order_; l != NULL; l = l->next) { 565 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
566 if (l->block->deferred()) continue; 566 if (b->deferred()) continue;
567 l->block->set_ao_number(number++); 567 b->set_ao_number(number++);
568 } 568 }
569 for (BlockList* l = order_; l != NULL; l = l->next) { 569 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
570 if (!l->block->deferred()) continue; 570 if (!b->deferred()) continue;
571 l->block->set_ao_number(number++); 571 b->set_ao_number(number++);
572 } 572 }
573 } 573 }
574 574
575 // Serialize the previously computed order as a special reverse-post-order 575 // Serialize the previously computed order as a special reverse-post-order
576 // numbering for basic blocks into the final schedule. 576 // numbering for basic blocks into the final schedule.
577 void SerializeRPOIntoSchedule() { 577 void SerializeRPOIntoSchedule() {
578 int32_t number = 0; 578 int32_t number = 0;
579 for (BlockList* l = order_; l != NULL; l = l->next) { 579 for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
580 l->block->set_rpo_number(number++); 580 b->set_rpo_number(number++);
581 schedule_->rpo_order()->push_back(l->block); 581 schedule_->rpo_order()->push_back(b);
582 } 582 }
583 BeyondEndSentinel()->set_rpo_number(number); 583 BeyondEndSentinel()->set_rpo_number(number);
584 } 584 }
585 585
586 // Print and verify the special reverse-post-order. 586 // Print and verify the special reverse-post-order.
587 void PrintAndVerifySpecialRPO() { 587 void PrintAndVerifySpecialRPO() {
588 #if DEBUG 588 #if DEBUG
589 if (FLAG_trace_turbo_scheduler) PrintRPO(); 589 if (FLAG_trace_turbo_scheduler) PrintRPO();
590 VerifySpecialRPO(); 590 VerifySpecialRPO();
591 #endif 591 #endif
592 } 592 }
593 593
594 private: 594 private:
595 typedef std::pair<BasicBlock*, size_t> Backedge; 595 typedef std::pair<BasicBlock*, size_t> Backedge;
596 596
597 // TODO(mstarzinger): Only for Scheduler::GenerateImmediateDominatorTree.
598 friend class Scheduler;
599
600 // Numbering for BasicBlock::rpo_number for this block traversal: 597 // Numbering for BasicBlock::rpo_number for this block traversal:
601 static const int kBlockOnStack = -2; 598 static const int kBlockOnStack = -2;
602 static const int kBlockVisited1 = -3; 599 static const int kBlockVisited1 = -3;
603 static const int kBlockVisited2 = -4; 600 static const int kBlockVisited2 = -4;
604 static const int kBlockUnvisited1 = -1; 601 static const int kBlockUnvisited1 = -1;
605 static const int kBlockUnvisited2 = kBlockVisited1; 602 static const int kBlockUnvisited2 = kBlockVisited1;
606 603
607 struct SpecialRPOStackFrame { 604 struct SpecialRPOStackFrame {
608 BasicBlock* block; 605 BasicBlock* block;
609 size_t index; 606 size_t index;
610 }; 607 };
611 608
612 struct BlockList {
613 BasicBlock* block;
614 BlockList* next;
615
616 BlockList* Add(Zone* zone, BasicBlock* b) {
617 BlockList* list = static_cast<BlockList*>(zone->New(sizeof(BlockList)));
618 list->block = b;
619 list->next = this;
620 return list;
621 }
622
623 BlockList* FindForBlock(BasicBlock* b) {
624 for (BlockList* l = this; l != NULL; l = l->next) {
625 if (l->block == b) return l;
626 }
627 return NULL;
628 }
629 };
630
631 struct LoopInfo { 609 struct LoopInfo {
632 BasicBlock* header; 610 BasicBlock* header;
633 ZoneList<BasicBlock*>* outgoing; 611 ZoneList<BasicBlock*>* outgoing;
634 BitVector* members; 612 BitVector* members;
635 LoopInfo* prev; 613 LoopInfo* prev;
636 BlockList* end; 614 BasicBlock* end;
637 BlockList* start; 615 BasicBlock* start;
638 616
639 void AddOutgoing(Zone* zone, BasicBlock* block) { 617 void AddOutgoing(Zone* zone, BasicBlock* block) {
640 if (outgoing == NULL) { 618 if (outgoing == NULL) {
641 outgoing = new (zone) ZoneList<BasicBlock*>(2, zone); 619 outgoing = new (zone) ZoneList<BasicBlock*>(2, zone);
642 } 620 }
643 outgoing->Add(block, zone); 621 outgoing->Add(block, zone);
644 } 622 }
645 }; 623 };
646 624
647 int Push(ZoneVector<SpecialRPOStackFrame>& stack, int depth, 625 int Push(ZoneVector<SpecialRPOStackFrame>& stack, int depth,
648 BasicBlock* child, int unvisited) { 626 BasicBlock* child, int unvisited) {
649 if (child->rpo_number() == unvisited) { 627 if (child->rpo_number() == unvisited) {
650 stack[depth].block = child; 628 stack[depth].block = child;
651 stack[depth].index = 0; 629 stack[depth].index = 0;
652 child->set_rpo_number(kBlockOnStack); 630 child->set_rpo_number(kBlockOnStack);
653 return depth + 1; 631 return depth + 1;
654 } 632 }
655 return depth; 633 return depth;
656 } 634 }
657 635
636 BasicBlock* PushFront(BasicBlock* head, BasicBlock* block) {
637 block->set_rpo_next(head);
638 return block;
639 }
640
658 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that 641 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that
659 // these numbers are only valid within this class. 642 // these numbers are only valid within this class.
660 static int GetLoopNumber(BasicBlock* block) { return block->ao_number(); } 643 static int GetLoopNumber(BasicBlock* block) { return block->ao_number(); }
661 static void SetLoopNumber(BasicBlock* block, int loop_number) { 644 static void SetLoopNumber(BasicBlock* block, int loop_number) {
662 return block->set_ao_number(loop_number); 645 return block->set_ao_number(loop_number);
663 } 646 }
664 static bool HasLoopNumber(BasicBlock* block) { 647 static bool HasLoopNumber(BasicBlock* block) {
665 return block->ao_number() >= 0; 648 return block->ao_number() >= 0;
666 } 649 }
667 650
(...skipping 10 matching lines...) Expand all
678 661
679 // Compute special RPO for the control flow graph between {entry} and {end}, 662 // Compute special RPO for the control flow graph between {entry} and {end},
680 // mutating any existing order so that the result is still valid. 663 // mutating any existing order so that the result is still valid.
681 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) { 664 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) {
682 // RPO should not have been serialized for this schedule yet. 665 // RPO should not have been serialized for this schedule yet.
683 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number()); 666 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number());
684 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); 667 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number());
685 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); 668 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size()));
686 669
687 // Find correct insertion point within existing order. 670 // Find correct insertion point within existing order.
688 BlockList* insert_before = order_->FindForBlock(entry); 671 BasicBlock* insertion_point = entry->rpo_next();
689 BlockList* insert_after = insert_before ? insert_before->next : NULL; 672 BasicBlock* order = insertion_point;
690 BlockList* order = insert_after;
691 673
692 // Perform an iterative RPO traversal using an explicit stack, 674 // Perform an iterative RPO traversal using an explicit stack,
693 // recording backedges that form cycles. O(|B|). 675 // recording backedges that form cycles. O(|B|).
694 DCHECK_LT(previous_block_count_, schedule_->BasicBlockCount()); 676 DCHECK_LT(previous_block_count_, schedule_->BasicBlockCount());
695 stack_.resize(schedule_->BasicBlockCount() - previous_block_count_); 677 stack_.resize(schedule_->BasicBlockCount() - previous_block_count_);
696 previous_block_count_ = schedule_->BasicBlockCount(); 678 previous_block_count_ = schedule_->BasicBlockCount();
697 int stack_depth = Push(stack_, 0, entry, kBlockUnvisited1); 679 int stack_depth = Push(stack_, 0, entry, kBlockUnvisited1);
698 int num_loops = static_cast<int>(loops_.size()); 680 int num_loops = static_cast<int>(loops_.size());
699 681
700 while (stack_depth > 0) { 682 while (stack_depth > 0) {
(...skipping 12 matching lines...) Expand all
713 // Assign a new loop number to the header if it doesn't have one. 695 // Assign a new loop number to the header if it doesn't have one.
714 SetLoopNumber(succ, num_loops++); 696 SetLoopNumber(succ, num_loops++);
715 } 697 }
716 } else { 698 } else {
717 // Push the successor onto the stack. 699 // Push the successor onto the stack.
718 DCHECK(succ->rpo_number() == kBlockUnvisited1); 700 DCHECK(succ->rpo_number() == kBlockUnvisited1);
719 stack_depth = Push(stack_, stack_depth, succ, kBlockUnvisited1); 701 stack_depth = Push(stack_, stack_depth, succ, kBlockUnvisited1);
720 } 702 }
721 } else { 703 } else {
722 // Finished with all successors; pop the stack and add the block. 704 // Finished with all successors; pop the stack and add the block.
723 order = order->Add(zone_, frame->block); 705 order = PushFront(order, frame->block);
724 frame->block->set_rpo_number(kBlockVisited1); 706 frame->block->set_rpo_number(kBlockVisited1);
725 stack_depth--; 707 stack_depth--;
726 } 708 }
727 } 709 }
728 710
729 // If no loops were encountered, then the order we computed was correct. 711 // If no loops were encountered, then the order we computed was correct.
730 if (num_loops > static_cast<int>(loops_.size())) { 712 if (num_loops > static_cast<int>(loops_.size())) {
731 // Otherwise, compute the loop information from the backedges in order 713 // Otherwise, compute the loop information from the backedges in order
732 // to perform a traversal that groups loop bodies together. 714 // to perform a traversal that groups loop bodies together.
733 ComputeLoopInfo(stack_, num_loops, &backedges_); 715 ComputeLoopInfo(stack_, num_loops, &backedges_);
734 716
735 // Initialize the "loop stack". Note the entry could be a loop header. 717 // Initialize the "loop stack". Note the entry could be a loop header.
736 LoopInfo* loop = 718 LoopInfo* loop =
737 HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL; 719 HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL;
738 order = insert_after; 720 order = insertion_point;
739 721
740 // Perform an iterative post-order traversal, visiting loop bodies before 722 // Perform an iterative post-order traversal, visiting loop bodies before
741 // edges that lead out of loops. Visits each block once, but linking loop 723 // edges that lead out of loops. Visits each block once, but linking loop
742 // sections together is linear in the loop size, so overall is 724 // sections together is linear in the loop size, so overall is
743 // O(|B| + max(loop_depth) * max(|loop|)) 725 // O(|B| + max(loop_depth) * max(|loop|))
744 stack_depth = Push(stack_, 0, entry, kBlockUnvisited2); 726 stack_depth = Push(stack_, 0, entry, kBlockUnvisited2);
745 while (stack_depth > 0) { 727 while (stack_depth > 0) {
746 SpecialRPOStackFrame* frame = &stack_[stack_depth - 1]; 728 SpecialRPOStackFrame* frame = &stack_[stack_depth - 1];
747 BasicBlock* block = frame->block; 729 BasicBlock* block = frame->block;
748 BasicBlock* succ = NULL; 730 BasicBlock* succ = NULL;
749 731
750 if (block != end && frame->index < block->SuccessorCount()) { 732 if (block != end && frame->index < block->SuccessorCount()) {
751 // Process the next normal successor. 733 // Process the next normal successor.
752 succ = block->SuccessorAt(frame->index++); 734 succ = block->SuccessorAt(frame->index++);
753 } else if (HasLoopNumber(block)) { 735 } else if (HasLoopNumber(block)) {
754 // Process additional outgoing edges from the loop header. 736 // Process additional outgoing edges from the loop header.
755 if (block->rpo_number() == kBlockOnStack) { 737 if (block->rpo_number() == kBlockOnStack) {
756 // Finish the loop body the first time the header is left on the 738 // Finish the loop body the first time the header is left on the
757 // stack. 739 // stack.
758 DCHECK(loop != NULL && loop->header == block); 740 DCHECK(loop != NULL && loop->header == block);
759 loop->start = order->Add(zone_, block); 741 loop->start = PushFront(order, block);
760 order = loop->end; 742 order = loop->end;
761 block->set_rpo_number(kBlockVisited2); 743 block->set_rpo_number(kBlockVisited2);
762 // Pop the loop stack and continue visiting outgoing edges within 744 // Pop the loop stack and continue visiting outgoing edges within
763 // the context of the outer loop, if any. 745 // the context of the outer loop, if any.
764 loop = loop->prev; 746 loop = loop->prev;
765 // We leave the loop header on the stack; the rest of this iteration 747 // We leave the loop header on the stack; the rest of this iteration
766 // and later iterations will go through its outgoing edges list. 748 // and later iterations will go through its outgoing edges list.
767 } 749 }
768 750
769 // Use the next outgoing edge if there are any. 751 // Use the next outgoing edge if there are any.
(...skipping 27 matching lines...) Expand all
797 next->end = order; 779 next->end = order;
798 next->prev = loop; 780 next->prev = loop;
799 loop = next; 781 loop = next;
800 } 782 }
801 } 783 }
802 } else { 784 } else {
803 // Finished with all successors of the current block. 785 // Finished with all successors of the current block.
804 if (HasLoopNumber(block)) { 786 if (HasLoopNumber(block)) {
805 // If we are going to pop a loop header, then add its entire body. 787 // If we are going to pop a loop header, then add its entire body.
806 LoopInfo* info = &loops_[GetLoopNumber(block)]; 788 LoopInfo* info = &loops_[GetLoopNumber(block)];
807 for (BlockList* l = info->start; true; l = l->next) { 789 for (BasicBlock* b = info->start; true; b = b->rpo_next()) {
808 if (l->next == info->end) { 790 if (b->rpo_next() == info->end) {
809 l->next = order; 791 b->set_rpo_next(order);
810 info->end = order; 792 info->end = order;
811 break; 793 break;
812 } 794 }
813 } 795 }
814 order = info->start; 796 order = info->start;
815 } else { 797 } else {
816 // Pop a single node off the stack and add it to the order. 798 // Pop a single node off the stack and add it to the order.
817 order = order->Add(zone_, block); 799 order = PushFront(order, block);
818 block->set_rpo_number(kBlockVisited2); 800 block->set_rpo_number(kBlockVisited2);
819 } 801 }
820 stack_depth--; 802 stack_depth--;
821 } 803 }
822 } 804 }
823 } 805 }
824 806
825 // Insert result into existing order. 807 // Publish new order the first time.
826 if (insert_before == NULL) { 808 if (order_ == NULL) order_ = order;
827 order_ = order;
828 } else {
829 // There already is a list element for the entry block in the list, hence
830 // we skip the first element of the sub-list to compensate duplication.
831 DCHECK_EQ(insert_before->block, order->block);
832 insert_before->next = order->next;
833 }
834 809
835 // Compute the correct loop headers and set the correct loop ends. 810 // Compute the correct loop headers and set the correct loop ends.
836 LoopInfo* current_loop = NULL; 811 LoopInfo* current_loop = NULL;
837 BasicBlock* current_header = entry->loop_header(); 812 BasicBlock* current_header = entry->loop_header();
838 int32_t loop_depth = entry->loop_depth(); 813 int32_t loop_depth = entry->loop_depth();
839 if (entry->IsLoopHeader()) --loop_depth; // Entry might be a loop header. 814 if (entry->IsLoopHeader()) --loop_depth; // Entry might be a loop header.
840 for (BlockList* l = order; l != insert_after; l = l->next) { 815 for (BasicBlock* b = order; b != insertion_point; b = b->rpo_next()) {
841 BasicBlock* current = l->block; 816 BasicBlock* current = b;
842 817
843 // Reset BasicBlock::rpo_number again. 818 // Reset BasicBlock::rpo_number again.
844 current->set_rpo_number(kBlockUnvisited1); 819 current->set_rpo_number(kBlockUnvisited1);
845 820
846 // Finish the previous loop(s) if we just exited them. 821 // Finish the previous loop(s) if we just exited them.
847 while (current_header != NULL && current == current_header->loop_end()) { 822 while (current_header != NULL && current == current_header->loop_end()) {
848 DCHECK(current_header->IsLoopHeader()); 823 DCHECK(current_header->IsLoopHeader());
849 DCHECK(current_loop != NULL); 824 DCHECK(current_loop != NULL);
850 current_loop = current_loop->prev; 825 current_loop = current_loop->prev;
851 current_header = current_loop == NULL ? NULL : current_loop->header; 826 current_header = current_loop == NULL ? NULL : current_loop->header;
852 --loop_depth; 827 --loop_depth;
853 } 828 }
854 current->set_loop_header(current_header); 829 current->set_loop_header(current_header);
855 830
856 // Push a new loop onto the stack if this loop is a loop header. 831 // Push a new loop onto the stack if this loop is a loop header.
857 if (HasLoopNumber(current)) { 832 if (HasLoopNumber(current)) {
858 ++loop_depth; 833 ++loop_depth;
859 current_loop = &loops_[GetLoopNumber(current)]; 834 current_loop = &loops_[GetLoopNumber(current)];
860 BlockList* end = current_loop->end; 835 BasicBlock* end = current_loop->end;
861 current->set_loop_end(end == NULL ? BeyondEndSentinel() : end->block); 836 current->set_loop_end(end == NULL ? BeyondEndSentinel() : end);
862 current_header = current_loop->header; 837 current_header = current_loop->header;
863 Trace("B%d is a loop header, increment loop depth to %d\n", 838 Trace("B%d is a loop header, increment loop depth to %d\n",
864 current->id().ToInt(), loop_depth); 839 current->id().ToInt(), loop_depth);
865 } 840 }
866 841
867 current->set_loop_depth(loop_depth); 842 current->set_loop_depth(loop_depth);
868 843
869 if (current->loop_header() == NULL) { 844 if (current->loop_header() == NULL) {
870 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(), 845 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
871 current->loop_depth()); 846 current->loop_depth());
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 if (loops_.size() > 0) { 911 if (loops_.size() > 0) {
937 os << " ("; 912 os << " (";
938 for (size_t i = 0; i < loops_.size(); i++) { 913 for (size_t i = 0; i < loops_.size(); i++) {
939 if (i > 0) os << " "; 914 if (i > 0) os << " ";
940 os << "B" << loops_[i].header->id(); 915 os << "B" << loops_[i].header->id();
941 } 916 }
942 os << ")"; 917 os << ")";
943 } 918 }
944 os << ":\n"; 919 os << ":\n";
945 920
946 for (BlockList* l = order_; l != NULL; l = l->next) { 921 for (BasicBlock* block = order_; block != NULL; block = block->rpo_next()) {
947 BasicBlock* block = l->block;
948 BasicBlock::Id bid = block->id(); 922 BasicBlock::Id bid = block->id();
949 // TODO(jarin,svenpanne): Add formatting here once we have support for 923 // TODO(jarin,svenpanne): Add formatting here once we have support for
950 // that in streams (we want an equivalent of PrintF("%5d:", x) here). 924 // that in streams (we want an equivalent of PrintF("%5d:", x) here).
951 os << " " << block->rpo_number() << ":"; 925 os << " " << block->rpo_number() << ":";
952 for (size_t i = 0; i < loops_.size(); i++) { 926 for (size_t i = 0; i < loops_.size(); i++) {
953 bool range = loops_[i].header->LoopContains(block); 927 bool range = loops_[i].header->LoopContains(block);
954 bool membership = loops_[i].header != block && range; 928 bool membership = loops_[i].header != block && range;
955 os << (membership ? " |" : " "); 929 os << (membership ? " |" : " ");
956 os << (range ? "x" : " "); 930 os << (range ? "x" : " ");
957 } 931 }
(...skipping 25 matching lines...) Expand all
983 DCHECK(header != NULL); 957 DCHECK(header != NULL);
984 DCHECK(header->rpo_number() >= 0); 958 DCHECK(header->rpo_number() >= 0);
985 DCHECK(header->rpo_number() < static_cast<int>(order->size())); 959 DCHECK(header->rpo_number() < static_cast<int>(order->size()));
986 DCHECK(end != NULL); 960 DCHECK(end != NULL);
987 DCHECK(end->rpo_number() <= static_cast<int>(order->size())); 961 DCHECK(end->rpo_number() <= static_cast<int>(order->size()));
988 DCHECK(end->rpo_number() > header->rpo_number()); 962 DCHECK(end->rpo_number() > header->rpo_number());
989 DCHECK(header->loop_header() != header); 963 DCHECK(header->loop_header() != header);
990 964
991 // Verify the start ... end list relationship. 965 // Verify the start ... end list relationship.
992 int links = 0; 966 int links = 0;
993 BlockList* l = loop->start; 967 BasicBlock* block = loop->start;
994 DCHECK(l != NULL && l->block == header); 968 DCHECK_EQ(header, block);
995 bool end_found; 969 bool end_found;
996 while (true) { 970 while (true) {
997 if (l == NULL || l == loop->end) { 971 if (block == NULL || block == loop->end) {
998 end_found = (loop->end == l); 972 end_found = (loop->end == block);
999 break; 973 break;
1000 } 974 }
1001 // The list should be in same order as the final result. 975 // The list should be in same order as the final result.
1002 DCHECK(l->block->rpo_number() == links + header->rpo_number()); 976 DCHECK(block->rpo_number() == links + header->rpo_number());
1003 links++; 977 links++;
1004 l = l->next; 978 block = block->rpo_next();
1005 DCHECK(links < static_cast<int>(2 * order->size())); // cycle? 979 DCHECK(links < static_cast<int>(2 * order->size())); // cycle?
1006 } 980 }
1007 DCHECK(links > 0); 981 DCHECK(links > 0);
1008 DCHECK(links == end->rpo_number() - header->rpo_number()); 982 DCHECK(links == end->rpo_number() - header->rpo_number());
1009 DCHECK(end_found); 983 DCHECK(end_found);
1010 984
1011 // Check loop depth of the header. 985 // Check loop depth of the header.
1012 int loop_depth = 0; 986 int loop_depth = 0;
1013 for (LoopInfo* outer = loop; outer != NULL; outer = outer->prev) { 987 for (LoopInfo* outer = loop; outer != NULL; outer = outer->prev) {
1014 loop_depth++; 988 loop_depth++;
(...skipping 13 matching lines...) Expand all
1028 count++; 1002 count++;
1029 } 1003 }
1030 } 1004 }
1031 DCHECK(links == count); 1005 DCHECK(links == count);
1032 } 1006 }
1033 } 1007 }
1034 #endif // DEBUG 1008 #endif // DEBUG
1035 1009
1036 Zone* zone_; 1010 Zone* zone_;
1037 Schedule* schedule_; 1011 Schedule* schedule_;
1038 BlockList* order_; 1012 BasicBlock* order_;
1013 BasicBlock* beyond_end_;
1039 ZoneVector<LoopInfo> loops_; 1014 ZoneVector<LoopInfo> loops_;
1040 BasicBlock* beyond_end_;
1041 ZoneList<Backedge> backedges_; 1015 ZoneList<Backedge> backedges_;
1042 ZoneVector<SpecialRPOStackFrame> stack_; 1016 ZoneVector<SpecialRPOStackFrame> stack_;
1043 size_t previous_block_count_; 1017 size_t previous_block_count_;
1044 }; 1018 };
1045 1019
1046 1020
1047 BasicBlockVector* Scheduler::ComputeSpecialRPO(Zone* zone, Schedule* schedule) { 1021 BasicBlockVector* Scheduler::ComputeSpecialRPO(Zone* zone, Schedule* schedule) {
1048 SpecialRPONumberer numberer(zone, schedule); 1022 SpecialRPONumberer numberer(zone, schedule);
1049 numberer.ComputeSpecialRPO(); 1023 numberer.ComputeSpecialRPO();
1050 numberer.SerializeAOIntoSchedule(); 1024 numberer.SerializeAOIntoSchedule();
(...skipping 12 matching lines...) Expand all
1063 } 1037 }
1064 1038
1065 1039
1066 void Scheduler::GenerateImmediateDominatorTree() { 1040 void Scheduler::GenerateImmediateDominatorTree() {
1067 Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n"); 1041 Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
1068 1042
1069 // TODO(danno): Consider using Lengauer & Tarjan's if this becomes too slow. 1043 // TODO(danno): Consider using Lengauer & Tarjan's if this becomes too slow.
1070 1044
1071 // Build the block dominator tree. 1045 // Build the block dominator tree.
1072 schedule_->start()->set_dominator_depth(0); 1046 schedule_->start()->set_dominator_depth(0);
1073 typedef SpecialRPONumberer::BlockList BlockList; 1047 BasicBlock* second = schedule_->start()->rpo_next();
1074 DCHECK_EQ(schedule_->start(), special_rpo_->order_->block); 1048 for (BasicBlock* block = second; block != NULL; block = block->rpo_next()) {
1075 for (BlockList* l = special_rpo_->order_->next; l != NULL; l = l->next) { 1049 BasicBlock::Predecessors::iterator pred = block->predecessors_begin();
1076 BasicBlock* current = l->block; 1050 BasicBlock::Predecessors::iterator end = block->predecessors_end();
1077 BasicBlock::Predecessors::iterator pred = current->predecessors_begin();
1078 BasicBlock::Predecessors::iterator end = current->predecessors_end();
1079 DCHECK(pred != end); // All blocks except start have predecessors. 1051 DCHECK(pred != end); // All blocks except start have predecessors.
1080 BasicBlock* dominator = *pred; 1052 BasicBlock* dominator = *pred;
1081 // For multiple predecessors, walk up the dominator tree until a common 1053 // For multiple predecessors, walk up the dominator tree until a common
1082 // dominator is found. Visitation order guarantees that all predecessors 1054 // dominator is found. Visitation order guarantees that all predecessors
1083 // except for backwards edges have been visited. 1055 // except for backwards edges have been visited.
1084 for (++pred; pred != end; ++pred) { 1056 for (++pred; pred != end; ++pred) {
1085 // Don't examine backwards edges. 1057 // Don't examine backwards edges.
1086 if ((*pred)->dominator_depth() < 0) continue; 1058 if ((*pred)->dominator_depth() < 0) continue;
1087 dominator = GetCommonDominator(dominator, *pred); 1059 dominator = GetCommonDominator(dominator, *pred);
1088 } 1060 }
1089 current->set_dominator(dominator); 1061 block->set_dominator(dominator);
1090 current->set_dominator_depth(dominator->dominator_depth() + 1); 1062 block->set_dominator_depth(dominator->dominator_depth() + 1);
1091 // Propagate "deferredness" of the dominator. 1063 // Propagate "deferredness" of the dominator.
1092 if (dominator->deferred()) current->set_deferred(true); 1064 if (dominator->deferred()) block->set_deferred(true);
1093 Trace("Block B%d's idom is B%d, depth = %d\n", current->id().ToInt(), 1065 Trace("Block B%d's idom is B%d, depth = %d\n", block->id().ToInt(),
1094 dominator->id().ToInt(), current->dominator_depth()); 1066 dominator->id().ToInt(), block->dominator_depth());
1095 } 1067 }
1096 } 1068 }
1097 1069
1098 1070
1099 // ----------------------------------------------------------------------------- 1071 // -----------------------------------------------------------------------------
1100 // Phase 3: Prepare use counts for nodes. 1072 // Phase 3: Prepare use counts for nodes.
1101 1073
1102 1074
1103 class PrepareUsesVisitor : public NullNodeVisitor { 1075 class PrepareUsesVisitor : public NullNodeVisitor {
1104 public: 1076 public:
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { 1482 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
1511 schedule_->SetBlockForNode(to, *i); 1483 schedule_->SetBlockForNode(to, *i);
1512 scheduled_nodes_[to->id().ToSize()].push_back(*i); 1484 scheduled_nodes_[to->id().ToSize()].push_back(*i);
1513 } 1485 }
1514 nodes->clear(); 1486 nodes->clear();
1515 } 1487 }
1516 1488
1517 } // namespace compiler 1489 } // namespace compiler
1518 } // namespace internal 1490 } // namespace internal
1519 } // namespace v8 1491 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/schedule.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698