summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMingyao Yang <mingyao@google.com>2015-02-27 14:43:53 -0800
committerMingyao Yang <mingyao@google.com>2015-03-02 15:45:08 -0800
commit4559f000b323b64e4bd179b72cfb788b30b25b23 (patch)
tree00728f44d761f8663bbadc51d6d6eb67c42465ff
parent1d8587fe1d98909b4949282f14c0334085fdc964 (diff)
downloadart-4559f000b323b64e4bd179b72cfb788b30b25b23.zip
art-4559f000b323b64e4bd179b72cfb788b30b25b23.tar.gz
art-4559f000b323b64e4bd179b72cfb788b30b25b23.tar.bz2
bce: handle a pattern for circular buffer
Change-Id: Ie54bdd7c044af58deea0d0addaaa8186cabf3532
-rw-r--r--compiler/optimizing/bounds_check_elimination.cc15
-rw-r--r--test/449-checker-bce/src/Main.java23
2 files changed, 38 insertions, 0 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 811a3bd..deaeb8e 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -823,6 +823,21 @@ class BCEVisitor : public HGraphVisitor {
FindAndHandlePartialArrayLength(ushr);
}
+ void VisitAnd(HAnd* instruction) {
+ if (instruction->GetRight()->IsIntConstant()) {
+ int32_t constant = instruction->GetRight()->AsIntConstant()->GetValue();
+ if (constant > 0) {
+ // constant serves as a mask so any number masked with it
+ // gets a [0, constant] value range.
+ ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
+ GetGraph()->GetArena(),
+ ValueBound(nullptr, 0),
+ ValueBound(nullptr, constant));
+ GetValueRangeMap(instruction->GetBlock())->Overwrite(instruction->GetId(), range);
+ }
+ }
+ }
+
void VisitNewArray(HNewArray* new_array) {
HInstruction* len = new_array->InputAt(0);
if (!len->IsIntConstant()) {
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index ad4092b..ebd5b0e 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -314,6 +314,29 @@ public class Main {
array[10] = 1; // Bounds check can't be eliminated.
}
+
+ static byte readData() {
+ return 1;
+ }
+
+ // CHECK-START: void Main.circularBufferProducer() BCE (before)
+ // CHECK: BoundsCheck
+ // CHECK: ArraySet
+
+ // CHECK-START: void Main.circularBufferProducer() BCE (after)
+ // CHECK-NOT: BoundsCheck
+ // CHECK: ArraySet
+
+ static void circularBufferProducer() {
+ byte[] array = new byte[4096];
+ int i = 0;
+ while (true) {
+ array[i & (array.length - 1)] = readData();
+ i++;
+ }
+ }
+
+
// CHECK-START: void Main.pyramid1(int[]) BCE (before)
// CHECK: BoundsCheck
// CHECK: ArraySet