diff options
author | Mark Mendell <mark.p.mendell@intel.com> | 2015-04-22 16:18:52 -0400 |
---|---|---|
committer | Mark Mendell <mark.p.mendell@intel.com> | 2015-04-24 19:53:16 -0400 |
commit | 99dbd6883f5dab7743d5fb5d0ad2e82c75a7011e (patch) | |
tree | 21b307f551ec645aeefb848c7fb2d8b7f41c6e67 /compiler/optimizing/code_generator_x86.cc | |
parent | 76f1413492c228bfa710e1eaa4c60370eaffbb8a (diff) | |
download | art-99dbd6883f5dab7743d5fb5d0ad2e82c75a7011e.tar.gz art-99dbd6883f5dab7743d5fb5d0ad2e82c75a7011e.tar.bz2 art-99dbd6883f5dab7743d5fb5d0ad2e82c75a7011e.zip |
[optimizing] Handle x86 const length BoundsCheck
Allow a constant length for BoundsCheck.
Change-Id: I2c7adc6e733cf8ce6997aba76aa763d0835bd2d6
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
Diffstat (limited to 'compiler/optimizing/code_generator_x86.cc')
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 70e4440e7a..de68cfaf93 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -3815,7 +3815,7 @@ void LocationsBuilderX86::VisitBoundsCheck(HBoundsCheck* instruction) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall); locations->SetInAt(0, Location::RegisterOrConstant(instruction->InputAt(0))); - locations->SetInAt(1, Location::RequiresRegister()); + locations->SetInAt(1, Location::RegisterOrConstant(instruction->InputAt(1))); if (instruction->HasUses()) { locations->SetOut(Location::SameAsFirstInput()); } @@ -3827,16 +3827,38 @@ void InstructionCodeGeneratorX86::VisitBoundsCheck(HBoundsCheck* instruction) { Location length_loc = locations->InAt(1); SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) BoundsCheckSlowPathX86(instruction, index_loc, length_loc); - codegen_->AddSlowPath(slow_path); - Register length = length_loc.AsRegister<Register>(); - if (index_loc.IsConstant()) { - int32_t value = CodeGenerator::GetInt32ValueOf(index_loc.GetConstant()); - __ cmpl(length, Immediate(value)); + if (length_loc.IsConstant()) { + int32_t length = CodeGenerator::GetInt32ValueOf(length_loc.GetConstant()); + if (index_loc.IsConstant()) { + // BCE will remove the bounds check if we are guarenteed to pass. + int32_t index = CodeGenerator::GetInt32ValueOf(index_loc.GetConstant()); + if (index < 0 || index >= length) { + codegen_->AddSlowPath(slow_path); + __ jmp(slow_path->GetEntryLabel()); + } else { + // Some optimization after BCE may have generated this, and we should not + // generate a bounds check if it is a valid range. + } + return; + } + + // We have to reverse the jump condition because the length is the constant. + Register index_reg = index_loc.AsRegister<Register>(); + __ cmpl(index_reg, Immediate(length)); + codegen_->AddSlowPath(slow_path); + __ j(kAboveEqual, slow_path->GetEntryLabel()); } else { - __ cmpl(length, index_loc.AsRegister<Register>()); + Register length = length_loc.AsRegister<Register>(); + if (index_loc.IsConstant()) { + int32_t value = CodeGenerator::GetInt32ValueOf(index_loc.GetConstant()); + __ cmpl(length, Immediate(value)); + } else { + __ cmpl(length, index_loc.AsRegister<Register>()); + } + codegen_->AddSlowPath(slow_path); + __ j(kBelowEqual, slow_path->GetEntryLabel()); } - __ j(kBelowEqual, slow_path->GetEntryLabel()); } void LocationsBuilderX86::VisitTemporary(HTemporary* temp) { |