Clean up NullCheck generation and record stats about it.
This removes redundant code from the generators and allows for easier
stat recording.
Change-Id: Iccd4368f9e9d87a6fecb863dee4e2145c97851c4
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index af50363..4d12099 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -1110,6 +1110,16 @@
}
}
+void CodeGenerator::GenerateNullCheck(HNullCheck* instruction) {
+ if (IsImplicitNullCheckAllowed(instruction)) {
+ MaybeRecordStat(kImplicitNullCheckGenerated);
+ GenerateImplicitNullCheck(instruction);
+ } else {
+ MaybeRecordStat(kExplicitNullCheckGenerated);
+ GenerateExplicitNullCheck(instruction);
+ }
+}
+
void CodeGenerator::ClearSpillSlotsFromLoopPhisInStackMap(HSuspendCheck* suspend_check) const {
LocationSummary* locations = suspend_check->GetLocations();
HBasicBlock* block = suspend_check->GetBlock();
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 9297fc9..3066048 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -278,6 +278,9 @@
bool CanMoveNullCheckToUser(HNullCheck* null_check);
void MaybeRecordImplicitNullCheck(HInstruction* instruction);
+ void GenerateNullCheck(HNullCheck* null_check);
+ virtual void GenerateImplicitNullCheck(HNullCheck* null_check) = 0;
+ virtual void GenerateExplicitNullCheck(HNullCheck* null_check) = 0;
// Records a stack map which the runtime might use to set catch phi values
// during exception delivery.
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 0b7fefa..a02bafc 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -4284,19 +4284,19 @@
}
}
-void InstructionCodeGeneratorARM::GenerateImplicitNullCheck(HNullCheck* instruction) {
- if (codegen_->CanMoveNullCheckToUser(instruction)) {
+void CodeGeneratorARM::GenerateImplicitNullCheck(HNullCheck* instruction) {
+ if (CanMoveNullCheckToUser(instruction)) {
return;
}
Location obj = instruction->GetLocations()->InAt(0);
__ LoadFromOffset(kLoadWord, IP, obj.AsRegister<Register>(), 0);
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ RecordPcInfo(instruction, instruction->GetDexPc());
}
-void InstructionCodeGeneratorARM::GenerateExplicitNullCheck(HNullCheck* instruction) {
+void CodeGeneratorARM::GenerateExplicitNullCheck(HNullCheck* instruction) {
SlowPathCode* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathARM(instruction);
- codegen_->AddSlowPath(slow_path);
+ AddSlowPath(slow_path);
LocationSummary* locations = instruction->GetLocations();
Location obj = locations->InAt(0);
@@ -4305,11 +4305,7 @@
}
void InstructionCodeGeneratorARM::VisitNullCheck(HNullCheck* instruction) {
- if (codegen_->IsImplicitNullCheckAllowed(instruction)) {
- GenerateImplicitNullCheck(instruction);
- } else {
- GenerateExplicitNullCheck(instruction);
- }
+ codegen_->GenerateNullCheck(instruction);
}
void LocationsBuilderARM::VisitArrayGet(HArrayGet* instruction) {
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index 06e7c00..5c0f31c 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -274,9 +274,6 @@
Location root,
Register obj,
uint32_t offset);
-
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
void GenerateTestAndBranch(HInstruction* instruction,
size_t condition_input_index,
Label* true_target,
@@ -514,6 +511,9 @@
void GenerateNop();
+ void GenerateImplicitNullCheck(HNullCheck* instruction);
+ void GenerateExplicitNullCheck(HNullCheck* instruction);
+
private:
// Factored implementation of GenerateFieldLoadWithBakerReadBarrier
// and GenerateArrayLoadWithBakerReadBarrier.
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 89b9e2c..3835f0b 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -4193,20 +4193,20 @@
}
}
-void InstructionCodeGeneratorARM64::GenerateImplicitNullCheck(HNullCheck* instruction) {
- if (codegen_->CanMoveNullCheckToUser(instruction)) {
+void CodeGeneratorARM64::GenerateImplicitNullCheck(HNullCheck* instruction) {
+ if (CanMoveNullCheckToUser(instruction)) {
return;
}
BlockPoolsScope block_pools(GetVIXLAssembler());
Location obj = instruction->GetLocations()->InAt(0);
__ Ldr(wzr, HeapOperandFrom(obj, Offset(0)));
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ RecordPcInfo(instruction, instruction->GetDexPc());
}
-void InstructionCodeGeneratorARM64::GenerateExplicitNullCheck(HNullCheck* instruction) {
+void CodeGeneratorARM64::GenerateExplicitNullCheck(HNullCheck* instruction) {
SlowPathCodeARM64* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathARM64(instruction);
- codegen_->AddSlowPath(slow_path);
+ AddSlowPath(slow_path);
LocationSummary* locations = instruction->GetLocations();
Location obj = locations->InAt(0);
@@ -4215,11 +4215,7 @@
}
void InstructionCodeGeneratorARM64::VisitNullCheck(HNullCheck* instruction) {
- if (codegen_->IsImplicitNullCheckAllowed(instruction)) {
- GenerateImplicitNullCheck(instruction);
- } else {
- GenerateExplicitNullCheck(instruction);
- }
+ codegen_->GenerateNullCheck(instruction);
}
void LocationsBuilderARM64::VisitOr(HOr* instruction) {
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index 10f1e7f..a1f686e 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -258,8 +258,6 @@
uint32_t offset);
void HandleShift(HBinaryOperation* instr);
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
void GenerateTestAndBranch(HInstruction* instruction,
size_t condition_input_index,
vixl::Label* true_target,
@@ -537,6 +535,9 @@
void GenerateNop();
+ void GenerateImplicitNullCheck(HNullCheck* instruction);
+ void GenerateExplicitNullCheck(HNullCheck* instruction);
+
private:
// Factored implementation of GenerateFieldLoadWithBakerReadBarrier
// and GenerateArrayLoadWithBakerReadBarrier.
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index f3c12ef..680dba6 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -4395,19 +4395,19 @@
}
}
-void InstructionCodeGeneratorMIPS::GenerateImplicitNullCheck(HNullCheck* instruction) {
- if (codegen_->CanMoveNullCheckToUser(instruction)) {
+void CodeGeneratorMIPS::GenerateImplicitNullCheck(HNullCheck* instruction) {
+ if (CanMoveNullCheckToUser(instruction)) {
return;
}
Location obj = instruction->GetLocations()->InAt(0);
__ Lw(ZERO, obj.AsRegister<Register>(), 0);
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ RecordPcInfo(instruction, instruction->GetDexPc());
}
-void InstructionCodeGeneratorMIPS::GenerateExplicitNullCheck(HNullCheck* instruction) {
+void CodeGeneratorMIPS::GenerateExplicitNullCheck(HNullCheck* instruction) {
SlowPathCodeMIPS* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathMIPS(instruction);
- codegen_->AddSlowPath(slow_path);
+ AddSlowPath(slow_path);
Location obj = instruction->GetLocations()->InAt(0);
@@ -4415,11 +4415,7 @@
}
void InstructionCodeGeneratorMIPS::VisitNullCheck(HNullCheck* instruction) {
- if (codegen_->IsImplicitNullCheckAllowed(instruction)) {
- GenerateImplicitNullCheck(instruction);
- } else {
- GenerateExplicitNullCheck(instruction);
- }
+ codegen_->GenerateNullCheck(instruction);
}
void LocationsBuilderMIPS::VisitOr(HOr* instruction) {
diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h
index 605c794..b720573 100644
--- a/compiler/optimizing/code_generator_mips.h
+++ b/compiler/optimizing/code_generator_mips.h
@@ -226,8 +226,6 @@
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction, const FieldInfo& field_info, uint32_t dex_pc);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info, uint32_t dex_pc);
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
void GenerateIntCompare(IfCondition cond, LocationSummary* locations);
void GenerateIntCompareAndBranch(IfCondition cond,
LocationSummary* locations,
@@ -362,6 +360,8 @@
}
void GenerateNop();
+ void GenerateImplicitNullCheck(HNullCheck* instruction);
+ void GenerateExplicitNullCheck(HNullCheck* instruction);
private:
// Labels for each block that will be compiled.
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index c2b84b4..88a643e 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -3550,19 +3550,19 @@
}
}
-void InstructionCodeGeneratorMIPS64::GenerateImplicitNullCheck(HNullCheck* instruction) {
- if (codegen_->CanMoveNullCheckToUser(instruction)) {
+void CodeGeneratorMIPS64::GenerateImplicitNullCheck(HNullCheck* instruction) {
+ if (CanMoveNullCheckToUser(instruction)) {
return;
}
Location obj = instruction->GetLocations()->InAt(0);
__ Lw(ZERO, obj.AsRegister<GpuRegister>(), 0);
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ RecordPcInfo(instruction, instruction->GetDexPc());
}
-void InstructionCodeGeneratorMIPS64::GenerateExplicitNullCheck(HNullCheck* instruction) {
+void CodeGeneratorMIPS64::GenerateExplicitNullCheck(HNullCheck* instruction) {
SlowPathCodeMIPS64* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathMIPS64(instruction);
- codegen_->AddSlowPath(slow_path);
+ AddSlowPath(slow_path);
Location obj = instruction->GetLocations()->InAt(0);
@@ -3570,11 +3570,7 @@
}
void InstructionCodeGeneratorMIPS64::VisitNullCheck(HNullCheck* instruction) {
- if (codegen_->IsImplicitNullCheckAllowed(instruction)) {
- GenerateImplicitNullCheck(instruction);
- } else {
- GenerateExplicitNullCheck(instruction);
- }
+ codegen_->GenerateNullCheck(instruction);
}
void LocationsBuilderMIPS64::VisitOr(HOr* instruction) {
diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h
index ba9eaff..9464a14 100644
--- a/compiler/optimizing/code_generator_mips64.h
+++ b/compiler/optimizing/code_generator_mips64.h
@@ -228,8 +228,6 @@
const FieldInfo& field_info,
bool value_can_be_null);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
void GenerateTestAndBranch(HInstruction* instruction,
size_t condition_input_index,
Mips64Label* true_target,
@@ -354,6 +352,8 @@
}
void GenerateNop();
+ void GenerateImplicitNullCheck(HNullCheck* instruction);
+ void GenerateExplicitNullCheck(HNullCheck* instruction);
private:
// Labels for each block that will be compiled.
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 6b4a18c..fce9df4 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -4971,20 +4971,20 @@
}
}
-void InstructionCodeGeneratorX86::GenerateImplicitNullCheck(HNullCheck* instruction) {
- if (codegen_->CanMoveNullCheckToUser(instruction)) {
+void CodeGeneratorX86::GenerateImplicitNullCheck(HNullCheck* instruction) {
+ if (CanMoveNullCheckToUser(instruction)) {
return;
}
LocationSummary* locations = instruction->GetLocations();
Location obj = locations->InAt(0);
__ testl(EAX, Address(obj.AsRegister<Register>(), 0));
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ RecordPcInfo(instruction, instruction->GetDexPc());
}
-void InstructionCodeGeneratorX86::GenerateExplicitNullCheck(HNullCheck* instruction) {
+void CodeGeneratorX86::GenerateExplicitNullCheck(HNullCheck* instruction) {
SlowPathCode* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathX86(instruction);
- codegen_->AddSlowPath(slow_path);
+ AddSlowPath(slow_path);
LocationSummary* locations = instruction->GetLocations();
Location obj = locations->InAt(0);
@@ -5003,11 +5003,7 @@
}
void InstructionCodeGeneratorX86::VisitNullCheck(HNullCheck* instruction) {
- if (codegen_->IsImplicitNullCheckAllowed(instruction)) {
- GenerateImplicitNullCheck(instruction);
- } else {
- GenerateExplicitNullCheck(instruction);
- }
+ codegen_->GenerateNullCheck(instruction);
}
void LocationsBuilderX86::VisitArrayGet(HArrayGet* instruction) {
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index 0795f3b..c397899 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -271,8 +271,6 @@
void PushOntoFPStack(Location source, uint32_t temp_offset,
uint32_t stack_adjustment, bool is_fp, bool is_wide);
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
template<class LabelType>
void GenerateTestAndBranch(HInstruction* instruction,
size_t condition_input_index,
@@ -541,6 +539,8 @@
}
void GenerateNop();
+ void GenerateImplicitNullCheck(HNullCheck* instruction);
+ void GenerateExplicitNullCheck(HNullCheck* instruction);
private:
// Factored implementation of GenerateFieldLoadWithBakerReadBarrier
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index c132663..06cc668 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -4487,20 +4487,20 @@
}
}
-void InstructionCodeGeneratorX86_64::GenerateImplicitNullCheck(HNullCheck* instruction) {
- if (codegen_->CanMoveNullCheckToUser(instruction)) {
+void CodeGeneratorX86_64::GenerateImplicitNullCheck(HNullCheck* instruction) {
+ if (CanMoveNullCheckToUser(instruction)) {
return;
}
LocationSummary* locations = instruction->GetLocations();
Location obj = locations->InAt(0);
__ testl(CpuRegister(RAX), Address(obj.AsRegister<CpuRegister>(), 0));
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ RecordPcInfo(instruction, instruction->GetDexPc());
}
-void InstructionCodeGeneratorX86_64::GenerateExplicitNullCheck(HNullCheck* instruction) {
+void CodeGeneratorX86_64::GenerateExplicitNullCheck(HNullCheck* instruction) {
SlowPathCode* slow_path = new (GetGraph()->GetArena()) NullCheckSlowPathX86_64(instruction);
- codegen_->AddSlowPath(slow_path);
+ AddSlowPath(slow_path);
LocationSummary* locations = instruction->GetLocations();
Location obj = locations->InAt(0);
@@ -4519,11 +4519,7 @@
}
void InstructionCodeGeneratorX86_64::VisitNullCheck(HNullCheck* instruction) {
- if (codegen_->IsImplicitNullCheckAllowed(instruction)) {
- GenerateImplicitNullCheck(instruction);
- } else {
- GenerateExplicitNullCheck(instruction);
- }
+ codegen_->GenerateNullCheck(instruction);
}
void LocationsBuilderX86_64::VisitArrayGet(HArrayGet* instruction) {
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index b3d27e1..c3fce6e 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -260,8 +260,6 @@
CpuRegister obj,
uint32_t offset);
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
void PushOntoFPStack(Location source, uint32_t temp_offset,
uint32_t stack_adjustment, bool is_float);
void GenerateCompareTest(HCondition* condition);
@@ -514,6 +512,8 @@
}
void GenerateNop();
+ void GenerateImplicitNullCheck(HNullCheck* instruction);
+ void GenerateExplicitNullCheck(HNullCheck* instruction);
private:
// Factored implementation of GenerateFieldLoadWithBakerReadBarrier
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 7a82063..a9cb1cc 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -697,7 +697,8 @@
CodeGenerator::Create(graph,
instruction_set,
*compiler_driver->GetInstructionSetFeatures(),
- compiler_driver->GetCompilerOptions()));
+ compiler_driver->GetCompilerOptions(),
+ compilation_stats_.get()));
if (codegen.get() == nullptr) {
MaybeRecordStat(MethodCompilationStat::kNotCompiledNoCodegen);
return nullptr;
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index ecbe371..3717926 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -62,6 +62,8 @@
kSelectGenerated,
kRemovedInstanceOf,
kInlinedInvokeVirtualOrInterface,
+ kImplicitNullCheckGenerated,
+ kExplicitNullCheckGenerated,
kLastStat
};
@@ -137,6 +139,8 @@
case kSelectGenerated : name = "SelectGenerated"; break;
case kRemovedInstanceOf: name = "RemovedInstanceOf"; break;
case kInlinedInvokeVirtualOrInterface: name = "InlinedInvokeVirtualOrInterface"; break;
+ case kImplicitNullCheckGenerated: name = "ImplicitNullCheckGenerated"; break;
+ case kExplicitNullCheckGenerated: name = "ExplicitNullCheckGenerated"; break;
case kLastStat:
LOG(FATAL) << "invalid stat "