diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-24 17:47:10 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-11-24 18:05:48 +0000 |
commit | a8eed3acbc39c71ec22dc2943e71eaa07c6507dd (patch) | |
tree | 73f00c656e118c118c0b7dd8985df06624ca4666 /compiler/optimizing/ssa_liveness_analysis.cc | |
parent | 4d3ed1a6f34bd31ed30faaca0433cf2a4b19bb7b (diff) | |
download | art-a8eed3acbc39c71ec22dc2943e71eaa07c6507dd.zip art-a8eed3acbc39c71ec22dc2943e71eaa07c6507dd.tar.gz art-a8eed3acbc39c71ec22dc2943e71eaa07c6507dd.tar.bz2 |
Revert "Revert "Fix the computation of linear ordering.""
PS2 fixes the obvious typos/wrong refactoring.
This reverts commit e50fa5887b1342b845826197d81950e26753fc9c.
Change-Id: I22f81d63a12cf01aafd61535abc2399d936d49c2
Diffstat (limited to 'compiler/optimizing/ssa_liveness_analysis.cc')
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.cc | 93 |
1 files changed, 53 insertions, 40 deletions
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 0085b27..660a5c5 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -28,11 +28,6 @@ void SsaLivenessAnalysis::Analyze() { ComputeLiveness(); } -static bool IsLoopExit(HLoopInformation* current, HLoopInformation* to) { - // `to` is either not part of a loop, or `current` is an inner loop of `to`. - return to == nullptr || (current != to && current->IsIn(*to)); -} - static bool IsLoop(HLoopInformation* info) { return info != nullptr; } @@ -48,46 +43,64 @@ static bool IsInnerLoop(HLoopInformation* outer, HLoopInformation* inner) { && inner->IsIn(*outer); } -static void VisitBlockForLinearization(HBasicBlock* block, - GrowableArray<HBasicBlock*>* order, - ArenaBitVector* visited) { - if (visited->IsBitSet(block->GetBlockId())) { - return; - } - visited->SetBit(block->GetBlockId()); - size_t number_of_successors = block->GetSuccessors().Size(); - if (number_of_successors == 0) { - // Nothing to do. - } else if (number_of_successors == 1) { - VisitBlockForLinearization(block->GetSuccessors().Get(0), order, visited); - } else { - DCHECK_EQ(number_of_successors, 2u); - HBasicBlock* first_successor = block->GetSuccessors().Get(0); - HBasicBlock* second_successor = block->GetSuccessors().Get(1); - HLoopInformation* my_loop = block->GetLoopInformation(); - HLoopInformation* first_loop = first_successor->GetLoopInformation(); - HLoopInformation* second_loop = second_successor->GetLoopInformation(); - - if (!IsLoop(my_loop)) { - // Nothing to do. Current order is fine. - } else if (IsLoopExit(my_loop, second_loop) && InSameLoop(my_loop, first_loop)) { - // Visit the loop exit first in post order. - std::swap(first_successor, second_successor); - } else if (IsInnerLoop(my_loop, first_loop) && !IsInnerLoop(my_loop, second_loop)) { - // Visit the inner loop last in post order. - std::swap(first_successor, second_successor); +static void AddToListForLinearization(GrowableArray<HBasicBlock*>* worklist, HBasicBlock* block) { + size_t insert_at = worklist->Size(); + HLoopInformation* block_loop = block->GetLoopInformation(); + for (; insert_at > 0; --insert_at) { + HBasicBlock* current = worklist->Get(insert_at - 1); + HLoopInformation* current_loop = current->GetLoopInformation(); + if (InSameLoop(block_loop, current_loop) + || !IsLoop(current_loop) + || IsInnerLoop(current_loop, block_loop)) { + // The block can be processed immediately. + break; } - VisitBlockForLinearization(first_successor, order, visited); - VisitBlockForLinearization(second_successor, order, visited); } - order->Add(block); + worklist->InsertAt(insert_at, block); } void SsaLivenessAnalysis::LinearizeGraph() { - // For simplicity of the implementation, we create post linear order. The order for - // computing live ranges is the reverse of that order. - ArenaBitVector visited(graph_.GetArena(), graph_.GetBlocks().Size(), false); - VisitBlockForLinearization(graph_.GetEntryBlock(), &linear_post_order_, &visited); + // 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. + GrowableArray<uint32_t> forward_predecessors(graph_.GetArena(), graph_.GetBlocks().Size()); + forward_predecessors.SetSize(graph_.GetBlocks().Size()); + for (size_t i = 0, e = graph_.GetBlocks().Size(); i < e; ++i) { + HBasicBlock* block = graph_.GetBlocks().Get(i); + size_t number_of_forward_predecessors = block->GetPredecessors().Size(); + if (block->IsLoopHeader()) { + // We rely on having simplified the CFG. + DCHECK_EQ(1u, block->GetLoopInformation()->NumberOfBackEdges()); + number_of_forward_predecessors--; + } + forward_predecessors.Put(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. + GrowableArray<HBasicBlock*> worklist(graph_.GetArena(), 1); + worklist.Add(graph_.GetEntryBlock()); + do { + HBasicBlock* current = worklist.Pop(); + linear_order_.Add(current); + for (size_t i = 0, e = current->GetSuccessors().Size(); i < e; ++i) { + HBasicBlock* successor = current->GetSuccessors().Get(i); + int block_id = successor->GetBlockId(); + size_t number_of_remaining_predecessors = forward_predecessors.Get(block_id); + if (number_of_remaining_predecessors == 1) { + AddToListForLinearization(&worklist, successor); + } + forward_predecessors.Put(block_id, number_of_remaining_predecessors - 1); + } + } while (!worklist.IsEmpty()); } void SsaLivenessAnalysis::NumberInstructions() { |