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/test/570-checker-osr/osr.cc b/test/570-checker-osr/osr.cc
index 09e97ea..ac2e0ce 100644
--- a/test/570-checker-osr/osr.cc
+++ b/test/570-checker-osr/osr.cc
@@ -20,15 +20,17 @@
 #include "jit/profiling_info.h"
 #include "oat_quick_method_header.h"
 #include "scoped_thread_state_change.h"
+#include "ScopedUtfChars.h"
 #include "stack_map.h"
 
 namespace art {
 
 class OsrVisitor : public StackVisitor {
  public:
-  explicit OsrVisitor(Thread* thread)
+  explicit OsrVisitor(Thread* thread, const char* method_name)
       SHARED_REQUIRES(Locks::mutator_lock_)
       : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
+        method_name_(method_name),
         in_osr_method_(false),
         in_interpreter_(false) {}
 
@@ -36,13 +38,7 @@
     ArtMethod* m = GetMethod();
     std::string m_name(m->GetName());
 
-    if ((m_name.compare("$noinline$returnInt") == 0) ||
-        (m_name.compare("$noinline$returnFloat") == 0) ||
-        (m_name.compare("$noinline$returnDouble") == 0) ||
-        (m_name.compare("$noinline$returnLong") == 0) ||
-        (m_name.compare("$noinline$deopt") == 0) ||
-        (m_name.compare("$noinline$inlineCache") == 0) ||
-        (m_name.compare("$noinline$stackOverflow") == 0)) {
+    if (m_name.compare(method_name_) == 0) {
       const OatQuickMethodHeader* header =
           Runtime::Current()->GetJit()->GetCodeCache()->LookupOsrMethodHeader(m);
       if (header != nullptr && header == GetCurrentOatQuickMethodHeader()) {
@@ -55,29 +51,38 @@
     return true;
   }
 
+  const char* const method_name_;
   bool in_osr_method_;
   bool in_interpreter_;
 };
 
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_ensureInOsrCode(JNIEnv*, jclass) {
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInOsrCode(JNIEnv* env,
+                                                            jclass,
+                                                            jstring method_name) {
   jit::Jit* jit = Runtime::Current()->GetJit();
   if (jit == nullptr) {
     // Just return true for non-jit configurations to stop the infinite loop.
     return JNI_TRUE;
   }
+  ScopedUtfChars chars(env, method_name);
+  CHECK(chars.c_str() != nullptr);
   ScopedObjectAccess soa(Thread::Current());
-  OsrVisitor visitor(soa.Self());
+  OsrVisitor visitor(soa.Self(), chars.c_str());
   visitor.WalkStack();
   return visitor.in_osr_method_;
 }
 
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_ensureInInterpreter(JNIEnv*, jclass) {
+extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInInterpreter(JNIEnv* env,
+                                                                jclass,
+                                                                jstring method_name) {
   if (!Runtime::Current()->UseJit()) {
     // The return value is irrelevant if we're not using JIT.
     return false;
   }
+  ScopedUtfChars chars(env, method_name);
+  CHECK(chars.c_str() != nullptr);
   ScopedObjectAccess soa(Thread::Current());
-  OsrVisitor visitor(soa.Self());
+  OsrVisitor visitor(soa.Self(), chars.c_str());
   visitor.WalkStack();
   return visitor.in_interpreter_;
 }
@@ -112,17 +117,17 @@
 
 class OsrCheckVisitor : public StackVisitor {
  public:
-  explicit OsrCheckVisitor(Thread* thread)
+  OsrCheckVisitor(Thread* thread, const char* const method_name)
       SHARED_REQUIRES(Locks::mutator_lock_)
-      : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {}
+      : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
+        method_name_(method_name) {}
 
   bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
     ArtMethod* m = GetMethod();
     std::string m_name(m->GetName());
 
     jit::Jit* jit = Runtime::Current()->GetJit();
-    if ((m_name.compare("$noinline$inlineCache") == 0) ||
-        (m_name.compare("$noinline$stackOverflow") == 0)) {
+    if (m_name.compare(method_name_) == 0) {
       while (jit->GetCodeCache()->LookupOsrMethodHeader(m) == nullptr) {
         // Sleep to yield to the compiler thread.
         sleep(0);
@@ -133,14 +138,20 @@
     }
     return true;
   }
+
+  const char* const method_name_;
 };
 
-extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasOsrCode(JNIEnv*, jclass) {
+extern "C" JNIEXPORT void JNICALL Java_Main_ensureHasOsrCode(JNIEnv* env,
+                                                             jclass,
+                                                             jstring method_name) {
   if (!Runtime::Current()->UseJit()) {
     return;
   }
+  ScopedUtfChars chars(env, method_name);
+  CHECK(chars.c_str() != nullptr);
   ScopedObjectAccess soa(Thread::Current());
-  OsrCheckVisitor visitor(soa.Self());
+  OsrCheckVisitor visitor(soa.Self(), chars.c_str());
   visitor.WalkStack();
 }