From: Calin Juravle Date: Fri, 12 Jun 2015 12:13:43 +0000 (+0000) Subject: Revert "Bring ReferenceTypePropagation to HInvoke return types" X-Git-Tag: android-x86-7.1-r1~889^2~1008^2~2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=958857d0f9686770a3b1117166d5fa700b39704a;p=android-x86%2Fart.git Revert "Bring ReferenceTypePropagation to HInvoke return types" We exceed stack frame size with Clang in art::OptimizingCompiler::CompileOptimized This reverts commit ddedddcedaae78fc6aa29940fdb1fbe40bb05774. Change-Id: I6f992dda228acb9cae2087d1e6c78f2afdf30050 --- diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 1f9287cbf..e4680ff2f 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -723,16 +723,10 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, } } - invoke = new (arena_) HInvokeStaticOrDirect(arena_, - number_of_arguments, - return_type, - dex_pc, - target_method.dex_method_index, - is_recursive, - string_init_offset, - invoke_type, - optimized_invoke_type, - clinit_check_requirement); + invoke = new (arena_) HInvokeStaticOrDirect( + arena_, number_of_arguments, return_type, dex_pc, target_method.dex_method_index, + is_recursive, string_init_offset, invoke_type, optimized_invoke_type, + clinit_check_requirement); } size_t start_index = 0; diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 92ebf060e..5aeaad23c 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -256,7 +256,7 @@ bool HInliner::TryInline(HInvoke* invoke_instruction, uint32_t method_index) con return false; } - if (!TryBuildAndInline(resolved_method, invoke_instruction, same_dex_file)) { + if (!TryBuildAndInline(resolved_method, invoke_instruction, method_index, same_dex_file)) { return false; } @@ -267,11 +267,11 @@ bool HInliner::TryInline(HInvoke* invoke_instruction, uint32_t method_index) con bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, HInvoke* invoke_instruction, + uint32_t method_index, bool same_dex_file) const { ScopedObjectAccess soa(Thread::Current()); const DexFile::CodeItem* code_item = resolved_method->GetCodeItem(); - const DexFile& callee_dex_file = *resolved_method->GetDexFile(); - uint32_t method_index = resolved_method->GetDexMethodIndex(); + const DexFile& caller_dex_file = *caller_compilation_unit_.GetDexFile(); DexCompilationUnit dex_compilation_unit( nullptr, @@ -311,7 +311,7 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, } HGraph* callee_graph = new (graph_->GetArena()) HGraph( graph_->GetArena(), - callee_dex_file, + caller_dex_file, method_index, requires_ctor_barrier, compiler_driver_->GetInstructionSet(), @@ -328,7 +328,7 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, &inline_stats); if (!builder.BuildGraph(*code_item)) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be built, so cannot be inlined"; // There could be multiple reasons why the graph could not be built, including // unaccessible methods/fields due to using a different dex cache. We do not mark @@ -338,14 +338,14 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, if (!RegisterAllocator::CanAllocateRegistersFor(*callee_graph, compiler_driver_->GetInstructionSet())) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " cannot be inlined because of the register allocator"; resolved_method->SetShouldNotInline(); return false; } if (!callee_graph->TryBuildingSsa()) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be transformed to SSA"; resolved_method->SetShouldNotInline(); return false; @@ -385,7 +385,7 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, // a throw predecessor. HBasicBlock* exit_block = callee_graph->GetExitBlock(); if (exit_block == nullptr) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be inlined because it has an infinite loop"; resolved_method->SetShouldNotInline(); return false; @@ -399,7 +399,7 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, } } if (has_throw_predecessor) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be inlined because one branch always throws"; resolved_method->SetShouldNotInline(); return false; @@ -410,7 +410,7 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, for (; !it.Done(); it.Advance()) { HBasicBlock* block = it.Current(); if (block->IsLoopHeader()) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be inlined because it contains a loop"; resolved_method->SetShouldNotInline(); return false; @@ -424,21 +424,21 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, if (current->IsInvokeInterface()) { // Disable inlining of interface calls. The cost in case of entering the // resolution conflict is currently too high. - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be inlined because it has an interface call."; resolved_method->SetShouldNotInline(); return false; } if (!same_dex_file && current->NeedsEnvironment()) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be inlined because " << current->DebugName() << " needs an environment and is in a different dex file"; return false; } if (!same_dex_file && current->NeedsDexCache()) { - VLOG(compiler) << "Method " << PrettyMethod(method_index, callee_dex_file) + VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " could not be inlined because " << current->DebugName() << " it is in a different dex file and requires access to the dex cache"; // Do not flag the method as not-inlineable. A caller within the same diff --git a/compiler/optimizing/inliner.h b/compiler/optimizing/inliner.h index 24044b73a..7465278f8 100644 --- a/compiler/optimizing/inliner.h +++ b/compiler/optimizing/inliner.h @@ -52,6 +52,7 @@ class HInliner : public HOptimization { bool TryInline(HInvoke* invoke_instruction, uint32_t method_index) const; bool TryBuildAndInline(ArtMethod* resolved_method, HInvoke* invoke_instruction, + uint32_t method_index, bool same_dex_file) const; const DexCompilationUnit& outer_compilation_unit_; diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index cd907361d..3d81c20a1 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -27,7 +27,7 @@ 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(*GetGraph()); !it.Done(); it.Advance()) { + for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { VisitBasicBlock(it.Current()); } ProcessWorklist(); @@ -35,12 +35,23 @@ void ReferenceTypePropagation::Run() { void ReferenceTypePropagation::VisitBasicBlock(HBasicBlock* block) { // TODO: handle other instructions that give type info - // (array accesses) + // (Call/array accesses) // Initialize exact types first for faster convergence. for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { HInstruction* instr = it.Current(); - instr->Accept(this); + // TODO: Make ReferenceTypePropagation a visitor or create a new one. + if (instr->IsNewInstance()) { + VisitNewInstance(instr->AsNewInstance()); + } else if (instr->IsLoadClass()) { + VisitLoadClass(instr->AsLoadClass()); + } else if (instr->IsNewArray()) { + VisitNewArray(instr->AsNewArray()); + } else if (instr->IsInstanceFieldGet()) { + VisitInstanceFieldGet(instr->AsInstanceFieldGet()); + } else if (instr->IsStaticFieldGet()) { + VisitStaticFieldGet(instr->AsStaticFieldGet()); + } } // Handle Phis. @@ -85,7 +96,7 @@ void ReferenceTypePropagation::BoundTypeForIfNotNull(HBasicBlock* block) { HInstruction* user = it.Current()->GetUser(); if (notNullBlock->Dominates(user->GetBlock())) { if (bound_type == nullptr) { - bound_type = new (GetGraph()->GetArena()) HBoundType(obj, ReferenceTypeInfo::CreateTop(false)); + bound_type = new (graph_->GetArena()) HBoundType(obj, ReferenceTypeInfo::CreateTop(false)); notNullBlock->InsertInstructionBefore(bound_type, notNullBlock->GetFirstInstruction()); } user->ReplaceInput(bound_type, it.Current()->GetIndex()); @@ -134,7 +145,7 @@ void ReferenceTypePropagation::BoundTypeForIfInstanceOf(HBasicBlock* block) { ReferenceTypeInfo obj_rti = obj->GetReferenceTypeInfo(); ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI(); - bound_type = new (GetGraph()->GetArena()) HBoundType(obj, class_rti); + bound_type = new (graph_->GetArena()) HBoundType(obj, class_rti); // Narrow the type as much as possible. { @@ -288,21 +299,6 @@ bool ReferenceTypePropagation::UpdateReferenceTypeInfo(HInstruction* instr) { return !previous_rti.IsEqual(instr->GetReferenceTypeInfo()); } -void ReferenceTypePropagation::VisitInvoke(HInvoke* instr) { - if (instr->GetType() != Primitive::kPrimNot) { - return; - } - - ScopedObjectAccess soa(Thread::Current()); - ClassLinker* cl = Runtime::Current()->GetClassLinker(); - mirror::DexCache* dex_cache = cl->FindDexCache(instr->GetDexFile()); - ArtMethod* method = dex_cache->GetResolvedMethod( - instr->GetDexMethodIndex(), cl->GetImagePointerSize()); - DCHECK(method != nullptr); - mirror::Class* klass = method->GetReturnType(false); - SetClassAsTypeInfo(instr, klass, /* is_exact */ false); -} - void ReferenceTypePropagation::UpdateBoundType(HBoundType* instr) { ReferenceTypeInfo new_rti = instr->InputAt(0)->GetReferenceTypeInfo(); // Be sure that we don't go over the bounded type. diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 5902770d3..0a1d4c496 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -28,11 +28,10 @@ namespace art { /** * Propagates reference types to instructions. */ -class ReferenceTypePropagation : public HOptimization, public HGraphDelegateVisitor { +class ReferenceTypePropagation : public HOptimization { public: ReferenceTypePropagation(HGraph* graph, StackHandleScopeCollection* handles) : HOptimization(graph, true, kReferenceTypePropagationPassName), - HGraphDelegateVisitor(graph), handles_(handles), worklist_(graph->GetArena(), kDefaultWorklistSize) {} @@ -60,7 +59,6 @@ class ReferenceTypePropagation : public HOptimization, public HGraphDelegateVisi bool is_exact); void VisitInstanceFieldGet(HInstanceFieldGet* instr); void VisitStaticFieldGet(HStaticFieldGet* instr); - void VisitInvoke(HInvoke* instr); void ProcessWorklist(); void AddToWorklist(HInstruction* instr); diff --git a/test/450-checker-types/src/Main.java b/test/450-checker-types/src/Main.java index 618a50bfd..4056275d3 100644 --- a/test/450-checker-types/src/Main.java +++ b/test/450-checker-types/src/Main.java @@ -364,18 +364,6 @@ public class Main { ((SubclassA)b).$noinline$g(); } - public SubclassA getSubclass() { throw new RuntimeException(); } - - /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier_after_types (before) - /// CHECK: CheckCast - - /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier_after_types (after) - /// CHECK-NOT: CheckCast - public void testInvokeSimpleRemove() { - Super b = getSubclass(); - ((SubclassA)b).$noinline$g(); - } - public static void main(String[] args) { } }