diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 33 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/loop_optimization.cc | 27 |
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); } |