summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/code_generator_mips.cc33
-rw-r--r--compiler/optimizing/code_generator_x86.cc5
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc5
-rw-r--r--compiler/optimizing/loop_optimization.cc27
4 files changed, 50 insertions, 20 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index e58f43e1bb..56df6b5289 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -7677,7 +7677,9 @@ void LocationsBuilderMIPS::VisitLoadClass(HLoadClass* cls) {
break;
}
if (has_irreducible_loops) {
- codegen_->ClobberRA();
+ if (load_kind != HLoadClass::LoadKind::kBootImageAddress) {
+ codegen_->ClobberRA();
+ }
break;
}
FALLTHROUGH_INTENDED;
@@ -7894,7 +7896,9 @@ void LocationsBuilderMIPS::VisitLoadString(HLoadString* load) {
break;
}
if (has_irreducible_loops) {
- codegen_->ClobberRA();
+ if (load_kind != HLoadString::LoadKind::kBootImageAddress) {
+ codegen_->ClobberRA();
+ }
break;
}
FALLTHROUGH_INTENDED;
@@ -9026,6 +9030,15 @@ void LocationsBuilderMIPS::VisitPackedSwitch(HPackedSwitch* switch_instr) {
LocationSummary* locations =
new (GetGraph()->GetAllocator()) LocationSummary(switch_instr, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
+ if (!codegen_->GetInstructionSetFeatures().IsR6()) {
+ uint32_t num_entries = switch_instr->GetNumEntries();
+ if (num_entries > InstructionCodeGeneratorMIPS::kPackedSwitchJumpTableThreshold) {
+ // When there's no HMipsComputeBaseMethodAddress input, R2 uses the NAL
+ // instruction to simulate PC-relative addressing when accessing the jump table.
+ // NAL clobbers RA. Make sure RA is preserved.
+ codegen_->ClobberRA();
+ }
+ }
}
void InstructionCodeGeneratorMIPS::GenPackedSwitchWithCompares(Register value_reg,
@@ -9109,13 +9122,17 @@ void InstructionCodeGeneratorMIPS::VisitPackedSwitch(HPackedSwitch* switch_instr
HBasicBlock* switch_block = switch_instr->GetBlock();
HBasicBlock* default_block = switch_instr->GetDefaultBlock();
- if (codegen_->GetInstructionSetFeatures().IsR6() &&
- num_entries > kPackedSwitchJumpTableThreshold) {
+ if (num_entries > kPackedSwitchJumpTableThreshold) {
// R6 uses PC-relative addressing to access the jump table.
- // R2, OTOH, requires an HMipsComputeBaseMethodAddress input to access
- // the jump table and it is implemented by changing HPackedSwitch to
- // HMipsPackedSwitch, which bears HMipsComputeBaseMethodAddress.
- // See VisitMipsPackedSwitch() for the table-based implementation on R2.
+ //
+ // R2, OTOH, uses an HMipsComputeBaseMethodAddress input (when available)
+ // to access the jump table and it is implemented by changing HPackedSwitch to
+ // HMipsPackedSwitch, which bears HMipsComputeBaseMethodAddress (see
+ // VisitMipsPackedSwitch()).
+ //
+ // When there's no HMipsComputeBaseMethodAddress input (e.g. in presence of
+ // irreducible loops), R2 uses the NAL instruction to simulate PC-relative
+ // addressing.
GenTableBasedPackedSwitch(value_reg,
ZERO,
lower_bound,
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 39a07b82d1..828e7ffd1d 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -144,7 +144,8 @@ class BoundsCheckSlowPathX86 : public SlowPathCode {
InvokeRuntimeCallingConvention calling_convention;
if (array_length->IsArrayLength() && array_length->IsEmittedAtUseSite()) {
// Load the array length into our temporary.
- uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(array_length->AsArrayLength());
+ HArrayLength* length = array_length->AsArrayLength();
+ uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(length);
Location array_loc = array_length->GetLocations()->InAt(0);
Address array_len(array_loc.AsRegister<Register>(), len_offset);
length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(1));
@@ -154,7 +155,7 @@ class BoundsCheckSlowPathX86 : public SlowPathCode {
length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(2));
}
__ movl(length_loc.AsRegister<Register>(), array_len);
- if (mirror::kUseStringCompression) {
+ if (mirror::kUseStringCompression && length->IsStringLength()) {
__ shrl(length_loc.AsRegister<Register>(), Immediate(1));
}
}
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index c8032c25df..6de5e9cd4d 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -195,7 +195,8 @@ class BoundsCheckSlowPathX86_64 : public SlowPathCode {
InvokeRuntimeCallingConvention calling_convention;
if (array_length->IsArrayLength() && array_length->IsEmittedAtUseSite()) {
// Load the array length into our temporary.
- uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(array_length->AsArrayLength());
+ HArrayLength* length = array_length->AsArrayLength();
+ uint32_t len_offset = CodeGenerator::GetArrayLengthOffset(length);
Location array_loc = array_length->GetLocations()->InAt(0);
Address array_len(array_loc.AsRegister<CpuRegister>(), len_offset);
length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(1));
@@ -205,7 +206,7 @@ class BoundsCheckSlowPathX86_64 : public SlowPathCode {
length_loc = Location::RegisterLocation(calling_convention.GetRegisterAt(2));
}
__ movl(length_loc.AsRegister<CpuRegister>(), array_len);
- if (mirror::kUseStringCompression) {
+ if (mirror::kUseStringCompression && length->IsStringLength()) {
__ shrl(length_loc.AsRegister<CpuRegister>(), Immediate(1));
}
}
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 645915e2f8..69c6b94c6b 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -1623,17 +1623,28 @@ void HLoopOptimization::GenerateVecReductionPhiInputs(HPhi* phi, HInstruction* r
}
// Prepare the new initialization.
if (vector_mode_ == kVector) {
- // Generate a [initial, 0, .., 0] vector.
+ // Generate a [initial, 0, .., 0] vector for add or
+ // a [initial, initial, .., initial] vector for min/max.
HVecOperation* red_vector = new_red->AsVecOperation();
+ HVecReduce::ReductionKind kind = GetReductionKind(red_vector);
size_t vector_length = red_vector->GetVectorLength();
DataType::Type type = red_vector->GetPackedType();
- new_init = Insert(vector_preheader_,
- new (global_allocator_) HVecSetScalars(global_allocator_,
- &new_init,
- type,
- vector_length,
- 1,
- kNoDexPc));
+ if (kind == HVecReduce::ReductionKind::kSum) {
+ new_init = Insert(vector_preheader_,
+ new (global_allocator_) HVecSetScalars(global_allocator_,
+ &new_init,
+ type,
+ vector_length,
+ 1,
+ kNoDexPc));
+ } else {
+ new_init = Insert(vector_preheader_,
+ new (global_allocator_) HVecReplicateScalar(global_allocator_,
+ new_init,
+ type,
+ vector_length,
+ kNoDexPc));
+ }
} else {
new_init = ReduceAndExtractIfNeeded(new_init);
}