summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Aart Bik <ajcbik@google.com> 2018-01-23 00:32:35 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2018-01-23 00:32:35 +0000
commitd78ca5213b780ca3165acb68e44f88f639e8ca45 (patch)
tree02cea569c648b488483250cffd330c9c2bc95bc3
parent8105dad6cb540f6521d25507ae3e70718bc7a264 (diff)
parenta95a5cc888e61e3a2ae7abecc00be770c6297267 (diff)
Merge "Improve bound analysis on constant range."
-rw-r--r--compiler/optimizing/bounds_check_elimination.cc20
-rw-r--r--test/449-checker-bce/src/Main.java40
2 files changed, 54 insertions, 6 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 147df1e3e8..d893cc88c4 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -836,9 +836,23 @@ class BCEVisitor : public HGraphVisitor {
ValueRange array_range(&allocator_, lower, upper);
// Try index range obtained by dominator-based analysis.
ValueRange* index_range = LookupValueRange(index, block);
- if (index_range != nullptr && index_range->FitsIn(&array_range)) {
- ReplaceInstruction(bounds_check, index);
- return;
+ if (index_range != nullptr) {
+ if (index_range->FitsIn(&array_range)) {
+ ReplaceInstruction(bounds_check, index);
+ return;
+ } else if (index_range->IsConstantValueRange()) {
+ // If the non-constant index turns out to have a constant range,
+ // make one more attempt to get a constant in the array range.
+ ValueRange* existing_range = LookupValueRange(array_length, block);
+ if (existing_range != nullptr &&
+ existing_range->IsConstantValueRange()) {
+ ValueRange constant_array_range(&allocator_, lower, existing_range->GetLower());
+ if (index_range->FitsIn(&constant_array_range)) {
+ ReplaceInstruction(bounds_check, index);
+ return;
+ }
+ }
+ }
}
// Try index range obtained by induction variable analysis.
// Disables dynamic bce if OOB is certain.
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index 3506649d3c..4868355b90 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -1068,6 +1068,7 @@ public class Main {
//
/// CHECK-START: void Main.lengthAlias1(int[], int) BCE (after)
/// CHECK-NOT: BoundsCheck
+ /// CHECK-NOT: Deoptimize
public static void lengthAlias1(int[] a, int len) {
if (len == a.length) {
for (int i = 0; i < len; i++) {
@@ -1087,6 +1088,7 @@ public class Main {
//
/// CHECK-START: void Main.lengthAlias2(int[], int) BCE (after)
/// CHECK-NOT: BoundsCheck
+ /// CHECK-NOT: Deoptimize
public static void lengthAlias2(int[] a, int len) {
if (len != a.length) {
return;
@@ -1107,6 +1109,7 @@ public class Main {
//
/// CHECK-START: void Main.lengthAlias3(int[], int) BCE (after)
/// CHECK-NOT: BoundsCheck
+ /// CHECK-NOT: Deoptimize
public static void lengthAlias3(int[] a, int len) {
if (a.length == len) {
for (int i = 0; i < len; i++) {
@@ -1115,6 +1118,27 @@ public class Main {
}
}
+ /// CHECK-START: void Main.lengthAlias4(int[]) BCE (before)
+ /// CHECK-DAG: <<Arr:l\d+>> ParameterValue loop:none
+ /// CHECK-DAG: <<Val:i\d+>> IntConstant 8 loop:none
+ /// CHECK-DAG: <<Nul:l\d+>> NullCheck [<<Arr>>] loop:none
+ /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>] loop:none
+ /// CHECK-DAG: Equal [<<Len>>,<<Val>>] loop:none
+ /// CHECK-DAG: <<Idx:i\d+>> Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>>
+ //
+ /// CHECK-START: void Main.lengthAlias4(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK-NOT: Deoptimize
+ public static void lengthAlias4(int[] a) {
+ if (8 != a.length) {
+ return;
+ }
+ for (int i = 0; i < 8; i++) {
+ a[i] = 4;
+ }
+ }
+
static int[][] mA;
/// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before)
@@ -1824,10 +1848,20 @@ public class Main {
System.out.println("alias3 failed!");
}
}
-
- lengthAlias1(array, /*mismatched value*/ 32);
+ lengthAlias4(array);
for (int i = 0; i < 8; i++) {
- if (array[i] != 3) {
+ if (array[i] != 4) {
+ System.out.println("alias4 failed!");
+ }
+ }
+
+ array = new int[10];
+ lengthAlias1(array, /*mismatched value*/ 8);
+ lengthAlias2(array, /*mismatched value*/ 8);
+ lengthAlias3(array, /*mismatched value*/ 8);
+ lengthAlias4(array); // implicit mismatch
+ for (int i = 0; i < 10; i++) {
+ if (array[i] != 0) {
System.out.println("mismatch failed!");
}
}