BasicBlockVector* final_order = schedule_->rpo_order();
order->Serialize(final_order);
- // Compute the correct loop header for every block and set the correct loop
- // ends.
+ // Compute the correct loop headers and set the correct loop ends.
LoopInfo* current_loop = NULL;
BasicBlock* current_header = NULL;
int loop_depth = 0;
for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
++i) {
BasicBlock* current = *i;
+
+ // Finish the previous loop(s) if we just exited them.
+ while (current_header != NULL &&
+ current->rpo_number() >= current_header->loop_end()) {
+ DCHECK(current_header->IsLoopHeader());
+ DCHECK(current_loop != NULL);
+ current_loop = current_loop->prev;
+ current_header = current_loop == NULL ? NULL : current_loop->header;
+ --loop_depth;
+ }
current->set_loop_header(current_header);
+
+ // Push a new loop onto the stack if this loop is a loop header.
if (current->IsLoopHeader()) {
loop_depth++;
current_loop = &loops[current->loop_end()];
current_header = current_loop->header;
Trace("B%d is a loop header, increment loop depth to %d\n",
current->id().ToInt(), loop_depth);
- } else {
- while (current_header != NULL &&
- current->rpo_number() >= current_header->loop_end()) {
- DCHECK(current_header->IsLoopHeader());
- DCHECK(current_loop != NULL);
- current_loop = current_loop->prev;
- current_header = current_loop == NULL ? NULL : current_loop->header;
- --loop_depth;
- }
}
+
current->set_loop_depth(loop_depth);
+
if (current->loop_header() == NULL) {
Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
current->loop_depth());
os << " range: [" << block->rpo_number() << ", " << block->loop_end()
<< ")";
}
+ if (block->loop_header() != NULL) {
+ os << " header: B" << block->loop_header()->id();
+ }
+ if (block->loop_depth() > 0) {
+ os << " depth: " << block->loop_depth();
+ }
os << "\n";
}
}
DCHECK(header->loop_end() >= 0);
DCHECK(header->loop_end() <= static_cast<int>(order->size()));
DCHECK(header->loop_end() > header->rpo_number());
+ DCHECK(header->loop_header() != header);
// Verify the start ... end list relationship.
int links = 0;
// Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
// into enclosing loop pre-headers until they would preceed their
// ScheduleEarly position.
- BasicBlock* hoist_block = block;
+ BasicBlock* hoist_block = GetPreHeader(block);
while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) {
- if (hoist_block->loop_depth() < block->loop_depth()) {
- block = hoist_block;
- Trace(" hoisting #%d:%s to block %d\n", node->id(),
- node->op()->mnemonic(), block->id().ToInt());
- }
- // Try to hoist to the pre-header of the loop header.
- hoist_block = hoist_block->loop_header();
- if (hoist_block != NULL) {
- BasicBlock* pre_header = hoist_block->dominator();
- DCHECK(pre_header == NULL ||
- *hoist_block->predecessors_begin() == pre_header);
- Trace(
- " hoist to pre-header B%d of loop header B%d, depth would be %d\n",
- pre_header->id().ToInt(), hoist_block->id().ToInt(),
- pre_header->loop_depth());
- hoist_block = pre_header;
- }
+ Trace(" hoisting #%d:%s to block %d\n", node->id(),
+ node->op()->mnemonic(), hoist_block->id().ToInt());
+ DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
+ block = hoist_block;
+ hoist_block = GetPreHeader(hoist_block);
}
ScheduleNode(block, node);
}
private:
+ BasicBlock* GetPreHeader(BasicBlock* block) {
+ if (block->IsLoopHeader()) {
+ return block->dominator();
+ } else if (block->loop_header() != NULL) {
+ return block->loop_header()->dominator();
+ } else {
+ return NULL;
+ }
+ }
+
BasicBlock* GetCommonDominatorOfUses(Node* node) {
BasicBlock* block = NULL;
Node::Uses uses = node->uses();
using namespace v8::internal::compiler;
// TODO(titzer): pull RPO tests out to their own file.
+static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
+ bool loops_allowed) {
+ CHECK(expected == order->size());
+ for (int i = 0; i < static_cast<int>(order->size()); i++) {
+ CHECK(order->at(i)->rpo_number() == i);
+ if (!loops_allowed) {
+ CHECK_LT(order->at(i)->loop_end(), 0);
+ CHECK_EQ(NULL, order->at(i)->loop_header());
+ }
+ }
+}
+
+
+static void CheckLoop(BasicBlockVector* order, BasicBlock** blocks,
+ int body_size) {
+ BasicBlock* header = blocks[0];
+ CHECK_GT(header->loop_end(), 0);
+ CHECK_EQ(body_size, (header->loop_end() - header->rpo_number()));
+ for (int i = 0; i < body_size; i++) {
+ int num = blocks[i]->rpo_number();
+ CHECK(num >= header->rpo_number() && num < header->loop_end());
+ CHECK(header->LoopContains(blocks[i]));
+ CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header);
+ }
+ if (header->rpo_number() > 0) {
+ CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header);
+ }
+ if (header->loop_end() < static_cast<int>(order->size())) {
+ CHECK_NE(order->at(header->loop_end())->loop_header(), header);
+ }
+}
+
+
struct TestLoop {
int count;
BasicBlock** nodes;
BasicBlock* header() { return nodes[0]; }
BasicBlock* last() { return nodes[count - 1]; }
~TestLoop() { delete[] nodes; }
+
+ void Check(BasicBlockVector* order) { CheckLoop(order, nodes, count); }
};
}
-static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
- bool loops_allowed) {
- CHECK(expected == order->size());
- for (int i = 0; i < static_cast<int>(order->size()); i++) {
- CHECK(order->at(i)->rpo_number() == i);
- if (!loops_allowed) CHECK_LT(order->at(i)->loop_end(), 0);
- }
-}
-
-
-static void CheckLoopContains(BasicBlock** blocks, int body_size) {
- BasicBlock* header = blocks[0];
- CHECK_GT(header->loop_end(), 0);
- CHECK_EQ(body_size, (header->loop_end() - header->rpo_number()));
- for (int i = 0; i < body_size; i++) {
- int num = blocks[i]->rpo_number();
- CHECK(num >= header->rpo_number() && num < header->loop_end());
- CHECK(header->LoopContains(blocks[i]));
- CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header);
- }
-}
-
-
static int GetScheduledNodeCount(Schedule* schedule) {
int node_count = 0;
for (BasicBlockVectorIter i = schedule->rpo_order()->begin();
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 1, true);
BasicBlock* loop[] = {schedule.start()};
- CheckLoopContains(loop, 1);
+ CheckLoop(order, loop, 1);
}
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 2, true);
BasicBlock* loop[] = {schedule.start(), schedule.end()};
- CheckLoopContains(loop, 2);
+ CheckLoop(order, loop, 2);
}
ZonePool zone_pool(scope.main_isolate());
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 3, true);
- CheckLoopContains(loop1->nodes, loop1->count);
+ loop1->Check(order);
}
ZonePool zone_pool(scope.main_isolate());
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 3, true);
- CheckLoopContains(loop1->nodes, loop1->count);
+ loop1->Check(order);
}
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 4, true);
BasicBlock* loop[] = {B, C};
- CheckLoopContains(loop, 2);
+ CheckLoop(order, loop, 2);
}
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 4, true);
BasicBlock* loop[] = {B, C};
- CheckLoopContains(loop, 2);
+ CheckLoop(order, loop, 2);
}
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 7, true);
BasicBlock* loop[] = {B, C, D, E, F};
- CheckLoopContains(loop, 5);
+ CheckLoop(order, loop, 5);
}
}
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 6, true);
BasicBlock* loop1[] = {B, C, D, E};
- CheckLoopContains(loop1, 4);
+ CheckLoop(order, loop1, 4);
BasicBlock* loop2[] = {C, D};
- CheckLoopContains(loop2, 2);
+ CheckLoop(order, loop2, 2);
}
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, 8, true);
BasicBlock* loop1[] = {B, C, D, E, F, G};
- CheckLoopContains(loop1, 6);
+ CheckLoop(order, loop1, 6);
BasicBlock* loop2[] = {C, D, E, F};
- CheckLoopContains(loop2, 4);
+ CheckLoop(order, loop2, 4);
BasicBlock* loop3[] = {D, E};
- CheckLoopContains(loop3, 2);
+ CheckLoop(order, loop3, 2);
}
ZonePool zone_pool(scope.main_isolate());
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
- CheckLoopContains(loop1->nodes, loop1->count);
-
CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
static_cast<int>(order->size()));
- CheckLoopContains(loop1->nodes, loop1->count);
- CheckLoopContains(loop2->nodes, loop2->count);
+
+ loop1->Check(order);
+ loop2->Check(order);
}
ZonePool zone_pool(scope.main_isolate());
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
- CheckLoopContains(loop1->nodes, loop1->count);
-
CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
static_cast<int>(order->size()));
- CheckLoopContains(loop1->nodes, loop1->count);
- CheckLoopContains(loop2->nodes, loop2->count);
+ loop1->Check(order);
+ loop2->Check(order);
}
ZonePool zone_pool(scope.main_isolate());
BasicBlockVector* order =
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
- CheckLoopContains(loop1->nodes, loop1->count);
CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
static_cast<int>(order->size()));
- CheckLoopContains(loop1->nodes, loop1->count);
- CheckLoopContains(loop2->nodes, loop2->count);
+ loop1->Check(order);
+ loop2->Check(order);
}
}
}
ZonePool zone_pool(scope.main_isolate());
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
- CheckLoopContains(loop1->nodes, loop1->count);
-
CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
static_cast<int>(order->size()));
- CheckLoopContains(loop1->nodes, loop1->count);
- CheckLoopContains(loop2->nodes, loop2->count);
+ loop1->Check(order);
+ loop2->Check(order);
BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C};
- CheckLoopContains(loop3, 4);
+ CheckLoop(order, loop3, 4);
}
BasicBlockVector* order =
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, schedule.BasicBlockCount(), true);
- CheckLoopContains(loop1->nodes, loop1->count);
+ loop1->Check(order);
}
}
}
BasicBlockVector* order =
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, schedule.BasicBlockCount(), true);
- CheckLoopContains(loop1->nodes, loop1->count);
+ loop1->Check(order);
}
}
}
BasicBlockVector* order =
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, schedule.BasicBlockCount(), true);
- CheckLoopContains(loop1->nodes, loop1->count);
+ loop1->Check(order);
}
}
BasicBlockVector* order =
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
CheckRPONumbers(order, schedule.BasicBlockCount(), true);
- CheckLoopContains(loop1->nodes, loop1->count);
+ loop1->Check(order);
for (int j = 0; j < size; j++) {
- CheckLoopContains(loopN[j]->nodes, loopN[j]->count);
+ loopN[j]->Check(order);
delete loopN[j];
}
delete[] loopN;
CheckRPONumbers(order, 5, true);
BasicBlock* loop1[] = {B, C, D, E};
- CheckLoopContains(loop1, 4);
+ CheckLoop(order, loop1, 4);
}