// Helper method to update work list for linear order. staticvoid AddToListForLinearization(ScopedArenaVector<HBasicBlock*>* worklist,
HBasicBlock* block) {
HLoopInformation* block_loop = block->GetLoopInformation(); auto insert_pos = worklist->rbegin(); // insert_pos.base() will be the actual position.
bool block_is_back_edge = false; if (block_loop != nullptr) { for (HBasicBlock* successor : block->GetSuccessors()) { if (successor == block_loop->GetHeader()) {
block_is_back_edge = true; break;
}
}
}
for (auto end = worklist->rend(); insert_pos != end; ++insert_pos) {
HBasicBlock* current = *insert_pos;
HLoopInformation* current_loop = current->GetLoopInformation(); if (!IsLoop(current_loop) || IsInnerLoop(current_loop, block_loop)) { // The block can be processed immediately. break;
}
if (InSameLoop(block_loop, current_loop)) {
DCHECK(IsLoop(current_loop)); constbool current_is_back_edge = current_loop->IsBackEdge(*current); if (!block_is_back_edge || current_is_back_edge) { // Prioritize non-backedges before backedges. break;
}
}
}
worklist->insert(insert_pos.base(), block);
}
// Helper method to validate linear order. staticbool IsLinearOrderWellFormed(const HGraph* graph, ArrayRef<HBasicBlock*> linear_order) { for (HBasicBlock* header : graph->GetBlocks()) { if (header == nullptr || !header->IsLoopHeader()) { continue;
}
HLoopInformation* loop = header->GetLoopInformation();
size_t num_blocks = loop->GetBlockMask().NumSetBits();
size_t found_blocks = 0u; for (HBasicBlock* block : linear_order) { if (loop->Contains(*block)) {
found_blocks++; if (found_blocks == 1u && block != header) { // First block is not the header. returnfalse;
} elseif (found_blocks == num_blocks && !loop->IsBackEdge(*block)) { // Last block is not a back edge. returnfalse;
}
} elseif (found_blocks != 0u && found_blocks != num_blocks) { // Blocks are not adjacent. returnfalse;
}
}
DCHECK_EQ(found_blocks, num_blocks);
} returntrue;
}
void LinearizeGraphInternal(const HGraph* graph, ArrayRef<HBasicBlock*> linear_order) {
DCHECK_EQ(linear_order.size(), graph->GetReversePostOrder().size()); // Create a reverse post ordering with the following properties: // - Blocks in a loop are consecutive, // - Back-edge is the last block before loop exits. // // (1): Record the number of forward predecessors for each block. This is to // ensure the resulting order is reverse post order. We could use the // current reverse post order in the graph, but it would require making // order queries to a GrowableArray, which is not the best data structure // for it.
ScopedArenaAllocator allocator(graph->GetArenaStack());
ScopedArenaVector<uint32_t> forward_predecessors(graph->GetBlocks().size(),
allocator.Adapter(kArenaAllocLinearOrder)); for (HBasicBlock* block : graph->GetReversePostOrder()) {
size_t number_of_forward_predecessors = block->GetPredecessors().size(); if (block->IsLoopHeader()) {
number_of_forward_predecessors -= block->GetLoopInformation()->NumberOfBackEdges();
}
forward_predecessors[block->GetBlockId()] = number_of_forward_predecessors;
} // (2): Following a worklist approach, first start with the entry block, and // iterate over the successors. When all non-back edge predecessors of a // successor block are visited, the successor block is added in the worklist // following an order that satisfies the requirements to build our linear graph.
ScopedArenaVector<HBasicBlock*> worklist(allocator.Adapter(kArenaAllocLinearOrder));
worklist.push_back(graph->GetEntryBlock());
size_t num_added = 0u; do {
HBasicBlock* current = worklist.back();
worklist.pop_back();
linear_order[num_added] = current;
++num_added; for (HBasicBlock* successor : current->GetSuccessors()) { int block_id = successor->GetBlockId();
size_t number_of_remaining_predecessors = forward_predecessors[block_id]; if (number_of_remaining_predecessors == 1) {
AddToListForLinearization(&worklist, successor);
}
forward_predecessors[block_id] = number_of_remaining_predecessors - 1;
}
} while (!worklist.empty());
DCHECK_EQ(num_added, linear_order.size());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.