summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2023-10-30 10:12:01 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2024-01-30 15:33:00 +0000
commitf5307a31f5b67f6184cbb7e8b7fab61be3725fce (patch)
tree01d9284e052f5d96e723989dba214588c5c5d3dc
parentee4c3d633f673be1d43c959a3bc99519a376dba0 (diff)
Allow compilation of large methods with no branches
Popular apps include such methods in their profiles. Having the extra heuristic of skipping compilation for large methods with no branches can be unintuitive for developers who created those profiles. Some apps see startup improvements with this heuristic removed. Bug: 316617683 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: I21a8da93e89399dac0e45c3ab43a8bbedc925a44
-rw-r--r--compiler/driver/compiler_options.cc1
-rw-r--r--compiler/driver/compiler_options.h10
-rw-r--r--compiler/driver/compiler_options_map-inl.h6
-rw-r--r--compiler/driver/compiler_options_map.def1
-rw-r--r--compiler/optimizing/block_builder.cc5
-rw-r--r--compiler/optimizing/block_builder.h2
-rw-r--r--compiler/optimizing/builder.cc13
-rw-r--r--compiler/optimizing/builder.h2
8 files changed, 5 insertions, 35 deletions
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index ada7685b78..36943a0dd1 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -40,7 +40,6 @@ namespace art HIDDEN {
CompilerOptions::CompilerOptions()
: compiler_filter_(CompilerFilter::kDefaultCompilerFilter),
huge_method_threshold_(kDefaultHugeMethodThreshold),
- large_method_threshold_(kDefaultLargeMethodThreshold),
inline_max_code_units_(kUnsetInlineMaxCodeUnits),
instruction_set_(kRuntimeISA == InstructionSet::kArm ? InstructionSet::kThumb2 : kRuntimeISA),
instruction_set_features_(nullptr),
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 3064729597..5890227c36 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -62,7 +62,6 @@ class CompilerOptions final {
public:
// Guide heuristics to determine whether to compile method if profile data not available.
static const size_t kDefaultHugeMethodThreshold = 10000;
- static const size_t kDefaultLargeMethodThreshold = 600;
static const bool kDefaultGenerateDebugInfo = false;
static const bool kDefaultGenerateMiniDebugInfo = true;
static const size_t kDefaultInlineMaxCodeUnits = 32;
@@ -121,18 +120,10 @@ class CompilerOptions final {
return huge_method_threshold_;
}
- size_t GetLargeMethodThreshold() const {
- return large_method_threshold_;
- }
-
bool IsHugeMethod(size_t num_dalvik_instructions) const {
return num_dalvik_instructions > huge_method_threshold_;
}
- bool IsLargeMethod(size_t num_dalvik_instructions) const {
- return num_dalvik_instructions > large_method_threshold_;
- }
-
size_t GetInlineMaxCodeUnits() const {
return inline_max_code_units_;
}
@@ -392,7 +383,6 @@ class CompilerOptions final {
CompilerFilter::Filter compiler_filter_;
size_t huge_method_threshold_;
- size_t large_method_threshold_;
size_t inline_max_code_units_;
InstructionSet instruction_set_;
diff --git a/compiler/driver/compiler_options_map-inl.h b/compiler/driver/compiler_options_map-inl.h
index 9a02b576d1..317b2861b7 100644
--- a/compiler/driver/compiler_options_map-inl.h
+++ b/compiler/driver/compiler_options_map-inl.h
@@ -57,7 +57,6 @@ inline bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string
}
map.AssignIfExists(Base::CompileArtTest, &options->compile_art_test_);
map.AssignIfExists(Base::HugeMethodMaxThreshold, &options->huge_method_threshold_);
- map.AssignIfExists(Base::LargeMethodMaxThreshold, &options->large_method_threshold_);
map.AssignIfExists(Base::InlineMaxCodeUnitsThreshold, &options->inline_max_code_units_);
map.AssignIfExists(Base::GenerateDebugInfo, &options->generate_debug_info_);
map.AssignIfExists(Base::GenerateMiniDebugInfo, &options->generate_mini_debug_info_);
@@ -134,10 +133,6 @@ NO_INLINE void AddCompilerOptionsArgumentParserOptions(Builder& b) {
.template WithType<unsigned int>()
.WithHelp("threshold size for a huge method for compiler filter tuning.")
.IntoKey(Map::HugeMethodMaxThreshold)
- .Define("--large-method-max=_")
- .template WithType<unsigned int>()
- .WithHelp("threshold size for a large method for compiler filter tuning.")
- .IntoKey(Map::LargeMethodMaxThreshold)
.Define("--inline-max-code-units=_")
.template WithType<unsigned int>()
.WithHelp("the maximum code units that a methodcan have to be considered for inlining.\n"
@@ -256,6 +251,7 @@ NO_INLINE void AddCompilerOptionsArgumentParserOptions(Builder& b) {
.Ignore({
"--num-dex-methods=_",
"--top-k-profile-threshold=_",
+ "--large-method-max=_",
});
// clang-format on
}
diff --git a/compiler/driver/compiler_options_map.def b/compiler/driver/compiler_options_map.def
index 133ad2b5d0..767a86cb89 100644
--- a/compiler/driver/compiler_options_map.def
+++ b/compiler/driver/compiler_options_map.def
@@ -40,7 +40,6 @@ COMPILER_OPTIONS_KEY (CompilerFilter::Filter, CompilerFilter)
COMPILER_OPTIONS_KEY (bool, CompileArtTest)
COMPILER_OPTIONS_KEY (Unit, PIC)
COMPILER_OPTIONS_KEY (unsigned int, HugeMethodMaxThreshold)
-COMPILER_OPTIONS_KEY (unsigned int, LargeMethodMaxThreshold)
COMPILER_OPTIONS_KEY (unsigned int, InlineMaxCodeUnitsThreshold)
COMPILER_OPTIONS_KEY (bool, GenerateDebugInfo)
COMPILER_OPTIONS_KEY (bool, GenerateMiniDebugInfo)
diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc
index 9da2bfb8ef..12c260a146 100644
--- a/compiler/optimizing/block_builder.cc
+++ b/compiler/optimizing/block_builder.cc
@@ -38,8 +38,7 @@ HBasicBlockBuilder::HBasicBlockBuilder(HGraph* graph,
nullptr,
local_allocator->Adapter(kArenaAllocGraphBuilder)),
throwing_blocks_(kDefaultNumberOfThrowingBlocks,
- local_allocator->Adapter(kArenaAllocGraphBuilder)),
- number_of_branches_(0u) {}
+ local_allocator->Adapter(kArenaAllocGraphBuilder)) {}
HBasicBlock* HBasicBlockBuilder::MaybeCreateBlockAt(uint32_t dex_pc) {
return MaybeCreateBlockAt(dex_pc, dex_pc);
@@ -101,10 +100,8 @@ bool HBasicBlockBuilder::CreateBranchTargets() {
const Instruction& instruction = pair.Inst();
if (instruction.IsBranch()) {
- number_of_branches_++;
MaybeCreateBlockAt(dex_pc + instruction.GetTargetOffset());
} else if (instruction.IsSwitch()) {
- number_of_branches_++; // count as at least one branch (b/77652521)
DexSwitchTable table(instruction, dex_pc);
for (DexSwitchTableIterator s_it(table); !s_it.Done(); s_it.Advance()) {
MaybeCreateBlockAt(dex_pc + s_it.CurrentTargetOffset());
diff --git a/compiler/optimizing/block_builder.h b/compiler/optimizing/block_builder.h
index 1aa9375e5a..ce1fb6f054 100644
--- a/compiler/optimizing/block_builder.h
+++ b/compiler/optimizing/block_builder.h
@@ -42,7 +42,6 @@ class HBasicBlockBuilder : public ValueObject {
// Creates basic blocks in `graph_` for compiling an intrinsic.
void BuildIntrinsic();
- size_t GetNumberOfBranches() const { return number_of_branches_; }
HBasicBlock* GetBlockAt(uint32_t dex_pc) const { return branch_targets_[dex_pc]; }
private:
@@ -79,7 +78,6 @@ class HBasicBlockBuilder : public ValueObject {
ScopedArenaAllocator* const local_allocator_;
ScopedArenaVector<HBasicBlock*> branch_targets_;
ScopedArenaVector<HBasicBlock*> throwing_blocks_;
- size_t number_of_branches_;
static constexpr size_t kDefaultNumberOfThrowingBlocks = 2u;
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 48d1a9da2f..9233ea4fcd 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -63,7 +63,7 @@ HGraphBuilder::HGraphBuilder(HGraph* graph,
compilation_stats_(nullptr),
return_type_(return_type) {}
-bool HGraphBuilder::SkipCompilation(size_t number_of_branches) {
+bool HGraphBuilder::SkipCompilation() {
if (code_generator_ == nullptr) {
// Note that the codegen is null when unit testing.
return false;
@@ -84,15 +84,6 @@ bool HGraphBuilder::SkipCompilation(size_t number_of_branches) {
return true;
}
- // If it's large and contains no branches, it's likely to be machine generated initialization.
- if (compiler_options.IsLargeMethod(code_units) && (number_of_branches == 0)) {
- VLOG(compiler) << "Skip compilation of large method with no branch "
- << dex_file_->PrettyMethod(dex_compilation_unit_->GetDexMethodIndex())
- << ": " << code_units << " code units";
- MaybeRecordStat(compilation_stats_, MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
- return true;
- }
-
return false;
}
@@ -131,7 +122,7 @@ GraphAnalysisResult HGraphBuilder::BuildGraph() {
// 2) Decide whether to skip this method based on its code size and number
// of branches.
- if (SkipCompilation(block_builder.GetNumberOfBranches())) {
+ if (SkipCompilation()) {
return kAnalysisSkipped;
}
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index ef225d9a6a..b81b2f0d11 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -53,7 +53,7 @@ class HGraphBuilder : public ValueObject {
static constexpr const char* kBuilderPassName = "builder";
private:
- bool SkipCompilation(size_t number_of_branches);
+ bool SkipCompilation();
HGraph* const graph_;
const DexFile* const dex_file_;