diff options
author | 2018-01-23 00:32:35 +0000 | |
---|---|---|
committer | 2018-01-23 00:32:35 +0000 | |
commit | d78ca5213b780ca3165acb68e44f88f639e8ca45 (patch) | |
tree | 02cea569c648b488483250cffd330c9c2bc95bc3 | |
parent | 8105dad6cb540f6521d25507ae3e70718bc7a264 (diff) | |
parent | a95a5cc888e61e3a2ae7abecc00be770c6297267 (diff) |
Merge "Improve bound analysis on constant range."
-rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 20 | ||||
-rw-r--r-- | test/449-checker-bce/src/Main.java | 40 |
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!"); } } |