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

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

Issue 702683002: Avoid redundant work in scheduler loop header/depth calculation. (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 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 #if DEBUG 577 #if DEBUG
578 if (FLAG_trace_turbo_scheduler) PrintRPO(); 578 if (FLAG_trace_turbo_scheduler) PrintRPO();
579 VerifySpecialRPO(); 579 VerifySpecialRPO();
580 #endif 580 #endif
581 } 581 }
582 582
583 private: 583 private:
584 // TODO(mstarzinger): Only for Scheduler::GenerateImmediateDominatorTree. 584 // TODO(mstarzinger): Only for Scheduler::GenerateImmediateDominatorTree.
585 friend class Scheduler; 585 friend class Scheduler;
586 586
587 // Numbering for BasicBlockData.rpo_number_ for this block traversal: 587 // Numbering for BasicBlock::rpo_number for this block traversal:
588 static const int kBlockOnStack = -2; 588 static const int kBlockOnStack = -2;
589 static const int kBlockVisited1 = -3; 589 static const int kBlockVisited1 = -3;
590 static const int kBlockVisited2 = -4; 590 static const int kBlockVisited2 = -4;
591 static const int kBlockUnvisited1 = -1; 591 static const int kBlockUnvisited1 = -1;
592 static const int kBlockUnvisited2 = kBlockVisited1; 592 static const int kBlockUnvisited2 = kBlockVisited1;
593 593
594 struct SpecialRPOStackFrame { 594 struct SpecialRPOStackFrame {
595 BasicBlock* block; 595 BasicBlock* block;
596 size_t index; 596 size_t index;
597 }; 597 };
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 // mutating any existing order so that the result is still valid. 667 // mutating any existing order so that the result is still valid.
668 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) { 668 void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) {
669 // RPO should not have been serialized for this schedule yet. 669 // RPO should not have been serialized for this schedule yet.
670 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number()); 670 CHECK_EQ(kBlockUnvisited1, schedule_->start()->ao_number());
671 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number()); 671 CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number());
672 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size())); 672 CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size()));
673 673
674 // Find correct insertion point within existing order. 674 // Find correct insertion point within existing order.
675 BlockList* insert_head = order_->FindForBlock(entry); 675 BlockList* insert_head = order_->FindForBlock(entry);
676 BlockList* insert_tail = insert_head == NULL ? NULL : insert_head->next; 676 BlockList* insert_tail = insert_head == NULL ? NULL : insert_head->next;
677 BlockList* order = insert_tail;
677 678
678 // Perform an iterative RPO traversal using an explicit stack, 679 // Perform an iterative RPO traversal using an explicit stack,
679 // recording backedges that form cycles. O(|B|). 680 // recording backedges that form cycles. O(|B|).
680 ZoneList<std::pair<BasicBlock*, size_t> > backedges(1, zone_); 681 ZoneList<std::pair<BasicBlock*, size_t> > backedges(1, zone_);
681 SpecialRPOStackFrame* stack = zone_->NewArray<SpecialRPOStackFrame>( 682 SpecialRPOStackFrame* stack = zone_->NewArray<SpecialRPOStackFrame>(
682 static_cast<int>(schedule_->BasicBlockCount())); 683 static_cast<int>(schedule_->BasicBlockCount()));
683 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1); 684 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1);
684 int num_loops = 0; 685 int num_loops = 0;
685 686
686 while (stack_depth > 0) { 687 while (stack_depth > 0) {
(...skipping 14 matching lines...) Expand all
701 // Assign a new loop number to the header if it doesn't have one. 702 // Assign a new loop number to the header if it doesn't have one.
702 SetLoopNumber(succ, num_loops++); 703 SetLoopNumber(succ, num_loops++);
703 } 704 }
704 } else { 705 } else {
705 // Push the successor onto the stack. 706 // Push the successor onto the stack.
706 DCHECK(succ->rpo_number() == kBlockUnvisited1); 707 DCHECK(succ->rpo_number() == kBlockUnvisited1);
707 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1); 708 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1);
708 } 709 }
709 } else { 710 } else {
710 // Finished with all successors; pop the stack and add the block. 711 // Finished with all successors; pop the stack and add the block.
711 insert_tail = insert_tail->Add(zone_, frame->block); 712 order = order->Add(zone_, frame->block);
712 frame->block->set_rpo_number(kBlockVisited1); 713 frame->block->set_rpo_number(kBlockVisited1);
713 stack_depth--; 714 stack_depth--;
714 } 715 }
715 } 716 }
716 717
717 // Insert the result into any existing order.
718 if (insert_head == NULL) {
719 order_ = insert_tail;
720 } else {
721 insert_head->next = insert_tail->next;
722 }
723
724 // If no loops were encountered, then the order we computed was correct. 718 // If no loops were encountered, then the order we computed was correct.
725 if (num_loops != 0) { 719 if (num_loops != 0) {
726 // Otherwise, compute the loop information from the backedges in order 720 // Otherwise, compute the loop information from the backedges in order
727 // to perform a traversal that groups loop bodies together. 721 // to perform a traversal that groups loop bodies together.
728 ComputeLoopInfo(stack, num_loops, &backedges); 722 ComputeLoopInfo(stack, num_loops, &backedges);
729 723
730 // Initialize the "loop stack". Note the entry could be a loop header. 724 // Initialize the "loop stack". Note the entry could be a loop header.
731 LoopInfo* loop = 725 LoopInfo* loop =
732 HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL; 726 HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL;
733 order_ = NULL; 727 order = NULL;
734 728
735 // Perform an iterative post-order traversal, visiting loop bodies before 729 // Perform an iterative post-order traversal, visiting loop bodies before
736 // edges that lead out of loops. Visits each block once, but linking loop 730 // edges that lead out of loops. Visits each block once, but linking loop
737 // sections together is linear in the loop size, so overall is 731 // sections together is linear in the loop size, so overall is
738 // O(|B| + max(loop_depth) * max(|loop|)) 732 // O(|B| + max(loop_depth) * max(|loop|))
739 stack_depth = Push(stack, 0, entry, kBlockUnvisited2); 733 stack_depth = Push(stack, 0, entry, kBlockUnvisited2);
740 while (stack_depth > 0) { 734 while (stack_depth > 0) {
741 SpecialRPOStackFrame* frame = stack + (stack_depth - 1); 735 SpecialRPOStackFrame* frame = stack + (stack_depth - 1);
742 BasicBlock* block = frame->block; 736 BasicBlock* block = frame->block;
743 BasicBlock* succ = NULL; 737 BasicBlock* succ = NULL;
744 738
745 if (frame->index < block->SuccessorCount()) { 739 if (frame->index < block->SuccessorCount()) {
746 // Process the next normal successor. 740 // Process the next normal successor.
747 succ = block->SuccessorAt(frame->index++); 741 succ = block->SuccessorAt(frame->index++);
748 } else if (HasLoopNumber(block)) { 742 } else if (HasLoopNumber(block)) {
749 // Process additional outgoing edges from the loop header. 743 // Process additional outgoing edges from the loop header.
750 if (block->rpo_number() == kBlockOnStack) { 744 if (block->rpo_number() == kBlockOnStack) {
751 // Finish the loop body the first time the header is left on the 745 // Finish the loop body the first time the header is left on the
752 // stack. 746 // stack.
753 DCHECK(loop != NULL && loop->header == block); 747 DCHECK(loop != NULL && loop->header == block);
754 loop->start = order_->Add(zone_, block); 748 loop->start = order->Add(zone_, block);
755 order_ = loop->end; 749 order = loop->end;
756 block->set_rpo_number(kBlockVisited2); 750 block->set_rpo_number(kBlockVisited2);
757 // Pop the loop stack and continue visiting outgoing edges within 751 // Pop the loop stack and continue visiting outgoing edges within
758 // the context of the outer loop, if any. 752 // the context of the outer loop, if any.
759 loop = loop->prev; 753 loop = loop->prev;
760 // We leave the loop header on the stack; the rest of this iteration 754 // We leave the loop header on the stack; the rest of this iteration
761 // and later iterations will go through its outgoing edges list. 755 // and later iterations will go through its outgoing edges list.
762 } 756 }
763 757
764 // Use the next outgoing edge if there are any. 758 // Use the next outgoing edge if there are any.
765 int outgoing_index = 759 int outgoing_index =
(...skipping 16 matching lines...) Expand all
782 // The successor is not in the current loop or any nested loop. 776 // The successor is not in the current loop or any nested loop.
783 // Add it to the outgoing edges of this loop and visit it later. 777 // Add it to the outgoing edges of this loop and visit it later.
784 loop->AddOutgoing(zone_, succ); 778 loop->AddOutgoing(zone_, succ);
785 } else { 779 } else {
786 // Push the successor onto the stack. 780 // Push the successor onto the stack.
787 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2); 781 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2);
788 if (HasLoopNumber(succ)) { 782 if (HasLoopNumber(succ)) {
789 // Push the inner loop onto the loop stack. 783 // Push the inner loop onto the loop stack.
790 DCHECK(GetLoopNumber(succ) < num_loops); 784 DCHECK(GetLoopNumber(succ) < num_loops);
791 LoopInfo* next = &loops_[GetLoopNumber(succ)]; 785 LoopInfo* next = &loops_[GetLoopNumber(succ)];
792 next->end = order_; 786 next->end = order;
793 next->prev = loop; 787 next->prev = loop;
794 loop = next; 788 loop = next;
795 } 789 }
796 } 790 }
797 } else { 791 } else {
798 // Finished with all successors of the current block. 792 // Finished with all successors of the current block.
799 if (HasLoopNumber(block)) { 793 if (HasLoopNumber(block)) {
800 // If we are going to pop a loop header, then add its entire body. 794 // If we are going to pop a loop header, then add its entire body.
801 LoopInfo* info = &loops_[GetLoopNumber(block)]; 795 LoopInfo* info = &loops_[GetLoopNumber(block)];
802 for (BlockList* l = info->start; true; l = l->next) { 796 for (BlockList* l = info->start; true; l = l->next) {
803 if (l->next == info->end) { 797 if (l->next == info->end) {
804 l->next = order_; 798 l->next = order;
805 info->end = order_; 799 info->end = order;
806 break; 800 break;
807 } 801 }
808 } 802 }
809 order_ = info->start; 803 order = info->start;
810 } else { 804 } else {
811 // Pop a single node off the stack and add it to the order. 805 // Pop a single node off the stack and add it to the order.
812 order_ = order_->Add(zone_, block); 806 order = order->Add(zone_, block);
813 block->set_rpo_number(kBlockVisited2); 807 block->set_rpo_number(kBlockVisited2);
814 } 808 }
815 stack_depth--; 809 stack_depth--;
816 } 810 }
817 } 811 }
818 } 812 }
819 813
814 // Insert result into existing order.
815 if (insert_head == NULL) {
816 order_ = order;
817 } else {
818 insert_head->next = order->next;
819 }
820
820 // Compute the correct loop headers and set the correct loop ends. 821 // Compute the correct loop headers and set the correct loop ends.
821 LoopInfo* current_loop = NULL; 822 LoopInfo* current_loop = NULL;
822 BasicBlock* current_header = NULL; 823 BasicBlock* current_header = entry->loop_header();
823 int loop_depth = 0; 824 int32_t loop_depth = entry->loop_depth();
824 for (BlockList* l = order_; l != NULL; l = l->next) { 825 for (BlockList* l = order; l != insert_tail; l = l->next) {
825 BasicBlock* current = l->block; 826 BasicBlock* current = l->block;
826 827
828 // Reset BasicBlock::rpo_number again.
829 current->set_rpo_number(-1);
Jarin 2014/11/05 01:03:56 Could we use the constant defined above? (kBlockUn
Michael Starzinger 2014/11/05 10:18:40 Done.
830
827 // Finish the previous loop(s) if we just exited them. 831 // Finish the previous loop(s) if we just exited them.
828 while (current_header != NULL && current == current_header->loop_end()) { 832 while (current_header != NULL && current == current_header->loop_end()) {
829 DCHECK(current_header->IsLoopHeader()); 833 DCHECK(current_header->IsLoopHeader());
830 DCHECK(current_loop != NULL); 834 DCHECK(current_loop != NULL);
831 current_loop = current_loop->prev; 835 current_loop = current_loop->prev;
832 current_header = current_loop == NULL ? NULL : current_loop->header; 836 current_header = current_loop == NULL ? NULL : current_loop->header;
833 --loop_depth; 837 --loop_depth;
834 } 838 }
835 current->set_loop_header(current_header); 839 current->set_loop_header(current_header);
836 840
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 if (FLAG_trace_turbo_scheduler) { 1427 if (FLAG_trace_turbo_scheduler) {
1424 OFStream os(stdout); 1428 OFStream os(stdout);
1425 os << "Schedule before control flow fusion:\n" << *schedule_; 1429 os << "Schedule before control flow fusion:\n" << *schedule_;
1426 } 1430 }
1427 1431
1428 // Iterate on phase 1: Build control-flow graph. 1432 // Iterate on phase 1: Build control-flow graph.
1429 CFGBuilder cfg_builder(zone_, this); 1433 CFGBuilder cfg_builder(zone_, this);
1430 cfg_builder.Run(block, node); 1434 cfg_builder.Run(block, node);
1431 1435
1432 // Iterate on phase 2: Compute special RPO and dominator tree. 1436 // Iterate on phase 2: Compute special RPO and dominator tree.
1437 special_rpo_->UpdateSpecialRPO(block, schedule_->block(node));
1433 // TODO(mstarzinger): Currently "iterate on" means "re-run". Fix that. 1438 // TODO(mstarzinger): Currently "iterate on" means "re-run". Fix that.
1434 for (BasicBlock* block : schedule_->all_blocks_) { 1439 for (BasicBlock* block : schedule_->all_blocks_) {
1435 block->set_rpo_number(-1);
1436 block->set_dominator_depth(-1); 1440 block->set_dominator_depth(-1);
1437 block->set_dominator(NULL); 1441 block->set_dominator(NULL);
1438 } 1442 }
1439 special_rpo_->UpdateSpecialRPO(block, schedule_->block(node));
1440 GenerateImmediateDominatorTree(); 1443 GenerateImmediateDominatorTree();
1441 1444
1442 // Move previously planned nodes. 1445 // Move previously planned nodes.
1443 // TODO(mstarzinger): Improve that by supporting bulk moves. 1446 // TODO(mstarzinger): Improve that by supporting bulk moves.
1444 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_)); 1447 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_));
1445 MovePlannedNodes(block, schedule_->block(node)); 1448 MovePlannedNodes(block, schedule_->block(node));
1446 1449
1447 if (FLAG_trace_turbo_scheduler) { 1450 if (FLAG_trace_turbo_scheduler) {
1448 OFStream os(stdout); 1451 OFStream os(stdout);
1449 os << "Schedule after control flow fusion:\n" << *schedule_; 1452 os << "Schedule after control flow fusion:\n" << *schedule_;
1450 } 1453 }
1451 } 1454 }
1452 1455
1453 1456
1454 void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) { 1457 void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) {
1455 Trace("Move planned nodes from B%d to B%d\n", from->id().ToInt(), 1458 Trace("Move planned nodes from B%d to B%d\n", from->id().ToInt(),
1456 to->id().ToInt()); 1459 to->id().ToInt());
1457 NodeVector* nodes = &(scheduled_nodes_[from->id().ToSize()]); 1460 NodeVector* nodes = &(scheduled_nodes_[from->id().ToSize()]);
1458 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { 1461 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
1459 schedule_->SetBlockForNode(to, *i); 1462 schedule_->SetBlockForNode(to, *i);
1460 scheduled_nodes_[to->id().ToSize()].push_back(*i); 1463 scheduled_nodes_[to->id().ToSize()].push_back(*i);
1461 } 1464 }
1462 nodes->clear(); 1465 nodes->clear();
1463 } 1466 }
1464 1467
1465 } // namespace compiler 1468 } // namespace compiler
1466 } // namespace internal 1469 } // namespace internal
1467 } // namespace v8 1470 } // 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