summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.cc
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2015-09-22 13:04:14 +0100
committer David Brazdil <dbrazdil@google.com> 2015-09-25 10:40:08 +0100
commitd7558daaa86decf5a38f4f9bcd82267ab6e3e17f (patch)
treeabfbc97a44e301f850b775eaa1d63aaa5efd1a0e /compiler/optimizing/nodes.cc
parentc7e0da5292e841f6a864dd010bd6e0b06e0ece73 (diff)
ART: Preserve loop headers with try/catch
Algorithm for inserting HTryBoundary instructions would generate a non-natural loop when a loop header block was covered by a TryItem. This patch changes the approach to fix the issue. Bug: 23895756 Change-Id: I0e1ee6cf135cea326a96c97954907d202c9793cc
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r--compiler/optimizing/nodes.cc26
1 files changed, 26 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 1ca990700c..ef89932e3b 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1170,6 +1170,23 @@ HBasicBlock* HBasicBlock::SplitBefore(HInstruction* cursor) {
return new_block;
}
+HBasicBlock* HBasicBlock::CreateImmediateDominator() {
+ DCHECK(!graph_->IsInSsaForm()) << "Support for SSA form not implemented";
+ DCHECK(!IsCatchBlock()) << "Support for updating try/catch information not implemented.";
+
+ HBasicBlock* new_block = new (GetGraph()->GetArena()) HBasicBlock(GetGraph(), GetDexPc());
+
+ for (HBasicBlock* predecessor : GetPredecessors()) {
+ new_block->predecessors_.push_back(predecessor);
+ predecessor->successors_[predecessor->GetSuccessorIndexOf(this)] = new_block;
+ }
+ predecessors_.clear();
+ AddPredecessor(new_block);
+
+ GetGraph()->AddBlock(new_block);
+ return new_block;
+}
+
HBasicBlock* HBasicBlock::SplitAfter(HInstruction* cursor) {
DCHECK(!cursor->IsControlFlow());
DCHECK_NE(instructions_.last_instruction_, cursor);
@@ -1215,6 +1232,15 @@ const HTryBoundary* HBasicBlock::ComputeTryEntryOfSuccessors() const {
}
}
+bool HBasicBlock::HasThrowingInstructions() const {
+ for (HInstructionIterator it(GetInstructions()); !it.Done(); it.Advance()) {
+ if (it.Current()->CanThrow()) {
+ return true;
+ }
+ }
+ return false;
+}
+
static bool HasOnlyOneInstruction(const HBasicBlock& block) {
return block.GetPhis().IsEmpty()
&& !block.GetInstructions().IsEmpty()