summaryrefslogtreecommitdiff
path: root/compiler/optimizing/ssa_builder.h
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2015-07-06 11:48:53 +0100
committer David Brazdil <dbrazdil@google.com> 2015-07-15 17:20:30 +0200
commitffee3d33f3ea39aa6031c3d2ff29c4806c8dcc51 (patch)
tree9b990552fbf7e0ba91954758b07e2a51d95da9cd /compiler/optimizing/ssa_builder.h
parent045da88bd0230ddf48aaf037b3d6c16fbb97ba65 (diff)
ART: Build SSA form when try/catch is present
This patch implements support for try/catch in the SsaBuilder. Values of locals are propagated from throwing sites inside try blocks to their respective catch blocks and phis ("catch phis") are created when necessary. Change-Id: I0736565c2c4ff3f9f0924b6e3a785a50023f875a
Diffstat (limited to 'compiler/optimizing/ssa_builder.h')
-rw-r--r--compiler/optimizing/ssa_builder.h19
1 files changed, 16 insertions, 3 deletions
diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h
index 1c83c4ba48..64600db648 100644
--- a/compiler/optimizing/ssa_builder.h
+++ b/compiler/optimizing/ssa_builder.h
@@ -61,9 +61,22 @@ class SsaBuilder : public HGraphVisitor {
GrowableArray<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
GrowableArray<HInstruction*>* locals = locals_for_.Get(block->GetBlockId());
if (locals == nullptr) {
- locals = new (GetGraph()->GetArena()) GrowableArray<HInstruction*>(
- GetGraph()->GetArena(), GetGraph()->GetNumberOfVRegs());
- locals->SetSize(GetGraph()->GetNumberOfVRegs());
+ const size_t vregs = GetGraph()->GetNumberOfVRegs();
+ ArenaAllocator* arena = GetGraph()->GetArena();
+ locals = new (arena) GrowableArray<HInstruction*>(arena, vregs);
+ locals->SetSize(vregs);
+
+ if (block->IsCatchBlock()) {
+ // We record incoming inputs of catch phis at throwing instructions and
+ // must therefore eagerly create the phis. Unused phis will be removed
+ // in the dead phi analysis.
+ for (size_t i = 0; i < vregs; ++i) {
+ HPhi* phi = new (arena) HPhi(arena, i, 0, Primitive::kPrimVoid);
+ block->AddPhi(phi);
+ locals->Put(i, phi);
+ }
+ }
+
locals_for_.Put(block->GetBlockId(), locals);
}
return locals;