summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Brazdil <dbrazdil@google.com>2015-03-31 11:37:18 +0100
committerDavid Brazdil <dbrazdil@google.com>2015-03-31 16:36:31 +0100
commit1b498727f79e85756a9eee86d31214393dc7002c (patch)
tree45c42ed6e28304e3ee9b713289fc32007f2faa06
parentebbb1e322d8c89e69424a543faa03402e5b63673 (diff)
downloadart-1b498727f79e85756a9eee86d31214393dc7002c.tar.gz
art-1b498727f79e85756a9eee86d31214393dc7002c.tar.bz2
art-1b498727f79e85756a9eee86d31214393dc7002c.zip
ART: Same skip-compilation heuristic in both backends
When deciding if a method should be compiled, Optimizing counts the DEX instructions while Quick approximates this figure as the size of the CodeItem. This patch modifies Optimizing to use the same logic so that the two backends reject the same set of methods. Change-Id: Icb12bf2977f948198df08d59f243532ec8c61783
-rw-r--r--compiler/optimizing/builder.cc28
-rw-r--r--compiler/optimizing/builder.h6
2 files changed, 9 insertions, 25 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 2cdd5af9f3..62bd86af98 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -230,8 +230,7 @@ void HGraphBuilder::MaybeRecordStat(MethodCompilationStat compilation_stat) {
}
}
-bool HGraphBuilder::SkipCompilation(size_t number_of_dex_instructions,
- size_t number_of_blocks ATTRIBUTE_UNUSED,
+bool HGraphBuilder::SkipCompilation(const DexFile::CodeItem& code_item,
size_t number_of_branches) {
const CompilerOptions& compiler_options = compiler_driver_->GetCompilerOptions();
CompilerOptions::CompilerFilter compiler_filter = compiler_options.GetCompilerFilter();
@@ -239,19 +238,20 @@ bool HGraphBuilder::SkipCompilation(size_t number_of_dex_instructions,
return false;
}
- if (compiler_options.IsHugeMethod(number_of_dex_instructions)) {
+ if (compiler_options.IsHugeMethod(code_item.insns_size_in_code_units_)) {
VLOG(compiler) << "Skip compilation of huge method "
<< PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
- << ": " << number_of_dex_instructions << " dex instructions";
+ << ": " << code_item.insns_size_in_code_units_ << " code units";
MaybeRecordStat(MethodCompilationStat::kNotCompiledHugeMethod);
return true;
}
// If it's large and contains no branches, it's likely to be machine generated initialization.
- if (compiler_options.IsLargeMethod(number_of_dex_instructions) && (number_of_branches == 0)) {
+ if (compiler_options.IsLargeMethod(code_item.insns_size_in_code_units_)
+ && (number_of_branches == 0)) {
VLOG(compiler) << "Skip compilation of large method with no branch "
<< PrettyMethod(dex_compilation_unit_->GetDexMethodIndex(), *dex_file_)
- << ": " << number_of_dex_instructions << " dex instructions";
+ << ": " << code_item.insns_size_in_code_units_ << " code units";
MaybeRecordStat(MethodCompilationStat::kNotCompiledLargeMethodNoBranches);
return true;
}
@@ -278,18 +278,14 @@ bool HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) {
// Compute the number of dex instructions, blocks, and branches. We will
// check these values against limits given to the compiler.
- size_t number_of_dex_instructions = 0;
- size_t number_of_blocks = 0;
size_t number_of_branches = 0;
// To avoid splitting blocks, we compute ahead of time the instructions that
// start a new block, and create these blocks.
- ComputeBranchTargets(
- code_ptr, code_end, &number_of_dex_instructions, &number_of_blocks, &number_of_branches);
+ ComputeBranchTargets(code_ptr, code_end, &number_of_branches);
// Note that the compiler driver is null when unit testing.
- if ((compiler_driver_ != nullptr)
- && SkipCompilation(number_of_dex_instructions, number_of_blocks, number_of_branches)) {
+ if ((compiler_driver_ != nullptr) && SkipCompilation(code_item, number_of_branches)) {
return false;
}
@@ -355,8 +351,6 @@ void HGraphBuilder::MaybeUpdateCurrentBlock(size_t index) {
void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
const uint16_t* code_end,
- size_t* number_of_dex_instructions,
- size_t* number_of_blocks,
size_t* number_of_branches) {
branch_targets_.SetSize(code_end - code_ptr);
@@ -369,7 +363,6 @@ void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
// the locations these instructions branch to.
uint32_t dex_pc = 0;
while (code_ptr < code_end) {
- (*number_of_dex_instructions)++;
const Instruction& instruction = *Instruction::At(code_ptr);
if (instruction.IsBranch()) {
(*number_of_branches)++;
@@ -378,14 +371,12 @@ void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
if (FindBlockStartingAt(target) == nullptr) {
block = new (arena_) HBasicBlock(graph_, target);
branch_targets_.Put(target, block);
- (*number_of_blocks)++;
}
dex_pc += instruction.SizeInCodeUnits();
code_ptr += instruction.SizeInCodeUnits();
if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) {
block = new (arena_) HBasicBlock(graph_, dex_pc);
branch_targets_.Put(dex_pc, block);
- (*number_of_blocks)++;
}
} else if (instruction.IsSwitch()) {
SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH);
@@ -403,14 +394,12 @@ void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
if (FindBlockStartingAt(target) == nullptr) {
block = new (arena_) HBasicBlock(graph_, target);
branch_targets_.Put(target, block);
- (*number_of_blocks)++;
}
// The next case gets its own block.
if (i < num_entries) {
block = new (arena_) HBasicBlock(graph_, target);
branch_targets_.Put(table.GetDexPcForIndex(i), block);
- (*number_of_blocks)++;
}
}
@@ -420,7 +409,6 @@ void HGraphBuilder::ComputeBranchTargets(const uint16_t* code_ptr,
if ((code_ptr < code_end) && (FindBlockStartingAt(dex_pc) == nullptr)) {
block = new (arena_) HBasicBlock(graph_, dex_pc);
branch_targets_.Put(dex_pc, block);
- (*number_of_blocks)++;
}
} else {
code_ptr += instruction.SizeInCodeUnits();
diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h
index 6a0738a7b9..dc6d97eb0c 100644
--- a/compiler/optimizing/builder.h
+++ b/compiler/optimizing/builder.h
@@ -90,8 +90,6 @@ class HGraphBuilder : public ValueObject {
// branches.
void ComputeBranchTargets(const uint16_t* start,
const uint16_t* end,
- size_t* number_of_dex_instructions,
- size_t* number_of_block,
size_t* number_of_branches);
void MaybeUpdateCurrentBlock(size_t index);
HBasicBlock* FindBlockStartingAt(int32_t index) const;
@@ -217,9 +215,7 @@ class HGraphBuilder : public ValueObject {
HInstruction* value, int32_t case_value_int,
int32_t target_offset, uint32_t dex_pc);
- bool SkipCompilation(size_t number_of_dex_instructions,
- size_t number_of_blocks,
- size_t number_of_branches);
+ bool SkipCompilation(const DexFile::CodeItem& code_item, size_t number_of_branches);
void MaybeRecordStat(MethodCompilationStat compilation_stat);