summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_mips.cc
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2017-09-21 21:29:42 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-09-21 21:29:42 +0000
commit994cfb3d1595e28b61b8831264c5fc0ebdb6d156 (patch)
tree701912858cd2e6cca5bae653fcab37d9afb2e0c2 /compiler/optimizing/code_generator_mips.cc
parent478abf08c6d2a95eef12e78d3b12857917a91872 (diff)
parentdebb510e34b844cc6d80d0304db34c7530fbaf44 (diff)
Merge "MIPS32R2: Allow all kinds of class/string loads and invokes"
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r--compiler/optimizing/code_generator_mips.cc107
1 files changed, 45 insertions, 62 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 8ada76a053..0e6d210f10 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -291,7 +291,9 @@ class LoadClassSlowPathMIPS : public SlowPathCodeMIPS {
// For non-Baker read barriers we need to re-calculate the address of
// the class entry.
const bool isR6 = mips_codegen->GetInstructionSetFeatures().IsR6();
- Register base = isR6 ? ZERO : locations->InAt(0).AsRegister<Register>();
+ const bool has_irreducible_loops = codegen->GetGraph()->HasIrreducibleLoops();
+ Register base =
+ (isR6 || has_irreducible_loops) ? ZERO : locations->InAt(0).AsRegister<Register>();
CodeGeneratorMIPS::PcRelativePatchInfo* info_high =
mips_codegen->NewTypeBssEntryPatch(cls_->GetDexFile(), type_index);
CodeGeneratorMIPS::PcRelativePatchInfo* info_low =
@@ -381,7 +383,9 @@ class LoadStringSlowPathMIPS : public SlowPathCodeMIPS {
// For non-Baker read barriers we need to re-calculate the address of
// the string entry.
const bool isR6 = mips_codegen->GetInstructionSetFeatures().IsR6();
- Register base = isR6 ? ZERO : locations->InAt(0).AsRegister<Register>();
+ const bool has_irreducible_loops = codegen->GetGraph()->HasIrreducibleLoops();
+ Register base =
+ (isR6 || has_irreducible_loops) ? ZERO : locations->InAt(0).AsRegister<Register>();
CodeGeneratorMIPS::PcRelativePatchInfo* info_high =
mips_codegen->NewStringBssEntryPatch(load->GetDexFile(), string_index);
CodeGeneratorMIPS::PcRelativePatchInfo* info_low =
@@ -7333,7 +7337,8 @@ void LocationsBuilderMIPS::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invo
DCHECK(!invoke->IsStaticWithExplicitClinitCheck());
bool is_r6 = codegen_->GetInstructionSetFeatures().IsR6();
- bool has_extra_input = invoke->HasPcRelativeMethodLoadKind() && !is_r6;
+ bool has_irreducible_loops = codegen_->GetGraph()->HasIrreducibleLoops();
+ bool has_extra_input = invoke->HasPcRelativeMethodLoadKind() && !is_r6 && !has_irreducible_loops;
IntrinsicLocationsBuilderMIPS intrinsic(codegen_);
if (intrinsic.TryDispatch(invoke)) {
@@ -7371,75 +7376,49 @@ static bool TryGenerateIntrinsicCode(HInvoke* invoke, CodeGeneratorMIPS* codegen
HLoadString::LoadKind CodeGeneratorMIPS::GetSupportedLoadStringKind(
HLoadString::LoadKind desired_string_load_kind) {
- // We disable PC-relative load on pre-R6 when there is an irreducible loop, as the optimization
- // is incompatible with it.
- // TODO: Create as many HMipsComputeBaseMethodAddress instructions as needed for methods
- // with irreducible loops.
- bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops();
- bool is_r6 = GetInstructionSetFeatures().IsR6();
- bool fallback_load = has_irreducible_loops && !is_r6;
switch (desired_string_load_kind) {
case HLoadString::LoadKind::kBootImageLinkTimePcRelative:
case HLoadString::LoadKind::kBootImageInternTable:
case HLoadString::LoadKind::kBssEntry:
DCHECK(!Runtime::Current()->UseJitCompilation());
break;
- case HLoadString::LoadKind::kBootImageAddress:
- break;
case HLoadString::LoadKind::kJitTableAddress:
DCHECK(Runtime::Current()->UseJitCompilation());
- fallback_load = false;
break;
+ case HLoadString::LoadKind::kBootImageAddress:
case HLoadString::LoadKind::kRuntimeCall:
- fallback_load = false;
break;
}
- if (fallback_load) {
- desired_string_load_kind = HLoadString::LoadKind::kRuntimeCall;
- }
return desired_string_load_kind;
}
HLoadClass::LoadKind CodeGeneratorMIPS::GetSupportedLoadClassKind(
HLoadClass::LoadKind desired_class_load_kind) {
- // We disable PC-relative load on pre-R6 when there is an irreducible loop, as the optimization
- // is incompatible with it.
- // TODO: Create as many HMipsComputeBaseMethodAddress instructions as needed for methods
- // with irreducible loops.
- bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops();
- bool is_r6 = GetInstructionSetFeatures().IsR6();
- bool fallback_load = has_irreducible_loops && !is_r6;
switch (desired_class_load_kind) {
case HLoadClass::LoadKind::kInvalid:
LOG(FATAL) << "UNREACHABLE";
UNREACHABLE();
case HLoadClass::LoadKind::kReferrersClass:
- fallback_load = false;
break;
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageClassTable:
case HLoadClass::LoadKind::kBssEntry:
DCHECK(!Runtime::Current()->UseJitCompilation());
break;
- case HLoadClass::LoadKind::kBootImageAddress:
- break;
case HLoadClass::LoadKind::kJitTableAddress:
DCHECK(Runtime::Current()->UseJitCompilation());
- fallback_load = false;
break;
+ case HLoadClass::LoadKind::kBootImageAddress:
case HLoadClass::LoadKind::kRuntimeCall:
- fallback_load = false;
break;
}
- if (fallback_load) {
- desired_class_load_kind = HLoadClass::LoadKind::kRuntimeCall;
- }
return desired_class_load_kind;
}
Register CodeGeneratorMIPS::GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke,
Register temp) {
CHECK(!GetInstructionSetFeatures().IsR6());
+ CHECK(!GetGraph()->HasIrreducibleLoops());
CHECK_EQ(invoke->InputCount(), invoke->GetNumberOfArguments() + 1u);
Location location = invoke->GetLocations()->InAt(invoke->GetSpecialInputIndex());
if (!invoke->GetLocations()->Intrinsified()) {
@@ -7467,27 +7446,7 @@ Register CodeGeneratorMIPS::GetInvokeStaticOrDirectExtraParameter(HInvokeStaticO
HInvokeStaticOrDirect::DispatchInfo CodeGeneratorMIPS::GetSupportedInvokeStaticOrDirectDispatch(
const HInvokeStaticOrDirect::DispatchInfo& desired_dispatch_info,
HInvokeStaticOrDirect* invoke ATTRIBUTE_UNUSED) {
- HInvokeStaticOrDirect::DispatchInfo dispatch_info = desired_dispatch_info;
- // We disable PC-relative load on pre-R6 when there is an irreducible loop, as the optimization
- // is incompatible with it.
- // TODO: Create as many HMipsComputeBaseMethodAddress instructions as needed for methods
- // with irreducible loops.
- bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops();
- bool is_r6 = GetInstructionSetFeatures().IsR6();
- bool fallback_load = has_irreducible_loops && !is_r6;
- switch (dispatch_info.method_load_kind) {
- case HInvokeStaticOrDirect::MethodLoadKind::kBootImageLinkTimePcRelative:
- case HInvokeStaticOrDirect::MethodLoadKind::kBssEntry:
- break;
- default:
- fallback_load = false;
- break;
- }
- if (fallback_load) {
- dispatch_info.method_load_kind = HInvokeStaticOrDirect::MethodLoadKind::kRuntimeCall;
- dispatch_info.method_load_data = 0;
- }
- return dispatch_info;
+ return desired_dispatch_info;
}
void CodeGeneratorMIPS::GenerateStaticOrDirectCall(
@@ -7497,7 +7456,8 @@ void CodeGeneratorMIPS::GenerateStaticOrDirectCall(
HInvokeStaticOrDirect::MethodLoadKind method_load_kind = invoke->GetMethodLoadKind();
HInvokeStaticOrDirect::CodePtrLocation code_ptr_location = invoke->GetCodePtrLocation();
bool is_r6 = GetInstructionSetFeatures().IsR6();
- Register base_reg = (invoke->HasPcRelativeMethodLoadKind() && !is_r6)
+ bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops();
+ Register base_reg = (invoke->HasPcRelativeMethodLoadKind() && !is_r6 && !has_irreducible_loops)
? GetInvokeStaticOrDirectExtraParameter(invoke, temp.AsRegister<Register>())
: ZERO;
@@ -7636,6 +7596,7 @@ void LocationsBuilderMIPS::VisitLoadClass(HLoadClass* cls) {
}
DCHECK(!cls->NeedsAccessCheck());
const bool isR6 = codegen_->GetInstructionSetFeatures().IsR6();
+ const bool has_irreducible_loops = codegen_->GetGraph()->HasIrreducibleLoops();
const bool requires_read_barrier = kEmitCompilerReadBarrier && !cls->IsInBootImage();
LocationSummary::CallKind call_kind = (cls->NeedsEnvironment() || requires_read_barrier)
? LocationSummary::kCallOnSlowPath
@@ -7653,6 +7614,10 @@ void LocationsBuilderMIPS::VisitLoadClass(HLoadClass* cls) {
if (isR6) {
break;
}
+ if (has_irreducible_loops) {
+ codegen_->ClobberRA();
+ break;
+ }
FALLTHROUGH_INTENDED;
case HLoadClass::LoadKind::kReferrersClass:
locations->SetInAt(0, Location::RequiresRegister());
@@ -7691,12 +7656,15 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAF
Register out = out_loc.AsRegister<Register>();
Register base_or_current_method_reg;
bool isR6 = codegen_->GetInstructionSetFeatures().IsR6();
+ bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops();
switch (load_kind) {
// We need an extra register for PC-relative literals on R2.
case HLoadClass::LoadKind::kBootImageLinkTimePcRelative:
case HLoadClass::LoadKind::kBootImageAddress:
+ case HLoadClass::LoadKind::kBootImageClassTable:
case HLoadClass::LoadKind::kBssEntry:
- base_or_current_method_reg = isR6 ? ZERO : locations->InAt(0).AsRegister<Register>();
+ base_or_current_method_reg =
+ (isR6 || has_irreducible_loops) ? ZERO : locations->InAt(0).AsRegister<Register>();
break;
case HLoadClass::LoadKind::kReferrersClass:
case HLoadClass::LoadKind::kRuntimeCall:
@@ -7742,9 +7710,13 @@ void InstructionCodeGeneratorMIPS::VisitLoadClass(HLoadClass* cls) NO_THREAD_SAF
uint32_t address = dchecked_integral_cast<uint32_t>(
reinterpret_cast<uintptr_t>(cls->GetClass().Get()));
DCHECK_NE(address, 0u);
- __ LoadLiteral(out,
- base_or_current_method_reg,
- codegen_->DeduplicateBootImageAddressLiteral(address));
+ if (isR6 || !has_irreducible_loops) {
+ __ LoadLiteral(out,
+ base_or_current_method_reg,
+ codegen_->DeduplicateBootImageAddressLiteral(address));
+ } else {
+ __ LoadConst32(out, address);
+ }
break;
}
case HLoadClass::LoadKind::kBootImageClassTable: {
@@ -7849,6 +7821,7 @@ void LocationsBuilderMIPS::VisitLoadString(HLoadString* load) {
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(load, call_kind);
HLoadString::LoadKind load_kind = load->GetLoadKind();
const bool isR6 = codegen_->GetInstructionSetFeatures().IsR6();
+ const bool has_irreducible_loops = codegen_->GetGraph()->HasIrreducibleLoops();
switch (load_kind) {
// We need an extra register for PC-relative literals on R2.
case HLoadString::LoadKind::kBootImageAddress:
@@ -7858,6 +7831,10 @@ void LocationsBuilderMIPS::VisitLoadString(HLoadString* load) {
if (isR6) {
break;
}
+ if (has_irreducible_loops) {
+ codegen_->ClobberRA();
+ break;
+ }
FALLTHROUGH_INTENDED;
// We need an extra register for PC-relative dex cache accesses.
case HLoadString::LoadKind::kRuntimeCall:
@@ -7896,13 +7873,15 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_
Register out = out_loc.AsRegister<Register>();
Register base_or_current_method_reg;
bool isR6 = codegen_->GetInstructionSetFeatures().IsR6();
+ bool has_irreducible_loops = GetGraph()->HasIrreducibleLoops();
switch (load_kind) {
// We need an extra register for PC-relative literals on R2.
case HLoadString::LoadKind::kBootImageAddress:
case HLoadString::LoadKind::kBootImageLinkTimePcRelative:
case HLoadString::LoadKind::kBootImageInternTable:
case HLoadString::LoadKind::kBssEntry:
- base_or_current_method_reg = isR6 ? ZERO : locations->InAt(0).AsRegister<Register>();
+ base_or_current_method_reg =
+ (isR6 || has_irreducible_loops) ? ZERO : locations->InAt(0).AsRegister<Register>();
break;
default:
base_or_current_method_reg = ZERO;
@@ -7926,9 +7905,13 @@ void InstructionCodeGeneratorMIPS::VisitLoadString(HLoadString* load) NO_THREAD_
uint32_t address = dchecked_integral_cast<uint32_t>(
reinterpret_cast<uintptr_t>(load->GetString().Get()));
DCHECK_NE(address, 0u);
- __ LoadLiteral(out,
- base_or_current_method_reg,
- codegen_->DeduplicateBootImageAddressLiteral(address));
+ if (isR6 || !has_irreducible_loops) {
+ __ LoadLiteral(out,
+ base_or_current_method_reg,
+ codegen_->DeduplicateBootImageAddressLiteral(address));
+ } else {
+ __ LoadConst32(out, address);
+ }
return;
}
case HLoadString::LoadKind::kBootImageInternTable: {