diff options
| author | 2016-05-04 22:55:43 +0000 | |
|---|---|---|
| committer | 2016-05-04 22:55:43 +0000 | |
| commit | 861c135cec1cb4943e075d49719c86a36c03de1b (patch) | |
| tree | 9b07a9a999c0fff883163b06e4eb0a92ede376fd | |
| parent | f5d1fbe2893803b22d57121ce80a7f44f484a438 (diff) | |
| parent | a210689f1a0e7839f5b3589fd57583e6ae20ded0 (diff) | |
Merge "Exploit NE/EQ tests on array length in BCE."
| -rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 29 | ||||
| -rw-r--r-- | test/449-checker-bce/src/Main.java | 46 | ||||
| -rw-r--r-- | test/530-checker-loops2/src/Main.java | 14 |
3 files changed, 75 insertions, 14 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc index b65e98a120..6c6e5af0b2 100644 --- a/compiler/optimizing/bounds_check_elimination.cc +++ b/compiler/optimizing/bounds_check_elimination.cc @@ -800,6 +800,27 @@ class BCEVisitor : public HGraphVisitor { ValueRange(GetGraph()->GetArena(), ValueBound::Min(), new_upper); ApplyRangeFromComparison(left, block, false_successor, new_range); } + } else if (cond == kCondNE || cond == kCondEQ) { + if (left->IsArrayLength() && lower.IsConstant() && upper.IsConstant()) { + // Special case: + // length == [c,d] yields [c, d] along true + // length != [c,d] yields [c, d] along false + if (!lower.Equals(ValueBound::Min()) || !upper.Equals(ValueBound::Max())) { + ValueRange* new_range = new (GetGraph()->GetArena()) + ValueRange(GetGraph()->GetArena(), lower, upper); + ApplyRangeFromComparison( + left, block, cond == kCondEQ ? true_successor : false_successor, new_range); + } + // In addition: + // length == 0 yields [1, max] along false + // length != 0 yields [1, max] along true + if (lower.GetConstant() == 0 && upper.GetConstant() == 0) { + ValueRange* new_range = new (GetGraph()->GetArena()) + ValueRange(GetGraph()->GetArena(), ValueBound(nullptr, 1), ValueBound::Max()); + ApplyRangeFromComparison( + left, block, cond == kCondEQ ? false_successor : true_successor, new_range); + } + } } } @@ -955,13 +976,7 @@ class BCEVisitor : public HGraphVisitor { void VisitIf(HIf* instruction) OVERRIDE { if (instruction->InputAt(0)->IsCondition()) { HCondition* cond = instruction->InputAt(0)->AsCondition(); - IfCondition cmp = cond->GetCondition(); - if (cmp == kCondGT || cmp == kCondGE || - cmp == kCondLT || cmp == kCondLE) { - HInstruction* left = cond->GetLeft(); - HInstruction* right = cond->GetRight(); - HandleIf(instruction, left, right, cmp); - } + HandleIf(instruction, cond->GetLeft(), cond->GetRight(), cond->GetCondition()); } } diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java index 66e1d92cc2..41771b52c4 100644 --- a/test/449-checker-bce/src/Main.java +++ b/test/449-checker-bce/src/Main.java @@ -927,6 +927,32 @@ public class Main { } } + /// CHECK-START: void Main.nonzeroLength(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.nonzeroLength(int[]) BCE (after) + /// CHECK-NOT: BoundsCheck + /// CHECK-NOT: Deoptimize + public static void nonzeroLength(int[] a) { + if (a.length != 0) { + a[0] = 112; + } + } + + /// CHECK-START: void Main.knownLength(int[]) BCE (before) + /// CHECK-DAG: BoundsCheck + /// CHECK-DAG: BoundsCheck + // + /// CHECK-START: void Main.knownLength(int[]) BCE (after) + /// CHECK-NOT: BoundsCheck + /// CHECK-NOT: Deoptimize + public static void knownLength(int[] a) { + if (a.length == 2) { + a[0] = -1; + a[1] = -2; + } + } + static int[][] mA; /// CHECK-START: void Main.dynamicBCEAndIntrinsic(int) BCE (before) @@ -1586,6 +1612,26 @@ public class Main { } } + nonzeroLength(array); + if (array[0] != 112) { + System.out.println("nonzero length failed!"); + } + + knownLength(array); + if (array[0] != 112 || array[1] != 1) { + System.out.println("nonzero length failed!"); + } + array = new int[2]; + knownLength(array); + if (array[0] != -1 || array[1] != -2) { + System.out.println("nonzero length failed!"); + } + + // Zero length array does not break. + array = new int[0]; + nonzeroLength(array); + knownLength(array); + mA = new int[4][4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { diff --git a/test/530-checker-loops2/src/Main.java b/test/530-checker-loops2/src/Main.java index c644692f03..b12fbd6091 100644 --- a/test/530-checker-loops2/src/Main.java +++ b/test/530-checker-loops2/src/Main.java @@ -710,8 +710,8 @@ public class Main { // making them a candidate for deoptimization based on constant indices. // Compiler should ensure the array loads are not subsequently hoisted // "above" the deoptimization "barrier" on the bounds. - a[0][i] = 1; - a[1][i] = 2; + a[1][i] = 1; + a[2][i] = 2; a[99][i] = 3; } } @@ -1042,11 +1042,11 @@ public class Main { a = new int[100][10]; expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10)); for (int i = 0; i < 10; i++) { - expectEquals((i % 10) != 0 ? 1 : 0, a[0][i]); - expectEquals((i % 10) != 0 ? 2 : 0, a[1][i]); + expectEquals((i % 10) != 0 ? 1 : 0, a[1][i]); + expectEquals((i % 10) != 0 ? 2 : 0, a[2][i]); expectEquals((i % 10) != 0 ? 3 : 0, a[99][i]); } - a = new int[2][10]; + a = new int[3][10]; sResult = 0; try { expectEquals(55, dynamicBCEAndConstantIndices(x, a, 0, 10)); @@ -1054,8 +1054,8 @@ public class Main { sResult = 1; } expectEquals(1, sResult); - expectEquals(a[0][1], 1); - expectEquals(a[1][1], 2); + expectEquals(a[1][1], 1); + expectEquals(a[2][1], 2); // Dynamic BCE combined with constant indices of all types. boolean[] x1 = { true }; |