summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2023-12-01 14:47:37 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2023-12-04 10:35:16 +0000
commit8891ea4eac12b8f48934d47f2d99da1e9b455788 (patch)
tree00b523efef48ab608779156af751e1bf38c70091
parentf51e433b5d32cb83eb2ee302544ecf67a10525b9 (diff)
Put branch profiling under a flag.
Until we evaluate its usefulness and reduce its overhead. Bug: 306638020 Test: test.py Change-Id: Ibb01c70a7ea19b03802dcc1b0792d3d2ff4f4d67
-rw-r--r--compiler/driver/compiler_options.cc1
-rw-r--r--compiler/driver/compiler_options.h5
-rw-r--r--compiler/driver/compiler_options_map-inl.h7
-rw-r--r--compiler/driver/compiler_options_map.def1
-rw-r--r--compiler/optimizing/code_generator_arm64.cc6
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc10
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc10
-rw-r--r--compiler/optimizing/code_generator_x86.cc21
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc21
-rw-r--r--compiler/optimizing/nodes.h7
-rw-r--r--compiler/optimizing/prepare_for_register_allocation.cc2
-rw-r--r--test/850-checker-branches/run.py1
12 files changed, 58 insertions, 34 deletions
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index 45664b792e..ada7685b78 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -64,6 +64,7 @@ CompilerOptions::CompilerOptions()
dump_timings_(false),
dump_pass_timings_(false),
dump_stats_(false),
+ profile_branches_(false),
profile_compilation_info_(nullptr),
verbose_methods_(),
abort_on_hard_verifier_failure_(false),
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index f816c1485d..3064729597 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -220,6 +220,10 @@ class CompilerOptions final {
return baseline_;
}
+ bool ProfileBranches() const {
+ return profile_branches_;
+ }
+
// Are we compiling an app image?
bool IsAppImage() const {
return image_type_ == ImageType::kAppImage;
@@ -427,6 +431,7 @@ class CompilerOptions final {
bool dump_timings_;
bool dump_pass_timings_;
bool dump_stats_;
+ bool profile_branches_;
// Info for profile guided compilation.
const ProfileCompilationInfo* profile_compilation_info_;
diff --git a/compiler/driver/compiler_options_map-inl.h b/compiler/driver/compiler_options_map-inl.h
index 4734950a2c..9a02b576d1 100644
--- a/compiler/driver/compiler_options_map-inl.h
+++ b/compiler/driver/compiler_options_map-inl.h
@@ -68,6 +68,9 @@ inline bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string
if (map.Exists(Base::Baseline)) {
options->baseline_ = true;
}
+ if (map.Exists(Base::ProfileBranches)) {
+ options->profile_branches_ = true;
+ }
map.AssignIfExists(Base::AbortOnHardVerifierFailure, &options->abort_on_hard_verifier_failure_);
map.AssignIfExists(Base::AbortOnSoftVerifierFailure, &options->abort_on_soft_verifier_failure_);
if (map.Exists(Base::DumpInitFailures)) {
@@ -198,6 +201,10 @@ NO_INLINE void AddCompilerOptionsArgumentParserOptions(Builder& b) {
.WithHelp("Produce code using the baseline compilation")
.IntoKey(Map::Baseline)
+ .Define("--profile-branches")
+ .WithHelp("Profile branches in baseline generated code")
+ .IntoKey(Map::ProfileBranches)
+
.Define({"--abort-on-hard-verifier-error", "--no-abort-on-hard-verifier-error"})
.WithValues({true, false})
.IntoKey(Map::AbortOnHardVerifierFailure)
diff --git a/compiler/driver/compiler_options_map.def b/compiler/driver/compiler_options_map.def
index c6666a8085..133ad2b5d0 100644
--- a/compiler/driver/compiler_options_map.def
+++ b/compiler/driver/compiler_options_map.def
@@ -47,6 +47,7 @@ COMPILER_OPTIONS_KEY (bool, GenerateMiniDebugInfo)
COMPILER_OPTIONS_KEY (bool, GenerateBuildID)
COMPILER_OPTIONS_KEY (Unit, Debuggable)
COMPILER_OPTIONS_KEY (Unit, Baseline)
+COMPILER_OPTIONS_KEY (Unit, ProfileBranches)
COMPILER_OPTIONS_KEY (bool, AbortOnHardVerifierFailure)
COMPILER_OPTIONS_KEY (bool, AbortOnSoftVerifierFailure)
COMPILER_OPTIONS_KEY (bool, ResolveStartupConstStrings, false)
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index d855d5ecad..bd1f71f344 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -3866,7 +3866,9 @@ void InstructionCodeGeneratorARM64::VisitIf(HIf* if_instr) {
false_target = nullptr;
}
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
DCHECK(if_instr->InputAt(0)->IsCondition());
ProfilingInfo* info = GetGraph()->GetProfilingInfo();
DCHECK(info != nullptr);
@@ -3891,8 +3893,6 @@ void InstructionCodeGeneratorARM64::VisitIf(HIf* if_instr) {
__ Bind(&done);
}
}
- } else {
- DCHECK(!GetGraph()->IsCompilingBaseline()) << if_instr->InputAt(0)->DebugName();
}
GenerateTestAndBranch(if_instr, /* condition_input_index= */ 0, true_target, false_target);
}
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index f98f4d75be..25331dfcc9 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -2990,7 +2990,9 @@ void LocationsBuilderARMVIXL::VisitIf(HIf* if_instr) {
LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(if_instr);
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
locations->SetInAt(0, Location::RequiresRegister());
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
locations->AddTemp(Location::RequiresRegister());
}
}
@@ -3004,7 +3006,9 @@ void InstructionCodeGeneratorARMVIXL::VisitIf(HIf* if_instr) {
vixl32::Label* false_target = codegen_->GoesToNextBlock(if_instr->GetBlock(), false_successor) ?
nullptr : codegen_->GetLabelOf(false_successor);
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
DCHECK(if_instr->InputAt(0)->IsCondition());
ProfilingInfo* info = GetGraph()->GetProfilingInfo();
DCHECK(info != nullptr);
@@ -3030,8 +3034,6 @@ void InstructionCodeGeneratorARMVIXL::VisitIf(HIf* if_instr) {
__ Bind(&done);
}
}
- } else {
- DCHECK(!GetGraph()->IsCompilingBaseline()) << if_instr->InputAt(0)->DebugName();
}
GenerateTestAndBranch(if_instr, /* condition_input_index= */ 0, true_target, false_target);
}
diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc
index 7331ad6e4e..92ed3f1d4f 100644
--- a/compiler/optimizing/code_generator_riscv64.cc
+++ b/compiler/optimizing/code_generator_riscv64.cc
@@ -3698,7 +3698,9 @@ void LocationsBuilderRISCV64::VisitIf(HIf* instruction) {
LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction);
if (IsBooleanValueOrMaterializedCondition(instruction->InputAt(0))) {
locations->SetInAt(0, Location::RequiresRegister());
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
DCHECK(instruction->InputAt(0)->IsCondition());
ProfilingInfo* info = GetGraph()->GetProfilingInfo();
DCHECK(info != nullptr);
@@ -3720,7 +3722,9 @@ void InstructionCodeGeneratorRISCV64::VisitIf(HIf* instruction) {
? nullptr
: codegen_->GetLabelOf(false_successor);
if (IsBooleanValueOrMaterializedCondition(instruction->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
DCHECK(instruction->InputAt(0)->IsCondition());
ProfilingInfo* info = GetGraph()->GetProfilingInfo();
DCHECK(info != nullptr);
@@ -3751,8 +3755,6 @@ void InstructionCodeGeneratorRISCV64::VisitIf(HIf* instruction) {
__ Bind(&done);
}
}
- } else {
- DCHECK(!GetGraph()->IsCompilingBaseline()) << instruction->InputAt(0)->DebugName();
}
GenerateTestAndBranch(instruction, /* condition_input_index= */ 0, true_target, false_target);
}
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index c353087dd7..461d14afc9 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -2109,7 +2109,9 @@ void InstructionCodeGeneratorX86::GenerateCompareTestAndBranch(HCondition* condi
}
}
-static bool AreEflagsSetFrom(HInstruction* cond, HInstruction* branch) {
+static bool AreEflagsSetFrom(HInstruction* cond,
+ HInstruction* branch,
+ const CompilerOptions& compiler_options) {
// Moves may affect the eflags register (move zero uses xorl), so the EFLAGS
// are set only strictly before `branch`. We can't use the eflags on long/FP
// conditions if they are materialized due to the complex branching.
@@ -2117,7 +2119,8 @@ static bool AreEflagsSetFrom(HInstruction* cond, HInstruction* branch) {
cond->GetNext() == branch &&
cond->InputAt(0)->GetType() != DataType::Type::kInt64 &&
!DataType::IsFloatingPointType(cond->InputAt(0)->GetType()) &&
- !cond->GetBlock()->GetGraph()->IsCompilingBaseline();
+ !(cond->GetBlock()->GetGraph()->IsCompilingBaseline() &&
+ compiler_options.ProfileBranches());
}
template<class LabelType>
@@ -2154,7 +2157,7 @@ void InstructionCodeGeneratorX86::GenerateTestAndBranch(HInstruction* instructio
// - condition true => branch to true_target
// - branch to false_target
if (IsBooleanValueOrMaterializedCondition(cond)) {
- if (AreEflagsSetFrom(cond, instruction)) {
+ if (AreEflagsSetFrom(cond, instruction, codegen_->GetCompilerOptions())) {
if (true_target == nullptr) {
__ j(X86Condition(cond->AsCondition()->GetOppositeCondition()), false_target);
} else {
@@ -2208,7 +2211,9 @@ void InstructionCodeGeneratorX86::GenerateTestAndBranch(HInstruction* instructio
void LocationsBuilderX86::VisitIf(HIf* if_instr) {
LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(if_instr);
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
locations->SetInAt(0, Location::RequiresRegister());
locations->AddTemp(Location::RequiresRegister());
locations->AddTemp(Location::RequiresRegister());
@@ -2226,7 +2231,9 @@ void InstructionCodeGeneratorX86::VisitIf(HIf* if_instr) {
Label* false_target = codegen_->GoesToNextBlock(if_instr->GetBlock(), false_successor) ?
nullptr : codegen_->GetLabelOf(false_successor);
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
DCHECK(if_instr->InputAt(0)->IsCondition());
Register temp = if_instr->GetLocations()->GetTemp(0).AsRegister<Register>();
Register counter = if_instr->GetLocations()->GetTemp(1).AsRegister<Register>();
@@ -2250,8 +2257,6 @@ void InstructionCodeGeneratorX86::VisitIf(HIf* if_instr) {
__ Bind(&done);
}
}
- } else {
- DCHECK(!GetGraph()->IsCompilingBaseline()) << if_instr->InputAt(0)->DebugName();
}
GenerateTestAndBranch(if_instr, /* condition_input_index= */ 0, true_target, false_target);
}
@@ -2348,7 +2353,7 @@ void InstructionCodeGeneratorX86::VisitSelect(HSelect* select) {
if (!condition->IsEmittedAtUseSite()) {
// This was a previously materialized condition.
// Can we use the existing condition code?
- if (AreEflagsSetFrom(condition, select)) {
+ if (AreEflagsSetFrom(condition, select, codegen_->GetCompilerOptions())) {
// Materialization was the previous instruction. Condition codes are right.
cond = X86Condition(condition->GetCondition());
} else {
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index d72a436e91..46c52a219a 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -2173,14 +2173,17 @@ void InstructionCodeGeneratorX86_64::GenerateCompareTestAndBranch(HCondition* co
}
}
-static bool AreEflagsSetFrom(HInstruction* cond, HInstruction* branch) {
+static bool AreEflagsSetFrom(HInstruction* cond,
+ HInstruction* branch,
+ const CompilerOptions& compiler_options) {
// Moves may affect the eflags register (move zero uses xorl), so the EFLAGS
// are set only strictly before `branch`. We can't use the eflags on long
// conditions if they are materialized due to the complex branching.
return cond->IsCondition() &&
cond->GetNext() == branch &&
!DataType::IsFloatingPointType(cond->InputAt(0)->GetType()) &&
- !cond->GetBlock()->GetGraph()->IsCompilingBaseline();
+ !(cond->GetBlock()->GetGraph()->IsCompilingBaseline() &&
+ compiler_options.ProfileBranches());
}
template<class LabelType>
@@ -2217,7 +2220,7 @@ void InstructionCodeGeneratorX86_64::GenerateTestAndBranch(HInstruction* instruc
// - condition true => branch to true_target
// - branch to false_target
if (IsBooleanValueOrMaterializedCondition(cond)) {
- if (AreEflagsSetFrom(cond, instruction)) {
+ if (AreEflagsSetFrom(cond, instruction, codegen_->GetCompilerOptions())) {
if (true_target == nullptr) {
__ j(X86_64IntegerCondition(cond->AsCondition()->GetOppositeCondition()), false_target);
} else {
@@ -2270,7 +2273,9 @@ void InstructionCodeGeneratorX86_64::GenerateTestAndBranch(HInstruction* instruc
void LocationsBuilderX86_64::VisitIf(HIf* if_instr) {
LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(if_instr);
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
locations->SetInAt(0, Location::RequiresRegister());
locations->AddTemp(Location::RequiresRegister());
} else {
@@ -2287,7 +2292,9 @@ void InstructionCodeGeneratorX86_64::VisitIf(HIf* if_instr) {
Label* false_target = codegen_->GoesToNextBlock(if_instr->GetBlock(), false_successor) ?
nullptr : codegen_->GetLabelOf(false_successor);
if (IsBooleanValueOrMaterializedCondition(if_instr->InputAt(0))) {
- if (GetGraph()->IsCompilingBaseline() && !Runtime::Current()->IsAotCompiler()) {
+ if (GetGraph()->IsCompilingBaseline() &&
+ codegen_->GetCompilerOptions().ProfileBranches() &&
+ !Runtime::Current()->IsAotCompiler()) {
DCHECK(if_instr->InputAt(0)->IsCondition());
CpuRegister temp = if_instr->GetLocations()->GetTemp(0).AsRegister<CpuRegister>();
ProfilingInfo* info = GetGraph()->GetProfilingInfo();
@@ -2310,8 +2317,6 @@ void InstructionCodeGeneratorX86_64::VisitIf(HIf* if_instr) {
__ Bind(&done);
}
}
- } else {
- DCHECK(!GetGraph()->IsCompilingBaseline()) << if_instr->InputAt(0)->DebugName();
}
GenerateTestAndBranch(if_instr, /* condition_input_index= */ 0, true_target, false_target);
}
@@ -2405,7 +2410,7 @@ void InstructionCodeGeneratorX86_64::VisitSelect(HSelect* select) {
if (!condition->IsEmittedAtUseSite()) {
// This was a previously materialized condition.
// Can we use the existing condition code?
- if (AreEflagsSetFrom(condition, select)) {
+ if (AreEflagsSetFrom(condition, select, codegen_->GetCompilerOptions())) {
// Materialization was the previous instruction. Condition codes are right.
cond = X86_64IntegerCondition(condition->GetCondition());
} else {
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 4db72a68e3..6ec83beabd 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2663,12 +2663,7 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> {
void RemoveEnvironmentUsers();
bool IsEmittedAtUseSite() const { return GetPackedFlag<kFlagEmittedAtUseSite>(); }
- void MarkEmittedAtUseSite() {
- // When compiling baseline, in order to do branch profiling, we don't want to
- // emit conditions at use site.
- DCHECK(!IsCondition() || !GetBlock()->GetGraph()->IsCompilingBaseline());
- SetPackedFlag<kFlagEmittedAtUseSite>(true);
- }
+ void MarkEmittedAtUseSite() { SetPackedFlag<kFlagEmittedAtUseSite>(true); }
protected:
// If set, the machine code for this instruction is assumed to be generated by
diff --git a/compiler/optimizing/prepare_for_register_allocation.cc b/compiler/optimizing/prepare_for_register_allocation.cc
index 59282a7222..1e99732d03 100644
--- a/compiler/optimizing/prepare_for_register_allocation.cc
+++ b/compiler/optimizing/prepare_for_register_allocation.cc
@@ -180,7 +180,7 @@ bool PrepareForRegisterAllocation::CanEmitConditionAt(HCondition* condition,
return false;
}
- if (GetGraph()->IsCompilingBaseline()) {
+ if (GetGraph()->IsCompilingBaseline() && compiler_options_.ProfileBranches()) {
// To do branch profiling, we cannot emit conditions at use site.
return false;
}
diff --git a/test/850-checker-branches/run.py b/test/850-checker-branches/run.py
index b7ff987785..9bdc033284 100644
--- a/test/850-checker-branches/run.py
+++ b/test/850-checker-branches/run.py
@@ -25,5 +25,6 @@ def run(ctx, args):
jit=True,
runtime_option=["-Xjitinitialsize:32M"],
Xcompiler_option=[
+ "--profile-branches",
"--verbose-methods=withBranch"
])