optimizing: Refactor statistics to use OptimizingCompilerStats helper
Remove all copies of 'MaybeRecordStat', replacing them with a single
OptimizingCompilerStats::MaybeRecordStat helper.
Change-Id: I83b96b41439dccece3eee2e159b18c95336ea933
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 2927e1f..0d9d3d4 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 @@
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 @@
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 43429cf..2c9a9ef 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -109,7 +109,6 @@
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 d7d0fff..1e5f1ec 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -610,12 +610,6 @@
}
}
-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 @@
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 51a0bae..30c2b52 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -254,8 +254,6 @@
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 e598e19..6c3a9fd 100644
--- a/compiler/optimizing/code_sinking.cc
+++ b/compiler/optimizing/code_sinking.cc
@@ -414,7 +414,7 @@
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 c31c66a..787296d 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -359,7 +359,7 @@
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 0141c26..6567a3a 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -75,7 +75,7 @@
#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 @@
// 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 @@
}
case kInlineCacheMonomorphic: {
- MaybeRecordStat(kMonomorphicCall);
+ MaybeRecordStat(stats_, kMonomorphicCall);
if (UseOnlyPolymorphicInliningWithNoDeopt()) {
return TryInlinePolymorphicCall(invoke_instruction, resolved_method, inline_cache);
} else {
@@ -541,7 +541,7 @@
}
case kInlineCachePolymorphic: {
- MaybeRecordStat(kPolymorphicCall);
+ MaybeRecordStat(stats_, kPolymorphicCall);
return TryInlinePolymorphicCall(invoke_instruction, resolved_method, inline_cache);
}
@@ -550,7 +550,7 @@
<< "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 @@
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 @@
/* is_first_run */ false);
rtp_fixup.Run();
- MaybeRecordStat(kInlinedMonomorphicCall);
+ MaybeRecordStat(stats_, kInlinedMonomorphicCall);
return true;
}
@@ -993,7 +993,7 @@
return false;
}
- MaybeRecordStat(kInlinedPolymorphicCall);
+ MaybeRecordStat(stats_, kInlinedPolymorphicCall);
// Run type propagation to get the guards typed.
ReferenceTypePropagation rtp_fixup(graph_,
@@ -1199,7 +1199,7 @@
/* 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
}
LOG_SUCCESS() << method->PrettyMethod();
- MaybeRecordStat(kInlinedInvoke);
+ MaybeRecordStat(stats_, kInlinedInvoke);
return true;
}
@@ -1677,7 +1677,7 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
// 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 @@
!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 @@
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 @@
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 @@
}
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 @@
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 143c77f..b66883f 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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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 @@
<< 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 2a9b9f5..b7fa394 100644
--- a/compiler/optimizing/instruction_builder.h
+++ b/compiler/optimizing/instruction_builder.h
@@ -78,8 +78,6 @@
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 02cfbbc..5c79511 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -43,13 +43,7 @@
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 @@
if (object->IsNullConstant()) {
check_cast->GetBlock()->RemoveInstruction(check_cast);
- MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast);
+ MaybeRecordStat(stats_, MethodCompilationStat::kRemovedCheckedCast);
return;
}
@@ -527,7 +521,7 @@
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 @@
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 @@
// 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 7bdeef5..11725f4 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -154,7 +154,8 @@
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 f0086fb..10524b0 100644
--- a/compiler/optimizing/licm.cc
+++ b/compiler/optimizing/licm.cc
@@ -141,7 +141,7 @@
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 efe71c7..20a8a76 100644
--- a/compiler/optimizing/load_store_elimination.h
+++ b/compiler/optimizing/load_store_elimination.h
@@ -28,8 +28,9 @@
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 3d76949..1e68ca2 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 0819fb0..ce41a2e 100644
--- a/compiler/optimizing/optimization.h
+++ b/compiler/optimizing/optimization.h
@@ -47,8 +47,6 @@
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 76a243f..70bbc38 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -329,12 +329,6 @@
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 @@
} 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
&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 @@
}
}
} 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 @@
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 a211c54..098d23d 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -216,6 +216,14 @@
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 46d0d0e..cb7ade9 100644
--- a/compiler/optimizing/select_generator.cc
+++ b/compiler/optimizing/select_generator.cc
@@ -140,7 +140,7 @@
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