diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 9 | ||||
-rw-r--r-- | compiler/optimizing/inliner.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 34 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.h | 5 |
5 files changed, 29 insertions, 47 deletions
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 264c94e938..4111671a9b 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -24,7 +24,6 @@ #include "code_generator.h" #include "dead_code_elimination.h" #include "disassembler.h" -#include "inliner.h" #include "licm.h" #include "nodes.h" #include "optimization.h" @@ -425,6 +424,11 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { return strcmp(pass_name_, name) == 0; } + bool IsReferenceTypePropagationPass() { + return strstr(pass_name_, ReferenceTypePropagation::kReferenceTypePropagationPassName) + != nullptr; + } + void PrintInstruction(HInstruction* instruction) { output_ << instruction->DebugName(); if (instruction->InputCount() > 0) { @@ -488,8 +492,7 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { } else { StartAttributeStream("loop") << "B" << info->GetHeader()->GetBlockId(); } - } else if ((IsPass(ReferenceTypePropagation::kReferenceTypePropagationPassName) - || IsPass(HInliner::kInlinerPassName)) + } else if (IsReferenceTypePropagationPass() && (instruction->GetType() == Primitive::kPrimNot)) { ReferenceTypeInfo info = instruction->IsLoadClass() ? instruction->AsLoadClass()->GetLoadedClassRTI() diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 7a8ac2b3ec..e2aca3091f 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -512,9 +512,6 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, if ((return_replacement != nullptr) && (return_replacement->GetType() == Primitive::kPrimNot)) { - // TODO(calin): If valid, return_replacement could still be object (as a result of a merge). - // This happens because we don't implement the smallest common type and merge to Object. - // In this case, we should bound its type to the type of the invoke. if (!return_replacement->GetReferenceTypeInfo().IsValid()) { // Make sure that we have a valid type for the return. We may get an invalid one when // we inline invokes with multiple branches and create a Phi for the result. @@ -523,19 +520,10 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, DCHECK(return_replacement->IsPhi()); size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); ReferenceTypeInfo::TypeHandle return_handle = - handles_->NewHandle(resolved_method->GetReturnType(true /* resolve */, pointer_size)); + handles_->NewHandle(resolved_method->GetReturnType(true /* resolve */, pointer_size)); return_replacement->SetReferenceTypeInfo(ReferenceTypeInfo::Create( return_handle, return_handle->CannotBeAssignedFromOtherTypes() /* is_exact */)); } - - // Check if the actual return type is a subtype of the declared invoke type. - // If so, run a limited type propagation to update the types in the original graph. - ReferenceTypeInfo return_rti = return_replacement->GetReferenceTypeInfo(); - ReferenceTypeInfo invoke_rti = invoke_instruction->GetReferenceTypeInfo(); - if (!return_rti.IsEqual(invoke_rti) && invoke_rti.IsSupertypeOf(return_rti)) { - ReferenceTypePropagation rtp_fixup(graph_, handles_); - rtp_fixup.Run(return_replacement); - } } return true; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index ec9b4d9797..d6f2543890 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -390,9 +390,19 @@ static void MaybeRunInliner(HGraph* graph, return; } - HInliner* inliner = new (graph->GetArena()) HInliner( + ArenaAllocator* arena = graph->GetArena(); + HInliner* inliner = new (arena) HInliner( graph, dex_compilation_unit, dex_compilation_unit, driver, handles, stats); - HOptimization* optimizations[] = { inliner }; + ReferenceTypePropagation* type_propagation = + new (arena) ReferenceTypePropagation(graph, handles, + "reference_type_propagation_after_inlining"); + + HOptimization* optimizations[] = { + inliner, + // Run another type propagation phase: inlining will open up more opportunities + // to remove checkcast/instanceof and null checks. + type_propagation, + }; RunOptimizations(optimizations, arraysize(optimizations), pass_observer); } diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index b0b7f3fe21..26a05da4cb 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -99,9 +99,17 @@ ReferenceTypePropagation::ReferenceTypePropagation(HGraph* graph, } } -void ReferenceTypePropagation::ValidateTypes() { - // TODO: move this to the graph checker. +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. + // We take advantage of this order in `VisitBasicBlock`. + for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { + VisitBasicBlock(it.Current()); + } + ProcessWorklist(); + if (kIsDebugBuild) { + // TODO: move this to the graph checker. ScopedObjectAccess soa(Thread::Current()); for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { HBasicBlock* block = it.Current(); @@ -127,28 +135,6 @@ void ReferenceTypePropagation::ValidateTypes() { } } -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. - // We take advantage of this order in `VisitBasicBlock`. - for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { - VisitBasicBlock(it.Current()); - } - - ProcessWorklist(); - ValidateTypes(); -} - -void ReferenceTypePropagation::Run(HInstruction* start_from) { - DCHECK(start_from != nullptr); - DCHECK_EQ(graph_, start_from->GetBlock()->GetGraph()); - DCHECK_EQ(Primitive::kPrimNot, start_from->GetType()); - - AddDependentInstructionsToWorklist(start_from); - ProcessWorklist(); - ValidateTypes(); -} - void ReferenceTypePropagation::VisitBasicBlock(HBasicBlock* block) { RTPVisitor visitor(graph_, handles_, diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 139f881668..5493601adc 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -36,9 +36,6 @@ class ReferenceTypePropagation : public HOptimization { const char* name = kReferenceTypePropagationPassName); void Run() OVERRIDE; - // Run the type propagation and propagate information only for the - // instructions dominated by `start_from`. - void Run(HInstruction* start_from); static constexpr const char* kReferenceTypePropagationPassName = "reference_type_propagation"; @@ -59,8 +56,6 @@ class ReferenceTypePropagation : public HOptimization { ReferenceTypeInfo MergeTypes(const ReferenceTypeInfo& a, const ReferenceTypeInfo& b) SHARED_REQUIRES(Locks::mutator_lock_); - void ValidateTypes(); - StackHandleScopeCollection* handles_; ArenaVector<HInstruction*> worklist_; |