summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_x86.cc
diff options
context:
space:
mode:
authorMark Mendell <mark.p.mendell@intel.com>2015-04-22 16:18:52 -0400
committerMark Mendell <mark.p.mendell@intel.com>2015-04-24 19:53:16 -0400
commit99dbd6883f5dab7743d5fb5d0ad2e82c75a7011e (patch)
tree21b307f551ec645aeefb848c7fb2d8b7f41c6e67 /compiler/optimizing/code_generator_x86.cc
parent76f1413492c228bfa710e1eaa4c60370eaffbb8a (diff)
downloadart-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.cc38
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) {