Handle String.<init> with a phi input.

We wrongly assumed only irreducible loops could lead
to this situation, but any loop can actually be in between
a String NewInstance and a String.<init>.

bug: 109666561
Test: 563-checker-fakestring
Change-Id: I018a22f7e22c15e140252544415f51d544f7cc13
diff --git a/compiler/optimizing/ssa_builder.h b/compiler/optimizing/ssa_builder.h
index 60831a9..7655445 100644
--- a/compiler/optimizing/ssa_builder.h
+++ b/compiler/optimizing/ssa_builder.h
@@ -61,7 +61,8 @@
         local_allocator_(local_allocator),
         ambiguous_agets_(local_allocator->Adapter(kArenaAllocGraphBuilder)),
         ambiguous_asets_(local_allocator->Adapter(kArenaAllocGraphBuilder)),
-        uninitialized_strings_(local_allocator->Adapter(kArenaAllocGraphBuilder)) {
+        uninitialized_strings_(local_allocator->Adapter(kArenaAllocGraphBuilder)),
+        uninitialized_string_phis_(local_allocator->Adapter(kArenaAllocGraphBuilder)) {
     graph_->InitializeInexactObjectRTI(handles);
   }
 
@@ -96,6 +97,10 @@
     }
   }
 
+  void AddUninitializedStringPhi(HPhi* phi, HInvoke* invoke) {
+    uninitialized_string_phis_.push_back(std::make_pair(phi, invoke));
+  }
+
  private:
   void SetLoopHeaderPhiInputs();
   void FixEnvironmentPhis();
@@ -118,6 +123,7 @@
   HArrayGet* GetFloatOrDoubleEquivalentOfArrayGet(HArrayGet* aget);
 
   void RemoveRedundantUninitializedStrings();
+  void ReplaceUninitializedStringPhis();
 
   HGraph* const graph_;
   Handle<mirror::ClassLoader> class_loader_;
@@ -131,6 +137,7 @@
   ScopedArenaVector<HArrayGet*> ambiguous_agets_;
   ScopedArenaVector<HArraySet*> ambiguous_asets_;
   ScopedArenaVector<HNewInstance*> uninitialized_strings_;
+  ScopedArenaVector<std::pair<HPhi*, HInvoke*>> uninitialized_string_phis_;
 
   DISALLOW_COPY_AND_ASSIGN(SsaBuilder);
 };