Chromium Code Reviews| 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 |