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

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

Issue 677683002: Fix bugs in Scheduler hoisting and RPO loop bounds computations. (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 | test/cctest/compiler/test-scheduler.cc » ('j') | 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/compiler/graph.h" 10 #include "src/compiler/graph.h"
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 } 554 }
555 stack_depth--; 555 stack_depth--;
556 } 556 }
557 } 557 }
558 } 558 }
559 559
560 // Construct the final order from the list. 560 // Construct the final order from the list.
561 BasicBlockVector* final_order = schedule_->rpo_order(); 561 BasicBlockVector* final_order = schedule_->rpo_order();
562 order->Serialize(final_order); 562 order->Serialize(final_order);
563 563
564 // Compute the correct loop header for every block and set the correct loop 564 // Compute the correct loop headersand set the correct loop ends.
Michael Starzinger 2014/10/24 13:36:43 nit: Missing space.
titzer 2014/10/24 13:41:45 Done.
565 // ends.
566 LoopInfo* current_loop = NULL; 565 LoopInfo* current_loop = NULL;
567 BasicBlock* current_header = NULL; 566 BasicBlock* current_header = NULL;
568 int loop_depth = 0; 567 int loop_depth = 0;
569 for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end(); 568 for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
570 ++i) { 569 ++i) {
571 BasicBlock* current = *i; 570 BasicBlock* current = *i;
571
572 // Finish the previous loop(s) if we just exited them.
573 while (current_header != NULL &&
574 current->rpo_number() >= current_header->loop_end()) {
575 DCHECK(current_header->IsLoopHeader());
576 DCHECK(current_loop != NULL);
577 current_loop = current_loop->prev;
578 current_header = current_loop == NULL ? NULL : current_loop->header;
579 --loop_depth;
580 }
572 current->set_loop_header(current_header); 581 current->set_loop_header(current_header);
582
583 // Push a new loop onto the stack if this loop is a loop header.
573 if (current->IsLoopHeader()) { 584 if (current->IsLoopHeader()) {
574 loop_depth++; 585 loop_depth++;
575 current_loop = &loops[current->loop_end()]; 586 current_loop = &loops[current->loop_end()];
576 BlockList* end = current_loop->end; 587 BlockList* end = current_loop->end;
577 current->set_loop_end(end == NULL 588 current->set_loop_end(end == NULL
578 ? static_cast<int>(final_order->size()) 589 ? static_cast<int>(final_order->size())
579 : end->block->rpo_number()); 590 : end->block->rpo_number());
580 current_header = current_loop->header; 591 current_header = current_loop->header;
581 Trace("B%d is a loop header, increment loop depth to %d\n", 592 Trace("B%d is a loop header, increment loop depth to %d\n",
582 current->id().ToInt(), loop_depth); 593 current->id().ToInt(), loop_depth);
583 } else {
584 while (current_header != NULL &&
585 current->rpo_number() >= current_header->loop_end()) {
586 DCHECK(current_header->IsLoopHeader());
587 DCHECK(current_loop != NULL);
588 current_loop = current_loop->prev;
589 current_header = current_loop == NULL ? NULL : current_loop->header;
590 --loop_depth;
591 }
592 } 594 }
595
593 current->set_loop_depth(loop_depth); 596 current->set_loop_depth(loop_depth);
597
594 if (current->loop_header() == NULL) { 598 if (current->loop_header() == NULL) {
595 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(), 599 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
596 current->loop_depth()); 600 current->loop_depth());
597 } else { 601 } else {
598 Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(), 602 Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(),
599 current->loop_header()->id().ToInt(), current->loop_depth()); 603 current->loop_header()->id().ToInt(), current->loop_depth());
600 } 604 }
601 } 605 }
602 606
603 // Compute the assembly order (non-deferred code first, deferred code 607 // Compute the assembly order (non-deferred code first, deferred code
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 bool membership = loops[j].members->Contains(bid.ToInt()); 752 bool membership = loops[j].members->Contains(bid.ToInt());
749 bool range = loops[j].header->LoopContains(block); 753 bool range = loops[j].header->LoopContains(block);
750 os << (membership ? " |" : " "); 754 os << (membership ? " |" : " ");
751 os << (range ? "x" : " "); 755 os << (range ? "x" : " ");
752 } 756 }
753 os << " B" << bid << ": "; 757 os << " B" << bid << ": ";
754 if (block->loop_end() >= 0) { 758 if (block->loop_end() >= 0) {
755 os << " range: [" << block->rpo_number() << ", " << block->loop_end() 759 os << " range: [" << block->rpo_number() << ", " << block->loop_end()
756 << ")"; 760 << ")";
757 } 761 }
762 if (block->loop_header() != NULL) {
763 os << " header: B" << block->loop_header()->id();
764 }
765 if (block->loop_depth() > 0) {
766 os << " depth: " << block->loop_depth();
767 }
758 os << "\n"; 768 os << "\n";
759 } 769 }
760 } 770 }
761 771
762 void VerifySpecialRPO(int num_loops, LoopInfo* loops, 772 void VerifySpecialRPO(int num_loops, LoopInfo* loops,
763 BasicBlockVector* order) { 773 BasicBlockVector* order) {
764 DCHECK(order->size() > 0); 774 DCHECK(order->size() > 0);
765 DCHECK((*order)[0]->id().ToInt() == 0); // entry should be first. 775 DCHECK((*order)[0]->id().ToInt() == 0); // entry should be first.
766 776
767 for (int i = 0; i < num_loops; i++) { 777 for (int i = 0; i < num_loops; i++) {
768 LoopInfo* loop = &loops[i]; 778 LoopInfo* loop = &loops[i];
769 BasicBlock* header = loop->header; 779 BasicBlock* header = loop->header;
770 780
771 DCHECK(header != NULL); 781 DCHECK(header != NULL);
772 DCHECK(header->rpo_number() >= 0); 782 DCHECK(header->rpo_number() >= 0);
773 DCHECK(header->rpo_number() < static_cast<int>(order->size())); 783 DCHECK(header->rpo_number() < static_cast<int>(order->size()));
774 DCHECK(header->loop_end() >= 0); 784 DCHECK(header->loop_end() >= 0);
775 DCHECK(header->loop_end() <= static_cast<int>(order->size())); 785 DCHECK(header->loop_end() <= static_cast<int>(order->size()));
776 DCHECK(header->loop_end() > header->rpo_number()); 786 DCHECK(header->loop_end() > header->rpo_number());
787 DCHECK(header->loop_header() != header);
777 788
778 // Verify the start ... end list relationship. 789 // Verify the start ... end list relationship.
779 int links = 0; 790 int links = 0;
780 BlockList* l = loop->start; 791 BlockList* l = loop->start;
781 DCHECK(l != NULL && l->block == header); 792 DCHECK(l != NULL && l->block == header);
782 bool end_found; 793 bool end_found;
783 while (true) { 794 while (true) {
784 if (l == NULL || l == loop->end) { 795 if (l == NULL || l == loop->end) {
785 end_found = (loop->end == l); 796 end_found = (loop->end == l);
786 break; 797 break;
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 DCHECK_NOT_NULL(block); 1077 DCHECK_NOT_NULL(block);
1067 1078
1068 int min_rpo = scheduler_->GetData(node)->minimum_block_->rpo_number(); 1079 int min_rpo = scheduler_->GetData(node)->minimum_block_->rpo_number();
1069 Trace("Schedule late of #%d:%s is B%d at loop depth %d, minimum_rpo = %d\n", 1080 Trace("Schedule late of #%d:%s is B%d at loop depth %d, minimum_rpo = %d\n",
1070 node->id(), node->op()->mnemonic(), block->id().ToInt(), 1081 node->id(), node->op()->mnemonic(), block->id().ToInt(),
1071 block->loop_depth(), min_rpo); 1082 block->loop_depth(), min_rpo);
1072 1083
1073 // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively 1084 // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
1074 // into enclosing loop pre-headers until they would preceed their 1085 // into enclosing loop pre-headers until they would preceed their
1075 // ScheduleEarly position. 1086 // ScheduleEarly position.
1076 BasicBlock* hoist_block = block; 1087 BasicBlock* hoist_block = GetPreHeader(block);
1077 while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) { 1088 while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) {
1078 if (hoist_block->loop_depth() < block->loop_depth()) { 1089 Trace(" hoisting #%d:%s to block %d\n", node->id(),
1079 block = hoist_block; 1090 node->op()->mnemonic(), hoist_block->id().ToInt());
1080 Trace(" hoisting #%d:%s to block %d\n", node->id(), 1091 DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
1081 node->op()->mnemonic(), block->id().ToInt()); 1092 block = hoist_block;
1082 } 1093 hoist_block = GetPreHeader(hoist_block);
1083 // Try to hoist to the pre-header of the loop header.
1084 hoist_block = hoist_block->loop_header();
1085 if (hoist_block != NULL) {
1086 BasicBlock* pre_header = hoist_block->dominator();
1087 DCHECK(pre_header == NULL ||
1088 *hoist_block->predecessors_begin() == pre_header);
1089 Trace(
1090 " hoist to pre-header B%d of loop header B%d, depth would be %d\n",
1091 pre_header->id().ToInt(), hoist_block->id().ToInt(),
1092 pre_header->loop_depth());
1093 hoist_block = pre_header;
1094 }
1095 } 1094 }
1096 1095
1097 ScheduleNode(block, node); 1096 ScheduleNode(block, node);
1098 } 1097 }
1099 1098
1099 BasicBlock* GetPreHeader(BasicBlock* block) {
Michael Starzinger 2014/10/24 13:36:43 nit: Please make this private (i.e. move it down t
titzer 2014/10/24 13:41:45 Done.
1100 if (block->IsLoopHeader()) {
1101 return block->dominator();
1102 } else if (block->loop_header() != NULL) {
1103 return block->loop_header()->dominator();
1104 } else {
1105 return NULL;
1106 }
1107 }
1108
1100 private: 1109 private:
1101 BasicBlock* GetCommonDominatorOfUses(Node* node) { 1110 BasicBlock* GetCommonDominatorOfUses(Node* node) {
1102 BasicBlock* block = NULL; 1111 BasicBlock* block = NULL;
1103 Node::Uses uses = node->uses(); 1112 Node::Uses uses = node->uses();
1104 for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) { 1113 for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
1105 BasicBlock* use_block = GetBlockForUse(i.edge()); 1114 BasicBlock* use_block = GetBlockForUse(i.edge());
1106 block = block == NULL ? use_block : use_block == NULL 1115 block = block == NULL ? use_block : use_block == NULL
1107 ? block 1116 ? block
1108 : scheduler_->GetCommonDominator( 1117 : scheduler_->GetCommonDominator(
1109 block, use_block); 1118 block, use_block);
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 start->ReplaceInput(NodeProperties::FirstControlIndex(start), block_start); 1286 start->ReplaceInput(NodeProperties::FirstControlIndex(start), block_start);
1278 1287
1279 Trace(" Connecting floating control start %d:%s to %d:%s\n", start->id(), 1288 Trace(" Connecting floating control start %d:%s to %d:%s\n", start->id(),
1280 start->op()->mnemonic(), block_start->id(), 1289 start->op()->mnemonic(), block_start->id(),
1281 block_start->op()->mnemonic()); 1290 block_start->op()->mnemonic());
1282 } 1291 }
1283 1292
1284 } // namespace compiler 1293 } // namespace compiler
1285 } // namespace internal 1294 } // namespace internal
1286 } // namespace v8 1295 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/compiler/test-scheduler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698