From be9a92aa804c0d210f80966b74ef8ed3987f335a Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Tue, 25 Feb 2014 14:22:56 +0000 Subject: Add conditional branches, and build dominator tree. Change-Id: I4b151a07b72692961235a1419b54b6b45cf54e63 --- compiler/optimizing/nodes.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'compiler/optimizing/nodes.cc') diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index e7e9f47..9ec8e89 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -24,6 +24,103 @@ void HGraph::AddBlock(HBasicBlock* block) { blocks_.Add(block); } +void HGraph::FindBackEdges(ArenaBitVector* visited) const { + ArenaBitVector visiting(arena_, blocks_.Size(), false); + VisitBlockForBackEdges(GetEntryBlock(), visited, &visiting); +} + +void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) const { + for (size_t i = 0; i < blocks_.Size(); i++) { + if (!visited.IsBitSet(i)) { + HBasicBlock* block = blocks_.Get(i); + for (size_t j = 0; j < block->successors()->Size(); j++) { + block->successors()->Get(j)->RemovePredecessor(block); + } + } + } +} + +void HGraph::VisitBlockForBackEdges(HBasicBlock* block, + ArenaBitVector* visited, + ArenaBitVector* visiting) const { + int id = block->block_id(); + if (visited->IsBitSet(id)) return; + + visited->SetBit(id); + visiting->SetBit(id); + for (size_t i = 0; i < block->successors()->Size(); i++) { + HBasicBlock* successor = block->successors()->Get(i); + if (visiting->IsBitSet(successor->block_id())) { + successor->AddBackEdge(block); + } else { + VisitBlockForBackEdges(successor, visited, visiting); + } + } + visiting->ClearBit(id); +} + +void HGraph::BuildDominatorTree() { + ArenaBitVector visited(arena_, blocks_.Size(), false); + + // (1) Find the back edges in the graph doing a DFS traversal. + FindBackEdges(&visited); + + // (2) Remove blocks not visited during the initial DFS. + // Step (3) requires dead blocks to be removed from the + // predecessors list of live blocks. + RemoveDeadBlocks(visited); + + // (3) Compute the immediate dominator of each block. We visit + // the successors of a block only when all its forward branches + // have been processed. + GrowableArray visits(arena_, blocks_.Size()); + visits.SetSize(blocks_.Size()); + HBasicBlock* entry = GetEntryBlock(); + dominator_order_.Add(entry); + for (size_t i = 0; i < entry->successors()->Size(); i++) { + VisitBlockForDominatorTree(entry->successors()->Get(i), entry, &visits); + } +} + +HBasicBlock* HGraph::FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const { + ArenaBitVector visited(arena_, blocks_.Size(), false); + // Walk the dominator tree of the first block and mark the visited blocks. + while (first != nullptr) { + visited.SetBit(first->block_id()); + first = first->dominator(); + } + // Walk the dominator tree of the second block until a marked block is found. + while (second != nullptr) { + if (visited.IsBitSet(second->block_id())) { + return second; + } + second = second->dominator(); + } + LOG(ERROR) << "Could not find common dominator"; + return nullptr; +} + +void HGraph::VisitBlockForDominatorTree(HBasicBlock* block, + HBasicBlock* predecessor, + GrowableArray* visits) { + if (block->dominator() == nullptr) { + block->set_dominator(predecessor); + } else { + block->set_dominator(FindCommonDominator(block->dominator(), predecessor)); + } + + visits->Increment(block->block_id()); + // Once all the forward edges have been visited, we know the immediate + // dominator of the block. We can then start visiting its successors. + if (visits->Get(block->block_id()) == + block->predecessors()->Size() - block->NumberOfBackEdges()) { + dominator_order_.Add(block); + for (size_t i = 0; i < block->successors()->Size(); i++) { + VisitBlockForDominatorTree(block->successors()->Get(i), block, visits); + } + } +} + void HBasicBlock::AddInstruction(HInstruction* instruction) { if (first_instruction_ == nullptr) { DCHECK(last_instruction_ == nullptr); -- cgit v1.1