Revert^4 "Partial Load Store Elimination"
This reverts commit 791df7a161ecfa28eb69862a4bc285282463b960.
This unreverts commit fc1ce4e8be0d977e3d41699f5ec746d68f63c024.
This unreverts commit b8686ce4c93eba7192ed7ef89e7ffd9f3aa6cd07.
We incorrectly failed to include PredicatedInstanceFieldGet in a few
conditions, including a DCHECK. This caused tests to fail under the
read-barrier-table-lookup configuration.
Reason for revert: Fixed 2 incorrect checks
Bug: 67037140
Test: ./art/test/testrunner/run_build_test_target.py -j70 art-gtest-read-barrier-table-lookup
Change-Id: I32b01b29fb32077fb5074e7c77a0226bd1fcaab4
diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java
index f250aa5..a303782 100644
--- a/test/530-checker-lse/src/Main.java
+++ b/test/530-checker-lse/src/Main.java
@@ -64,6 +64,20 @@
boolean test1 = true;
}
+// Chosen to have different values with (x + 1) * 10 and (x - 1) * 10. This
+// means we can easily make sure that different code is in fact executed on
+// escape and non-escape paths.
+// Negative so that high-bits will be set for all the 64-bit values allowing us
+// to easily check for truncation.
+class TestClass4 {
+ float floatField = -3.0f;
+ double doubleField = -3.0d;
+ short shortField = -3;
+ int intField = -3;
+ byte byteField = -3;
+ long longField = -3l;
+}
+
class Finalizable {
static boolean sVisited = false;
static final int VALUE1 = 0xbeef;
@@ -83,9 +97,20 @@
}
public class Main {
+ static void $noinline$Escape4(TestClass4 o) {
+ o.floatField += 1.0f;
+ o.doubleField += 1.0d;
+ o.byteField += 1;
+ o.shortField += 1;
+ o.intField += 1;
+ o.longField += 1;
+ }
static Object ESCAPE = null;
static void $noinline$Escape(TestClass o) {
+ if (o == null) {
+ return;
+ }
ESCAPE = o;
o.next.i++;
}
@@ -3792,6 +3817,248 @@
return res;
}
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (before)
+ /// CHECK-DAG: ParameterValue
+ /// CHECK-DAG: NewInstance
+ /// CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-DAG: InstanceFieldSet
+ /// CHECK-DAG: InstanceFieldSet
+ /// CHECK-DAG: InstanceFieldSet
+ /// CHECK-DAG: InstanceFieldGet
+ /// CHECK-DAG: InstanceFieldGet
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+ /// CHECK-DAG: ParameterValue
+ /// CHECK-DAG: NewInstance
+ /// CHECK-DAG: Phi
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+ /// CHECK: InvokeStaticOrDirect
+ /// CHECK: InvokeStaticOrDirect
+ /// CHECK: InvokeStaticOrDirect
+ //
+ /// CHECK-NOT: InvokeStaticOrDirect
+
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:false
+ /// CHECK-NOT: InstanceFieldSet predicated:false
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldGet
+ //
+ /// CHECK-NOT: InstanceFieldGet
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape2(TestClass, boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ //
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static int $noinline$testPartialEscape2(TestClass obj, boolean escape) {
+ TestClass i = new SubTestClass();
+ if ($noinline$getBoolean(escape)) {
+ i.next = obj;
+ $noinline$Escape(i);
+ } else {
+ i.next = obj;
+ }
+ $noinline$clobberObservables();
+ // Predicated-get
+ TestClass res = i.next;
+ // Predicated-set
+ i.next = null;
+ return res.i;
+ }
+
+ /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (before)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ //
+ /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (after)
+ /// CHECK: Phi
+ /// CHECK: Phi
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: float Main.$noinline$testPartialEscape3_float(boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static float $noinline$testPartialEscape3_float(boolean escape) {
+ TestClass4 tc = new TestClass4();
+ if ($noinline$getBoolean(escape)) {
+ $noinline$Escape4(tc);
+ } else {
+ tc.floatField -= 1f;
+ }
+ // Partial escape
+ $noinline$clobberObservables();
+ // Predicated set
+ tc.floatField *= 10;
+ // Predicated get
+ return tc.floatField;
+ }
+
+ /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (before)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ //
+ /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (after)
+ /// CHECK: Phi
+ /// CHECK: Phi
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: double Main.$noinline$testPartialEscape3_double(boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static double $noinline$testPartialEscape3_double(boolean escape) {
+ TestClass4 tc = new TestClass4();
+ if ($noinline$getBoolean(escape)) {
+ $noinline$Escape4(tc);
+ } else {
+ tc.doubleField -= 1d;
+ }
+ // Partial escape
+ $noinline$clobberObservables();
+ // Predicated set
+ tc.doubleField *= 10;
+ // Predicated get
+ return tc.doubleField;
+ }
+
+ /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (before)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ //
+ /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (after)
+ /// CHECK: Phi
+ /// CHECK: Phi
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: short Main.$noinline$testPartialEscape3_short(boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static short $noinline$testPartialEscape3_short(boolean escape) {
+ TestClass4 tc = new TestClass4();
+ if ($noinline$getBoolean(escape)) {
+ $noinline$Escape4(tc);
+ } else {
+ tc.shortField -= 1;
+ }
+ // Partial escape
+ $noinline$clobberObservables();
+ // Predicated set
+ tc.shortField *= 10;
+ // Predicated get
+ return tc.shortField;
+ }
+
+ /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (before)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ //
+ /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (after)
+ /// CHECK: Phi
+ /// CHECK: Phi
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: byte Main.$noinline$testPartialEscape3_byte(boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static byte $noinline$testPartialEscape3_byte(boolean escape) {
+ TestClass4 tc = new TestClass4();
+ if ($noinline$getBoolean(escape)) {
+ $noinline$Escape4(tc);
+ } else {
+ tc.byteField -= 1;
+ }
+ // Partial escape
+ $noinline$clobberObservables();
+ // Predicated set
+ tc.byteField *= 10;
+ // Predicated get
+ return tc.byteField;
+ }
+
+ /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (before)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (after)
+ /// CHECK: Phi
+ /// CHECK: Phi
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: int Main.$noinline$testPartialEscape3_int(boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static int $noinline$testPartialEscape3_int(boolean escape) {
+ TestClass4 tc = new TestClass4();
+ if ($noinline$getBoolean(escape)) {
+ $noinline$Escape4(tc);
+ } else {
+ tc.intField -= 1;
+ }
+ // Partial escape
+ $noinline$clobberObservables();
+ // Predicated set
+ tc.intField *= 10;
+ // Predicated get
+ return tc.intField;
+ }
+
+ /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (before)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ //
+ /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (after)
+ /// CHECK: Phi
+ /// CHECK: Phi
+ /// CHECK-NOT: Phi
+ //
+ /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (after)
+ /// CHECK: InstanceFieldSet predicated:true
+ /// CHECK-NOT: InstanceFieldSet predicated:true
+ //
+ /// CHECK-START: long Main.$noinline$testPartialEscape3_long(boolean) load_store_elimination (after)
+ /// CHECK: PredicatedInstanceFieldGet
+ /// CHECK-NOT: PredicatedInstanceFieldGet
+ private static long $noinline$testPartialEscape3_long(boolean escape) {
+ TestClass4 tc = new TestClass4();
+ if ($noinline$getBoolean(escape)) {
+ $noinline$Escape4(tc);
+ } else {
+ tc.longField -= 1;
+ }
+ // Partial escape
+ $noinline$clobberObservables();
+ // Predicated set
+ tc.longField *= 10;
+ // Predicated get
+ return tc.longField;
+ }
private static void $noinline$clobberObservables() {}
@@ -4196,5 +4463,19 @@
assertLongEquals(testOverlapLoop(50), 7778742049l);
assertIntEquals($noinline$testPartialEscape1(new TestClass(), true), 1);
assertIntEquals($noinline$testPartialEscape1(new TestClass(), false), 0);
+ assertIntEquals($noinline$testPartialEscape2(new TestClass(), true), 1);
+ assertIntEquals($noinline$testPartialEscape2(new TestClass(), false), 0);
+ assertDoubleEquals($noinline$testPartialEscape3_double(true), -20d);
+ assertDoubleEquals($noinline$testPartialEscape3_double(false), -40d);
+ assertFloatEquals($noinline$testPartialEscape3_float(true), -20f);
+ assertFloatEquals($noinline$testPartialEscape3_float(false), -40f);
+ assertIntEquals($noinline$testPartialEscape3_int(true), -20);
+ assertIntEquals($noinline$testPartialEscape3_int(false), -40);
+ assertIntEquals($noinline$testPartialEscape3_byte(true), -20);
+ assertIntEquals($noinline$testPartialEscape3_byte(false), -40);
+ assertIntEquals($noinline$testPartialEscape3_short(true), -20);
+ assertIntEquals($noinline$testPartialEscape3_short(false), -40);
+ assertLongEquals($noinline$testPartialEscape3_long(true), -20);
+ assertLongEquals($noinline$testPartialEscape3_long(false), -40);
}
}