diff options
| author | 2015-12-02 09:03:44 +0000 | |
|---|---|---|
| committer | 2015-12-02 09:03:44 +0000 | |
| commit | 5f3fb18e9705f7d0d594f665858bff2020409c6a (patch) | |
| tree | cd23e1e0a3cea10cc9a9ae8269a01f75ada8ef0e /compiler/optimizing | |
| parent | 3a738bfe9784b9ea0f2fccbe75f0c72ede536641 (diff) | |
Revert "ART: Do not eagerly type LoopPhi [null, ...]"
Breaks some libcore tests. Revert to unblock others while investigating.
This reverts commit 3a738bfe9784b9ea0f2fccbe75f0c72ede536641.
Change-Id: I9f103c692199b8f9b6e7af469fc424512b57544a
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 103 | ||||
| -rw-r--r-- | compiler/optimizing/reference_type_propagation.h | 1 |
2 files changed, 6 insertions, 98 deletions
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index bcdbeecfd7..0d05c49fc5 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -127,87 +127,6 @@ void ReferenceTypePropagation::ValidateTypes() { } } -static void CheckHasNoTypedInputs(HInstruction* root_instr) { - ArenaAllocatorAdapter<void> adapter = - root_instr->GetBlock()->GetGraph()->GetArena()->Adapter(kArenaAllocReferenceTypePropagation); - - ArenaVector<HPhi*> visited_phis(adapter); - ArenaVector<HInstruction*> worklist(adapter); - worklist.push_back(root_instr); - - while (!worklist.empty()) { - HInstruction* instr = worklist.back(); - worklist.pop_back(); - - if (instr->IsPhi() || instr->IsBoundType() || instr->IsNullCheck()) { - // Expect that both `root_instr` and its inputs have invalid RTI. - ScopedObjectAccess soa(Thread::Current()); - DCHECK(!instr->GetReferenceTypeInfo().IsValid()) << "Instruction should not have valid RTI."; - - // Insert all unvisited inputs to the worklist. - for (HInputIterator it(instr); !it.Done(); it.Advance()) { - HInstruction* input = it.Current(); - if (input->IsPhi()) { - if (ContainsElement(visited_phis, input->AsPhi())) { - continue; - } else { - visited_phis.push_back(input->AsPhi()); - } - } - worklist.push_back(input); - } - } else if (instr->IsNullConstant()) { - // The only input of `root_instr` allowed to have valid RTI because it is ignored. - } else { - LOG(FATAL) << "Unexpected input " << instr->DebugName() << instr->GetId() << " with RTI " - << instr->GetReferenceTypeInfo(); - UNREACHABLE(); - } - } -} - -template<typename Functor> -static void ForEachUntypedInstruction(HGraph* graph, Functor fn) { - ScopedObjectAccess soa(Thread::Current()); - for (HReversePostOrderIterator block_it(*graph); !block_it.Done(); block_it.Advance()) { - for (HInstructionIterator it(block_it.Current()->GetPhis()); !it.Done(); it.Advance()) { - HInstruction* instr = it.Current(); - if (instr->GetType() == Primitive::kPrimNot && !instr->GetReferenceTypeInfo().IsValid()) { - fn(instr); - } - } - for (HInstructionIterator it(block_it.Current()->GetInstructions()); !it.Done(); it.Advance()) { - HInstruction* instr = it.Current(); - if (instr->GetType() == Primitive::kPrimNot && !instr->GetReferenceTypeInfo().IsValid()) { - fn(instr); - } - } - } -} - -void ReferenceTypePropagation::SetUntypedInstructionsToObject() { - // In some cases, the fix-point iteration will leave kPrimNot instructions with - // invalid RTI because bytecode does not provide enough typing information. - // Set the RTI of such instructions to Object. - // Example: - // MyClass a = null, b = null; - // while (a == null) { - // if (cond) { a = b; } else { b = a; } - // } - - if (kIsDebugBuild) { - // Test that if we are going to set RTI from invalid to Object, that - // instruction did not have any typed instructions in its def-use chain - // and therefore its type could not be inferred. - ForEachUntypedInstruction(graph_, [](HInstruction* instr) { CheckHasNoTypedInputs(instr); }); - } - - ReferenceTypeInfo obj_rti = ReferenceTypeInfo::Create(object_class_handle_, /* is_exact */ false); - ForEachUntypedInstruction(graph_, [obj_rti](HInstruction* instr) { - instr->SetReferenceTypeInfo(obj_rti); - }); -} - void ReferenceTypePropagation::Run() { // To properly propagate type info we need to visit in the dominator-based order. // Reverse post order guarantees a node's dominators are visited first. @@ -217,7 +136,6 @@ void ReferenceTypePropagation::Run() { } ProcessWorklist(); - SetUntypedInstructionsToObject(); ValidateTypes(); } @@ -616,9 +534,8 @@ void RTPVisitor::VisitLoadException(HLoadException* instr) { void RTPVisitor::VisitNullCheck(HNullCheck* instr) { ScopedObjectAccess soa(Thread::Current()); ReferenceTypeInfo parent_rti = instr->InputAt(0)->GetReferenceTypeInfo(); - if (parent_rti.IsValid()) { - instr->SetReferenceTypeInfo(parent_rti); - } + DCHECK(parent_rti.IsValid()); + instr->SetReferenceTypeInfo(parent_rti); } void RTPVisitor::VisitFakeString(HFakeString* instr) { @@ -671,16 +588,11 @@ void ReferenceTypePropagation::VisitPhi(HPhi* phi) { } if (phi->GetBlock()->IsLoopHeader()) { - ScopedObjectAccess soa(Thread::Current()); // Set the initial type for the phi. Use the non back edge input for reaching // a fixed point faster. - HInstruction* first_input = phi->InputAt(0); - ReferenceTypeInfo first_input_rti = first_input->GetReferenceTypeInfo(); - if (first_input_rti.IsValid() && !first_input->IsNullConstant()) { - phi->SetCanBeNull(first_input->CanBeNull()); - phi->SetReferenceTypeInfo(first_input_rti); - } AddToWorklist(phi); + phi->SetCanBeNull(phi->InputAt(0)->CanBeNull()); + phi->SetReferenceTypeInfo(phi->InputAt(0)->GetReferenceTypeInfo()); } else { // Eagerly compute the type of the phi, for quicker convergence. Note // that we don't need to add users to the worklist because we are @@ -771,7 +683,7 @@ bool ReferenceTypePropagation::UpdateReferenceTypeInfo(HInstruction* instr) { instr->SetReferenceTypeInfo(parent_rti); } } else if (instr->IsArrayGet()) { - // TODO: consider if it's worth "looking back" and binding the input object + // TODO: consider if it's worth "looking back" and bounding the input object // to an array type. UpdateArrayGet(instr->AsArrayGet(), handles_, object_class_handle_); } else { @@ -858,10 +770,7 @@ void ReferenceTypePropagation::UpdatePhi(HPhi* instr) { } } } - - if (new_rti.IsValid()) { - instr->SetReferenceTypeInfo(new_rti); - } + instr->SetReferenceTypeInfo(new_rti); } // Re-computes and updates the nullability of the instruction. Returns whether or diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 21789e1331..5c05592726 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -57,7 +57,6 @@ class ReferenceTypePropagation : public HOptimization { SHARED_REQUIRES(Locks::mutator_lock_); void ValidateTypes(); - void SetUntypedInstructionsToObject(); StackHandleScopeCollection* handles_; |