From: Nicolas Geoffray Date: Wed, 24 Jun 2015 11:20:24 +0000 (+0100) Subject: Recompute dominator tree after DCE. X-Git-Tag: android-x86-7.1-r1~889^2~901^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=1f82ecc6a0c9f88d03d6d1a6d95eeb8707bd06c1;p=android-x86%2Fart.git Recompute dominator tree after DCE. bug:22031382 Change-Id: Ifebe169897b76872015e3ce0ed7d0a9662f80cef --- diff --git a/compiler/optimizing/boolean_simplifier.cc b/compiler/optimizing/boolean_simplifier.cc index 8100a29f3..daf7d6774 100644 --- a/compiler/optimizing/boolean_simplifier.cc +++ b/compiler/optimizing/boolean_simplifier.cc @@ -141,6 +141,12 @@ void HBooleanSimplifier::TryRemovingBooleanSelection(HBasicBlock* block) { block->MergeWith(false_block); block->MergeWith(merge_block); + // No need to update any dominance information, as we are simplifying + // a simple diamond shape, where the join block is merged with the + // entry block. Any following blocks would have had the join block + // as a dominator, and `MergeWith` handles changing that to the + // entry block. + // Remove the original condition if it is now unused. if (!if_condition->HasUses()) { if_condition->GetBlock()->RemoveInstructionOrPhi(if_condition); diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index fdfe518e9..5de629d60 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -68,6 +68,7 @@ void HDeadCodeElimination::RemoveDeadBlocks() { ArenaBitVector affected_loops(allocator, graph_->GetBlocks().Size(), false); MarkReachableBlocks(graph_->GetEntryBlock(), &live_blocks); + bool removed_one_or_more_blocks = false; // Remove all dead blocks. Iterate in post order because removal needs the // block's chain of dominators and nested loops need to be updated from the @@ -84,9 +85,17 @@ void HDeadCodeElimination::RemoveDeadBlocks() { MaybeRecordDeadBlock(block); MarkLoopHeadersContaining(*block, &affected_loops); block->DisconnectAndDelete(); + removed_one_or_more_blocks = true; } } + // If we removed at least one block, we need to recompute the full + // dominator tree. + if (removed_one_or_more_blocks) { + graph_->ClearDominanceInformation(); + graph_->ComputeDominanceInformation(); + } + // Connect successive blocks created by dead branches. Order does not matter. for (HReversePostOrderIterator it(*graph_); !it.Done();) { HBasicBlock* block = it.Current(); diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 01eb2d7f8..3891a152c 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -117,9 +117,24 @@ void HGraph::BuildDominatorTree() { // dominators and the reverse post order. SimplifyCFG(); - // (5) Compute the immediate dominator of each block. We visit - // the successors of a block only when all its forward branches - // have been processed. + // (5) Compute the dominance information and the reverse post order. + ComputeDominanceInformation(); +} + +void HGraph::ClearDominanceInformation() { + for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) { + it.Current()->ClearDominanceInformation(); + } + reverse_post_order_.Reset(); +} + +void HBasicBlock::ClearDominanceInformation() { + dominated_blocks_.Reset(); + dominator_ = nullptr; +} + +void HGraph::ComputeDominanceInformation() { + DCHECK(reverse_post_order_.IsEmpty()); GrowableArray visits(arena_, blocks_.Size()); visits.SetSize(blocks_.Size()); reverse_post_order_.Add(entry_block_); @@ -1133,8 +1148,7 @@ void HBasicBlock::DisconnectAndDelete() { } predecessors_.Reset(); - // Disconnect the block from its successors and update their dominators - // and phis. + // Disconnect the block from its successors and update their phis. for (size_t i = 0, e = successors_.Size(); i < e; ++i) { HBasicBlock* successor = successors_.Get(i); // Delete this block from the list of predecessors. @@ -1145,19 +1159,6 @@ void HBasicBlock::DisconnectAndDelete() { // dominator of `successor` which violates the order DCHECKed at the top. DCHECK(!successor->predecessors_.IsEmpty()); - // Recompute the successor's dominator. - HBasicBlock* old_dominator = successor->GetDominator(); - HBasicBlock* new_dominator = successor->predecessors_.Get(0); - for (size_t j = 1, f = successor->predecessors_.Size(); j < f; ++j) { - new_dominator = graph_->FindCommonDominator( - new_dominator, successor->predecessors_.Get(j)); - } - if (old_dominator != new_dominator) { - successor->SetDominator(new_dominator); - old_dominator->RemoveDominatedBlock(successor); - new_dominator->AddDominatedBlock(successor); - } - // Remove this block's entries in the successor's phis. if (successor->predecessors_.Size() == 1u) { // The successor has just one predecessor left. Replace phis with the only diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 26eee1c52..581645f21 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -183,6 +183,9 @@ class HGraph : public ArenaObject { return true; } + void ComputeDominanceInformation(); + void ClearDominanceInformation(); + void BuildDominatorTree(); void TransformToSsa(); void SimplifyCFG(); @@ -590,11 +593,10 @@ class HBasicBlock : public ArenaObject { LOG(FATAL) << "Unreachable"; UNREACHABLE(); } + void ClearDominanceInformation(); int NumberOfBackEdges() const { - return loop_information_ == nullptr - ? 0 - : loop_information_->NumberOfBackEdges(); + return IsLoopHeader() ? loop_information_->NumberOfBackEdges() : 0; } HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; } diff --git a/test/515-dce-dominator/expected.txt b/test/515-dce-dominator/expected.txt new file mode 100644 index 000000000..ccaf6f8f0 --- /dev/null +++ b/test/515-dce-dominator/expected.txt @@ -0,0 +1 @@ +Enter diff --git a/test/515-dce-dominator/info.txt b/test/515-dce-dominator/info.txt new file mode 100644 index 000000000..af706e019 --- /dev/null +++ b/test/515-dce-dominator/info.txt @@ -0,0 +1,3 @@ +Regression test for the DCE phase of optimizing, where +we need to recompute the full dominance information of +the graph when blocks get removed. diff --git a/test/515-dce-dominator/smali/Dominator.smali b/test/515-dce-dominator/smali/Dominator.smali new file mode 100644 index 000000000..a504aba15 --- /dev/null +++ b/test/515-dce-dominator/smali/Dominator.smali @@ -0,0 +1,37 @@ +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +.class public LDominator; + +.super Ljava/lang/Object; + +.method public static method(I)I + .registers 2 + const/4 v0, 0 + :b1 + if-ne v0, v0, :b3 + :b2 + if-eq v0, p0, :b4 + :b5 + if-eq v0, p0, :b2 + goto :b6 + :b4 + goto :b7 + :b3 + goto :b6 + :b6 + goto :b7 + :b7 + return v1 +.end method diff --git a/test/515-dce-dominator/src/Main.java b/test/515-dce-dominator/src/Main.java new file mode 100644 index 000000000..bf9ee2560 --- /dev/null +++ b/test/515-dce-dominator/src/Main.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Method; + +public class Main { + public static void main(String[] args) throws Exception { + // Workaround for b/18051191. + System.out.println("Enter"); + Class c = Class.forName("Dominator"); + Method m = c.getMethod("method", int.class); + Object[] arguments = { 5 }; + m.invoke(null, arguments); + } +}