diff options
author | Alexey Frunze <Alexey.Frunze@imgtec.com> | 2017-10-10 23:01:34 -0700 |
---|---|---|
committer | Alexey Frunze <Alexey.Frunze@imgtec.com> | 2017-10-16 17:06:21 -0700 |
commit | 3b8c82f4864624da8a1efd09f02bfec754413a20 (patch) | |
tree | 175a5835f4f62f539b5ae457a9e62ec3dcb91d13 /compiler/optimizing/code_generator_mips.cc | |
parent | 26d46e51a8c387d26e7971857e26f4582b936204 (diff) |
MIPS32R2: Enable table-based switch in presence of irreducible loops
Test: test-art-host-gtest
Test: booted MIPS32R2 in QEMU
Test: testrunner.py --target --optimizing --32
Test: repeat all of the above with suppressed generation
of HMipsPackedSwitch
Change-Id: Ic8a27d88cd2d7eebaf5826ce8fd1a5607a024844
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 33 |
1 files changed, 25 insertions, 8 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, |