diff options
author | 2019-08-07 10:41:09 +0100 | |
---|---|---|
committer | 2019-08-07 15:49:47 +0000 | |
commit | 7cfc8f5b2a7c1af68de5f2e79652cf55954794dc (patch) | |
tree | bef388a5083ed2b9cf497cd6689489828f2ae13e | |
parent | 70b93ffca22d665db661a7f15f2f1b59dc60839a (diff) |
Don't compile OSR methods that have phi equivalents at loop entry.
We currently don't handle this in the stack map, where we only encode
one stack slot for a dex register.
Bug: 136698025
Test: 721-osr
Change-Id: Ib395ed1165387ad5446a463c307cc0a45e365885
-rw-r--r-- | compiler/optimizing/nodes.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler_stats.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 20 | ||||
-rw-r--r-- | test/721-osr/expected.txt | 0 | ||||
-rw-r--r-- | test/721-osr/info.txt | 3 | ||||
-rw-r--r-- | test/721-osr/src/Main.java | 45 |
7 files changed, 75 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 25f9e3cb73..09ae6fab84 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -131,6 +131,7 @@ enum GraphAnalysisResult { kAnalysisFailThrowCatchLoop, kAnalysisFailAmbiguousArrayOp, kAnalysisFailIrreducibleLoopAndStringInit, + kAnalysisFailPhiEquivalentInOsr, kAnalysisSuccess, }; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 6f3b9feb9d..b1a3abee2f 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -914,6 +914,11 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, MethodCompilationStat::kNotCompiledIrreducibleLoopAndStringInit); break; } + case kAnalysisFailPhiEquivalentInOsr: { + MaybeRecordStat(compilation_stats_.get(), + MethodCompilationStat::kNotCompiledPhiEquivalentInOsr); + break; + } case kAnalysisSuccess: UNREACHABLE(); } diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h index ddd57f5f1a..83dbef7409 100644 --- a/compiler/optimizing/optimizing_compiler_stats.h +++ b/compiler/optimizing/optimizing_compiler_stats.h @@ -61,6 +61,7 @@ enum class MethodCompilationStat { kNotCompiledVerificationError, kNotCompiledVerifyAtRuntime, kNotCompiledIrreducibleLoopAndStringInit, + kNotCompiledPhiEquivalentInOsr, kInlinedMonomorphicCall, kInlinedPolymorphicCall, kMonomorphicCall, diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 0d0e1ecf1f..a5e8ff65a9 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -496,6 +496,22 @@ void SsaBuilder::RemoveRedundantUninitializedStrings() { } } +static bool HasPhiEquivalentAtLoopEntry(HGraph* graph) { + // Phi equivalents for a dex register do not work with OSR, as the phis will + // receive two different stack slots but only one is recorded in the stack + // map. + for (HBasicBlock* block : graph->GetReversePostOrder()) { + if (block->IsLoopHeader()) { + for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { + if (it.Current()->AsPhi()->HasEquivalentPhi()) { + return true; + } + } + } + } + return false; +} + GraphAnalysisResult SsaBuilder::BuildSsa() { DCHECK(!graph_->IsInSsaForm()); @@ -574,6 +590,10 @@ GraphAnalysisResult SsaBuilder::BuildSsa() { // other optimizations. RemoveRedundantUninitializedStrings(); + if (graph_->IsCompilingOsr() && HasPhiEquivalentAtLoopEntry(graph_)) { + return kAnalysisFailPhiEquivalentInOsr; + } + graph_->SetInSsaForm(); return kAnalysisSuccess; } diff --git a/test/721-osr/expected.txt b/test/721-osr/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/721-osr/expected.txt diff --git a/test/721-osr/info.txt b/test/721-osr/info.txt new file mode 100644 index 0000000000..d43357e875 --- /dev/null +++ b/test/721-osr/info.txt @@ -0,0 +1,3 @@ +Regression test for OSR compilation, which used to not fill the +right dex register value in the presence of equivalent phis. +(see b/136698025) diff --git a/test/721-osr/src/Main.java b/test/721-osr/src/Main.java new file mode 100644 index 0000000000..2f0892c3fb --- /dev/null +++ b/test/721-osr/src/Main.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2019 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. + */ + +import java.util.ArrayList; +import java.util.List; + +public class Main { + private enum TestType { + ONE, + TWO + } + + private static TestType type = TestType.ONE; + + public static void main(String[] args) { + float testFloat; + switch (type) { + case ONE: testFloat = 1000.0f; break; + default: testFloat = 5f; break; + } + + // Loop enough to potentially trigger OSR. + List<Integer> dummyObjects = new ArrayList<Integer>(200_000); + for (int i = 0; i < 200_000; i++) { + dummyObjects.add(1024); + } + + if (testFloat != 1000.0f) { + throw new Error("Expected 1000.0f, got " + testFloat); + } + } +} |