From aa02410a2de17b638a1eb5c664b390c4b1c36aed Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Wed, 21 Feb 2024 12:13:01 +0100 Subject: Inliner: Always try code pattern recognition. Try code pattern recognition whenever we're allowed to inline. The pattern recognition is fast and when we find a match, we avoid costly processing, such as building the callee graph. The pattern replacement is always better than the invoke, so do it even when inlining is not "encouraged", for example in blocks that end with a `throw`. Reorder the code so that the pattern recognition respects the @NeverInline annotation. Enable run-test 569 for target and add a test for the @NeverInline annotation. Also remove some duplicated helper functions and reduce the number of arguments we pass around. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: testrunner.py --jvm Test: run-gtests.sh Test: testrunner.py --target --optimizing Bug: 181943478 Change-Id: I863fe1190eb38c7decf0c5e34a00c103e8e559f1 --- compiler/optimizing/inliner.cc | 32 +++++++++++++++++++------------- compiler/optimizing/inliner.h | 1 + 2 files changed, 20 insertions(+), 13 deletions(-) (limited to 'compiler/optimizing') diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index d7ca17b646..f1e2733f3e 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1619,17 +1619,28 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, return true; } + CodeItemDataAccessor accessor(method->DexInstructionData()); + + if (!IsInliningAllowed(method, accessor)) { + return false; + } + + // We have checked above that inlining is "allowed" to make sure that the method has bytecode + // (is not native), is compilable and verified and to enforce the @NeverInline annotation. + // However, the pattern substitution is always preferable, so we do it before the check if + // inlining is "encouraged". It also has an exception to the `MayInline()` restriction. + if (TryPatternSubstitution(invoke_instruction, method, accessor, return_replacement)) { + LOG_SUCCESS() << "Successfully replaced pattern of invoke " + << method->PrettyMethod(); + MaybeRecordStat(stats_, MethodCompilationStat::kReplacedInvokeWithSimplePattern); + return true; + } + // Check whether we're allowed to inline. The outermost compilation unit is the relevant // dex file here (though the transitivity of an inline chain would allow checking the caller). if (!MayInline(codegen_->GetCompilerOptions(), *method->GetDexFile(), *outer_compilation_unit_.GetDexFile())) { - if (TryPatternSubstitution(invoke_instruction, method, return_replacement)) { - LOG_SUCCESS() << "Successfully replaced pattern of invoke " - << method->PrettyMethod(); - MaybeRecordStat(stats_, MethodCompilationStat::kReplacedInvokeWithSimplePattern); - return true; - } LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedWont) << "Won't inline " << method->PrettyMethod() << " in " << outer_compilation_unit_.GetDexFile()->GetLocation() << " (" @@ -1638,12 +1649,6 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, return false; } - CodeItemDataAccessor accessor(method->DexInstructionData()); - - if (!IsInliningAllowed(method, accessor)) { - return false; - } - if (!IsInliningSupported(invoke_instruction, method, accessor)) { return false; } @@ -1683,9 +1688,10 @@ static HInstruction* GetInvokeInputForArgVRegIndex(HInvoke* invoke_instruction, // Try to recognize known simple patterns and replace invoke call with appropriate instructions. bool HInliner::TryPatternSubstitution(HInvoke* invoke_instruction, ArtMethod* method, + const CodeItemDataAccessor& accessor, HInstruction** return_replacement) { InlineMethod inline_method; - if (!InlineMethodAnalyser::AnalyseMethodCode(method, &inline_method)) { + if (!InlineMethodAnalyser::AnalyseMethodCode(method, &accessor, &inline_method)) { return false; } diff --git a/compiler/optimizing/inliner.h b/compiler/optimizing/inliner.h index 48600543c6..57d3364051 100644 --- a/compiler/optimizing/inliner.h +++ b/compiler/optimizing/inliner.h @@ -126,6 +126,7 @@ class HInliner : public HOptimization { // Try to recognize known simple patterns and replace invoke call with appropriate instructions. bool TryPatternSubstitution(HInvoke* invoke_instruction, ArtMethod* method, + const CodeItemDataAccessor& accessor, HInstruction** return_replacement) REQUIRES_SHARED(Locks::mutator_lock_); -- cgit v1.2.3-59-g8ed1b