Fix inlining loops in OSR mode.
When compiling a method in OSR mode and the method does not
contain a loop (arguably, a very odd case) but we inline
another method with a loop and then the final DCE re-runs
the loop identification, the inlined loop would previously
be marked as irreducible. However, the SSA liveness analysis
expects irreducible loop to have extra loop Phis which were
already eliminated from the loop before the inner graph was
inlined to the outer graph, so we would fail a DCHECK().
We fix this by not marking inlined loops as irreducible when
compiling in OSR mode.
Bug: 28210356
Change-Id: If10057ed883333c62a878ed2ae3fe01bb5280e33
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 1afa36a..5091c7b 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -618,7 +618,24 @@
}
}
- if (is_irreducible_loop || graph->IsCompilingOsr()) {
+ if (!is_irreducible_loop && graph->IsCompilingOsr()) {
+ // When compiling in OSR mode, all loops in the compiled method may be entered
+ // from the interpreter. We treat this OSR entry point just like an extra entry
+ // to an irreducible loop, so we need to mark the method's loops as irreducible.
+ // This does not apply to inlined loops which do not act as OSR entry points.
+ if (suspend_check_ == nullptr) {
+ // Just building the graph in OSR mode, this loop is not inlined. We never build an
+ // inner graph in OSR mode as we can do OSR transition only from the outer method.
+ is_irreducible_loop = true;
+ } else {
+ // Look at the suspend check's environment to determine if the loop was inlined.
+ DCHECK(suspend_check_->HasEnvironment());
+ if (!suspend_check_->GetEnvironment()->IsFromInlinedInvoke()) {
+ is_irreducible_loop = true;
+ }
+ }
+ }
+ if (is_irreducible_loop) {
irreducible_ = true;
graph->SetHasIrreducibleLoops(true);
}