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/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |