diff options
author | 2017-08-09 13:20:34 -0700 | |
---|---|---|
committer | 2017-08-11 10:23:07 -0700 | |
commit | 1e065a54845da12541572f4f149e6ab0dcd20180 (patch) | |
tree | 061d28c8905c7bc8ac50c8c86f4073034afb5ba2 /compiler | |
parent | f573972a087b798f74bf5404e271355a2805e100 (diff) |
optimizing: Refactor statistics to use OptimizingCompilerStats helper
Remove all copies of 'MaybeRecordStat', replacing them with a single
OptimizingCompilerStats::MaybeRecordStat helper.
Change-Id: I83b96b41439dccece3eee2e159b18c95336ea933
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/optimizing/builder.cc | 12 | ||||
-rw-r--r-- | compiler/optimizing/builder.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/code_sinking.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/inliner.cc | 66 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 30 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 16 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/licm.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/load_store_elimination.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/optimization.cc | 7 | ||||
-rw-r--r-- | compiler/optimizing/optimization.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 66 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler_stats.h | 8 | ||||
-rw-r--r-- | compiler/optimizing/select_generator.cc | 2 |
18 files changed, 117 insertions, 121 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 2927e1f7c0..0d9d3d4c92 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -31,12 +31,6 @@ namespace art { -void HGraphBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) { - if (compilation_stats_ != nullptr) { - compilation_stats_->RecordStat(compilation_stat); - } -} - bool HGraphBuilder::SkipCompilation(size_t number_of_branches) { if (compiler_driver_ == nullptr) { // Note that the compiler driver is null when unit testing. @@ -53,7 +47,8 @@ bool HGraphBuilder::SkipCompilation(size_t number_of_branches) { VLOG(compiler) << "Skip compilation of huge method " << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) << ": " << code_item_.insns_size_in_code_units_ << " code units"; - MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kNotCompiledHugeMethod); return true; } @@ -63,7 +58,8 @@ bool HGraphBuilder::SkipCompilation(size_t number_of_branches) { VLOG(compiler) << "Skip compilation of large method with no branch " << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) << ": " << code_item_.insns_size_in_code_units_ << " code units"; - MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kNotCompiledLargeMethodNoBranches); return true; } diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 43429cf3d2..2c9a9efadf 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -109,7 +109,6 @@ class HGraphBuilder : public ValueObject { static constexpr const char* kBuilderPassName = "builder"; private: - void MaybeRecordStat(MethodCompilationStat compilation_stat); bool SkipCompilation(size_t number_of_branches); HGraph* const graph_; diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index d7d0ffffda..1e5f1ec00f 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -610,12 +610,6 @@ void CodeGenerator::AllocateLocations(HInstruction* instruction) { } } -void CodeGenerator::MaybeRecordStat(MethodCompilationStat compilation_stat, size_t count) const { - if (stats_ != nullptr) { - stats_->RecordStat(compilation_stat, count); - } -} - std::unique_ptr<CodeGenerator> CodeGenerator::Create(HGraph* graph, InstructionSet instruction_set, const InstructionSetFeatures& isa_features, @@ -1212,10 +1206,10 @@ LocationSummary* CodeGenerator::CreateThrowingSlowPathLocations(HInstruction* in void CodeGenerator::GenerateNullCheck(HNullCheck* instruction) { if (compiler_options_.GetImplicitNullChecks()) { - MaybeRecordStat(kImplicitNullCheckGenerated); + MaybeRecordStat(stats_, kImplicitNullCheckGenerated); GenerateImplicitNullCheck(instruction); } else { - MaybeRecordStat(kExplicitNullCheckGenerated); + MaybeRecordStat(stats_, kExplicitNullCheckGenerated); GenerateExplicitNullCheck(instruction); } } diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 51a0bae799..30c2b52242 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -254,8 +254,6 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { const CompilerOptions& GetCompilerOptions() const { return compiler_options_; } - void MaybeRecordStat(MethodCompilationStat compilation_stat, size_t count = 1) const; - // Saves the register in the stack. Returns the size taken on stack. virtual size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) = 0; // Restores the register from the stack. Returns the size taken on stack. diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc index e598e19b67..6c3a9fd6b5 100644 --- a/compiler/optimizing/code_sinking.cc +++ b/compiler/optimizing/code_sinking.cc @@ -414,7 +414,7 @@ void CodeSinking::SinkCodeToUncommonBranch(HBasicBlock* end_block) { if (!post_dominated.IsBitSet(position->GetBlock()->GetBlockId())) { continue; } - MaybeRecordStat(MethodCompilationStat::kInstructionSunk); + MaybeRecordStat(stats_, MethodCompilationStat::kInstructionSunk); instruction->MoveBefore(position, /* ensure_safety */ false); } } diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index c31c66a056..787296dc9d 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -359,7 +359,7 @@ void HDeadCodeElimination::RemoveDeadInstructions() { DCHECK(!inst->IsControlFlow()); if (inst->IsDeadAndRemovable()) { block->RemoveInstruction(inst); - MaybeRecordStat(MethodCompilationStat::kRemovedDeadInstruction); + MaybeRecordStat(stats_, MethodCompilationStat::kRemovedDeadInstruction); } } } diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 0141c26352..6567a3a445 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -75,7 +75,7 @@ static constexpr bool kUseAOTInlineCaches = true; #define LOG_TRY() LOG_INTERNAL("Try inlinining call: ") #define LOG_NOTE() LOG_INTERNAL("Note: ") #define LOG_SUCCESS() LOG_INTERNAL("Success: ") -#define LOG_FAIL(stat) MaybeRecordStat(stat); LOG_INTERNAL("Fail: ") +#define LOG_FAIL(stats_ptr, stat) MaybeRecordStat(stats_ptr, stat); LOG_INTERNAL("Fail: ") #define LOG_FAIL_NO_STAT() LOG_INTERNAL("Fail: ") std::string HInliner::DepthString(int line) const { @@ -440,9 +440,9 @@ bool HInliner::TryInline(HInvoke* invoke_instruction) { // Add dependency due to devirtulization. We've assumed resolved_method // has single implementation. outermost_graph_->AddCHASingleImplementationDependency(resolved_method); - MaybeRecordStat(kCHAInline); + MaybeRecordStat(stats_, kCHAInline); } else { - MaybeRecordStat(kInlinedInvokeVirtualOrInterface); + MaybeRecordStat(stats_, kInlinedInvokeVirtualOrInterface); } } return result; @@ -532,7 +532,7 @@ bool HInliner::TryInlineFromInlineCache(const DexFile& caller_dex_file, } case kInlineCacheMonomorphic: { - MaybeRecordStat(kMonomorphicCall); + MaybeRecordStat(stats_, kMonomorphicCall); if (UseOnlyPolymorphicInliningWithNoDeopt()) { return TryInlinePolymorphicCall(invoke_instruction, resolved_method, inline_cache); } else { @@ -541,7 +541,7 @@ bool HInliner::TryInlineFromInlineCache(const DexFile& caller_dex_file, } case kInlineCachePolymorphic: { - MaybeRecordStat(kPolymorphicCall); + MaybeRecordStat(stats_, kPolymorphicCall); return TryInlinePolymorphicCall(invoke_instruction, resolved_method, inline_cache); } @@ -550,7 +550,7 @@ bool HInliner::TryInlineFromInlineCache(const DexFile& caller_dex_file, << "Interface or virtual call to " << caller_dex_file.PrettyMethod(invoke_instruction->GetDexMethodIndex()) << " is megamorphic and not inlined"; - MaybeRecordStat(kMegamorphicCall); + MaybeRecordStat(stats_, kMegamorphicCall); return false; } @@ -754,7 +754,7 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, dex::TypeIndex class_index = FindClassIndexIn( GetMonomorphicType(classes), caller_compilation_unit_); if (!class_index.IsValid()) { - LOG_FAIL(kNotInlinedDexCache) + LOG_FAIL(stats_, kNotInlinedDexCache) << "Call to " << ArtMethod::PrettyMethod(resolved_method) << " from inline cache is not inlined because its class is not" << " accessible to the caller"; @@ -803,7 +803,7 @@ bool HInliner::TryInlineMonomorphicCall(HInvoke* invoke_instruction, /* is_first_run */ false); rtp_fixup.Run(); - MaybeRecordStat(kInlinedMonomorphicCall); + MaybeRecordStat(stats_, kInlinedMonomorphicCall); return true; } @@ -993,7 +993,7 @@ bool HInliner::TryInlinePolymorphicCall(HInvoke* invoke_instruction, return false; } - MaybeRecordStat(kInlinedPolymorphicCall); + MaybeRecordStat(stats_, kInlinedPolymorphicCall); // Run type propagation to get the guards typed. ReferenceTypePropagation rtp_fixup(graph_, @@ -1199,7 +1199,7 @@ bool HInliner::TryInlinePolymorphicCallToSameTarget( /* is_first_run */ false); rtp_fixup.Run(); - MaybeRecordStat(kInlinedPolymorphicCall); + MaybeRecordStat(stats_, kInlinedPolymorphicCall); LOG_SUCCESS() << "Inlined same polymorphic target " << actual_method->PrettyMethod(); return true; @@ -1300,14 +1300,14 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, ReferenceTypeInfo receiver_type, HInstruction** return_replacement) { if (method->IsProxyMethod()) { - LOG_FAIL(kNotInlinedProxy) + LOG_FAIL(stats_, kNotInlinedProxy) << "Method " << method->PrettyMethod() << " is not inlined because of unimplemented inline support for proxy methods."; return false; } if (CountRecursiveCallsOf(method) > kMaximumNumberOfRecursiveCalls) { - LOG_FAIL(kNotInlinedRecursiveBudget) + LOG_FAIL(stats_, kNotInlinedRecursiveBudget) << "Method " << method->PrettyMethod() << " is not inlined because it has reached its recursive call budget."; @@ -1321,10 +1321,10 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, if (TryPatternSubstitution(invoke_instruction, method, return_replacement)) { LOG_SUCCESS() << "Successfully replaced pattern of invoke " << method->PrettyMethod(); - MaybeRecordStat(kReplacedInvokeWithSimplePattern); + MaybeRecordStat(stats_, kReplacedInvokeWithSimplePattern); return true; } - LOG_FAIL(kNotInlinedWont) + LOG_FAIL(stats_, kNotInlinedWont) << "Won't inline " << method->PrettyMethod() << " in " << outer_compilation_unit_.GetDexFile()->GetLocation() << " (" << caller_compilation_unit_.GetDexFile()->GetLocation() << ") from " @@ -1344,7 +1344,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, size_t inline_max_code_units = compiler_driver_->GetCompilerOptions().GetInlineMaxCodeUnits(); if (code_item->insns_size_in_code_units_ > inline_max_code_units) { - LOG_FAIL(kNotInlinedCodeItem) + LOG_FAIL(stats_, kNotInlinedCodeItem) << "Method " << method->PrettyMethod() << " is not inlined because its code item is too big: " << code_item->insns_size_in_code_units_ @@ -1354,13 +1354,13 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, } if (code_item->tries_size_ != 0) { - LOG_FAIL(kNotInlinedTryCatch) + LOG_FAIL(stats_, kNotInlinedTryCatch) << "Method " << method->PrettyMethod() << " is not inlined because of try block"; return false; } if (!method->IsCompilable()) { - LOG_FAIL(kNotInlinedNotVerified) + LOG_FAIL(stats_, kNotInlinedNotVerified) << "Method " << method->PrettyMethod() << " has soft failures un-handled by the compiler, so it cannot be inlined"; } @@ -1370,7 +1370,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, if (Runtime::Current()->UseJitCompilation() || !compiler_driver_->IsMethodVerifiedWithoutFailures( method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) { - LOG_FAIL(kNotInlinedNotVerified) + LOG_FAIL(stats_, kNotInlinedNotVerified) << "Method " << method->PrettyMethod() << " couldn't be verified, so it cannot be inlined"; return false; @@ -1381,7 +1381,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, invoke_instruction->AsInvokeStaticOrDirect()->IsStaticWithImplicitClinitCheck()) { // Case of a static method that cannot be inlined because it implicitly // requires an initialization check of its declaring class. - LOG_FAIL(kNotInlinedDexCache) << "Method " << method->PrettyMethod() + LOG_FAIL(stats_, kNotInlinedDexCache) << "Method " << method->PrettyMethod() << " is not inlined because it is static and requires a clinit" << " check that cannot be emitted due to Dex cache limitations"; return false; @@ -1393,7 +1393,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, } LOG_SUCCESS() << method->PrettyMethod(); - MaybeRecordStat(kInlinedInvoke); + MaybeRecordStat(stats_, kInlinedInvoke); return true; } @@ -1677,7 +1677,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, handles_); if (builder.BuildGraph() != kAnalysisSuccess) { - LOG_FAIL(kNotInlinedCannotBuild) + LOG_FAIL(stats_, kNotInlinedCannotBuild) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be built, so cannot be inlined"; return false; @@ -1685,7 +1685,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, if (!RegisterAllocator::CanAllocateRegistersFor(*callee_graph, compiler_driver_->GetInstructionSet())) { - LOG_FAIL(kNotInlinedRegisterAllocator) + LOG_FAIL(stats_, kNotInlinedRegisterAllocator) << "Method " << callee_dex_file.PrettyMethod(method_index) << " cannot be inlined because of the register allocator"; return false; @@ -1738,7 +1738,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, HBasicBlock* exit_block = callee_graph->GetExitBlock(); if (exit_block == nullptr) { - LOG_FAIL(kNotInlinedInfiniteLoop) + LOG_FAIL(stats_, kNotInlinedInfiniteLoop) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because it has an infinite loop"; return false; @@ -1749,14 +1749,14 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, if (predecessor->GetLastInstruction()->IsThrow()) { if (invoke_instruction->GetBlock()->IsTryBlock()) { // TODO(ngeoffray): Support adding HTryBoundary in Hgraph::InlineInto. - LOG_FAIL(kNotInlinedTryCatch) + LOG_FAIL(stats_, kNotInlinedTryCatch) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because one branch always throws and" << " caller is in a try/catch block"; return false; } else if (graph_->GetExitBlock() == nullptr) { // TODO(ngeoffray): Support adding HExit in the caller graph. - LOG_FAIL(kNotInlinedInfiniteLoop) + LOG_FAIL(stats_, kNotInlinedInfiniteLoop) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because one branch always throws and" << " caller does not have an exit block"; @@ -1775,7 +1775,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, } if (!has_one_return) { - LOG_FAIL(kNotInlinedAlwaysThrows) + LOG_FAIL(stats_, kNotInlinedAlwaysThrows) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because it always throws"; return false; @@ -1788,7 +1788,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, if (block->GetLoopInformation()->IsIrreducible()) { // Don't inline methods with irreducible loops, they could prevent some // optimizations to run. - LOG_FAIL(kNotInlinedIrreducibleLoop) + LOG_FAIL(stats_, kNotInlinedIrreducibleLoop) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because it contains an irreducible loop"; return false; @@ -1797,7 +1797,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, // Don't inline methods with loops without exit, since they cause the // loop information to be computed incorrectly when updating after // inlining. - LOG_FAIL(kNotInlinedLoopWithoutExit) + LOG_FAIL(stats_, kNotInlinedLoopWithoutExit) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because it contains a loop with no exit"; return false; @@ -1808,7 +1808,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, !instr_it.Done(); instr_it.Advance()) { if (++number_of_instructions >= inlining_budget_) { - LOG_FAIL(kNotInlinedInstructionBudget) + LOG_FAIL(stats_, kNotInlinedInstructionBudget) << "Method " << callee_dex_file.PrettyMethod(method_index) << " is not inlined because the outer method has reached" << " its instruction budget limit."; @@ -1817,7 +1817,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, HInstruction* current = instr_it.Current(); if (current->NeedsEnvironment() && (total_number_of_dex_registers_ >= kMaximumNumberOfCumulatedDexRegisters)) { - LOG_FAIL(kNotInlinedEnvironmentBudget) + LOG_FAIL(stats_, kNotInlinedEnvironmentBudget) << "Method " << callee_dex_file.PrettyMethod(method_index) << " is not inlined because its caller has reached" << " its environment budget limit."; @@ -1827,7 +1827,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, if (current->NeedsEnvironment() && !CanEncodeInlinedMethodInStackMap(*caller_compilation_unit_.GetDexFile(), resolved_method)) { - LOG_FAIL(kNotInlinedStackMaps) + LOG_FAIL(stats_, kNotInlinedStackMaps) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because " << current->DebugName() << " needs an environment, is in a different dex file" @@ -1836,7 +1836,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, } if (!same_dex_file && current->NeedsDexCacheOfDeclaringClass()) { - LOG_FAIL(kNotInlinedDexCache) + LOG_FAIL(stats_, kNotInlinedDexCache) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because " << current->DebugName() << " it is in a different dex file and requires access to the dex cache"; @@ -1848,7 +1848,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, current->IsUnresolvedStaticFieldSet() || current->IsUnresolvedInstanceFieldSet()) { // Entrypoint for unresolved fields does not handle inlined frames. - LOG_FAIL(kNotInlinedUnresolvedEntrypoint) + LOG_FAIL(stats_, kNotInlinedUnresolvedEntrypoint) << "Method " << callee_dex_file.PrettyMethod(method_index) << " could not be inlined because it is using an unresolved" << " entrypoint"; diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 143c77f334..b66883f6ad 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -28,12 +28,6 @@ namespace art { -void HInstructionBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) { - if (compilation_stats_ != nullptr) { - compilation_stats_->RecordStat(compilation_stat); - } -} - HBasicBlock* HInstructionBuilder::FindBlockStartingAt(uint32_t dex_pc) const { return block_builder_->GetBlockAt(dex_pc); } @@ -816,7 +810,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, ArtMethod* resolved_method = ResolveMethod(method_idx, invoke_type); if (UNLIKELY(resolved_method == nullptr)) { - MaybeRecordStat(MethodCompilationStat::kUnresolvedMethod); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kUnresolvedMethod); HInvoke* invoke = new (arena_) HInvokeUnresolved(arena_, number_of_arguments, return_type, @@ -1122,7 +1117,8 @@ bool HInstructionBuilder::SetupInvokeArguments(HInvoke* invoke, VLOG(compiler) << "Did not compile " << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) << " because of non-sequential dex register pair in wide argument"; - MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kNotCompiledMalformedOpcode); return false; } HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type); @@ -1136,7 +1132,8 @@ bool HInstructionBuilder::SetupInvokeArguments(HInvoke* invoke, VLOG(compiler) << "Did not compile " << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) << " because of wrong number of arguments in invoke instruction"; - MaybeRecordStat(MethodCompilationStat::kNotCompiledMalformedOpcode); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kNotCompiledMalformedOpcode); return false; } @@ -1286,7 +1283,8 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio HInstruction* value = LoadLocal(source_or_dest_reg, field_type); HInstruction* field_set = nullptr; if (resolved_field == nullptr) { - MaybeRecordStat(MethodCompilationStat::kUnresolvedField); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kUnresolvedField); field_set = new (arena_) HUnresolvedInstanceFieldSet(object, value, field_type, @@ -1309,7 +1307,8 @@ bool HInstructionBuilder::BuildInstanceFieldAccess(const Instruction& instructio } else { HInstruction* field_get = nullptr; if (resolved_field == nullptr) { - MaybeRecordStat(MethodCompilationStat::kUnresolvedField); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kUnresolvedField); field_get = new (arena_) HUnresolvedInstanceFieldGet(object, field_type, field_index, @@ -1444,7 +1443,8 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, ArtField* resolved_field = ResolveField(field_index, /* is_static */ true, is_put); if (resolved_field == nullptr) { - MaybeRecordStat(MethodCompilationStat::kUnresolvedField); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kUnresolvedField); Primitive::Type field_type = GetFieldAccessType(*dex_file_, field_index); BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type); return true; @@ -1462,7 +1462,8 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, if (constant == nullptr) { // The class cannot be referenced from this compiled code. Generate // an unresolved access. - MaybeRecordStat(MethodCompilationStat::kUnresolvedFieldNotAFastAccess); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kUnresolvedFieldNotAFastAccess); BuildUnresolvedStaticFieldAccess(instruction, dex_pc, is_put, field_type); return true; } @@ -2823,7 +2824,8 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex()) << " because of unhandled instruction " << instruction.Name(); - MaybeRecordStat(MethodCompilationStat::kNotCompiledUnhandledInstruction); + MaybeRecordStat(compilation_stats_, + MethodCompilationStat::kNotCompiledUnhandledInstruction); return false; } return true; diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index 2a9b9f513d..b7fa39404b 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -78,8 +78,6 @@ class HInstructionBuilder : public ValueObject { bool Build(); private: - void MaybeRecordStat(MethodCompilationStat compilation_stat); - void InitializeBlockLocals(); void PropagateLocalsToCatchBlocks(); void SetLoopHeaderPhiInputs(); diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 02cfbbcfb3..5c79511bab 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -43,13 +43,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor { void RecordSimplification() { simplification_occurred_ = true; simplifications_at_current_position_++; - MaybeRecordStat(kInstructionSimplifications); - } - - void MaybeRecordStat(MethodCompilationStat stat) { - if (stats_ != nullptr) { - stats_->RecordStat(stat); - } + MaybeRecordStat(stats_, kInstructionSimplifications); } bool ReplaceRotateWithRor(HBinaryOperation* op, HUShr* ushr, HShl* shl); @@ -517,7 +511,7 @@ void InstructionSimplifierVisitor::VisitCheckCast(HCheckCast* check_cast) { if (object->IsNullConstant()) { check_cast->GetBlock()->RemoveInstruction(check_cast); - MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast); + MaybeRecordStat(stats_, MethodCompilationStat::kRemovedCheckedCast); return; } @@ -527,7 +521,7 @@ void InstructionSimplifierVisitor::VisitCheckCast(HCheckCast* check_cast) { if (TypeCheckHasKnownOutcome(load_class, object, &outcome)) { if (outcome) { check_cast->GetBlock()->RemoveInstruction(check_cast); - MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast); + MaybeRecordStat(stats_, MethodCompilationStat::kRemovedCheckedCast); if (!load_class->HasUses()) { // We cannot rely on DCE to remove the class because the `HLoadClass` thinks it can throw. // However, here we know that it cannot because the checkcast was successfull, hence @@ -557,7 +551,7 @@ void InstructionSimplifierVisitor::VisitInstanceOf(HInstanceOf* instruction) { HGraph* graph = GetGraph(); if (object->IsNullConstant()) { - MaybeRecordStat(kRemovedInstanceOf); + MaybeRecordStat(stats_, kRemovedInstanceOf); instruction->ReplaceWith(graph->GetIntConstant(0)); instruction->GetBlock()->RemoveInstruction(instruction); RecordSimplification(); @@ -568,7 +562,7 @@ void InstructionSimplifierVisitor::VisitInstanceOf(HInstanceOf* instruction) { // the return value check with the `outcome` check, b/27651442 . bool outcome = false; if (TypeCheckHasKnownOutcome(load_class, object, &outcome)) { - MaybeRecordStat(kRemovedInstanceOf); + MaybeRecordStat(stats_, kRemovedInstanceOf); if (outcome && can_be_null) { // Type test will succeed, we just need a null test. HNotEqual* test = new (graph->GetArena()) HNotEqual(graph->GetNullConstant(), object); diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 7bdeef527e..11725f43c3 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -154,7 +154,8 @@ void IntrinsicsRecognizer::Run() { NeedsEnvironmentOrCache(intrinsic), GetSideEffects(intrinsic), GetExceptions(intrinsic)); - MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized); + MaybeRecordStat(stats_, + MethodCompilationStat::kIntrinsicRecognized); } } } diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc index f0086fb202..10524b0ae6 100644 --- a/compiler/optimizing/licm.cc +++ b/compiler/optimizing/licm.cc @@ -141,7 +141,7 @@ void LICM::Run() { DCHECK(!instruction->HasEnvironment()); } instruction->MoveBefore(pre_header->GetLastInstruction()); - MaybeRecordStat(MethodCompilationStat::kLoopInvariantMoved); + MaybeRecordStat(stats_, MethodCompilationStat::kLoopInvariantMoved); } else if (instruction->CanThrow() || instruction->DoesAnyWrite()) { // If `instruction` can do something visible (throw or write), // we cannot move further instructions that can throw. diff --git a/compiler/optimizing/load_store_elimination.h b/compiler/optimizing/load_store_elimination.h index efe71c733a..20a8a769c0 100644 --- a/compiler/optimizing/load_store_elimination.h +++ b/compiler/optimizing/load_store_elimination.h @@ -28,8 +28,9 @@ class LoadStoreElimination : public HOptimization { public: LoadStoreElimination(HGraph* graph, const SideEffectsAnalysis& side_effects, - const LoadStoreAnalysis& lsa) - : HOptimization(graph, kLoadStoreEliminationPassName), + const LoadStoreAnalysis& lsa, + OptimizingCompilerStats* stats) + : HOptimization(graph, kLoadStoreEliminationPassName, stats), side_effects_(side_effects), lsa_(lsa) {} diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index 3d769491a5..1e68ca2802 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -17,11 +17,4 @@ #include "optimization.h" namespace art { - -void HOptimization::MaybeRecordStat(MethodCompilationStat compilation_stat, size_t count) const { - if (stats_ != nullptr) { - stats_->RecordStat(compilation_stat, count); - } -} - } // namespace art diff --git a/compiler/optimizing/optimization.h b/compiler/optimizing/optimization.h index 0819fb01ac..ce41a2e512 100644 --- a/compiler/optimizing/optimization.h +++ b/compiler/optimizing/optimization.h @@ -47,8 +47,6 @@ class HOptimization : public ArenaObject<kArenaAllocOptimization> { virtual void Run() = 0; protected: - void MaybeRecordStat(MethodCompilationStat compilation_stat, size_t count = 1) const; - HGraph* const graph_; // Used to record stats about the optimization. OptimizingCompilerStats* const stats_; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 76a243f793..70bbc382b4 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -329,12 +329,6 @@ class OptimizingCompiler FINAL : public Compiler { void UnInit() const OVERRIDE; - void MaybeRecordStat(MethodCompilationStat compilation_stat) const { - if (compilation_stats_.get() != nullptr) { - compilation_stats_->RecordStat(compilation_stat); - } - } - bool JitCompile(Thread* self, jit::JitCodeCache* code_cache, ArtMethod* method, @@ -512,7 +506,8 @@ static HOptimization* BuildOptimization( } else if (opt_name == LoadStoreElimination::kLoadStoreEliminationPassName) { CHECK(most_recent_side_effects != nullptr); CHECK(most_recent_lsa != nullptr); - return new (arena) LoadStoreElimination(graph, *most_recent_side_effects, *most_recent_lsa); + return + new (arena) LoadStoreElimination(graph, *most_recent_side_effects, *most_recent_lsa, stats); } else if (opt_name == SideEffectsAnalysis::kSideEffectsAnalysisPassName) { return new (arena) SideEffectsAnalysis(graph); } else if (opt_name == HLoopOptimization::kLoopOptimizationPassName) { @@ -778,7 +773,7 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, BoundsCheckElimination* bce = new (arena) BoundsCheckElimination(graph, *side_effects1, induction); HLoopOptimization* loop = new (arena) HLoopOptimization(graph, driver, induction); LoadStoreAnalysis* lsa = new (arena) LoadStoreAnalysis(graph); - LoadStoreElimination* lse = new (arena) LoadStoreElimination(graph, *side_effects2, *lsa); + LoadStoreElimination* lse = new (arena) LoadStoreElimination(graph, *side_effects2, *lsa, stats); HSharpening* sharpening = new (arena) HSharpening( graph, codegen, dex_compilation_unit, driver, handles); InstructionSimplifier* simplify2 = new (arena) InstructionSimplifier( @@ -894,7 +889,8 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, ArtMethod* method, bool osr, VariableSizedHandleScope* handles) const { - MaybeRecordStat(MethodCompilationStat::kAttemptCompilation); + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kAttemptCompilation); CompilerDriver* compiler_driver = GetCompilerDriver(); InstructionSet instruction_set = compiler_driver->GetInstructionSet(); @@ -904,12 +900,14 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, // Do not attempt to compile on architectures we do not support. if (!IsInstructionSetSupported(instruction_set)) { - MaybeRecordStat(MethodCompilationStat::kNotCompiledUnsupportedIsa); + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledUnsupportedIsa); return nullptr; } if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) { - MaybeRecordStat(MethodCompilationStat::kNotCompiledPathological); + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledPathological); return nullptr; } @@ -919,7 +917,8 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions(); if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace) && (code_item->insns_size_in_code_units_ > kSpaceFilterOptimizingThreshold)) { - MaybeRecordStat(MethodCompilationStat::kNotCompiledSpaceFilter); + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledSpaceFilter); return nullptr; } @@ -966,7 +965,8 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, compiler_driver->GetCompilerOptions(), compilation_stats_.get())); if (codegen.get() == nullptr) { - MaybeRecordStat(MethodCompilationStat::kNotCompiledNoCodegen); + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledNoCodegen); return nullptr; } codegen->GetAssembler()->cfi().SetEnabled( @@ -995,17 +995,25 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, GraphAnalysisResult result = builder.BuildGraph(); if (result != kAnalysisSuccess) { switch (result) { - case kAnalysisSkipped: - MaybeRecordStat(MethodCompilationStat::kNotCompiledSkipped); + case kAnalysisSkipped: { + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledSkipped); + } break; - case kAnalysisInvalidBytecode: - MaybeRecordStat(MethodCompilationStat::kNotCompiledInvalidBytecode); + case kAnalysisInvalidBytecode: { + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledInvalidBytecode); + } break; - case kAnalysisFailThrowCatchLoop: - MaybeRecordStat(MethodCompilationStat::kNotCompiledThrowCatchLoop); + case kAnalysisFailThrowCatchLoop: { + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledThrowCatchLoop); + } break; - case kAnalysisFailAmbiguousArrayOp: - MaybeRecordStat(MethodCompilationStat::kNotCompiledAmbiguousArrayOp); + case kAnalysisFailAmbiguousArrayOp: { + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledAmbiguousArrayOp); + } break; case kAnalysisSuccess: UNREACHABLE(); @@ -1024,7 +1032,10 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, RegisterAllocator::Strategy regalloc_strategy = compiler_options.GetRegisterAllocationStrategy(); - AllocateRegisters(graph, codegen.get(), &pass_observer, regalloc_strategy); + AllocateRegisters(graph, + codegen.get(), + &pass_observer, + regalloc_strategy); codegen->Compile(code_allocator); pass_observer.DumpDisassembly(); @@ -1072,7 +1083,8 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, &handles)); } if (codegen.get() != nullptr) { - MaybeRecordStat(MethodCompilationStat::kCompiled); + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kCompiled); method = Emit(&arena, &code_allocator, codegen.get(), compiler_driver, code_item); if (kArenaAllocatorCountAllocations) { @@ -1083,11 +1095,13 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, } } } else { + MethodCompilationStat method_stat; if (compiler_driver->GetCompilerOptions().VerifyAtRuntime()) { - MaybeRecordStat(MethodCompilationStat::kNotCompiledVerifyAtRuntime); + method_stat = MethodCompilationStat::kNotCompiledVerifyAtRuntime; } else { - MaybeRecordStat(MethodCompilationStat::kNotCompiledVerificationError); + method_stat = MethodCompilationStat::kNotCompiledVerificationError; } + MaybeRecordStat(compilation_stats_.get(), method_stat); } if (kIsDebugBuild && @@ -1221,7 +1235,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, if (stack_map_data == nullptr || roots_data == nullptr) { return false; } - MaybeRecordStat(MethodCompilationStat::kCompiled); + MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kCompiled); codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size), MemoryRegion(method_info_data, method_info_size), *code_item); diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h index a211c5472a..098d23dac1 100644 --- a/compiler/optimizing/optimizing_compiler_stats.h +++ b/compiler/optimizing/optimizing_compiler_stats.h @@ -216,6 +216,14 @@ class OptimizingCompilerStats { DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats); }; +inline void MaybeRecordStat(OptimizingCompilerStats* compiler_stats, + MethodCompilationStat stat, + uint32_t count = 1) { + if (compiler_stats != nullptr) { + compiler_stats->RecordStat(stat, count); + } +} + } // namespace art #endif // ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_ diff --git a/compiler/optimizing/select_generator.cc b/compiler/optimizing/select_generator.cc index 46d0d0eb65..cb7ade915f 100644 --- a/compiler/optimizing/select_generator.cc +++ b/compiler/optimizing/select_generator.cc @@ -140,7 +140,7 @@ void HSelectGenerator::Run() { block->MergeWith(merge_block); } - MaybeRecordStat(MethodCompilationStat::kSelectGenerated); + MaybeRecordStat(stats_, MethodCompilationStat::kSelectGenerated); // No need to update dominance information, as we are simplifying // a simple diamond shape, where the join block is merged with the |