| Index: src/compiler/scheduler.cc
|
| diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
|
| index 9c7e86b7090dffa8dd2a22e298da9ad36a6dadaf..0f3b4c4248dea93856a6c4a2a7b677f8c0abfba7 100644
|
| --- a/src/compiler/scheduler.cc
|
| +++ b/src/compiler/scheduler.cc
|
| @@ -536,8 +536,8 @@ class SpecialRPONumberer : public ZoneObject {
|
| : zone_(zone),
|
| schedule_(schedule),
|
| order_(NULL),
|
| - loops_(zone),
|
| beyond_end_(NULL),
|
| + loops_(zone),
|
| backedges_(1, zone),
|
| stack_(zone),
|
| previous_block_count_(0) {}
|
| @@ -562,13 +562,13 @@ class SpecialRPONumberer : public ZoneObject {
|
| // code first, deferred code afterwards) into the final schedule.
|
| void SerializeAOIntoSchedule() {
|
| int32_t number = 0;
|
| - for (BlockList* l = order_; l != NULL; l = l->next) {
|
| - if (l->block->deferred()) continue;
|
| - l->block->set_ao_number(number++);
|
| + for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
|
| + if (b->deferred()) continue;
|
| + b->set_ao_number(number++);
|
| }
|
| - for (BlockList* l = order_; l != NULL; l = l->next) {
|
| - if (!l->block->deferred()) continue;
|
| - l->block->set_ao_number(number++);
|
| + for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
|
| + if (!b->deferred()) continue;
|
| + b->set_ao_number(number++);
|
| }
|
| }
|
|
|
| @@ -576,9 +576,9 @@ class SpecialRPONumberer : public ZoneObject {
|
| // numbering for basic blocks into the final schedule.
|
| void SerializeRPOIntoSchedule() {
|
| int32_t number = 0;
|
| - for (BlockList* l = order_; l != NULL; l = l->next) {
|
| - l->block->set_rpo_number(number++);
|
| - schedule_->rpo_order()->push_back(l->block);
|
| + for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
|
| + b->set_rpo_number(number++);
|
| + schedule_->rpo_order()->push_back(b);
|
| }
|
| BeyondEndSentinel()->set_rpo_number(number);
|
| }
|
| @@ -594,9 +594,6 @@ class SpecialRPONumberer : public ZoneObject {
|
| private:
|
| typedef std::pair<BasicBlock*, size_t> Backedge;
|
|
|
| - // TODO(mstarzinger): Only for Scheduler::GenerateImmediateDominatorTree.
|
| - friend class Scheduler;
|
| -
|
| // Numbering for BasicBlock::rpo_number for this block traversal:
|
| static const int kBlockOnStack = -2;
|
| static const int kBlockVisited1 = -3;
|
| @@ -609,32 +606,13 @@ class SpecialRPONumberer : public ZoneObject {
|
| size_t index;
|
| };
|
|
|
| - struct BlockList {
|
| - BasicBlock* block;
|
| - BlockList* next;
|
| -
|
| - BlockList* Add(Zone* zone, BasicBlock* b) {
|
| - BlockList* list = static_cast<BlockList*>(zone->New(sizeof(BlockList)));
|
| - list->block = b;
|
| - list->next = this;
|
| - return list;
|
| - }
|
| -
|
| - BlockList* FindForBlock(BasicBlock* b) {
|
| - for (BlockList* l = this; l != NULL; l = l->next) {
|
| - if (l->block == b) return l;
|
| - }
|
| - return NULL;
|
| - }
|
| - };
|
| -
|
| struct LoopInfo {
|
| BasicBlock* header;
|
| ZoneList<BasicBlock*>* outgoing;
|
| BitVector* members;
|
| LoopInfo* prev;
|
| - BlockList* end;
|
| - BlockList* start;
|
| + BasicBlock* end;
|
| + BasicBlock* start;
|
|
|
| void AddOutgoing(Zone* zone, BasicBlock* block) {
|
| if (outgoing == NULL) {
|
| @@ -655,6 +633,11 @@ class SpecialRPONumberer : public ZoneObject {
|
| return depth;
|
| }
|
|
|
| + BasicBlock* PushFront(BasicBlock* head, BasicBlock* block) {
|
| + block->set_rpo_next(head);
|
| + return block;
|
| + }
|
| +
|
| // We are hijacking the {ao_number} to enumerate loops temporarily. Note that
|
| // these numbers are only valid within this class.
|
| static int GetLoopNumber(BasicBlock* block) { return block->ao_number(); }
|
| @@ -685,9 +668,8 @@ class SpecialRPONumberer : public ZoneObject {
|
| CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size()));
|
|
|
| // Find correct insertion point within existing order.
|
| - BlockList* insert_before = order_->FindForBlock(entry);
|
| - BlockList* insert_after = insert_before ? insert_before->next : NULL;
|
| - BlockList* order = insert_after;
|
| + BasicBlock* insertion_point = entry->rpo_next();
|
| + BasicBlock* order = insertion_point;
|
|
|
| // Perform an iterative RPO traversal using an explicit stack,
|
| // recording backedges that form cycles. O(|B|).
|
| @@ -720,7 +702,7 @@ class SpecialRPONumberer : public ZoneObject {
|
| }
|
| } else {
|
| // Finished with all successors; pop the stack and add the block.
|
| - order = order->Add(zone_, frame->block);
|
| + order = PushFront(order, frame->block);
|
| frame->block->set_rpo_number(kBlockVisited1);
|
| stack_depth--;
|
| }
|
| @@ -735,7 +717,7 @@ class SpecialRPONumberer : public ZoneObject {
|
| // Initialize the "loop stack". Note the entry could be a loop header.
|
| LoopInfo* loop =
|
| HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL;
|
| - order = insert_after;
|
| + order = insertion_point;
|
|
|
| // Perform an iterative post-order traversal, visiting loop bodies before
|
| // edges that lead out of loops. Visits each block once, but linking loop
|
| @@ -756,7 +738,7 @@ class SpecialRPONumberer : public ZoneObject {
|
| // Finish the loop body the first time the header is left on the
|
| // stack.
|
| DCHECK(loop != NULL && loop->header == block);
|
| - loop->start = order->Add(zone_, block);
|
| + loop->start = PushFront(order, block);
|
| order = loop->end;
|
| block->set_rpo_number(kBlockVisited2);
|
| // Pop the loop stack and continue visiting outgoing edges within
|
| @@ -804,9 +786,9 @@ class SpecialRPONumberer : public ZoneObject {
|
| if (HasLoopNumber(block)) {
|
| // If we are going to pop a loop header, then add its entire body.
|
| LoopInfo* info = &loops_[GetLoopNumber(block)];
|
| - for (BlockList* l = info->start; true; l = l->next) {
|
| - if (l->next == info->end) {
|
| - l->next = order;
|
| + for (BasicBlock* b = info->start; true; b = b->rpo_next()) {
|
| + if (b->rpo_next() == info->end) {
|
| + b->set_rpo_next(order);
|
| info->end = order;
|
| break;
|
| }
|
| @@ -814,7 +796,7 @@ class SpecialRPONumberer : public ZoneObject {
|
| order = info->start;
|
| } else {
|
| // Pop a single node off the stack and add it to the order.
|
| - order = order->Add(zone_, block);
|
| + order = PushFront(order, block);
|
| block->set_rpo_number(kBlockVisited2);
|
| }
|
| stack_depth--;
|
| @@ -822,23 +804,16 @@ class SpecialRPONumberer : public ZoneObject {
|
| }
|
| }
|
|
|
| - // Insert result into existing order.
|
| - if (insert_before == NULL) {
|
| - order_ = order;
|
| - } else {
|
| - // There already is a list element for the entry block in the list, hence
|
| - // we skip the first element of the sub-list to compensate duplication.
|
| - DCHECK_EQ(insert_before->block, order->block);
|
| - insert_before->next = order->next;
|
| - }
|
| + // Publish new order the first time.
|
| + if (order_ == NULL) order_ = order;
|
|
|
| // Compute the correct loop headers and set the correct loop ends.
|
| LoopInfo* current_loop = NULL;
|
| BasicBlock* current_header = entry->loop_header();
|
| int32_t loop_depth = entry->loop_depth();
|
| if (entry->IsLoopHeader()) --loop_depth; // Entry might be a loop header.
|
| - for (BlockList* l = order; l != insert_after; l = l->next) {
|
| - BasicBlock* current = l->block;
|
| + for (BasicBlock* b = order; b != insertion_point; b = b->rpo_next()) {
|
| + BasicBlock* current = b;
|
|
|
| // Reset BasicBlock::rpo_number again.
|
| current->set_rpo_number(kBlockUnvisited1);
|
| @@ -857,8 +832,8 @@ class SpecialRPONumberer : public ZoneObject {
|
| if (HasLoopNumber(current)) {
|
| ++loop_depth;
|
| current_loop = &loops_[GetLoopNumber(current)];
|
| - BlockList* end = current_loop->end;
|
| - current->set_loop_end(end == NULL ? BeyondEndSentinel() : end->block);
|
| + BasicBlock* end = current_loop->end;
|
| + current->set_loop_end(end == NULL ? BeyondEndSentinel() : end);
|
| current_header = current_loop->header;
|
| Trace("B%d is a loop header, increment loop depth to %d\n",
|
| current->id().ToInt(), loop_depth);
|
| @@ -943,8 +918,7 @@ class SpecialRPONumberer : public ZoneObject {
|
| }
|
| os << ":\n";
|
|
|
| - for (BlockList* l = order_; l != NULL; l = l->next) {
|
| - BasicBlock* block = l->block;
|
| + for (BasicBlock* block = order_; block != NULL; block = block->rpo_next()) {
|
| BasicBlock::Id bid = block->id();
|
| // TODO(jarin,svenpanne): Add formatting here once we have support for
|
| // that in streams (we want an equivalent of PrintF("%5d:", x) here).
|
| @@ -990,18 +964,18 @@ class SpecialRPONumberer : public ZoneObject {
|
|
|
| // Verify the start ... end list relationship.
|
| int links = 0;
|
| - BlockList* l = loop->start;
|
| - DCHECK(l != NULL && l->block == header);
|
| + BasicBlock* block = loop->start;
|
| + DCHECK_EQ(header, block);
|
| bool end_found;
|
| while (true) {
|
| - if (l == NULL || l == loop->end) {
|
| - end_found = (loop->end == l);
|
| + if (block == NULL || block == loop->end) {
|
| + end_found = (loop->end == block);
|
| break;
|
| }
|
| // The list should be in same order as the final result.
|
| - DCHECK(l->block->rpo_number() == links + header->rpo_number());
|
| + DCHECK(block->rpo_number() == links + header->rpo_number());
|
| links++;
|
| - l = l->next;
|
| + block = block->rpo_next();
|
| DCHECK(links < static_cast<int>(2 * order->size())); // cycle?
|
| }
|
| DCHECK(links > 0);
|
| @@ -1035,9 +1009,9 @@ class SpecialRPONumberer : public ZoneObject {
|
|
|
| Zone* zone_;
|
| Schedule* schedule_;
|
| - BlockList* order_;
|
| - ZoneVector<LoopInfo> loops_;
|
| + BasicBlock* order_;
|
| BasicBlock* beyond_end_;
|
| + ZoneVector<LoopInfo> loops_;
|
| ZoneList<Backedge> backedges_;
|
| ZoneVector<SpecialRPOStackFrame> stack_;
|
| size_t previous_block_count_;
|
| @@ -1070,12 +1044,10 @@ void Scheduler::GenerateImmediateDominatorTree() {
|
|
|
| // Build the block dominator tree.
|
| schedule_->start()->set_dominator_depth(0);
|
| - typedef SpecialRPONumberer::BlockList BlockList;
|
| - DCHECK_EQ(schedule_->start(), special_rpo_->order_->block);
|
| - for (BlockList* l = special_rpo_->order_->next; l != NULL; l = l->next) {
|
| - BasicBlock* current = l->block;
|
| - BasicBlock::Predecessors::iterator pred = current->predecessors_begin();
|
| - BasicBlock::Predecessors::iterator end = current->predecessors_end();
|
| + BasicBlock* second = schedule_->start()->rpo_next();
|
| + for (BasicBlock* block = second; block != NULL; block = block->rpo_next()) {
|
| + BasicBlock::Predecessors::iterator pred = block->predecessors_begin();
|
| + BasicBlock::Predecessors::iterator end = block->predecessors_end();
|
| DCHECK(pred != end); // All blocks except start have predecessors.
|
| BasicBlock* dominator = *pred;
|
| // For multiple predecessors, walk up the dominator tree until a common
|
| @@ -1086,12 +1058,12 @@ void Scheduler::GenerateImmediateDominatorTree() {
|
| if ((*pred)->dominator_depth() < 0) continue;
|
| dominator = GetCommonDominator(dominator, *pred);
|
| }
|
| - current->set_dominator(dominator);
|
| - current->set_dominator_depth(dominator->dominator_depth() + 1);
|
| + block->set_dominator(dominator);
|
| + block->set_dominator_depth(dominator->dominator_depth() + 1);
|
| // Propagate "deferredness" of the dominator.
|
| - if (dominator->deferred()) current->set_deferred(true);
|
| - Trace("Block B%d's idom is B%d, depth = %d\n", current->id().ToInt(),
|
| - dominator->id().ToInt(), current->dominator_depth());
|
| + if (dominator->deferred()) block->set_deferred(true);
|
| + Trace("Block B%d's idom is B%d, depth = %d\n", block->id().ToInt(),
|
| + dominator->id().ToInt(), block->dominator_depth());
|
| }
|
| }
|
|
|
|
|