summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/ssa_builder.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-06-04 12:12:08 +0100
committerNicolas Geoffray <ngeoffray@google.com>2014-06-04 13:39:37 +0100
commit7c3560f2ce0ec9484004d05a94bfaa6e02f5a96a (patch)
tree44544a733178fe7416264e064477c681f08ae562 /compiler/optimizing/ssa_builder.cc
parent57795db7d44bcd6d106481fa192691400b2358c8 (diff)
downloadart-7c3560f2ce0ec9484004d05a94bfaa6e02f5a96a.zip
art-7c3560f2ce0ec9484004d05a94bfaa6e02f5a96a.tar.gz
art-7c3560f2ce0ec9484004d05a94bfaa6e02f5a96a.tar.bz2
Fix a bug in SSA construction.
If a join block does not have an incoming value for a local from a predecessor block, we should not create a phi. The verifier has made sure the local is updated before any following reads after this block. Change-Id: Id2785efc73c9fb3224826fff2f4b4ad215905ff4
Diffstat (limited to 'compiler/optimizing/ssa_builder.cc')
-rw-r--r--compiler/optimizing/ssa_builder.cc18
1 files changed, 15 insertions, 3 deletions
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index 33084df..1284a97 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -95,14 +95,26 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
// All predecessors have already been visited because we are visiting in reverse post order.
// We merge the values of all locals, creating phis if those values differ.
for (size_t local = 0; local < current_locals_->Size(); local++) {
+ bool one_predecessor_has_no_value = false;
bool is_different = false;
HInstruction* value = ValueOfLocal(block->GetPredecessors().Get(0), local);
- for (size_t i = 1; i < block->GetPredecessors().Size(); i++) {
- if (ValueOfLocal(block->GetPredecessors().Get(i), local) != value) {
+
+ for (size_t i = 0, e = block->GetPredecessors().Size(); i < e; ++i) {
+ HInstruction* current = ValueOfLocal(block->GetPredecessors().Get(i), local);
+ if (current == nullptr) {
+// one_predecessor_has_no_value = true;
+// break;
+ } else if (current != value) {
is_different = true;
- break;
}
}
+
+ if (one_predecessor_has_no_value) {
+ // If one predecessor has no value for this local, we trust the verifier has
+ // successfully checked that there is a store dominating any read after this block.
+ continue;
+ }
+
if (is_different) {
HPhi* phi = new (GetGraph()->GetArena()) HPhi(
GetGraph()->GetArena(), local, block->GetPredecessors().Size(), Primitive::kPrimVoid);