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

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

Issue 695303003: Reuse RPO traversal stack in the scheduler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) {} 530 beyond_end_(NULL),
531 backedges_(1, zone),
532 stack_(zone),
533 previous_block_count_(0) {}
531 534
532 // Computes the special reverse-post-order for the main control flow graph, 535 // Computes the special reverse-post-order for the main control flow graph,
533 // that is for the graph spanned between the schedule's start and end blocks. 536 // that is for the graph spanned between the schedule's start and end blocks.
534 void ComputeSpecialRPO() { 537 void ComputeSpecialRPO() {
535 DCHECK_EQ(NULL, order_); // Main order does not exist yet. 538 DCHECK_EQ(NULL, order_); // Main order does not exist yet.
536 // TODO(mstarzinger): Should use Schedule::end() after tests are fixed. 539 // TODO(mstarzinger): Should use Schedule::end() after tests are fixed.
537 ComputeAndInsertSpecialRPO(schedule_->start(), NULL); 540 ComputeAndInsertSpecialRPO(schedule_->start(), NULL);
538 } 541 }
539 542
540 // Computes the special reverse-post-order for a partial control flow graph, 543 // Computes the special reverse-post-order for a partial control flow graph,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 575
573 // Print and verify the special reverse-post-order. 576 // Print and verify the special reverse-post-order.
574 void PrintAndVerifySpecialRPO() { 577 void PrintAndVerifySpecialRPO() {
575 #if DEBUG 578 #if DEBUG
576 if (FLAG_trace_turbo_scheduler) PrintRPO(); 579 if (FLAG_trace_turbo_scheduler) PrintRPO();
577 VerifySpecialRPO(); 580 VerifySpecialRPO();
578 #endif 581 #endif
579 } 582 }
580 583
581 private: 584 private:
585 typedef std::pair<BasicBlock*, size_t> Backedge;
586
582 // TODO(mstarzinger): Only for Scheduler::GenerateImmediateDominatorTree. 587 // TODO(mstarzinger): Only for Scheduler::GenerateImmediateDominatorTree.
583 friend class Scheduler; 588 friend class Scheduler;
584 589
585 // Numbering for BasicBlock::rpo_number for this block traversal: 590 // Numbering for BasicBlock::rpo_number for this block traversal:
586 static const int kBlockOnStack = -2; 591 static const int kBlockOnStack = -2;
587 static const int kBlockVisited1 = -3; 592 static const int kBlockVisited1 = -3;
588 static const int kBlockVisited2 = -4; 593 static const int kBlockVisited2 = -4;
589 static const int kBlockUnvisited1 = -1; 594 static const int kBlockUnvisited1 = -1;
590 static const int kBlockUnvisited2 = kBlockVisited1; 595 static const int kBlockUnvisited2 = kBlockVisited1;
591 596
(...skipping 30 matching lines...) Expand all
622 BlockList* start; 627 BlockList* start;
623 628
624 void AddOutgoing(Zone* zone, BasicBlock* block) { 629 void AddOutgoing(Zone* zone, BasicBlock* block) {
625 if (outgoing == NULL) { 630 if (outgoing == NULL) {
626 outgoing = new (zone) ZoneList<BasicBlock*>(2, zone); 631 outgoing = new (zone) ZoneList<BasicBlock*>(2, zone);
627 } 632 }
628 outgoing->Add(block, zone); 633 outgoing->Add(block, zone);
629 } 634 }
630 }; 635 };
631 636
632 int Push(SpecialRPOStackFrame* stack, int depth, BasicBlock* child, 637 int Push(ZoneVector<SpecialRPOStackFrame>& stack, int depth,
633 int unvisited) { 638 BasicBlock* child, int unvisited) {
634 if (child->rpo_number() == unvisited) { 639 if (child->rpo_number() == unvisited) {
635 stack[depth].block = child; 640 stack[depth].block = child;
636 stack[depth].index = 0; 641 stack[depth].index = 0;
637 child->set_rpo_number(kBlockOnStack); 642 child->set_rpo_number(kBlockOnStack);
638 return depth + 1; 643 return depth + 1;
639 } 644 }
640 return depth; 645 return depth;
641 } 646 }
642 647
643 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that 648 // We are hijacking the {ao_number} to enumerate loops temporarily. Note that
(...skipping 25 matching lines...) Expand all
669 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); 674 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number());
670 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); 675 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size()));
671 676
672 // Find correct insertion point within existing order. 677 // Find correct insertion point within existing order.
673 BlockList* insert_before = order_->FindForBlock(entry); 678 BlockList* insert_before = order_->FindForBlock(entry);
674 BlockList* insert_after = insert_before ? insert_before->next : NULL; 679 BlockList* insert_after = insert_before ? insert_before->next : NULL;
675 BlockList* order = insert_after; 680 BlockList* order = insert_after;
676 681
677 // Perform an iterative RPO traversal using an explicit stack, 682 // Perform an iterative RPO traversal using an explicit stack,
678 // recording backedges that form cycles. O(|B|). 683 // recording backedges that form cycles. O(|B|).
679 ZoneList<std::pair<BasicBlock*, size_t> > backedges(1, zone_); 684 DCHECK_LT(previous_block_count_, schedule_->BasicBlockCount());
680 SpecialRPOStackFrame* stack = zone_->NewArray<SpecialRPOStackFrame>( 685 stack_.resize(schedule_->BasicBlockCount() - previous_block_count_);
681 static_cast<int>(schedule_->BasicBlockCount())); 686 previous_block_count_ = schedule_->BasicBlockCount();
682 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1); 687 int stack_depth = Push(stack_, 0, entry, kBlockUnvisited1);
683 int num_loops = 0; 688 int num_loops = 0;
684 689
685 while (stack_depth > 0) { 690 while (stack_depth > 0) {
686 int current = stack_depth - 1; 691 int current = stack_depth - 1;
687 SpecialRPOStackFrame* frame = stack + current; 692 SpecialRPOStackFrame* frame = &stack_[current];
688 693
689 if (frame->block != end && 694 if (frame->block != end &&
690 frame->index < frame->block->SuccessorCount()) { 695 frame->index < frame->block->SuccessorCount()) {
691 // Process the next successor. 696 // Process the next successor.
692 BasicBlock* succ = frame->block->SuccessorAt(frame->index++); 697 BasicBlock* succ = frame->block->SuccessorAt(frame->index++);
693 if (succ->rpo_number() == kBlockVisited1) continue; 698 if (succ->rpo_number() == kBlockVisited1) continue;
694 if (succ->rpo_number() == kBlockOnStack) { 699 if (succ->rpo_number() == kBlockOnStack) {
695 // The successor is on the stack, so this is a backedge (cycle). 700 // The successor is on the stack, so this is a backedge (cycle).
696 backedges.Add( 701 backedges_.Add(Backedge(frame->block, frame->index - 1), zone_);
697 std::pair<BasicBlock*, size_t>(frame->block, frame->index - 1),
698 zone_);
699 if (!HasLoopNumber(succ)) { 702 if (!HasLoopNumber(succ)) {
700 // Assign a new loop number to the header if it doesn't have one. 703 // Assign a new loop number to the header if it doesn't have one.
701 SetLoopNumber(succ, num_loops++); 704 SetLoopNumber(succ, num_loops++);
702 } 705 }
703 } else { 706 } else {
704 // Push the successor onto the stack. 707 // Push the successor onto the stack.
705 DCHECK(succ->rpo_number() == kBlockUnvisited1); 708 DCHECK(succ->rpo_number() == kBlockUnvisited1);
706 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1); 709 stack_depth = Push(stack_, stack_depth, succ, kBlockUnvisited1);
707 } 710 }
708 } else { 711 } else {
709 // Finished with all successors; pop the stack and add the block. 712 // Finished with all successors; pop the stack and add the block.
710 order = order->Add(zone_, frame->block); 713 order = order->Add(zone_, frame->block);
711 frame->block->set_rpo_number(kBlockVisited1); 714 frame->block->set_rpo_number(kBlockVisited1);
712 stack_depth--; 715 stack_depth--;
713 } 716 }
714 } 717 }
715 718
716 // If no loops were encountered, then the order we computed was correct. 719 // If no loops were encountered, then the order we computed was correct.
717 if (num_loops != 0) { 720 if (num_loops != 0) {
718 // Otherwise, compute the loop information from the backedges in order 721 // Otherwise, compute the loop information from the backedges in order
719 // to perform a traversal that groups loop bodies together. 722 // to perform a traversal that groups loop bodies together.
720 ComputeLoopInfo(stack, num_loops, &backedges); 723 ComputeLoopInfo(stack_, num_loops, &backedges_);
721 724
722 // Initialize the "loop stack". Note the entry could be a loop header. 725 // Initialize the "loop stack". Note the entry could be a loop header.
723 LoopInfo* loop = 726 LoopInfo* loop =
724 HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL; 727 HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL;
725 order = NULL; 728 order = NULL;
726 729
727 // Perform an iterative post-order traversal, visiting loop bodies before 730 // Perform an iterative post-order traversal, visiting loop bodies before
728 // edges that lead out of loops. Visits each block once, but linking loop 731 // edges that lead out of loops. Visits each block once, but linking loop
729 // sections together is linear in the loop size, so overall is 732 // sections together is linear in the loop size, so overall is
730 // O(|B| + max(loop_depth) * max(|loop|)) 733 // O(|B| + max(loop_depth) * max(|loop|))
731 stack_depth = Push(stack, 0, entry, kBlockUnvisited2); 734 stack_depth = Push(stack_, 0, entry, kBlockUnvisited2);
732 while (stack_depth > 0) { 735 while (stack_depth > 0) {
733 SpecialRPOStackFrame* frame = stack + (stack_depth - 1); 736 SpecialRPOStackFrame* frame = &stack_[stack_depth - 1];
734 BasicBlock* block = frame->block; 737 BasicBlock* block = frame->block;
735 BasicBlock* succ = NULL; 738 BasicBlock* succ = NULL;
736 739
737 if (frame->index < block->SuccessorCount()) { 740 if (frame->index < block->SuccessorCount()) {
738 // Process the next normal successor. 741 // Process the next normal successor.
739 succ = block->SuccessorAt(frame->index++); 742 succ = block->SuccessorAt(frame->index++);
740 } else if (HasLoopNumber(block)) { 743 } else if (HasLoopNumber(block)) {
741 // Process additional outgoing edges from the loop header. 744 // Process additional outgoing edges from the loop header.
742 if (block->rpo_number() == kBlockOnStack) { 745 if (block->rpo_number() == kBlockOnStack) {
743 // Finish the loop body the first time the header is left on the 746 // Finish the loop body the first time the header is left on the
(...skipping 25 matching lines...) Expand all
769 // Process the next successor. 772 // Process the next successor.
770 if (succ->rpo_number() == kBlockOnStack) continue; 773 if (succ->rpo_number() == kBlockOnStack) continue;
771 if (succ->rpo_number() == kBlockVisited2) continue; 774 if (succ->rpo_number() == kBlockVisited2) continue;
772 DCHECK(succ->rpo_number() == kBlockUnvisited2); 775 DCHECK(succ->rpo_number() == kBlockUnvisited2);
773 if (loop != NULL && !loop->members->Contains(succ->id().ToInt())) { 776 if (loop != NULL && !loop->members->Contains(succ->id().ToInt())) {
774 // The successor is not in the current loop or any nested loop. 777 // The successor is not in the current loop or any nested loop.
775 // Add it to the outgoing edges of this loop and visit it later. 778 // Add it to the outgoing edges of this loop and visit it later.
776 loop->AddOutgoing(zone_, succ); 779 loop->AddOutgoing(zone_, succ);
777 } else { 780 } else {
778 // Push the successor onto the stack. 781 // Push the successor onto the stack.
779 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2); 782 stack_depth = Push(stack_, stack_depth, succ, kBlockUnvisited2);
780 if (HasLoopNumber(succ)) { 783 if (HasLoopNumber(succ)) {
781 // Push the inner loop onto the loop stack. 784 // Push the inner loop onto the loop stack.
782 DCHECK(GetLoopNumber(succ) < num_loops); 785 DCHECK(GetLoopNumber(succ) < num_loops);
783 LoopInfo* next = &loops_[GetLoopNumber(succ)]; 786 LoopInfo* next = &loops_[GetLoopNumber(succ)];
784 next->end = order; 787 next->end = order;
785 next->prev = loop; 788 next->prev = loop;
786 loop = next; 789 loop = next;
787 } 790 }
788 } 791 }
789 } else { 792 } else {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(), 860 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
858 current->loop_depth()); 861 current->loop_depth());
859 } else { 862 } else {
860 Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(), 863 Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(),
861 current->loop_header()->id().ToInt(), current->loop_depth()); 864 current->loop_header()->id().ToInt(), current->loop_depth());
862 } 865 }
863 } 866 }
864 } 867 }
865 868
866 // Computes loop membership from the backedges of the control flow graph. 869 // Computes loop membership from the backedges of the control flow graph.
867 void ComputeLoopInfo(SpecialRPOStackFrame* queue, size_t num_loops, 870 void ComputeLoopInfo(ZoneVector<SpecialRPOStackFrame>& queue,
868 ZoneList<std::pair<BasicBlock*, size_t> >* backedges) { 871 size_t num_loops, ZoneList<Backedge>* backedges) {
869 loops_.resize(num_loops, LoopInfo()); 872 loops_.resize(num_loops, LoopInfo());
870 873
871 // Compute loop membership starting from backedges. 874 // Compute loop membership starting from backedges.
872 // O(max(loop_depth) * max(|loop|) 875 // O(max(loop_depth) * max(|loop|)
873 for (int i = 0; i < backedges->length(); i++) { 876 for (int i = 0; i < backedges->length(); i++) {
874 BasicBlock* member = backedges->at(i).first; 877 BasicBlock* member = backedges->at(i).first;
875 BasicBlock* header = member->SuccessorAt(backedges->at(i).second); 878 BasicBlock* header = member->SuccessorAt(backedges->at(i).second);
876 size_t loop_num = GetLoopNumber(header); 879 size_t loop_num = GetLoopNumber(header);
877 if (loops_[loop_num].header == NULL) { 880 if (loops_[loop_num].header == NULL) {
878 loops_[loop_num].header = header; 881 loops_[loop_num].header = header;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 DCHECK(links == count); 1012 DCHECK(links == count);
1010 } 1013 }
1011 } 1014 }
1012 #endif // DEBUG 1015 #endif // DEBUG
1013 1016
1014 Zone* zone_; 1017 Zone* zone_;
1015 Schedule* schedule_; 1018 Schedule* schedule_;
1016 BlockList* order_; 1019 BlockList* order_;
1017 ZoneVector<LoopInfo> loops_; 1020 ZoneVector<LoopInfo> loops_;
1018 BasicBlock* beyond_end_; 1021 BasicBlock* beyond_end_;
1022 ZoneList<Backedge> backedges_;
1023 ZoneVector<SpecialRPOStackFrame> stack_;
1024 size_t previous_block_count_;
1019 }; 1025 };
1020 1026
1021 1027
1022 BasicBlockVector* Scheduler::ComputeSpecialRPO(ZonePool* zone_pool, 1028 BasicBlockVector* Scheduler::ComputeSpecialRPO(ZonePool* zone_pool,
1023 Schedule* schedule) { 1029 Schedule* schedule) {
1024 ZonePool::Scope zone_scope(zone_pool); 1030 ZonePool::Scope zone_scope(zone_pool);
1025 Zone* zone = zone_scope.zone(); 1031 Zone* zone = zone_scope.zone();
1026 1032
1027 SpecialRPONumberer numberer(zone, schedule); 1033 SpecialRPONumberer numberer(zone, schedule);
1028 numberer.ComputeSpecialRPO(); 1034 numberer.ComputeSpecialRPO();
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { 1474 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
1469 schedule_->SetBlockForNode(to, *i); 1475 schedule_->SetBlockForNode(to, *i);
1470 scheduled_nodes_[to->id().ToSize()].push_back(*i); 1476 scheduled_nodes_[to->id().ToSize()].push_back(*i);
1471 } 1477 }
1472 nodes->clear(); 1478 nodes->clear();
1473 } 1479 }
1474 1480
1475 } // namespace compiler 1481 } // namespace compiler
1476 } // namespace internal 1482 } // namespace internal
1477 } // namespace v8 1483 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698