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

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

Issue 606403003: Refactor BasicBlock, no inheritance from GenericNode (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Attempt n+1 to address the size_t madness Created 6 years, 2 months 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 | « src/compiler/scheduler.h ('k') | src/compiler/verifier.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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 ConnectReturn(node); 115 ConnectReturn(node);
116 break; 116 break;
117 default: 117 default:
118 break; 118 break;
119 } 119 }
120 } 120 }
121 121
122 void BuildBlockForNode(Node* node) { 122 void BuildBlockForNode(Node* node) {
123 if (schedule_->block(node) == NULL) { 123 if (schedule_->block(node) == NULL) {
124 BasicBlock* block = schedule_->NewBasicBlock(); 124 BasicBlock* block = schedule_->NewBasicBlock();
125 Trace("Create block B%d for #%d:%s\n", block->id(), node->id(), 125 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(),
126 node->op()->mnemonic()); 126 node->op()->mnemonic());
127 FixNode(block, node); 127 FixNode(block, node);
128 } 128 }
129 } 129 }
130 130
131 void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a, 131 void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a,
132 IrOpcode::Value b) { 132 IrOpcode::Value b) {
133 Node* successors[2]; 133 Node* successors[2];
134 CollectSuccessorProjections(node, successors, a, b); 134 CollectSuccessorProjections(node, successors, a, b);
135 BuildBlockForNode(successors[0]); 135 BuildBlockForNode(successors[0]);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 Node* return_block_node = NodeProperties::GetControlInput(ret); 202 Node* return_block_node = NodeProperties::GetControlInput(ret);
203 BasicBlock* return_block = schedule_->block(return_block_node); 203 BasicBlock* return_block = schedule_->block(return_block_node);
204 TraceConnect(ret, return_block, NULL); 204 TraceConnect(ret, return_block, NULL);
205 schedule_->AddReturn(return_block, ret); 205 schedule_->AddReturn(return_block, ret);
206 } 206 }
207 207
208 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { 208 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
209 DCHECK_NE(NULL, block); 209 DCHECK_NE(NULL, block);
210 if (succ == NULL) { 210 if (succ == NULL) {
211 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(), 211 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
212 block->id()); 212 block->id().ToInt());
213 } else { 213 } else {
214 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(), 214 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
215 block->id(), succ->id()); 215 block->id().ToInt(), succ->id().ToInt());
216 } 216 }
217 } 217 }
218 }; 218 };
219 219
220 220
221 Scheduler::SchedulerData Scheduler::DefaultSchedulerData() { 221 Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
222 SchedulerData def = {0, 0, false, false, kUnknown}; 222 SchedulerData def = {0, 0, false, false, kUnknown};
223 return def; 223 return def;
224 } 224 }
225 225
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_)); 304 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_));
305 } 305 }
306 306
307 307
308 BasicBlock* Scheduler::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) { 308 BasicBlock* Scheduler::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) {
309 while (b1 != b2) { 309 while (b1 != b2) {
310 int b1_rpo = GetRPONumber(b1); 310 int b1_rpo = GetRPONumber(b1);
311 int b2_rpo = GetRPONumber(b2); 311 int b2_rpo = GetRPONumber(b2);
312 DCHECK(b1_rpo != b2_rpo); 312 DCHECK(b1_rpo != b2_rpo);
313 if (b1_rpo < b2_rpo) { 313 if (b1_rpo < b2_rpo) {
314 b2 = b2->dominator_; 314 b2 = b2->dominator();
315 } else { 315 } else {
316 b1 = b1->dominator_; 316 b1 = b1->dominator();
317 } 317 }
318 } 318 }
319 return b1; 319 return b1;
320 } 320 }
321 321
322 322
323 void Scheduler::GenerateImmediateDominatorTree() { 323 void Scheduler::GenerateImmediateDominatorTree() {
324 // Build the dominator graph. TODO(danno): consider using Lengauer & Tarjan's 324 // Build the dominator graph. TODO(danno): consider using Lengauer & Tarjan's
325 // if this becomes really slow. 325 // if this becomes really slow.
326 Trace("------------ IMMEDIATE BLOCK DOMINATORS -----------\n"); 326 Trace("------------ IMMEDIATE BLOCK DOMINATORS -----------\n");
327 for (size_t i = 0; i < schedule_->rpo_order_.size(); i++) { 327 for (size_t i = 0; i < schedule_->rpo_order_.size(); i++) {
328 BasicBlock* current_rpo = schedule_->rpo_order_[i]; 328 BasicBlock* current_rpo = schedule_->rpo_order_[i];
329 if (current_rpo != schedule_->start()) { 329 if (current_rpo != schedule_->start()) {
330 BasicBlock::Predecessors::iterator current_pred = 330 BasicBlock::Predecessors::iterator current_pred =
331 current_rpo->predecessors().begin(); 331 current_rpo->predecessors_begin();
332 BasicBlock::Predecessors::iterator end = 332 BasicBlock::Predecessors::iterator end = current_rpo->predecessors_end();
333 current_rpo->predecessors().end();
334 DCHECK(current_pred != end); 333 DCHECK(current_pred != end);
335 BasicBlock* dominator = *current_pred; 334 BasicBlock* dominator = *current_pred;
336 ++current_pred; 335 ++current_pred;
337 // For multiple predecessors, walk up the rpo ordering until a common 336 // For multiple predecessors, walk up the rpo ordering until a common
338 // dominator is found. 337 // dominator is found.
339 int current_rpo_pos = GetRPONumber(current_rpo); 338 int current_rpo_pos = GetRPONumber(current_rpo);
340 while (current_pred != end) { 339 while (current_pred != end) {
341 // Don't examine backwards edges 340 // Don't examine backwards edges
342 BasicBlock* pred = *current_pred; 341 BasicBlock* pred = *current_pred;
343 if (GetRPONumber(pred) < current_rpo_pos) { 342 if (GetRPONumber(pred) < current_rpo_pos) {
344 dominator = GetCommonDominator(dominator, *current_pred); 343 dominator = GetCommonDominator(dominator, *current_pred);
345 } 344 }
346 ++current_pred; 345 ++current_pred;
347 } 346 }
348 current_rpo->dominator_ = dominator; 347 current_rpo->set_dominator(dominator);
349 Trace("Block %d's idom is %d\n", current_rpo->id(), dominator->id()); 348 Trace("Block %d's idom is %d\n", current_rpo->id(),
349 dominator->id().ToInt());
350 } 350 }
351 } 351 }
352 } 352 }
353 353
354 354
355 class ScheduleEarlyNodeVisitor : public NullNodeVisitor { 355 class ScheduleEarlyNodeVisitor : public NullNodeVisitor {
356 public: 356 public:
357 explicit ScheduleEarlyNodeVisitor(Scheduler* scheduler) 357 explicit ScheduleEarlyNodeVisitor(Scheduler* scheduler)
358 : has_changed_rpo_constraints_(true), 358 : has_changed_rpo_constraints_(true),
359 scheduler_(scheduler), 359 scheduler_(scheduler),
360 schedule_(scheduler->schedule_) {} 360 schedule_(scheduler->schedule_) {}
361 361
362 GenericGraphVisit::Control Pre(Node* node) { 362 GenericGraphVisit::Control Pre(Node* node) {
363 int max_rpo = 0; 363 int max_rpo = 0;
364 // Fixed nodes already know their schedule early position. 364 // Fixed nodes already know their schedule early position.
365 if (scheduler_->GetPlacement(node) == Scheduler::kFixed) { 365 if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
366 BasicBlock* block = schedule_->block(node); 366 BasicBlock* block = schedule_->block(node);
367 DCHECK(block != NULL); 367 DCHECK(block != NULL);
368 max_rpo = block->rpo_number_; 368 max_rpo = block->rpo_number();
369 if (scheduler_->GetData(node)->minimum_rpo_ != max_rpo) { 369 if (scheduler_->GetData(node)->minimum_rpo_ != max_rpo) {
370 has_changed_rpo_constraints_ = true; 370 has_changed_rpo_constraints_ = true;
371 } 371 }
372 scheduler_->GetData(node)->minimum_rpo_ = max_rpo; 372 scheduler_->GetData(node)->minimum_rpo_ = max_rpo;
373 Trace("Preschedule #%d:%s minimum_rpo = %d\n", node->id(), 373 Trace("Preschedule #%d:%s minimum_rpo = %d\n", node->id(),
374 node->op()->mnemonic(), max_rpo); 374 node->op()->mnemonic(), max_rpo);
375 } 375 }
376 return GenericGraphVisit::CONTINUE; 376 return GenericGraphVisit::CONTINUE;
377 } 377 }
378 378
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 ? block 506 ? block
507 : scheduler_->GetCommonDominator( 507 : scheduler_->GetCommonDominator(
508 block, use_block); 508 block, use_block);
509 } 509 }
510 DCHECK(block != NULL); 510 DCHECK(block != NULL);
511 511
512 int min_rpo = data->minimum_rpo_; 512 int min_rpo = data->minimum_rpo_;
513 Trace( 513 Trace(
514 "Schedule late conservative for #%d:%s is B%d at loop depth %d, " 514 "Schedule late conservative for #%d:%s is B%d at loop depth %d, "
515 "minimum_rpo = %d\n", 515 "minimum_rpo = %d\n",
516 node->id(), node->op()->mnemonic(), block->id(), block->loop_depth_, 516 node->id(), node->op()->mnemonic(), block->id().ToInt(),
517 min_rpo); 517 block->loop_depth(), min_rpo);
518 // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively 518 // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
519 // into enclosing loop pre-headers until they would preceed their 519 // into enclosing loop pre-headers until they would preceed their
520 // ScheduleEarly position. 520 // ScheduleEarly position.
521 BasicBlock* hoist_block = block; 521 BasicBlock* hoist_block = block;
522 while (hoist_block != NULL && hoist_block->rpo_number_ >= min_rpo) { 522 while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) {
523 if (hoist_block->loop_depth_ < block->loop_depth_) { 523 if (hoist_block->loop_depth() < block->loop_depth()) {
524 block = hoist_block; 524 block = hoist_block;
525 Trace(" hoisting #%d:%s to block %d\n", node->id(), 525 Trace(" hoisting #%d:%s to block %d\n", node->id(),
526 node->op()->mnemonic(), block->id()); 526 node->op()->mnemonic(), block->id().ToInt());
527 } 527 }
528 // Try to hoist to the pre-header of the loop header. 528 // Try to hoist to the pre-header of the loop header.
529 hoist_block = hoist_block->loop_header(); 529 hoist_block = hoist_block->loop_header();
530 if (hoist_block != NULL) { 530 if (hoist_block != NULL) {
531 BasicBlock* pre_header = hoist_block->dominator_; 531 BasicBlock* pre_header = hoist_block->dominator();
532 DCHECK(pre_header == NULL || 532 DCHECK(pre_header == NULL ||
533 *hoist_block->predecessors().begin() == pre_header); 533 *hoist_block->predecessors_begin() == pre_header);
534 Trace( 534 Trace(
535 " hoist to pre-header B%d of loop header B%d, depth would be %d\n", 535 " hoist to pre-header B%d of loop header B%d, depth would be %d\n",
536 pre_header->id(), hoist_block->id(), pre_header->loop_depth_); 536 pre_header->id().ToInt(), hoist_block->id().ToInt(),
537 pre_header->loop_depth());
537 hoist_block = pre_header; 538 hoist_block = pre_header;
538 } 539 }
539 } 540 }
540 541
541 ScheduleNode(block, node); 542 ScheduleNode(block, node);
542 543
543 return GenericGraphVisit::CONTINUE; 544 return GenericGraphVisit::CONTINUE;
544 } 545 }
545 546
546 private: 547 private:
547 BasicBlock* GetBlockForUse(Node::Edge edge) { 548 BasicBlock* GetBlockForUse(Node::Edge edge) {
548 Node* use = edge.from(); 549 Node* use = edge.from();
549 IrOpcode::Value opcode = use->opcode(); 550 IrOpcode::Value opcode = use->opcode();
550 if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) { 551 if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
551 // If the use is from a fixed (i.e. non-floating) phi, use the block 552 // If the use is from a fixed (i.e. non-floating) phi, use the block
552 // of the corresponding control input to the merge. 553 // of the corresponding control input to the merge.
553 int index = edge.index(); 554 int index = edge.index();
554 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) { 555 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
555 Trace(" input@%d into a fixed phi #%d:%s\n", index, use->id(), 556 Trace(" input@%d into a fixed phi #%d:%s\n", index, use->id(),
556 use->op()->mnemonic()); 557 use->op()->mnemonic());
557 Node* merge = NodeProperties::GetControlInput(use, 0); 558 Node* merge = NodeProperties::GetControlInput(use, 0);
558 opcode = merge->opcode(); 559 opcode = merge->opcode();
559 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop); 560 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop);
560 use = NodeProperties::GetControlInput(merge, index); 561 use = NodeProperties::GetControlInput(merge, index);
561 } 562 }
562 } 563 }
563 BasicBlock* result = schedule_->block(use); 564 BasicBlock* result = schedule_->block(use);
564 if (result == NULL) return NULL; 565 if (result == NULL) return NULL;
565 Trace(" must dominate use #%d:%s in B%d\n", use->id(), 566 Trace(" must dominate use #%d:%s in B%d\n", use->id(),
566 use->op()->mnemonic(), result->id()); 567 use->op()->mnemonic(), result->id().ToInt());
567 return result; 568 return result;
568 } 569 }
569 570
570 void ScheduleNode(BasicBlock* block, Node* node) { 571 void ScheduleNode(BasicBlock* block, Node* node) {
571 schedule_->PlanNode(block, node); 572 schedule_->PlanNode(block, node);
572 scheduler_->scheduled_nodes_[block->id()].push_back(node); 573 scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
573 574
574 // Reduce the use count of the node's inputs to potentially make them 575 // Reduce the use count of the node's inputs to potentially make them
575 // schedulable. 576 // schedulable.
576 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { 577 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
577 Scheduler::SchedulerData* data = scheduler_->GetData(*i); 578 Scheduler::SchedulerData* data = scheduler_->GetData(*i);
578 DCHECK(data->unscheduled_count_ > 0); 579 DCHECK(data->unscheduled_count_ > 0);
579 --data->unscheduled_count_; 580 --data->unscheduled_count_;
580 if (FLAG_trace_turbo_scheduler) { 581 if (FLAG_trace_turbo_scheduler) {
581 Trace(" Use count for #%d:%s (used by #%d:%s)-- = %d\n", (*i)->id(), 582 Trace(" Use count for #%d:%s (used by #%d:%s)-- = %d\n", (*i)->id(),
582 (*i)->op()->mnemonic(), i.edge().from()->id(), 583 (*i)->op()->mnemonic(), i.edge().from()->id(),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 // Process blocks and instructions backwards to find and connect floating 637 // Process blocks and instructions backwards to find and connect floating
637 // control nodes into the control graph according to the block they were 638 // control nodes into the control graph according to the block they were
638 // scheduled into. 639 // scheduled into.
639 int max = static_cast<int>(schedule_->rpo_order()->size()); 640 int max = static_cast<int>(schedule_->rpo_order()->size());
640 for (int i = max - 1; i >= 0; i--) { 641 for (int i = max - 1; i >= 0; i--) {
641 BasicBlock* block = schedule_->rpo_order()->at(i); 642 BasicBlock* block = schedule_->rpo_order()->at(i);
642 // TODO(titzer): we place at most one floating control structure per 643 // TODO(titzer): we place at most one floating control structure per
643 // basic block because scheduling currently can interleave phis from 644 // basic block because scheduling currently can interleave phis from
644 // one subgraph with the merges from another subgraph. 645 // one subgraph with the merges from another subgraph.
645 bool one_placed = false; 646 bool one_placed = false;
646 for (int j = static_cast<int>(block->nodes_.size()) - 1; j >= 0; j--) { 647 for (size_t j = 0; j < block->NodeCount(); j++) {
647 Node* node = block->nodes_[j]; 648 Node* node = block->NodeAt(block->NodeCount() - 1 - j);
648 SchedulerData* data = GetData(node); 649 SchedulerData* data = GetData(node);
649 if (data->is_floating_control_ && !data->is_connected_control_ && 650 if (data->is_floating_control_ && !data->is_connected_control_ &&
650 !one_placed) { 651 !one_placed) {
651 Trace(" Floating control #%d:%s was scheduled in B%d\n", node->id(), 652 Trace(" Floating control #%d:%s was scheduled in B%d\n", node->id(),
652 node->op()->mnemonic(), block->id()); 653 node->op()->mnemonic(), block->id().ToInt());
653 ConnectFloatingControlSubgraph(block, node); 654 ConnectFloatingControlSubgraph(block, node);
654 one_placed = true; 655 one_placed = true;
655 } 656 }
656 } 657 }
657 } 658 }
658 659
659 return true; 660 return true;
660 } 661 }
661 662
662 663
663 void Scheduler::ConnectFloatingControlSubgraph(BasicBlock* block, Node* end) { 664 void Scheduler::ConnectFloatingControlSubgraph(BasicBlock* block, Node* end) {
664 Node* block_start = block->nodes_[0]; 665 Node* block_start = block->NodeAt(0);
665 DCHECK(IrOpcode::IsControlOpcode(block_start->opcode())); 666 DCHECK(IrOpcode::IsControlOpcode(block_start->opcode()));
666 // Find the current "control successor" of the node that starts the block 667 // Find the current "control successor" of the node that starts the block
667 // by searching the control uses for a control input edge from a connected 668 // by searching the control uses for a control input edge from a connected
668 // control node. 669 // control node.
669 Node* control_succ = NULL; 670 Node* control_succ = NULL;
670 for (UseIter i = block_start->uses().begin(); i != block_start->uses().end(); 671 for (UseIter i = block_start->uses().begin(); i != block_start->uses().end();
671 ++i) { 672 ++i) {
672 Node::Edge edge = i.edge(); 673 Node::Edge edge = i.edge();
673 if (NodeProperties::IsControlEdge(edge) && 674 if (NodeProperties::IsControlEdge(edge) &&
674 GetData(edge.from())->is_connected_control_) { 675 GetData(edge.from())->is_connected_control_) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 727
727 // Numbering for BasicBlockData.rpo_number_ for this block traversal: 728 // Numbering for BasicBlockData.rpo_number_ for this block traversal:
728 static const int kBlockOnStack = -2; 729 static const int kBlockOnStack = -2;
729 static const int kBlockVisited1 = -3; 730 static const int kBlockVisited1 = -3;
730 static const int kBlockVisited2 = -4; 731 static const int kBlockVisited2 = -4;
731 static const int kBlockUnvisited1 = -1; 732 static const int kBlockUnvisited1 = -1;
732 static const int kBlockUnvisited2 = kBlockVisited1; 733 static const int kBlockUnvisited2 = kBlockVisited1;
733 734
734 struct SpecialRPOStackFrame { 735 struct SpecialRPOStackFrame {
735 BasicBlock* block; 736 BasicBlock* block;
736 int index; 737 size_t index;
737 }; 738 };
738 739
739 struct BlockList { 740 struct BlockList {
740 BasicBlock* block; 741 BasicBlock* block;
741 BlockList* next; 742 BlockList* next;
742 743
743 BlockList* Add(Zone* zone, BasicBlock* b) { 744 BlockList* Add(Zone* zone, BasicBlock* b) {
744 BlockList* list = static_cast<BlockList*>(zone->New(sizeof(BlockList))); 745 BlockList* list = static_cast<BlockList*>(zone->New(sizeof(BlockList)));
745 list->block = b; 746 list->block = b;
746 list->next = this; 747 list->next = this;
747 return list; 748 return list;
748 } 749 }
749 750
750 void Serialize(BasicBlockVector* final_order) { 751 void Serialize(BasicBlockVector* final_order) {
751 for (BlockList* l = this; l != NULL; l = l->next) { 752 for (BlockList* l = this; l != NULL; l = l->next) {
752 l->block->rpo_number_ = static_cast<int>(final_order->size()); 753 l->block->set_rpo_number(static_cast<int>(final_order->size()));
753 final_order->push_back(l->block); 754 final_order->push_back(l->block);
754 } 755 }
755 } 756 }
756 }; 757 };
757 758
758 struct LoopInfo { 759 struct LoopInfo {
759 BasicBlock* header; 760 BasicBlock* header;
760 ZoneList<BasicBlock*>* outgoing; 761 ZoneList<BasicBlock*>* outgoing;
761 BitVector* members; 762 BitVector* members;
762 LoopInfo* prev; 763 LoopInfo* prev;
763 BlockList* end; 764 BlockList* end;
764 BlockList* start; 765 BlockList* start;
765 766
766 void AddOutgoing(Zone* zone, BasicBlock* block) { 767 void AddOutgoing(Zone* zone, BasicBlock* block) {
767 if (outgoing == NULL) outgoing = new (zone) ZoneList<BasicBlock*>(2, zone); 768 if (outgoing == NULL) outgoing = new (zone) ZoneList<BasicBlock*>(2, zone);
768 outgoing->Add(block, zone); 769 outgoing->Add(block, zone);
769 } 770 }
770 }; 771 };
771 772
772 773
773 static int Push(SpecialRPOStackFrame* stack, int depth, BasicBlock* child, 774 static int Push(SpecialRPOStackFrame* stack, int depth, BasicBlock* child,
774 int unvisited) { 775 int unvisited) {
775 if (child->rpo_number_ == unvisited) { 776 if (child->rpo_number() == unvisited) {
776 stack[depth].block = child; 777 stack[depth].block = child;
777 stack[depth].index = 0; 778 stack[depth].index = 0;
778 child->rpo_number_ = kBlockOnStack; 779 child->set_rpo_number(kBlockOnStack);
779 return depth + 1; 780 return depth + 1;
780 } 781 }
781 return depth; 782 return depth;
782 } 783 }
783 784
784 785
785 // Computes loop membership from the backedges of the control flow graph. 786 // Computes loop membership from the backedges of the control flow graph.
786 static LoopInfo* ComputeLoopInfo( 787 static LoopInfo* ComputeLoopInfo(
787 Zone* zone, SpecialRPOStackFrame* queue, int num_loops, int num_blocks, 788 Zone* zone, SpecialRPOStackFrame* queue, int num_loops, size_t num_blocks,
788 ZoneList<std::pair<BasicBlock*, int> >* backedges) { 789 ZoneList<std::pair<BasicBlock*, size_t> >* backedges) {
789 LoopInfo* loops = zone->NewArray<LoopInfo>(num_loops); 790 LoopInfo* loops = zone->NewArray<LoopInfo>(num_loops);
790 memset(loops, 0, num_loops * sizeof(LoopInfo)); 791 memset(loops, 0, num_loops * sizeof(LoopInfo));
791 792
792 // Compute loop membership starting from backedges. 793 // Compute loop membership starting from backedges.
793 // O(max(loop_depth) * max(|loop|) 794 // O(max(loop_depth) * max(|loop|)
794 for (int i = 0; i < backedges->length(); i++) { 795 for (int i = 0; i < backedges->length(); i++) {
795 BasicBlock* member = backedges->at(i).first; 796 BasicBlock* member = backedges->at(i).first;
796 BasicBlock* header = member->SuccessorAt(backedges->at(i).second); 797 BasicBlock* header = member->SuccessorAt(backedges->at(i).second);
797 int loop_num = header->loop_end_; 798 int loop_num = header->loop_end();
798 if (loops[loop_num].header == NULL) { 799 if (loops[loop_num].header == NULL) {
799 loops[loop_num].header = header; 800 loops[loop_num].header = header;
800 loops[loop_num].members = new (zone) BitVector(num_blocks, zone); 801 loops[loop_num].members =
802 new (zone) BitVector(static_cast<int>(num_blocks), zone);
801 } 803 }
802 804
803 int queue_length = 0; 805 int queue_length = 0;
804 if (member != header) { 806 if (member != header) {
805 // As long as the header doesn't have a backedge to itself, 807 // As long as the header doesn't have a backedge to itself,
806 // Push the member onto the queue and process its predecessors. 808 // Push the member onto the queue and process its predecessors.
807 if (!loops[loop_num].members->Contains(member->id())) { 809 if (!loops[loop_num].members->Contains(member->id().ToInt())) {
808 loops[loop_num].members->Add(member->id()); 810 loops[loop_num].members->Add(member->id().ToInt());
809 } 811 }
810 queue[queue_length++].block = member; 812 queue[queue_length++].block = member;
811 } 813 }
812 814
813 // Propagate loop membership backwards. All predecessors of M up to the 815 // Propagate loop membership backwards. All predecessors of M up to the
814 // loop header H are members of the loop too. O(|blocks between M and H|). 816 // loop header H are members of the loop too. O(|blocks between M and H|).
815 while (queue_length > 0) { 817 while (queue_length > 0) {
816 BasicBlock* block = queue[--queue_length].block; 818 BasicBlock* block = queue[--queue_length].block;
817 for (int i = 0; i < block->PredecessorCount(); i++) { 819 for (size_t i = 0; i < block->PredecessorCount(); i++) {
818 BasicBlock* pred = block->PredecessorAt(i); 820 BasicBlock* pred = block->PredecessorAt(i);
819 if (pred != header) { 821 if (pred != header) {
820 if (!loops[loop_num].members->Contains(pred->id())) { 822 if (!loops[loop_num].members->Contains(pred->id().ToInt())) {
821 loops[loop_num].members->Add(pred->id()); 823 loops[loop_num].members->Add(pred->id().ToInt());
822 queue[queue_length++].block = pred; 824 queue[queue_length++].block = pred;
823 } 825 }
824 } 826 }
825 } 827 }
826 } 828 }
827 } 829 }
828 return loops; 830 return loops;
829 } 831 }
830 832
831 833
832 #if DEBUG 834 #if DEBUG
833 static void PrintRPO(int num_loops, LoopInfo* loops, BasicBlockVector* order) { 835 static void PrintRPO(int num_loops, LoopInfo* loops, BasicBlockVector* order) {
834 PrintF("-- RPO with %d loops ", num_loops); 836 OFStream os(stdout);
837 os << "-- RPO with " << num_loops << " loops ";
835 if (num_loops > 0) { 838 if (num_loops > 0) {
836 PrintF("("); 839 os << "(";
837 for (int i = 0; i < num_loops; i++) { 840 for (int i = 0; i < num_loops; i++) {
838 if (i > 0) PrintF(" "); 841 if (i > 0) os << " ";
839 PrintF("B%d", loops[i].header->id()); 842 os << "B" << loops[i].header->id();
840 } 843 }
841 PrintF(") "); 844 os << ") ";
842 } 845 }
843 PrintF("-- \n"); 846 os << "-- \n";
844 847
845 for (int i = 0; i < static_cast<int>(order->size()); i++) { 848 for (size_t i = 0; i < order->size(); i++) {
846 BasicBlock* block = (*order)[i]; 849 BasicBlock* block = (*order)[i];
847 int bid = block->id(); 850 BasicBlock::Id bid = block->id();
848 PrintF("%5d:", i); 851 // TODO(jarin,svenpanne): Add formatting here once we have support for that
849 for (int i = 0; i < num_loops; i++) { 852 // in streams (we want an equivalent of PrintF("%5d:", i) here).
850 bool membership = loops[i].members->Contains(bid); 853 os << i << ":";
851 bool range = loops[i].header->LoopContains(block); 854 for (int j = 0; j < num_loops; j++) {
852 PrintF(membership ? " |" : " "); 855 bool membership = loops[j].members->Contains(bid.ToInt());
853 PrintF(range ? "x" : " "); 856 bool range = loops[j].header->LoopContains(block);
857 os << (membership ? " |" : " ");
858 os << (range ? "x" : " ");
854 } 859 }
855 PrintF(" B%d: ", bid); 860 os << " B" << bid << ": ";
856 if (block->loop_end_ >= 0) { 861 if (block->loop_end() >= 0) {
857 PrintF(" range: [%d, %d)", block->rpo_number_, block->loop_end_); 862 os << " range: [" << block->rpo_number() << ", " << block->loop_end()
863 << ")";
858 } 864 }
859 PrintF("\n"); 865 os << "\n";
860 } 866 }
861 } 867 }
862 868
863 869
864 static void VerifySpecialRPO(int num_loops, LoopInfo* loops, 870 static void VerifySpecialRPO(int num_loops, LoopInfo* loops,
865 BasicBlockVector* order) { 871 BasicBlockVector* order) {
866 DCHECK(order->size() > 0); 872 DCHECK(order->size() > 0);
867 DCHECK((*order)[0]->id() == 0); // entry should be first. 873 DCHECK((*order)[0]->id().ToInt() == 0); // entry should be first.
868 874
869 for (int i = 0; i < num_loops; i++) { 875 for (int i = 0; i < num_loops; i++) {
870 LoopInfo* loop = &loops[i]; 876 LoopInfo* loop = &loops[i];
871 BasicBlock* header = loop->header; 877 BasicBlock* header = loop->header;
872 878
873 DCHECK(header != NULL); 879 DCHECK(header != NULL);
874 DCHECK(header->rpo_number_ >= 0); 880 DCHECK(header->rpo_number() >= 0);
875 DCHECK(header->rpo_number_ < static_cast<int>(order->size())); 881 DCHECK(header->rpo_number() < static_cast<int>(order->size()));
876 DCHECK(header->loop_end_ >= 0); 882 DCHECK(header->loop_end() >= 0);
877 DCHECK(header->loop_end_ <= static_cast<int>(order->size())); 883 DCHECK(header->loop_end() <= static_cast<int>(order->size()));
878 DCHECK(header->loop_end_ > header->rpo_number_); 884 DCHECK(header->loop_end() > header->rpo_number());
879 885
880 // Verify the start ... end list relationship. 886 // Verify the start ... end list relationship.
881 int links = 0; 887 int links = 0;
882 BlockList* l = loop->start; 888 BlockList* l = loop->start;
883 DCHECK(l != NULL && l->block == header); 889 DCHECK(l != NULL && l->block == header);
884 bool end_found; 890 bool end_found;
885 while (true) { 891 while (true) {
886 if (l == NULL || l == loop->end) { 892 if (l == NULL || l == loop->end) {
887 end_found = (loop->end == l); 893 end_found = (loop->end == l);
888 break; 894 break;
889 } 895 }
890 // The list should be in same order as the final result. 896 // The list should be in same order as the final result.
891 DCHECK(l->block->rpo_number_ == links + loop->header->rpo_number_); 897 DCHECK(l->block->rpo_number() == links + loop->header->rpo_number());
892 links++; 898 links++;
893 l = l->next; 899 l = l->next;
894 DCHECK(links < static_cast<int>(2 * order->size())); // cycle? 900 DCHECK(links < static_cast<int>(2 * order->size())); // cycle?
895 } 901 }
896 DCHECK(links > 0); 902 DCHECK(links > 0);
897 DCHECK(links == (header->loop_end_ - header->rpo_number_)); 903 DCHECK(links == (header->loop_end() - header->rpo_number()));
898 DCHECK(end_found); 904 DCHECK(end_found);
899 905
900 // Check the contiguousness of loops. 906 // Check the contiguousness of loops.
901 int count = 0; 907 int count = 0;
902 for (int j = 0; j < static_cast<int>(order->size()); j++) { 908 for (int j = 0; j < static_cast<int>(order->size()); j++) {
903 BasicBlock* block = order->at(j); 909 BasicBlock* block = order->at(j);
904 DCHECK(block->rpo_number_ == j); 910 DCHECK(block->rpo_number() == j);
905 if (j < header->rpo_number_ || j >= header->loop_end_) { 911 if (j < header->rpo_number() || j >= header->loop_end()) {
906 DCHECK(!loop->members->Contains(block->id())); 912 DCHECK(!loop->members->Contains(block->id().ToInt()));
907 } else { 913 } else {
908 if (block == header) { 914 if (block == header) {
909 DCHECK(!loop->members->Contains(block->id())); 915 DCHECK(!loop->members->Contains(block->id().ToInt()));
910 } else { 916 } else {
911 DCHECK(loop->members->Contains(block->id())); 917 DCHECK(loop->members->Contains(block->id().ToInt()));
912 } 918 }
913 count++; 919 count++;
914 } 920 }
915 } 921 }
916 DCHECK(links == count); 922 DCHECK(links == count);
917 } 923 }
918 } 924 }
919 #endif // DEBUG 925 #endif // DEBUG
920 926
921 927
922 // Compute the special reverse-post-order block ordering, which is essentially 928 // Compute the special reverse-post-order block ordering, which is essentially
923 // a RPO of the graph where loop bodies are contiguous. Properties: 929 // a RPO of the graph where loop bodies are contiguous. Properties:
924 // 1. If block A is a predecessor of B, then A appears before B in the order, 930 // 1. If block A is a predecessor of B, then A appears before B in the order,
925 // unless B is a loop header and A is in the loop headed at B 931 // unless B is a loop header and A is in the loop headed at B
926 // (i.e. A -> B is a backedge). 932 // (i.e. A -> B is a backedge).
927 // => If block A dominates block B, then A appears before B in the order. 933 // => If block A dominates block B, then A appears before B in the order.
928 // => If block A is a loop header, A appears before all blocks in the loop 934 // => If block A is a loop header, A appears before all blocks in the loop
929 // headed at A. 935 // headed at A.
930 // 2. All loops are contiguous in the order (i.e. no intervening blocks that 936 // 2. All loops are contiguous in the order (i.e. no intervening blocks that
931 // do not belong to the loop.) 937 // do not belong to the loop.)
932 // Note a simple RPO traversal satisfies (1) but not (3). 938 // Note a simple RPO traversal satisfies (1) but not (3).
933 BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) { 939 BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
934 Zone tmp_zone(schedule->zone()->isolate()); 940 Zone tmp_zone(schedule->zone()->isolate());
935 Zone* zone = &tmp_zone; 941 Zone* zone = &tmp_zone;
936 Trace("------------- COMPUTING SPECIAL RPO ---------------\n"); 942 Trace("------------- COMPUTING SPECIAL RPO ---------------\n");
937 // RPO should not have been computed for this schedule yet. 943 // RPO should not have been computed for this schedule yet.
938 CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number_); 944 CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number());
939 CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size())); 945 CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size()));
940 946
941 // Perform an iterative RPO traversal using an explicit stack, 947 // Perform an iterative RPO traversal using an explicit stack,
942 // recording backedges that form cycles. O(|B|). 948 // recording backedges that form cycles. O(|B|).
943 ZoneList<std::pair<BasicBlock*, int> > backedges(1, zone); 949 ZoneList<std::pair<BasicBlock*, size_t> > backedges(1, zone);
944 SpecialRPOStackFrame* stack = 950 SpecialRPOStackFrame* stack = zone->NewArray<SpecialRPOStackFrame>(
945 zone->NewArray<SpecialRPOStackFrame>(schedule->BasicBlockCount()); 951 static_cast<int>(schedule->BasicBlockCount()));
946 BasicBlock* entry = schedule->start(); 952 BasicBlock* entry = schedule->start();
947 BlockList* order = NULL; 953 BlockList* order = NULL;
948 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1); 954 int stack_depth = Push(stack, 0, entry, kBlockUnvisited1);
949 int num_loops = 0; 955 int num_loops = 0;
950 956
951 while (stack_depth > 0) { 957 while (stack_depth > 0) {
952 int current = stack_depth - 1; 958 int current = stack_depth - 1;
953 SpecialRPOStackFrame* frame = stack + current; 959 SpecialRPOStackFrame* frame = stack + current;
954 960
955 if (frame->index < frame->block->SuccessorCount()) { 961 if (frame->index < frame->block->SuccessorCount()) {
956 // Process the next successor. 962 // Process the next successor.
957 BasicBlock* succ = frame->block->SuccessorAt(frame->index++); 963 BasicBlock* succ = frame->block->SuccessorAt(frame->index++);
958 if (succ->rpo_number_ == kBlockVisited1) continue; 964 if (succ->rpo_number() == kBlockVisited1) continue;
959 if (succ->rpo_number_ == kBlockOnStack) { 965 if (succ->rpo_number() == kBlockOnStack) {
960 // The successor is on the stack, so this is a backedge (cycle). 966 // The successor is on the stack, so this is a backedge (cycle).
961 backedges.Add( 967 backedges.Add(
962 std::pair<BasicBlock*, int>(frame->block, frame->index - 1), zone); 968 std::pair<BasicBlock*, size_t>(frame->block, frame->index - 1),
963 if (succ->loop_end_ < 0) { 969 zone);
970 if (succ->loop_end() < 0) {
964 // Assign a new loop number to the header if it doesn't have one. 971 // Assign a new loop number to the header if it doesn't have one.
965 succ->loop_end_ = num_loops++; 972 succ->set_loop_end(num_loops++);
966 } 973 }
967 } else { 974 } else {
968 // Push the successor onto the stack. 975 // Push the successor onto the stack.
969 DCHECK(succ->rpo_number_ == kBlockUnvisited1); 976 DCHECK(succ->rpo_number() == kBlockUnvisited1);
970 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1); 977 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1);
971 } 978 }
972 } else { 979 } else {
973 // Finished with all successors; pop the stack and add the block. 980 // Finished with all successors; pop the stack and add the block.
974 order = order->Add(zone, frame->block); 981 order = order->Add(zone, frame->block);
975 frame->block->rpo_number_ = kBlockVisited1; 982 frame->block->set_rpo_number(kBlockVisited1);
976 stack_depth--; 983 stack_depth--;
977 } 984 }
978 } 985 }
979 986
980 // If no loops were encountered, then the order we computed was correct. 987 // If no loops were encountered, then the order we computed was correct.
981 LoopInfo* loops = NULL; 988 LoopInfo* loops = NULL;
982 if (num_loops != 0) { 989 if (num_loops != 0) {
983 // Otherwise, compute the loop information from the backedges in order 990 // Otherwise, compute the loop information from the backedges in order
984 // to perform a traversal that groups loop bodies together. 991 // to perform a traversal that groups loop bodies together.
985 loops = ComputeLoopInfo(zone, stack, num_loops, schedule->BasicBlockCount(), 992 loops = ComputeLoopInfo(zone, stack, num_loops, schedule->BasicBlockCount(),
986 &backedges); 993 &backedges);
987 994
988 // Initialize the "loop stack". Note the entry could be a loop header. 995 // Initialize the "loop stack". Note the entry could be a loop header.
989 LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end_] : NULL; 996 LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end()] : NULL;
990 order = NULL; 997 order = NULL;
991 998
992 // Perform an iterative post-order traversal, visiting loop bodies before 999 // Perform an iterative post-order traversal, visiting loop bodies before
993 // edges that lead out of loops. Visits each block once, but linking loop 1000 // edges that lead out of loops. Visits each block once, but linking loop
994 // sections together is linear in the loop size, so overall is 1001 // sections together is linear in the loop size, so overall is
995 // O(|B| + max(loop_depth) * max(|loop|)) 1002 // O(|B| + max(loop_depth) * max(|loop|))
996 stack_depth = Push(stack, 0, entry, kBlockUnvisited2); 1003 stack_depth = Push(stack, 0, entry, kBlockUnvisited2);
997 while (stack_depth > 0) { 1004 while (stack_depth > 0) {
998 SpecialRPOStackFrame* frame = stack + (stack_depth - 1); 1005 SpecialRPOStackFrame* frame = stack + (stack_depth - 1);
999 BasicBlock* block = frame->block; 1006 BasicBlock* block = frame->block;
1000 BasicBlock* succ = NULL; 1007 BasicBlock* succ = NULL;
1001 1008
1002 if (frame->index < block->SuccessorCount()) { 1009 if (frame->index < block->SuccessorCount()) {
1003 // Process the next normal successor. 1010 // Process the next normal successor.
1004 succ = block->SuccessorAt(frame->index++); 1011 succ = block->SuccessorAt(frame->index++);
1005 } else if (block->IsLoopHeader()) { 1012 } else if (block->IsLoopHeader()) {
1006 // Process additional outgoing edges from the loop header. 1013 // Process additional outgoing edges from the loop header.
1007 if (block->rpo_number_ == kBlockOnStack) { 1014 if (block->rpo_number() == kBlockOnStack) {
1008 // Finish the loop body the first time the header is left on the 1015 // Finish the loop body the first time the header is left on the
1009 // stack. 1016 // stack.
1010 DCHECK(loop != NULL && loop->header == block); 1017 DCHECK(loop != NULL && loop->header == block);
1011 loop->start = order->Add(zone, block); 1018 loop->start = order->Add(zone, block);
1012 order = loop->end; 1019 order = loop->end;
1013 block->rpo_number_ = kBlockVisited2; 1020 block->set_rpo_number(kBlockVisited2);
1014 // Pop the loop stack and continue visiting outgoing edges within the 1021 // Pop the loop stack and continue visiting outgoing edges within the
1015 // the context of the outer loop, if any. 1022 // the context of the outer loop, if any.
1016 loop = loop->prev; 1023 loop = loop->prev;
1017 // We leave the loop header on the stack; the rest of this iteration 1024 // We leave the loop header on the stack; the rest of this iteration
1018 // and later iterations will go through its outgoing edges list. 1025 // and later iterations will go through its outgoing edges list.
1019 } 1026 }
1020 1027
1021 // Use the next outgoing edge if there are any. 1028 // Use the next outgoing edge if there are any.
1022 int outgoing_index = frame->index - block->SuccessorCount(); 1029 int outgoing_index =
1023 LoopInfo* info = &loops[block->loop_end_]; 1030 static_cast<int>(frame->index - block->SuccessorCount());
1031 LoopInfo* info = &loops[block->loop_end()];
1024 DCHECK(loop != info); 1032 DCHECK(loop != info);
1025 if (info->outgoing != NULL && 1033 if (info->outgoing != NULL &&
1026 outgoing_index < info->outgoing->length()) { 1034 outgoing_index < info->outgoing->length()) {
1027 succ = info->outgoing->at(outgoing_index); 1035 succ = info->outgoing->at(outgoing_index);
1028 frame->index++; 1036 frame->index++;
1029 } 1037 }
1030 } 1038 }
1031 1039
1032 if (succ != NULL) { 1040 if (succ != NULL) {
1033 // Process the next successor. 1041 // Process the next successor.
1034 if (succ->rpo_number_ == kBlockOnStack) continue; 1042 if (succ->rpo_number() == kBlockOnStack) continue;
1035 if (succ->rpo_number_ == kBlockVisited2) continue; 1043 if (succ->rpo_number() == kBlockVisited2) continue;
1036 DCHECK(succ->rpo_number_ == kBlockUnvisited2); 1044 DCHECK(succ->rpo_number() == kBlockUnvisited2);
1037 if (loop != NULL && !loop->members->Contains(succ->id())) { 1045 if (loop != NULL && !loop->members->Contains(succ->id().ToInt())) {
1038 // The successor is not in the current loop or any nested loop. 1046 // The successor is not in the current loop or any nested loop.
1039 // Add it to the outgoing edges of this loop and visit it later. 1047 // Add it to the outgoing edges of this loop and visit it later.
1040 loop->AddOutgoing(zone, succ); 1048 loop->AddOutgoing(zone, succ);
1041 } else { 1049 } else {
1042 // Push the successor onto the stack. 1050 // Push the successor onto the stack.
1043 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2); 1051 stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2);
1044 if (succ->IsLoopHeader()) { 1052 if (succ->IsLoopHeader()) {
1045 // Push the inner loop onto the loop stack. 1053 // Push the inner loop onto the loop stack.
1046 DCHECK(succ->loop_end_ >= 0 && succ->loop_end_ < num_loops); 1054 DCHECK(succ->loop_end() >= 0 && succ->loop_end() < num_loops);
1047 LoopInfo* next = &loops[succ->loop_end_]; 1055 LoopInfo* next = &loops[succ->loop_end()];
1048 next->end = order; 1056 next->end = order;
1049 next->prev = loop; 1057 next->prev = loop;
1050 loop = next; 1058 loop = next;
1051 } 1059 }
1052 } 1060 }
1053 } else { 1061 } else {
1054 // Finished with all successors of the current block. 1062 // Finished with all successors of the current block.
1055 if (block->IsLoopHeader()) { 1063 if (block->IsLoopHeader()) {
1056 // If we are going to pop a loop header, then add its entire body. 1064 // If we are going to pop a loop header, then add its entire body.
1057 LoopInfo* info = &loops[block->loop_end_]; 1065 LoopInfo* info = &loops[block->loop_end()];
1058 for (BlockList* l = info->start; true; l = l->next) { 1066 for (BlockList* l = info->start; true; l = l->next) {
1059 if (l->next == info->end) { 1067 if (l->next == info->end) {
1060 l->next = order; 1068 l->next = order;
1061 info->end = order; 1069 info->end = order;
1062 break; 1070 break;
1063 } 1071 }
1064 } 1072 }
1065 order = info->start; 1073 order = info->start;
1066 } else { 1074 } else {
1067 // Pop a single node off the stack and add it to the order. 1075 // Pop a single node off the stack and add it to the order.
1068 order = order->Add(zone, block); 1076 order = order->Add(zone, block);
1069 block->rpo_number_ = kBlockVisited2; 1077 block->set_rpo_number(kBlockVisited2);
1070 } 1078 }
1071 stack_depth--; 1079 stack_depth--;
1072 } 1080 }
1073 } 1081 }
1074 } 1082 }
1075 1083
1076 // Construct the final order from the list. 1084 // Construct the final order from the list.
1077 BasicBlockVector* final_order = &schedule->rpo_order_; 1085 BasicBlockVector* final_order = &schedule->rpo_order_;
1078 order->Serialize(final_order); 1086 order->Serialize(final_order);
1079 1087
1080 // Compute the correct loop header for every block and set the correct loop 1088 // Compute the correct loop header for every block and set the correct loop
1081 // ends. 1089 // ends.
1082 LoopInfo* current_loop = NULL; 1090 LoopInfo* current_loop = NULL;
1083 BasicBlock* current_header = NULL; 1091 BasicBlock* current_header = NULL;
1084 int loop_depth = 0; 1092 int loop_depth = 0;
1085 for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end(); 1093 for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
1086 ++i) { 1094 ++i) {
1087 BasicBlock* current = *i; 1095 BasicBlock* current = *i;
1088 current->loop_header_ = current_header; 1096 current->set_loop_header(current_header);
1089 if (current->IsLoopHeader()) { 1097 if (current->IsLoopHeader()) {
1090 loop_depth++; 1098 loop_depth++;
1091 current_loop = &loops[current->loop_end_]; 1099 current_loop = &loops[current->loop_end()];
1092 BlockList* end = current_loop->end; 1100 BlockList* end = current_loop->end;
1093 current->loop_end_ = end == NULL ? static_cast<int>(final_order->size()) 1101 current->set_loop_end(end == NULL ? static_cast<int>(final_order->size())
1094 : end->block->rpo_number_; 1102 : end->block->rpo_number());
1095 current_header = current_loop->header; 1103 current_header = current_loop->header;
1096 Trace("B%d is a loop header, increment loop depth to %d\n", current->id(), 1104 Trace("B%d is a loop header, increment loop depth to %d\n",
1097 loop_depth); 1105 current->id().ToInt(), loop_depth);
1098 } else { 1106 } else {
1099 while (current_header != NULL && 1107 while (current_header != NULL &&
1100 current->rpo_number_ >= current_header->loop_end_) { 1108 current->rpo_number() >= current_header->loop_end()) {
1101 DCHECK(current_header->IsLoopHeader()); 1109 DCHECK(current_header->IsLoopHeader());
1102 DCHECK(current_loop != NULL); 1110 DCHECK(current_loop != NULL);
1103 current_loop = current_loop->prev; 1111 current_loop = current_loop->prev;
1104 current_header = current_loop == NULL ? NULL : current_loop->header; 1112 current_header = current_loop == NULL ? NULL : current_loop->header;
1105 --loop_depth; 1113 --loop_depth;
1106 } 1114 }
1107 } 1115 }
1108 current->loop_depth_ = loop_depth; 1116 current->set_loop_depth(loop_depth);
1109 if (current->loop_header_ == NULL) { 1117 if (current->loop_header() == NULL) {
1110 Trace("B%d is not in a loop (depth == %d)\n", current->id(), 1118 Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
1111 current->loop_depth_); 1119 current->loop_depth());
1112 } else { 1120 } else {
1113 Trace("B%d has loop header B%d, (depth == %d)\n", current->id(), 1121 Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(),
1114 current->loop_header_->id(), current->loop_depth_); 1122 current->loop_header()->id().ToInt(), current->loop_depth());
1115 } 1123 }
1116 } 1124 }
1117 1125
1118 #if DEBUG 1126 #if DEBUG
1119 if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order); 1127 if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order);
1120 VerifySpecialRPO(num_loops, loops, final_order); 1128 VerifySpecialRPO(num_loops, loops, final_order);
1121 #endif 1129 #endif
1122 return final_order; 1130 return final_order;
1123 } 1131 }
1124 } 1132 }
1125 } 1133 }
1126 } // namespace v8::internal::compiler 1134 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/compiler/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698