diff options
| author | 2015-09-22 13:04:14 +0100 | |
|---|---|---|
| committer | 2015-09-25 10:40:08 +0100 | |
| commit | d7558daaa86decf5a38f4f9bcd82267ab6e3e17f (patch) | |
| tree | abfbc97a44e301f850b775eaa1d63aaa5efd1a0e /compiler/optimizing/nodes.cc | |
| parent | c7e0da5292e841f6a864dd010bd6e0b06e0ece73 (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.cc | 26 |
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() |