diff options
author | 2015-06-11 11:17:49 +0100 | |
---|---|---|
committer | 2015-06-25 16:58:08 +0100 | |
commit | 0b5c7d1994b76090afcc825e737f2b8c546da2f8 (patch) | |
tree | 057eddf8830b1991f02af3c3ce1b63dee90dd2ad /compiler/optimizing/graph_checker.cc | |
parent | 1dd3136d9f6b1c7d551897a2d96c8314e40f7324 (diff) |
ART: Implement try/catch blocks in Builder
This patch enables the GraphBuilder to generate blocks and edges which
represent the exceptional control flow when try/catch blocks are
present in the code. Actual compilation is still delegated to Quick
and Baseline ignores the additional code.
To represent the relationship between try and catch blocks, Builder
splits the edges which enter/exit a try block and links the newly
created blocks to the corresponding exception handlers. This layout
will later enable the SsaBuilder to correctly infer the dominators of
the catch blocks and to produce the appropriate reverse post ordering.
It will not, however, allow for building the complete SSA form of the
catch blocks and consequently optimizing such blocks.
To this end, a new TryBoundary control-flow instruction is introduced.
Codegen treats it the same as a Goto but it allows for additional
successors (the handlers).
Change-Id: I415b985596d5bebb7b1bb358a46e08b7b04bb53a
Diffstat (limited to 'compiler/optimizing/graph_checker.cc')
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index fd28f0b83f..d7e6bd8161 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -81,7 +81,10 @@ void GraphChecker::VisitBasicBlock(HBasicBlock* block) { } // Ensure `block` ends with a branch instruction. - if (!block->EndsWithControlFlowInstruction()) { + // This invariant is not enforced on non-SSA graphs. Graph built from DEX with + // dead code that falls out of the method will not end with a control-flow + // instruction. Such code is removed during the SSA-building DCE phase. + if (GetGraph()->IsInSsaForm() && !block->EndsWithControlFlowInstruction()) { AddError(StringPrintf("Block %d does not end with a branch instruction.", block->GetBlockId())); } @@ -253,6 +256,22 @@ void GraphChecker::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) { } } +void GraphChecker::VisitReturn(HReturn* ret) { + if (!ret->GetBlock()->GetSingleSuccessor()->IsExitBlock()) { + AddError(StringPrintf("%s:%d does not jump to the exit block.", + ret->DebugName(), + ret->GetId())); + } +} + +void GraphChecker::VisitReturnVoid(HReturnVoid* ret) { + if (!ret->GetBlock()->GetSingleSuccessor()->IsExitBlock()) { + AddError(StringPrintf("%s:%d does not jump to the exit block.", + ret->DebugName(), + ret->GetId())); + } +} + void SSAChecker::VisitBasicBlock(HBasicBlock* block) { super_type::VisitBasicBlock(block); |