diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-09-15 01:00:28 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-09-15 01:00:28 +0000 |
commit | 996bf69c5739cdeeeb225516afa12272db107588 (patch) | |
tree | 5aae4e675fb1f150d51640bbb5d2993b612140bb | |
parent | f4e778d338e072566a9b70903724d2b6d1c0b82e (diff) | |
parent | 020c79e5f2b61924d6e21e8162f52e992d7b30fe (diff) |
Snap for 7732468 from 020c79e5f2b61924d6e21e8162f52e992d7b30fe to sc-qpr1-release
Change-Id: I44559e16534133a93fe580999895e4ffbfd41b3c
-rw-r--r-- | compiler/optimizing/load_store_elimination.h | 2 | ||||
-rw-r--r-- | runtime/oat.h | 4 | ||||
-rw-r--r-- | test/530-checker-lse/src/Main.java | 257 | ||||
-rw-r--r-- | test/639-checker-code-sinking/src/Main.java | 15 | ||||
-rw-r--r-- | test/828-partial-lse/expected-stderr.txt | 0 | ||||
-rw-r--r-- | test/828-partial-lse/expected-stdout.txt | 0 | ||||
-rw-r--r-- | test/828-partial-lse/info.txt | 2 | ||||
-rw-r--r-- | test/828-partial-lse/src/Main.java | 53 |
8 files changed, 62 insertions, 271 deletions
diff --git a/compiler/optimizing/load_store_elimination.h b/compiler/optimizing/load_store_elimination.h index e73ef5ef34..6ad2eb2c51 100644 --- a/compiler/optimizing/load_store_elimination.h +++ b/compiler/optimizing/load_store_elimination.h @@ -27,7 +27,7 @@ class LoadStoreElimination : public HOptimization { public: // Whether or not we should attempt partial Load-store-elimination which // requires additional blocks and predicated instructions. - static constexpr bool kEnablePartialLSE = true; + static constexpr bool kEnablePartialLSE = false; // Controls whether to enable VLOG(compiler) logs explaining the transforms taking place. static constexpr bool kVerboseLoggingMode = false; diff --git a/runtime/oat.h b/runtime/oat.h index ab45b84888..31a328d979 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,8 +32,8 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr std::array<uint8_t, 4> kOatMagic { { 'o', 'a', 't', '\n' } }; - // Last oat version changed reason: Apex versions in key/value store. - static constexpr std::array<uint8_t, 4> kOatVersion { { '1', '9', '5', '\0' } }; + // Last oat version changed reason: Disable partial LSE b/197818595. + static constexpr std::array<uint8_t, 4> kOatVersion { { '1', '9', '9', '\0' } }; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; static constexpr const char* kDebuggableKey = "debuggable"; diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java index 35f1dc2ee4..a707a8ae5c 100644 --- a/test/530-checker-lse/src/Main.java +++ b/test/530-checker-lse/src/Main.java @@ -3964,249 +3964,6 @@ public class Main { 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() {} static void assertLongEquals(long result, long expected) { @@ -4613,19 +4370,5 @@ public class Main { 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); } } diff --git a/test/639-checker-code-sinking/src/Main.java b/test/639-checker-code-sinking/src/Main.java index 28fa57cfbf..91c3ec48ab 100644 --- a/test/639-checker-code-sinking/src/Main.java +++ b/test/639-checker-code-sinking/src/Main.java @@ -110,8 +110,6 @@ public class Main { /// CHECK: <<Int42:i\d+>> IntConstant 42 /// CHECK: begin_block /// CHECK: <<LoadClass:l\d+>> LoadClass class_name:Main - /// CHECK: If - /// CHECK: begin_block /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>] /// CHECK: InstanceFieldSet [<<NewInstance>>,<<Int42>>] /// CHECK: Throw @@ -121,14 +119,14 @@ public class Main { /// CHECK-NOT: NewInstance /// CHECK: If /// CHECK: begin_block + /// CHECK: <<Error:l\d+>> LoadClass class_name:java.lang.Error + /// CHECK-NOT: begin_block /// CHECK: <<LoadClass:l\d+>> LoadClass class_name:Main /// CHECK-NOT: begin_block /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>] /// CHECK-NOT: begin_block /// CHECK: InstanceFieldSet [<<NewInstance>>,<<Int42>>] /// CHECK-NOT: begin_block - /// CHECK: <<Error:l\d+>> LoadClass class_name:java.lang.Error - /// CHECK-NOT: begin_block /// CHECK: <<Throw:l\d+>> NewInstance [<<Error>>] /// CHECK-NOT: begin_block /// CHECK: Throw [<<Throw>>] @@ -325,12 +323,7 @@ public class Main { /// CHECK: <<Int42:i\d+>> IntConstant 42 /// CHECK: <<Int43:i\d+>> IntConstant 43 /// CHECK: <<LoadClass:l\d+>> LoadClass class_name:Main - /// CHECK: If - /// CHECK: begin_block - // Moved to throw block by partial-LSE and DCE. /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>] - // These were moved by partial LSE and order of sets is not observable and are - // in an arbitrary order. /// CHECK-DAG: InstanceFieldSet [<<NewInstance>>,<<Int42>>] /// CHECK-DAG: InstanceFieldSet [<<NewInstance>>,<<Int43>>] /// CHECK: Throw @@ -342,14 +335,14 @@ public class Main { /// CHECK-NOT: NewInstance /// CHECK: If /// CHECK: begin_block + /// CHECK: <<Error:l\d+>> LoadClass class_name:java.lang.Error + /// CHECK-NOT: begin_block /// CHECK: <<LoadClass:l\d+>> LoadClass class_name:Main /// CHECK: <<NewInstance:l\d+>> NewInstance [<<LoadClass>>] /// CHECK-NOT: begin_block /// CHECK-DAG: InstanceFieldSet [<<NewInstance>>,<<Int42>>] /// CHECK-DAG: InstanceFieldSet [<<NewInstance>>,<<Int43>>] /// CHECK-NOT: begin_block - /// CHECK: <<Error:l\d+>> LoadClass class_name:java.lang.Error - /// CHECK-NOT: begin_block /// CHECK: NewInstance [<<Error>>] /// CHECK: Throw /// CHECK-NOT: InstanceFieldSet diff --git a/test/828-partial-lse/expected-stderr.txt b/test/828-partial-lse/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/828-partial-lse/expected-stderr.txt diff --git a/test/828-partial-lse/expected-stdout.txt b/test/828-partial-lse/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/828-partial-lse/expected-stdout.txt diff --git a/test/828-partial-lse/info.txt b/test/828-partial-lse/info.txt new file mode 100644 index 0000000000..8d28cbdbfa --- /dev/null +++ b/test/828-partial-lse/info.txt @@ -0,0 +1,2 @@ +Regression test for the partial LSE pass, see +https://issuetracker.google.com/197818595. diff --git a/test/828-partial-lse/src/Main.java b/test/828-partial-lse/src/Main.java new file mode 100644 index 0000000000..2dde0eff95 --- /dev/null +++ b/test/828-partial-lse/src/Main.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Main { + + public static void $noinline$testMain(Main m) { + expectEquals(0, m.myField); + } + + public static void main(String[] args) { + $noinline$doTest(true); + $noinline$doTest(false); + } + + public static void $noinline$doTest(boolean testValue) { + Main m = new Main(); + // LSE will find that this store can be removed, as both branches override the value with a new + // one. + m.myField = 42; + if (testValue) { + // LSE will remove this store as well, as it's the value after the store of 42 is removed. + m.myField = 0; + // This makes sure `m` gets materialized. At this point, the bug is that the partial LSE + // optimization thinks the value incoming this block for `m.myField` is 42, however that + // store, as well as the store to 0, have been removed. + $noinline$testMain(m); + } else { + m.myField = 3; + expectEquals(3, m.myField); + } + } + + public static void expectEquals(int expected, int actual) { + if (expected != actual) { + throw new Error("Expected " + expected + ", got " + actual); + } + } + + int myField = 0; +} |