Merge "Remove references to $(ACP)"
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 23601c3..79a6d38 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -230,10 +230,10 @@
   }
 
   // Trim maps to reduce memory usage.
-  // TODO: measure how much this increases compile time.
+  // TODO: move this to an idle phase.
   {
     TimingLogger::ScopedTiming t2("TrimMaps", &logger);
-    runtime->GetArenaPool()->TrimMaps();
+    runtime->GetJitArenaPool()->TrimMaps();
   }
 
   total_time_ += NanoTime() - start_time;
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 5a9f258..13d6d62 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -861,7 +861,7 @@
   const uint32_t access_flags = method->GetAccessFlags();
   const InvokeType invoke_type = method->GetInvokeType();
 
-  ArenaAllocator arena(Runtime::Current()->GetArenaPool());
+  ArenaAllocator arena(Runtime::Current()->GetJitArenaPool());
   CodeVectorAllocator code_allocator(&arena);
   std::unique_ptr<CodeGenerator> codegen;
   {
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index e30b968..c187536 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -361,6 +361,7 @@
                    const char* method_filter,
                    bool list_classes,
                    bool list_methods,
+                   bool dump_header_only,
                    const char* export_dex_location,
                    uint32_t addr2instr)
     : dump_raw_mapping_table_(dump_raw_mapping_table),
@@ -373,6 +374,7 @@
       method_filter_(method_filter),
       list_classes_(list_classes),
       list_methods_(list_methods),
+      dump_header_only_(dump_header_only),
       export_dex_location_(export_dex_location),
       addr2instr_(addr2instr),
       class_loader_(nullptr) {}
@@ -387,6 +389,7 @@
   const char* const method_filter_;
   const bool list_classes_;
   const bool list_methods_;
+  const bool dump_header_only_;
   const char* const export_dex_location_;
   uint32_t addr2instr_;
   Handle<mirror::ClassLoader>* class_loader_;
@@ -514,21 +517,24 @@
       os << StringPrintf("0x%08x\n\n", resolved_addr2instr_);
     }
 
-    for (size_t i = 0; i < oat_dex_files_.size(); i++) {
-      const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
-      CHECK(oat_dex_file != nullptr);
+    if (!options_.dump_header_only_) {
+      for (size_t i = 0; i < oat_dex_files_.size(); i++) {
+        const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
+        CHECK(oat_dex_file != nullptr);
 
-      // If file export selected skip file analysis
-      if (options_.export_dex_location_) {
-        if (!ExportDexFile(os, *oat_dex_file)) {
-          success = false;
-        }
-      } else {
-        if (!DumpOatDexFile(os, *oat_dex_file)) {
-          success = false;
+        // If file export selected skip file analysis
+        if (options_.export_dex_location_) {
+          if (!ExportDexFile(os, *oat_dex_file)) {
+            success = false;
+          }
+        } else {
+          if (!DumpOatDexFile(os, *oat_dex_file)) {
+            success = false;
+          }
         }
       }
     }
+
     os << std::flush;
     return success;
   }
@@ -2572,6 +2578,8 @@
       dump_code_info_stack_maps_ = true;
     } else if (option == "--no-disassemble") {
       disassemble_code_ = false;
+    } else if (option =="--header-only") {
+      dump_header_only_ = true;
     } else if (option.starts_with("--symbolize=")) {
       oat_filename_ = option.substr(strlen("--symbolize=")).data();
       symbolize_ = true;
@@ -2655,6 +2663,9 @@
         "  --no-disassemble may be used to disable disassembly.\n"
         "      Example: --no-disassemble\n"
         "\n"
+        "  --header-only may be used to print only the oat header.\n"
+        "      Example: --header-only\n"
+        "\n"
         "  --list-classes may be used to list target file classes (can be used with filters).\n"
         "      Example: --list-classes\n"
         "      Example: --list-classes --class-filter=com.example.foo\n"
@@ -2697,6 +2708,7 @@
   bool symbolize_ = false;
   bool list_classes_ = false;
   bool list_methods_ = false;
+  bool dump_header_only_ = false;
   uint32_t addr2instr_ = 0;
   const char* export_dex_location_ = nullptr;
 };
@@ -2719,6 +2731,7 @@
         args_->method_filter_,
         args_->list_classes_,
         args_->list_methods_,
+        args_->dump_header_only_,
         args_->export_dex_location_,
         args_->addr2instr_));
 
diff --git a/runtime/base/arena_allocator.cc b/runtime/base/arena_allocator.cc
index a4b38ea..44af3f7 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -183,10 +183,10 @@
   free(reinterpret_cast<void*>(memory_));
 }
 
-MemMapArena::MemMapArena(size_t size, bool low_4gb) {
+MemMapArena::MemMapArena(size_t size, bool low_4gb, const char* name) {
   std::string error_msg;
   map_.reset(MemMap::MapAnonymous(
-      "LinearAlloc", nullptr, size, PROT_READ | PROT_WRITE, low_4gb, false, &error_msg));
+      name, nullptr, size, PROT_READ | PROT_WRITE, low_4gb, false, &error_msg));
   CHECK(map_.get() != nullptr) << error_msg;
   memory_ = map_->Begin();
   size_ = map_->Size();
@@ -210,9 +210,12 @@
   }
 }
 
-ArenaPool::ArenaPool(bool use_malloc, bool low_4gb)
-    : use_malloc_(use_malloc), lock_("Arena pool lock", kArenaPoolLock), free_arenas_(nullptr),
-      low_4gb_(low_4gb) {
+ArenaPool::ArenaPool(bool use_malloc, bool low_4gb, const char* name)
+    : use_malloc_(use_malloc),
+      lock_("Arena pool lock", kArenaPoolLock),
+      free_arenas_(nullptr),
+      low_4gb_(low_4gb),
+      name_(name) {
   if (low_4gb) {
     CHECK(!use_malloc) << "low4gb must use map implementation";
   }
@@ -250,7 +253,7 @@
   }
   if (ret == nullptr) {
     ret = use_malloc_ ? static_cast<Arena*>(new MallocArena(size)) :
-        new MemMapArena(size, low_4gb_);
+        new MemMapArena(size, low_4gb_, name_);
   }
   ret->Reset();
   return ret;
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index 8a96571..728f897 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -261,7 +261,7 @@
 
 class MemMapArena FINAL : public Arena {
  public:
-  MemMapArena(size_t size, bool low_4gb);
+  MemMapArena(size_t size, bool low_4gb, const char* name);
   virtual ~MemMapArena();
   void Release() OVERRIDE;
 
@@ -271,7 +271,9 @@
 
 class ArenaPool {
  public:
-  explicit ArenaPool(bool use_malloc = true, bool low_4gb = false);
+  ArenaPool(bool use_malloc = true,
+            bool low_4gb = false,
+            const char* name = "LinearAlloc");
   ~ArenaPool();
   Arena* AllocArena(size_t size) REQUIRES(!lock_);
   void FreeArenaChain(Arena* first) REQUIRES(!lock_);
@@ -287,6 +289,7 @@
   mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   Arena* free_arenas_ GUARDED_BY(lock_);
   const bool low_4gb_;
+  const char* name_;
   DISALLOW_COPY_AND_ASSIGN(ArenaPool);
 };
 
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index bfb1f9d..b7e5b30 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -295,9 +295,7 @@
     }
 
     jit::Jit* jit = Runtime::Current()->GetJit();
-    if (UNLIKELY(jit != nullptr &&
-                 jit->JitAtFirstUse() &&
-                 jit->GetCodeCache()->ContainsMethod(method))) {
+    if (jit != nullptr && jit->CanInvokeCompiledCode(method)) {
       JValue result;
 
       // Pop the shadow frame before calling into compiled code.
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index e1bde1b..ca727f4 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -150,7 +150,8 @@
   bool unhandled_instrumentation;
   // TODO: enable for other targets after more extensive testing.
   if ((kRuntimeISA == kArm64) || (kRuntimeISA == kArm) ||
-      (kRuntimeISA == kX86) || (kRuntimeISA == kMips)) {
+      (kRuntimeISA == kX86_64) || (kRuntimeISA == kX86) ||
+      (kRuntimeISA == kMips)) {
     unhandled_instrumentation = instrumentation->NonJitProfilingActive();
   } else {
     unhandled_instrumentation = instrumentation->IsActive();
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index 53fa50f..a1360e0 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -169,13 +169,23 @@
 #define OFF_FP_CODE_ITEM OFF_FP(SHADOWFRAME_CODE_ITEM_OFFSET)
 #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET)
 
+#define MTERP_PROFILE_BRANCHES 1
+#define MTERP_LOGGING 0
+
 /*
- *
- * The reference interpreter performs explicit suspect checks, which is somewhat wasteful.
- * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually
- * mterp should do so as well.
+ * Profile branch. rINST should contain the offset. %eax is scratch.
  */
-#define MTERP_SUSPEND 0
+.macro MTERP_PROFILE_BRANCH
+#ifdef MTERP_PROFILE_BRANCHES
+    EXPORT_PC
+    movq    rSELF, OUT_ARG0
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+    movl    rINST, OUT_32_ARG2
+    call    SYMBOL(MterpProfileBranch)
+    testb   %al, %al
+    jnz     MterpOnStackReplacement
+#endif
+.endm
 
 /*
  * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects.  Must
@@ -992,17 +1002,12 @@
  * double to get a byte offset.
  */
     /* goto +AA */
-    movsbq  rINSTbl, %rax                   # rax <- ssssssAA
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    movsbq  rINSTbl, rINSTq                 # rINSTq <- ssssssAA
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1016,17 +1021,12 @@
  * double to get a byte offset.
  */
     /* goto/16 +AAAA */
-    movswq  2(rPC), %rax                    # rax <- ssssAAAA
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    movswq  2(rPC), rINSTq                  # rINSTq <- ssssAAAA
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1043,17 +1043,12 @@
  * to convert from Dalvik offset to byte offset.
  */
     /* goto/32 +AAAAAAAA */
-    movslq  2(rPC), %rax                    # rax <- AAAAAAAA
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    movslq  2(rPC), rINSTq                  # rINSTq <- AAAAAAAA
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1074,17 +1069,12 @@
     leaq    (rPC,OUT_ARG0,2), OUT_ARG0      # rcx <- PC + BBBBbbbb*2
     GET_VREG OUT_32_ARG1, rINSTq            # eax <- vAA
     call    SYMBOL(MterpDoPackedSwitch)
-    addl    %eax, %eax
-    movslq  %eax, %rax
-    leaq    (rPC, %rax), rPC
+    movslq  %eax, rINSTq
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue
     GOTO_NEXT
 
 /* ------------------------------ */
@@ -1106,17 +1096,12 @@
     leaq    (rPC,OUT_ARG0,2), OUT_ARG0      # rcx <- PC + BBBBbbbb*2
     GET_VREG OUT_32_ARG1, rINSTq            # eax <- vAA
     call    SYMBOL(MterpDoSparseSwitch)
-    addl    %eax, %eax
-    movslq  %eax, %rax
-    leaq    (rPC, %rax), rPC
+    movslq  %eax, rINSTq
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue
     GOTO_NEXT
 
 
@@ -1324,20 +1309,15 @@
     andb    $0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $2, %eax                       # assume not taken
+    movl    $2, rINST                      # assume not taken
     jne   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1359,20 +1339,15 @@
     andb    $0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $2, %eax                       # assume not taken
+    movl    $2, rINST                      # assume not taken
     je   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1394,20 +1369,15 @@
     andb    $0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $2, %eax                       # assume not taken
+    movl    $2, rINST                      # assume not taken
     jge   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1429,20 +1399,15 @@
     andb    $0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $2, %eax                       # assume not taken
+    movl    $2, rINST                      # assume not taken
     jl   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1464,20 +1429,15 @@
     andb    $0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $2, %eax                       # assume not taken
+    movl    $2, rINST                      # assume not taken
     jle   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1499,20 +1459,15 @@
     andb    $0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $2, %eax                       # assume not taken
+    movl    $2, rINST                      # assume not taken
     jg   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1530,20 +1485,15 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $2, %eax                       # assume branch not taken
+    movl    $2, rINST                      # assume branch not taken
     jne   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1561,20 +1511,15 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $2, %eax                       # assume branch not taken
+    movl    $2, rINST                      # assume branch not taken
     je   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1592,20 +1537,15 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $2, %eax                       # assume branch not taken
+    movl    $2, rINST                      # assume branch not taken
     jge   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1623,20 +1563,15 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $2, %eax                       # assume branch not taken
+    movl    $2, rINST                      # assume branch not taken
     jl   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1654,20 +1589,15 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $2, %eax                       # assume branch not taken
+    movl    $2, rINST                      # assume branch not taken
     jle   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -1685,20 +1615,15 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $2, %eax                       # assume branch not taken
+    movl    $2, rINST                      # assume branch not taken
     jg   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
 
 
@@ -2931,7 +2856,12 @@
     call    SYMBOL(MterpInvokeVirtual)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 /*
  * Handle a virtual method call.
@@ -2961,7 +2891,12 @@
     call    SYMBOL(MterpInvokeSuper)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 /*
  * Handle a "super" method call.
@@ -2991,7 +2926,12 @@
     call    SYMBOL(MterpInvokeDirect)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -3014,7 +2954,12 @@
     call    SYMBOL(MterpInvokeStatic)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 
@@ -3038,7 +2983,12 @@
     call    SYMBOL(MterpInvokeInterface)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 /*
  * Handle an interface method call.
@@ -3080,7 +3030,12 @@
     call    SYMBOL(MterpInvokeVirtualRange)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -3103,7 +3058,12 @@
     call    SYMBOL(MterpInvokeSuperRange)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -3126,7 +3086,12 @@
     call    SYMBOL(MterpInvokeDirectRange)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -3149,7 +3114,12 @@
     call    SYMBOL(MterpInvokeStaticRange)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -3172,7 +3142,12 @@
     call    SYMBOL(MterpInvokeInterfaceRange)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -5811,7 +5786,12 @@
     call    SYMBOL(MterpInvokeVirtualQuick)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -5834,7 +5814,12 @@
     call    SYMBOL(MterpInvokeVirtualQuickRange)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
 
 
 /* ------------------------------ */
@@ -11805,7 +11790,6 @@
  * has not yet been thrown.  Just bail out to the reference interpreter to deal with it.
  * TUNING: for consistency, we may want to just go ahead and handle these here.
  */
-#define MTERP_LOGGING 0
 common_errDivideByZero:
     EXPORT_PC
 #if MTERP_LOGGING
@@ -11891,13 +11875,17 @@
     call    SYMBOL(MterpHandleException)
     testb   %al, %al
     jz      MterpExceptionReturn
-    REFRESH_IBASE
     movq    OFF_FP_CODE_ITEM(rFP), %rax
     mov     OFF_FP_DEX_PC(rFP), %ecx
     leaq    CODEITEM_INSNS_OFFSET(%rax), rPC
     leaq    (rPC, %rcx, 2), rPC
     movq    rPC, OFF_FP_DEX_PC_PTR(rFP)
+    /* Do we need to switch interpreters? */
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
     /* resume execution at catch block */
+    REFRESH_IBASE
     FETCH_INST
     GOTO_NEXT
     /* NOTE: no fallthrough */
@@ -11917,6 +11905,19 @@
     GOTO_NEXT
 
 /*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+    movq    rSELF, OUT_ARG0
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+    movl    rINST, OUT_32_ARG2
+    call    SYMBOL(MterpLogOSR)
+#endif
+    movl    $1, %eax
+    jmp     MterpDone
+
+/*
  * Bail out to reference interpreter.
  */
 MterpFallback:
diff --git a/runtime/interpreter/mterp/x86_64/bincmp.S b/runtime/interpreter/mterp/x86_64/bincmp.S
index 5e4225f..a16050b 100644
--- a/runtime/interpreter/mterp/x86_64/bincmp.S
+++ b/runtime/interpreter/mterp/x86_64/bincmp.S
@@ -11,18 +11,13 @@
     andb    $$0xf, %cl                      # rcx <- A
     GET_VREG %eax, %rcx                     # eax <- vA
     cmpl    VREG_ADDRESS(rINSTq), %eax      # compare (vA, vB)
-    movl    $$2, %eax                       # assume not taken
+    movl    $$2, rINST                      # assume not taken
     j${revcmp}   1f
-    movswq  2(rPC),%rax                     # Get signed branch offset
+    movswq  2(rPC), rINSTq                  # Get signed branch offset
 1:
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rax <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/footer.S b/runtime/interpreter/mterp/x86_64/footer.S
index cb60c01..573256b 100644
--- a/runtime/interpreter/mterp/x86_64/footer.S
+++ b/runtime/interpreter/mterp/x86_64/footer.S
@@ -12,7 +12,6 @@
  * has not yet been thrown.  Just bail out to the reference interpreter to deal with it.
  * TUNING: for consistency, we may want to just go ahead and handle these here.
  */
-#define MTERP_LOGGING 0
 common_errDivideByZero:
     EXPORT_PC
 #if MTERP_LOGGING
@@ -98,13 +97,17 @@
     call    SYMBOL(MterpHandleException)
     testb   %al, %al
     jz      MterpExceptionReturn
-    REFRESH_IBASE
     movq    OFF_FP_CODE_ITEM(rFP), %rax
     mov     OFF_FP_DEX_PC(rFP), %ecx
     leaq    CODEITEM_INSNS_OFFSET(%rax), rPC
     leaq    (rPC, %rcx, 2), rPC
     movq    rPC, OFF_FP_DEX_PC_PTR(rFP)
+    /* Do we need to switch interpreters? */
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
     /* resume execution at catch block */
+    REFRESH_IBASE
     FETCH_INST
     GOTO_NEXT
     /* NOTE: no fallthrough */
@@ -124,6 +127,19 @@
     GOTO_NEXT
 
 /*
+ * On-stack replacement has happened, and now we've returned from the compiled method.
+ */
+MterpOnStackReplacement:
+#if MTERP_LOGGING
+    movq    rSELF, OUT_ARG0
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+    movl    rINST, OUT_32_ARG2
+    call    SYMBOL(MterpLogOSR)
+#endif
+    movl    $$1, %eax
+    jmp     MterpDone
+
+/*
  * Bail out to reference interpreter.
  */
 MterpFallback:
diff --git a/runtime/interpreter/mterp/x86_64/header.S b/runtime/interpreter/mterp/x86_64/header.S
index dfc7b53..eb84ea1 100644
--- a/runtime/interpreter/mterp/x86_64/header.S
+++ b/runtime/interpreter/mterp/x86_64/header.S
@@ -162,13 +162,23 @@
 #define OFF_FP_CODE_ITEM OFF_FP(SHADOWFRAME_CODE_ITEM_OFFSET)
 #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET)
 
+#define MTERP_PROFILE_BRANCHES 1
+#define MTERP_LOGGING 0
+
 /*
- *
- * The reference interpreter performs explicit suspect checks, which is somewhat wasteful.
- * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually
- * mterp should do so as well.
+ * Profile branch. rINST should contain the offset. %eax is scratch.
  */
-#define MTERP_SUSPEND 0
+.macro MTERP_PROFILE_BRANCH
+#ifdef MTERP_PROFILE_BRANCHES
+    EXPORT_PC
+    movq    rSELF, OUT_ARG0
+    leaq    OFF_FP_SHADOWFRAME(rFP), OUT_ARG1
+    movl    rINST, OUT_32_ARG2
+    call    SYMBOL(MterpProfileBranch)
+    testb   %al, %al
+    jnz     MterpOnStackReplacement
+#endif
+.endm
 
 /*
  * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects.  Must
diff --git a/runtime/interpreter/mterp/x86_64/invoke.S b/runtime/interpreter/mterp/x86_64/invoke.S
index 86eccdb..f7e6155 100644
--- a/runtime/interpreter/mterp/x86_64/invoke.S
+++ b/runtime/interpreter/mterp/x86_64/invoke.S
@@ -14,4 +14,9 @@
     call    SYMBOL($helper)
     testb   %al, %al
     jz      MterpException
-    ADVANCE_PC_FETCH_AND_GOTO_NEXT 3
+    ADVANCE_PC 3
+    call    SYMBOL(MterpShouldSwitchInterpreters)
+    testb   %al, %al
+    jnz     MterpFallback
+    FETCH_INST
+    GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/op_goto.S b/runtime/interpreter/mterp/x86_64/op_goto.S
index 05a2dda..c4fc976 100644
--- a/runtime/interpreter/mterp/x86_64/op_goto.S
+++ b/runtime/interpreter/mterp/x86_64/op_goto.S
@@ -5,15 +5,10 @@
  * double to get a byte offset.
  */
     /* goto +AA */
-    movsbq  rINSTbl, %rax                   # rax <- ssssssAA
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    movsbq  rINSTbl, rINSTq                 # rINSTq <- ssssssAA
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/op_goto_16.S b/runtime/interpreter/mterp/x86_64/op_goto_16.S
index 029749c..8cb9a5c 100644
--- a/runtime/interpreter/mterp/x86_64/op_goto_16.S
+++ b/runtime/interpreter/mterp/x86_64/op_goto_16.S
@@ -5,15 +5,10 @@
  * double to get a byte offset.
  */
     /* goto/16 +AAAA */
-    movswq  2(rPC), %rax                    # rax <- ssssAAAA
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    movswq  2(rPC), rINSTq                  # rINSTq <- ssssAAAA
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/op_goto_32.S b/runtime/interpreter/mterp/x86_64/op_goto_32.S
index 2823310..4ecdacd 100644
--- a/runtime/interpreter/mterp/x86_64/op_goto_32.S
+++ b/runtime/interpreter/mterp/x86_64/op_goto_32.S
@@ -8,15 +8,10 @@
  * to convert from Dalvik offset to byte offset.
  */
     /* goto/32 +AAAAAAAA */
-    movslq  2(rPC), %rax                    # rax <- AAAAAAAA
-    addq    %rax, %rax                      # rax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    movslq  2(rPC), rINSTq                  # rINSTq <- AAAAAAAA
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/op_packed_switch.S b/runtime/interpreter/mterp/x86_64/op_packed_switch.S
index 0400ca4..cb0acb7 100644
--- a/runtime/interpreter/mterp/x86_64/op_packed_switch.S
+++ b/runtime/interpreter/mterp/x86_64/op_packed_switch.S
@@ -13,15 +13,10 @@
     leaq    (rPC,OUT_ARG0,2), OUT_ARG0      # rcx <- PC + BBBBbbbb*2
     GET_VREG OUT_32_ARG1, rINSTq            # eax <- vAA
     call    SYMBOL($func)
-    addl    %eax, %eax
-    movslq  %eax, %rax
-    leaq    (rPC, %rax), rPC
+    movslq  %eax, rINSTq
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      1f
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-1:
+    jle     MterpCheckSuspendAndContinue
     GOTO_NEXT
diff --git a/runtime/interpreter/mterp/x86_64/zcmp.S b/runtime/interpreter/mterp/x86_64/zcmp.S
index e503ec1..0051407 100644
--- a/runtime/interpreter/mterp/x86_64/zcmp.S
+++ b/runtime/interpreter/mterp/x86_64/zcmp.S
@@ -7,18 +7,13 @@
  */
     /* if-cmp vAA, +BBBB */
     cmpl    $$0, VREG_ADDRESS(rINSTq)       # compare (vA, 0)
-    movl    $$2, %eax                       # assume branch not taken
+    movl    $$2, rINST                      # assume branch not taken
     j${revcmp}   1f
-    movswq  2(rPC),%rax                     # fetch signed displacement
+    movswq  2(rPC), rINSTq                  # fetch signed displacement
 1:
-    addq    %rax, %rax                      # eax <- AA * 2
-    leaq    (rPC, %rax), rPC
+    MTERP_PROFILE_BRANCH
+    addq    rINSTq, rINSTq                  # rINSTq <- AA * 2
+    leaq    (rPC, rINSTq), rPC
     FETCH_INST
-    jg      2f                              # AA * 2 > 0 => no suspend check
-#if MTERP_SUSPEND
-    REFRESH_IBASE
-#else
-    jmp     MterpCheckSuspendAndContinue
-#endif
-2:
+    jle     MterpCheckSuspendAndContinue    # AA * 2 <= 0 => suspend check
     GOTO_NEXT
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 3e66ce2..91b006a 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -213,6 +213,10 @@
   return false;
 }
 
+bool Jit::CanInvokeCompiledCode(ArtMethod* method) {
+  return code_cache_->ContainsPc(method->GetEntryPointFromQuickCompiledCode());
+}
+
 Jit::~Jit() {
   DCHECK(!save_profiling_info_ || !ProfileSaver::IsStarted());
   if (dump_info_on_shutdown_) {
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index 109ca3d..3f54192 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -84,8 +84,12 @@
   // into the specified class linker to the jit debug interface,
   void DumpTypeInfoForLoadedTypes(ClassLinker* linker);
 
+  // Return whether we should try to JIT compiled code as soon as an ArtMethod is invoked.
   bool JitAtFirstUse();
 
+  // Return whether we can invoke JIT code for `method`.
+  bool CanInvokeCompiledCode(ArtMethod* method);
+
   // If an OSR compiled version is available for `method`,
   // and `dex_pc + dex_pc_offset` is an entry point of that compiled
   // version, this method will jump to the compiled code, let it run,
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 8858b48..e8a7189 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -123,7 +123,7 @@
       current_capacity_(initial_code_capacity + initial_data_capacity),
       code_end_(initial_code_capacity),
       data_end_(initial_data_capacity),
-      has_done_full_collection_(false),
+      last_collection_increased_code_cache_(false),
       last_update_time_ns_(0),
       garbage_collect_code_(garbage_collect_code),
       used_memory_for_data_(0),
@@ -546,34 +546,20 @@
   }
 }
 
-void JitCodeCache::RemoveUnusedCode(Thread* self) {
-  // Clear the osr map, chances are most of the code in it is now dead.
-  {
-    MutexLock mu(self, lock_);
-    osr_code_map_.clear();
-  }
-
-  // Run a checkpoint on all threads to mark the JIT compiled code they are running.
-  MarkCompiledCodeOnThreadStacks(self);
-
-  // Iterate over all compiled code and remove entries that are not marked and not
-  // the entrypoint of their corresponding ArtMethod.
-  {
-    MutexLock mu(self, lock_);
-    ScopedCodeCacheWrite scc(code_map_.get());
-    for (auto it = method_code_map_.begin(); it != method_code_map_.end();) {
-      const void* code_ptr = it->first;
-      ArtMethod* method = it->second;
-      uintptr_t allocation = FromCodeToAllocation(code_ptr);
-      const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
-      if ((method->GetEntryPointFromQuickCompiledCode() != method_header->GetEntryPoint()) &&
-          !GetLiveBitmap()->Test(allocation)) {
-        FreeCode(code_ptr, method);
-        it = method_code_map_.erase(it);
-      } else {
-        ++it;
-      }
-    }
+bool JitCodeCache::ShouldDoFullCollection() {
+  if (current_capacity_ == max_capacity_) {
+    // Always do a full collection when the code cache is full.
+    return true;
+  } else if (current_capacity_ < kReservedCapacity) {
+    // Always do partial collection when the code cache size is below the reserved
+    // capacity.
+    return false;
+  } else if (last_collection_increased_code_cache_) {
+    // This time do a full collection.
+    return true;
+  } else {
+    // This time do a partial collection.
+    return false;
   }
 }
 
@@ -599,21 +585,10 @@
     }
   }
 
-  // Check if we want to do a full collection.
-  bool do_full_collection = true;
+  bool do_full_collection = false;
   {
     MutexLock mu(self, lock_);
-    if (current_capacity_ == max_capacity_) {
-      // Always do a full collection when the code cache is full.
-      do_full_collection = true;
-    } else if (current_capacity_ < kReservedCapacity) {
-      // Do a partial collection until we hit the reserved capacity limit.
-      do_full_collection = false;
-    } else if (has_done_full_collection_) {
-      // Do a partial collection if we have done a full collection in the last
-      // collection round.
-      do_full_collection = false;
-    }
+    do_full_collection = ShouldDoFullCollection();
   }
 
   if (!kIsDebugBuild || VLOG_IS_ON(jit)) {
@@ -624,45 +599,91 @@
               << ", data=" << PrettySize(DataCacheSize());
   }
 
-  if (do_full_collection) {
-    DoFullCollection(self);
-  } else {
-    RemoveUnusedCode(self);
-  }
-
-  {
-    MutexLock mu(self, lock_);
-    if (!do_full_collection) {
-      has_done_full_collection_ = false;
-      IncreaseCodeCacheCapacity();
-    } else {
-      has_done_full_collection_ = true;
-    }
-    live_bitmap_.reset(nullptr);
-    NotifyCollectionDone(self);
-  }
+  DoCollection(self, /* collect_profiling_info */ do_full_collection);
 
   if (!kIsDebugBuild || VLOG_IS_ON(jit)) {
     LOG(INFO) << "After code cache collection, code="
               << PrettySize(CodeCacheSize())
               << ", data=" << PrettySize(DataCacheSize());
   }
-}
 
-void JitCodeCache::DoFullCollection(Thread* self) {
-  instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
   {
     MutexLock mu(self, lock_);
-    // Walk over all compiled methods and set the entry points of these
-    // methods to interpreter.
-    for (auto& it : method_code_map_) {
-      instrumentation->UpdateMethodsCode(it.second, GetQuickToInterpreterBridge());
+
+    // Increase the code cache only when we do partial collections.
+    // TODO: base this strategy on how full the code cache is?
+    if (do_full_collection) {
+      last_collection_increased_code_cache_ = false;
+    } else {
+      last_collection_increased_code_cache_ = true;
+      IncreaseCodeCacheCapacity();
     }
 
-    // Clear the profiling info of methods that are not being compiled.
-    for (ProfilingInfo* info : profiling_infos_) {
-      if (!info->IsMethodBeingCompiled()) {
-        info->GetMethod()->SetProfilingInfo(nullptr);
+    bool next_collection_will_be_full = ShouldDoFullCollection();
+
+    // Start polling the liveness of compiled code to prepare for the next full collection.
+    // We avoid doing this if exit stubs are installed to not mess with the instrumentation.
+    // TODO(ngeoffray): Clean up instrumentation and code cache interactions.
+    if (!Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled() &&
+        next_collection_will_be_full) {
+      // Save the entry point of methods we have compiled, and update the entry
+      // point of those methods to the interpreter. If the method is invoked, the
+      // interpreter will update its entry point to the compiled code and call it.
+      for (ProfilingInfo* info : profiling_infos_) {
+        const void* entry_point = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+        if (ContainsPc(entry_point)) {
+          info->SetSavedEntryPoint(entry_point);
+          info->GetMethod()->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+        }
+      }
+
+      DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
+    }
+    live_bitmap_.reset(nullptr);
+    NotifyCollectionDone(self);
+  }
+}
+
+void JitCodeCache::RemoveUnusedAndUnmarkedCode(Thread* self) {
+  MutexLock mu(self, lock_);
+  ScopedCodeCacheWrite scc(code_map_.get());
+  // Iterate over all compiled code and remove entries that are not marked and not
+  // the entrypoint of their corresponding ArtMethod.
+  for (auto it = method_code_map_.begin(); it != method_code_map_.end();) {
+    const void* code_ptr = it->first;
+    ArtMethod* method = it->second;
+    uintptr_t allocation = FromCodeToAllocation(code_ptr);
+    const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
+    const void* entrypoint = method->GetEntryPointFromQuickCompiledCode();
+    if ((entrypoint == method_header->GetEntryPoint()) || GetLiveBitmap()->Test(allocation)) {
+      ++it;
+    } else {
+      if (entrypoint == GetQuickToInterpreterBridge()) {
+        method->ClearCounter();
+      }
+      FreeCode(code_ptr, method);
+      it = method_code_map_.erase(it);
+    }
+  }
+}
+
+void JitCodeCache::DoCollection(Thread* self, bool collect_profiling_info) {
+  {
+    MutexLock mu(self, lock_);
+    if (collect_profiling_info) {
+      // Clear the profiling info of methods that do not have compiled code as entrypoint.
+      // Also remove the saved entry point from the ProfilingInfo objects.
+      for (ProfilingInfo* info : profiling_infos_) {
+        const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+        if (!ContainsPc(ptr) && !info->IsMethodBeingCompiled()) {
+          info->GetMethod()->SetProfilingInfo(nullptr);
+        }
+        info->SetSavedEntryPoint(nullptr);
+      }
+    } else if (kIsDebugBuild) {
+      // Sanity check that the profiling infos do not have a dangling entry point.
+      for (ProfilingInfo* info : profiling_infos_) {
+        DCHECK(info->GetSavedEntryPoint() == nullptr);
       }
     }
 
@@ -674,41 +695,50 @@
   // Run a checkpoint on all threads to mark the JIT compiled code they are running.
   MarkCompiledCodeOnThreadStacks(self);
 
-  {
-    MutexLock mu(self, lock_);
-    // Free unused compiled code, and restore the entry point of used compiled code.
-    {
-      ScopedCodeCacheWrite scc(code_map_.get());
-      for (auto it = method_code_map_.begin(); it != method_code_map_.end();) {
-        const void* code_ptr = it->first;
-        ArtMethod* method = it->second;
-        uintptr_t allocation = FromCodeToAllocation(code_ptr);
-        const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
-        if (GetLiveBitmap()->Test(allocation)) {
-          instrumentation->UpdateMethodsCode(method, method_header->GetEntryPoint());
-          ++it;
-        } else {
-          method->ClearCounter();
-          DCHECK_NE(method->GetEntryPointFromQuickCompiledCode(), method_header->GetEntryPoint());
-          FreeCode(code_ptr, method);
-          it = method_code_map_.erase(it);
-        }
-      }
-    }
+  // Remove compiled code that is not the entrypoint of their method and not in the call
+  // stack.
+  RemoveUnusedAndUnmarkedCode(self);
 
-    // Free all profiling infos of methods that were not being compiled.
+  if (collect_profiling_info) {
+    MutexLock mu(self, lock_);
+    // Free all profiling infos of methods not compiled nor being compiled.
     auto profiling_kept_end = std::remove_if(profiling_infos_.begin(), profiling_infos_.end(),
       [this] (ProfilingInfo* info) NO_THREAD_SAFETY_ANALYSIS {
-        if (info->GetMethod()->GetProfilingInfo(sizeof(void*)) == nullptr) {
+        const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+        if (ContainsPc(ptr) && info->GetMethod()->GetProfilingInfo(sizeof(void*)) == nullptr) {
+          // Make sure compiled methods have a ProfilingInfo object. It is needed for
+          // code cache collection.
+          info->GetMethod()->SetProfilingInfo(info);
+        } else if (info->GetMethod()->GetProfilingInfo(sizeof(void*)) != info) {
+          // No need for this ProfilingInfo object anymore.
           FreeData(reinterpret_cast<uint8_t*>(info));
           return true;
         }
         return false;
       });
     profiling_infos_.erase(profiling_kept_end, profiling_infos_.end());
+    DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
   }
 }
 
+bool JitCodeCache::CheckLiveCompiledCodeHasProfilingInfo() {
+  // Check that methods we have compiled do have a ProfilingInfo object. We would
+  // have memory leaks of compiled code otherwise.
+  for (const auto& it : method_code_map_) {
+    ArtMethod* method = it.second;
+    if (method->GetProfilingInfo(sizeof(void*)) == nullptr) {
+      const void* code_ptr = it.first;
+      const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
+      if (method_header->GetEntryPoint() == method->GetEntryPointFromQuickCompiledCode()) {
+        // If the code is not dead, then we have a problem. Note that this can even
+        // happen just after a collection, as mutator threads are running in parallel
+        // and could deoptimize an existing compiled code.
+        return false;
+      }
+    }
+  }
+  return true;
+}
 
 OatQuickMethodHeader* JitCodeCache::LookupMethodHeader(uintptr_t pc, ArtMethod* method) {
   static_assert(kRuntimeISA != kThumb2, "kThumb2 cannot be a runtime ISA");
@@ -849,6 +879,13 @@
 
 void JitCodeCache::InvalidateCompiledCodeFor(ArtMethod* method,
                                              const OatQuickMethodHeader* header) {
+  ProfilingInfo* profiling_info = method->GetProfilingInfo(sizeof(void*));
+  if ((profiling_info != nullptr) &&
+      (profiling_info->GetSavedEntryPoint() == header->GetEntryPoint())) {
+    // Prevent future uses of the compiled code.
+    profiling_info->SetSavedEntryPoint(nullptr);
+  }
+
   if (method->GetEntryPointFromQuickCompiledCode() == header->GetEntryPoint()) {
     // The entrypoint is the one to invalidate, so we just update
     // it to the interpreter entry point and clear the counter to get the method
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 4574edf..7b33b92 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -124,6 +124,11 @@
     return live_bitmap_.get();
   }
 
+  // Return whether we should do a full collection given the current state of the cache.
+  bool ShouldDoFullCollection()
+      REQUIRES(lock_)
+      SHARED_REQUIRES(Locks::mutator_lock_);
+
   // Perform a collection on the code cache.
   void GarbageCollectCache(Thread* self)
       REQUIRES(!lock_)
@@ -235,11 +240,11 @@
   // Set the footprint limit of the code cache.
   void SetFootprintLimit(size_t new_footprint) REQUIRES(lock_);
 
-  void DoFullCollection(Thread* self)
+  void DoCollection(Thread* self, bool collect_profiling_info)
       REQUIRES(!lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
-  void RemoveUnusedCode(Thread* self)
+  void RemoveUnusedAndUnmarkedCode(Thread* self)
       REQUIRES(!lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
@@ -247,6 +252,10 @@
       REQUIRES(!lock_)
       SHARED_REQUIRES(Locks::mutator_lock_);
 
+  bool CheckLiveCompiledCodeHasProfilingInfo()
+      REQUIRES(lock_)
+      SHARED_REQUIRES(Locks::mutator_lock_);
+
   // Lock for guarding allocations, collections, and the method_code_map_.
   Mutex lock_;
   // Condition to wait on during collection.
@@ -282,8 +291,8 @@
   // The current footprint in bytes of the data portion of the code cache.
   size_t data_end_ GUARDED_BY(lock_);
 
-  // Whether a full collection has already been done on the current capacity.
-  bool has_done_full_collection_ GUARDED_BY(lock_);
+  // Whether the last collection round increased the code cache.
+  bool last_collection_increased_code_cache_ GUARDED_BY(lock_);
 
   // Last time the the code_cache was updated.
   // It is atomic to avoid locking when reading it.
diff --git a/runtime/jit/jit_instrumentation.cc b/runtime/jit/jit_instrumentation.cc
index 46c362a..d751e5a 100644
--- a/runtime/jit/jit_instrumentation.cc
+++ b/runtime/jit/jit_instrumentation.cc
@@ -187,7 +187,18 @@
     return;
   }
 
-  instrumentation_cache_->AddSamples(thread, method, 1);
+  ProfilingInfo* profiling_info = method->GetProfilingInfo(sizeof(void*));
+  // Update the entrypoint if the ProfilingInfo has one. The interpreter will call it
+  // instead of interpreting the method.
+  // We avoid doing this if exit stubs are installed to not mess with the instrumentation.
+  // TODO(ngeoffray): Clean up instrumentation and code cache interactions.
+  if ((profiling_info != nullptr) &&
+      (profiling_info->GetSavedEntryPoint() != nullptr) &&
+      !Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled()) {
+    method->SetEntryPointFromQuickCompiledCode(profiling_info->GetSavedEntryPoint());
+  } else {
+    instrumentation_cache_->AddSamples(thread, method, 1);
+  }
 }
 
 void JitInstrumentationListener::Branch(Thread* thread,
diff --git a/runtime/jit/profiling_info.h b/runtime/jit/profiling_info.h
index ab72373..d54f3df 100644
--- a/runtime/jit/profiling_info.h
+++ b/runtime/jit/profiling_info.h
@@ -126,11 +126,20 @@
     is_method_being_compiled_ = value;
   }
 
+  void SetSavedEntryPoint(const void* entry_point) {
+    saved_entry_point_ = entry_point;
+  }
+
+  const void* GetSavedEntryPoint() const {
+    return saved_entry_point_;
+  }
+
  private:
   ProfilingInfo(ArtMethod* method, const std::vector<uint32_t>& entries)
       : number_of_inline_caches_(entries.size()),
         method_(method),
-        is_method_being_compiled_(false) {
+        is_method_being_compiled_(false),
+        saved_entry_point_(nullptr) {
     memset(&cache_, 0, number_of_inline_caches_ * sizeof(InlineCache));
     for (size_t i = 0; i < number_of_inline_caches_; ++i) {
       cache_[i].dex_pc_ = entries[i];
@@ -148,6 +157,10 @@
   // TODO: Make the JIT code cache lock global.
   bool is_method_being_compiled_;
 
+  // Entry point of the corresponding ArtMethod, while the JIT code cache
+  // is poking for the liveness of compiled code.
+  const void* saved_entry_point_;
+
   // Dynamically allocated array of size `number_of_inline_caches_`.
   InlineCache cache_[0];
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index eb5455a..47ef214 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -316,6 +316,7 @@
   linear_alloc_.reset();
   low_4gb_arena_pool_.reset();
   arena_pool_.reset();
+  jit_arena_pool_.reset();
   MemMap::Shutdown();
   ATRACE_END();
 
@@ -1019,10 +1020,13 @@
   // Use MemMap arena pool for jit, malloc otherwise. Malloc arenas are faster to allocate but
   // can't be trimmed as easily.
   const bool use_malloc = IsAotCompiler();
-  arena_pool_.reset(new ArenaPool(use_malloc, false));
+  arena_pool_.reset(new ArenaPool(use_malloc, /* low_4gb */ false));
+  jit_arena_pool_.reset(
+      new ArenaPool(/* use_malloc */ false, /* low_4gb */ false, "CompilerMetadata"));
+
   if (IsAotCompiler() && Is64BitInstructionSet(kRuntimeISA)) {
     // 4gb, no malloc. Explanation in header.
-    low_4gb_arena_pool_.reset(new ArenaPool(false, true));
+    low_4gb_arena_pool_.reset(new ArenaPool(/* use_malloc */ false, /* low_4gb */ true));
   }
   linear_alloc_.reset(CreateLinearAlloc());
 
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 8aac4ce..83e77d2 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -561,6 +561,9 @@
   ArenaPool* GetArenaPool() {
     return arena_pool_.get();
   }
+  ArenaPool* GetJitArenaPool() {
+    return jit_arena_pool_.get();
+  }
   const ArenaPool* GetArenaPool() const {
     return arena_pool_.get();
   }
@@ -669,6 +672,7 @@
 
   gc::Heap* heap_;
 
+  std::unique_ptr<ArenaPool> jit_arena_pool_;
   std::unique_ptr<ArenaPool> arena_pool_;
   // Special low 4gb pool for compiler linear alloc. We need ArtFields to be in low 4gb if we are
   // compiling using a 32 bit image on a 64 bit compiler in case we resolve things in the image
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index d45e4bd..49d54fd 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -59,10 +59,6 @@
 static constexpr useconds_t kThreadSuspendMaxYieldUs = 3000;
 static constexpr useconds_t kThreadSuspendMaxSleepUs = 5000;
 
-// Whether we should try to dump the native stack of unattached threads. See commit ed8b723 for
-// some history.
-static constexpr bool kDumpUnattachedThreadNativeStack = true;
-
 ThreadList::ThreadList()
     : suspend_all_count_(0),
       debug_suspend_all_count_(0),
@@ -153,7 +149,9 @@
   // refactor DumpState to avoid skipping analysis.
   Thread::DumpState(os, nullptr, tid);
   DumpKernelStack(os, tid, "  kernel: ", false);
-  if (kDumpUnattachedThreadNativeStack) {
+  // TODO: Reenable this when the native code in system_server can handle it.
+  // Currently "adb shell kill -3 `pid system_server`" will cause it to exit.
+  if (false) {
     DumpNativeStack(os, tid, nullptr, "  native: ");
   }
   os << "\n";
diff --git a/test/004-ReferenceMap/build b/test/004-ReferenceMap/build
deleted file mode 100644
index 08987b5..0000000
--- a/test/004-ReferenceMap/build
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2015 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.
-
-# Stop if something fails.
-set -e
-
-# The test relies on DEX file produced by javac+dx so keep building with them for now
-# (see b/19467889)
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \
-  --dump-width=1000 ${DX_FLAGS} classes
-zip $TEST_NAME.jar classes.dex
diff --git a/test/004-ReferenceMap/stack_walk_refmap_jni.cc b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
index 2dbd7e8..2d26fa1 100644
--- a/test/004-ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
@@ -65,19 +65,19 @@
       // We eliminate the non-live registers at a return, so only v3 is live.
       // Note that it is OK for a compiler to not have a dex map at this dex PC because
       // a return is not necessarily a safepoint.
-      CHECK_REGS_CONTAIN_REFS(0x13U, false, 3);  // v3: y
+      CHECK_REGS_CONTAIN_REFS(0x14U, false, 2);  // v2: y
       // Note that v0: ex can be eliminated because it's a dead merge of two different exceptions.
       CHECK_REGS_CONTAIN_REFS(0x18U, true, 8, 2, 1);  // v8: this, v2: y, v1: x (dead v0: ex)
       if (!GetCurrentOatQuickMethodHeader()->IsOptimized()) {
-        // v8: this, v5: x[1], v2: y, v1: x (dead v0: ex)
-        CHECK_REGS_CONTAIN_REFS(0x1aU, true, 8, 5, 2, 1);
-        // v8: this, v5: x[1], v2: y, v1: x (dead v0: ex)
-        CHECK_REGS_CONTAIN_REFS(0x1dU, true, 8, 5, 2, 1);
-        // v5 is removed from the root set because there is a "merge" operation.
-        // See 0015: if-nez v2, 001f.
-        CHECK_REGS_CONTAIN_REFS(0x1fU, true, 8, 2, 1);  // v8: this, v2: y, v1: x (dead v0: ex)
+        // v8: this, v4: x[1], v2: y, v1: x (dead v0: ex)
+        CHECK_REGS_CONTAIN_REFS(0x1aU, true, 8, 4, 2, 1);
+        // v8: this, v4: x[1], v2: y, v1: x (dead v0: ex)
+        CHECK_REGS_CONTAIN_REFS(0x1eU, true, 8, 4, 2, 1);
+        // v4 is removed from the root set because there is a "merge" operation.
+        // See 0016: if-nez v2, 0020.
+        CHECK_REGS_CONTAIN_REFS(0x20U, true, 8, 2, 1);  // v8: this, v2: y, v1: x (dead v0: ex)
       }
-      CHECK_REGS_CONTAIN_REFS(0x21U, true, 8, 2, 1);  // v8: this, v2: y, v1: x (dead v0: ex)
+      CHECK_REGS_CONTAIN_REFS(0x22U, true, 8, 2, 1);  // v8: this, v2: y, v1: x (dead v0: ex)
 
       if (!GetCurrentOatQuickMethodHeader()->IsOptimized()) {
         CHECK_REGS_CONTAIN_REFS(0x27U, true, 8, 4, 2, 1);  // v8: this, v4: ex, v2: y, v1: x
@@ -94,124 +94,79 @@
   }
 };
 
-// Dex instructions for the function 'f' in ReferenceMap.java
-// Virtual methods   -
-//    #0              : (in LReferenceMap;)
-//      name          : 'f'
-//      type          : '()Ljava/lang/Object;'
-//      access        : 0x0000 ()
-//      code          -
-//      registers     : 9
-//      ins           : 1
-//      outs          : 2
-//      insns size    : 51 16-bit code units
-//      |[0001e8] ReferenceMap.f:()Ljava/lang/Object;
-//      |0000: const/4 v4, #int 2 // #2
-//      |0001: const/4 v7, #int 0 // #0
-//      |0002: const/4 v6, #int 1 // #1
+// DEX code
 //
-// 0:[Unknown],1:[Unknown],2:[Unknown],3:[Unknown],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0003: new-array v1, v4, [Ljava/lang/Object;  // type@0007
-//      |0005: const/4 v2, #int 0 // #0
-
-// 0:[Unknown],1:[Reference: java.lang.Object[]],2:[Zero],3:[Unknown],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0006: new-instance v3, Ljava/lang/Object;  // type@0003
-
-// [Unknown],1:[Reference: java.lang.Object[]],2:[Zero],3:[Uninitialized Reference: java.lang.Object],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0008: +invoke-object-init/range {}, Ljava/lang/Object;.<init>:()V // method@0005
-//      |000b: const/4 v4, #int 2 // #2
-
-// 0:[Unknown],1:[Reference: java.lang.Object[]],2:[Zero],3:[Reference: java.lang.Object],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |000c: aput-object v3, v1, v4
-
-// 0:[Unknown],1:[Reference: java.lang.Object[]],2:[Zero],3:[Reference: java.lang.Object],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |000e: aput-object v3, v1, v6
-
-// 0:[Unknown],1:[Reference: java.lang.Object[]],2:[Zero],3:[Reference: java.lang.Object],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0010: +invoke-virtual-quick {v8, v7}, [000c] // vtable #000c
-
-// 0:[Conflict],1:[Conflict],2:[Conflict],3:[Reference: java.lang.Object],4:[Conflict],5:[Conflict],6:[Conflict],7:[Conflict],8:[Conflict],
-//      |0013: return-object v3
-//      |0014: move-exception v0
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0015: if-nez v2, 001f // +000a
-//      |0017: const/4 v4, #int 1 // #1
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[32-bit Constant: 1],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0018: new-instance v5, Ljava/lang/Object;  // type@0003
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[32-bit Constant: 1],5:[Uninitialized Reference: java.lang.Object],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |001a: +invoke-object-init/range {}, Ljava/lang/Object;.<init>:()V // method@0005
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[32-bit Constant: 1],5:[Reference: java.lang.Object],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |001d: aput-object v5, v1, v4
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[32-bit Constant: 2],5:[Conflict],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |001f: aput-object v2, v1, v6
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[32-bit Constant: 2],5:[Conflict],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0021: +invoke-virtual-quick {v8, v7}, [000c] // vtable #000c
-//      |0024: move-object v3, v2
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Reference: java.lang.Object],4:[32-bit Constant: 2],5:[Conflict],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0025: goto 0013 // -0012
-//      |0026: move-exception v4
-
-// 0:[Conflict],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[Reference: java.lang.Throwable],5:[Conflict],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0027: aput-object v2, v1, v6
-
-// 0:[Conflict],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[Reference: java.lang.Throwable],5:[Conflict],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0029: +invoke-virtual-quick {v8, v7}, [000c] // vtable #000c
-
-// 0:[Conflict],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Conflict],4:[Reference: java.lang.Throwable],5:[Conflict],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |002c: throw v4
-//      |002d: move-exception v4
-//      |002e: move-object v2, v3
-
-// 0:[Unknown],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Reference: java.lang.Object],4:[Reference: java.lang.Throwable],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |002f: goto 0027 // -0008
-//      |0030: move-exception v0
-//      |0031: move-object v2, v3
-
-// 0:[Reference: java.lang.Exception],1:[Reference: java.lang.Object[]],2:[Reference: java.lang.Object],3:[Reference: java.lang.Object],4:[32-bit Constant: 2],5:[Unknown],6:[32-bit Constant: 1],7:[Zero],8:[Reference: ReferenceMap],
-//      |0032: goto 0015 // -001d
-//      catches       : 3
-//        0x0006 - 0x000b
-//          Ljava/lang/Exception; -> 0x0014
-//          <any> -> 0x0026
-//        0x000c - 0x000e
-//          Ljava/lang/Exception; -> 0x0030
-//          <any> -> 0x002d
-//        0x0018 - 0x001f
-//          <any> -> 0x0026
-//      positions     :
-//        0x0003 line=8
-//        0x0005 line=9
-//        0x0006 line=11
-//        0x000b line=12
-//        0x000e line=18
-//        0x0010 line=19
-//        0x0013 line=21
-//        0x0014 line=13
-//        0x0015 line=14
-//        0x0017 line=15
-//        0x001f line=18
-//        0x0021 line=19
-//        0x0025 line=20
-//        0x0026 line=18
-//        0x0029 line=19
-//        0x002d line=18
-//        0x0030 line=13
-//      locals        :
-//        0x0006 - 0x000b reg=2 y Ljava/lang/Object;
-//        0x000b - 0x0013 reg=3 y Ljava/lang/Object;
-//        0x0014 - 0x0015 reg=2 y Ljava/lang/Object;
-//        0x0015 - 0x0026 reg=0 ex Ljava/lang/Exception;
-//        0x002d - 0x0032 reg=3 y Ljava/lang/Object;
-//        0x0005 - 0x0033 reg=1 x [Ljava/lang/Object;
-//        0x0032 - 0x0033 reg=2 y Ljava/lang/Object;
-//        0x0000 - 0x0033 reg=8 this LReferenceMap;
+// 0000: const/4 v4, #int 2 // #2
+// 0001: const/4 v7, #int 0 // #0
+// 0002: const/4 v6, #int 1 // #1
+// 0003: new-array v1, v4, [Ljava/lang/Object; // type@0007
+// 0005: const/4 v2, #int 0 // #0
+// 0006: new-instance v3, Ljava/lang/Object; // type@0003
+// 0008: invoke-direct {v3}, Ljava/lang/Object;.<init>:()V // method@0004
+// 000b: const/4 v4, #int 2 // #2
+// 000c: aput-object v3, v1, v4
+// 000e: aput-object v3, v1, v6
+// 0010: invoke-virtual {v8, v7}, LMain;.refmap:(I)I // method@0003
+// 0013: move-object v2, v3
+// 0014: return-object v2
+// 0015: move-exception v0
+// 0016: if-nez v2, 0020 // +000a
+// 0018: new-instance v4, Ljava/lang/Object; // type@0003
+// 001a: invoke-direct {v4}, Ljava/lang/Object;.<init>:()V // method@0004
+// 001d: const/4 v5, #int 1 // #1
+// 001e: aput-object v4, v1, v5
+// 0020: aput-object v2, v1, v6
+// 0022: invoke-virtual {v8, v7}, LMain;.refmap:(I)I // method@0003
+// 0025: goto 0014 // -0011
+// 0026: move-exception v4
+// 0027: aput-object v2, v1, v6
+// 0029: invoke-virtual {v8, v7}, LMain;.refmap:(I)I // method@0003
+// 002c: throw v4
+// 002d: move-exception v4
+// 002e: move-object v2, v3
+// 002f: goto 0027 // -0008
+// 0030: move-exception v0
+// 0031: move-object v2, v3
+// 0032: goto 0016 // -001c
+//    catches       : 3
+//      0x0006 - 0x000b
+//        Ljava/lang/Exception; -> 0x0015
+//        <any> -> 0x0026
+//      0x000c - 0x000e
+//        Ljava/lang/Exception; -> 0x0030
+//        <any> -> 0x002d
+//      0x0018 - 0x0020
+//        <any> -> 0x0026
+//    positions     :
+//      0x0003 line=22
+//      0x0005 line=23
+//      0x0006 line=25
+//      0x000b line=26
+//      0x000e line=32
+//      0x0010 line=33
+//      0x0014 line=35
+//      0x0015 line=27
+//      0x0016 line=28
+//      0x0018 line=29
+//      0x0020 line=32
+//      0x0022 line=33
+//      0x0026 line=31
+//      0x0027 line=32
+//      0x0029 line=33
+//      0x002c line=31
+//      0x0030 line=27
+//    locals        :
+//      0x0006 - 0x000b reg=2 y Ljava/lang/Object;
+//      0x000b - 0x0014 reg=3 y Ljava/lang/Object;
+//      0x0015 - 0x0016 reg=2 y Ljava/lang/Object;
+//      0x0016 - 0x0026 reg=0 ex Ljava/lang/Exception;
+//      0x002d - 0x002f reg=3 y Ljava/lang/Object;
+//      0x002f - 0x0030 reg=2 y Ljava/lang/Object;
+//      0x0030 - 0x0032 reg=3 y Ljava/lang/Object;
+//      0x0031 - 0x0033 reg=0 ex Ljava/lang/Exception;
+//      0x0005 - 0x0033 reg=1 x [Ljava/lang/Object;
+//      0x0032 - 0x0033 reg=2 y Ljava/lang/Object;
+//      0x0000 - 0x0033 reg=8 this LMain;
 
 extern "C" JNIEXPORT jint JNICALL Java_Main_refmap(JNIEnv*, jobject, jint count) {
   // Visitor
diff --git a/test/004-StackWalk/build b/test/004-StackWalk/build
deleted file mode 100644
index 08987b5..0000000
--- a/test/004-StackWalk/build
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2015 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.
-
-# Stop if something fails.
-set -e
-
-# The test relies on DEX file produced by javac+dx so keep building with them for now
-# (see b/19467889)
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \
-  --dump-width=1000 ${DX_FLAGS} classes
-zip $TEST_NAME.jar classes.dex
diff --git a/test/004-StackWalk/stack_walk_jni.cc b/test/004-StackWalk/stack_walk_jni.cc
index 3a5854b..51bb68f 100644
--- a/test/004-StackWalk/stack_walk_jni.cc
+++ b/test/004-StackWalk/stack_walk_jni.cc
@@ -42,31 +42,31 @@
     // Given the method name and the number of times the method has been called,
     // we know the Dex registers with live reference values. Assert that what we
     // find is what is expected.
-    if (m_name == "f") {
+    if (m_name == "$noinline$f") {
       if (gJava_StackWalk_refmap_calls == 1) {
         CHECK_EQ(1U, GetDexPc());
-        CHECK_REGS(4);
+        CHECK_REGS(1);  // v1: this
       } else {
         CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
         CHECK_EQ(5U, GetDexPc());
-        CHECK_REGS(4);
+        CHECK_REGS(1);  // v1: this
       }
     } else if (m_name == "g") {
       if (gJava_StackWalk_refmap_calls == 1) {
-        CHECK_EQ(0xcU, GetDexPc());
-        CHECK_REGS(0, 2);  // Note that v1 is not in the minimal root set
+        CHECK_EQ(0xdU, GetDexPc());
+        CHECK_REGS(0, 2);  // v2: this (Note that v1 is not in the minimal root set)
       } else {
         CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
-        CHECK_EQ(0xcU, GetDexPc());
+        CHECK_EQ(0xdU, GetDexPc());
         CHECK_REGS(0, 2);
       }
     } else if (m_name == "shlemiel") {
       if (gJava_StackWalk_refmap_calls == 1) {
-        CHECK_EQ(0x380U, GetDexPc());
+        CHECK_EQ(0x393U, GetDexPc());
         CHECK_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
       } else {
         CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
-        CHECK_EQ(0x380U, GetDexPc());
+        CHECK_EQ(0x393U, GetDexPc());
         CHECK_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
       }
     }
diff --git a/test/089-many-methods/build b/test/089-many-methods/build
index ff77c60..58144e1 100644
--- a/test/089-many-methods/build
+++ b/test/089-many-methods/build
@@ -43,8 +43,4 @@
     printf("}\n") > fileName;
 }'
 
-# The test relies on the error message produced by dx, not jack, so keep building with dx for now
-# (b/19467889).
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx1024m --dex --no-optimize classes
+./default-build
diff --git a/test/089-many-methods/expected.txt b/test/089-many-methods/expected.txt
index b74e0ee..bfee8b3 100644
--- a/test/089-many-methods/expected.txt
+++ b/test/089-many-methods/expected.txt
@@ -1,6 +1,2 @@
-
-trouble writing output: Too many field references: 131000; max is 65536.
-You may try using --multi-dex option.
-References by package:
-131000 default
-build exit status: 2
+ERROR: Dex writing phase: classes.dex has too many IDs. Try using multi-dex
+build exit status: 4
diff --git a/test/138-duplicate-classes-check2/build b/test/138-duplicate-classes-check2/build
index abcbbb8..d346251 100755
--- a/test/138-duplicate-classes-check2/build
+++ b/test/138-duplicate-classes-check2/build
@@ -24,9 +24,17 @@
 ${JAVAC} -d classes-ex `find src-ex -name '*.java'`
 rm classes-ex/A.class
 
-if [ ${NEED_DEX} = "true" ]; then
+if [ ${USE_JACK} = "true" ]; then
+  jar cf classes.jill.jar -C classes .
+  ${JACK} --import classes.jill.jar --output-dex .
+  zip ${TEST_NAME}.jar classes.dex
+
+  jar cf classes-ex.jill.jar -C classes-ex .
+  ${JACK} --import classes-ex.jill.jar --output-dex .
+  zip ${TEST_NAME}-ex.jar classes.dex
+elif [ ${NEED_DEX} = "true" ]; then
   ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 classes
-  zip $TEST_NAME.jar classes.dex
+  zip ${TEST_NAME}.jar classes.dex
   ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 classes-ex
   zip ${TEST_NAME}-ex.jar classes.dex
 fi
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index 93fe397..b7712a7 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -51,6 +51,21 @@
     }
   }
 
+  private static int $inline$int(int x) {
+    return x;
+  }
+
+  private static long $inline$long(long x) {
+    return x;
+  }
+
+  private static float $inline$float(float x) {
+    return x;
+  }
+
+  private static double $inline$double(double x) {
+    return x;
+  }
 
   // Wrappers around methods located in file TestCmp.smali.
 
@@ -194,121 +209,119 @@
     return y;
   }
 
-
   /**
    * Exercise constant folding on addition.
    */
 
-  /// CHECK-START: int Main.IntAddition1() constant_folding (before)
+  /// CHECK-START: int Main.IntAddition1() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const1:i\d+>>  IntConstant 1
   /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
   /// CHECK-DAG:     <<Add:i\d+>>     Add [<<Const1>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Add>>]
 
-  /// CHECK-START: int Main.IntAddition1() constant_folding (after)
+  /// CHECK-START: int Main.IntAddition1() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const3:i\d+>>  IntConstant 3
   /// CHECK-DAG:                      Return [<<Const3>>]
 
-  /// CHECK-START: int Main.IntAddition1() constant_folding (after)
+  /// CHECK-START: int Main.IntAddition1() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Add
 
   public static int IntAddition1() {
     int a, b, c;
-    a = 1;
-    b = 2;
+    a = $inline$int(1);
+    b = $inline$int(2);
     c = a + b;
     return c;
   }
 
-  /// CHECK-START: int Main.IntAddition2() constant_folding (before)
+  /// CHECK-START: int Main.IntAddition2() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const1:i\d+>>  IntConstant 1
   /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
   /// CHECK-DAG:     <<Const5:i\d+>>  IntConstant 5
   /// CHECK-DAG:     <<Const6:i\d+>>  IntConstant 6
-  /// CHECK-DAG:     <<Const11:i\d+>> IntConstant 11
   /// CHECK-DAG:     <<Add1:i\d+>>    Add [<<Const1>>,<<Const2>>]
-  /// CHECK-DAG:                      Add [<<Const5>>,<<Const6>>]
-  /// CHECK-DAG:     <<Add3:i\d+>>    Add [<<Add1>>,<<Const11>>]
+  /// CHECK-DAG:     <<Add2:i\d+>>    Add [<<Const5>>,<<Const6>>]
+  /// CHECK-DAG:     <<Add3:i\d+>>    Add [<<Add1>>,<<Add2>>]
   /// CHECK-DAG:                      Return [<<Add3>>]
 
-  /// CHECK-START: int Main.IntAddition2() constant_folding (after)
+  /// CHECK-START: int Main.IntAddition2() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const14:i\d+>> IntConstant 14
   /// CHECK-DAG:                      Return [<<Const14>>]
 
-  /// CHECK-START: int Main.IntAddition2() constant_folding (after)
+  /// CHECK-START: int Main.IntAddition2() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Add
 
   public static int IntAddition2() {
     int a, b, c;
-    a = 1;
-    b = 2;
+    a = $inline$int(1);
+    b = $inline$int(2);
     a += b;
-    b = 5;
-    c = 6;
+    b = $inline$int(5);
+    c = $inline$int(6);
     b += c;
     c = a + b;
     return c;
   }
 
-  /// CHECK-START: long Main.LongAddition() constant_folding (before)
+  /// CHECK-START: long Main.LongAddition() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const1:j\d+>>  LongConstant 1
   /// CHECK-DAG:     <<Const2:j\d+>>  LongConstant 2
   /// CHECK-DAG:     <<Add:j\d+>>     Add [<<Const1>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Add>>]
 
-  /// CHECK-START: long Main.LongAddition() constant_folding (after)
+  /// CHECK-START: long Main.LongAddition() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const3:j\d+>>  LongConstant 3
   /// CHECK-DAG:                      Return [<<Const3>>]
 
-  /// CHECK-START: long Main.LongAddition() constant_folding (after)
+  /// CHECK-START: long Main.LongAddition() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Add
 
   public static long LongAddition() {
     long a, b, c;
-    a = 1L;
-    b = 2L;
+    a = $inline$long(1L);
+    b = $inline$long(2L);
     c = a + b;
     return c;
   }
 
-  /// CHECK-START: float Main.FloatAddition() constant_folding (before)
+  /// CHECK-START: float Main.FloatAddition() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const1:f\d+>>  FloatConstant 1
   /// CHECK-DAG:     <<Const2:f\d+>>  FloatConstant 2
   /// CHECK-DAG:     <<Add:f\d+>>     Add [<<Const1>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Add>>]
 
-  /// CHECK-START: float Main.FloatAddition() constant_folding (after)
+  /// CHECK-START: float Main.FloatAddition() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const3:f\d+>>  FloatConstant 3
   /// CHECK-DAG:                      Return [<<Const3>>]
 
-  /// CHECK-START: float Main.FloatAddition() constant_folding (after)
+  /// CHECK-START: float Main.FloatAddition() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Add
 
   public static float FloatAddition() {
     float a, b, c;
-    a = 1F;
-    b = 2F;
+    a = $inline$float(1F);
+    b = $inline$float(2F);
     c = a + b;
     return c;
   }
 
-  /// CHECK-START: double Main.DoubleAddition() constant_folding (before)
+  /// CHECK-START: double Main.DoubleAddition() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const1:d\d+>>  DoubleConstant 1
   /// CHECK-DAG:     <<Const2:d\d+>>  DoubleConstant 2
   /// CHECK-DAG:     <<Add:d\d+>>     Add [<<Const1>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Add>>]
 
-  /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
+  /// CHECK-START: double Main.DoubleAddition() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const3:d\d+>>  DoubleConstant 3
   /// CHECK-DAG:                      Return [<<Const3>>]
 
-  /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
+  /// CHECK-START: double Main.DoubleAddition() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Add
 
   public static double DoubleAddition() {
     double a, b, c;
-    a = 1D;
-    b = 2D;
+    a = $inline$double(1D);
+    b = $inline$double(2D);
     c = a + b;
     return c;
   }
@@ -318,86 +331,86 @@
    * Exercise constant folding on subtraction.
    */
 
-  /// CHECK-START: int Main.IntSubtraction() constant_folding (before)
+  /// CHECK-START: int Main.IntSubtraction() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const6:i\d+>>  IntConstant 6
   /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<Const6>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Sub>>]
 
-  /// CHECK-START: int Main.IntSubtraction() constant_folding (after)
+  /// CHECK-START: int Main.IntSubtraction() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const4:i\d+>>  IntConstant 4
   /// CHECK-DAG:                      Return [<<Const4>>]
 
-  /// CHECK-START: int Main.IntSubtraction() constant_folding (after)
+  /// CHECK-START: int Main.IntSubtraction() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Sub
 
   public static int IntSubtraction() {
     int a, b, c;
-    a = 6;
-    b = 2;
+    a = $inline$int(6);
+    b = $inline$int(2);
     c = a - b;
     return c;
   }
 
-  /// CHECK-START: long Main.LongSubtraction() constant_folding (before)
+  /// CHECK-START: long Main.LongSubtraction() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const6:j\d+>>  LongConstant 6
   /// CHECK-DAG:     <<Const2:j\d+>>  LongConstant 2
   /// CHECK-DAG:     <<Sub:j\d+>>     Sub [<<Const6>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Sub>>]
 
-  /// CHECK-START: long Main.LongSubtraction() constant_folding (after)
+  /// CHECK-START: long Main.LongSubtraction() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const4:j\d+>>  LongConstant 4
   /// CHECK-DAG:                      Return [<<Const4>>]
 
-  /// CHECK-START: long Main.LongSubtraction() constant_folding (after)
+  /// CHECK-START: long Main.LongSubtraction() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Sub
 
   public static long LongSubtraction() {
     long a, b, c;
-    a = 6L;
-    b = 2L;
+    a = $inline$long(6L);
+    b = $inline$long(2L);
     c = a - b;
     return c;
   }
 
-  /// CHECK-START: float Main.FloatSubtraction() constant_folding (before)
+  /// CHECK-START: float Main.FloatSubtraction() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const6:f\d+>>  FloatConstant 6
   /// CHECK-DAG:     <<Const2:f\d+>>  FloatConstant 2
   /// CHECK-DAG:     <<Sub:f\d+>>     Sub [<<Const6>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Sub>>]
 
-  /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
+  /// CHECK-START: float Main.FloatSubtraction() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const4:f\d+>>  FloatConstant 4
   /// CHECK-DAG:                      Return [<<Const4>>]
 
-  /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
+  /// CHECK-START: float Main.FloatSubtraction() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Sub
 
   public static float FloatSubtraction() {
     float a, b, c;
-    a = 6F;
-    b = 2F;
+    a = $inline$float(6F);
+    b = $inline$float(2F);
     c = a - b;
     return c;
   }
 
-  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (before)
+  /// CHECK-START: double Main.DoubleSubtraction() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const6:d\d+>>  DoubleConstant 6
   /// CHECK-DAG:     <<Const2:d\d+>>  DoubleConstant 2
   /// CHECK-DAG:     <<Sub:d\d+>>     Sub [<<Const6>>,<<Const2>>]
   /// CHECK-DAG:                      Return [<<Sub>>]
 
-  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
+  /// CHECK-START: double Main.DoubleSubtraction() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const4:d\d+>>  DoubleConstant 4
   /// CHECK-DAG:                      Return [<<Const4>>]
 
-  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
+  /// CHECK-START: double Main.DoubleSubtraction() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Sub
 
   public static double DoubleSubtraction() {
     double a, b, c;
-    a = 6D;
-    b = 2D;
+    a = $inline$double(6D);
+    b = $inline$double(2D);
     c = a - b;
     return c;
   }
@@ -407,86 +420,86 @@
    * Exercise constant folding on multiplication.
    */
 
-  /// CHECK-START: int Main.IntMultiplication() constant_folding (before)
+  /// CHECK-START: int Main.IntMultiplication() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const7:i\d+>>  IntConstant 7
   /// CHECK-DAG:     <<Const3:i\d+>>  IntConstant 3
   /// CHECK-DAG:     <<Mul:i\d+>>     Mul [<<Const7>>,<<Const3>>]
   /// CHECK-DAG:                      Return [<<Mul>>]
 
-  /// CHECK-START: int Main.IntMultiplication() constant_folding (after)
+  /// CHECK-START: int Main.IntMultiplication() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const21:i\d+>> IntConstant 21
   /// CHECK-DAG:                      Return [<<Const21>>]
 
-  /// CHECK-START: int Main.IntMultiplication() constant_folding (after)
+  /// CHECK-START: int Main.IntMultiplication() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Mul
 
   public static int IntMultiplication() {
     int a, b, c;
-    a = 7;
-    b = 3;
+    a = $inline$int(7);
+    b = $inline$int(3);
     c = a * b;
     return c;
   }
 
-  /// CHECK-START: long Main.LongMultiplication() constant_folding (before)
+  /// CHECK-START: long Main.LongMultiplication() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const7:j\d+>>  LongConstant 7
   /// CHECK-DAG:     <<Const3:j\d+>>  LongConstant 3
   /// CHECK-DAG:     <<Mul:j\d+>>     Mul [<<Const7>>,<<Const3>>]
   /// CHECK-DAG:                      Return [<<Mul>>]
 
-  /// CHECK-START: long Main.LongMultiplication() constant_folding (after)
+  /// CHECK-START: long Main.LongMultiplication() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const21:j\d+>> LongConstant 21
   /// CHECK-DAG:                      Return [<<Const21>>]
 
-  /// CHECK-START: long Main.LongMultiplication() constant_folding (after)
+  /// CHECK-START: long Main.LongMultiplication() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Mul
 
   public static long LongMultiplication() {
     long a, b, c;
-    a = 7L;
-    b = 3L;
+    a = $inline$long(7L);
+    b = $inline$long(3L);
     c = a * b;
     return c;
   }
 
-  /// CHECK-START: float Main.FloatMultiplication() constant_folding (before)
+  /// CHECK-START: float Main.FloatMultiplication() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const7:f\d+>>  FloatConstant 7
   /// CHECK-DAG:     <<Const3:f\d+>>  FloatConstant 3
   /// CHECK-DAG:     <<Mul:f\d+>>     Mul [<<Const7>>,<<Const3>>]
   /// CHECK-DAG:                      Return [<<Mul>>]
 
-  /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
+  /// CHECK-START: float Main.FloatMultiplication() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const21:f\d+>> FloatConstant 21
   /// CHECK-DAG:                      Return [<<Const21>>]
 
-  /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
+  /// CHECK-START: float Main.FloatMultiplication() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Mul
 
   public static float FloatMultiplication() {
     float a, b, c;
-    a = 7F;
-    b = 3F;
+    a = $inline$float(7F);
+    b = $inline$float(3F);
     c = a * b;
     return c;
   }
 
-  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (before)
+  /// CHECK-START: double Main.DoubleMultiplication() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const7:d\d+>>  DoubleConstant 7
   /// CHECK-DAG:     <<Const3:d\d+>>  DoubleConstant 3
   /// CHECK-DAG:     <<Mul:d\d+>>     Mul [<<Const7>>,<<Const3>>]
   /// CHECK-DAG:                      Return [<<Mul>>]
 
-  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
+  /// CHECK-START: double Main.DoubleMultiplication() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const21:d\d+>> DoubleConstant 21
   /// CHECK-DAG:                      Return [<<Const21>>]
 
-  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
+  /// CHECK-START: double Main.DoubleMultiplication() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Mul
 
   public static double DoubleMultiplication() {
     double a, b, c;
-    a = 7D;
-    b = 3D;
+    a = $inline$double(7D);
+    b = $inline$double(3D);
     c = a * b;
     return c;
   }
@@ -496,90 +509,90 @@
    * Exercise constant folding on division.
    */
 
-  /// CHECK-START: int Main.IntDivision() constant_folding (before)
+  /// CHECK-START: int Main.IntDivision() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:i\d+>>   IntConstant 8
   /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
   /// CHECK-DAG:     <<Div0Chk:i\d+>>  DivZeroCheck [<<Const3>>]
   /// CHECK-DAG:     <<Div:i\d+>>      Div [<<Const8>>,<<Div0Chk>>]
   /// CHECK-DAG:                       Return [<<Div>>]
 
-  /// CHECK-START: int Main.IntDivision() constant_folding (after)
+  /// CHECK-START: int Main.IntDivision() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
   /// CHECK-DAG:                       Return [<<Const2>>]
 
-  /// CHECK-START: int Main.IntDivision() constant_folding (after)
+  /// CHECK-START: int Main.IntDivision() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       DivZeroCheck
   /// CHECK-NOT:                       Div
 
   public static int IntDivision() {
     int a, b, c;
-    a = 8;
-    b = 3;
+    a = $inline$int(8);
+    b = $inline$int(3);
     c = a / b;
     return c;
   }
 
-  /// CHECK-START: long Main.LongDivision() constant_folding (before)
+  /// CHECK-START: long Main.LongDivision() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:j\d+>>   LongConstant 8
   /// CHECK-DAG:     <<Const3:j\d+>>   LongConstant 3
   /// CHECK-DAG:     <<Div0Chk:j\d+>>  DivZeroCheck [<<Const3>>]
   /// CHECK-DAG:     <<Div:j\d+>>      Div [<<Const8>>,<<Div0Chk>>]
   /// CHECK-DAG:                       Return [<<Div>>]
 
-  /// CHECK-START: long Main.LongDivision() constant_folding (after)
+  /// CHECK-START: long Main.LongDivision() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
   /// CHECK-DAG:                       Return [<<Const2>>]
 
-  /// CHECK-START: long Main.LongDivision() constant_folding (after)
+  /// CHECK-START: long Main.LongDivision() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       DivZeroCheck
   /// CHECK-NOT:                       Div
 
   public static long LongDivision() {
     long a, b, c;
-    a = 8L;
-    b = 3L;
+    a = $inline$long(8L);
+    b = $inline$long(3L);
     c = a / b;
     return c;
   }
 
-  /// CHECK-START: float Main.FloatDivision() constant_folding (before)
+  /// CHECK-START: float Main.FloatDivision() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:f\d+>>   FloatConstant 8
   /// CHECK-DAG:     <<Const2P5:f\d+>> FloatConstant 2.5
   /// CHECK-DAG:     <<Div:f\d+>>      Div [<<Const8>>,<<Const2P5>>]
   /// CHECK-DAG:                       Return [<<Div>>]
 
-  /// CHECK-START: float Main.FloatDivision() constant_folding (after)
+  /// CHECK-START: float Main.FloatDivision() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const3P2:f\d+>> FloatConstant 3.2
   /// CHECK-DAG:                       Return [<<Const3P2>>]
 
-  /// CHECK-START: float Main.FloatDivision() constant_folding (after)
+  /// CHECK-START: float Main.FloatDivision() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Div
 
   public static float FloatDivision() {
     float a, b, c;
-    a = 8F;
-    b = 2.5F;
+    a = $inline$float(8F);
+    b = $inline$float(2.5F);
     c = a / b;
     return c;
   }
 
-  /// CHECK-START: double Main.DoubleDivision() constant_folding (before)
+  /// CHECK-START: double Main.DoubleDivision() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:d\d+>>   DoubleConstant 8
   /// CHECK-DAG:     <<Const2P5:d\d+>> DoubleConstant 2.5
   /// CHECK-DAG:     <<Div:d\d+>>      Div [<<Const8>>,<<Const2P5>>]
   /// CHECK-DAG:                       Return [<<Div>>]
 
-  /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
+  /// CHECK-START: double Main.DoubleDivision() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const3P2:d\d+>> DoubleConstant 3.2
   /// CHECK-DAG:                       Return [<<Const3P2>>]
 
-  /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
+  /// CHECK-START: double Main.DoubleDivision() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Div
 
   public static double DoubleDivision() {
     double a, b, c;
-    a = 8D;
-    b = 2.5D;
+    a = $inline$double(8D);
+    b = $inline$double(2.5D);
     c = a / b;
     return c;
   }
@@ -589,90 +602,90 @@
    * Exercise constant folding on remainder.
    */
 
-  /// CHECK-START: int Main.IntRemainder() constant_folding (before)
+  /// CHECK-START: int Main.IntRemainder() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:i\d+>>   IntConstant 8
   /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
   /// CHECK-DAG:     <<Div0Chk:i\d+>>  DivZeroCheck [<<Const3>>]
   /// CHECK-DAG:     <<Rem:i\d+>>      Rem [<<Const8>>,<<Div0Chk>>]
   /// CHECK-DAG:                       Return [<<Rem>>]
 
-  /// CHECK-START: int Main.IntRemainder() constant_folding (after)
+  /// CHECK-START: int Main.IntRemainder() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
   /// CHECK-DAG:                       Return [<<Const2>>]
 
-  /// CHECK-START: int Main.IntRemainder() constant_folding (after)
+  /// CHECK-START: int Main.IntRemainder() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       DivZeroCheck
   /// CHECK-NOT:                       Rem
 
   public static int IntRemainder() {
     int a, b, c;
-    a = 8;
-    b = 3;
+    a = $inline$int(8);
+    b = $inline$int(3);
     c = a % b;
     return c;
   }
 
-  /// CHECK-START: long Main.LongRemainder() constant_folding (before)
+  /// CHECK-START: long Main.LongRemainder() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:j\d+>>   LongConstant 8
   /// CHECK-DAG:     <<Const3:j\d+>>   LongConstant 3
   /// CHECK-DAG:     <<Div0Chk:j\d+>>  DivZeroCheck [<<Const3>>]
   /// CHECK-DAG:     <<Rem:j\d+>>      Rem [<<Const8>>,<<Div0Chk>>]
   /// CHECK-DAG:                       Return [<<Rem>>]
 
-  /// CHECK-START: long Main.LongRemainder() constant_folding (after)
+  /// CHECK-START: long Main.LongRemainder() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
   /// CHECK-DAG:                       Return [<<Const2>>]
 
-  /// CHECK-START: long Main.LongRemainder() constant_folding (after)
+  /// CHECK-START: long Main.LongRemainder() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       DivZeroCheck
   /// CHECK-NOT:                       Rem
 
   public static long LongRemainder() {
     long a, b, c;
-    a = 8L;
-    b = 3L;
+    a = $inline$long(8L);
+    b = $inline$long(3L);
     c = a % b;
     return c;
   }
 
-  /// CHECK-START: float Main.FloatRemainder() constant_folding (before)
+  /// CHECK-START: float Main.FloatRemainder() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:f\d+>>   FloatConstant 8
   /// CHECK-DAG:     <<Const2P5:f\d+>> FloatConstant 2.5
   /// CHECK-DAG:     <<Rem:f\d+>>      Rem [<<Const8>>,<<Const2P5>>]
   /// CHECK-DAG:                       Return [<<Rem>>]
 
-  /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
+  /// CHECK-START: float Main.FloatRemainder() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const0P5:f\d+>> FloatConstant 0.5
   /// CHECK-DAG:                       Return [<<Const0P5>>]
 
-  /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
+  /// CHECK-START: float Main.FloatRemainder() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Rem
 
   public static float FloatRemainder() {
     float a, b, c;
-    a = 8F;
-    b = 2.5F;
+    a = $inline$float(8F);
+    b = $inline$float(2.5F);
     c = a % b;
     return c;
   }
 
-  /// CHECK-START: double Main.DoubleRemainder() constant_folding (before)
+  /// CHECK-START: double Main.DoubleRemainder() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const8:d\d+>>   DoubleConstant 8
   /// CHECK-DAG:     <<Const2P5:d\d+>> DoubleConstant 2.5
   /// CHECK-DAG:     <<Rem:d\d+>>      Rem [<<Const8>>,<<Const2P5>>]
   /// CHECK-DAG:                       Return [<<Rem>>]
 
-  /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
+  /// CHECK-START: double Main.DoubleRemainder() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const0P5:d\d+>> DoubleConstant 0.5
   /// CHECK-DAG:                       Return [<<Const0P5>>]
 
-  /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
+  /// CHECK-START: double Main.DoubleRemainder() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Rem
 
   public static double DoubleRemainder() {
     double a, b, c;
-    a = 8D;
-    b = 2.5D;
+    a = $inline$double(8D);
+    b = $inline$double(2.5D);
     c = a % b;
     return c;
   }
@@ -682,42 +695,42 @@
    * Exercise constant folding on left shift.
    */
 
-  /// CHECK-START: int Main.ShlIntLong() constant_folding (before)
+  /// CHECK-START: int Main.ShlIntLong() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
   /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
   /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
   /// CHECK-DAG:     <<Shl:i\d+>>      Shl [<<Const1>>,<<TypeConv>>]
   /// CHECK-DAG:                       Return [<<Shl>>]
 
-  /// CHECK-START: int Main.ShlIntLong() constant_folding (after)
+  /// CHECK-START: int Main.ShlIntLong() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const4:i\d+>>   IntConstant 4
   /// CHECK-DAG:                       Return [<<Const4>>]
 
-  /// CHECK-START: int Main.ShlIntLong() constant_folding (after)
+  /// CHECK-START: int Main.ShlIntLong() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Shl
 
   public static int ShlIntLong() {
-    int lhs = 1;
-    long rhs = 2;
+    int lhs = $inline$int(1);
+    long rhs = $inline$long(2L);
     return lhs << rhs;
   }
 
-  /// CHECK-START: long Main.ShlLongInt() constant_folding (before)
+  /// CHECK-START: long Main.ShlLongInt() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
   /// CHECK-DAG:     <<Shl:j\d+>>      Shl [<<Const3L>>,<<Const2>>]
   /// CHECK-DAG:                       Return [<<Shl>>]
 
-  /// CHECK-START: long Main.ShlLongInt() constant_folding (after)
+  /// CHECK-START: long Main.ShlLongInt() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const12L:j\d+>> LongConstant 12
   /// CHECK-DAG:                       Return [<<Const12L>>]
 
-  /// CHECK-START: long Main.ShlLongInt() constant_folding (after)
+  /// CHECK-START: long Main.ShlLongInt() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Shl
 
   public static long ShlLongInt() {
-    long lhs = 3;
-    int rhs = 2;
+    long lhs = $inline$long(3L);
+    int rhs = $inline$int(2);
     return lhs << rhs;
   }
 
@@ -726,42 +739,42 @@
    * Exercise constant folding on right shift.
    */
 
-  /// CHECK-START: int Main.ShrIntLong() constant_folding (before)
+  /// CHECK-START: int Main.ShrIntLong() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const7:i\d+>>   IntConstant 7
   /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
   /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
   /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Const7>>,<<TypeConv>>]
   /// CHECK-DAG:                       Return [<<Shr>>]
 
-  /// CHECK-START: int Main.ShrIntLong() constant_folding (after)
+  /// CHECK-START: int Main.ShrIntLong() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
   /// CHECK-DAG:                       Return [<<Const1>>]
 
-  /// CHECK-START: int Main.ShrIntLong() constant_folding (after)
+  /// CHECK-START: int Main.ShrIntLong() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Shr
 
   public static int ShrIntLong() {
-    int lhs = 7;
-    long rhs = 2;
+    int lhs = $inline$int(7);
+    long rhs = $inline$long(2L);
     return lhs >> rhs;
   }
 
-  /// CHECK-START: long Main.ShrLongInt() constant_folding (before)
+  /// CHECK-START: long Main.ShrLongInt() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const9L:j\d+>>  LongConstant 9
   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Const9L>>,<<Const2>>]
   /// CHECK-DAG:                       Return [<<Shr>>]
 
-  /// CHECK-START: long Main.ShrLongInt() constant_folding (after)
+  /// CHECK-START: long Main.ShrLongInt() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
   /// CHECK-DAG:                       Return [<<Const2L>>]
 
-  /// CHECK-START: long Main.ShrLongInt() constant_folding (after)
+  /// CHECK-START: long Main.ShrLongInt() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Shr
 
   public static long ShrLongInt() {
-    long lhs = 9;
-    int rhs = 2;
+    long lhs = $inline$long(9);
+    int rhs = $inline$int(2);
     return lhs >> rhs;
   }
 
@@ -770,42 +783,42 @@
    * Exercise constant folding on unsigned right shift.
    */
 
-  /// CHECK-START: int Main.UShrIntLong() constant_folding (before)
+  /// CHECK-START: int Main.UShrIntLong() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<ConstM7:i\d+>>  IntConstant -7
   /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
   /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<ConstM7>>,<<TypeConv>>]
   /// CHECK-DAG:                       Return [<<UShr>>]
 
-  /// CHECK-START: int Main.UShrIntLong() constant_folding (after)
+  /// CHECK-START: int Main.UShrIntLong() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<ConstRes:i\d+>> IntConstant 1073741822
   /// CHECK-DAG:                       Return [<<ConstRes>>]
 
-  /// CHECK-START: int Main.UShrIntLong() constant_folding (after)
+  /// CHECK-START: int Main.UShrIntLong() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       UShr
 
   public static int UShrIntLong() {
-    int lhs = -7;
-    long rhs = 2;
+    int lhs = $inline$int(-7);
+    long rhs = $inline$long(2L);
     return lhs >>> rhs;
   }
 
-  /// CHECK-START: long Main.UShrLongInt() constant_folding (before)
+  /// CHECK-START: long Main.UShrLongInt() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<ConstM9L:j\d+>> LongConstant -9
   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<ConstM9L>>,<<Const2>>]
   /// CHECK-DAG:                       Return [<<UShr>>]
 
-  /// CHECK-START: long Main.UShrLongInt() constant_folding (after)
+  /// CHECK-START: long Main.UShrLongInt() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<ConstRes:j\d+>> LongConstant 4611686018427387901
   /// CHECK-DAG:                       Return [<<ConstRes>>]
 
-  /// CHECK-START: long Main.UShrLongInt() constant_folding (after)
+  /// CHECK-START: long Main.UShrLongInt() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       UShr
 
   public static long UShrLongInt() {
-    long lhs = -9;
-    int rhs = 2;
+    long lhs = $inline$long(-9);
+    int rhs = $inline$int(2);
     return lhs >>> rhs;
   }
 
@@ -814,43 +827,43 @@
    * Exercise constant folding on logical and.
    */
 
-  /// CHECK-START: long Main.AndIntLong() constant_folding (before)
+  /// CHECK-START: long Main.AndIntLong() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
   /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
   /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
   /// CHECK-DAG:     <<And:j\d+>>      And [<<TypeConv>>,<<Const3L>>]
   /// CHECK-DAG:                       Return [<<And>>]
 
-  /// CHECK-START: long Main.AndIntLong() constant_folding (after)
+  /// CHECK-START: long Main.AndIntLong() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
   /// CHECK-DAG:                       Return [<<Const2>>]
 
-  /// CHECK-START: long Main.AndIntLong() constant_folding (after)
+  /// CHECK-START: long Main.AndIntLong() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       And
 
   public static long AndIntLong() {
-    int lhs = 10;
-    long rhs = 3;
+    int lhs = $inline$int(10);
+    long rhs = $inline$long(3L);
     return lhs & rhs;
   }
 
-  /// CHECK-START: long Main.AndLongInt() constant_folding (before)
+  /// CHECK-START: long Main.AndLongInt() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
   /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
   /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
   /// CHECK-DAG:     <<And:j\d+>>      And [<<TypeConv>>,<<Const10L>>]
   /// CHECK-DAG:                       Return [<<And>>]
 
-  /// CHECK-START: long Main.AndLongInt() constant_folding (after)
+  /// CHECK-START: long Main.AndLongInt() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
   /// CHECK-DAG:                       Return [<<Const2>>]
 
-  /// CHECK-START: long Main.AndLongInt() constant_folding (after)
+  /// CHECK-START: long Main.AndLongInt() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       And
 
   public static long AndLongInt() {
-    long lhs = 10;
-    int rhs = 3;
+    long lhs = $inline$long(10L);
+    int rhs = $inline$int(3);
     return lhs & rhs;
   }
 
@@ -859,43 +872,43 @@
    * Exercise constant folding on logical or.
    */
 
-  /// CHECK-START: long Main.OrIntLong() constant_folding (before)
+  /// CHECK-START: long Main.OrIntLong() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
   /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
   /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
   /// CHECK-DAG:     <<Or:j\d+>>       Or [<<TypeConv>>,<<Const3L>>]
   /// CHECK-DAG:                       Return [<<Or>>]
 
-  /// CHECK-START: long Main.OrIntLong() constant_folding (after)
+  /// CHECK-START: long Main.OrIntLong() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const11:j\d+>>  LongConstant 11
   /// CHECK-DAG:                       Return [<<Const11>>]
 
-  /// CHECK-START: long Main.OrIntLong() constant_folding (after)
+  /// CHECK-START: long Main.OrIntLong() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Or
 
   public static long OrIntLong() {
-    int lhs = 10;
-    long rhs = 3;
+    int lhs = $inline$int(10);
+    long rhs = $inline$long(3L);
     return lhs | rhs;
   }
 
-  /// CHECK-START: long Main.OrLongInt() constant_folding (before)
+  /// CHECK-START: long Main.OrLongInt() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
   /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
   /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
   /// CHECK-DAG:     <<Or:j\d+>>       Or [<<TypeConv>>,<<Const10L>>]
   /// CHECK-DAG:                       Return [<<Or>>]
 
-  /// CHECK-START: long Main.OrLongInt() constant_folding (after)
+  /// CHECK-START: long Main.OrLongInt() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const11:j\d+>>  LongConstant 11
   /// CHECK-DAG:                       Return [<<Const11>>]
 
-  /// CHECK-START: long Main.OrLongInt() constant_folding (after)
+  /// CHECK-START: long Main.OrLongInt() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Or
 
   public static long OrLongInt() {
-    long lhs = 10;
-    int rhs = 3;
+    long lhs = $inline$long(10L);
+    int rhs = $inline$int(3);
     return lhs | rhs;
   }
 
@@ -904,43 +917,43 @@
    * Exercise constant folding on logical exclusive or.
    */
 
-  /// CHECK-START: long Main.XorIntLong() constant_folding (before)
+  /// CHECK-START: long Main.XorIntLong() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
   /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
   /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
   /// CHECK-DAG:     <<Xor:j\d+>>      Xor [<<TypeConv>>,<<Const3L>>]
   /// CHECK-DAG:                       Return [<<Xor>>]
 
-  /// CHECK-START: long Main.XorIntLong() constant_folding (after)
+  /// CHECK-START: long Main.XorIntLong() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const9:j\d+>>   LongConstant 9
   /// CHECK-DAG:                       Return [<<Const9>>]
 
-  /// CHECK-START: long Main.XorIntLong() constant_folding (after)
+  /// CHECK-START: long Main.XorIntLong() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Xor
 
   public static long XorIntLong() {
-    int lhs = 10;
-    long rhs = 3;
+    int lhs = $inline$int(10);
+    long rhs = $inline$long(3L);
     return lhs ^ rhs;
   }
 
-  /// CHECK-START: long Main.XorLongInt() constant_folding (before)
+  /// CHECK-START: long Main.XorLongInt() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
   /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
   /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
   /// CHECK-DAG:     <<Xor:j\d+>>      Xor [<<TypeConv>>,<<Const10L>>]
   /// CHECK-DAG:                       Return [<<Xor>>]
 
-  /// CHECK-START: long Main.XorLongInt() constant_folding (after)
+  /// CHECK-START: long Main.XorLongInt() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const9:j\d+>>   LongConstant 9
   /// CHECK-DAG:                       Return [<<Const9>>]
 
-  /// CHECK-START: long Main.XorLongInt() constant_folding (after)
+  /// CHECK-START: long Main.XorLongInt() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       Xor
 
   public static long XorLongInt() {
-    long lhs = 10;
-    int rhs = 3;
+    long lhs = $inline$long(10L);
+    int rhs = $inline$int(3);
     return lhs ^ rhs;
   }
 
@@ -949,23 +962,23 @@
    * Exercise constant folding on constant (static) condition.
    */
 
-  /// CHECK-START: int Main.StaticCondition() constant_folding (before)
+  /// CHECK-START: int Main.StaticCondition() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const7:i\d+>>  IntConstant 7
   /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
   /// CHECK-DAG:     <<Cond:z\d+>>    GreaterThanOrEqual [<<Const7>>,<<Const2>>]
-  /// CHECK-DAG:                      If [<<Cond>>]
+  /// CHECK-DAG:                      Select [{{i\d+}},{{i\d+}},<<Cond>>]
 
-  /// CHECK-START: int Main.StaticCondition() constant_folding (after)
+  /// CHECK-START: int Main.StaticCondition() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const1:i\d+>>  IntConstant 1
-  /// CHECK-DAG:                      If [<<Const1>>]
+  /// CHECK-DAG:                      Select [{{i\d+}},{{i\d+}},<<Const1>>]
 
-  /// CHECK-START: int Main.StaticCondition() constant_folding (after)
+  /// CHECK-START: int Main.StaticCondition() constant_folding_after_inlining (after)
   /// CHECK-NOT:                      GreaterThanOrEqual
 
   public static int StaticCondition() {
     int a, b, c;
-    a = 7;
-    b = 2;
+    a = $inline$int(7);
+    b = $inline$int(2);
     if (a < b)
       c = a + b;
     else
@@ -1010,28 +1023,30 @@
    * (forward) post-order traversal of the the dominator tree.
    */
 
-  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (before)
+  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding_after_inlining (before)
+  /// CHECK-DAG:     <<Cond:z\d+>>    ParameterValue
   /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
   /// CHECK-DAG:     <<Const5:i\d+>>  IntConstant 5
   /// CHECK-DAG:     <<Add:i\d+>>     Add [<<Const5>>,<<Const2>>]
   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<Const5>>,<<Const2>>]
-  /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Add>>,<<Sub>>]
+  /// CHECK-DAG:     <<Phi:i\d+>>     Select [<<Sub>>,<<Add>>,<<Cond>>]
   /// CHECK-DAG:                      Return [<<Phi>>]
 
-  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
+  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding_after_inlining (after)
+  /// CHECK-DAG:     <<Cond:z\d+>>    ParameterValue
   /// CHECK-DAG:     <<Const3:i\d+>>  IntConstant 3
   /// CHECK-DAG:     <<Const7:i\d+>>  IntConstant 7
-  /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Const7>>,<<Const3>>]
+  /// CHECK-DAG:     <<Phi:i\d+>>     Select [<<Const3>>,<<Const7>>,<<Cond>>]
   /// CHECK-DAG:                      Return [<<Phi>>]
 
-  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
+  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding_after_inlining (after)
   /// CHECK-NOT:                      Add
   /// CHECK-NOT:                      Sub
 
   public static int JumpsAndConditionals(boolean cond) {
     int a, b, c;
-    a = 5;
-    b = 2;
+    a = $inline$int(5);
+    b = $inline$int(2);
     if (cond)
       c = a + b;
     else
@@ -1310,204 +1325,204 @@
    * Exercise constant folding on type conversions.
    */
 
-  /// CHECK-START: int Main.ReturnInt33() constant_folding (before)
+  /// CHECK-START: int Main.ReturnInt33() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const33:j\d+>>  LongConstant 33
   /// CHECK-DAG:     <<Convert:i\d+>>  TypeConversion [<<Const33>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: int Main.ReturnInt33() constant_folding (after)
+  /// CHECK-START: int Main.ReturnInt33() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
   /// CHECK-DAG:                       Return [<<Const33>>]
 
-  /// CHECK-START: int Main.ReturnInt33() constant_folding (after)
+  /// CHECK-START: int Main.ReturnInt33() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static int ReturnInt33() {
-    long imm = 33L;
+    long imm = $inline$long(33L);
     return (int) imm;
   }
 
-  /// CHECK-START: int Main.ReturnIntMax() constant_folding (before)
+  /// CHECK-START: int Main.ReturnIntMax() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<ConstMax:f\d+>> FloatConstant 1e+34
   /// CHECK-DAG:     <<Convert:i\d+>>  TypeConversion [<<ConstMax>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: int Main.ReturnIntMax() constant_folding (after)
+  /// CHECK-START: int Main.ReturnIntMax() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<ConstMax:i\d+>> IntConstant 2147483647
   /// CHECK-DAG:                       Return [<<ConstMax>>]
 
-  /// CHECK-START: int Main.ReturnIntMax() constant_folding (after)
+  /// CHECK-START: int Main.ReturnIntMax() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static int ReturnIntMax() {
-    float imm = 1.0e34f;
+    float imm = $inline$float(1.0e34f);
     return (int) imm;
   }
 
-  /// CHECK-START: int Main.ReturnInt0() constant_folding (before)
+  /// CHECK-START: int Main.ReturnInt0() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<ConstNaN:d\d+>> DoubleConstant nan
   /// CHECK-DAG:     <<Convert:i\d+>>  TypeConversion [<<ConstNaN>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: int Main.ReturnInt0() constant_folding (after)
+  /// CHECK-START: int Main.ReturnInt0() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
   /// CHECK-DAG:                       Return [<<Const0>>]
 
-  /// CHECK-START: int Main.ReturnInt0() constant_folding (after)
+  /// CHECK-START: int Main.ReturnInt0() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static int ReturnInt0() {
-    double imm = Double.NaN;
+    double imm = $inline$double(Double.NaN);
     return (int) imm;
   }
 
-  /// CHECK-START: long Main.ReturnLong33() constant_folding (before)
+  /// CHECK-START: long Main.ReturnLong33() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
   /// CHECK-DAG:     <<Convert:j\d+>>  TypeConversion [<<Const33>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: long Main.ReturnLong33() constant_folding (after)
+  /// CHECK-START: long Main.ReturnLong33() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const33:j\d+>>  LongConstant 33
   /// CHECK-DAG:                       Return [<<Const33>>]
 
-  /// CHECK-START: long Main.ReturnLong33() constant_folding (after)
+  /// CHECK-START: long Main.ReturnLong33() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static long ReturnLong33() {
-    int imm = 33;
+    int imm = $inline$int(33);
     return (long) imm;
   }
 
-  /// CHECK-START: long Main.ReturnLong34() constant_folding (before)
+  /// CHECK-START: long Main.ReturnLong34() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const34:f\d+>>  FloatConstant 34
   /// CHECK-DAG:     <<Convert:j\d+>>  TypeConversion [<<Const34>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: long Main.ReturnLong34() constant_folding (after)
+  /// CHECK-START: long Main.ReturnLong34() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const34:j\d+>>  LongConstant 34
   /// CHECK-DAG:                       Return [<<Const34>>]
 
-  /// CHECK-START: long Main.ReturnLong34() constant_folding (after)
+  /// CHECK-START: long Main.ReturnLong34() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static long ReturnLong34() {
-    float imm = 34.0f;
+    float imm = $inline$float(34.0f);
     return (long) imm;
   }
 
-  /// CHECK-START: long Main.ReturnLong0() constant_folding (before)
+  /// CHECK-START: long Main.ReturnLong0() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<ConstNaN:d\d+>> DoubleConstant nan
   /// CHECK-DAG:     <<Convert:j\d+>>  TypeConversion [<<ConstNaN>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: long Main.ReturnLong0() constant_folding (after)
+  /// CHECK-START: long Main.ReturnLong0() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
   /// CHECK-DAG:                       Return [<<Const0>>]
 
-  /// CHECK-START: long Main.ReturnLong0() constant_folding (after)
+  /// CHECK-START: long Main.ReturnLong0() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static long ReturnLong0() {
-    double imm = -Double.NaN;
+    double imm = $inline$double(-Double.NaN);
     return (long) imm;
   }
 
-  /// CHECK-START: float Main.ReturnFloat33() constant_folding (before)
+  /// CHECK-START: float Main.ReturnFloat33() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
   /// CHECK-DAG:     <<Convert:f\d+>>  TypeConversion [<<Const33>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: float Main.ReturnFloat33() constant_folding (after)
+  /// CHECK-START: float Main.ReturnFloat33() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const33:f\d+>>  FloatConstant 33
   /// CHECK-DAG:                       Return [<<Const33>>]
 
-  /// CHECK-START: float Main.ReturnFloat33() constant_folding (after)
+  /// CHECK-START: float Main.ReturnFloat33() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static float ReturnFloat33() {
-    int imm = 33;
+    int imm = $inline$int(33);
     return (float) imm;
   }
 
-  /// CHECK-START: float Main.ReturnFloat34() constant_folding (before)
+  /// CHECK-START: float Main.ReturnFloat34() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const34:j\d+>>  LongConstant 34
   /// CHECK-DAG:     <<Convert:f\d+>>  TypeConversion [<<Const34>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: float Main.ReturnFloat34() constant_folding (after)
+  /// CHECK-START: float Main.ReturnFloat34() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const34:f\d+>>  FloatConstant 34
   /// CHECK-DAG:                       Return [<<Const34>>]
 
-  /// CHECK-START: float Main.ReturnFloat34() constant_folding (after)
+  /// CHECK-START: float Main.ReturnFloat34() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static float ReturnFloat34() {
-    long imm = 34L;
+    long imm = $inline$long(34L);
     return (float) imm;
   }
 
-  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (before)
+  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const:d\d+>>    DoubleConstant 99.25
   /// CHECK-DAG:     <<Convert:f\d+>>  TypeConversion [<<Const>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (after)
+  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const:f\d+>>    FloatConstant 99.25
   /// CHECK-DAG:                       Return [<<Const>>]
 
-  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (after)
+  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static float ReturnFloat99P25() {
-    double imm = 99.25;
+    double imm = $inline$double(99.25);
     return (float) imm;
   }
 
-  /// CHECK-START: double Main.ReturnDouble33() constant_folding (before)
+  /// CHECK-START: double Main.ReturnDouble33() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
   /// CHECK-DAG:     <<Convert:d\d+>>  TypeConversion [<<Const33>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: double Main.ReturnDouble33() constant_folding (after)
+  /// CHECK-START: double Main.ReturnDouble33() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const33:d\d+>>  DoubleConstant 33
   /// CHECK-DAG:                       Return [<<Const33>>]
 
   public static double ReturnDouble33() {
-    int imm = 33;
+    int imm = $inline$int(33);
     return (double) imm;
   }
 
-  /// CHECK-START: double Main.ReturnDouble34() constant_folding (before)
+  /// CHECK-START: double Main.ReturnDouble34() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const34:j\d+>>  LongConstant 34
   /// CHECK-DAG:     <<Convert:d\d+>>  TypeConversion [<<Const34>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: double Main.ReturnDouble34() constant_folding (after)
+  /// CHECK-START: double Main.ReturnDouble34() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const34:d\d+>>  DoubleConstant 34
   /// CHECK-DAG:                       Return [<<Const34>>]
 
-  /// CHECK-START: double Main.ReturnDouble34() constant_folding (after)
+  /// CHECK-START: double Main.ReturnDouble34() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static double ReturnDouble34() {
-    long imm = 34L;
+    long imm = $inline$long(34L);
     return (double) imm;
   }
 
-  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (before)
+  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding_after_inlining (before)
   /// CHECK-DAG:     <<Const:f\d+>>    FloatConstant 99.25
   /// CHECK-DAG:     <<Convert:d\d+>>  TypeConversion [<<Const>>]
   /// CHECK-DAG:                       Return [<<Convert>>]
 
-  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (after)
+  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding_after_inlining (after)
   /// CHECK-DAG:     <<Const:d\d+>>    DoubleConstant 99.25
   /// CHECK-DAG:                       Return [<<Const>>]
 
-  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (after)
+  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding_after_inlining (after)
   /// CHECK-NOT:                       TypeConversion
 
   public static double ReturnDouble99P25() {
-    float imm = 99.25f;
+    float imm = $inline$float(99.25f);
     return (double) imm;
   }
 
diff --git a/test/450-checker-types/smali/SmaliTests.smali b/test/450-checker-types/smali/SmaliTests.smali
new file mode 100644
index 0000000..6a3122e
--- /dev/null
+++ b/test/450-checker-types/smali/SmaliTests.smali
@@ -0,0 +1,120 @@
+# Copyright (C) 2016 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 public LSmaliTests;
+.super Ljava/lang/Object;
+
+## CHECK-START: void SmaliTests.testInstanceOf_EQ0_NotInlined(java.lang.Object) builder (after)
+## CHECK-DAG:     <<Cst0:i\d+>> IntConstant 0
+## CHECK-DAG:     <<IOf:z\d+>>  InstanceOf
+## CHECK-DAG:                   Equal [<<IOf>>,<<Cst0>>]
+
+## CHECK-START: void SmaliTests.testInstanceOf_EQ0_NotInlined(java.lang.Object) instruction_simplifier (before)
+## CHECK:         CheckCast
+
+## CHECK-START: void SmaliTests.testInstanceOf_EQ0_NotInlined(java.lang.Object) instruction_simplifier (after)
+## CHECK-NOT:     CheckCast
+
+.method public static testInstanceOf_EQ0_NotInlined(Ljava/lang/Object;)V
+  .registers 3
+
+  const v0, 0x0
+  instance-of v1, p0, LSubclassC;
+  if-eq v1, v0, :return
+
+  check-cast p0, LSubclassC;
+  invoke-virtual {p0}, LSubclassC;->$noinline$g()V
+
+  :return
+  return-void
+
+.end method
+
+## CHECK-START: void SmaliTests.testInstanceOf_EQ1_NotInlined(java.lang.Object) builder (after)
+## CHECK-DAG:     <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG:     <<IOf:z\d+>>  InstanceOf
+## CHECK-DAG:                   Equal [<<IOf>>,<<Cst1>>]
+
+## CHECK-START: void SmaliTests.testInstanceOf_EQ1_NotInlined(java.lang.Object) instruction_simplifier (before)
+## CHECK:         CheckCast
+
+## CHECK-START: void SmaliTests.testInstanceOf_EQ1_NotInlined(java.lang.Object) instruction_simplifier (after)
+## CHECK-NOT:     CheckCast
+
+.method public static testInstanceOf_EQ1_NotInlined(Ljava/lang/Object;)V
+  .registers 3
+
+  const v0, 0x1
+  instance-of v1, p0, LSubclassC;
+  if-eq v1, v0, :invoke
+  return-void
+
+  :invoke
+  check-cast p0, LSubclassC;
+  invoke-virtual {p0}, LSubclassC;->$noinline$g()V
+  return-void
+
+.end method
+
+## CHECK-START: void SmaliTests.testInstanceOf_NE0_NotInlined(java.lang.Object) builder (after)
+## CHECK-DAG:     <<Cst0:i\d+>> IntConstant 0
+## CHECK-DAG:     <<IOf:z\d+>>  InstanceOf
+## CHECK-DAG:                   NotEqual [<<IOf>>,<<Cst0>>]
+
+## CHECK-START: void SmaliTests.testInstanceOf_NE0_NotInlined(java.lang.Object) instruction_simplifier (before)
+## CHECK:         CheckCast
+
+## CHECK-START: void SmaliTests.testInstanceOf_NE0_NotInlined(java.lang.Object) instruction_simplifier (after)
+## CHECK-NOT:     CheckCast
+
+.method public static testInstanceOf_NE0_NotInlined(Ljava/lang/Object;)V
+  .registers 3
+
+  const v0, 0x0
+  instance-of v1, p0, LSubclassC;
+  if-ne v1, v0, :invoke
+  return-void
+
+  :invoke
+  check-cast p0, LSubclassC;
+  invoke-virtual {p0}, LSubclassC;->$noinline$g()V
+  return-void
+
+.end method
+
+## CHECK-START: void SmaliTests.testInstanceOf_NE1_NotInlined(java.lang.Object) builder (after)
+## CHECK-DAG:     <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG:     <<IOf:z\d+>>  InstanceOf
+## CHECK-DAG:                   NotEqual [<<IOf>>,<<Cst1>>]
+
+## CHECK-START: void SmaliTests.testInstanceOf_NE1_NotInlined(java.lang.Object) instruction_simplifier (before)
+## CHECK:         CheckCast
+
+## CHECK-START: void SmaliTests.testInstanceOf_NE1_NotInlined(java.lang.Object) instruction_simplifier (after)
+## CHECK-NOT:     CheckCast
+
+.method public static testInstanceOf_NE1_NotInlined(Ljava/lang/Object;)V
+  .registers 3
+
+  const v0, 0x1
+  instance-of v1, p0, LSubclassC;
+  if-ne v1, v0, :return
+
+  check-cast p0, LSubclassC;
+  invoke-virtual {p0}, LSubclassC;->$noinline$g()V
+
+  :return
+  return-void
+
+.end method
diff --git a/test/450-checker-types/src/Main.java b/test/450-checker-types/src/Main.java
index 027a9d9..08b6cec 100644
--- a/test/450-checker-types/src/Main.java
+++ b/test/450-checker-types/src/Main.java
@@ -205,58 +205,6 @@
   public static boolean $inline$InstanceofSubclassB(Object o) { return o instanceof SubclassB; }
   public static boolean $inline$InstanceofSubclassC(Object o) { return o instanceof SubclassC; }
 
-  /// CHECK-START: void Main.testInstanceOf_NotInlined(java.lang.Object) builder (after)
-  /// CHECK-DAG:     <<Cst0:i\d+>> IntConstant 0
-  /// CHECK-DAG:     <<Cst1:i\d+>> IntConstant 1
-  /// CHECK-DAG:     <<IOf1:z\d+>> InstanceOf
-  /// CHECK-DAG:                   NotEqual [<<IOf1>>,<<Cst1>>]
-  /// CHECK-DAG:     <<IOf2:z\d+>> InstanceOf
-  /// CHECK-DAG:                   Equal [<<IOf2>>,<<Cst0>>]
-
-  /// CHECK-START: void Main.testInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (before)
-  /// CHECK:         CheckCast
-  /// CHECK:         CheckCast
-  /// CHECK-NOT:     CheckCast
-
-  /// CHECK-START: void Main.testInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (after)
-  /// CHECK-NOT:     CheckCast
-  public void testInstanceOf_NotInlined(Object o) {
-    if ((o instanceof SubclassC) == true) {
-      ((SubclassC)o).$noinline$g();
-    }
-    if ((o instanceof SubclassB) != false) {
-      ((SubclassB)o).$noinline$g();
-    }
-  }
-
-  /// CHECK-START: void Main.testNotInstanceOf_NotInlined(java.lang.Object) builder (after)
-  /// CHECK-DAG:     <<Cst0:i\d+>> IntConstant 0
-  /// CHECK-DAG:     <<Cst1:i\d+>> IntConstant 1
-  /// CHECK-DAG:     <<IOf1:z\d+>> InstanceOf
-  /// CHECK-DAG:                   Equal [<<IOf1>>,<<Cst1>>]
-  /// CHECK-DAG:     <<IOf2:z\d+>> InstanceOf
-  /// CHECK-DAG:                   NotEqual [<<IOf2>>,<<Cst0>>]
-
-  /// CHECK-START: void Main.testNotInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (before)
-  /// CHECK:         CheckCast
-  /// CHECK:         CheckCast
-  /// CHECK-NOT:     CheckCast
-
-  /// CHECK-START: void Main.testNotInstanceOf_NotInlined(java.lang.Object) instruction_simplifier (after)
-  /// CHECK-NOT:     CheckCast
-  public void testNotInstanceOf_NotInlined(Object o) {
-    if ((o instanceof SubclassC) != true) {
-      // Empty branch to flip the condition.
-    } else {
-      ((SubclassC)o).$noinline$g();
-    }
-    if ((o instanceof SubclassB) == false) {
-      // Empty branch to flip the condition.
-    } else {
-      ((SubclassB)o).$noinline$g();
-    }
-  }
-
   /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) inliner (after)
   /// CHECK-DAG:     <<IOf:z\d+>>  InstanceOf
   /// CHECK-DAG:                   If [<<IOf>>]
diff --git a/test/454-get-vreg/build b/test/454-get-vreg/build
deleted file mode 100644
index 08987b5..0000000
--- a/test/454-get-vreg/build
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2015 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.
-
-# Stop if something fails.
-set -e
-
-# The test relies on DEX file produced by javac+dx so keep building with them for now
-# (see b/19467889)
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \
-  --dump-width=1000 ${DX_FLAGS} classes
-zip $TEST_NAME.jar classes.dex
diff --git a/test/458-checker-instruction-simplification/smali/SmaliTests.smali b/test/458-checker-instruction-simplification/smali/SmaliTests.smali
new file mode 100644
index 0000000..ede599b
--- /dev/null
+++ b/test/458-checker-instruction-simplification/smali/SmaliTests.smali
@@ -0,0 +1,193 @@
+# Copyright (C) 2016 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 public LSmaliTests;
+.super Ljava/lang/Object;
+
+## CHECK-START: int SmaliTests.EqualTrueRhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const1>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.EqualTrueRhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static EqualTrueRhs(Z)I
+  .registers 3
+
+  const v0, 0x1
+  const v1, 0x5
+  if-eq p0, v0, :return
+  const v1, 0x3
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.EqualTrueLhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Const1>>,<<Arg>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.EqualTrueLhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static EqualTrueLhs(Z)I
+  .registers 3
+
+  const v0, 0x1
+  const v1, 0x5
+  if-eq v0, p0, :return
+  const v1, 0x3
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.EqualFalseRhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const0>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.EqualFalseRhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static EqualFalseRhs(Z)I
+  .registers 3
+
+  const v0, 0x0
+  const v1, 0x3
+  if-eq p0, v0, :return
+  const v1, 0x5
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.EqualFalseLhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Const0>>,<<Arg>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.EqualFalseLhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static EqualFalseLhs(Z)I
+  .registers 3
+
+  const v0, 0x0
+  const v1, 0x3
+  if-eq v0, p0, :return
+  const v1, 0x5
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.NotEqualTrueRhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const1>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.NotEqualTrueRhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static NotEqualTrueRhs(Z)I
+  .registers 3
+
+  const v0, 0x1
+  const v1, 0x3
+  if-ne p0, v0, :return
+  const v1, 0x5
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.NotEqualTrueLhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Const1>>,<<Arg>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.NotEqualTrueLhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static NotEqualTrueLhs(Z)I
+  .registers 3
+
+  const v0, 0x1
+  const v1, 0x3
+  if-ne v0, p0, :return
+  const v1, 0x5
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.NotEqualFalseRhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const0>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.NotEqualFalseRhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static NotEqualFalseRhs(Z)I
+  .registers 3
+
+  const v0, 0x0
+  const v1, 0x5
+  if-ne p0, v0, :return
+  const v1, 0x3
+  :return
+  return v1
+
+.end method
+
+## CHECK-START: int SmaliTests.NotEqualFalseLhs(boolean) instruction_simplifier (before)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Const0>>,<<Arg>>]
+## CHECK-DAG:                       If [<<Cond>>]
+
+## CHECK-START: int SmaliTests.NotEqualFalseLhs(boolean) instruction_simplifier (after)
+## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+## CHECK-DAG:                       If [<<Arg>>]
+
+.method public static NotEqualFalseLhs(Z)I
+  .registers 3
+
+  const v0, 0x0
+  const v1, 0x5
+  if-ne v0, p0, :return
+  const v1, 0x3
+  :return
+  return v1
+
+.end method
+
diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruction-simplification/src/Main.java
index 8d6bb65..8640148 100644
--- a/test/458-checker-instruction-simplification/src/Main.java
+++ b/test/458-checker-instruction-simplification/src/Main.java
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+import java.lang.reflect.Method;
+
 public class Main {
 
   public static void assertBooleanEquals(boolean expected, boolean result) {
@@ -826,17 +828,16 @@
 
   /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
-  /// CHECK-DAG:     <<ConstF1:j\d+>>  LongConstant -1
-  /// CHECK-DAG:     <<Xor1:j\d+>>     Xor [<<Arg>>,<<ConstF1>>]
-  /// CHECK-DAG:     <<Xor2:j\d+>>     Xor [<<Xor1>>,<<ConstF1>>]
-  /// CHECK-DAG:                       Return [<<Xor2>>]
+  /// CHECK-DAG:     <<Not1:j\d+>>     Not [<<Arg>>]
+  /// CHECK-DAG:     <<Not2:j\d+>>     Not [<<Not1>>]
+  /// CHECK-DAG:                       Return [<<Not2>>]
 
   /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
   /// CHECK-DAG:                       Return [<<Arg>>]
 
   /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
-  /// CHECK-NOT:                       Xor
+  /// CHECK-NOT:                       Not
 
   public static long NotNot1(long arg) {
     return ~~arg;
@@ -844,10 +845,9 @@
 
   /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
-  /// CHECK-DAG:     <<ConstF1:i\d+>>  IntConstant -1
-  /// CHECK-DAG:     <<Xor1:i\d+>>     Xor [<<Arg>>,<<ConstF1>>]
-  /// CHECK-DAG:     <<Xor2:i\d+>>     Xor [<<Xor1>>,<<ConstF1>>]
-  /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Xor2>>,<<Xor1>>]
+  /// CHECK-DAG:     <<Not1:i\d+>>     Not [<<Arg>>]
+  /// CHECK-DAG:     <<Not2:i\d+>>     Not [<<Not1>>]
+  /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Not2>>,<<Not1>>]
   /// CHECK-DAG:                       Return [<<Add>>]
 
   /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
@@ -857,7 +857,8 @@
   /// CHECK-DAG:                       Return [<<Add>>]
 
   /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
-  /// CHECK-NOT:                       Xor
+  /// CHECK:                           Not
+  /// CHECK-NOT:                       Not
 
   public static int NotNot2(int arg) {
     int temp = ~arg;
@@ -965,174 +966,6 @@
     return res;
   }
 
-  /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
-  /// CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const1>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const3>>,<<Const5>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int EqualTrueRhs(boolean arg) {
-    return (arg != true) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
-  /// CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Const1>>,<<Arg>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const3>>,<<Const5>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int EqualTrueLhs(boolean arg) {
-    return (true != arg) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
-  /// CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const0>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const5>>,<<Const3>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int EqualFalseRhs(boolean arg) {
-    return (arg != false) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
-  /// CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const0>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const5>>,<<Const3>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int EqualFalseLhs(boolean arg) {
-    return (false != arg) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
-  /// CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const1>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const5>>,<<Const3>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int NotEqualTrueRhs(boolean arg) {
-    return (arg == true) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
-  /// CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Const1>>,<<Arg>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const5>>,<<Const3>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int NotEqualTrueLhs(boolean arg) {
-    return (true == arg) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
-  /// CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const0>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const3>>,<<Const5>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int NotEqualFalseRhs(boolean arg) {
-    return (arg == false) ? 3 : 5;
-  }
-
-  /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
-  /// CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const0>>]
-  /// CHECK-DAG:                       If [<<Cond>>]
-
-  /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:                       If [<<Arg>>]
-
-  /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier_before_codegen (after)
-  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
-  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
-  /// CHECK-DAG:     <<Const5:i\d+>>   IntConstant 5
-  /// CHECK-DAG:     <<Select:i\d+>>   Select [<<Const3>>,<<Const5>>,<<Arg>>]
-  /// CHECK-DAG:                       Return [<<Select>>]
-
-  public static int NotEqualFalseLhs(boolean arg) {
-    return (false == arg) ? 3 : 5;
-  }
-
   /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
   /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
@@ -1307,17 +1140,16 @@
     return arg * 31;
   }
 
-  /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier (before)
+  /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (before)
   /// CHECK-DAG:      <<Const1:i\d+>>   IntConstant 1
+  /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
+  /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<NE:z\d+>>       NotEqual [<<Field>>,<<Const1>>]
-  /// CHECK-DAG:                        If [<<NE>>]
+  /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const13>>,<<Const54>>,<<NE>>]
+  /// CHECK-DAG:                        Return [<<Select>>]
 
-  /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier (after)
-  /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
-  /// CHECK-DAG:                        If [<<Field>>]
-
-  /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_before_codegen (after)
+  /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (after)
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
@@ -1325,20 +1157,19 @@
   /// CHECK-DAG:                        Return [<<Select>>]
 
   public static int booleanFieldNotEqualOne() {
-    return (booleanField == true) ? 13 : 54;
+    return (booleanField == $inline$true()) ? 13 : 54;
   }
 
-  /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier (before)
+  /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (before)
   /// CHECK-DAG:      <<Const0:i\d+>>   IntConstant 0
+  /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
+  /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
-  /// CHECK-DAG:      <<EQ:z\d+>>       Equal [<<Field>>,<<Const0>>]
-  /// CHECK-DAG:                        If [<<EQ>>]
+  /// CHECK-DAG:      <<NE:z\d+>>       Equal [<<Field>>,<<Const0>>]
+  /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const13>>,<<Const54>>,<<NE>>]
+  /// CHECK-DAG:                        Return [<<Select>>]
 
-  /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier (after)
-  /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
-  /// CHECK-DAG:                        If [<<Field>>]
-
-  /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_before_codegen (after)
+  /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (after)
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
@@ -1346,7 +1177,7 @@
   /// CHECK-DAG:                        Return [<<Select>>]
 
   public static int booleanFieldEqualZero() {
-    return (booleanField != false) ? 13 : 54;
+    return (booleanField != $inline$false()) ? 13 : 54;
   }
 
   /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (before)
@@ -1374,7 +1205,7 @@
   // LessThanOrEqual instructions.
 
   public static int intConditionNotEqualOne(int i) {
-    return ((i > 42) == true) ? 13 : 54;
+    return ((i > 42) == $inline$true()) ? 13 : 54;
   }
 
   /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (before)
@@ -1402,7 +1233,7 @@
   // LessThanOrEqual instructions.
 
   public static int intConditionEqualZero(int i) {
-    return ((i > 42) != false) ? 13 : 54;
+    return ((i > 42) != $inline$false()) ? 13 : 54;
   }
 
   // Test that conditions on float/double are not flipped.
@@ -1770,6 +1601,16 @@
     return (short) (value & 0x17fff);
   }
 
+  public static int runSmaliTest(String name, boolean input) {
+    try {
+      Class<?> c = Class.forName("SmaliTests");
+      Method m = c.getMethod(name, new Class[] { boolean.class });
+      return (Integer) m.invoke(null, input);
+    } catch (Exception ex) {
+      throw new Error(ex);
+    }
+  }
+
   public static void main(String[] args) {
     int arg = 123456;
 
@@ -1804,14 +1645,6 @@
     assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
     assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
     assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
-    assertIntEquals(EqualTrueRhs(true), 5);
-    assertIntEquals(EqualTrueLhs(true), 5);
-    assertIntEquals(EqualFalseRhs(true), 3);
-    assertIntEquals(EqualFalseLhs(true), 3);
-    assertIntEquals(NotEqualTrueRhs(true), 3);
-    assertIntEquals(NotEqualTrueLhs(true), 3);
-    assertIntEquals(NotEqualFalseRhs(true), 5);
-    assertIntEquals(NotEqualFalseLhs(true), 5);
     assertBooleanEquals(EqualBoolVsIntConst(true), true);
     assertBooleanEquals(EqualBoolVsIntConst(true), true);
     assertBooleanEquals(NotEqualBoolVsIntConst(false), false);
@@ -1906,7 +1739,20 @@
     assertIntEquals(intAnd0x17fffToShort(0x88888888), 0x0888);
     assertIntEquals(intAnd0x17fffToShort(Integer.MIN_VALUE), 0);
     assertIntEquals(intAnd0x17fffToShort(Integer.MAX_VALUE), Short.MAX_VALUE);
+
+    for (String condition : new String[] { "Equal", "NotEqual" }) {
+      for (String constant : new String[] { "True", "False" }) {
+        for (String side : new String[] { "Rhs", "Lhs" }) {
+          String name = condition + constant + side;
+          assertIntEquals(runSmaliTest(name, true), 5);
+          assertIntEquals(runSmaliTest(name, false), 3);
+        }
+      }
+    }
   }
 
+  private static boolean $inline$true() { return true; }
+  private static boolean $inline$false() { return false; }
+
   public static boolean booleanField;
 }
diff --git a/test/463-checker-boolean-simplifier/src/Main.java b/test/463-checker-boolean-simplifier/src/Main.java
index 682f126..f0fe1b1 100644
--- a/test/463-checker-boolean-simplifier/src/Main.java
+++ b/test/463-checker-boolean-simplifier/src/Main.java
@@ -42,7 +42,7 @@
   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
   /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
   /// CHECK-DAG:                       If [<<Param>>]
-  /// CHECK-DAG:     <<Phi:i\d+>>      Phi [<<Const1>>,<<Const0>>]
+  /// CHECK-DAG:     <<Phi:i\d+>>      Phi [<<Const0>>,<<Const1>>]
   /// CHECK-DAG:                       Return [<<Phi>>]
 
   /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (before)
@@ -185,11 +185,7 @@
   /// CHECK-NOT:                       BooleanNot
 
   public static int NegatedCondition(boolean x) {
-    if (x != false) {
-      return 42;
-    } else {
-      return 43;
-    }
+    return (x != false) ? 42 : 43;
   }
 
   /// CHECK-START: int Main.SimpleTrueBlock(boolean, int) select_generator (after)
@@ -253,13 +249,7 @@
   /// CHECK-DAG:                        Return [<<Select123>>]
 
   public static int ThreeBlocks(boolean x, boolean y) {
-    if (x) {
-      return 1;
-    } else if (y) {
-      return 2;
-    } else {
-      return 3;
-    }
+    return x ? 1 : (y ? 2 : 3);
   }
 
   /// CHECK-START: int Main.MultiplePhis() select_generator (before)
@@ -292,8 +282,10 @@
     while (y++ < 10) {
       if (y > 1) {
         x = 13;
+        continue;
       } else {
         x = 42;
+        continue;
       }
     }
     return x;
diff --git a/test/537-checker-inline-and-unverified/src/Main.java b/test/537-checker-inline-and-unverified/src/Main.java
index bdc14b0..b9d5fc9 100644
--- a/test/537-checker-inline-and-unverified/src/Main.java
+++ b/test/537-checker-inline-and-unverified/src/Main.java
@@ -45,12 +45,14 @@
     }
 
     public static boolean $opt$noinline$testNoInline() {
+        boolean result = true;
         try {
-            return null instanceof InaccessibleClass;
+            result = (null instanceof InaccessibleClass);
+            throw new Error("Unreachable");
         } catch (IllegalAccessError e) {
             // expected
         }
-        return false;
+        return result;
     }
 
     public static boolean $opt$inline$testInline() {
diff --git a/test/555-checker-regression-x86const/build b/test/555-checker-regression-x86const/build
index 09dcc36..92ddfc9 100644
--- a/test/555-checker-regression-x86const/build
+++ b/test/555-checker-regression-x86const/build
@@ -27,14 +27,12 @@
 mv classes/UnresolvedClass.class classes-ex
 
 if [ ${USE_JACK} = "true" ]; then
-  # Create .jack files from classes generated with javac.
-  ${JILL} classes --output classes.jack
-  ${JILL} classes-ex --output classes-ex.jack
+  jar cf classes.jill.jar -C classes .
+  jar cf classes-ex.jill.jar -C classes-ex .
 
-  # Create DEX files from .jack files.
-  ${JACK} --import classes.jack --output-dex .
+  ${JACK} --import classes.jill.jar --output-dex .
   zip $TEST_NAME.jar classes.dex
-  ${JACK} --import classes-ex.jack --output-dex .
+  ${JACK} --import classes-ex.jill.jar --output-dex .
   zip ${TEST_NAME}-ex.jar classes.dex
 else
   if [ ${NEED_DEX} = "true" ]; then
diff --git a/test/565-checker-condition-liveness/src/Main.java b/test/565-checker-condition-liveness/src/Main.java
index dc4cb76..acfcecd 100644
--- a/test/565-checker-condition-liveness/src/Main.java
+++ b/test/565-checker-condition-liveness/src/Main.java
@@ -28,10 +28,7 @@
   /// CHECK-EVAL:    <<UseInput>> == <<LivSel>> + 1
 
   public static int p(float arg) {
-    if (arg > 5.0f) {
-      return 0;
-    }
-    return -1;
+    return (arg > 5.0f) ? 0 : -1;
   }
 
   /// CHECK-START: void Main.main(java.lang.String[]) liveness (after)
diff --git a/test/565-checker-doublenegbitwise/src/Main.java b/test/565-checker-doublenegbitwise/src/Main.java
index 2d70e11..e426b75 100644
--- a/test/565-checker-doublenegbitwise/src/Main.java
+++ b/test/565-checker-doublenegbitwise/src/Main.java
@@ -35,14 +35,11 @@
    * Test transformation of Not/Not/And into Or/Not.
    */
 
-  // Note: before the instruction_simplifier pass, Xor's are used instead of
-  // Not's (the simplification happens during the same pass).
   /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
-  /// CHECK:       <<CstM1:i\d+>>       IntConstant -1
-  /// CHECK:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
-  /// CHECK:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
+  /// CHECK:       <<Not1:i\d+>>        Not [<<P1>>]
+  /// CHECK:       <<Not2:i\d+>>        Not [<<P2>>]
   /// CHECK:       <<And:i\d+>>         And [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<And>>]
 
@@ -106,14 +103,11 @@
    * Test transformation of Not/Not/Or into And/Not.
    */
 
-  // See note above.
-  // The second Xor has its arguments reversed for no obvious reason.
   /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (before)
   /// CHECK:       <<P1:j\d+>>          ParameterValue
   /// CHECK:       <<P2:j\d+>>          ParameterValue
-  /// CHECK:       <<CstM1:j\d+>>       LongConstant -1
-  /// CHECK:       <<Not1:j\d+>>        Xor [<<P1>>,<<CstM1>>]
-  /// CHECK:       <<Not2:j\d+>>        Xor [<<CstM1>>,<<P2>>]
+  /// CHECK:       <<Not1:j\d+>>        Not [<<P1>>]
+  /// CHECK:       <<Not2:j\d+>>        Not [<<P2>>]
   /// CHECK:       <<Or:j\d+>>          Or [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<Or>>]
 
@@ -183,12 +177,11 @@
   /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
-  /// CHECK-DAG:   <<Cst1:i\d+>>        IntConstant 1
-  /// CHECK-DAG:   <<CstM1:i\d+>>       IntConstant -1
+  /// CHECK:       <<Cst1:i\d+>>        IntConstant 1
   /// CHECK:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
-  /// CHECK:       <<Not1:i\d+>>        Xor [<<AddP1>>,<<CstM1>>]
+  /// CHECK:       <<Not1:i\d+>>        Not [<<AddP1>>]
   /// CHECK:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
-  /// CHECK:       <<Not2:i\d+>>        Xor [<<AddP2>>,<<CstM1>>]
+  /// CHECK:       <<Not2:i\d+>>        Not [<<AddP2>>]
   /// CHECK:       <<Or:i\d+>>          Or [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<Or>>]
 
@@ -226,9 +219,8 @@
   /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
-  /// CHECK:       <<CstM1:i\d+>>       IntConstant -1
-  /// CHECK:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
-  /// CHECK:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
+  /// CHECK:       <<Not1:i\d+>>        Not [<<P1>>]
+  /// CHECK:       <<Not2:i\d+>>        Not [<<P2>>]
   /// CHECK:       <<Xor:i\d+>>         Xor [<<Not1>>,<<Not2>>]
   /// CHECK:                            Return [<<Xor>>]
 
@@ -285,11 +277,10 @@
   /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (before)
   /// CHECK:       <<P1:i\d+>>          ParameterValue
   /// CHECK:       <<P2:i\d+>>          ParameterValue
-  /// CHECK:       <<CstM1:i\d+>>       IntConstant -1
   /// CHECK:       <<One:i\d+>>         IntConstant 1
-  /// CHECK:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
+  /// CHECK:       <<Not2:i\d+>>        Not [<<P2>>]
   /// CHECK:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
-  /// CHECK:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
+  /// CHECK:       <<Not1:i\d+>>        Not [<<P1>>]
   /// CHECK:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
   /// CHECK:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
   /// CHECK:                            Return [<<Add>>]
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 167ad85..19b5358 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -222,8 +222,13 @@
 
 
 # Disable 097-duplicate-method while investigation (broken by latest Jack release, b/27358065)
+# Disable 137-cfi (b/27391690).
+# Disable 536-checker-needs-access-check and 537-checker-inline-and-unverified (b/27425061)
 TEST_ART_BROKEN_ALL_TARGET_TESTS := \
-  097-duplicate-method
+  097-duplicate-method \
+  137-cfi \
+  536-checker-needs-access-check \
+  537-checker-inline-and-unverified \
 
 ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
     $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
diff --git a/test/run-test b/test/run-test
index f1875d7..d0f93b9 100755
--- a/test/run-test
+++ b/test/run-test
@@ -677,11 +677,7 @@
 # Tests named '<number>-checker-*' will also have their CFGs verified with
 # Checker when compiled with Optimizing on host.
 if [[ "$TEST_NAME" =~ ^[0-9]+-checker- ]]; then
-  # Jack does not necessarily generate the same DEX output than dx. Because these tests depend
-  # on a particular DEX output, keep building them with dx for now (b/19467889).
-  USE_JACK="false"
-
-  if [ "$runtime" = "art" -a "$image_suffix" = "-optimizing" ]; then
+  if [ "$runtime" = "art" -a "$image_suffix" = "-optimizing" -a "$USE_JACK" = "true" ]; then
     # Optimizing has read barrier support for certain architectures
     # only. On other architectures, compiling is disabled when read
     # barriers are enabled, meaning that we do not produce a CFG file
diff --git a/tools/checker/common/logger.py b/tools/checker/common/logger.py
index 28bb458..f13eaf6 100644
--- a/tools/checker/common/logger.py
+++ b/tools/checker/common/logger.py
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 from __future__ import print_function
+import collections
 import sys
 
 class Logger(object):
@@ -21,7 +22,7 @@
     NoOutput, Error, Info = range(3)
 
   class Color(object):
-    Default, Blue, Gray, Purple, Red = range(5)
+    Default, Blue, Gray, Purple, Red, Green = range(6)
 
     @staticmethod
     def terminalCode(color, out=sys.stdout):
@@ -35,6 +36,8 @@
         return '\033[95m'
       elif color == Logger.Color.Red:
         return '\033[91m'
+      elif color == Logger.Color.Green:
+        return '\033[32m'
       else:
         return '\033[0m'
 
@@ -52,19 +55,34 @@
       out.flush()
 
   @staticmethod
-  def fail(msg, file=None, line=-1):
-    location = ""
-    if file:
-      location += file + ":"
-    if line > 0:
-      location += str(line) + ":"
-    if location:
-      location += " "
-
-    Logger.log(location, Logger.Level.Error, color=Logger.Color.Gray, newLine=False, out=sys.stderr)
+  def fail(msg, file=None, line=-1, lineText=None, variables=None):
     Logger.log("error: ", Logger.Level.Error, color=Logger.Color.Red, newLine=False, out=sys.stderr)
     Logger.log(msg, Logger.Level.Error, out=sys.stderr)
-    sys.exit(msg)
+
+    if lineText:
+      loc = ""
+      if file:
+        loc += file + ":"
+      if line > 0:
+        loc += str(line) + ":"
+      if loc:
+        loc += " "
+      Logger.log(loc, Logger.Level.Error, color=Logger.Color.Gray, newLine=False, out=sys.stderr)
+      Logger.log(lineText, Logger.Level.Error, out=sys.stderr)
+
+    if variables:
+      longestName = 0
+      for var in variables:
+        longestName = max(longestName, len(var))
+
+      for var in collections.OrderedDict(sorted(variables.items())):
+        padding = ' ' * (longestName - len(var))
+        Logger.log(var, Logger.Level.Error, color=Logger.Color.Green, newLine=False, out=sys.stderr)
+        Logger.log(padding, Logger.Level.Error, newLine=False, out=sys.stderr)
+        Logger.log(" = ", Logger.Level.Error, newLine=False, out=sys.stderr)
+        Logger.log(variables[var], Logger.Level.Error, out=sys.stderr)
+
+    sys.exit(1)
 
   @staticmethod
   def startTest(name):
@@ -76,6 +94,6 @@
     Logger.log("PASS", color=Logger.Color.Blue)
 
   @staticmethod
-  def testFailed(msg, file=None, line=-1):
+  def testFailed(msg, assertion, variables):
     Logger.log("FAIL", color=Logger.Color.Red)
-    Logger.fail(msg, file, line)
+    Logger.fail(msg, assertion.fileName, assertion.lineNo, assertion.originalText, variables)
diff --git a/tools/checker/match/file.py b/tools/checker/match/file.py
index 3ded074..6ff19d5 100644
--- a/tools/checker/match/file.py
+++ b/tools/checker/match/file.py
@@ -23,9 +23,10 @@
 MatchInfo = namedtuple("MatchInfo", ["scope", "variables"])
 
 class MatchFailedException(Exception):
-  def __init__(self, assertion, lineNo):
+  def __init__(self, assertion, lineNo, variables):
     self.assertion = assertion
     self.lineNo = lineNo
+    self.variables = variables
 
 def splitIntoGroups(assertions):
   """ Breaks up a list of assertions, grouping instructions which should be
@@ -58,7 +59,7 @@
     newVariables = MatchLines(assertion, c1Pass.body[i], variables)
     if newVariables is not None:
       return MatchInfo(MatchScope(i, i), newVariables)
-  raise MatchFailedException(assertion, scope.start)
+  raise MatchFailedException(assertion, scope.start, variables)
 
 def matchDagGroup(assertions, c1Pass, scope, variables):
   """ Attempts to find matching `c1Pass` lines for a group of DAG assertions.
@@ -92,12 +93,12 @@
     for assertion in assertions:
       assert assertion.variant == TestAssertion.Variant.Not
       if MatchLines(assertion, line, variables) is not None:
-        raise MatchFailedException(assertion, i)
+        raise MatchFailedException(assertion, i, variables)
 
 def testEvalGroup(assertions, scope, variables):
   for assertion in assertions:
     if not EvaluateLine(assertion, variables):
-      raise MatchFailedException(assertion, scope.start)
+      raise MatchFailedException(assertion, scope.start, variables)
 
 def MatchTestCase(testCase, c1Pass):
   """ Runs a test case against a C1visualizer graph dump.
@@ -181,8 +182,8 @@
     except MatchFailedException as e:
       lineNo = c1Pass.startLineNo + e.lineNo
       if e.assertion.variant == TestAssertion.Variant.Not:
-        Logger.testFailed("NOT assertion matched line {}".format(lineNo),
-                          e.assertion.fileName, e.assertion.lineNo)
+        msg = "NOT assertion matched line {}"
       else:
-        Logger.testFailed("Assertion could not be matched starting from line {}".format(lineNo),
-                          e.assertion.fileName, e.assertion.lineNo)
+        msg = "Assertion could not be matched starting from line {}"
+      msg = msg.format(lineNo)
+      Logger.testFailed(msg, e.assertion, e.variables)
diff --git a/tools/checker/match/line.py b/tools/checker/match/line.py
index 08f001f..ed48a53 100644
--- a/tools/checker/match/line.py
+++ b/tools/checker/match/line.py
@@ -35,15 +35,13 @@
   if name in variables:
     return variables[name]
   else:
-    Logger.testFailed("Missing definition of variable \"{}\"".format(name),
-                      pos.fileName, pos.lineNo)
+    Logger.testFailed("Missing definition of variable \"{}\"".format(name), pos, variables)
 
 def setVariable(name, value, variables, pos):
   if name not in variables:
     return variables.copyWith(name, value)
   else:
-    Logger.testFailed("Multiple definitions of variable \"{}\"".format(name),
-                      pos.fileName, pos.lineNo)
+    Logger.testFailed("Multiple definitions of variable \"{}\"".format(name), pos, variables)
 
 def matchWords(checkerWord, stringWord, variables, pos):
   """ Attempts to match a list of TestExpressions against a string.