diff --git a/build/Android.common.mk b/build/Android.common.mk
index 65cb75d..cd1d6da 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -23,20 +23,6 @@
 $(info Enabling ART_USE_PORTABLE_COMPILER because WITH_ART_USE_PORTABLE_COMPILER=true)
 ART_USE_PORTABLE_COMPILER := true
 endif
-ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-WITH_ART_USE_LLVM_COMPILER := true
-endif
-
-# Use llvm as the backend
-ART_USE_LLVM_COMPILER := false
-ifneq ($(wildcard art/USE_LLVM_COMPILER),)
-$(info Enabling ART_USE_LLVM_COMPILER because of existence of art/USE_LLVM_COMPILER)
-ART_USE_LLVM_COMPILER := true
-endif
-ifeq ($(WITH_ART_USE_LLVM_COMPILER),true)
-$(info Enabling ART_USE_LLVM_COMPILER because WITH_ART_USE_LLVM_COMPILER=true)
-ART_USE_LLVM_COMPILER := true
-endif
 
 LLVM_ROOT_PATH := external/llvm
 include $(LLVM_ROOT_PATH)/llvm.mk
@@ -124,7 +110,7 @@
 
 ART_TARGET_DEBUG_CFLAGS := $(art_debug_cflags)
 
-ifeq ($(ART_USE_LLVM_COMPILER),true)
+ifeq ($(ART_USE_PORTABLE_COMPILER),true)
 PARALLEL_ART_COMPILE_JOBS := -j8
 endif
 
@@ -144,7 +130,7 @@
 	src/base/mutex.cc \
 	src/base/stringpiece.cc \
 	src/base/stringprintf.cc \
-        src/base/timing_logger.cc \
+	src/base/timing_logger.cc \
 	src/base/unix_file/fd_file.cc \
 	src/base/unix_file/mapped_file.cc \
 	src/base/unix_file/null_file.cc \
@@ -266,11 +252,10 @@
 	src/well_known_classes.cc \
 	src/zip_archive.cc
 
-ifeq ($(ART_USE_LLVM_COMPILER),true)
+ifeq ($(ART_USE_PORTABLE_COMPILER),true)
 LIBART_COMMON_SRC_FILES += \
 	src/compiler_llvm/procedure_linkage_table.cc \
-	src/compiler_llvm/runtime_support_llvm.cc \
-	src/greenland/inferred_reg_category_map.cc
+	src/compiler_llvm/runtime_support_llvm.cc
 endif
 
 LIBART_COMMON_SRC_FILES += \
@@ -291,7 +276,7 @@
 	src/oat/runtime/support_stubs.cc \
 	src/oat/runtime/support_thread.cc \
 	src/oat/runtime/support_throw.cc \
-        src/oat/runtime/support_interpreter.cc
+	src/oat/runtime/support_interpreter.cc
 
 LIBART_TARGET_SRC_FILES := \
 	$(LIBART_COMMON_SRC_FILES) \
@@ -366,7 +351,7 @@
 	src/compiler/compiler_enums.h \
 	src/dex_file.h \
 	src/dex_instruction.h \
-        src/gc/gc_type.h \
+	src/gc/gc_type.h \
 	src/gc/space.h \
 	src/heap.h \
 	src/indirect_reference_table.h \
@@ -377,7 +362,7 @@
 	src/locks.h \
 	src/mirror/class.h \
 	src/thread.h \
-        src/thread_state.h \
+	src/thread_state.h \
 	src/verifier/method_verifier.h
 
 LIBARTTEST_COMMON_SRC_FILES := \
@@ -410,7 +395,7 @@
 	src/jni_compiler_test.cc \
 	src/jni_internal_test.cc \
 	src/mirror/dex_cache_test.cc \
-        src/mirror/object_test.cc \
+	src/mirror/object_test.cc \
 	src/oat/utils/arm/managed_register_arm_test.cc \
 	src/oat/utils/x86/managed_register_x86_test.cc \
 	src/oat_test.cc \
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index d06b200..730c980 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -18,9 +18,6 @@
 ART_TARGET_EXECUTABLES :=
 
 ART_EXECUTABLES_CFLAGS :=
-ifeq ($(ART_USE_LLVM_COMPILER),true)
-  ART_EXECUTABLES_CFLAGS += -DART_USE_LLVM_COMPILER=1
-endif
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   ART_EXECUTABLES_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
 endif
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 5f518a4..2dd63af 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -20,9 +20,6 @@
 ART_TARGET_TEST_TARGETS :=
 
 ART_TEST_CFLAGS :=
-ifeq ($(ART_USE_LLVM_COMPILER),true)
-  ART_TEST_CFLAGS += -DART_USE_LLVM_COMPILER=1
-endif
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   ART_TEST_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
 endif
diff --git a/build/Android.libart-compiler.mk b/build/Android.libart-compiler.mk
index 5ae7ffb..90d4cc7 100644
--- a/build/Android.libart-compiler.mk
+++ b/build/Android.libart-compiler.mk
@@ -61,35 +61,25 @@
 	src/oat/jni/x86/jni_internal_x86.cc
 
 LIBART_COMPILER_CFLAGS :=
-ifeq ($(ART_USE_LLVM_COMPILER),true)
-  LIBART_COMPILER_CFLAGS += -DART_USE_LLVM_COMPILER=1
-endif
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   LIBART_COMPILER_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
 endif
 
-ifeq ($(ART_USE_LLVM_COMPILER),true)
+ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   LIBART_COMPILER_SRC_FILES += \
 	src/compiler_llvm/compiler_llvm.cc \
-	src/compiler_llvm/dalvik_reg.cc \
+	src/compiler_llvm/gbc_expander.cc \
 	src/compiler_llvm/generated/art_module.cc \
 	src/compiler_llvm/ir_builder.cc \
 	src/compiler_llvm/jni_compiler.cc \
 	src/compiler_llvm/llvm_compilation_unit.cc \
 	src/compiler_llvm/md_builder.cc \
-	src/compiler_llvm/method_compiler.cc \
 	src/compiler_llvm/runtime_support_builder.cc \
 	src/compiler_llvm/runtime_support_builder_arm.cc \
 	src/compiler_llvm/runtime_support_builder_thumb2.cc \
 	src/compiler_llvm/runtime_support_builder_x86.cc \
 	src/compiler_llvm/runtime_support_llvm.cc \
-	src/compiler_llvm/stub_compiler.cc \
-	src/greenland/inferred_reg_category_map.cc
-endif
-
-ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-  LIBART_COMPILER_SRC_FILES += \
-	src/compiler_llvm/gbc_expander.cc
+	src/compiler_llvm/stub_compiler.cc
 endif
 
 # $(1): target or host
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index 5226db7..630f05a 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -15,9 +15,6 @@
 #
 
 LIBART_CFLAGS :=
-ifeq ($(ART_USE_LLVM_COMPILER),true)
-  LIBART_CFLAGS += -DART_USE_LLVM_COMPILER=1
-endif
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   LIBART_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
 endif
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 56c37fd..a00b4b9 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -57,7 +57,7 @@
 #include "os.h"
 #include "runtime.h"
 #include "runtime_support.h"
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
 #include "compiler_llvm/runtime_support_llvm.h"
 #endif
 #include "ScopedLocalRef.h"
@@ -2569,7 +2569,7 @@
   method->SetCoreSpillMask(refs_and_args->GetCoreSpillMask());
   method->SetFpSpillMask(refs_and_args->GetFpSpillMask());
   method->SetFrameSizeInBytes(refs_and_args->GetFrameSizeInBytes());
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   method->SetCode(reinterpret_cast<void*>(art_quick_proxy_invoke_handler));
 #else
   OatFile::OatMethod oat_method = GetOatMethodFor(prototype.get());
diff --git a/src/common_test.h b/src/common_test.h
index d2c9102..d78576c 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -199,7 +199,7 @@
                                 reinterpret_cast<uint32_t>(vmap_table),
                                 reinterpret_cast<uint32_t>(gc_map),
                                 reinterpret_cast<uint32_t>(invoke_stub)
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
                               , 0
 #endif
                                 );
@@ -360,8 +360,6 @@
     // TODO: make selectable
 #if defined(ART_USE_PORTABLE_COMPILER)
     CompilerBackend compiler_backend = kPortable;
-#elif defined(ART_USE_LLVM_COMPILER)
-    CompilerBackend compiler_backend = kIceland; // TODO: remove
 #else
     CompilerBackend compiler_backend = kQuick;
 #endif
diff --git a/src/compiler.cc b/src/compiler.cc
index 580da60..af0bba3 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -318,7 +318,7 @@
   // TODO: more work needed to combine initializations and allow per-method backend selection
   typedef void (*InitCompilerContextFn)(Compiler&);
   InitCompilerContextFn init_compiler_context;
-  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){
+  if (compiler_backend_ == kPortable){
     // Initialize compiler_context_
     init_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name,
                                                   compiler_library_, "ArtInitCompilerContext");
@@ -331,13 +331,13 @@
 
   init_compiler_context(*this);
 
-  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){
+  if (compiler_backend_ == kPortable) {
     jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtLLVMJniCompileMethod");
   } else {
     jni_compiler_ = FindFunction<JniCompilerFn>(compiler_so_name, compiler_library_, "ArtQuickJniCompileMethod");
   }
 
-  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)){
+  if (compiler_backend_ == kPortable) {
     create_invoke_stub_ =
         FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateLLVMInvokeStub");
   } else {
@@ -360,7 +360,7 @@
     }
   }
 
-  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
+  if (compiler_backend_ == kPortable) {
     create_proxy_stub_ = FindFunction<CreateProxyStubFn>(
         compiler_so_name, compiler_library_, "ArtCreateProxyStub");
   }
@@ -403,7 +403,7 @@
   UninitCompilerContextFn uninit_compiler_context;
   // Uninitialize compiler_context_
   // TODO: rework to combine initialization/uninitialization
-  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
+  if (compiler_backend_ == kPortable) {
     uninit_compiler_context = FindFunction<void (*)(Compiler&)>(compiler_so_name,
                                                     compiler_library_, "ArtUnInitCompilerContext");
   } else {
@@ -836,7 +836,7 @@
   // invoked, so this can be passed to the out-of-line runtime support code.
   direct_code = 0;
   direct_method = 0;
-  if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
+  if (compiler_backend_ == kPortable) {
     if (sharp_type != kStatic && sharp_type != kDirect) {
       return;
     }
@@ -1647,7 +1647,7 @@
     CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
   }
   uint64_t duration_ns = NanoTime() - start_ns;
-#ifdef ART_USE_LLVM_COMPILER
+#ifdef ART_USE_PORTABLE_COMPILER
   const uint64_t kWarnMilliSeconds = 1000;
 #else
   const uint64_t kWarnMilliSeconds = 100;
@@ -1679,7 +1679,7 @@
     InsertInvokeStub(key, compiled_invoke_stub);
   }
 
-  if (((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) && !is_static) {
+  if ((compiler_backend_ == kPortable) && !is_static) {
     const CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty);
     if (compiled_proxy_stub == NULL) {
       compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len);
diff --git a/src/compiler.h b/src/compiler.h
index 0f99f4d..9475642 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -42,8 +42,7 @@
 enum CompilerBackend {
   kQuick,
   kQuickGBC,
-  kPortable,
-  kIceland  // Temporary - remove soon
+  kPortable
 };
 
 // Thread-local storage compiler worker threads
diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc
index 9afd18e..c0f3316 100644
--- a/src/compiler/frontend.cc
+++ b/src/compiler/frontend.cc
@@ -28,7 +28,7 @@
 #include <llvm/Support/Threading.h>
 
 namespace {
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   pthread_once_t llvm_multi_init = PTHREAD_ONCE_INIT;
 #endif
   void InitializeLLVMForQuick() {
@@ -39,7 +39,7 @@
 namespace art {
 
 LLVMInfo::LLVMInfo() {
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   pthread_once(&llvm_multi_init, InitializeLLVMForQuick);
 #endif
   // Create context, module, intrinsic helper & ir builder
@@ -814,7 +814,6 @@
   if ((compiler_backend == kQuickGBC) || (compiler_backend == kPortable)) {
     cu->gen_bitcode = true;
   }
-  DCHECK_NE(compiler_backend, kIceland);  // TODO: remove when Portable/Iceland merge complete
   cu->llvm_info = llvm_info;
   /* Adjust this value accordingly once inlining is performed */
   cu->num_dalvik_registers = code_item->registers_size_;
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index b635dd0..db2a91b 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -24,7 +24,6 @@
 #include "ir_builder.h"
 #include "jni_compiler.h"
 #include "llvm_compilation_unit.h"
-#include "method_compiler.h"
 #include "oat_compilation_unit.h"
 #include "oat_file.h"
 #include "stub_compiler.h"
@@ -37,7 +36,6 @@
 #include <llvm/Support/TargetSelect.h>
 #include <llvm/Support/Threading.h>
 
-#if defined(ART_USE_PORTABLE_COMPILER)
 namespace art {
 void CompileOneMethod(Compiler& compiler,
                       const CompilerBackend compilerBackend,
@@ -47,7 +45,6 @@
                       const DexFile& dex_file,
                       LLVMInfo* llvm_info);
 }
-#endif
 
 namespace llvm {
   extern bool TimePassesIsEnabled;
@@ -139,47 +136,31 @@
 CompileDexMethod(OatCompilationUnit* oat_compilation_unit, InvokeType invoke_type) {
   UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
 
-#if defined(ART_USE_PORTABLE_COMPILER)
   std::string methodName(PrettyMethod(oat_compilation_unit->GetDexMethodIndex(),
                                       *oat_compilation_unit->GetDexFile()));
-  if (insn_set_ == kX86) {
-    // Use iceland
-    UniquePtr<MethodCompiler> method_compiler(
-        new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));
+  // TODO: consolidate ArtCompileMethods
+  CompileOneMethod(*compiler_,
+                   kPortable,
+                   oat_compilation_unit->GetCodeItem(),
+                   oat_compilation_unit->access_flags_,
+                   invoke_type,
+                   oat_compilation_unit->GetClassDefIndex(),
+                   oat_compilation_unit->GetDexMethodIndex(),
+                   oat_compilation_unit->GetClassLoader(),
+                   *oat_compilation_unit->GetDexFile(),
+                   cunit->GetQuickContext()
+  );
 
-    return method_compiler->Compile();
-  } else {
+  cunit->SetCompiler(compiler_);
+  cunit->SetOatCompilationUnit(oat_compilation_unit);
 
-    // TODO: consolidate ArtCompileMethods
-    CompileOneMethod(*compiler_,
-                     kPortable,
-                     oat_compilation_unit->GetCodeItem(),
-                     oat_compilation_unit->access_flags_,
-                     invoke_type,
-                     oat_compilation_unit->GetClassDefIndex(),
-                     oat_compilation_unit->GetDexMethodIndex(),
-                     oat_compilation_unit->GetClassLoader(),
-                     *oat_compilation_unit->GetDexFile(),
-                     cunit->GetQuickContext()
-                     );
+  cunit->Materialize();
 
-    cunit->SetCompiler(compiler_);
-    cunit->SetOatCompilationUnit(oat_compilation_unit);
-
-    cunit->Materialize();
-
-    Compiler::MethodReference mref(oat_compilation_unit->GetDexFile(),
-                                   oat_compilation_unit->GetDexMethodIndex());
-    return new CompiledMethod(compiler_->GetInstructionSet(),
-                              cunit->GetCompiledCode(),
-                              *verifier::MethodVerifier::GetDexGcMap(mref));
-  }
-#else
-  UniquePtr<MethodCompiler> method_compiler(
-      new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));
-
-  return method_compiler->Compile();
-#endif
+  Compiler::MethodReference mref(oat_compilation_unit->GetDexFile(),
+                                 oat_compilation_unit->GetDexMethodIndex());
+  return new CompiledMethod(compiler_->GetInstructionSet(),
+                            cunit->GetCompiledCode(),
+                            *verifier::MethodVerifier::GetDexGcMap(mref));
 }
 
 
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index b11ce12..0cd08a7 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -79,9 +79,7 @@
   CompiledMethod* CompileDexMethod(OatCompilationUnit* oat_compilation_unit,
                                    InvokeType invoke_type);
 
-#if defined(ART_USE_PORTABLE_COMPILER)
   CompiledMethod* CompileGBCMethod(OatCompilationUnit* oat_compilation_unit, std::string* func);
-#endif
 
   CompiledMethod* CompileNativeMethod(OatCompilationUnit* oat_compilation_unit);
 
diff --git a/src/compiler_llvm/dalvik_reg.cc b/src/compiler_llvm/dalvik_reg.cc
deleted file mode 100644
index dc73e75..0000000
--- a/src/compiler_llvm/dalvik_reg.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include "dalvik_reg.h"
-
-#include "ir_builder.h"
-#include "method_compiler.h"
-
-using namespace art;
-using namespace art::compiler_llvm;
-
-
-//----------------------------------------------------------------------------
-// Dalvik Register
-//----------------------------------------------------------------------------
-
-DalvikReg::DalvikReg(MethodCompiler& method_compiler, const std::string& name, llvm::Value* vreg)
-: method_compiler_(&method_compiler), irb_(method_compiler.GetIRBuilder()),
-  reg_name_(name), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL), vreg_(vreg) {
-}
-
-
-DalvikReg::~DalvikReg() {
-}
-
-
-llvm::Type* DalvikReg::GetRegCategoryEquivSizeTy(IRBuilder& irb, RegCategory reg_cat) {
-  switch (reg_cat) {
-  case kRegCat1nr:  return irb.getJIntTy();
-  case kRegCat2:    return irb.getJLongTy();
-  case kRegObject:  return irb.getJObjectTy();
-  default:
-    LOG(FATAL) << "Unknown register category: " << reg_cat;
-    return NULL;
-  }
-}
-
-
-char DalvikReg::GetRegCategoryNamePrefix(RegCategory reg_cat) {
-  switch (reg_cat) {
-  case kRegCat1nr:  return 'r';
-  case kRegCat2:    return 'w';
-  case kRegObject:  return 'p';
-  default:
-    LOG(FATAL) << "Unknown register category: " << reg_cat;
-    return '\0';
-  }
-}
-
-
-inline llvm::Value* DalvikReg::RegCat1SExt(llvm::Value* value) {
-  return irb_.CreateSExt(value, irb_.getJIntTy());
-}
-
-
-inline llvm::Value* DalvikReg::RegCat1ZExt(llvm::Value* value) {
-  return irb_.CreateZExt(value, irb_.getJIntTy());
-}
-
-
-inline llvm::Value* DalvikReg::RegCat1Trunc(llvm::Value* value,
-                                            llvm::Type* ty) {
-  return irb_.CreateTrunc(value, ty);
-}
-
-
-llvm::Value* DalvikReg::GetValue(JType jty, JTypeSpace space) {
-  DCHECK_NE(jty, kVoid) << "Dalvik register will never be void type";
-
-  llvm::Value* value = NULL;
-  switch (space) {
-  case kReg:
-  case kField:
-    value = irb_.CreateLoad(GetAddr(jty), kTBAARegister);
-    break;
-
-  case kAccurate:
-  case kArray:
-    switch (jty) {
-    case kVoid:
-      LOG(FATAL) << "Dalvik register with void type has no value";
-      return NULL;
-
-    case kBoolean:
-    case kChar:
-    case kByte:
-    case kShort:
-      // NOTE: In array type space, boolean is truncated from i32 to i8, while
-      // in accurate type space, boolean is truncated from i32 to i1.
-      // For the other cases, array type space is equal to accurate type space.
-      value = RegCat1Trunc(irb_.CreateLoad(GetAddr(jty), kTBAARegister),
-                           irb_.getJType(jty, space));
-      break;
-
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kObject:
-      value = irb_.CreateLoad(GetAddr(jty), kTBAARegister);
-      break;
-
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-      return NULL;
-    }
-    break;
-  }
-
-  if (jty == kFloat || jty == kDouble) {
-    value = irb_.CreateBitCast(value, irb_.getJType(jty, space));
-  }
-  return value;
-}
-
-
-void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
-  DCHECK_NE(jty, kVoid) << "Dalvik register will never be void type";
-
-  if (jty == kFloat || jty == kDouble) {
-    value = irb_.CreateBitCast(value, irb_.getJType(jty, kReg));
-  }
-
-  switch (space) {
-  case kReg:
-  case kField:
-    break;
-
-  case kAccurate:
-  case kArray:
-    switch (jty) {
-    case kVoid:
-      LOG(FATAL) << "Dalvik register with void type has no value";
-      break;
-
-    case kBoolean:
-    case kChar:
-      // NOTE: In accurate type space, we have to zero extend boolean from
-      // i1 to i32, and char from i16 to i32.  In array type space, we have
-      // to zero extend boolean from i8 to i32, and char from i16 to i32.
-      value = RegCat1ZExt(value);
-      break;
-
-    case kByte:
-    case kShort:
-      // NOTE: In accurate type space, we have to signed extend byte from
-      // i8 to i32, and short from i16 to i32.  In array type space, we have
-      // to sign extend byte from i8 to i32, and short from i16 to i32.
-      value = RegCat1SExt(value);
-      break;
-
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kObject:
-      break;
-
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-    }
-  }
-
-  irb_.CreateStore(value, GetAddr(jty), kTBAARegister);
-  if (vreg_ != NULL) {
-    irb_.CreateStore(value,
-                     irb_.CreateBitCast(vreg_, value->getType()->getPointerTo()),
-                     kTBAAShadowFrame);
-  }
-}
-
-
-llvm::Value* DalvikReg::GetAddr(JType jty) {
-  switch (GetRegCategoryFromJType(jty)) {
-  case kRegCat1nr:
-    if (reg_32_ == NULL) {
-      reg_32_ = method_compiler_->AllocDalvikReg(kRegCat1nr, reg_name_);
-    }
-    return reg_32_;
-
-  case kRegCat2:
-    if (reg_64_ == NULL) {
-      reg_64_ = method_compiler_->AllocDalvikReg(kRegCat2, reg_name_);
-    }
-    return reg_64_;
-
-  case kRegObject:
-    if (reg_obj_ == NULL) {
-      reg_obj_ = method_compiler_->AllocDalvikReg(kRegObject, reg_name_);
-    }
-    return reg_obj_;
-
-  default:
-    LOG(FATAL) << "Unexpected register category: "
-               << GetRegCategoryFromJType(jty);
-    return NULL;
-  }
-}
diff --git a/src/compiler_llvm/dalvik_reg.h b/src/compiler_llvm/dalvik_reg.h
deleted file mode 100644
index ac0f421..0000000
--- a/src/compiler_llvm/dalvik_reg.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ART_SRC_COMPILER_LLVM_DALVIK_REG_H_
-#define ART_SRC_COMPILER_LLVM_DALVIK_REG_H_
-
-#include "backend_types.h"
-
-#include <stdint.h>
-#include <string>
-
-namespace llvm {
-  class Type;
-  class Value;
-}
-
-namespace art {
-namespace compiler_llvm {
-
-class IRBuilder;
-class MethodCompiler;
-
-class DalvikReg {
- public:
-  static llvm::Type* GetRegCategoryEquivSizeTy(IRBuilder& irb, RegCategory reg_cat);
-
-  static char GetRegCategoryNamePrefix(RegCategory reg_cat);
-
-  DalvikReg(MethodCompiler& method_compiler, const std::string& name, llvm::Value* vreg);
-
-  ~DalvikReg();
-
-  llvm::Value* GetValue(JType jty, JTypeSpace space);
-
-  llvm::Value* GetValue(char shorty, JTypeSpace space) {
-    return GetValue(GetJTypeFromShorty(shorty), space);
-  }
-
-  void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
-
-  void SetValue(char shorty, JTypeSpace space, llvm::Value* value) {
-    return SetValue(GetJTypeFromShorty(shorty), space, value);
-  }
-
- private:
-  llvm::Value* GetAddr(JType jty);
-
-  llvm::Value* RegCat1SExt(llvm::Value* value);
-  llvm::Value* RegCat1ZExt(llvm::Value* value);
-
-  llvm::Value* RegCat1Trunc(llvm::Value* value, llvm::Type* ty);
-
-  MethodCompiler* method_compiler_;
-  IRBuilder& irb_;
-
-  std::string reg_name_;
-  llvm::Value* reg_32_;
-  llvm::Value* reg_64_;
-  llvm::Value* reg_obj_;
-  llvm::Value* vreg_;
-};
-
-} // namespace compiler_llvm
-} // namespace art
-
-#endif // ART_SRC_COMPILER_LLVM_DALVIK_REG_H_
diff --git a/src/compiler_llvm/llvm_compilation_unit.cc b/src/compiler_llvm/llvm_compilation_unit.cc
index 97aa6b9..5f653c6 100644
--- a/src/compiler_llvm/llvm_compilation_unit.cc
+++ b/src/compiler_llvm/llvm_compilation_unit.cc
@@ -80,11 +80,9 @@
 namespace art {
 namespace compiler_llvm {
 
-#if defined(ART_USE_PORTABLE_COMPILER)
 llvm::FunctionPass*
 CreateGBCExpanderPass(const greenland::IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
                       Compiler* compiler, OatCompilationUnit* oat_compilation_unit);
-#endif
 
 llvm::Module* makeLLVMModuleContents(llvm::Module* module);
 
@@ -92,16 +90,11 @@
 LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm,
                                  size_t cunit_idx)
 : compiler_llvm_(compiler_llvm), cunit_idx_(cunit_idx) {
-#if !defined(ART_USE_PORTABLE_COMPILER)
-  context_.reset(new llvm::LLVMContext());
-  module_ = new llvm::Module("art", *context_);
-#else
   compiler_ = NULL;
   oat_compilation_unit_ = NULL;
   llvm_info_.reset(new LLVMInfo());
   context_.reset(llvm_info_->GetLLVMContext());
   module_ = llvm_info_->GetLLVMModule();
-#endif
 
   // Include the runtime function declaration
   makeLLVMModuleContents(module_);
@@ -130,10 +123,8 @@
 
 
 LlvmCompilationUnit::~LlvmCompilationUnit() {
-#if defined(ART_USE_PORTABLE_COMPILER)
   llvm::LLVMContext* llvm_context = context_.release(); // Managed by llvm_info_
   CHECK(llvm_context != NULL);
-#endif
 }
 
 
@@ -219,12 +210,9 @@
   if (bitcode_filename_.empty()) {
     // If we don't need write the bitcode to file, add the AddSuspendCheckToLoopLatchPass to the
     // regular FunctionPass.
-#if defined(ART_USE_PORTABLE_COMPILER)
     fpm.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
                                   compiler_, oat_compilation_unit_));
-#endif
   } else {
-#if defined(ART_USE_PORTABLE_COMPILER)
     llvm::FunctionPassManager fpm2(module_);
     fpm2.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
                                    compiler_, oat_compilation_unit_));
@@ -234,7 +222,6 @@
       fpm2.run(*F);
     }
     fpm2.doFinalization();
-#endif
 
     // Write bitcode to file
     std::string errmsg;
diff --git a/src/compiler_llvm/llvm_compilation_unit.h b/src/compiler_llvm/llvm_compilation_unit.h
index af3ba7a..8cc3db7 100644
--- a/src/compiler_llvm/llvm_compilation_unit.h
+++ b/src/compiler_llvm/llvm_compilation_unit.h
@@ -19,17 +19,15 @@
 
 #include "base/logging.h"
 #include "base/mutex.h"
+#include "compiler/compiler_internals.h"
+#include "compiler.h"
 #include "globals.h"
 #include "instruction_set.h"
+#include "oat_compilation_unit.h"
 #include "runtime_support_builder.h"
 #include "runtime_support_func.h"
 #include "safe_map.h"
 
-#if defined(ART_USE_PORTABLE_COMPILER)
-# include "compiler/compiler_internals.h"
-# include "compiler.h"
-# include "oat_compilation_unit.h"
-#endif
 
 #include <UniquePtr.h>
 #include <string>
@@ -78,7 +76,6 @@
     bitcode_filename_ = bitcode_filename;
   }
 
-#if defined(ART_USE_PORTABLE_COMPILER)
   LLVMInfo* GetQuickContext() const {
     return llvm_info_.get();
   }
@@ -88,7 +85,6 @@
   void SetOatCompilationUnit(OatCompilationUnit* oat_compilation_unit) {
     oat_compilation_unit_ = oat_compilation_unit;
   }
-#endif
 
   bool Materialize();
 
@@ -112,11 +108,9 @@
   UniquePtr<IRBuilder> irb_;
   UniquePtr<RuntimeSupportBuilder> runtime_support_;
   llvm::Module* module_; // Managed by context_
-#if defined(ART_USE_PORTABLE_COMPILER)
   UniquePtr<LLVMInfo> llvm_info_;
   Compiler* compiler_;
   OatCompilationUnit* oat_compilation_unit_;
-#endif
 
   std::string bitcode_filename_;
 
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
deleted file mode 100644
index 47d9b01..0000000
--- a/src/compiler_llvm/method_compiler.cc
+++ /dev/null
@@ -1,4577 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include "method_compiler.h"
-
-#include "backend_types.h"
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "base/stringprintf.h"
-#include "compiler.h"
-#include "dalvik_reg.h"
-#include "greenland/inferred_reg_category_map.h"
-#include "ir_builder.h"
-#include "llvm_compilation_unit.h"
-#include "mirror/object.h"
-#include "oat_compilation_unit.h"
-#include "object_utils.h"
-#include "runtime_support_func.h"
-#include "runtime_support_llvm.h"
-#include "utils_llvm.h"
-#include "verifier/method_verifier.h"
-
-#include <iomanip>
-
-#include <llvm/BasicBlock.h>
-#include <llvm/Function.h>
-#include <llvm/GlobalVariable.h>
-#include <llvm/Intrinsics.h>
-
-namespace art {
-namespace compiler_llvm {
-
-using namespace runtime_support;
-
-
-MethodCompiler::MethodCompiler(LlvmCompilationUnit* cunit,
-                               Compiler* compiler,
-                               OatCompilationUnit* oat_compilation_unit)
-  : cunit_(cunit), compiler_(compiler),
-    dex_file_(oat_compilation_unit->dex_file_),
-    code_item_(oat_compilation_unit->code_item_),
-    oat_compilation_unit_(oat_compilation_unit),
-    method_idx_(oat_compilation_unit->method_idx_),
-    access_flags_(oat_compilation_unit->access_flags_),
-    module_(cunit->GetModule()),
-    context_(cunit->GetLLVMContext()),
-    irb_(*cunit->GetIRBuilder()),
-    func_(NULL),
-    regs_(code_item_->registers_size_),
-    retval_reg_(NULL),
-    basic_block_alloca_(NULL), basic_block_shadow_frame_(NULL),
-    basic_block_reg_arg_init_(NULL),
-    basic_blocks_(code_item_->insns_size_in_code_units_),
-    basic_block_landing_pads_(code_item_->tries_size_, NULL),
-    basic_block_unwind_(NULL),
-    shadow_frame_(NULL), old_shadow_frame_(NULL),
-    already_pushed_shadow_frame_(NULL) {
-}
-
-
-MethodCompiler::~MethodCompiler() {
-  STLDeleteElements(&regs_);
-}
-
-
-void MethodCompiler::CreateFunction() {
-  // LLVM function name
-  std::string func_name(ElfFuncName(cunit_->GetIndex()));
-
-  // Get function type
-  llvm::FunctionType* func_type =
-    GetFunctionType(method_idx_, oat_compilation_unit_->IsStatic());
-
-  // Create function
-  func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
-                                 func_name, module_);
-
-#if !defined(NDEBUG)
-  // Set argument name
-  llvm::Function::arg_iterator arg_iter(func_->arg_begin());
-  llvm::Function::arg_iterator arg_end(func_->arg_end());
-
-  DCHECK_NE(arg_iter, arg_end);
-  arg_iter->setName("method");
-  ++arg_iter;
-
-  if (!oat_compilation_unit_->IsStatic()) {
-    DCHECK_NE(arg_iter, arg_end);
-    arg_iter->setName("this");
-    ++arg_iter;
-  }
-
-  for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
-    arg_iter->setName(StringPrintf("a%u", i));
-  }
-#endif
-}
-
-
-llvm::FunctionType* MethodCompiler::GetFunctionType(uint32_t method_idx,
-                                                    bool is_static) {
-  // Get method signature
-  DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
-
-  uint32_t shorty_size;
-  const char* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
-  CHECK_GE(shorty_size, 1u);
-
-  // Get return type
-  llvm::Type* ret_type = irb_.getJType(shorty[0], kAccurate);
-
-  // Get argument type
-  std::vector<llvm::Type*> args_type;
-
-  args_type.push_back(irb_.getJObjectTy()); // method object pointer
-
-  if (!is_static) {
-    args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer
-  }
-
-  for (uint32_t i = 1; i < shorty_size; ++i) {
-    args_type.push_back(irb_.getJType(shorty[i], kAccurate));
-  }
-
-  return llvm::FunctionType::get(ret_type, args_type, false);
-}
-
-
-void MethodCompiler::EmitPrologue() {
-  // Create basic blocks for prologue
-#if !defined(NDEBUG)
-  // Add a BasicBlock named as PrettyMethod for debugging.
-  llvm::BasicBlock* entry =
-    llvm::BasicBlock::Create(*context_, PrettyMethod(method_idx_, *dex_file_), func_);
-#endif
-  basic_block_alloca_ =
-    llvm::BasicBlock::Create(*context_, "prologue.alloca", func_);
-
-  basic_block_shadow_frame_ =
-    llvm::BasicBlock::Create(*context_, "prologue.shadowframe", func_);
-
-  basic_block_reg_arg_init_ =
-    llvm::BasicBlock::Create(*context_, "prologue.arginit", func_);
-
-#if !defined(NDEBUG)
-  irb_.SetInsertPoint(entry);
-  irb_.CreateBr(basic_block_alloca_);
-#endif
-
-  irb_.SetInsertPoint(basic_block_alloca_);
-
-  // Create Shadow Frame
-  if (method_info_.need_shadow_frame) {
-    EmitPrologueAllocShadowFrame();
-  }
-
-  // Create register array
-  for (uint16_t r = 0; r < code_item_->registers_size_; ++r) {
-    std::string name;
-#if !defined(NDEBUG)
-    name = StringPrintf("%u", r);
-#endif
-    regs_[r] = new DalvikReg(*this, name, GetVRegEntry(r));
-  }
-
-  std::string name;
-#if !defined(NDEBUG)
-  name = "_res";
-#endif
-  retval_reg_.reset(new DalvikReg(*this, name, NULL));
-
-  // Store argument to dalvik register
-  irb_.SetInsertPoint(basic_block_reg_arg_init_);
-  EmitPrologueAssignArgRegister();
-
-  // Branch to start address
-  irb_.CreateBr(GetBasicBlock(0));
-}
-
-
-void MethodCompiler::EmitStackOverflowCheck() {
-  // Call llvm intrinsic function to get frame address.
-  llvm::Function* frameaddress =
-      llvm::Intrinsic::getDeclaration(module_, llvm::Intrinsic::frameaddress);
-
-  // The type of llvm::frameaddress is: i8* @llvm.frameaddress(i32)
-  llvm::Value* frame_address = irb_.CreateCall(frameaddress, irb_.getInt32(0));
-
-  // Cast i8* to int
-  frame_address = irb_.CreatePtrToInt(frame_address, irb_.getPtrEquivIntTy());
-
-  // Get thread.stack_end_
-  llvm::Value* stack_end =
-    irb_.Runtime().EmitLoadFromThreadOffset(Thread::StackEndOffset().Int32Value(),
-                                            irb_.getPtrEquivIntTy(),
-                                            kTBAARuntimeInfo);
-
-  // Check the frame address < thread.stack_end_ ?
-  llvm::Value* is_stack_overflow = irb_.CreateICmpULT(frame_address, stack_end);
-
-  llvm::BasicBlock* block_exception =
-      llvm::BasicBlock::Create(*context_, "stack_overflow", func_);
-
-  llvm::BasicBlock* block_continue =
-      llvm::BasicBlock::Create(*context_, "stack_overflow_cont", func_);
-
-  irb_.CreateCondBr(is_stack_overflow, block_exception, block_continue, kUnlikely);
-
-  // If stack overflow, throw exception.
-  irb_.SetInsertPoint(block_exception);
-  irb_.CreateCall(irb_.GetRuntime(ThrowStackOverflowException));
-
-  // Unwind.
-  char ret_shorty = oat_compilation_unit_->GetShorty()[0];
-  if (ret_shorty == 'V') {
-    irb_.CreateRetVoid();
-  } else {
-    irb_.CreateRet(irb_.getJZero(ret_shorty));
-  }
-
-  irb_.SetInsertPoint(block_continue);
-}
-
-
-void MethodCompiler::EmitPrologueLastBranch() {
-  llvm::BasicBlock* basic_block_stack_overflow =
-    llvm::BasicBlock::Create(*context_, "prologue.stack_overflow_check", func_);
-
-  irb_.SetInsertPoint(basic_block_alloca_);
-  irb_.CreateBr(basic_block_stack_overflow);
-
-  irb_.SetInsertPoint(basic_block_stack_overflow);
-  // If a method will not call to other method, and the method is small, we can avoid stack overflow
-  // check.
-  if (method_info_.has_invoke ||
-      code_item_->registers_size_ > 32) {  // Small leaf function is OK given
-                                           // the 8KB reserved at Stack End
-    EmitStackOverflowCheck();
-  }
-  // Garbage collection safe-point
-  if (method_info_.has_invoke) {
-    EmitGuard_GarbageCollectionSuspend(DexFile::kDexNoIndex);
-  }
-  irb_.CreateBr(basic_block_shadow_frame_);
-
-  irb_.SetInsertPoint(basic_block_shadow_frame_);
-  irb_.CreateBr(basic_block_reg_arg_init_);
-}
-
-
-void MethodCompiler::EmitPrologueAllocShadowFrame() {
-  irb_.SetInsertPoint(basic_block_alloca_);
-
-  // Allocate the shadow frame now!
-  llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(code_item_->registers_size_);
-  shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
-
-  // Alloca a pointer to old shadow frame
-  old_shadow_frame_ = irb_.CreateAlloca(shadow_frame_type->getElementType(0)->getPointerTo());
-
-  irb_.SetInsertPoint(basic_block_shadow_frame_);
-
-  // Lazy pushing shadow frame
-  if (method_info_.lazy_push_shadow_frame) {
-    irb_.SetInsertPoint(basic_block_alloca_);
-    already_pushed_shadow_frame_ = irb_.CreateAlloca(irb_.getInt1Ty());
-    irb_.SetInsertPoint(basic_block_shadow_frame_);
-    irb_.CreateStore(irb_.getFalse(), already_pushed_shadow_frame_, kTBAARegister);
-    return;
-  }
-
-  EmitPushShadowFrame(true);
-}
-
-
-void MethodCompiler::EmitPrologueAssignArgRegister() {
-  uint16_t arg_reg = code_item_->registers_size_ - code_item_->ins_size_;
-
-  llvm::Function::arg_iterator arg_iter(func_->arg_begin());
-  llvm::Function::arg_iterator arg_end(func_->arg_end());
-
-  uint32_t shorty_size = 0;
-  const char* shorty = oat_compilation_unit_->GetShorty(&shorty_size);
-  CHECK_GE(shorty_size, 1u);
-
-  ++arg_iter; // skip method object
-
-  if (!oat_compilation_unit_->IsStatic()) {
-    regs_[arg_reg]->SetValue(kObject, kAccurate, arg_iter);
-    ++arg_iter;
-    ++arg_reg;
-  }
-
-  for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
-    regs_[arg_reg]->SetValue(shorty[i], kAccurate, arg_iter);
-
-    ++arg_reg;
-    if (shorty[i] == 'J' || shorty[i] == 'D') {
-      // Wide types, such as long and double, are using a pair of registers
-      // to store the value, so we have to increase arg_reg again.
-      ++arg_reg;
-    }
-  }
-
-  DCHECK_EQ(arg_end, arg_iter);
-}
-
-
-void MethodCompiler::EmitInstructions() {
-  uint32_t dex_pc = 0;
-  while (dex_pc < code_item_->insns_size_in_code_units_) {
-    const Instruction* insn = Instruction::At(code_item_->insns_ + dex_pc);
-    EmitInstruction(dex_pc, insn);
-    dex_pc += insn->SizeInCodeUnits();
-  }
-}
-
-
-void MethodCompiler::EmitInstruction(uint32_t dex_pc,
-                                     const Instruction* insn) {
-
-  // Set the IRBuilder insertion point
-  irb_.SetInsertPoint(GetBasicBlock(dex_pc));
-
-#define ARGS dex_pc, insn
-
-  // Dispatch the instruction
-  switch (insn->Opcode()) {
-  case Instruction::NOP:
-    EmitInsn_Nop(ARGS);
-    break;
-
-  case Instruction::MOVE:
-  case Instruction::MOVE_FROM16:
-  case Instruction::MOVE_16:
-    EmitInsn_Move(ARGS, kInt);
-    break;
-
-  case Instruction::MOVE_WIDE:
-  case Instruction::MOVE_WIDE_FROM16:
-  case Instruction::MOVE_WIDE_16:
-    EmitInsn_Move(ARGS, kLong);
-    break;
-
-  case Instruction::MOVE_OBJECT:
-  case Instruction::MOVE_OBJECT_FROM16:
-  case Instruction::MOVE_OBJECT_16:
-    EmitInsn_Move(ARGS, kObject);
-    break;
-
-  case Instruction::MOVE_RESULT:
-    EmitInsn_MoveResult(ARGS, kInt);
-    break;
-
-  case Instruction::MOVE_RESULT_WIDE:
-    EmitInsn_MoveResult(ARGS, kLong);
-    break;
-
-  case Instruction::MOVE_RESULT_OBJECT:
-    EmitInsn_MoveResult(ARGS, kObject);
-    break;
-
-  case Instruction::MOVE_EXCEPTION:
-    EmitInsn_MoveException(ARGS);
-    break;
-
-  case Instruction::RETURN_VOID:
-    EmitInsn_ReturnVoid(ARGS);
-    break;
-
-  case Instruction::RETURN:
-  case Instruction::RETURN_WIDE:
-  case Instruction::RETURN_OBJECT:
-    EmitInsn_Return(ARGS);
-    break;
-
-  case Instruction::CONST_4:
-  case Instruction::CONST_16:
-  case Instruction::CONST:
-  case Instruction::CONST_HIGH16:
-    EmitInsn_LoadConstant(ARGS, kInt);
-    break;
-
-  case Instruction::CONST_WIDE_16:
-  case Instruction::CONST_WIDE_32:
-  case Instruction::CONST_WIDE:
-  case Instruction::CONST_WIDE_HIGH16:
-    EmitInsn_LoadConstant(ARGS, kLong);
-    break;
-
-  case Instruction::CONST_STRING:
-  case Instruction::CONST_STRING_JUMBO:
-    EmitInsn_LoadConstantString(ARGS);
-    break;
-
-  case Instruction::CONST_CLASS:
-    EmitInsn_LoadConstantClass(ARGS);
-    break;
-
-  case Instruction::MONITOR_ENTER:
-    EmitInsn_MonitorEnter(ARGS);
-    break;
-
-  case Instruction::MONITOR_EXIT:
-    EmitInsn_MonitorExit(ARGS);
-    break;
-
-  case Instruction::CHECK_CAST:
-    EmitInsn_CheckCast(ARGS);
-    break;
-
-  case Instruction::INSTANCE_OF:
-    EmitInsn_InstanceOf(ARGS);
-    break;
-
-  case Instruction::ARRAY_LENGTH:
-    EmitInsn_ArrayLength(ARGS);
-    break;
-
-  case Instruction::NEW_INSTANCE:
-    EmitInsn_NewInstance(ARGS);
-    break;
-
-  case Instruction::NEW_ARRAY:
-    EmitInsn_NewArray(ARGS);
-    break;
-
-  case Instruction::FILLED_NEW_ARRAY:
-    EmitInsn_FilledNewArray(ARGS, false);
-    break;
-
-  case Instruction::FILLED_NEW_ARRAY_RANGE:
-    EmitInsn_FilledNewArray(ARGS, true);
-    break;
-
-  case Instruction::FILL_ARRAY_DATA:
-    EmitInsn_FillArrayData(ARGS);
-    break;
-
-  case Instruction::THROW:
-    EmitInsn_ThrowException(ARGS);
-    break;
-
-  case Instruction::GOTO:
-  case Instruction::GOTO_16:
-  case Instruction::GOTO_32:
-    EmitInsn_UnconditionalBranch(ARGS);
-    break;
-
-  case Instruction::PACKED_SWITCH:
-    EmitInsn_PackedSwitch(ARGS);
-    break;
-
-  case Instruction::SPARSE_SWITCH:
-    EmitInsn_SparseSwitch(ARGS);
-    break;
-
-  case Instruction::CMPL_FLOAT:
-    EmitInsn_FPCompare(ARGS, kFloat, false);
-    break;
-
-  case Instruction::CMPG_FLOAT:
-    EmitInsn_FPCompare(ARGS, kFloat, true);
-    break;
-
-  case Instruction::CMPL_DOUBLE:
-    EmitInsn_FPCompare(ARGS, kDouble, false);
-    break;
-
-  case Instruction::CMPG_DOUBLE:
-    EmitInsn_FPCompare(ARGS, kDouble, true);
-    break;
-
-  case Instruction::CMP_LONG:
-    EmitInsn_LongCompare(ARGS);
-    break;
-
-  case Instruction::IF_EQ:
-    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_EQ);
-    break;
-
-  case Instruction::IF_NE:
-    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_NE);
-    break;
-
-  case Instruction::IF_LT:
-    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_LT);
-    break;
-
-  case Instruction::IF_GE:
-    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_GE);
-    break;
-
-  case Instruction::IF_GT:
-    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_GT);
-    break;
-
-  case Instruction::IF_LE:
-    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_LE);
-    break;
-
-  case Instruction::IF_EQZ:
-    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_EQ);
-    break;
-
-  case Instruction::IF_NEZ:
-    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_NE);
-    break;
-
-  case Instruction::IF_LTZ:
-    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_LT);
-    break;
-
-  case Instruction::IF_GEZ:
-    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_GE);
-    break;
-
-  case Instruction::IF_GTZ:
-    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_GT);
-    break;
-
-  case Instruction::IF_LEZ:
-    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_LE);
-    break;
-
-  case Instruction::AGET:
-    EmitInsn_AGet(ARGS, kInt);
-    break;
-
-  case Instruction::AGET_WIDE:
-    EmitInsn_AGet(ARGS, kLong);
-    break;
-
-  case Instruction::AGET_OBJECT:
-    EmitInsn_AGet(ARGS, kObject);
-    break;
-
-  case Instruction::AGET_BOOLEAN:
-    EmitInsn_AGet(ARGS, kBoolean);
-    break;
-
-  case Instruction::AGET_BYTE:
-    EmitInsn_AGet(ARGS, kByte);
-    break;
-
-  case Instruction::AGET_CHAR:
-    EmitInsn_AGet(ARGS, kChar);
-    break;
-
-  case Instruction::AGET_SHORT:
-    EmitInsn_AGet(ARGS, kShort);
-    break;
-
-  case Instruction::APUT:
-    EmitInsn_APut(ARGS, kInt);
-    break;
-
-  case Instruction::APUT_WIDE:
-    EmitInsn_APut(ARGS, kLong);
-    break;
-
-  case Instruction::APUT_OBJECT:
-    EmitInsn_APut(ARGS, kObject);
-    break;
-
-  case Instruction::APUT_BOOLEAN:
-    EmitInsn_APut(ARGS, kBoolean);
-    break;
-
-  case Instruction::APUT_BYTE:
-    EmitInsn_APut(ARGS, kByte);
-    break;
-
-  case Instruction::APUT_CHAR:
-    EmitInsn_APut(ARGS, kChar);
-    break;
-
-  case Instruction::APUT_SHORT:
-    EmitInsn_APut(ARGS, kShort);
-    break;
-
-  case Instruction::IGET:
-    EmitInsn_IGet(ARGS, kInt);
-    break;
-
-  case Instruction::IGET_WIDE:
-    EmitInsn_IGet(ARGS, kLong);
-    break;
-
-  case Instruction::IGET_OBJECT:
-    EmitInsn_IGet(ARGS, kObject);
-    break;
-
-  case Instruction::IGET_BOOLEAN:
-    EmitInsn_IGet(ARGS, kBoolean);
-    break;
-
-  case Instruction::IGET_BYTE:
-    EmitInsn_IGet(ARGS, kByte);
-    break;
-
-  case Instruction::IGET_CHAR:
-    EmitInsn_IGet(ARGS, kChar);
-    break;
-
-  case Instruction::IGET_SHORT:
-    EmitInsn_IGet(ARGS, kShort);
-    break;
-
-  case Instruction::IPUT:
-    EmitInsn_IPut(ARGS, kInt);
-    break;
-
-  case Instruction::IPUT_WIDE:
-    EmitInsn_IPut(ARGS, kLong);
-    break;
-
-  case Instruction::IPUT_OBJECT:
-    EmitInsn_IPut(ARGS, kObject);
-    break;
-
-  case Instruction::IPUT_BOOLEAN:
-    EmitInsn_IPut(ARGS, kBoolean);
-    break;
-
-  case Instruction::IPUT_BYTE:
-    EmitInsn_IPut(ARGS, kByte);
-    break;
-
-  case Instruction::IPUT_CHAR:
-    EmitInsn_IPut(ARGS, kChar);
-    break;
-
-  case Instruction::IPUT_SHORT:
-    EmitInsn_IPut(ARGS, kShort);
-    break;
-
-  case Instruction::SGET:
-    EmitInsn_SGet(ARGS, kInt);
-    break;
-
-  case Instruction::SGET_WIDE:
-    EmitInsn_SGet(ARGS, kLong);
-    break;
-
-  case Instruction::SGET_OBJECT:
-    EmitInsn_SGet(ARGS, kObject);
-    break;
-
-  case Instruction::SGET_BOOLEAN:
-    EmitInsn_SGet(ARGS, kBoolean);
-    break;
-
-  case Instruction::SGET_BYTE:
-    EmitInsn_SGet(ARGS, kByte);
-    break;
-
-  case Instruction::SGET_CHAR:
-    EmitInsn_SGet(ARGS, kChar);
-    break;
-
-  case Instruction::SGET_SHORT:
-    EmitInsn_SGet(ARGS, kShort);
-    break;
-
-  case Instruction::SPUT:
-    EmitInsn_SPut(ARGS, kInt);
-    break;
-
-  case Instruction::SPUT_WIDE:
-    EmitInsn_SPut(ARGS, kLong);
-    break;
-
-  case Instruction::SPUT_OBJECT:
-    EmitInsn_SPut(ARGS, kObject);
-    break;
-
-  case Instruction::SPUT_BOOLEAN:
-    EmitInsn_SPut(ARGS, kBoolean);
-    break;
-
-  case Instruction::SPUT_BYTE:
-    EmitInsn_SPut(ARGS, kByte);
-    break;
-
-  case Instruction::SPUT_CHAR:
-    EmitInsn_SPut(ARGS, kChar);
-    break;
-
-  case Instruction::SPUT_SHORT:
-    EmitInsn_SPut(ARGS, kShort);
-    break;
-
-
-  case Instruction::INVOKE_VIRTUAL:
-    EmitInsn_Invoke(ARGS, kVirtual, kArgReg);
-    break;
-
-  case Instruction::INVOKE_SUPER:
-    EmitInsn_Invoke(ARGS, kSuper, kArgReg);
-    break;
-
-  case Instruction::INVOKE_DIRECT:
-    EmitInsn_Invoke(ARGS, kDirect, kArgReg);
-    break;
-
-  case Instruction::INVOKE_STATIC:
-    EmitInsn_Invoke(ARGS, kStatic, kArgReg);
-    break;
-
-  case Instruction::INVOKE_INTERFACE:
-    EmitInsn_Invoke(ARGS, kInterface, kArgReg);
-    break;
-
-  case Instruction::INVOKE_VIRTUAL_RANGE:
-    EmitInsn_Invoke(ARGS, kVirtual, kArgRange);
-    break;
-
-  case Instruction::INVOKE_SUPER_RANGE:
-    EmitInsn_Invoke(ARGS, kSuper, kArgRange);
-    break;
-
-  case Instruction::INVOKE_DIRECT_RANGE:
-    EmitInsn_Invoke(ARGS, kDirect, kArgRange);
-    break;
-
-  case Instruction::INVOKE_STATIC_RANGE:
-    EmitInsn_Invoke(ARGS, kStatic, kArgRange);
-    break;
-
-  case Instruction::INVOKE_INTERFACE_RANGE:
-    EmitInsn_Invoke(ARGS, kInterface, kArgRange);
-    break;
-
-  case Instruction::NEG_INT:
-    EmitInsn_Neg(ARGS, kInt);
-    break;
-
-  case Instruction::NOT_INT:
-    EmitInsn_Not(ARGS, kInt);
-    break;
-
-  case Instruction::NEG_LONG:
-    EmitInsn_Neg(ARGS, kLong);
-    break;
-
-  case Instruction::NOT_LONG:
-    EmitInsn_Not(ARGS, kLong);
-    break;
-
-  case Instruction::NEG_FLOAT:
-    EmitInsn_FNeg(ARGS, kFloat);
-    break;
-
-  case Instruction::NEG_DOUBLE:
-    EmitInsn_FNeg(ARGS, kDouble);
-    break;
-
-  case Instruction::INT_TO_LONG:
-    EmitInsn_SExt(ARGS);
-    break;
-
-  case Instruction::INT_TO_FLOAT:
-    EmitInsn_IntToFP(ARGS, kInt, kFloat);
-    break;
-
-  case Instruction::INT_TO_DOUBLE:
-    EmitInsn_IntToFP(ARGS, kInt, kDouble);
-    break;
-
-  case Instruction::LONG_TO_INT:
-    EmitInsn_Trunc(ARGS);
-    break;
-
-  case Instruction::LONG_TO_FLOAT:
-    EmitInsn_IntToFP(ARGS, kLong, kFloat);
-    break;
-
-  case Instruction::LONG_TO_DOUBLE:
-    EmitInsn_IntToFP(ARGS, kLong, kDouble);
-    break;
-
-  case Instruction::FLOAT_TO_INT:
-    EmitInsn_FPToInt(ARGS, kFloat, kInt, art_f2i);
-    break;
-
-  case Instruction::FLOAT_TO_LONG:
-    EmitInsn_FPToInt(ARGS, kFloat, kLong, art_f2l);
-    break;
-
-  case Instruction::FLOAT_TO_DOUBLE:
-    EmitInsn_FExt(ARGS);
-    break;
-
-  case Instruction::DOUBLE_TO_INT:
-    EmitInsn_FPToInt(ARGS, kDouble, kInt, art_d2i);
-    break;
-
-  case Instruction::DOUBLE_TO_LONG:
-    EmitInsn_FPToInt(ARGS, kDouble, kLong, art_d2l);
-    break;
-
-  case Instruction::DOUBLE_TO_FLOAT:
-    EmitInsn_FTrunc(ARGS);
-    break;
-
-  case Instruction::INT_TO_BYTE:
-    EmitInsn_TruncAndSExt(ARGS, 8);
-    break;
-
-  case Instruction::INT_TO_CHAR:
-    EmitInsn_TruncAndZExt(ARGS, 16);
-    break;
-
-  case Instruction::INT_TO_SHORT:
-    EmitInsn_TruncAndSExt(ARGS, 16);
-    break;
-
-  case Instruction::ADD_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kInt, false);
-    break;
-
-  case Instruction::SUB_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kInt, false);
-    break;
-
-  case Instruction::MUL_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kInt, false);
-    break;
-
-  case Instruction::DIV_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kInt, false);
-    break;
-
-  case Instruction::REM_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kInt, false);
-    break;
-
-  case Instruction::AND_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_And, kInt, false);
-    break;
-
-  case Instruction::OR_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kInt, false);
-    break;
-
-  case Instruction::XOR_INT:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kInt, false);
-    break;
-
-  case Instruction::SHL_INT:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kInt, false);
-    break;
-
-  case Instruction::SHR_INT:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kInt, false);
-    break;
-
-  case Instruction::USHR_INT:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kInt, false);
-    break;
-
-  case Instruction::ADD_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kLong, false);
-    break;
-
-  case Instruction::SUB_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kLong, false);
-    break;
-
-  case Instruction::MUL_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kLong, false);
-    break;
-
-  case Instruction::DIV_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kLong, false);
-    break;
-
-  case Instruction::REM_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kLong, false);
-    break;
-
-  case Instruction::AND_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_And, kLong, false);
-    break;
-
-  case Instruction::OR_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kLong, false);
-    break;
-
-  case Instruction::XOR_LONG:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kLong, false);
-    break;
-
-  case Instruction::SHL_LONG:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kLong, false);
-    break;
-
-  case Instruction::SHR_LONG:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kLong, false);
-    break;
-
-  case Instruction::USHR_LONG:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kLong, false);
-    break;
-
-  case Instruction::ADD_FLOAT:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kFloat, false);
-    break;
-
-  case Instruction::SUB_FLOAT:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kFloat, false);
-    break;
-
-  case Instruction::MUL_FLOAT:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kFloat, false);
-    break;
-
-  case Instruction::DIV_FLOAT:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kFloat, false);
-    break;
-
-  case Instruction::REM_FLOAT:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kFloat, false);
-    break;
-
-  case Instruction::ADD_DOUBLE:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kDouble, false);
-    break;
-
-  case Instruction::SUB_DOUBLE:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kDouble, false);
-    break;
-
-  case Instruction::MUL_DOUBLE:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kDouble, false);
-    break;
-
-  case Instruction::DIV_DOUBLE:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kDouble, false);
-    break;
-
-  case Instruction::REM_DOUBLE:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kDouble, false);
-    break;
-
-  case Instruction::ADD_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kInt, true);
-    break;
-
-  case Instruction::SUB_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kInt, true);
-    break;
-
-  case Instruction::MUL_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kInt, true);
-    break;
-
-  case Instruction::DIV_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kInt, true);
-    break;
-
-  case Instruction::REM_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kInt, true);
-    break;
-
-  case Instruction::AND_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_And, kInt, true);
-    break;
-
-  case Instruction::OR_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kInt, true);
-    break;
-
-  case Instruction::XOR_INT_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kInt, true);
-    break;
-
-  case Instruction::SHL_INT_2ADDR:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kInt, true);
-    break;
-
-  case Instruction::SHR_INT_2ADDR:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kInt, true);
-    break;
-
-  case Instruction::USHR_INT_2ADDR:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kInt, true);
-    break;
-
-  case Instruction::ADD_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kLong, true);
-    break;
-
-  case Instruction::SUB_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kLong, true);
-    break;
-
-  case Instruction::MUL_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kLong, true);
-    break;
-
-  case Instruction::DIV_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kLong, true);
-    break;
-
-  case Instruction::REM_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kLong, true);
-    break;
-
-  case Instruction::AND_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_And, kLong, true);
-    break;
-
-  case Instruction::OR_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kLong, true);
-    break;
-
-  case Instruction::XOR_LONG_2ADDR:
-    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kLong, true);
-    break;
-
-  case Instruction::SHL_LONG_2ADDR:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kLong, true);
-    break;
-
-  case Instruction::SHR_LONG_2ADDR:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kLong, true);
-    break;
-
-  case Instruction::USHR_LONG_2ADDR:
-    EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kLong, true);
-    break;
-
-  case Instruction::ADD_FLOAT_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kFloat, true);
-    break;
-
-  case Instruction::SUB_FLOAT_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kFloat, true);
-    break;
-
-  case Instruction::MUL_FLOAT_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kFloat, true);
-    break;
-
-  case Instruction::DIV_FLOAT_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kFloat, true);
-    break;
-
-  case Instruction::REM_FLOAT_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kFloat, true);
-    break;
-
-  case Instruction::ADD_DOUBLE_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kDouble, true);
-    break;
-
-  case Instruction::SUB_DOUBLE_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kDouble, true);
-    break;
-
-  case Instruction::MUL_DOUBLE_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kDouble, true);
-    break;
-
-  case Instruction::DIV_DOUBLE_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kDouble, true);
-    break;
-
-  case Instruction::REM_DOUBLE_2ADDR:
-    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kDouble, true);
-    break;
-
-  case Instruction::ADD_INT_LIT16:
-  case Instruction::ADD_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Add);
-    break;
-
-  case Instruction::RSUB_INT:
-  case Instruction::RSUB_INT_LIT8:
-    EmitInsn_RSubImmediate(ARGS);
-    break;
-
-  case Instruction::MUL_INT_LIT16:
-  case Instruction::MUL_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Mul);
-    break;
-
-  case Instruction::DIV_INT_LIT16:
-  case Instruction::DIV_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Div);
-    break;
-
-  case Instruction::REM_INT_LIT16:
-  case Instruction::REM_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Rem);
-    break;
-
-  case Instruction::AND_INT_LIT16:
-  case Instruction::AND_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_And);
-    break;
-
-  case Instruction::OR_INT_LIT16:
-  case Instruction::OR_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Or);
-    break;
-
-  case Instruction::XOR_INT_LIT16:
-  case Instruction::XOR_INT_LIT8:
-    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Xor);
-    break;
-
-  case Instruction::SHL_INT_LIT8:
-    EmitInsn_IntShiftArithmImmediate(ARGS, kIntArithm_Shl);
-    break;
-
-  case Instruction::SHR_INT_LIT8:
-    EmitInsn_IntShiftArithmImmediate(ARGS, kIntArithm_Shr);
-    break;
-
-  case Instruction::USHR_INT_LIT8:
-    EmitInsn_IntShiftArithmImmediate(ARGS, kIntArithm_UShr);
-    break;
-
-  case Instruction::UNUSED_3E:
-  case Instruction::UNUSED_3F:
-  case Instruction::UNUSED_40:
-  case Instruction::UNUSED_41:
-  case Instruction::UNUSED_42:
-  case Instruction::UNUSED_43:
-  case Instruction::UNUSED_73:
-  case Instruction::UNUSED_79:
-  case Instruction::UNUSED_7A:
-  case Instruction::UNUSED_E3:
-  case Instruction::UNUSED_E4:
-  case Instruction::UNUSED_E5:
-  case Instruction::UNUSED_E6:
-  case Instruction::UNUSED_E7:
-  case Instruction::UNUSED_E8:
-  case Instruction::UNUSED_E9:
-  case Instruction::UNUSED_EA:
-  case Instruction::UNUSED_EB:
-  case Instruction::UNUSED_EC:
-  case Instruction::UNUSED_ED:
-  case Instruction::UNUSED_EE:
-  case Instruction::UNUSED_EF:
-  case Instruction::UNUSED_F0:
-  case Instruction::UNUSED_F1:
-  case Instruction::UNUSED_F2:
-  case Instruction::UNUSED_F3:
-  case Instruction::UNUSED_F4:
-  case Instruction::UNUSED_F5:
-  case Instruction::UNUSED_F6:
-  case Instruction::UNUSED_F7:
-  case Instruction::UNUSED_F8:
-  case Instruction::UNUSED_F9:
-  case Instruction::UNUSED_FA:
-  case Instruction::UNUSED_FB:
-  case Instruction::UNUSED_FC:
-  case Instruction::UNUSED_FD:
-  case Instruction::UNUSED_FE:
-  case Instruction::UNUSED_FF:
-    LOG(FATAL) << "Dex file contains UNUSED bytecode: " << insn->Opcode();
-    break;
-  }
-
-#undef ARGS
-}
-
-
-void MethodCompiler::EmitInsn_Nop(uint32_t dex_pc,
-                                  const Instruction* insn) {
-
-  uint16_t insn_signature = code_item_->insns_[dex_pc];
-
-  if (insn_signature == Instruction::kPackedSwitchSignature ||
-      insn_signature == Instruction::kSparseSwitchSignature ||
-      insn_signature == Instruction::kArrayDataSignature) {
-    irb_.CreateUnreachable();
-  } else {
-    irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  }
-}
-
-
-void MethodCompiler::EmitInsn_Move(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, jty, kReg);
-  EmitStoreDalvikReg(dec_insn.vA, jty, kReg, src_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_MoveResult(uint32_t dex_pc,
-                                         const Instruction* insn,
-                                         JType jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikRetValReg(jty, kReg);
-  EmitStoreDalvikReg(dec_insn.vA, jty, kReg, src_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_MoveException(uint32_t dex_pc,
-                                            const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* exception_object_addr = irb_.Runtime().EmitGetAndClearException();
-
-  // Keep the exception object in the Dalvik register
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, exception_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_ThrowException(uint32_t dex_pc,
-                                             const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* exception_addr =
-    EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  EmitUpdateDexPC(dex_pc);
-
-  irb_.CreateCall(irb_.GetRuntime(ThrowException), exception_addr);
-
-  EmitBranchExceptionLandingPad(dex_pc);
-}
-
-
-void MethodCompiler::EmitInsn_ReturnVoid(uint32_t dex_pc,
-                                         const Instruction* insn) {
-  // Pop the shadow frame
-  EmitPopShadowFrame();
-
-  // Return!
-  irb_.CreateRetVoid();
-}
-
-
-void MethodCompiler::EmitInsn_Return(uint32_t dex_pc,
-                                     const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  // Pop the shadow frame
-  EmitPopShadowFrame();
-  // NOTE: It is important to keep this AFTER the GC safe-point.  Otherwise,
-  // the return value might be collected since the shadow stack is popped.
-
-  // Return!
-  char ret_shorty = oat_compilation_unit_->GetShorty()[0];
-  llvm::Value* retval = EmitLoadDalvikReg(dec_insn.vA, ret_shorty, kAccurate);
-
-  irb_.CreateRet(retval);
-}
-
-
-void MethodCompiler::EmitInsn_LoadConstant(uint32_t dex_pc,
-                                           const Instruction* insn,
-                                           JType imm_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(imm_jty == kInt || imm_jty == kLong) << imm_jty;
-
-  int64_t imm = 0;
-
-  switch (insn->Opcode()) {
-  // 32-bit Immediate
-  case Instruction::CONST_4:
-  case Instruction::CONST_16:
-  case Instruction::CONST:
-  case Instruction::CONST_WIDE_16:
-  case Instruction::CONST_WIDE_32:
-    imm = static_cast<int64_t>(static_cast<int32_t>(dec_insn.vB));
-    break;
-
-  case Instruction::CONST_HIGH16:
-    imm = static_cast<int64_t>(static_cast<int32_t>(
-          static_cast<uint32_t>(static_cast<uint16_t>(dec_insn.vB)) << 16));
-    break;
-
-  // 64-bit Immediate
-  case Instruction::CONST_WIDE:
-    imm = static_cast<int64_t>(dec_insn.vB_wide);
-    break;
-
-  case Instruction::CONST_WIDE_HIGH16:
-    imm = static_cast<int64_t>(
-          static_cast<uint64_t>(static_cast<uint16_t>(dec_insn.vB)) << 48);
-    break;
-
-  // Unknown opcode for load constant (unreachable)
-  default:
-    LOG(FATAL) << "Unknown opcode for load constant: " << insn->Opcode();
-    break;
-  }
-
-  // Store the non-object register
-  llvm::Type* imm_type = irb_.getJType(imm_jty, kAccurate);
-  llvm::Constant* imm_value = llvm::ConstantInt::getSigned(imm_type, imm);
-  EmitStoreDalvikReg(dec_insn.vA, imm_jty, kAccurate, imm_value);
-
-  // Store the object register if it is possible to be null.
-  if (imm_jty == kInt && imm == 0) {
-    EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, irb_.getJNull());
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_LoadConstantString(uint32_t dex_pc,
-                                                 const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t string_idx = dec_insn.vB;
-
-  llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
-
-  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
-
-  if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
-    llvm::BasicBlock* block_str_exist =
-      CreateBasicBlockWithDexPC(dex_pc, "str_exist");
-
-    llvm::BasicBlock* block_str_resolve =
-      CreateBasicBlockWithDexPC(dex_pc, "str_resolve");
-
-    // Test: Is the string resolved and in the dex cache?
-    llvm::Value* equal_null = irb_.CreateICmpEQ(string_addr, irb_.getJNull());
-
-    irb_.CreateCondBr(equal_null, block_str_resolve, block_str_exist, kUnlikely);
-
-    // String is resolved, go to next basic block.
-    irb_.SetInsertPoint(block_str_exist);
-    EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, string_addr);
-    irb_.CreateBr(GetNextBasicBlock(dex_pc));
-
-    // String is not resolved yet, resolve it now.
-    irb_.SetInsertPoint(block_str_resolve);
-
-    llvm::Function* runtime_func = irb_.GetRuntime(ResolveString);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    llvm::Value* string_idx_value = irb_.getInt32(string_idx);
-
-    EmitUpdateDexPC(dex_pc);
-
-    string_addr = irb_.CreateCall2(runtime_func, method_object_addr,
-                                   string_idx_value);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, true);
-  }
-
-  // Store the string object to the Dalvik register
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, string_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value* MethodCompiler::EmitLoadConstantClass(uint32_t dex_pc,
-                                                   uint32_t type_idx) {
-  if (!compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
-    llvm::Value* type_idx_value = irb_.getInt32(type_idx);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-    llvm::Function* runtime_func =
-      irb_.GetRuntime(InitializeTypeAndVerifyAccess);
-
-    EmitUpdateDexPC(dex_pc);
-
-    llvm::Value* type_object_addr =
-      irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, false);
-
-    return type_object_addr;
-
-  } else {
-    // Try to load the class (type) object from the test cache.
-    llvm::Value* type_field_addr =
-      EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
-
-    llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
-
-    if (compiler_->CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
-      return type_object_addr;
-    }
-
-    llvm::BasicBlock* block_original = irb_.GetInsertBlock();
-
-    // Test whether class (type) object is in the dex cache or not
-    llvm::Value* equal_null =
-      irb_.CreateICmpEQ(type_object_addr, irb_.getJNull());
-
-    llvm::BasicBlock* block_cont =
-      CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-    llvm::BasicBlock* block_load_class =
-      CreateBasicBlockWithDexPC(dex_pc, "load_class");
-
-    irb_.CreateCondBr(equal_null, block_load_class, block_cont, kUnlikely);
-
-    // Failback routine to load the class object
-    irb_.SetInsertPoint(block_load_class);
-
-    llvm::Function* runtime_func = irb_.GetRuntime(InitializeType);
-
-    llvm::Constant* type_idx_value = irb_.getInt32(type_idx);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-    EmitUpdateDexPC(dex_pc);
-
-    llvm::Value* loaded_type_object_addr =
-      irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, false);
-
-    llvm::BasicBlock* block_after_load_class = irb_.GetInsertBlock();
-
-    irb_.CreateBr(block_cont);
-
-    // Now the class object must be loaded
-    irb_.SetInsertPoint(block_cont);
-
-    llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2);
-
-    phi->addIncoming(type_object_addr, block_original);
-    phi->addIncoming(loaded_type_object_addr, block_after_load_class);
-
-    return phi;
-  }
-}
-
-
-void MethodCompiler::EmitInsn_LoadConstantClass(uint32_t dex_pc,
-                                                const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, dec_insn.vB);
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, type_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_MonitorEnter(uint32_t dex_pc,
-                                           const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr =
-    EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && dec_insn.vA == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  EmitUpdateDexPC(dex_pc);
-
-  irb_.Runtime().EmitLockObject(object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_MonitorExit(uint32_t dex_pc,
-                                          const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr =
-    EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && dec_insn.vA == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  EmitUpdateDexPC(dex_pc);
-
-  irb_.Runtime().EmitUnlockObject(object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_CheckCast(uint32_t dex_pc,
-                                        const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::BasicBlock* block_test_class =
-    CreateBasicBlockWithDexPC(dex_pc, "test_class");
-
-  llvm::BasicBlock* block_test_sub_class =
-    CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
-
-  llvm::Value* object_addr =
-    EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  // Test: Is the reference equal to null?  Act as no-op when it is null.
-  llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull());
-
-  irb_.CreateCondBr(equal_null,
-                    GetNextBasicBlock(dex_pc),
-                    block_test_class);
-
-  // Test: Is the object instantiated from the given class?
-  irb_.SetInsertPoint(block_test_class);
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, dec_insn.vB);
-  DCHECK_EQ(mirror::Object::ClassOffset().Int32Value(), 0);
-
-  llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy();
-
-  llvm::Value* object_type_field_addr =
-    irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo());
-
-  llvm::Value* object_type_object_addr =
-    irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject);
-
-  llvm::Value* equal_class =
-    irb_.CreateICmpEQ(type_object_addr, object_type_object_addr);
-
-  irb_.CreateCondBr(equal_class,
-                    GetNextBasicBlock(dex_pc),
-                    block_test_sub_class);
-
-  // Test: Is the object instantiated from the subclass of the given class?
-  irb_.SetInsertPoint(block_test_sub_class);
-
-  EmitUpdateDexPC(dex_pc);
-
-  irb_.CreateCall2(irb_.GetRuntime(CheckCast),
-                   type_object_addr, object_type_object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_InstanceOf(uint32_t dex_pc,
-                                         const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Constant* zero = irb_.getJInt(0);
-  llvm::Constant* one = irb_.getJInt(1);
-
-  llvm::BasicBlock* block_nullp = CreateBasicBlockWithDexPC(dex_pc, "nullp");
-
-  llvm::BasicBlock* block_test_class =
-    CreateBasicBlockWithDexPC(dex_pc, "test_class");
-
-  llvm::BasicBlock* block_class_equals =
-    CreateBasicBlockWithDexPC(dex_pc, "class_eq");
-
-  llvm::BasicBlock* block_test_sub_class =
-    CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
-
-  llvm::Value* object_addr =
-    EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-
-  // Overview of the following code :
-  // We check for null, if so, then false, otherwise check for class == . If so
-  // then true, otherwise do callout slowpath.
-  //
-  // Test: Is the reference equal to null?  Set 0 when it is null.
-  llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull());
-
-  irb_.CreateCondBr(equal_null, block_nullp, block_test_class);
-
-  irb_.SetInsertPoint(block_nullp);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, zero);
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-
-  // Test: Is the object instantiated from the given class?
-  irb_.SetInsertPoint(block_test_class);
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, dec_insn.vC);
-  DCHECK_EQ(mirror::Object::ClassOffset().Int32Value(), 0);
-
-  llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy();
-
-  llvm::Value* object_type_field_addr =
-    irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo());
-
-  llvm::Value* object_type_object_addr =
-    irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject);
-
-  llvm::Value* equal_class =
-    irb_.CreateICmpEQ(type_object_addr, object_type_object_addr);
-
-  irb_.CreateCondBr(equal_class, block_class_equals, block_test_sub_class);
-
-  irb_.SetInsertPoint(block_class_equals);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, one);
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-
-  // Test: Is the object instantiated from the subclass of the given class?
-  irb_.SetInsertPoint(block_test_sub_class);
-
-  llvm::Value* result =
-    irb_.CreateCall2(irb_.GetRuntime(IsAssignable),
-                     type_object_addr, object_type_object_addr);
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value* MethodCompiler::EmitLoadArrayLength(llvm::Value* array) {
-  // Load array length
-  return irb_.LoadFromObjectOffset(array,
-                                   mirror::Array::LengthOffset().Int32Value(),
-                                   irb_.getJIntTy(),
-                                   kTBAAConstJObject);
-}
-
-
-void MethodCompiler::EmitInsn_ArrayLength(uint32_t dex_pc,
-                                          const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  // Get the array object address
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-  EmitGuard_NullPointerException(dex_pc, array_addr);
-
-  // Get the array length and store it to the register
-  llvm::Value* array_len = EmitLoadArrayLength(array_addr);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, array_len);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_NewInstance(uint32_t dex_pc,
-                                          const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Function* runtime_func;
-  if (compiler_->CanAccessInstantiableTypeWithoutChecks(
-        method_idx_, *dex_file_, dec_insn.vB)) {
-    runtime_func = irb_.GetRuntime(AllocObject);
-  } else {
-    runtime_func = irb_.GetRuntime(AllocObjectWithAccessCheck);
-  }
-
-  llvm::Constant* type_index_value = irb_.getInt32(dec_insn.vB);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-  EmitUpdateDexPC(dex_pc);
-
-  llvm::Value* object_addr =
-    irb_.CreateCall3(runtime_func, type_index_value, method_object_addr, thread_object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value* MethodCompiler::EmitAllocNewArray(uint32_t dex_pc,
-                                               int32_t length,
-                                               uint32_t type_idx,
-                                               bool is_filled_new_array) {
-  llvm::Function* runtime_func;
-
-  bool skip_access_check =
-    compiler_->CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx);
-
-  llvm::Value* array_length_value;
-
-  if (is_filled_new_array) {
-    runtime_func = skip_access_check ?
-      irb_.GetRuntime(CheckAndAllocArray) :
-      irb_.GetRuntime(CheckAndAllocArrayWithAccessCheck);
-    array_length_value = irb_.getInt32(length);
-  } else {
-    runtime_func = skip_access_check ?
-      irb_.GetRuntime(AllocArray) :
-      irb_.GetRuntime(AllocArrayWithAccessCheck);
-    array_length_value = EmitLoadDalvikReg(length, kInt, kAccurate);
-  }
-
-  llvm::Constant* type_index_value = irb_.getInt32(type_idx);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-  EmitUpdateDexPC(dex_pc);
-
-  llvm::Value* object_addr =
-    irb_.CreateCall4(runtime_func, type_index_value, method_object_addr,
-                     array_length_value, thread_object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc, false);
-
-  return object_addr;
-}
-
-
-void MethodCompiler::EmitInsn_NewArray(uint32_t dex_pc,
-                                       const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr =
-    EmitAllocNewArray(dex_pc, dec_insn.vB, dec_insn.vC, false);
-
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FilledNewArray(uint32_t dex_pc,
-                                             const Instruction* insn,
-                                             bool is_range) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr =
-    EmitAllocNewArray(dex_pc, dec_insn.vA, dec_insn.vB, true);
-
-  if (dec_insn.vA > 0) {
-    // Check for the element type
-    uint32_t type_desc_len = 0;
-    const char* type_desc =
-      dex_file_->StringByTypeIdx(dec_insn.vB, &type_desc_len);
-
-    DCHECK_GE(type_desc_len, 2u); // should be guaranteed by verifier
-    DCHECK_EQ(type_desc[0], '['); // should be guaranteed by verifier
-    bool is_elem_int_ty = (type_desc[1] == 'I');
-
-    uint32_t alignment;
-    llvm::Constant* elem_size;
-    llvm::PointerType* field_type;
-
-    // NOTE: Currently filled-new-array only supports 'L', '[', and 'I'
-    // as the element, thus we are only checking 2 cases: primitive int and
-    // non-primitive type.
-    if (is_elem_int_ty) {
-      alignment = sizeof(int32_t);
-      elem_size = irb_.getPtrEquivInt(sizeof(int32_t));
-      field_type = irb_.getJIntTy()->getPointerTo();
-    } else {
-      alignment = irb_.getSizeOfPtrEquivInt();
-      elem_size = irb_.getSizeOfPtrEquivIntValue();
-      field_type = irb_.getJObjectTy()->getPointerTo();
-    }
-
-    llvm::Value* data_field_offset =
-      irb_.getPtrEquivInt(mirror::Array::DataOffset(alignment).Int32Value());
-
-    llvm::Value* data_field_addr =
-      irb_.CreatePtrDisp(object_addr, data_field_offset, field_type);
-
-    // TODO: Tune this code.  Currently we are generating one instruction for
-    // one element which may be very space consuming.  Maybe changing to use
-    // memcpy may help; however, since we can't guarantee that the alloca of
-    // dalvik register are continuous, we can't perform such optimization yet.
-    for (uint32_t i = 0; i < dec_insn.vA; ++i) {
-      int reg_index;
-      if (is_range) {
-        reg_index = dec_insn.vC + i;
-      } else {
-        reg_index = dec_insn.arg[i];
-      }
-
-      llvm::Value* reg_value;
-      if (is_elem_int_ty) {
-        reg_value = EmitLoadDalvikReg(reg_index, kInt, kAccurate);
-      } else {
-        reg_value = EmitLoadDalvikReg(reg_index, kObject, kAccurate);
-      }
-
-      irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray);
-
-      data_field_addr =
-        irb_.CreatePtrDisp(data_field_addr, elem_size, field_type);
-    }
-  }
-
-  EmitStoreDalvikRetValReg(kObject, kAccurate, object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FillArrayData(uint32_t dex_pc,
-                                            const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  // Read the payload
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           static_cast<int32_t>(dec_insn.vB);
-
-  const Instruction::ArrayDataPayload* payload =
-    reinterpret_cast<const Instruction::ArrayDataPayload*>(
-        code_item_->insns_ + payload_offset);
-
-  // Load array object
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  if (payload->element_count == 0) {
-    // When the number of the elements in the payload is zero, we don't have
-    // to copy any numbers.  However, we should check whether the array object
-    // address is equal to null or not.
-    EmitGuard_NullPointerException(dex_pc, array_addr);
-  } else {
-    // To save the code size, we are going to call the runtime function to
-    // copy the content from DexFile.
-
-    // NOTE: We will check for the NullPointerException in the runtime.
-
-    llvm::Function* runtime_func = irb_.GetRuntime(FillArrayData);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitUpdateDexPC(dex_pc);
-
-    irb_.CreateCall4(runtime_func,
-                     method_object_addr, irb_.getInt32(dex_pc),
-                     array_addr, irb_.getInt32(payload_offset));
-
-    EmitGuard_ExceptionLandingPad(dex_pc, true);
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_UnconditionalBranch(uint32_t dex_pc,
-                                                  const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  int32_t branch_offset = dec_insn.vA;
-
-  if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-    // Garbage collection safe-point on backward branch
-    EmitGuard_GarbageCollectionSuspend(dex_pc);
-  }
-
-  irb_.CreateBr(GetBasicBlock(dex_pc + branch_offset));
-}
-
-
-void MethodCompiler::EmitInsn_PackedSwitch(uint32_t dex_pc,
-                                           const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           static_cast<int32_t>(dec_insn.vB);
-
-  const Instruction::PackedSwitchPayload* payload =
-    reinterpret_cast<const Instruction::PackedSwitchPayload*>(
-        code_item_->insns_ + payload_offset);
-
-  llvm::Value* value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-
-  llvm::SwitchInst* sw =
-    irb_.CreateSwitch(value, GetNextBasicBlock(dex_pc), payload->case_count);
-
-  for (uint16_t i = 0; i < payload->case_count; ++i) {
-    sw->addCase(irb_.getInt32(payload->first_key + i),
-                GetBasicBlock(dex_pc + payload->targets[i]));
-  }
-}
-
-
-void MethodCompiler::EmitInsn_SparseSwitch(uint32_t dex_pc,
-                                           const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           static_cast<int32_t>(dec_insn.vB);
-
-  const Instruction::SparseSwitchPayload* payload =
-    reinterpret_cast<const Instruction::SparseSwitchPayload*>(
-        code_item_->insns_ + payload_offset);
-
-  const int32_t* keys = payload->GetKeys();
-  const int32_t* targets = payload->GetTargets();
-
-  llvm::Value* value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-
-  llvm::SwitchInst* sw =
-    irb_.CreateSwitch(value, GetNextBasicBlock(dex_pc), payload->case_count);
-
-  for (size_t i = 0; i < payload->case_count; ++i) {
-    sw->addCase(irb_.getInt32(keys[i]), GetBasicBlock(dex_pc + targets[i]));
-  }
-}
-
-
-void MethodCompiler::EmitInsn_FPCompare(uint32_t dex_pc,
-                                        const Instruction* insn,
-                                        JType fp_jty,
-                                        bool gt_bias) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(fp_jty == kFloat || fp_jty == kDouble) << "JType: " << fp_jty;
-
-  llvm::Value* src1_value = EmitLoadDalvikReg(dec_insn.vB, fp_jty, kAccurate);
-  llvm::Value* src2_value = EmitLoadDalvikReg(dec_insn.vC, fp_jty, kAccurate);
-
-  llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value);
-  llvm::Value* cmp_lt;
-
-  if (gt_bias) {
-    cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value);
-  } else {
-    cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value);
-  }
-
-  llvm::Value* result = EmitCompareResultSelection(cmp_eq, cmp_lt);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_LongCompare(uint32_t dex_pc,
-                                          const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src1_value = EmitLoadDalvikReg(dec_insn.vB, kLong, kAccurate);
-  llvm::Value* src2_value = EmitLoadDalvikReg(dec_insn.vC, kLong, kAccurate);
-
-  llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value);
-  llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value);
-
-  llvm::Value* result = EmitCompareResultSelection(cmp_eq, cmp_lt);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value* MethodCompiler::EmitCompareResultSelection(llvm::Value* cmp_eq,
-                                                        llvm::Value* cmp_lt) {
-
-  llvm::Constant* zero = irb_.getJInt(0);
-  llvm::Constant* pos1 = irb_.getJInt(1);
-  llvm::Constant* neg1 = irb_.getJInt(-1);
-
-  llvm::Value* result_lt = irb_.CreateSelect(cmp_lt, neg1, pos1);
-  llvm::Value* result_eq = irb_.CreateSelect(cmp_eq, zero, result_lt);
-
-  return result_eq;
-}
-
-
-void MethodCompiler::EmitInsn_BinaryConditionalBranch(uint32_t dex_pc,
-                                                      const Instruction* insn,
-                                                      CondBranchKind cond) {
-
-  DecodedInstruction dec_insn(insn);
-
-  greenland::RegCategory src1_reg_cat = GetInferredRegCategory(dex_pc, dec_insn.vA);
-  greenland::RegCategory src2_reg_cat = GetInferredRegCategory(dex_pc, dec_insn.vB);
-
-  DCHECK_NE(greenland::kRegUnknown, src1_reg_cat);
-  DCHECK_NE(greenland::kRegUnknown, src2_reg_cat);
-  DCHECK_NE(greenland::kRegCat2, src1_reg_cat);
-  DCHECK_NE(greenland::kRegCat2, src2_reg_cat);
-
-  int32_t branch_offset = dec_insn.vC;
-
-  if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-    // Garbage collection safe-point on backward branch
-    EmitGuard_GarbageCollectionSuspend(dex_pc);
-  }
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (src1_reg_cat == greenland::kRegZero && src2_reg_cat == greenland::kRegZero) {
-    src1_value = irb_.getInt32(0);
-    src2_value = irb_.getInt32(0);
-  } else if (src1_reg_cat != greenland::kRegZero && src2_reg_cat != greenland::kRegZero) {
-    CHECK_EQ(src1_reg_cat, src2_reg_cat);
-
-    if (src1_reg_cat == greenland::kRegCat1nr) {
-      src1_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-      src2_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-    } else {
-      src1_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-      src2_value = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-    }
-  } else {
-    DCHECK(src1_reg_cat == greenland::kRegZero ||
-           src2_reg_cat == greenland::kRegZero);
-
-    if (src1_reg_cat == greenland::kRegZero) {
-      if (src2_reg_cat == greenland::kRegCat1nr) {
-        src1_value = irb_.getJInt(0);
-        src2_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-      } else {
-        src1_value = irb_.getJNull();
-        src2_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-      }
-    } else { // src2_reg_cat == kRegZero
-      if (src2_reg_cat == greenland::kRegCat1nr) {
-        src1_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-        src2_value = irb_.getJInt(0);
-      } else {
-        src1_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-        src2_value = irb_.getJNull();
-      }
-    }
-  }
-
-  llvm::Value* cond_value =
-    EmitConditionResult(src1_value, src2_value, cond);
-
-  irb_.CreateCondBr(cond_value,
-                    GetBasicBlock(dex_pc + branch_offset),
-                    GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_UnaryConditionalBranch(uint32_t dex_pc,
-                                                     const Instruction* insn,
-                                                     CondBranchKind cond) {
-
-  DecodedInstruction dec_insn(insn);
-
-  greenland::RegCategory src_reg_cat = GetInferredRegCategory(dex_pc, dec_insn.vA);
-
-  DCHECK_NE(greenland::kRegUnknown, src_reg_cat);
-  DCHECK_NE(greenland::kRegCat2, src_reg_cat);
-
-  int32_t branch_offset = dec_insn.vB;
-
-  if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-    // Garbage collection safe-point on backward branch
-    EmitGuard_GarbageCollectionSuspend(dex_pc);
-  }
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (src_reg_cat == greenland::kRegZero) {
-    src1_value = irb_.getInt32(0);
-    src2_value = irb_.getInt32(0);
-  } else if (src_reg_cat == greenland::kRegCat1nr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-    src2_value = irb_.getInt32(0);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-    src2_value = irb_.getJNull();
-  }
-
-  llvm::Value* cond_value =
-    EmitConditionResult(src1_value, src2_value, cond);
-
-  irb_.CreateCondBr(cond_value,
-                    GetBasicBlock(dex_pc + branch_offset),
-                    GetNextBasicBlock(dex_pc));
-}
-
-const greenland::InferredRegCategoryMap* MethodCompiler::GetInferredRegCategoryMap() {
-  Compiler::MethodReference mref(dex_file_, method_idx_);
-
-  const greenland::InferredRegCategoryMap* map =
-    verifier::MethodVerifier::GetInferredRegCategoryMap(mref);
-
-  CHECK_NE(map, static_cast<greenland::InferredRegCategoryMap*>(NULL));
-
-  return map;
-}
-
-greenland::RegCategory MethodCompiler::GetInferredRegCategory(uint32_t dex_pc,
-                                                              uint16_t reg_idx) {
-  const greenland::InferredRegCategoryMap* map = GetInferredRegCategoryMap();
-
-  return map->GetRegCategory(dex_pc, reg_idx);
-}
-
-
-llvm::Value* MethodCompiler::EmitConditionResult(llvm::Value* lhs,
-                                                 llvm::Value* rhs,
-                                                 CondBranchKind cond) {
-  switch (cond) {
-  case kCondBranch_EQ:
-    return irb_.CreateICmpEQ(lhs, rhs);
-
-  case kCondBranch_NE:
-    return irb_.CreateICmpNE(lhs, rhs);
-
-  case kCondBranch_LT:
-    return irb_.CreateICmpSLT(lhs, rhs);
-
-  case kCondBranch_GE:
-    return irb_.CreateICmpSGE(lhs, rhs);
-
-  case kCondBranch_GT:
-    return irb_.CreateICmpSGT(lhs, rhs);
-
-  case kCondBranch_LE:
-    return irb_.CreateICmpSLE(lhs, rhs);
-
-  default: // Unreachable
-    LOG(FATAL) << "Unknown conditional branch kind: " << cond;
-    return NULL;
-  }
-}
-
-void MethodCompiler::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) {
-  // Using runtime support, let the target can override by InlineAssembly.
-  irb_.Runtime().EmitMarkGCCard(value, target_addr);
-}
-
-void
-MethodCompiler::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
-                                                         llvm::Value* array,
-                                                         llvm::Value* index) {
-  llvm::Value* array_len = EmitLoadArrayLength(array);
-
-  llvm::Value* cmp = irb_.CreateICmpUGE(index, array_len);
-
-  llvm::BasicBlock* block_exception =
-    CreateBasicBlockWithDexPC(dex_pc, "overflow");
-
-  llvm::BasicBlock* block_continue =
-    CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  irb_.CreateCondBr(cmp, block_exception, block_continue, kUnlikely);
-
-  irb_.SetInsertPoint(block_exception);
-
-  EmitUpdateDexPC(dex_pc);
-  irb_.CreateCall2(irb_.GetRuntime(ThrowIndexOutOfBounds), index, array_len);
-  EmitBranchExceptionLandingPad(dex_pc);
-
-  irb_.SetInsertPoint(block_continue);
-}
-
-
-void MethodCompiler::EmitGuard_ArrayException(uint32_t dex_pc,
-                                              llvm::Value* array,
-                                              llvm::Value* index) {
-  EmitGuard_NullPointerException(dex_pc, array);
-  EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array, index);
-}
-
-
-// Emit Array GetElementPtr
-llvm::Value* MethodCompiler::EmitArrayGEP(llvm::Value* array_addr,
-                                          llvm::Value* index_value,
-                                          JType elem_jty) {
-
-  int data_offset;
-  if (elem_jty == kLong || elem_jty == kDouble ||
-      (elem_jty == kObject && sizeof(uint64_t) == sizeof(mirror::Object*))) {
-    data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
-  } else {
-    data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
-  }
-
-  llvm::Constant* data_offset_value =
-    irb_.getPtrEquivInt(data_offset);
-
-  llvm::Type* elem_type = irb_.getJType(elem_jty, kArray);
-
-  llvm::Value* array_data_addr =
-    irb_.CreatePtrDisp(array_addr, data_offset_value,
-                       elem_type->getPointerTo());
-
-  return irb_.CreateGEP(array_data_addr, index_value);
-}
-
-
-void MethodCompiler::EmitInsn_AGet(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType elem_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-  llvm::Value* index_value = EmitLoadDalvikReg(dec_insn.vC, kInt, kAccurate);
-
-  EmitGuard_ArrayException(dex_pc, array_addr, index_value);
-
-  llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty);
-
-  llvm::Value* array_elem_value = irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty);
-
-  EmitStoreDalvikReg(dec_insn.vA, elem_jty, kArray, array_elem_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_APut(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType elem_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-  llvm::Value* index_value = EmitLoadDalvikReg(dec_insn.vC, kInt, kAccurate);
-
-  EmitGuard_ArrayException(dex_pc, array_addr, index_value);
-
-  llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty);
-
-  llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, elem_jty, kArray);
-
-  if (elem_jty == kObject) { // If put an object, check the type, and mark GC card table.
-    llvm::Function* runtime_func = irb_.GetRuntime(CheckPutArrayElement);
-
-    irb_.CreateCall2(runtime_func, new_value, array_addr);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, false);
-
-    EmitMarkGCCard(new_value, array_addr);
-  }
-
-  irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_IGet(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType field_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t reg_idx = dec_insn.vB;
-  uint32_t field_idx = dec_insn.vC;
-
-  llvm::Value* object_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && reg_idx == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  llvm::Value* field_value;
-
-  int field_offset;
-  bool is_volatile;
-  bool is_fast_path = compiler_->ComputeInstanceFieldInfo(
-    field_idx, oat_compilation_unit_, field_offset, is_volatile, false);
-
-  if (!is_fast_path) {
-    llvm::Function* runtime_func;
-
-    if (field_jty == kObject) {
-      runtime_func = irb_.GetRuntime(GetObjectInstance);
-    } else if (field_jty == kLong || field_jty == kDouble) {
-      runtime_func = irb_.GetRuntime(Get64Instance);
-    } else {
-      runtime_func = irb_.GetRuntime(Get32Instance);
-    }
-
-    llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitUpdateDexPC(dex_pc);
-
-    field_value = irb_.CreateCall3(runtime_func, field_idx_value,
-                                   method_object_addr, object_addr);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    llvm::PointerType* field_type =
-      irb_.getJType(field_jty, kField)->getPointerTo();
-
-    llvm::ConstantInt* field_offset_value = irb_.getPtrEquivInt(field_offset);
-
-    llvm::Value* field_addr =
-      irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
-
-    // TODO: Check is_volatile.  We need to generate atomic load instruction
-    // when is_volatile is true.
-    field_value = irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty);
-  }
-
-  EmitStoreDalvikReg(dec_insn.vA, field_jty, kField, field_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_IPut(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType field_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t reg_idx = dec_insn.vB;
-  uint32_t field_idx = dec_insn.vC;
-
-  llvm::Value* object_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && reg_idx == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, field_jty, kField);
-
-  int field_offset;
-  bool is_volatile;
-  bool is_fast_path = compiler_->ComputeInstanceFieldInfo(
-    field_idx, oat_compilation_unit_, field_offset, is_volatile, true);
-
-  if (!is_fast_path) {
-    llvm::Function* runtime_func;
-
-    if (field_jty == kObject) {
-      runtime_func = irb_.GetRuntime(SetObjectInstance);
-    } else if (field_jty == kLong || field_jty == kDouble) {
-      runtime_func = irb_.GetRuntime(Set64Instance);
-    } else {
-      runtime_func = irb_.GetRuntime(Set32Instance);
-    }
-
-    llvm::Value* field_idx_value = irb_.getInt32(field_idx);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitUpdateDexPC(dex_pc);
-
-    irb_.CreateCall4(runtime_func, field_idx_value,
-                     method_object_addr, object_addr, new_value);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    llvm::PointerType* field_type =
-      irb_.getJType(field_jty, kField)->getPointerTo();
-
-    llvm::Value* field_offset_value = irb_.getPtrEquivInt(field_offset);
-
-    llvm::Value* field_addr =
-      irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
-
-    // TODO: Check is_volatile.  We need to generate atomic store instruction
-    // when is_volatile is true.
-    irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty);
-
-    if (field_jty == kObject) { // If put an object, mark the GC card table.
-      EmitMarkGCCard(new_value, object_addr);
-    }
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value* MethodCompiler::EmitLoadStaticStorage(uint32_t dex_pc,
-                                                   uint32_t type_idx) {
-  llvm::BasicBlock* block_load_static =
-    CreateBasicBlockWithDexPC(dex_pc, "load_static");
-
-  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  // Load static storage from dex cache
-  llvm::Value* storage_field_addr =
-    EmitLoadDexCacheStaticStorageFieldAddr(type_idx);
-
-  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
-
-  llvm::BasicBlock* block_original = irb_.GetInsertBlock();
-
-  // Test: Is the static storage of this class initialized?
-  llvm::Value* equal_null =
-    irb_.CreateICmpEQ(storage_object_addr, irb_.getJNull());
-
-  irb_.CreateCondBr(equal_null, block_load_static, block_cont, kUnlikely);
-
-  // Failback routine to load the class object
-  irb_.SetInsertPoint(block_load_static);
-
-  llvm::Function* runtime_func =
-    irb_.GetRuntime(InitializeStaticStorage);
-
-  llvm::Constant* type_idx_value = irb_.getInt32(type_idx);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-  EmitUpdateDexPC(dex_pc);
-
-  llvm::Value* loaded_storage_object_addr =
-    irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc, false);
-
-  llvm::BasicBlock* block_after_load_static = irb_.GetInsertBlock();
-
-  irb_.CreateBr(block_cont);
-
-  // Now the class object must be loaded
-  irb_.SetInsertPoint(block_cont);
-
-  llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2);
-
-  phi->addIncoming(storage_object_addr, block_original);
-  phi->addIncoming(loaded_storage_object_addr, block_after_load_static);
-
-  return phi;
-}
-
-
-void MethodCompiler::EmitInsn_SGet(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType field_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t field_idx = dec_insn.vB;
-
-  int field_offset;
-  int ssb_index;
-  bool is_referrers_class;
-  bool is_volatile;
-
-  bool is_fast_path = compiler_->ComputeStaticFieldInfo(
-    field_idx, oat_compilation_unit_, field_offset, ssb_index,
-    is_referrers_class, is_volatile, false);
-
-  llvm::Value* static_field_value;
-
-  if (!is_fast_path) {
-    llvm::Function* runtime_func;
-
-    if (field_jty == kObject) {
-      runtime_func = irb_.GetRuntime(GetObjectStatic);
-    } else if (field_jty == kLong || field_jty == kDouble) {
-      runtime_func = irb_.GetRuntime(Get64Static);
-    } else {
-      runtime_func = irb_.GetRuntime(Get32Static);
-    }
-
-    llvm::Constant* field_idx_value = irb_.getInt32(dec_insn.vB);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitUpdateDexPC(dex_pc);
-
-    static_field_value =
-      irb_.CreateCall2(runtime_func, field_idx_value, method_object_addr);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    llvm::Value* static_storage_addr = NULL;
-
-    if (is_referrers_class) {
-      // Fast path, static storage base is this method's class
-      llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-      static_storage_addr =
-        irb_.LoadFromObjectOffset(method_object_addr,
-                                  mirror::AbstractMethod::DeclaringClassOffset().Int32Value(),
-                                  irb_.getJObjectTy(),
-                                  kTBAAConstJObject);
-    } else {
-      // Medium path, static storage base in a different class which
-      // requires checks that the other class is initialized
-      DCHECK_GE(ssb_index, 0);
-      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
-    }
-
-    llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset);
-
-    llvm::Value* static_field_addr =
-      irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
-                         irb_.getJType(field_jty, kField)->getPointerTo());
-
-    // TODO: Check is_volatile.  We need to generate atomic load instruction
-    // when is_volatile is true.
-    static_field_value = irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty);
-  }
-
-  EmitStoreDalvikReg(dec_insn.vA, field_jty, kField, static_field_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_SPut(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType field_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t field_idx = dec_insn.vB;
-
-  llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, field_jty, kField);
-
-  int field_offset;
-  int ssb_index;
-  bool is_referrers_class;
-  bool is_volatile;
-
-  bool is_fast_path = compiler_->ComputeStaticFieldInfo(
-    field_idx, oat_compilation_unit_, field_offset, ssb_index,
-    is_referrers_class, is_volatile, true);
-
-  if (!is_fast_path) {
-    llvm::Function* runtime_func;
-
-    if (field_jty == kObject) {
-      runtime_func = irb_.GetRuntime(SetObjectStatic);
-    } else if (field_jty == kLong || field_jty == kDouble) {
-      runtime_func = irb_.GetRuntime(Set64Static);
-    } else {
-      runtime_func = irb_.GetRuntime(Set32Static);
-    }
-
-    llvm::Constant* field_idx_value = irb_.getInt32(dec_insn.vB);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitUpdateDexPC(dex_pc);
-
-    irb_.CreateCall3(runtime_func, field_idx_value,
-                     method_object_addr, new_value);
-
-    EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    llvm::Value* static_storage_addr = NULL;
-
-    if (is_referrers_class) {
-      // Fast path, static storage base is this method's class
-      llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-      static_storage_addr =
-        irb_.LoadFromObjectOffset(method_object_addr,
-                                  mirror::AbstractMethod::DeclaringClassOffset().Int32Value(),
-                                  irb_.getJObjectTy(),
-                                  kTBAAConstJObject);
-    } else {
-      // Medium path, static storage base in a different class which
-      // requires checks that the other class is initialized
-      DCHECK_GE(ssb_index, 0);
-      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
-    }
-
-    llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset);
-
-    llvm::Value* static_field_addr =
-      irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
-                         irb_.getJType(field_jty, kField)->getPointerTo());
-
-    // TODO: Check is_volatile.  We need to generate atomic store instruction
-    // when is_volatile is true.
-    irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty);
-
-    if (field_jty == kObject) { // If put an object, mark the GC card table.
-      EmitMarkGCCard(new_value, static_storage_addr);
-    }
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::
-EmitLoadActualParameters(std::vector<llvm::Value*>& args,
-                         uint32_t callee_method_idx,
-                         DecodedInstruction const& dec_insn,
-                         InvokeArgFmt arg_fmt,
-                         bool is_static) {
-
-  // Get method signature
-  DexFile::MethodId const& method_id =
-    dex_file_->GetMethodId(callee_method_idx);
-
-  uint32_t shorty_size;
-  const char* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
-  CHECK_GE(shorty_size, 1u);
-
-  // Load argument values according to the shorty (without "this")
-  uint16_t reg_count = 0;
-
-  if (!is_static) {
-    ++reg_count; // skip the "this" pointer
-  }
-
-  bool is_range = (arg_fmt == kArgRange);
-
-  for (uint32_t i = 1; i < shorty_size; ++i) {
-    uint32_t reg_idx = (is_range) ? (dec_insn.vC + reg_count)
-                                  : (dec_insn.arg[reg_count]);
-
-    args.push_back(EmitLoadDalvikReg(reg_idx, shorty[i], kAccurate));
-
-    ++reg_count;
-    if (shorty[i] == 'J' || shorty[i] == 'D') {
-      // Wide types, such as long and double, are using a pair of registers
-      // to store the value, so we have to increase arg_reg again.
-      ++reg_count;
-    }
-  }
-
-  DCHECK_EQ(reg_count, dec_insn.vA)
-    << "Actual argument mismatch for callee: "
-    << PrettyMethod(callee_method_idx, *dex_file_);
-}
-
-
-void MethodCompiler::EmitInsn_Invoke(uint32_t dex_pc,
-                                     const Instruction* insn,
-                                     InvokeType invoke_type,
-                                     InvokeArgFmt arg_fmt) {
-  DecodedInstruction dec_insn(insn);
-
-  bool is_static = (invoke_type == kStatic);
-  uint32_t callee_method_idx = dec_insn.vB;
-
-  // Compute invoke related information for compiler decision
-  int vtable_idx = -1;
-  uintptr_t direct_code = 0;
-  uintptr_t direct_method = 0;
-  bool is_fast_path = compiler_->
-    ComputeInvokeInfo(callee_method_idx, oat_compilation_unit_,
-                      invoke_type, vtable_idx, direct_code, direct_method);
-
-  // Load *this* actual parameter
-  uint32_t this_reg = -1u;
-  llvm::Value* this_addr = NULL;
-
-  if (!is_static) {
-    // Test: Is *this* parameter equal to null?
-    this_reg = (arg_fmt == kArgReg) ? dec_insn.arg[0] : (dec_insn.vC + 0);
-    this_addr = EmitLoadDalvikReg(this_reg, kObject, kAccurate);
-  }
-
-  // Load the method object
-  llvm::Value* callee_method_object_addr = NULL;
-
-  if (!is_fast_path) {
-    callee_method_object_addr =
-      EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx, invoke_type,
-                                               this_addr, dex_pc, is_fast_path);
-
-    if (!is_static && (!method_info_.this_will_not_be_null ||
-                       this_reg != method_info_.this_reg_idx)) {
-      // NOTE: The null pointer test should come after the method resolution.
-      // So that the "NoSuchMethodError" can be thrown before the
-      // "NullPointerException".
-      EmitGuard_NullPointerException(dex_pc, this_addr);
-    }
-
-  } else {
-    if (!is_static && (!method_info_.this_will_not_be_null ||
-                       this_reg != method_info_.this_reg_idx)) {
-      // NOTE: In the fast path, we should do the null pointer check
-      // before the access to the class object and/or direct invocation.
-      EmitGuard_NullPointerException(dex_pc, this_addr);
-    }
-
-    switch (invoke_type) {
-    case kStatic:
-    case kDirect:
-      if (direct_method != 0u &&
-          direct_method != static_cast<uintptr_t>(-1)) {
-        callee_method_object_addr =
-          irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_method),
-                              irb_.getJObjectTy());
-      } else {
-        callee_method_object_addr =
-          EmitLoadSDCalleeMethodObjectAddr(callee_method_idx);
-      }
-      break;
-
-    case kVirtual:
-      DCHECK(vtable_idx != -1);
-      callee_method_object_addr =
-        EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr);
-      break;
-
-    case kSuper:
-      LOG(FATAL) << "invoke-super should be promoted to invoke-direct in "
-                    "the fast path.";
-      break;
-
-    case kInterface:
-      callee_method_object_addr =
-        EmitCallRuntimeForCalleeMethodObjectAddr(callee_method_idx,
-                                                 invoke_type, this_addr,
-                                                 dex_pc, is_fast_path);
-      break;
-    }
-  }
-
-  // Load the actual parameter
-  std::vector<llvm::Value*> args;
-
-  args.push_back(callee_method_object_addr); // method object for callee
-
-  if (!is_static) {
-    DCHECK(this_addr != NULL);
-    args.push_back(this_addr); // "this" object for callee
-  }
-
-  EmitLoadActualParameters(args, callee_method_idx, dec_insn,
-                           arg_fmt, is_static);
-
-  if (is_fast_path && (invoke_type == kDirect || invoke_type == kStatic)) {
-    bool need_retry = EmitInlineJavaIntrinsic(PrettyMethod(callee_method_idx, *dex_file_),
-                                              args,
-                                              GetNextBasicBlock(dex_pc));
-    if (!need_retry) {
-      return;
-    }
-  }
-
-  llvm::Value* code_addr;
-  if (direct_code != 0u &&
-      direct_code != static_cast<uintptr_t>(-1)) {
-    code_addr =
-      irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_code),
-                          GetFunctionType(callee_method_idx, is_static)->getPointerTo());
-  } else {
-    code_addr =
-      irb_.LoadFromObjectOffset(callee_method_object_addr,
-                                mirror::AbstractMethod::GetCodeOffset().Int32Value(),
-                                GetFunctionType(callee_method_idx, is_static)->getPointerTo(),
-                                kTBAARuntimeInfo);
-  }
-
-  // Invoke callee
-  EmitUpdateDexPC(dex_pc);
-  llvm::Value* retval = irb_.CreateCall(code_addr, args);
-  EmitGuard_ExceptionLandingPad(dex_pc, true);
-
-  uint32_t callee_access_flags = is_static ? kAccStatic : 0;
-  UniquePtr<OatCompilationUnit> callee_oat_compilation_unit(
-    oat_compilation_unit_->GetCallee(callee_method_idx, callee_access_flags));
-
-  char ret_shorty = callee_oat_compilation_unit->GetShorty()[0];
-  if (ret_shorty != 'V') {
-    EmitStoreDalvikRetValReg(ret_shorty, kAccurate, retval);
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value* MethodCompiler::
-EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx) {
-  llvm::Value* callee_method_object_field_addr =
-    EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx);
-
-  return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo);
-}
-
-
-llvm::Value* MethodCompiler::
-EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx,
-                                      llvm::Value* this_addr) {
-  // Load class object of *this* pointer
-  llvm::Value* class_object_addr =
-    irb_.LoadFromObjectOffset(this_addr,
-                              mirror::Object::ClassOffset().Int32Value(),
-                              irb_.getJObjectTy(),
-                              kTBAAConstJObject);
-
-  // Load vtable address
-  llvm::Value* vtable_addr =
-    irb_.LoadFromObjectOffset(class_object_addr,
-                              mirror::Class::VTableOffset().Int32Value(),
-                              irb_.getJObjectTy(),
-                              kTBAAConstJObject);
-
-  // Load callee method object
-  llvm::Value* vtable_idx_value =
-    irb_.getPtrEquivInt(static_cast<uint64_t>(vtable_idx));
-
-  llvm::Value* method_field_addr =
-    EmitArrayGEP(vtable_addr, vtable_idx_value, kObject);
-
-  return irb_.CreateLoad(method_field_addr, kTBAAConstJObject);
-}
-
-
-llvm::Value* MethodCompiler::
-EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
-                                         InvokeType invoke_type,
-                                         llvm::Value* this_addr,
-                                         uint32_t dex_pc,
-                                         bool is_fast_path) {
-
-  llvm::Function* runtime_func = NULL;
-
-  switch (invoke_type) {
-  case kStatic:
-    runtime_func = irb_.GetRuntime(FindStaticMethodWithAccessCheck);
-    break;
-
-  case kDirect:
-    runtime_func = irb_.GetRuntime(FindDirectMethodWithAccessCheck);
-    break;
-
-  case kVirtual:
-    runtime_func = irb_.GetRuntime(FindVirtualMethodWithAccessCheck);
-    break;
-
-  case kSuper:
-    runtime_func = irb_.GetRuntime(FindSuperMethodWithAccessCheck);
-    break;
-
-  case kInterface:
-    if (is_fast_path) {
-      runtime_func = irb_.GetRuntime(FindInterfaceMethod);
-    } else {
-      runtime_func = irb_.GetRuntime(FindInterfaceMethodWithAccessCheck);
-    }
-    break;
-  }
-
-  llvm::Value* callee_method_idx_value = irb_.getInt32(callee_method_idx);
-
-  if (this_addr == NULL) {
-    DCHECK_EQ(invoke_type, kStatic);
-    this_addr = irb_.getJNull();
-  }
-
-  llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread();
-
-  EmitUpdateDexPC(dex_pc);
-
-  llvm::Value* callee_method_object_addr =
-    irb_.CreateCall4(runtime_func,
-                     callee_method_idx_value,
-                     this_addr,
-                     caller_method_object_addr,
-                     thread_object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc, false);
-
-  return callee_method_object_addr;
-}
-
-
-void MethodCompiler::EmitInsn_Neg(uint32_t dex_pc,
-                                  const Instruction* insn,
-                                  JType op_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  llvm::Value* result_value = irb_.CreateNeg(src_value);
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_Not(uint32_t dex_pc,
-                                  const Instruction* insn,
-                                  JType op_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  llvm::Value* result_value =
-    irb_.CreateXor(src_value, static_cast<uint64_t>(-1));
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_SExt(uint32_t dex_pc,
-                                   const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-  llvm::Value* result_value = irb_.CreateSExt(src_value, irb_.getJLongTy());
-  EmitStoreDalvikReg(dec_insn.vA, kLong, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_Trunc(uint32_t dex_pc,
-                                    const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kLong, kAccurate);
-  llvm::Value* result_value = irb_.CreateTrunc(src_value, irb_.getJIntTy());
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_TruncAndSExt(uint32_t dex_pc,
-                                           const Instruction* insn,
-                                           unsigned N) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* trunc_value =
-    irb_.CreateTrunc(src_value, llvm::Type::getIntNTy(*context_, N));
-
-  llvm::Value* result_value = irb_.CreateSExt(trunc_value, irb_.getJIntTy());
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_TruncAndZExt(uint32_t dex_pc,
-                                           const Instruction* insn,
-                                           unsigned N) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* trunc_value =
-    irb_.CreateTrunc(src_value, llvm::Type::getIntNTy(*context_, N));
-
-  llvm::Value* result_value = irb_.CreateZExt(trunc_value, irb_.getJIntTy());
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FNeg(uint32_t dex_pc,
-                                   const Instruction* insn,
-                                   JType op_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kFloat || op_jty == kDouble) << op_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  llvm::Value* result_value = irb_.CreateFNeg(src_value);
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_IntToFP(uint32_t dex_pc,
-                                      const Instruction* insn,
-                                      JType src_jty,
-                                      JType dest_jty) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(src_jty == kInt || src_jty == kLong) << src_jty;
-  DCHECK(dest_jty == kFloat || dest_jty == kDouble) << dest_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, src_jty, kAccurate);
-  llvm::Type* dest_type = irb_.getJType(dest_jty, kAccurate);
-  llvm::Value* dest_value = irb_.CreateSIToFP(src_value, dest_type);
-  EmitStoreDalvikReg(dec_insn.vA, dest_jty, kAccurate, dest_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FPToInt(uint32_t dex_pc,
-                                      const Instruction* insn,
-                                      JType src_jty,
-                                      JType dest_jty,
-                                      runtime_support::RuntimeId runtime_func_id) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(src_jty == kFloat || src_jty == kDouble) << src_jty;
-  DCHECK(dest_jty == kInt || dest_jty == kLong) << dest_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, src_jty, kAccurate);
-  llvm::Value* dest_value = irb_.CreateCall(irb_.GetRuntime(runtime_func_id), src_value);
-  EmitStoreDalvikReg(dec_insn.vA, dest_jty, kAccurate, dest_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FExt(uint32_t dex_pc,
-                                   const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kFloat, kAccurate);
-  llvm::Value* result_value = irb_.CreateFPExt(src_value, irb_.getJDoubleTy());
-  EmitStoreDalvikReg(dec_insn.vA, kDouble, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FTrunc(uint32_t dex_pc,
-                                     const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kDouble, kAccurate);
-  llvm::Value* result_value = irb_.CreateFPTrunc(src_value, irb_.getJFloatTy());
-  EmitStoreDalvikReg(dec_insn.vA, kFloat, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_IntArithm(uint32_t dex_pc,
-                                        const Instruction* insn,
-                                        IntArithmKind arithm,
-                                        JType op_jty,
-                                        bool is_2addr) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (is_2addr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vC, op_jty, kAccurate);
-  }
-
-  llvm::Value* result_value =
-    EmitIntArithmResultComputation(dex_pc, src1_value, src2_value,
-                                   arithm, op_jty);
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_IntArithmImmediate(uint32_t dex_pc,
-                                                 const Instruction* insn,
-                                                 IntArithmKind arithm) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* imm_value = irb_.getInt32(dec_insn.vC);
-
-  llvm::Value* result_value =
-    EmitIntArithmResultComputation(dex_pc, src_value, imm_value, arithm, kInt);
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value*
-MethodCompiler::EmitIntArithmResultComputation(uint32_t dex_pc,
-                                               llvm::Value* lhs,
-                                               llvm::Value* rhs,
-                                               IntArithmKind arithm,
-                                               JType op_jty) {
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  switch (arithm) {
-  case kIntArithm_Add:
-    return irb_.CreateAdd(lhs, rhs);
-
-  case kIntArithm_Sub:
-    return irb_.CreateSub(lhs, rhs);
-
-  case kIntArithm_Mul:
-    return irb_.CreateMul(lhs, rhs);
-
-  case kIntArithm_Div:
-  case kIntArithm_Rem:
-    return EmitIntDivRemResultComputation(dex_pc, lhs, rhs, arithm, op_jty);
-
-  case kIntArithm_And:
-    return irb_.CreateAnd(lhs, rhs);
-
-  case kIntArithm_Or:
-    return irb_.CreateOr(lhs, rhs);
-
-  case kIntArithm_Xor:
-    return irb_.CreateXor(lhs, rhs);
-
-  default:
-    LOG(FATAL) << "Unknown integer arithmetic kind: " << arithm;
-    return NULL;
-  }
-}
-
-
-llvm::Value*
-MethodCompiler::EmitIntDivRemResultComputation(uint32_t dex_pc,
-                                               llvm::Value* dividend,
-                                               llvm::Value* divisor,
-                                               IntArithmKind arithm,
-                                               JType op_jty) {
-  // Throw exception if the divisor is 0.
-  EmitGuard_DivZeroException(dex_pc, divisor, op_jty);
-
-  // Check the special case: MININT / -1 = MININT
-  // That case will cause overflow, which is undefined behavior in llvm.
-  // So we check the divisor is -1 or not, if the divisor is -1, we do
-  // the special path to avoid undefined behavior.
-  llvm::Type* op_type = irb_.getJType(op_jty, kAccurate);
-  llvm::Value* zero = irb_.getJZero(op_jty);
-  llvm::Value* neg_one = llvm::ConstantInt::getSigned(op_type, -1);
-  llvm::Value* result = irb_.CreateAlloca(op_type);
-
-  llvm::BasicBlock* eq_neg_one = CreateBasicBlockWithDexPC(dex_pc, "eq_neg_one");
-  llvm::BasicBlock* ne_neg_one = CreateBasicBlockWithDexPC(dex_pc, "ne_neg_one");
-  llvm::BasicBlock* neg_one_cont = CreateBasicBlockWithDexPC(dex_pc, "neg_one_cont");
-
-  llvm::Value* is_equal_neg_one = EmitConditionResult(divisor, neg_one, kCondBranch_EQ);
-  irb_.CreateCondBr(is_equal_neg_one, eq_neg_one, ne_neg_one, kUnlikely);
-
-  // If divisor == -1
-  irb_.SetInsertPoint(eq_neg_one);
-  llvm::Value* eq_result;
-  if (arithm == kIntArithm_Div) {
-    // We can just change from "dividend div -1" to "neg dividend".
-    // The sub don't care the sign/unsigned because of two's complement representation.
-    // And the behavior is what we want:
-    //  -(2^n)        (2^n)-1
-    //  MININT  < k <= MAXINT    ->     mul k -1  =  -k
-    //  MININT == k              ->     mul k -1  =   k
-    //
-    // LLVM use sub to represent 'neg'
-    eq_result = irb_.CreateSub(zero, dividend);
-  } else {
-    // Everything modulo -1 will be 0.
-    eq_result = zero;
-  }
-  irb_.CreateStore(eq_result, result, kTBAAStackTemp);
-  irb_.CreateBr(neg_one_cont);
-
-  // If divisor != -1, just do the division.
-  irb_.SetInsertPoint(ne_neg_one);
-  llvm::Value* ne_result;
-  if (arithm == kIntArithm_Div) {
-    ne_result = irb_.CreateSDiv(dividend, divisor);
-  } else {
-    ne_result = irb_.CreateSRem(dividend, divisor);
-  }
-  irb_.CreateStore(ne_result, result, kTBAAStackTemp);
-  irb_.CreateBr(neg_one_cont);
-
-  irb_.SetInsertPoint(neg_one_cont);
-  return irb_.CreateLoad(result, kTBAAStackTemp);
-}
-
-
-void MethodCompiler::EmitInsn_IntShiftArithm(uint32_t dex_pc,
-                                             const Instruction* insn,
-                                             IntShiftArithmKind arithm,
-                                             JType op_jty,
-                                             bool is_2addr) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  // NOTE: The 2nd operand of the shift arithmetic instruction is
-  // 32-bit integer regardless of the 1st operand.
-  if (is_2addr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vC, kInt, kAccurate);
-  }
-
-  llvm::Value* result_value =
-    EmitIntShiftArithmResultComputation(dex_pc, src1_value, src2_value,
-                                        arithm, op_jty);
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::
-EmitInsn_IntShiftArithmImmediate(uint32_t dex_pc,
-                                 const Instruction* insn,
-                                 IntShiftArithmKind arithm) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* imm_value = irb_.getInt32(dec_insn.vC);
-
-  llvm::Value* result_value =
-    EmitIntShiftArithmResultComputation(dex_pc, src_value, imm_value,
-                                        arithm, kInt);
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value*
-MethodCompiler::EmitIntShiftArithmResultComputation(uint32_t dex_pc,
-                                                    llvm::Value* lhs,
-                                                    llvm::Value* rhs,
-                                                    IntShiftArithmKind arithm,
-                                                    JType op_jty) {
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  if (op_jty == kInt) {
-    rhs = irb_.CreateAnd(rhs, 0x1f);
-  } else {
-    llvm::Value* masked_rhs = irb_.CreateAnd(rhs, 0x3f);
-    rhs = irb_.CreateZExt(masked_rhs, irb_.getJLongTy());
-  }
-
-  switch (arithm) {
-  case kIntArithm_Shl:
-    return irb_.CreateShl(lhs, rhs);
-
-  case kIntArithm_Shr:
-    return irb_.CreateAShr(lhs, rhs);
-
-  case kIntArithm_UShr:
-    return irb_.CreateLShr(lhs, rhs);
-
-  default:
-    LOG(FATAL) << "Unknown integer shift arithmetic kind: " << arithm;
-    return NULL;
-  }
-}
-
-
-void MethodCompiler::EmitInsn_RSubImmediate(uint32_t dex_pc,
-                                            const Instruction* insn) {
-
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-  llvm::Value* imm_value = irb_.getInt32(dec_insn.vC);
-  llvm::Value* result_value = irb_.CreateSub(imm_value, src_value);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-void MethodCompiler::EmitInsn_FPArithm(uint32_t dex_pc,
-                                       const Instruction* insn,
-                                       FPArithmKind arithm,
-                                       JType op_jty,
-                                       bool is_2addr) {
-
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kFloat || op_jty == kDouble) << op_jty;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (is_2addr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vC, op_jty, kAccurate);
-  }
-
-  llvm::Value* result_value =
-    EmitFPArithmResultComputation(dex_pc, src1_value, src2_value, arithm);
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-}
-
-
-llvm::Value*
-MethodCompiler::EmitFPArithmResultComputation(uint32_t dex_pc,
-                                              llvm::Value *lhs,
-                                              llvm::Value *rhs,
-                                              FPArithmKind arithm) {
-  switch (arithm) {
-  case kFPArithm_Add:
-    return irb_.CreateFAdd(lhs, rhs);
-
-  case kFPArithm_Sub:
-    return irb_.CreateFSub(lhs, rhs);
-
-  case kFPArithm_Mul:
-    return irb_.CreateFMul(lhs, rhs);
-
-  case kFPArithm_Div:
-    return irb_.CreateFDiv(lhs, rhs);
-
-  case kFPArithm_Rem:
-    return irb_.CreateFRem(lhs, rhs);
-
-  default:
-    LOG(FATAL) << "Unknown floating-point arithmetic kind: " << arithm;
-    return NULL;
-  }
-}
-
-
-void MethodCompiler::EmitGuard_DivZeroException(uint32_t dex_pc,
-                                                llvm::Value* denominator,
-                                                JType op_jty) {
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Constant* zero = irb_.getJZero(op_jty);
-
-  llvm::Value* equal_zero = irb_.CreateICmpEQ(denominator, zero);
-
-  llvm::BasicBlock* block_exception = CreateBasicBlockWithDexPC(dex_pc, "div0");
-
-  llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  irb_.CreateCondBr(equal_zero, block_exception, block_continue, kUnlikely);
-
-  irb_.SetInsertPoint(block_exception);
-  EmitUpdateDexPC(dex_pc);
-  irb_.CreateCall(irb_.GetRuntime(ThrowDivZeroException));
-  EmitBranchExceptionLandingPad(dex_pc);
-
-  irb_.SetInsertPoint(block_continue);
-}
-
-
-void MethodCompiler::EmitGuard_NullPointerException(uint32_t dex_pc,
-                                                    llvm::Value* object) {
-  llvm::Value* equal_null = irb_.CreateICmpEQ(object, irb_.getJNull());
-
-  llvm::BasicBlock* block_exception =
-    CreateBasicBlockWithDexPC(dex_pc, "nullp");
-
-  llvm::BasicBlock* block_continue =
-    CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  irb_.CreateCondBr(equal_null, block_exception, block_continue, kUnlikely);
-
-  irb_.SetInsertPoint(block_exception);
-  EmitUpdateDexPC(dex_pc);
-  irb_.CreateCall(irb_.GetRuntime(ThrowNullPointerException), irb_.getInt32(dex_pc));
-  EmitBranchExceptionLandingPad(dex_pc);
-
-  irb_.SetInsertPoint(block_continue);
-}
-
-
-llvm::Value* MethodCompiler::EmitLoadDexCacheAddr(MemberOffset offset) {
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  return irb_.LoadFromObjectOffset(method_object_addr,
-                                   offset.Int32Value(),
-                                   irb_.getJObjectTy(),
-                                   kTBAAConstJObject);
-}
-
-
-llvm::Value* MethodCompiler::
-EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) {
-  llvm::Value* static_storage_dex_cache_addr =
-    EmitLoadDexCacheAddr(mirror::AbstractMethod::DexCacheInitializedStaticStorageOffset());
-
-  llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
-
-  return EmitArrayGEP(static_storage_dex_cache_addr, type_idx_value, kObject);
-}
-
-
-llvm::Value* MethodCompiler::
-EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) {
-  llvm::Value* resolved_type_dex_cache_addr =
-    EmitLoadDexCacheAddr(mirror::AbstractMethod::DexCacheResolvedTypesOffset());
-
-  llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
-
-  return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value, kObject);
-}
-
-
-llvm::Value* MethodCompiler::
-EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) {
-  llvm::Value* resolved_method_dex_cache_addr =
-    EmitLoadDexCacheAddr(mirror::AbstractMethod::DexCacheResolvedMethodsOffset());
-
-  llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx);
-
-  return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value, kObject);
-}
-
-
-llvm::Value* MethodCompiler::
-EmitLoadDexCacheStringFieldAddr(uint32_t string_idx) {
-  llvm::Value* string_dex_cache_addr =
-    EmitLoadDexCacheAddr(mirror::AbstractMethod::DexCacheStringsOffset());
-
-  llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx);
-
-  return EmitArrayGEP(string_dex_cache_addr, string_idx_value, kObject);
-}
-
-
-CompiledMethod *MethodCompiler::Compile() {
-  // TODO: Use high-level IR to do this
-  // Compute method info
-  ComputeMethodInfo();
-
-  // Code generation
-  CreateFunction();
-
-  EmitPrologue();
-  EmitInstructions();
-  EmitPrologueLastBranch();
-
-  // Verify the generated bitcode
-  VERIFY_LLVM_FUNCTION(*func_);
-
-  cunit_->Materialize();
-
-  Compiler::MethodReference mref(dex_file_, method_idx_);
-  return new CompiledMethod(cunit_->GetInstructionSet(),
-                            cunit_->GetCompiledCode(),
-                            *verifier::MethodVerifier::GetDexGcMap(mref));
-}
-
-
-llvm::Value* MethodCompiler::EmitLoadMethodObjectAddr() {
-  return func_->arg_begin();
-}
-
-
-void MethodCompiler::EmitBranchExceptionLandingPad(uint32_t dex_pc) {
-  if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
-    irb_.CreateBr(lpad);
-  } else {
-    irb_.CreateBr(GetUnwindBasicBlock());
-  }
-}
-
-
-void MethodCompiler::EmitGuard_ExceptionLandingPad(uint32_t dex_pc, bool can_skip_unwind) {
-  llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc);
-  const Instruction* insn = Instruction::At(code_item_->insns_ + dex_pc);
-  if (lpad == NULL && can_skip_unwind &&
-      IsInstructionDirectToReturn(dex_pc + insn->SizeInCodeUnits())) {
-    return;
-  }
-
-  llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
-
-  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  if (lpad) {
-    irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely);
-  } else {
-    irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely);
-  }
-
-  irb_.SetInsertPoint(block_cont);
-}
-
-
-void MethodCompiler::EmitGuard_GarbageCollectionSuspend(uint32_t dex_pc) {
-  llvm::Value* suspend_count =
-      irb_.Runtime().EmitLoadFromThreadOffset(Thread::ThreadFlagsOffset().Int32Value(),
-                                              irb_.getInt16Ty(),
-                                              kTBAARuntimeInfo);
-  llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0));
-
-  llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend");
-  llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont");
-
-  irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely);
-
-  irb_.SetInsertPoint(basic_block_suspend);
-  if (dex_pc != DexFile::kDexNoIndex) {
-    EmitUpdateDexPC(dex_pc);
-  }
-  irb_.Runtime().EmitTestSuspend();
-  irb_.CreateBr(basic_block_cont);
-
-  irb_.SetInsertPoint(basic_block_cont);
-}
-
-
-llvm::BasicBlock* MethodCompiler::
-CreateBasicBlockWithDexPC(uint32_t dex_pc, const char* postfix) {
-  std::string name;
-
-#if !defined(NDEBUG)
-  if (postfix) {
-    StringAppendF(&name, "B%04x.%s", dex_pc, postfix);
-  } else {
-    StringAppendF(&name, "B%04x", dex_pc);
-  }
-#endif
-
-  return llvm::BasicBlock::Create(*context_, name, func_);
-}
-
-
-llvm::BasicBlock* MethodCompiler::GetBasicBlock(uint32_t dex_pc) {
-  DCHECK(dex_pc < code_item_->insns_size_in_code_units_);
-
-  llvm::BasicBlock* basic_block = basic_blocks_[dex_pc];
-
-  if (!basic_block) {
-    basic_block = CreateBasicBlockWithDexPC(dex_pc);
-    basic_blocks_[dex_pc] = basic_block;
-  }
-
-  return basic_block;
-}
-
-
-llvm::BasicBlock*
-MethodCompiler::GetNextBasicBlock(uint32_t dex_pc) {
-  const Instruction* insn = Instruction::At(code_item_->insns_ + dex_pc);
-  return GetBasicBlock(dex_pc + insn->SizeInCodeUnits());
-}
-
-
-int32_t MethodCompiler::GetTryItemOffset(uint32_t dex_pc) {
-  // TODO: Since we are emitting the dex instructions in ascending order
-  // w.r.t.  address, we can cache the lastest try item offset so that we
-  // don't have to do binary search for every query.
-
-  int32_t min = 0;
-  int32_t max = code_item_->tries_size_ - 1;
-
-  while (min <= max) {
-    int32_t mid = min + (max - min) / 2;
-
-    const DexFile::TryItem* ti = DexFile::GetTryItems(*code_item_, mid);
-    uint32_t start = ti->start_addr_;
-    uint32_t end = start + ti->insn_count_;
-
-    if (dex_pc < start) {
-      max = mid - 1;
-    } else if (dex_pc >= end) {
-      min = mid + 1;
-    } else {
-      return mid; // found
-    }
-  }
-
-  return -1; // not found
-}
-
-
-llvm::BasicBlock* MethodCompiler::GetLandingPadBasicBlock(uint32_t dex_pc) {
-  // Find the try item for this address in this method
-  int32_t ti_offset = GetTryItemOffset(dex_pc);
-
-  if (ti_offset == -1) {
-    return NULL; // No landing pad is available for this address.
-  }
-
-  // Check for the existing landing pad basic block
-  DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset));
-  llvm::BasicBlock* block_lpad = basic_block_landing_pads_[ti_offset];
-
-  if (block_lpad) {
-    // We have generated landing pad for this try item already.  Return the
-    // same basic block.
-    return block_lpad;
-  }
-
-  // Get try item from code item
-  const DexFile::TryItem* ti = DexFile::GetTryItems(*code_item_, ti_offset);
-
-  std::string lpadname;
-
-#if !defined(NDEBUG)
-  StringAppendF(&lpadname, "lpad%d_%04x_to_%04x", ti_offset, ti->start_addr_, ti->handler_off_);
-#endif
-
-  // Create landing pad basic block
-  block_lpad = llvm::BasicBlock::Create(*context_, lpadname, func_);
-
-  // Change IRBuilder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  irb_.SetInsertPoint(block_lpad);
-
-  // Find catch block with matching type
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* ti_offset_value = irb_.getInt32(ti_offset);
-
-  llvm::Value* catch_handler_index_value =
-    irb_.CreateCall2(irb_.GetRuntime(FindCatchBlock),
-                     method_object_addr, ti_offset_value);
-
-  // Switch instruction (Go to unwind basic block by default)
-  llvm::SwitchInst* sw =
-    irb_.CreateSwitch(catch_handler_index_value, GetUnwindBasicBlock());
-
-  // Cases with matched catch block
-  CatchHandlerIterator iter(*code_item_, ti->start_addr_);
-
-  for (uint32_t c = 0; iter.HasNext(); iter.Next(), ++c) {
-    sw->addCase(irb_.getInt32(c), GetBasicBlock(iter.GetHandlerAddress()));
-  }
-
-  // Restore the orignal insert point for IRBuilder
-  irb_.restoreIP(irb_ip_original);
-
-  // Cache this landing pad
-  DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset));
-  basic_block_landing_pads_[ti_offset] = block_lpad;
-
-  return block_lpad;
-}
-
-
-llvm::BasicBlock* MethodCompiler::GetUnwindBasicBlock() {
-  // Check the existing unwinding baisc block block
-  if (basic_block_unwind_ != NULL) {
-    return basic_block_unwind_;
-  }
-
-  // Create new basic block for unwinding
-  basic_block_unwind_ =
-    llvm::BasicBlock::Create(*context_, "exception_unwind", func_);
-
-  // Change IRBuilder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  irb_.SetInsertPoint(basic_block_unwind_);
-
-  // Pop the shadow frame
-  EmitPopShadowFrame();
-
-  // Emit the code to return default value (zero) for the given return type.
-  char ret_shorty = oat_compilation_unit_->GetShorty()[0];
-  if (ret_shorty == 'V') {
-    irb_.CreateRetVoid();
-  } else {
-    irb_.CreateRet(irb_.getJZero(ret_shorty));
-  }
-
-  // Restore the orignal insert point for IRBuilder
-  irb_.restoreIP(irb_ip_original);
-
-  return basic_block_unwind_;
-}
-
-
-llvm::Value* MethodCompiler::AllocDalvikReg(RegCategory cat, const std::string& name) {
-  // Get reg_type and reg_name from DalvikReg
-  llvm::Type* reg_type = DalvikReg::GetRegCategoryEquivSizeTy(irb_, cat);
-  std::string reg_name;
-
-#if !defined(NDEBUG)
-  StringAppendF(&reg_name, "%c%s", DalvikReg::GetRegCategoryNamePrefix(cat), name.c_str());
-#endif
-
-  // Save current IR builder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  irb_.SetInsertPoint(basic_block_alloca_);
-
-  // Alloca
-  llvm::Value* reg_addr = irb_.CreateAlloca(reg_type, 0, reg_name);
-
-  // Restore IRBuilder insert point
-  irb_.restoreIP(irb_ip_original);
-
-  DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
-  return reg_addr;
-}
-
-
-llvm::Value* MethodCompiler::GetVRegEntry(uint32_t reg_idx) {
-  if (!method_info_.need_shadow_frame_entry) {
-    return NULL;
-  }
-
-  std::string reg_name;
-
-#if !defined(NDEBUG)
-  StringAppendF(&reg_name, "v%u", reg_idx);
-#endif
-
-  // Save current IR builder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-
-  irb_.SetInsertPoint(basic_block_shadow_frame_);
-
-  llvm::Value* gep_index[] = {
-    irb_.getInt32(0), // No pointer displacement
-    irb_.getInt32(1), // VRegs
-    irb_.getInt32(reg_idx) // Pointer field
-  };
-
-  llvm::Value* reg_addr = irb_.CreateGEP(shadow_frame_, gep_index, reg_name);
-
-  // Restore IRBuilder insert point
-  irb_.restoreIP(irb_ip_original);
-
-  DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
-  return reg_addr;
-}
-
-
-void MethodCompiler::EmitPushShadowFrame(bool is_inline) {
-  if (!method_info_.need_shadow_frame) {
-    return;
-  }
-  DCHECK(shadow_frame_ != NULL);
-  DCHECK(old_shadow_frame_ != NULL);
-
-  // Get method object
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  // Push the shadow frame
-  llvm::Value* shadow_frame_upcast =
-    irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
-
-  llvm::Value* result;
-  if (is_inline) {
-    result = irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr,
-                                                code_item_->registers_size_);
-  } else {
-    result = irb_.Runtime().EmitPushShadowFrameNoInline(shadow_frame_upcast, method_object_addr,
-                                                        code_item_->registers_size_);
-  }
-  irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
-}
-
-
-void MethodCompiler::EmitPopShadowFrame() {
-  if (!method_info_.need_shadow_frame) {
-    return;
-  }
-  DCHECK(old_shadow_frame_ != NULL);
-
-  if (method_info_.lazy_push_shadow_frame) {
-    llvm::BasicBlock* bb_pop = llvm::BasicBlock::Create(*context_, "pop", func_);
-    llvm::BasicBlock* bb_cont = llvm::BasicBlock::Create(*context_, "cont", func_);
-
-    llvm::Value* need_pop = irb_.CreateLoad(already_pushed_shadow_frame_, kTBAARegister);
-    irb_.CreateCondBr(need_pop, bb_pop, bb_cont, kUnlikely);
-
-    irb_.SetInsertPoint(bb_pop);
-    irb_.Runtime().EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
-    irb_.CreateBr(bb_cont);
-
-    irb_.SetInsertPoint(bb_cont);
-  } else {
-    irb_.Runtime().EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
-  }
-}
-
-
-void MethodCompiler::EmitUpdateDexPC(uint32_t dex_pc) {
-  if (!method_info_.need_shadow_frame) {
-    return;
-  }
-  irb_.StoreToObjectOffset(shadow_frame_,
-                           ShadowFrame::DexPCOffset(),
-                           irb_.getInt32(dex_pc),
-                           kTBAAShadowFrame);
-  // Lazy pushing shadow frame
-  if (method_info_.lazy_push_shadow_frame) {
-    llvm::BasicBlock* bb_push = CreateBasicBlockWithDexPC(dex_pc, "push");
-    llvm::BasicBlock* bb_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-    llvm::Value* no_need_push = irb_.CreateLoad(already_pushed_shadow_frame_, kTBAARegister);
-    irb_.CreateCondBr(no_need_push, bb_cont, bb_push, kLikely);
-
-    irb_.SetInsertPoint(bb_push);
-    EmitPushShadowFrame(false);
-    irb_.CreateStore(irb_.getTrue(), already_pushed_shadow_frame_, kTBAARegister);
-    irb_.CreateBr(bb_cont);
-
-    irb_.SetInsertPoint(bb_cont);
-  }
-}
-
-
-llvm::Value* MethodCompiler::EmitLoadDalvikReg(uint32_t reg_idx, JType jty,
-                                               JTypeSpace space) {
-  return regs_[reg_idx]->GetValue(jty, space);
-}
-
-llvm::Value* MethodCompiler::EmitLoadDalvikReg(uint32_t reg_idx, char shorty,
-                                               JTypeSpace space) {
-  return EmitLoadDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space);
-}
-
-void MethodCompiler::EmitStoreDalvikReg(uint32_t reg_idx, JType jty,
-                                        JTypeSpace space, llvm::Value* new_value) {
-  regs_[reg_idx]->SetValue(jty, space, new_value);
-}
-
-void MethodCompiler::EmitStoreDalvikReg(uint32_t reg_idx, char shorty,
-                                        JTypeSpace space, llvm::Value* new_value) {
-  EmitStoreDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space, new_value);
-}
-
-llvm::Value* MethodCompiler::EmitLoadDalvikRetValReg(JType jty, JTypeSpace space) {
-  return retval_reg_->GetValue(jty, space);
-}
-
-llvm::Value* MethodCompiler::EmitLoadDalvikRetValReg(char shorty, JTypeSpace space) {
-  return EmitLoadDalvikRetValReg(GetJTypeFromShorty(shorty), space);
-}
-
-void MethodCompiler::EmitStoreDalvikRetValReg(JType jty, JTypeSpace space,
-                                              llvm::Value* new_value) {
-  retval_reg_->SetValue(jty, space, new_value);
-}
-
-void MethodCompiler::EmitStoreDalvikRetValReg(char shorty, JTypeSpace space,
-                                              llvm::Value* new_value) {
-  EmitStoreDalvikRetValReg(GetJTypeFromShorty(shorty), space, new_value);
-}
-
-
-// TODO: Use high-level IR to do this
-bool MethodCompiler::EmitInlineJavaIntrinsic(const std::string& callee_method_name,
-                                             const std::vector<llvm::Value*>& args,
-                                             llvm::BasicBlock* after_invoke) {
-  if (callee_method_name == "char java.lang.String.charAt(int)") {
-    return EmitInlinedStringCharAt(args, after_invoke);
-  }
-  if (callee_method_name == "int java.lang.String.length()") {
-    return EmitInlinedStringLength(args, after_invoke);
-  }
-  if (callee_method_name == "int java.lang.String.indexOf(int, int)") {
-    return EmitInlinedStringIndexOf(args, after_invoke, false /* base 0 */);
-  }
-  if (callee_method_name == "int java.lang.String.indexOf(int)") {
-    return EmitInlinedStringIndexOf(args, after_invoke, true /* base 0 */);
-  }
-  if (callee_method_name == "int java.lang.String.compareTo(java.lang.String)") {
-    return EmitInlinedStringCompareTo(args, after_invoke);
-  }
-  return true;
-}
-
-bool MethodCompiler::EmitInlinedStringCharAt(const std::vector<llvm::Value*>& args,
-                                             llvm::BasicBlock* after_invoke) {
-  DCHECK_EQ(args.size(), 3U) <<
-      "char java.lang.String.charAt(int) has 3 args: method, this, char_index";
-  llvm::Value* this_object = args[1];
-  llvm::Value* char_index = args[2];
-  llvm::BasicBlock* block_retry = llvm::BasicBlock::Create(*context_, "CharAtRetry", func_);
-  llvm::BasicBlock* block_cont = llvm::BasicBlock::Create(*context_, "CharAtCont", func_);
-
-  llvm::Value* string_count = irb_.LoadFromObjectOffset(this_object,
-                                                        mirror::String::CountOffset().Int32Value(),
-                                                        irb_.getJIntTy(),
-                                                        kTBAAConstJObject);
-  // Two's complement, so we can use only one "less than" to check "in bounds"
-  llvm::Value* in_bounds = irb_.CreateICmpULT(char_index, string_count);
-  irb_.CreateCondBr(in_bounds, block_cont, block_retry, kLikely);
-
-  irb_.SetInsertPoint(block_cont);
-  llvm::Value* string_offset = irb_.LoadFromObjectOffset(this_object,
-                                                         mirror::String::OffsetOffset().Int32Value(),
-                                                         irb_.getJIntTy(),
-                                                         kTBAAConstJObject);
-  llvm::Value* string_value = irb_.LoadFromObjectOffset(this_object,
-                                                        mirror::String::ValueOffset().Int32Value(),
-                                                        irb_.getJObjectTy(),
-                                                        kTBAAConstJObject);
-
-  // index_value = string.offset + char_index
-  llvm::Value* index_value = irb_.CreateAdd(string_offset, char_index);
-
-  // array_elem_value = string.value[index_value]
-  llvm::Value* array_elem_addr = EmitArrayGEP(string_value, index_value, kChar);
-  llvm::Value* array_elem_value = irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, kChar);
-
-  EmitStoreDalvikRetValReg(kChar, kArray, array_elem_value);
-  irb_.CreateBr(after_invoke);
-
-  irb_.SetInsertPoint(block_retry);
-  return true;
-}
-
-bool MethodCompiler::EmitInlinedStringLength(const std::vector<llvm::Value*>& args,
-                                             llvm::BasicBlock* after_invoke) {
-  DCHECK_EQ(args.size(), 2U) <<
-      "int java.lang.String.length() has 2 args: method, this";
-  llvm::Value* this_object = args[1];
-  llvm::Value* string_count = irb_.LoadFromObjectOffset(this_object,
-                                                        mirror::String::CountOffset().Int32Value(),
-                                                        irb_.getJIntTy(),
-                                                        kTBAAConstJObject);
-  EmitStoreDalvikRetValReg(kInt, kAccurate, string_count);
-  irb_.CreateBr(after_invoke);
-  return false;
-}
-
-bool MethodCompiler::EmitInlinedStringIndexOf(const std::vector<llvm::Value*>& args,
-                                              llvm::BasicBlock* after_invoke,
-                                              bool zero_based) {
-  // TODO: Don't generate target specific bitcode, using intrinsic to delay to codegen.
-  if (compiler_->GetInstructionSet() == kArm || compiler_->GetInstructionSet() == kThumb2) {
-    DCHECK_EQ(args.size(), (zero_based ? 3U : 4U)) <<
-        "int java.lang.String.indexOf(int, int = 0) has 3~4 args: method, this, char, start";
-    llvm::Value* this_object = args[1];
-    llvm::Value* char_target = args[2];
-    llvm::Value* start_index = (zero_based ? irb_.getJInt(0) : args[3]);
-    llvm::BasicBlock* block_retry = llvm::BasicBlock::Create(*context_, "IndexOfRetry", func_);
-    llvm::BasicBlock* block_cont = llvm::BasicBlock::Create(*context_, "IndexOfCont", func_);
-
-    llvm::Value* slowpath = irb_.CreateICmpSGT(char_target, irb_.getJInt(0xFFFF));
-    irb_.CreateCondBr(slowpath, block_retry, block_cont, kUnlikely);
-
-    irb_.SetInsertPoint(block_cont);
-
-    llvm::Type* args_type[] = { irb_.getJObjectTy(), irb_.getJIntTy(), irb_.getJIntTy() };
-    llvm::FunctionType* func_ty = llvm::FunctionType::get(irb_.getJIntTy(), args_type, false);
-    llvm::Value* func =
-        irb_.Runtime().EmitLoadFromThreadOffset(ENTRYPOINT_OFFSET(pIndexOf),
-                                                func_ty->getPointerTo(),
-                                                kTBAAConstJObject);
-    llvm::Value* result = irb_.CreateCall3(func, this_object, char_target, start_index);
-    EmitStoreDalvikRetValReg(kInt, kAccurate, result);
-    irb_.CreateBr(after_invoke);
-
-    irb_.SetInsertPoint(block_retry);
-  }
-  return true;
-}
-
-bool MethodCompiler::EmitInlinedStringCompareTo(const std::vector<llvm::Value*>& args,
-                                                llvm::BasicBlock* after_invoke) {
-  // TODO: Don't generate target specific bitcode, using intrinsic to delay to codegen.
-  if (compiler_->GetInstructionSet() == kArm || compiler_->GetInstructionSet() == kThumb2) {
-    DCHECK_EQ(args.size(), 3U) <<
-        "int java.lang.String.compareTo(java.lang.String) has 3 args: method, this, cmpto";
-    llvm::Value* this_object = args[1];
-    llvm::Value* cmp_object = args[2];
-    llvm::BasicBlock* block_retry = llvm::BasicBlock::Create(*context_, "CompareToRetry", func_);
-    llvm::BasicBlock* block_cont = llvm::BasicBlock::Create(*context_, "CompareToCont", func_);
-
-    llvm::Value* is_null = irb_.CreateICmpEQ(cmp_object, irb_.getJNull());
-    irb_.CreateCondBr(is_null, block_retry, block_cont, kUnlikely);
-
-    irb_.SetInsertPoint(block_cont);
-
-    llvm::Type* args_type[] = { irb_.getJObjectTy(), irb_.getJObjectTy() };
-    llvm::FunctionType* func_ty = llvm::FunctionType::get(irb_.getJIntTy(), args_type, false);
-    llvm::Value* func =
-        irb_.Runtime().EmitLoadFromThreadOffset(ENTRYPOINT_OFFSET(pStringCompareTo),
-                                                func_ty->getPointerTo(),
-                                                kTBAAConstJObject);
-    llvm::Value* result = irb_.CreateCall2(func, this_object, cmp_object);
-    EmitStoreDalvikRetValReg(kInt, kAccurate, result);
-    irb_.CreateBr(after_invoke);
-
-    irb_.SetInsertPoint(block_retry);
-  }
-  return true;
-}
-
-
-bool MethodCompiler::IsInstructionDirectToReturn(uint32_t dex_pc) {
-  for (int i = 0; i < 8; ++i) {  // Trace at most 8 instructions.
-    if (dex_pc >= code_item_->insns_size_in_code_units_) {
-      return false;
-    }
-
-    const Instruction* insn = Instruction::At(code_item_->insns_ + dex_pc);
-
-    if (insn->IsReturn()) {
-      return true;
-    }
-
-    // Is throw, switch, invoke or conditional branch.
-    if (insn->IsThrow() || insn->IsSwitch() || insn->IsInvoke() ||
-        (insn->IsBranch() && !insn->IsUnconditional())) {
-      return false;
-    }
-
-    switch (insn->Opcode()) {
-    default:
-      dex_pc += insn->SizeInCodeUnits();
-      break;
-
-    // This instruction will remove the exception. Consider as a side effect.
-    case Instruction::MOVE_EXCEPTION:
-      return false;
-      break;
-
-    case Instruction::GOTO:
-    case Instruction::GOTO_16:
-    case Instruction::GOTO_32:
-      {
-        DecodedInstruction dec_insn(insn);
-        int32_t branch_offset = dec_insn.vA;
-        dex_pc += branch_offset;
-      }
-      break;
-    }
-  }
-  return false;
-}
-
-
-// TODO: Use high-level IR to do this
-void MethodCompiler::ComputeMethodInfo() {
-  // If this method is static, we set the "this" register index to -1. So we don't worry about this
-  // method is static or not in the following comparison.
-  int64_t this_reg_idx = (oat_compilation_unit_->IsStatic()) ?
-                         (-1) :
-                         (code_item_->registers_size_ - code_item_->ins_size_);
-  bool has_invoke = false;
-  bool may_have_loop = false;
-  bool may_throw_exception = false;
-  bool assume_this_non_null = false;
-  std::vector<bool>& set_to_another_object = method_info_.set_to_another_object;
-  set_to_another_object.resize(code_item_->registers_size_, false);
-
-  const Instruction* insn;
-  for (uint32_t dex_pc = 0;
-       dex_pc < code_item_->insns_size_in_code_units_;
-       dex_pc += insn->SizeInCodeUnits()) {
-    insn = Instruction::At(code_item_->insns_ + dex_pc);
-    DecodedInstruction dec_insn(insn);
-
-    switch (insn->Opcode()) {
-    case Instruction::NOP:
-      break;
-
-    case Instruction::MOVE:
-    case Instruction::MOVE_FROM16:
-    case Instruction::MOVE_16:
-    case Instruction::MOVE_WIDE:
-    case Instruction::MOVE_WIDE_FROM16:
-    case Instruction::MOVE_WIDE_16:
-    case Instruction::MOVE_RESULT:
-    case Instruction::MOVE_RESULT_WIDE:
-      break;
-
-    case Instruction::MOVE_OBJECT:
-    case Instruction::MOVE_OBJECT_FROM16:
-    case Instruction::MOVE_OBJECT_16:
-    case Instruction::MOVE_RESULT_OBJECT:
-    case Instruction::MOVE_EXCEPTION:
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::RETURN_VOID:
-    case Instruction::RETURN:
-    case Instruction::RETURN_WIDE:
-    case Instruction::RETURN_OBJECT:
-      break;
-
-    case Instruction::CONST_4:
-    case Instruction::CONST_16:
-    case Instruction::CONST:
-    case Instruction::CONST_HIGH16:
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::CONST_WIDE_16:
-    case Instruction::CONST_WIDE_32:
-    case Instruction::CONST_WIDE:
-    case Instruction::CONST_WIDE_HIGH16:
-      break;
-
-    case Instruction::CONST_STRING:
-    case Instruction::CONST_STRING_JUMBO:
-      // TODO: Will the ResolveString throw exception?
-      if (!compiler_->CanAssumeStringIsPresentInDexCache(*dex_file_, dec_insn.vB)) {
-        may_throw_exception = true;
-      }
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::CONST_CLASS:
-      may_throw_exception = true;
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::MONITOR_ENTER:
-    case Instruction::MONITOR_EXIT:
-    case Instruction::CHECK_CAST:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::ARRAY_LENGTH:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::INSTANCE_OF:
-    case Instruction::NEW_INSTANCE:
-    case Instruction::NEW_ARRAY:
-      may_throw_exception = true;
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::FILLED_NEW_ARRAY:
-    case Instruction::FILLED_NEW_ARRAY_RANGE:
-    case Instruction::FILL_ARRAY_DATA:
-    case Instruction::THROW:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::GOTO:
-    case Instruction::GOTO_16:
-    case Instruction::GOTO_32:
-      {
-        int32_t branch_offset = dec_insn.vA;
-        if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-          may_have_loop = true;
-        }
-      }
-      break;
-
-    case Instruction::PACKED_SWITCH:
-    case Instruction::SPARSE_SWITCH:
-    case Instruction::CMPL_FLOAT:
-    case Instruction::CMPG_FLOAT:
-    case Instruction::CMPL_DOUBLE:
-    case Instruction::CMPG_DOUBLE:
-    case Instruction::CMP_LONG:
-      break;
-
-    case Instruction::IF_EQ:
-    case Instruction::IF_NE:
-    case Instruction::IF_LT:
-    case Instruction::IF_GE:
-    case Instruction::IF_GT:
-    case Instruction::IF_LE:
-      {
-        int32_t branch_offset = dec_insn.vC;
-        if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-          may_have_loop = true;
-        }
-      }
-      break;
-
-    case Instruction::IF_EQZ:
-    case Instruction::IF_NEZ:
-    case Instruction::IF_LTZ:
-    case Instruction::IF_GEZ:
-    case Instruction::IF_GTZ:
-    case Instruction::IF_LEZ:
-      {
-        int32_t branch_offset = dec_insn.vB;
-        if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-          may_have_loop = true;
-        }
-      }
-      break;
-
-    case Instruction::AGET:
-    case Instruction::AGET_WIDE:
-    case Instruction::AGET_OBJECT:
-    case Instruction::AGET_BOOLEAN:
-    case Instruction::AGET_BYTE:
-    case Instruction::AGET_CHAR:
-    case Instruction::AGET_SHORT:
-      may_throw_exception = true;
-      if (insn->Opcode() == Instruction::AGET_OBJECT) {
-        set_to_another_object[dec_insn.vA] = true;
-      }
-      break;
-
-    case Instruction::APUT:
-    case Instruction::APUT_WIDE:
-    case Instruction::APUT_OBJECT:
-    case Instruction::APUT_BOOLEAN:
-    case Instruction::APUT_BYTE:
-    case Instruction::APUT_CHAR:
-    case Instruction::APUT_SHORT:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::IGET:
-    case Instruction::IGET_WIDE:
-    case Instruction::IGET_OBJECT:
-    case Instruction::IGET_BOOLEAN:
-    case Instruction::IGET_BYTE:
-    case Instruction::IGET_CHAR:
-    case Instruction::IGET_SHORT:
-      {
-        if (insn->Opcode() == Instruction::IGET_OBJECT) {
-          set_to_another_object[dec_insn.vA] = true;
-        }
-        uint32_t reg_idx = dec_insn.vB;
-        uint32_t field_idx = dec_insn.vC;
-        int field_offset;
-        bool is_volatile;
-        bool is_fast_path = compiler_->ComputeInstanceFieldInfo(
-          field_idx, oat_compilation_unit_, field_offset, is_volatile, false);
-        if (!is_fast_path) {
-          may_throw_exception = true;
-        } else {
-          // Fast-path, may throw NullPointerException
-          if (reg_idx == this_reg_idx) {
-            // We assume "this" will not be null at first.
-            assume_this_non_null = true;
-          } else {
-            may_throw_exception = true;
-          }
-        }
-      }
-      break;
-
-    case Instruction::IPUT:
-    case Instruction::IPUT_WIDE:
-    case Instruction::IPUT_OBJECT:
-    case Instruction::IPUT_BOOLEAN:
-    case Instruction::IPUT_BYTE:
-    case Instruction::IPUT_CHAR:
-    case Instruction::IPUT_SHORT:
-      {
-        uint32_t reg_idx = dec_insn.vB;
-        uint32_t field_idx = dec_insn.vC;
-        int field_offset;
-        bool is_volatile;
-        bool is_fast_path = compiler_->ComputeInstanceFieldInfo(
-          field_idx, oat_compilation_unit_, field_offset, is_volatile, true);
-        if (!is_fast_path) {
-          may_throw_exception = true;
-        } else {
-          // Fast-path, may throw NullPointerException
-          if (reg_idx == this_reg_idx) {
-            // We assume "this" will not be null at first.
-            assume_this_non_null = true;
-          } else {
-            may_throw_exception = true;
-          }
-        }
-      }
-      break;
-
-    case Instruction::SGET:
-    case Instruction::SGET_WIDE:
-    case Instruction::SGET_OBJECT:
-    case Instruction::SGET_BOOLEAN:
-    case Instruction::SGET_BYTE:
-    case Instruction::SGET_CHAR:
-    case Instruction::SGET_SHORT:
-      {
-        if (insn->Opcode() == Instruction::SGET_OBJECT) {
-          set_to_another_object[dec_insn.vA] = true;
-        }
-        uint32_t field_idx = dec_insn.vB;
-
-        int field_offset;
-        int ssb_index;
-        bool is_referrers_class;
-        bool is_volatile;
-
-        bool is_fast_path = compiler_->ComputeStaticFieldInfo(
-          field_idx, oat_compilation_unit_, field_offset, ssb_index,
-          is_referrers_class, is_volatile, false);
-        if (!is_fast_path || !is_referrers_class) {
-          may_throw_exception = true;
-        }
-      }
-      break;
-
-    case Instruction::SPUT:
-    case Instruction::SPUT_WIDE:
-    case Instruction::SPUT_OBJECT:
-    case Instruction::SPUT_BOOLEAN:
-    case Instruction::SPUT_BYTE:
-    case Instruction::SPUT_CHAR:
-    case Instruction::SPUT_SHORT:
-      {
-        uint32_t field_idx = dec_insn.vB;
-
-        int field_offset;
-        int ssb_index;
-        bool is_referrers_class;
-        bool is_volatile;
-
-        bool is_fast_path = compiler_->ComputeStaticFieldInfo(
-          field_idx, oat_compilation_unit_, field_offset, ssb_index,
-          is_referrers_class, is_volatile, true);
-        if (!is_fast_path || !is_referrers_class) {
-          may_throw_exception = true;
-        }
-      }
-      break;
-
-
-    case Instruction::INVOKE_VIRTUAL:
-    case Instruction::INVOKE_SUPER:
-    case Instruction::INVOKE_DIRECT:
-    case Instruction::INVOKE_STATIC:
-    case Instruction::INVOKE_INTERFACE:
-    case Instruction::INVOKE_VIRTUAL_RANGE:
-    case Instruction::INVOKE_SUPER_RANGE:
-    case Instruction::INVOKE_DIRECT_RANGE:
-    case Instruction::INVOKE_STATIC_RANGE:
-    case Instruction::INVOKE_INTERFACE_RANGE:
-      has_invoke = true;
-      may_throw_exception = true;
-      break;
-
-    case Instruction::NEG_INT:
-    case Instruction::NOT_INT:
-    case Instruction::NEG_LONG:
-    case Instruction::NOT_LONG:
-    case Instruction::NEG_FLOAT:
-    case Instruction::NEG_DOUBLE:
-    case Instruction::INT_TO_LONG:
-    case Instruction::INT_TO_FLOAT:
-    case Instruction::INT_TO_DOUBLE:
-    case Instruction::LONG_TO_INT:
-    case Instruction::LONG_TO_FLOAT:
-    case Instruction::LONG_TO_DOUBLE:
-    case Instruction::FLOAT_TO_INT:
-    case Instruction::FLOAT_TO_LONG:
-    case Instruction::FLOAT_TO_DOUBLE:
-    case Instruction::DOUBLE_TO_INT:
-    case Instruction::DOUBLE_TO_LONG:
-    case Instruction::DOUBLE_TO_FLOAT:
-    case Instruction::INT_TO_BYTE:
-    case Instruction::INT_TO_CHAR:
-    case Instruction::INT_TO_SHORT:
-    case Instruction::ADD_INT:
-    case Instruction::SUB_INT:
-    case Instruction::MUL_INT:
-    case Instruction::AND_INT:
-    case Instruction::OR_INT:
-    case Instruction::XOR_INT:
-    case Instruction::SHL_INT:
-    case Instruction::SHR_INT:
-    case Instruction::USHR_INT:
-    case Instruction::ADD_LONG:
-    case Instruction::SUB_LONG:
-    case Instruction::MUL_LONG:
-    case Instruction::AND_LONG:
-    case Instruction::OR_LONG:
-    case Instruction::XOR_LONG:
-    case Instruction::SHL_LONG:
-    case Instruction::SHR_LONG:
-    case Instruction::USHR_LONG:
-    case Instruction::ADD_INT_2ADDR:
-    case Instruction::SUB_INT_2ADDR:
-    case Instruction::MUL_INT_2ADDR:
-    case Instruction::AND_INT_2ADDR:
-    case Instruction::OR_INT_2ADDR:
-    case Instruction::XOR_INT_2ADDR:
-    case Instruction::SHL_INT_2ADDR:
-    case Instruction::SHR_INT_2ADDR:
-    case Instruction::USHR_INT_2ADDR:
-    case Instruction::ADD_LONG_2ADDR:
-    case Instruction::SUB_LONG_2ADDR:
-    case Instruction::MUL_LONG_2ADDR:
-    case Instruction::AND_LONG_2ADDR:
-    case Instruction::OR_LONG_2ADDR:
-    case Instruction::XOR_LONG_2ADDR:
-    case Instruction::SHL_LONG_2ADDR:
-    case Instruction::SHR_LONG_2ADDR:
-    case Instruction::USHR_LONG_2ADDR:
-      break;
-
-    case Instruction::DIV_INT:
-    case Instruction::REM_INT:
-    case Instruction::DIV_LONG:
-    case Instruction::REM_LONG:
-    case Instruction::DIV_INT_2ADDR:
-    case Instruction::REM_INT_2ADDR:
-    case Instruction::DIV_LONG_2ADDR:
-    case Instruction::REM_LONG_2ADDR:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::ADD_FLOAT:
-    case Instruction::SUB_FLOAT:
-    case Instruction::MUL_FLOAT:
-    case Instruction::DIV_FLOAT:
-    case Instruction::REM_FLOAT:
-    case Instruction::ADD_DOUBLE:
-    case Instruction::SUB_DOUBLE:
-    case Instruction::MUL_DOUBLE:
-    case Instruction::DIV_DOUBLE:
-    case Instruction::REM_DOUBLE:
-    case Instruction::ADD_FLOAT_2ADDR:
-    case Instruction::SUB_FLOAT_2ADDR:
-    case Instruction::MUL_FLOAT_2ADDR:
-    case Instruction::DIV_FLOAT_2ADDR:
-    case Instruction::REM_FLOAT_2ADDR:
-    case Instruction::ADD_DOUBLE_2ADDR:
-    case Instruction::SUB_DOUBLE_2ADDR:
-    case Instruction::MUL_DOUBLE_2ADDR:
-    case Instruction::DIV_DOUBLE_2ADDR:
-    case Instruction::REM_DOUBLE_2ADDR:
-      break;
-
-    case Instruction::ADD_INT_LIT16:
-    case Instruction::ADD_INT_LIT8:
-    case Instruction::RSUB_INT:
-    case Instruction::RSUB_INT_LIT8:
-    case Instruction::MUL_INT_LIT16:
-    case Instruction::MUL_INT_LIT8:
-    case Instruction::AND_INT_LIT16:
-    case Instruction::AND_INT_LIT8:
-    case Instruction::OR_INT_LIT16:
-    case Instruction::OR_INT_LIT8:
-    case Instruction::XOR_INT_LIT16:
-    case Instruction::XOR_INT_LIT8:
-    case Instruction::SHL_INT_LIT8:
-    case Instruction::SHR_INT_LIT8:
-    case Instruction::USHR_INT_LIT8:
-      break;
-
-    case Instruction::DIV_INT_LIT16:
-    case Instruction::DIV_INT_LIT8:
-    case Instruction::REM_INT_LIT16:
-    case Instruction::REM_INT_LIT8:
-      if (dec_insn.vC == 0) {
-        may_throw_exception = true;
-      }
-      break;
-
-    case Instruction::UNUSED_3E:
-    case Instruction::UNUSED_3F:
-    case Instruction::UNUSED_40:
-    case Instruction::UNUSED_41:
-    case Instruction::UNUSED_42:
-    case Instruction::UNUSED_43:
-    case Instruction::UNUSED_73:
-    case Instruction::UNUSED_79:
-    case Instruction::UNUSED_7A:
-    case Instruction::UNUSED_E3:
-    case Instruction::UNUSED_E4:
-    case Instruction::UNUSED_E5:
-    case Instruction::UNUSED_E6:
-    case Instruction::UNUSED_E7:
-    case Instruction::UNUSED_E8:
-    case Instruction::UNUSED_E9:
-    case Instruction::UNUSED_EA:
-    case Instruction::UNUSED_EB:
-    case Instruction::UNUSED_EC:
-    case Instruction::UNUSED_ED:
-    case Instruction::UNUSED_EE:
-    case Instruction::UNUSED_EF:
-    case Instruction::UNUSED_F0:
-    case Instruction::UNUSED_F1:
-    case Instruction::UNUSED_F2:
-    case Instruction::UNUSED_F3:
-    case Instruction::UNUSED_F4:
-    case Instruction::UNUSED_F5:
-    case Instruction::UNUSED_F6:
-    case Instruction::UNUSED_F7:
-    case Instruction::UNUSED_F8:
-    case Instruction::UNUSED_F9:
-    case Instruction::UNUSED_FA:
-    case Instruction::UNUSED_FB:
-    case Instruction::UNUSED_FC:
-    case Instruction::UNUSED_FD:
-    case Instruction::UNUSED_FE:
-    case Instruction::UNUSED_FF:
-      LOG(FATAL) << "Dex file contains UNUSED bytecode: " << insn->Opcode();
-      break;
-    }
-  }
-
-  method_info_.this_reg_idx = this_reg_idx;
-  // According to the statistics, there are few methods that modify the "this" pointer. So this is a
-  // simple way to avoid data flow analysis. After we have a high-level IR before IRBuilder, we
-  // should remove this trick.
-  method_info_.this_will_not_be_null =
-      (oat_compilation_unit_->IsStatic()) ? (true) : (!set_to_another_object[this_reg_idx]);
-  method_info_.has_invoke = has_invoke;
-  // If this method has loop or invoke instruction, it may suspend. Thus we need a shadow frame entry
-  // for GC.
-  method_info_.need_shadow_frame_entry = has_invoke || may_have_loop;
-  // If this method may throw an exception, we need a shadow frame for stack trace (dexpc).
-  method_info_.need_shadow_frame = method_info_.need_shadow_frame_entry || may_throw_exception ||
-                                   (assume_this_non_null && !method_info_.this_will_not_be_null);
-  // If can only throw exception, but can't suspend check (no loop, no invoke),
-  // then there is no shadow frame entry. Only Shadow frame is needed.
-  method_info_.lazy_push_shadow_frame =
-      method_info_.need_shadow_frame && !method_info_.need_shadow_frame_entry;
-}
-
-
-
-} // namespace compiler_llvm
-} // namespace art
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
deleted file mode 100644
index 4d759e5..0000000
--- a/src/compiler_llvm/method_compiler.h
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_
-#define ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_
-
-#include "backend_types.h"
-#include "dex_file.h"
-#include "dex_instruction.h"
-#include "greenland/backend_types.h"
-#include "invoke_type.h"
-#include "object_utils.h"
-#include "runtime_support_func.h"
-
-#include <llvm/Support/IRBuilder.h>
-
-#include <vector>
-
-#include <stdint.h>
-
-
-namespace art {
-  class ClassLinker;
-  class CompiledMethod;
-  class Compiler;
-  class OatCompilationUnit;
-
-  namespace mirror {
-    class ClassLoader;
-    class DexCache;
-    class Field;
-  }  // namespace mirror
-
-  namespace greenland {
-    class InferredRegCategoryMap;
-  }  // namespace greenland
-}  // namespace art
-
-
-namespace llvm {
-  class AllocaInst;
-  class BasicBlock;
-  class Function;
-  class FunctionType;
-  class LLVMContext;
-  class Module;
-  class Type;
-}  // namespace llvm
-
-
-namespace art {
-namespace compiler_llvm {
-
-class LlvmCompilationUnit;
-class CompilerLLVM;
-class DalvikReg;
-class IRBuilder;
-
-class MethodCompiler {
- public:
-  MethodCompiler(LlvmCompilationUnit* cunit,
-                 Compiler* compiler,
-                 OatCompilationUnit* oat_compilation_unit);
-
-  ~MethodCompiler();
-
-  CompiledMethod* Compile();
-
-
-  // Code generation helper function
-
-  IRBuilder& GetIRBuilder() const {
-    return irb_;
-  }
-
-
-  // Register helper function
-
-  llvm::Value* AllocDalvikReg(RegCategory cat, const std::string& name);
-
-  llvm::Value* GetShadowFrameEntry(uint32_t reg_idx);
-
-  llvm::Value* GetVRegEntry(uint32_t reg_idx);
-
-
- private:
-  void CreateFunction();
-  void EmitPrologue();
-  void EmitStackOverflowCheck();
-  void EmitPrologueLastBranch();
-  void EmitPrologueAllocShadowFrame();
-  void EmitPrologueAssignArgRegister();
-  void EmitInstructions();
-  void EmitInstruction(uint32_t dex_pc, const Instruction* insn);
-
-  enum CondBranchKind {
-    kCondBranch_EQ,
-    kCondBranch_NE,
-    kCondBranch_LT,
-    kCondBranch_GE,
-    kCondBranch_GT,
-    kCondBranch_LE,
-  };
-
-  enum IntArithmKind {
-    kIntArithm_Add,
-    kIntArithm_Sub,
-    kIntArithm_Mul,
-    kIntArithm_Div,
-    kIntArithm_Rem,
-    kIntArithm_And,
-    kIntArithm_Or,
-    kIntArithm_Xor,
-  };
-
-  enum IntShiftArithmKind {
-    kIntArithm_Shl,
-    kIntArithm_Shr,
-    kIntArithm_UShr,
-  };
-
-  enum FPArithmKind {
-    kFPArithm_Add,
-    kFPArithm_Sub,
-    kFPArithm_Mul,
-    kFPArithm_Div,
-    kFPArithm_Rem,
-  };
-
-  enum InvokeArgFmt {
-    kArgReg,
-    kArgRange,
-  };
-
-#define GEN_INSN_ARGS uint32_t dex_pc, const Instruction* insn
-
-  // NOP, PAYLOAD (unreachable) instructions
-  void EmitInsn_Nop(GEN_INSN_ARGS);
-
-  // MOVE, MOVE_RESULT instructions
-  void EmitInsn_Move(GEN_INSN_ARGS, JType jty);
-  void EmitInsn_MoveResult(GEN_INSN_ARGS, JType jty);
-
-  // MOVE_EXCEPTION, THROW instructions
-  void EmitInsn_MoveException(GEN_INSN_ARGS);
-  void EmitInsn_ThrowException(GEN_INSN_ARGS);
-
-  // RETURN instructions
-  void EmitInsn_ReturnVoid(GEN_INSN_ARGS);
-  void EmitInsn_Return(GEN_INSN_ARGS);
-
-  // CONST, CONST_CLASS, CONST_STRING instructions
-  void EmitInsn_LoadConstant(GEN_INSN_ARGS, JType imm_jty);
-  void EmitInsn_LoadConstantString(GEN_INSN_ARGS);
-  void EmitInsn_LoadConstantClass(GEN_INSN_ARGS);
-
-  // MONITOR_ENTER, MONITOR_EXIT instructions
-  void EmitInsn_MonitorEnter(GEN_INSN_ARGS);
-  void EmitInsn_MonitorExit(GEN_INSN_ARGS);
-
-  // CHECK_CAST, INSTANCE_OF instructions
-  void EmitInsn_CheckCast(GEN_INSN_ARGS);
-  void EmitInsn_InstanceOf(GEN_INSN_ARGS);
-
-  // NEW_INSTANCE instructions
-  void EmitInsn_NewInstance(GEN_INSN_ARGS);
-
-  // ARRAY_LEN, NEW_ARRAY, FILLED_NEW_ARRAY, FILL_ARRAY_DATA instructions
-  void EmitInsn_ArrayLength(GEN_INSN_ARGS);
-  void EmitInsn_NewArray(GEN_INSN_ARGS);
-  void EmitInsn_FilledNewArray(GEN_INSN_ARGS, bool is_range);
-  void EmitInsn_FillArrayData(GEN_INSN_ARGS);
-
-  // GOTO, IF_TEST, IF_TESTZ instructions
-  void EmitInsn_UnconditionalBranch(GEN_INSN_ARGS);
-  void EmitInsn_BinaryConditionalBranch(GEN_INSN_ARGS, CondBranchKind cond);
-  void EmitInsn_UnaryConditionalBranch(GEN_INSN_ARGS, CondBranchKind cond);
-
-  // PACKED_SWITCH, SPARSE_SWITCH instrutions
-  void EmitInsn_PackedSwitch(GEN_INSN_ARGS);
-  void EmitInsn_SparseSwitch(GEN_INSN_ARGS);
-
-  // CMPX_FLOAT, CMPX_DOUBLE, CMP_LONG instructions
-  void EmitInsn_FPCompare(GEN_INSN_ARGS, JType fp_jty, bool gt_bias);
-  void EmitInsn_LongCompare(GEN_INSN_ARGS);
-
-  // AGET, APUT instrutions
-  void EmitInsn_AGet(GEN_INSN_ARGS, JType elem_jty);
-  void EmitInsn_APut(GEN_INSN_ARGS, JType elem_jty);
-
-  // IGET, IPUT instructions
-  void EmitInsn_IGet(GEN_INSN_ARGS, JType field_jty);
-  void EmitInsn_IPut(GEN_INSN_ARGS, JType field_jty);
-
-  // SGET, SPUT instructions
-  void EmitInsn_SGet(GEN_INSN_ARGS, JType field_jty);
-  void EmitInsn_SPut(GEN_INSN_ARGS, JType field_jty);
-
-  // INVOKE instructions
-  void EmitInsn_Invoke(GEN_INSN_ARGS,
-                       InvokeType invoke_type,
-                       InvokeArgFmt arg_fmt);
-
-  llvm::Value* EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx);
-
-  llvm::Value* EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx,
-                                                     llvm::Value* this_addr);
-
-  llvm::Value* EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
-                                                        InvokeType invoke_type,
-                                                        llvm::Value* this_addr,
-                                                        uint32_t dex_pc,
-                                                        bool is_fast_path);
-
-  // Unary instructions
-  void EmitInsn_Neg(GEN_INSN_ARGS, JType op_jty);
-  void EmitInsn_Not(GEN_INSN_ARGS, JType op_jty);
-  void EmitInsn_SExt(GEN_INSN_ARGS);
-  void EmitInsn_Trunc(GEN_INSN_ARGS);
-  void EmitInsn_TruncAndSExt(GEN_INSN_ARGS, unsigned N);
-  void EmitInsn_TruncAndZExt(GEN_INSN_ARGS, unsigned N);
-
-  void EmitInsn_FNeg(GEN_INSN_ARGS, JType op_jty);
-  void EmitInsn_IntToFP(GEN_INSN_ARGS, JType src_jty, JType dest_jty);
-  void EmitInsn_FPToInt(GEN_INSN_ARGS, JType src_jty, JType dest_jty,
-                        runtime_support::RuntimeId runtime_func_id);
-  void EmitInsn_FExt(GEN_INSN_ARGS);
-  void EmitInsn_FTrunc(GEN_INSN_ARGS);
-
-  // Integer binary arithmetic instructions
-  void EmitInsn_IntArithm(GEN_INSN_ARGS, IntArithmKind arithm,
-                          JType op_jty, bool is_2addr);
-
-  void EmitInsn_IntArithmImmediate(GEN_INSN_ARGS, IntArithmKind arithm);
-
-  void EmitInsn_IntShiftArithm(GEN_INSN_ARGS, IntShiftArithmKind arithm,
-                               JType op_jty, bool is_2addr);
-
-  void EmitInsn_IntShiftArithmImmediate(GEN_INSN_ARGS,
-                                        IntShiftArithmKind arithm);
-
-  void EmitInsn_RSubImmediate(GEN_INSN_ARGS);
-
-
-  // Floating-point binary arithmetic instructions
-  void EmitInsn_FPArithm(GEN_INSN_ARGS, FPArithmKind arithm,
-                         JType op_jty, bool is_2addr);
-
-#undef GEN_INSN_ARGS
-
-  // GC card table helper function
-  void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr);
-
-  // Shadow frame helper function
-  void EmitPushShadowFrame(bool is_inline);
-  void EmitPopShadowFrame();
-  void EmitUpdateDexPC(uint32_t dex_pc);
-
-
-  // Dex cache code generation helper function
-  llvm::Value* EmitLoadDexCacheAddr(MemberOffset dex_cache_offset);
-
-  llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx);
-
-  llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx);
-
-  llvm::Value* EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx);
-
-  llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx);
-
-
-  // Code generation helper function
-
-  llvm::Value* EmitLoadMethodObjectAddr();
-
-  llvm::FunctionType* GetFunctionType(uint32_t method_idx, bool is_static);
-
-  void EmitGuard_ExceptionLandingPad(uint32_t dex_pc, bool can_skip_unwind);
-
-  void EmitBranchExceptionLandingPad(uint32_t dex_pc);
-
-  void EmitGuard_GarbageCollectionSuspend(uint32_t dex_pc);
-
-  llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq,
-                                          llvm::Value* cmp_lt);
-
-  llvm::Value* EmitConditionResult(llvm::Value* lhs,
-                                   llvm::Value* rhs,
-                                   CondBranchKind cond);
-
-  llvm::Value* EmitIntArithmResultComputation(uint32_t dex_pc,
-                                              llvm::Value* lhs,
-                                              llvm::Value* rhs,
-                                              IntArithmKind arithm,
-                                              JType op_jty);
-
-  llvm::Value* EmitIntDivRemResultComputation(uint32_t dex_pc,
-                                              llvm::Value* dividend,
-                                              llvm::Value* divisor,
-                                              IntArithmKind arithm,
-                                              JType op_jty);
-
-  llvm::Value* EmitIntShiftArithmResultComputation(uint32_t dex_pc,
-                                                   llvm::Value* lhs,
-                                                   llvm::Value* rhs,
-                                                   IntShiftArithmKind arithm,
-                                                   JType op_jty);
-
-  llvm::Value* EmitFPArithmResultComputation(uint32_t dex_pc,
-                                             llvm::Value* lhs,
-                                             llvm::Value* rhs,
-                                             FPArithmKind arithm);
-
-  llvm::Value* EmitAllocNewArray(uint32_t dex_pc,
-                                 int32_t length,
-                                 uint32_t type_idx,
-                                 bool is_filled_new_array);
-
-  llvm::Value* EmitLoadClassObjectAddr(llvm::Value* this_addr);
-
-  llvm::Value* EmitLoadVTableAddr(llvm::Value* class_object_addr);
-
-  llvm::Value* EmitLoadMethodObjectAddrFromVTable(llvm::Value* vtable_addr,
-                                                  uint16_t vtable_index);
-
-  llvm::Value* EmitLoadCodeAddr(llvm::Value* method_object_addr,
-                                uint32_t method_idx,
-                                bool is_static);
-
-  llvm::Value* EmitLoadArrayLength(llvm::Value* array);
-
-  llvm::Value* EmitArrayGEP(llvm::Value* array_addr,
-                            llvm::Value* index_value,
-                            JType elem_jty);
-
-  llvm::Value* EmitLoadConstantClass(uint32_t dex_pc, uint32_t type_idx);
-
-  llvm::Value* EmitLoadStaticStorage(uint32_t dex_pc, uint32_t type_idx);
-
-  void EmitLoadActualParameters(std::vector<llvm::Value*>& args,
-                                uint32_t callee_method_idx,
-                                DecodedInstruction const& di,
-                                InvokeArgFmt arg_fmt,
-                                bool is_static);
-
-  void EmitGuard_DivZeroException(uint32_t dex_pc,
-                                  llvm::Value* denominator,
-                                  JType op_jty);
-
-  void EmitGuard_NullPointerException(uint32_t dex_pc,
-                                      llvm::Value* object);
-
-  void EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
-                                                llvm::Value* array,
-                                                llvm::Value* index);
-
-  void EmitGuard_ArrayException(uint32_t dex_pc,
-                                llvm::Value* array,
-                                llvm::Value* index);
-
-  greenland::RegCategory GetInferredRegCategory(uint32_t dex_pc, uint16_t reg);
-
-  const greenland::InferredRegCategoryMap* GetInferredRegCategoryMap();
-
-  bool IsRegCanBeObject(uint16_t reg_idx);
-
-
-  // Basic block helper functions
-  llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc);
-
-  llvm::BasicBlock* GetNextBasicBlock(uint32_t dex_pc);
-
-  llvm::BasicBlock* CreateBasicBlockWithDexPC(uint32_t dex_pc,
-                                              const char* postfix = NULL);
-
-  int32_t GetTryItemOffset(uint32_t dex_pc);
-
-  llvm::BasicBlock* GetLandingPadBasicBlock(uint32_t dex_pc);
-
-  llvm::BasicBlock* GetUnwindBasicBlock();
-
-
-  // Register helper function
-
-  llvm::Value* EmitLoadDalvikReg(uint32_t reg_idx, JType jty, JTypeSpace space);
-
-  llvm::Value* EmitLoadDalvikReg(uint32_t reg_idx, char shorty, JTypeSpace space);
-
-  void EmitStoreDalvikReg(uint32_t reg_idx, JType jty,
-                          JTypeSpace space, llvm::Value* new_value);
-
-  void EmitStoreDalvikReg(uint32_t reg_idx, char shorty,
-                          JTypeSpace space, llvm::Value* new_value);
-
-  llvm::Value* EmitLoadDalvikRetValReg(JType jty, JTypeSpace space);
-
-  llvm::Value* EmitLoadDalvikRetValReg(char shorty, JTypeSpace space);
-
-  void EmitStoreDalvikRetValReg(JType jty, JTypeSpace space, llvm::Value* new_value);
-
-  void EmitStoreDalvikRetValReg(char shorty, JTypeSpace space, llvm::Value* new_value);
-
-  // TODO: Use high-level IR to do this
-  bool EmitInlineJavaIntrinsic(const std::string& callee_method_name,
-                               const std::vector<llvm::Value*>& args,
-                               llvm::BasicBlock* after_invoke);
-
-  bool EmitInlinedStringCharAt(const std::vector<llvm::Value*>& args,
-                               llvm::BasicBlock* after_invoke);
-
-  bool EmitInlinedStringLength(const std::vector<llvm::Value*>& args,
-                               llvm::BasicBlock* after_invoke);
-
-  bool EmitInlinedStringIndexOf(const std::vector<llvm::Value*>& args,
-                                llvm::BasicBlock* after_invoke,
-                                bool zero_based);
-
-  bool EmitInlinedStringCompareTo(const std::vector<llvm::Value*>& args,
-                                  llvm::BasicBlock* after_invoke);
-
-  bool IsInstructionDirectToReturn(uint32_t dex_pc);
-
-  struct MethodInfo {
-    int64_t this_reg_idx;
-    bool this_will_not_be_null;
-    bool has_invoke;
-    bool need_shadow_frame_entry;
-    bool need_shadow_frame;
-    bool lazy_push_shadow_frame;
-    std::vector<bool> set_to_another_object;
-  };
-  MethodInfo method_info_;
-
-  void ComputeMethodInfo();
-
- private:
-  LlvmCompilationUnit* cunit_;
-  Compiler* compiler_;
-
-  const DexFile* dex_file_;
-  const DexFile::CodeItem* code_item_;
-
-  OatCompilationUnit* oat_compilation_unit_;
-
-  uint32_t method_idx_;
-  uint32_t access_flags_;
-
-  llvm::Module* module_;
-  llvm::LLVMContext* context_;
-  IRBuilder& irb_;
-  llvm::Function* func_;
-
-  std::vector<DalvikReg*> regs_;
-  std::vector<llvm::Value*> vregs_;
-  UniquePtr<DalvikReg> retval_reg_;
-
-  llvm::BasicBlock* basic_block_alloca_;
-  llvm::BasicBlock* basic_block_shadow_frame_;
-  llvm::BasicBlock* basic_block_reg_arg_init_;
-  std::vector<llvm::BasicBlock*> basic_blocks_;
-
-  std::vector<llvm::BasicBlock*> basic_block_landing_pads_;
-  llvm::BasicBlock* basic_block_unwind_;
-
-  llvm::AllocaInst* shadow_frame_;
-  llvm::Value* old_shadow_frame_;
-
-  llvm::Value* already_pushed_shadow_frame_;
-  uint16_t num_shadow_frame_refs_;
-
-  uint16_t elf_func_idx_;
-};
-
-
-} // namespace compiler_llvm
-} // namespace art
-
-#endif // ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_
diff --git a/src/compiler_llvm/stub_compiler.cc b/src/compiler_llvm/stub_compiler.cc
index e6bee7b..77f5d8e 100644
--- a/src/compiler_llvm/stub_compiler.cc
+++ b/src/compiler_llvm/stub_compiler.cc
@@ -151,7 +151,6 @@
   llvm::Value* code_addr = irb_.CreateLoad(code_field_addr, kTBAARuntimeInfo);
 
   llvm::CallInst* retval = irb_.CreateCall(code_addr, args);
-#if defined(ART_USE_PORTABLE_COMPILER)
   for (size_t i = 1; i < shorty_size; ++i) {
     switch(shorty[i]) {
       case 'Z':
@@ -167,7 +166,6 @@
       default: break;
     }
   }
-#endif
 
   // Store the returned value
   if (shorty[0] != 'V') {
@@ -216,7 +214,6 @@
   llvm::Function* func =
     llvm::Function::Create(accurate_func_type, llvm::Function::ExternalLinkage,
                            func_name, module_);
-#if defined(ART_USE_PORTABLE_COMPILER)
   switch(shorty[0]) {
     case 'Z':
     case 'C':
@@ -230,7 +227,6 @@
 
     default: break;
   }
-#endif
 
   // Create basic block for the body of this function
   llvm::BasicBlock* block_body =
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index d00af79..703a5a1 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -249,7 +249,7 @@
                                               dump_stats,
                                               dump_timings));
 
-    if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
+    if (compiler_backend_ == kPortable) {
       compiler->SetBitcodeFileName(bitcode_filename);
     }
 
@@ -603,7 +603,7 @@
   }
 
   static const unsigned int kWatchDogWarningSeconds = 1 * 60;  // 1 minute.
-#ifdef ART_USE_LLVM_COMPILER
+#ifdef ART_USE_PORTABLE_COMPILER
   static const unsigned int kWatchDogTimeoutSeconds = 30 * 60;  // 25 minutes + buffer.
 #else
   static const unsigned int kWatchDogTimeoutSeconds = 3 * 60;  // 2 minutes + buffer.
@@ -647,8 +647,6 @@
   bool support_debugging = false;
 #if defined(ART_USE_PORTABLE_COMPILER)
   CompilerBackend compiler_backend = kPortable;
-#elif defined(ART_USE_LLVM_COMPILER)
-  CompilerBackend compiler_backend = kIceland;
 #else
   CompilerBackend compiler_backend = kQuick;
 #endif
@@ -734,9 +732,6 @@
         compiler_backend = kQuick;
       } else if (backend_str == "QuickGBC") {
         compiler_backend = kQuickGBC;
-      } else if (backend_str == "Iceland") {
-        // TODO: remove this when Portable/Iceland merge complete
-        compiler_backend = kIceland;
       } else if (backend_str == "Portable") {
         compiler_backend = kPortable;
       }
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 240bf95..1d32f1b 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -145,7 +145,7 @@
   ASSERT_EQ(kStackAlignment, 16);
   ASSERT_EQ(sizeof(uintptr_t), sizeof(uint32_t));
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // Create two fake stack frames with mapping data created in SetUp. We map offset 3 in the code
   // to dex pc 3.
   const uint32_t dex_pc = 3;
@@ -213,7 +213,7 @@
   EXPECT_STREQ("f", trace_array->Get(1)->GetMethodName()->ToModifiedUtf8().c_str());
   EXPECT_EQ(22, trace_array->Get(1)->GetLineNumber());
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   thread->SetTopOfStack(NULL, 0); // Disarm the assertion that no code is running when we detach.
 #else
   thread->PopShadowFrame();
diff --git a/src/greenland/inferred_reg_category_map.cc b/src/greenland/inferred_reg_category_map.cc
deleted file mode 100644
index b4ce12c..0000000
--- a/src/greenland/inferred_reg_category_map.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include "inferred_reg_category_map.h"
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/stl_util.h"
-
-namespace art {
-namespace greenland {
-
-
-InferredRegCategoryMap::InferredRegCategoryMap(uint32_t insns_size,
-                                               uint16_t regs_size)
-: registers_size_(regs_size) {
-}
-
-InferredRegCategoryMap::~InferredRegCategoryMap() {
-  STLDeleteValues(&lines_);
-}
-
-RegCategory InferredRegCategoryMap::GetRegCategory(uint32_t dex_pc,
-                                                   uint16_t reg_idx) const {
-  if (lines_.count(dex_pc) == 0) {
-    return kRegUnknown;
-  }
-  return lines_.Get(dex_pc)->GetRegCategory(reg_idx);
-}
-
-void InferredRegCategoryMap::SetRegCategory(uint32_t dex_pc,
-                                            uint16_t reg_idx,
-                                            RegCategory cat) {
-  if (cat != kRegUnknown) {
-    if (lines_.count(dex_pc) == 0) {
-      lines_.Put(dex_pc, new RegCategoryLine(registers_size_));
-    }
-
-    lines_.Get(dex_pc)->SetRegCategory(reg_idx, cat);
-  }
-}
-
-bool InferredRegCategoryMap::
-operator==(InferredRegCategoryMap const& rhs) const {
-
-  if (registers_size_ != rhs.registers_size_) {
-    return false;
-  }
-
-  if (lines_.size() != rhs.lines_.size()) {
-    return false;
-  }
-
-  for (size_t i = 0; i < lines_.size(); ++i) {
-    if (lines_.count(i) == 0 && rhs.lines_.count(i) == 0) {
-      continue;
-    }
-
-    if ((lines_.count(i) == 0 && rhs.lines_.count(i) != 0) ||
-        (lines_.count(i) != 0 && rhs.lines_.count(i) == 0)) {
-      return false;
-    }
-
-    if (*lines_.Get(i) != *rhs.lines_.Get(i)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool InferredRegCategoryMap::
-operator!=(InferredRegCategoryMap const& rhs) const {
-
-  return !(*this == rhs);
-}
-
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/inferred_reg_category_map.h b/src/greenland/inferred_reg_category_map.h
deleted file mode 100644
index b354097..0000000
--- a/src/greenland/inferred_reg_category_map.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ART_SRC_GREENLAND_INFERRED_REG_CATEGORY_MAP_H_
-#define ART_SRC_GREENLAND_INFERRED_REG_CATEGORY_MAP_H_
-
-#include "backend_types.h"
-
-#include <stdint.h>
-#include <vector>
-
-#include "safe_map.h"
-
-namespace art {
-namespace greenland {
-
-
-class InferredRegCategoryMap {
- private:
-  class RegCategoryLine {
-   private:
-    typedef std::vector<uint8_t> Table;
-    Table reg_category_line_;
-
-   public:
-    RegCategoryLine(size_t num_regs) : reg_category_line_(num_regs, kRegUnknown) {}
-    RegCategory GetRegCategory(uint16_t reg_idx) const {
-      DCHECK_LT(reg_idx, reg_category_line_.size());
-      return static_cast<RegCategory>(reg_category_line_[reg_idx]);
-    }
-
-    void SetRegCategory(uint16_t reg_idx, RegCategory cat) {
-      DCHECK_LT(reg_idx, reg_category_line_.size());
-      reg_category_line_[reg_idx] = cat;
-    }
-
-    bool operator==(RegCategoryLine const& rhs) const {
-      return reg_category_line_ == rhs.reg_category_line_;
-    }
-    bool operator!=(RegCategoryLine const& rhs) const {
-      return reg_category_line_ != rhs.reg_category_line_;
-    }
-  };
-
- public:
-  InferredRegCategoryMap(uint32_t insns_size_in_code_units, uint16_t regs_size);
-
-  ~InferredRegCategoryMap();
-
-  RegCategory GetRegCategory(uint32_t dex_pc, uint16_t reg_idx) const;
-  void SetRegCategory(uint32_t dex_pc, uint16_t reg_idx, RegCategory cat);
-
-  bool operator==(InferredRegCategoryMap const& rhs) const;
-  bool operator!=(InferredRegCategoryMap const& rhs) const;
-
- private:
-  uint16_t registers_size_;
-
-  SafeMap<uint32_t, RegCategoryLine*> lines_;
-
-  DISALLOW_COPY_AND_ASSIGN(InferredRegCategoryMap);
-};
-
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_INFERRED_REG_CATEGORY_MAP_H_
diff --git a/src/instrumentation.cc b/src/instrumentation.cc
index e3d4d28..33f2495 100644
--- a/src/instrumentation.cc
+++ b/src/instrumentation.cc
@@ -25,7 +25,7 @@
 #include "mirror/dex_cache.h"
 #include "mirror/abstract_method-inl.h"
 #include "mirror/object_array-inl.h"
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 #include "oat/runtime/oat_support_entrypoints.h"
 #endif
 #include "object_utils.h"
@@ -193,7 +193,7 @@
 }
 
 void Instrumentation::SaveAndUpdateCode(mirror::AbstractMethod* method) {
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   UNUSED(method);
   UNIMPLEMENTED(FATAL);
 #else
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index a945ba6..801e7c9 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -1175,7 +1175,7 @@
   } while (false)
 
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) {
   Thread::Current()->TransitionFromSuspendedToRunnable();
   LoadDex("AllFields");
diff --git a/src/mirror/abstract_method.cc b/src/mirror/abstract_method.cc
index 84b8809..202fa2f 100644
--- a/src/mirror/abstract_method.cc
+++ b/src/mirror/abstract_method.cc
@@ -189,7 +189,7 @@
 
 // Find the lowest-address native safepoint pc for a given dex pc
 uintptr_t AbstractMethod::ToFirstNativeSafepointPc(const uint32_t dex_pc) const {
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   const uint32_t* mapping_table = GetPcToDexMappingTable();
   if (mapping_table == NULL) {
     DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
@@ -211,7 +211,7 @@
 }
 
 uint32_t AbstractMethod::ToDexPc(const uintptr_t pc) const {
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   const uint32_t* mapping_table = GetPcToDexMappingTable();
   if (mapping_table == NULL) {
     DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
@@ -361,7 +361,7 @@
     // around JNI bugs, that include not giving Object** SIRT references to native methods. Direct
     // the native method to runtime support and store the target somewhere runtime support will
     // find it.
-#if defined(__arm__) && !defined(ART_USE_LLVM_COMPILER)
+#if defined(__arm__) && !defined(ART_USE_PORTABLE_COMPILER)
     SetNativeMethod(native_method);
 #else
     UNIMPLEMENTED(FATAL);
diff --git a/src/native/dalvik_system_VMRuntime.cc b/src/native/dalvik_system_VMRuntime.cc
index 5ce27fb..4c6777a 100644
--- a/src/native/dalvik_system_VMRuntime.cc
+++ b/src/native/dalvik_system_VMRuntime.cc
@@ -122,7 +122,7 @@
   return env->NewStringUTF(Runtime::Current()->GetVersion());
 }
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 static void DisableCheckJniCallback(Thread* t, void*) {
   t->GetJniEnv()->SetCheckJniEnabled(false);
 }
@@ -136,7 +136,7 @@
     Runtime* runtime = Runtime::Current();
     JavaVMExt* vm = runtime->GetJavaVM();
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
     if (vm->check_jni) {
       LOG(WARNING) << "Turning off CheckJNI so we can turn on JNI app bug workarounds...";
       Thread* self = static_cast<JNIEnvExt*>(env)->self;
diff --git a/src/oat.cc b/src/oat.cc
index 79a16cf..145abc6 100644
--- a/src/oat.cc
+++ b/src/oat.cc
@@ -147,7 +147,7 @@
     vmap_table_offset_(0),
     gc_map_offset_(0),
     invoke_stub_offset_(0)
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   , proxy_stub_offset_(0)
 #endif
 {}
@@ -160,7 +160,7 @@
                                    uint32_t vmap_table_offset,
                                    uint32_t gc_map_offset,
                                    uint32_t invoke_stub_offset
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
                                  , uint32_t proxy_stub_offset
 #endif
                                    )
@@ -172,7 +172,7 @@
     vmap_table_offset_(vmap_table_offset),
     gc_map_offset_(gc_map_offset),
     invoke_stub_offset_(invoke_stub_offset)
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   , proxy_stub_offset_(proxy_stub_offset)
 #endif
 {}
diff --git a/src/oat.h b/src/oat.h
index 1d2db6c..b4747d4 100644
--- a/src/oat.h
+++ b/src/oat.h
@@ -80,7 +80,7 @@
                    uint32_t vmap_table_offset,
                    uint32_t gc_map_offset,
                    uint32_t invoke_stub_offset
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
                  , uint32_t proxy_stub_offset
 #endif
                    );
@@ -96,7 +96,7 @@
   uint32_t gc_map_offset_;
   uint32_t invoke_stub_offset_;
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   uint32_t proxy_stub_offset_;
 #endif
 };
diff --git a/src/oat/runtime/arm/stub_arm.cc b/src/oat/runtime/arm/stub_arm.cc
index 90dfffc..9091928 100644
--- a/src/oat/runtime/arm/stub_arm.cc
+++ b/src/oat/runtime/arm/stub_arm.cc
@@ -29,7 +29,7 @@
 
 mirror::ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type) {
   UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // | Out args |
   // | Method*  | <- SP on entry
   // | LR       |    return address into caller
@@ -60,7 +60,7 @@
   __ bx(R12);  // Leaf call to method's code
 
   __ bkpt(0);
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
   RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
   __ PushList(save);
   __ LoadFromOffset(kLoadWord, R12, TR,
@@ -78,7 +78,7 @@
   __ bx(R12, NE);                   // If R12 != 0 tail call method's code
 
   __ bx(LR);                        // Return to caller to handle exception
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
   assembler->EmitSlowPaths();
   size_t cs = assembler->CodeSize();
@@ -95,7 +95,7 @@
 
 mirror::ByteArray* CreateAbstractMethodErrorStub() {
   UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // Save callee saves and ready frame for exception delivery
   RegList save = (1 << R4) | (1 << R5) | (1 << R6) | (1 << R7) | (1 << R8) | (1 << R9) |
                  (1 << R10) | (1 << R11) | (1 << LR);
@@ -116,7 +116,7 @@
   __ mov(PC, ShifterOperand(R12));  // Leaf call to routine that never returns
 
   __ bkpt(0);
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
   // R0 is the Method* already
   __ mov(R1, ShifterOperand(R9));  // Pass Thread::Current() in R1
   // Call to throw AbstractMethodError
@@ -124,7 +124,7 @@
   __ mov(PC, ShifterOperand(R12));  // Leaf call to routine that never returns
 
   __ bkpt(0);
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
   assembler->EmitSlowPaths();
 
diff --git a/src/oat/runtime/mips/stub_mips.cc b/src/oat/runtime/mips/stub_mips.cc
index fda9941..1b5e6cc 100644
--- a/src/oat/runtime/mips/stub_mips.cc
+++ b/src/oat/runtime/mips/stub_mips.cc
@@ -29,7 +29,7 @@
 
 mirror::ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) {
   UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // | Out args   |
   // | Method*    | <- SP on entry
   // | RA         |    return address into caller
@@ -78,7 +78,7 @@
   __ Jr(T9);  // Leaf call to method's code
 
   __ Break();
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
   // Build frame and save argument registers and RA.
   __ AddConstant(SP, SP, -32);
   __ StoreToOffset(kStoreWord, RA, SP, 28);
@@ -107,7 +107,7 @@
   __ Jr(V0); // If V0 != 0 tail call method's code
   __ Bind(&resolve_fail, false);
   __ Jr(RA); // Return to caller to handle exception
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
   assembler->EmitSlowPaths();
 
@@ -125,7 +125,7 @@
 
 mirror::ByteArray* CreateAbstractMethodErrorStub() {
   UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // Save callee saves and ready frame for exception delivery
   __ AddConstant(SP, SP, -64);
   __ StoreToOffset(kStoreWord, RA, SP, 60);
@@ -147,7 +147,7 @@
   __ Jr(T9);  // Leaf call to routine that never returns
 
   __ Break();
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
   // R0 is the Method* already
   __ Move(A1, S1);  // Pass Thread::Current() in A1
   // Call to throw AbstractMethodError
@@ -155,7 +155,7 @@
   __ Jr(T9);  // Leaf call to routine that never returns
 
   __ Break();
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
   assembler->EmitSlowPaths();
 
diff --git a/src/oat/runtime/support_stubs.cc b/src/oat/runtime/support_stubs.cc
index 6565dfe..1807a3d 100644
--- a/src/oat/runtime/support_stubs.cc
+++ b/src/oat/runtime/support_stubs.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 #include "callee_save_frame.h"
 #endif
 #include "class_linker-inl.h"
@@ -24,7 +24,7 @@
 #include "mirror/object.h"
 #include "mirror/object_array-inl.h"
 #include "object_utils.h"
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
 #include "nth_caller_visitor.h"
 #endif
 #include "scoped_thread_state_change.h"
@@ -34,7 +34,7 @@
 
 namespace art {
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 // Lazily resolve a method. Called by stub code.
 const void* UnresolvedDirectMethodTrampolineFromCode(mirror::AbstractMethod* called,
                                                      mirror::AbstractMethod** sp, Thread* thread,
@@ -252,7 +252,7 @@
   }
   return code;
 }
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
 const void* UnresolvedDirectMethodTrampolineFromCode(mirror::AbstractMethod* called,
                                                      mirror::AbstractMethod** called_addr,
                                                      Thread* thread, Runtime::TrampolineType type)
@@ -344,9 +344,9 @@
   }
   return code;
 }
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 // Called by the AbstractMethodError. Called by stub code.
 extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
                                              mirror::AbstractMethod** sp)
@@ -356,13 +356,13 @@
                              "abstract method \"%s\"", PrettyMethod(method).c_str());
   thread->QuickDeliverException();
 }
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
 extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
                                              mirror::AbstractMethod**)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   thread->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;",
                              "abstract method \"%s\"", PrettyMethod(method).c_str());
 }
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
 }  // namespace art
diff --git a/src/oat/runtime/x86/stub_x86.cc b/src/oat/runtime/x86/stub_x86.cc
index 92f3c5f..d314031 100644
--- a/src/oat/runtime/x86/stub_x86.cc
+++ b/src/oat/runtime/x86/stub_x86.cc
@@ -30,7 +30,7 @@
 mirror::ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type) {
   UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
   // return address
   __ pushl(EDI);
@@ -62,7 +62,7 @@
   __ xchgl(EDI, Address(ESP, 0));
   // Tail call to intended method.
   __ ret();
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
   __ pushl(EBP);
   __ movl(EBP, ESP);          // save ESP
   __ subl(ESP, Immediate(8));  // Align stack
@@ -88,7 +88,7 @@
 
   __ Bind(&resolve_fail);
   __ ret();
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
   assembler->EmitSlowPaths();
   size_t cs = assembler->CodeSize();
@@ -106,7 +106,7 @@
 mirror::ByteArray* CreateAbstractMethodErrorStub() {
   UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
 
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kSaveAll)
 
   // return address
@@ -129,7 +129,7 @@
 
   // Call never returns.
   __ int3();
-#else // ART_USE_LLVM_COMPILER
+#else // ART_USE_PORTABLE_COMPILER
   __ pushl(EBP);
   __ movl(EBP, ESP);          // save ESP
   __ subl(ESP, Immediate(12));  // Align stack
@@ -142,7 +142,7 @@
   __ leave();
   // Return to caller who will handle pending exception.
   __ ret();
-#endif // ART_USE_LLVM_COMPILER
+#endif // ART_USE_PORTABLE_COMPILER
 
   assembler->EmitSlowPaths();
 
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 3a81914..5fd95be 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -343,7 +343,7 @@
       oat_method_offsets.vmap_table_offset_,
       oat_method_offsets.gc_map_offset_,
       oat_method_offsets.invoke_stub_offset_
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
     , oat_method_offsets.proxy_stub_offset_
 #endif
       );
@@ -358,7 +358,7 @@
                               const uint32_t vmap_table_offset,
                               const uint32_t gc_map_offset,
                               const uint32_t invoke_stub_offset
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
                             , const uint32_t proxy_stub_offset
 #endif
                               )
@@ -371,7 +371,7 @@
     vmap_table_offset_(vmap_table_offset),
     native_gc_map_offset_(gc_map_offset),
     invoke_stub_offset_(invoke_stub_offset)
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   , proxy_stub_offset_(proxy_stub_offset)
 #endif
 {
@@ -421,7 +421,7 @@
   return reinterpret_cast<uint32_t*>(code)[-1];
 }
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
 const void* OatFile::OatMethod::GetProxyStub() const {
   return GetOatPointer<const void*>(proxy_stub_offset_);
 }
diff --git a/src/oat_file.h b/src/oat_file.h
index bff48fa..8efdf9f 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -114,7 +114,7 @@
     mirror::AbstractMethod::InvokeStub* GetInvokeStub() const;
     uint32_t GetInvokeStubSize() const;
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
     const void* GetProxyStub() const;
 #endif
 
@@ -130,7 +130,7 @@
               const uint32_t vmap_table_offset,
               const uint32_t gc_map_offset,
               const uint32_t invoke_stub_offset
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
             , const uint32_t proxy_stub_offset
 #endif
               );
@@ -155,7 +155,7 @@
     uint32_t native_gc_map_offset_;
     uint32_t invoke_stub_offset_;
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
     uint32_t proxy_stub_offset_;
 #endif
 
diff --git a/src/oat_test.cc b/src/oat_test.cc
index 8da3626..3d1e19b 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -38,7 +38,7 @@
     if (compiled_method == NULL) {
       EXPECT_TRUE(oat_method.GetCode() == NULL) << PrettyMethod(method) << " "
                                                 << oat_method.GetCode();
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
       EXPECT_EQ(oat_method.GetFrameSizeInBytes(), static_cast<uint32_t>(kStackAlignment));
       EXPECT_EQ(oat_method.GetCoreSpillMask(), 0U);
       EXPECT_EQ(oat_method.GetFpSpillMask(), 0U);
@@ -54,7 +54,7 @@
       EXPECT_EQ(0, memcmp(oat_code, &code[0], code_size))
           << PrettyMethod(method) << " " << code_size;
       CHECK_EQ(0, memcmp(oat_code, &code[0], code_size));
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
       EXPECT_EQ(oat_method.GetFrameSizeInBytes(), compiled_method->GetFrameSizeInBytes());
       EXPECT_EQ(oat_method.GetCoreSpillMask(), compiled_method->GetCoreSpillMask());
       EXPECT_EQ(oat_method.GetFpSpillMask(), compiled_method->GetFpSpillMask());
@@ -72,8 +72,6 @@
     // TODO: make selectable
 #if defined(ART_USE_PORTABLE_COMPILER)
     CompilerBackend compiler_backend = kPortable;
-#elif defined(ART_USE_LLVM_COMPILER)
-    CompilerBackend compiler_backend = kIceland; // TODO: remove
 #else
     CompilerBackend compiler_backend = kQuick;
 #endif
@@ -140,7 +138,7 @@
   // If this test is failing and you have to update these constants,
   // it is time to update OatHeader::kOatVersion
   EXPECT_EQ(36U, sizeof(OatHeader));
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   EXPECT_EQ(32U, sizeof(OatMethodOffsets));
 #else
   // ART-LLVM has a extra 4 bytes field: proxy_stub_offset_
diff --git a/src/oat_writer.cc b/src/oat_writer.cc
index 6fcea5d..5e2b30c 100644
--- a/src/oat_writer.cc
+++ b/src/oat_writer.cc
@@ -244,7 +244,7 @@
   uint32_t gc_map_offset = 0;
   // derived from CompiledInvokeStub if available
   uint32_t invoke_stub_offset = 0;
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   uint32_t proxy_stub_offset = 0;
 #endif
 
@@ -358,7 +358,7 @@
     }
   }
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   if (type != kStatic) {
     const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty);
     if (compiled_proxy_stub != NULL) {
@@ -393,7 +393,7 @@
                          vmap_table_offset,
                          gc_map_offset,
                          invoke_stub_offset
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
                        , proxy_stub_offset
 #endif
                          );
@@ -737,7 +737,7 @@
     }
   }
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   if (!is_static) {
     const CompiledInvokeStub* compiled_proxy_stub = compiler_->FindProxyStub(shorty);
     if (compiled_proxy_stub != NULL) {
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 4063d70..c378353 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -1024,9 +1024,7 @@
         DCHECK(method->GetNativeGcMap() == NULL) << PrettyMethod(method);
         DCHECK(method->GetMappingTable() == NULL) << PrettyMethod(method);
       } else {
-#if !defined(ART_USE_LLVM_COMPILER)
         DCHECK(method->GetNativeGcMap() != NULL) << PrettyMethod(method);
-#endif
 
         const DexFile::CodeItem* code_item = MethodHelper(method).GetCodeItem();
         size_t dex_instruction_bytes = code_item->insns_size_in_code_units_ * 2;
diff --git a/src/runtime.cc b/src/runtime.cc
index 07cd4c8..429dc32 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -57,7 +57,7 @@
 #include "verifier/method_verifier.h"
 #include "well_known_classes.h"
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
 #include "compiler_llvm/procedure_linkage_table.h"
 #endif
 
@@ -100,7 +100,7 @@
       use_compile_time_class_path_(false),
       main_thread_group_(NULL),
       system_thread_group_(NULL)
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
 #if defined(__arm__)
     , plt_(kArm)
 #elif defined(__mips__)
@@ -117,7 +117,7 @@
     callee_save_methods_[i] = NULL;
   }
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   CHECK(plt_.AllocateTable()) << "Failed to allocate PLT";
 #endif
 }
diff --git a/src/runtime.h b/src/runtime.h
index 1d71c13..45304d7 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -36,7 +36,7 @@
 #include "runtime_stats.h"
 #include "safe_map.h"
 
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
 #include "compiler_llvm/procedure_linkage_table.h"
 #endif
 
@@ -477,7 +477,7 @@
 
   jobject main_thread_group_;
   jobject system_thread_group_;
-#if defined(ART_USE_LLVM_COMPILER)
+#if defined(ART_USE_PORTABLE_COMPILER)
   compiler_llvm::ProcedureLinkageTable plt_;
 #endif
 
diff --git a/src/thread.cc b/src/thread.cc
index ca97e89..394d263 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -92,7 +92,7 @@
 }
 
 void Thread::SetDebuggerUpdatesEnabled(bool enabled) {
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
   ChangeDebuggerEntryPoint(&entrypoints_, enabled);
 #else
   UNIMPLEMENTED(FATAL);
@@ -1016,9 +1016,9 @@
   delete wait_cond_;
   delete wait_mutex_;
 
-#if !defined(ART_USE_LLVM_COMPILER)
-  delete long_jump_context_;
-#endif
+  if (long_jump_context_ != NULL) {
+    delete long_jump_context_;
+  }
 
   delete debug_invoke_req_;
   delete instrumentation_stack_;
diff --git a/src/trace.cc b/src/trace.cc
index a23d202..09c1d3f 100644
--- a/src/trace.cc
+++ b/src/trace.cc
@@ -25,7 +25,7 @@
 #include "mirror/abstract_method-inl.h"
 #include "mirror/dex_cache.h"
 #include "mirror/object_array-inl.h"
-#if !defined(ART_USE_LLVM_COMPILER)
+#if !defined(ART_USE_PORTABLE_COMPILER)
 #include "oat/runtime/oat_support_entrypoints.h"
 #endif
 #include "object_utils.h"
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 56344cf..46ce441 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -40,11 +40,6 @@
 #include "runtime.h"
 #include "verifier/dex_gc_map.h"
 
-#if defined(ART_USE_LLVM_COMPILER)
-#include "greenland/backend_types.h"
-#include "greenland/inferred_reg_category_map.h"
-#endif
-
 namespace art {
 namespace verifier {
 
@@ -954,12 +949,6 @@
   const std::vector<uint8_t>* dex_gc_map = CreateLengthPrefixedDexGcMap(*(map.get()));
   verifier::MethodVerifier::SetDexGcMap(ref, *dex_gc_map);
 
-#if defined(ART_USE_LLVM_COMPILER)
-  /* Generate Inferred Register Category for LLVM-based Code Generator */
-  const InferredRegCategoryMap* table = GenerateInferredRegCategoryMap();
-  verifier::MethodVerifier::SetInferredRegCategoryMap(ref, *table);
-#endif
-
   return true;
 }
 
@@ -3323,11 +3312,6 @@
 Mutex* MethodVerifier::rejected_classes_lock_ = NULL;
 MethodVerifier::RejectedClassesTable* MethodVerifier::rejected_classes_ = NULL;
 
-#if defined(ART_USE_LLVM_COMPILER)
-Mutex* MethodVerifier::inferred_reg_category_maps_lock_ = NULL;
-MethodVerifier::InferredRegCategoryMapTable* MethodVerifier::inferred_reg_category_maps_ = NULL;
-#endif
-
 void MethodVerifier::Init() {
   dex_gc_maps_lock_ = new Mutex("verifier GC maps lock");
   Thread* self = Thread::Current();
@@ -3341,14 +3325,6 @@
     MutexLock mu(self, *rejected_classes_lock_);
     rejected_classes_ = new MethodVerifier::RejectedClassesTable;
   }
-
-#if defined(ART_USE_LLVM_COMPILER)
-  inferred_reg_category_maps_lock_ = new Mutex("verifier GC maps lock");
-  {
-    MutexLock mu(self, *inferred_reg_category_maps_lock_);
-    inferred_reg_category_maps_ = new MethodVerifier::InferredRegCategoryMapTable;
-  }
-#endif
 }
 
 void MethodVerifier::Shutdown() {
@@ -3369,17 +3345,6 @@
   }
   delete rejected_classes_lock_;
   rejected_classes_lock_ = NULL;
-
-#if defined(ART_USE_LLVM_COMPILER)
-  {
-    MutexLock mu(self, *inferred_reg_category_maps_lock_);
-    STLDeleteValues(inferred_reg_category_maps_);
-    delete inferred_reg_category_maps_;
-    inferred_reg_category_maps_ = NULL;
-  }
-  delete inferred_reg_category_maps_lock_;
-  inferred_reg_category_maps_lock_ = NULL;
-#endif
 }
 
 void MethodVerifier::AddRejectedClass(Compiler::ClassReference ref) {
@@ -3395,69 +3360,5 @@
   return (rejected_classes_->find(ref) != rejected_classes_->end());
 }
 
-#if defined(ART_USE_LLVM_COMPILER)
-const greenland::InferredRegCategoryMap* MethodVerifier::GenerateInferredRegCategoryMap() {
-  uint32_t insns_size = code_item_->insns_size_in_code_units_;
-  uint16_t regs_size = code_item_->registers_size_;
-
-  UniquePtr<InferredRegCategoryMap> table(new InferredRegCategoryMap(insns_size, regs_size));
-
-  for (size_t i = 0; i < insns_size; ++i) {
-    if (RegisterLine* line = reg_table_.GetLine(i)) {
-      const Instruction* inst = Instruction::At(code_item_->insns_ + i);
-      /* We only use InferredRegCategoryMap in one case */
-      if (inst->IsBranch()) {
-        for (size_t r = 0; r < regs_size; ++r) {
-          const RegType &rt = line->GetRegisterType(r);
-
-          if (rt.IsZero()) {
-            table->SetRegCategory(i, r, greenland::kRegZero);
-          } else if (rt.IsCategory1Types()) {
-            table->SetRegCategory(i, r, greenland::kRegCat1nr);
-          } else if (rt.IsCategory2Types()) {
-            table->SetRegCategory(i, r, greenland::kRegCat2);
-          } else if (rt.IsReferenceTypes()) {
-            table->SetRegCategory(i, r, greenland::kRegObject);
-          } else {
-            table->SetRegCategory(i, r, greenland::kRegUnknown);
-          }
-        }
-      }
-    }
-  }
-
-  return table.release();
-}
-
-void MethodVerifier::SetInferredRegCategoryMap(Compiler::MethodReference ref,
-                                          const InferredRegCategoryMap& inferred_reg_category_map) {
-  {
-    MutexLock mu(Thread::Current(), *inferred_reg_category_maps_lock_);
-    InferredRegCategoryMapTable::iterator it = inferred_reg_category_maps_->find(ref);
-    if (it == inferred_reg_category_maps_->end()) {
-      inferred_reg_category_maps_->Put(ref, &inferred_reg_category_map);
-    } else {
-      CHECK(*(it->second) == inferred_reg_category_map);
-      delete &inferred_reg_category_map;
-    }
-  }
-  CHECK(GetInferredRegCategoryMap(ref) != NULL);
-}
-
-const greenland::InferredRegCategoryMap*
-MethodVerifier::GetInferredRegCategoryMap(Compiler::MethodReference ref) {
-  MutexLock mu(Thread::Current(), *inferred_reg_category_maps_lock_);
-
-  InferredRegCategoryMapTable::const_iterator it =
-      inferred_reg_category_maps_->find(ref);
-
-  if (it == inferred_reg_category_maps_->end()) {
-    return NULL;
-  }
-  CHECK(it->second != NULL);
-  return it->second;
-}
-#endif
-
 }  // namespace verifier
 }  // namespace art
diff --git a/src/verifier/method_verifier.h b/src/verifier/method_verifier.h
index 4939217..ba9b7b8 100644
--- a/src/verifier/method_verifier.h
+++ b/src/verifier/method_verifier.h
@@ -38,12 +38,6 @@
 
 struct ReferenceMap2Visitor;
 
-#if defined(ART_USE_LLVM_COMPILER)
-namespace greenland {
-  class InferredRegCategoryMap;
-}  // namespace greenland
-#endif
-
 namespace verifier {
 
 class MethodVerifier;
@@ -142,9 +136,6 @@
 
 // The verifier
 class MethodVerifier {
-#if defined(ART_USE_LLVM_COMPILER)
-  typedef greenland::InferredRegCategoryMap InferredRegCategoryMap;
-#endif
  public:
   enum FailureKind {
     kNoFailure,
@@ -204,11 +195,6 @@
   static void Init();
   static void Shutdown();
 
-#if defined(ART_USE_LLVM_COMPILER)
-  static const InferredRegCategoryMap* GetInferredRegCategoryMap(Compiler::MethodReference ref)
-      LOCKS_EXCLUDED(inferred_reg_category_maps_lock_);
-#endif
-
   static bool IsClassRejected(Compiler::ClassReference ref)
       LOCKS_EXCLUDED(rejected_classes_lock_);
 
@@ -566,14 +552,6 @@
   // Get a type representing the declaring class of the method.
   const RegType& GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-#if defined(ART_USE_LLVM_COMPILER)
-  /*
-   * Generate the inferred register category for LLVM-based code generator.
-   * Returns a pointer to a two-dimension Class array, or NULL on failure.
-   */
-  const InferredRegCategoryMap* GenerateInferredRegCategoryMap();
-#endif
-
   /*
    * Generate the GC map for a method that has just been verified (i.e. we're doing this as part of
    * verification). For type-precise determination we have all the data we need, so we just need to
@@ -601,17 +579,6 @@
   static Mutex* rejected_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
   static RejectedClassesTable* rejected_classes_;
 
-#if defined(ART_USE_LLVM_COMPILER)
-  // All the inferred register category maps that the verifier has created.
-  typedef SafeMap<const Compiler::MethodReference,
-                  const InferredRegCategoryMap*> InferredRegCategoryMapTable;
-  static Mutex* inferred_reg_category_maps_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
-  static InferredRegCategoryMapTable* inferred_reg_category_maps_ GUARDED_BY(inferred_reg_category_maps_lock_);
-  static void SetInferredRegCategoryMap(Compiler::MethodReference ref,
-                                        const InferredRegCategoryMap& m)
-      LOCKS_EXCLUDED(inferred_reg_category_maps_lock_);
-#endif
-
   static void AddRejectedClass(Compiler::ClassReference ref)
       LOCKS_EXCLUDED(rejected_classes_lock_);
 
