From bc9ab1630a198efbbf730275541291321ac3d2d4 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Wed, 20 Jan 2016 14:50:19 +0000 Subject: ART: Cannot assume String. called on NewInstance Irreducible loops create uneliminatable phis for all live vregs. This breaks the StringFactory optimization which assumes that the first input is always a NewInstance instruction. Bug: 26676472 Change-Id: Ib7dfdadbafbbfef89e1f5b1a80eb75ecf792621a --- compiler/optimizing/nodes.h | 12 +++--------- compiler/optimizing/ssa_builder.cc | 15 ++++++++++----- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index e222ef7260..019be5d494 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -3689,19 +3689,13 @@ class HInvokeStaticOrDirect : public HInvoke { DCHECK(!IsStaticWithExplicitClinitCheck()); } - HNewInstance* GetThisArgumentOfStringInit() const { + HInstruction* GetAndRemoveThisArgumentOfStringInit() { DCHECK(IsStringInit()); size_t index = InputCount() - 1; - DCHECK(InputAt(index)->IsNewInstance()); - return InputAt(index)->AsNewInstance(); - } - - void RemoveThisArgumentOfStringInit() { - DCHECK(IsStringInit()); - size_t index = InputCount() - 1; - DCHECK(InputAt(index)->IsNewInstance()); + HInstruction* input = InputAt(index); RemoveAsUserOfInput(index); inputs_.pop_back(); + return input; } // Is this a call to a static method whose declaring class has an diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index c0011cde8d..c8244aa800 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -927,16 +927,21 @@ void SsaBuilder::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) { if (invoke->IsStringInit()) { // This is a StringFactory call which acts as a String constructor. Its // result replaces the empty String pre-allocated by NewInstance. - HNewInstance* new_instance = invoke->GetThisArgumentOfStringInit(); - invoke->RemoveThisArgumentOfStringInit(); + HInstruction* arg_this = invoke->GetAndRemoveThisArgumentOfStringInit(); // Replacing the NewInstance might render it redundant. Keep a list of these // to be visited once it is clear whether it is has remaining uses. - uninitialized_strings_.push_back(new_instance); + if (arg_this->IsNewInstance()) { + uninitialized_strings_.push_back(arg_this->AsNewInstance()); + } else { + DCHECK(arg_this->IsIrreducibleLoopHeaderPhi()); + // NewInstance is not the direct input of the StringFactory call. It might + // be redundant but optimizing this case is not worth the effort. + } - // Walk over all vregs and replace any occurrence of `new_instance` with `invoke`. + // Walk over all vregs and replace any occurrence of `arg_this` with `invoke`. for (size_t vreg = 0, e = current_locals_->size(); vreg < e; ++vreg) { - if ((*current_locals_)[vreg] == new_instance) { + if ((*current_locals_)[vreg] == arg_this) { (*current_locals_)[vreg] = invoke; } } -- cgit v1.2.3-59-g8ed1b