diff --git a/compiler/Android.mk b/compiler/Android.mk
index a75417b..18d6cf7 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -84,7 +84,6 @@
 	jni/quick/x86_64/calling_convention_x86_64.cc \
 	jni/quick/calling_convention.cc \
 	jni/quick/jni_compiler.cc \
-	llvm/llvm_compiler.cc \
 	optimizing/builder.cc \
 	optimizing/bounds_check_elimination.cc \
 	optimizing/code_generator.cc \
@@ -137,38 +136,8 @@
 	output_stream.cc \
 	vector_output_stream.cc
 
-ifeq ($(ART_SEA_IR_MODE),true)
-LIBART_COMPILER_SRC_FILES += \
-	sea_ir/frontend.cc \
-	sea_ir/ir/instruction_tools.cc \
-	sea_ir/ir/sea.cc \
-	sea_ir/code_gen/code_gen.cc \
-	sea_ir/code_gen/code_gen_data.cc \
-	sea_ir/types/type_inference.cc \
-	sea_ir/types/type_inference_visitor.cc \
-	sea_ir/debug/dot_gen.cc
-endif
-
 LIBART_COMPILER_CFLAGS :=
 
-ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-LIBART_COMPILER_SRC_FILES += \
-	dex/portable/mir_to_gbc.cc \
-	elf_writer_mclinker.cc \
-	jni/portable/jni_compiler.cc \
-	llvm/compiler_llvm.cc \
-	llvm/gbc_expander.cc \
-	llvm/generated/art_module.cc \
-	llvm/intrinsic_helper.cc \
-	llvm/ir_builder.cc \
-	llvm/llvm_compilation_unit.cc \
-	llvm/md_builder.cc \
-	llvm/runtime_support_builder.cc \
-	llvm/runtime_support_builder_arm.cc \
-	llvm/runtime_support_builder_x86.cc
-LIBART_COMPILER_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
-endif
-
 LIBART_COMPILER_ENUM_OPERATOR_OUT_HEADER_FILES := \
   dex/quick/arm/arm_lir.h \
   dex/quick/arm64/arm64_lir.h \
@@ -249,28 +218,6 @@
     endif
   endif
 
-  ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-    LOCAL_SHARED_LIBRARIES += libLLVM
-    LOCAL_CFLAGS += -DART_USE_PORTABLE_COMPILER=1
-    ifeq ($$(art_target_or_host),target)
-      LOCAL_STATIC_LIBRARIES_arm += libmcldARMInfo libmcldARMTarget
-      LOCAL_STATIC_LIBRARIES_x86 += libmcldX86Info libmcldX86Target
-      LOCAL_STATIC_LIBRARIES_x86_64 += libmcldX86Info libmcldX86Target
-      LOCAL_STATIC_LIBRARIES_mips += libmcldMipsInfo libmcldMipsTarget
-      ifeq ($(TARGET_ARCH),arm64)
-         $$(info TODOAArch64: $$(LOCAL_PATH)/Android.mk Add Arm64 specific MCLinker libraries)
-      endif # TARGET_ARCH != arm64
-      include $(LLVM_DEVICE_BUILD_MK)
-    else # host
-      LOCAL_STATIC_LIBRARIES += libmcldARMInfo libmcldARMTarget
-      LOCAL_STATIC_LIBRARIES += libmcldX86Info libmcldX86Target
-      LOCAL_STATIC_LIBRARIES += libmcldMipsInfo libmcldMipsTarget
-      include $(LLVM_HOST_BUILD_MK)
-    endif
-    LOCAL_STATIC_LIBRARIES += libmcldCore libmcldObject libmcldADT libmcldFragment libmcldTarget libmcldCodeGen libmcldLDVariant libmcldMC libmcldSupport libmcldLD libmcldScript
-    include $(LLVM_GEN_INTRINSICS_MK)
-  endif
-
   LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime
 
   ifeq ($$(art_target_or_host),host)
@@ -323,18 +270,3 @@
 ifeq ($(ART_BUILD_TARGET_DEBUG),true)
   $(eval $(call build-libart-compiler,target,debug))
 endif
-
-# Rule to build /system/lib/libcompiler_rt.a
-# Usually static libraries are not installed on the device.
-ifeq ($(ART_USE_PORTABLE_COMPILER),true)
-ifeq ($(ART_BUILD_TARGET),true)
-# TODO: Move to external/compiler_rt
-$(eval $(call copy-one-file, $(call intermediates-dir-for,STATIC_LIBRARIES,libcompiler_rt,,)/libcompiler_rt.a, $(TARGET_OUT_SHARED_LIBRARIES)/libcompiler_rt.a))
-ifdef TARGET_2ND_ARCH
-$(eval $(call copy-one-file, $(call intermediates-dir-for,STATIC_LIBRARIES,libcompiler_rt,,,t)/libcompiler_rt.a, $(2ND_TARGET_OUT_SHARED_LIBRARIES)/libcompiler_rt.a))
-endif
-
-$(DEX2OAT): $(TARGET_OUT_SHARED_LIBRARIES)/libcompiler_rt.a
-
-endif
-endif
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index e84f65a..059a9ee 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -49,50 +49,43 @@
   }
   if (compiled_method != nullptr) {
     const std::vector<uint8_t>* code = compiled_method->GetQuickCode();
-    const void* code_ptr;
-    bool is_portable = (code == nullptr);
-    if (!is_portable) {
-      uint32_t code_size = code->size();
-      CHECK_NE(0u, code_size);
-      const std::vector<uint8_t>& vmap_table = compiled_method->GetVmapTable();
-      uint32_t vmap_table_offset = vmap_table.empty() ? 0u
-          : sizeof(OatQuickMethodHeader) + vmap_table.size();
-      const std::vector<uint8_t>& mapping_table = *compiled_method->GetMappingTable();
-      uint32_t mapping_table_offset = mapping_table.empty() ? 0u
-          : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size();
-      const std::vector<uint8_t>& gc_map = *compiled_method->GetGcMap();
-      uint32_t gc_map_offset = gc_map.empty() ? 0u
-          : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size() + gc_map.size();
-      OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, gc_map_offset,
-                                         compiled_method->GetFrameSizeInBytes(),
-                                         compiled_method->GetCoreSpillMask(),
-                                         compiled_method->GetFpSpillMask(), code_size);
+    uint32_t code_size = code->size();
+    CHECK_NE(0u, code_size);
+    const std::vector<uint8_t>& vmap_table = compiled_method->GetVmapTable();
+    uint32_t vmap_table_offset = vmap_table.empty() ? 0u
+        : sizeof(OatQuickMethodHeader) + vmap_table.size();
+    const std::vector<uint8_t>& mapping_table = *compiled_method->GetMappingTable();
+    uint32_t mapping_table_offset = mapping_table.empty() ? 0u
+        : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size();
+    const std::vector<uint8_t>& gc_map = *compiled_method->GetGcMap();
+    uint32_t gc_map_offset = gc_map.empty() ? 0u
+        : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size() + gc_map.size();
+    OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, gc_map_offset,
+                                       compiled_method->GetFrameSizeInBytes(),
+                                       compiled_method->GetCoreSpillMask(),
+                                       compiled_method->GetFpSpillMask(), code_size);
 
-      header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
-      std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
-      size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table.size() +
-          gc_map.size();
-      size_t code_offset = compiled_method->AlignCode(size - code_size);
-      size_t padding = code_offset - (size - code_size);
-      chunk->reserve(padding + size);
-      chunk->resize(sizeof(method_header));
-      memcpy(&(*chunk)[0], &method_header, sizeof(method_header));
-      chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end());
-      chunk->insert(chunk->begin(), mapping_table.begin(), mapping_table.end());
-      chunk->insert(chunk->begin(), gc_map.begin(), gc_map.end());
-      chunk->insert(chunk->begin(), padding, 0);
-      chunk->insert(chunk->end(), code->begin(), code->end());
-      CHECK_EQ(padding + size, chunk->size());
-      code_ptr = &(*chunk)[code_offset];
-    } else {
-      code = compiled_method->GetPortableCode();
-      code_ptr = &(*code)[0];
-    }
+    header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
+    std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
+    size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table.size() +
+        gc_map.size();
+    size_t code_offset = compiled_method->AlignCode(size - code_size);
+    size_t padding = code_offset - (size - code_size);
+    chunk->reserve(padding + size);
+    chunk->resize(sizeof(method_header));
+    memcpy(&(*chunk)[0], &method_header, sizeof(method_header));
+    chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end());
+    chunk->insert(chunk->begin(), mapping_table.begin(), mapping_table.end());
+    chunk->insert(chunk->begin(), gc_map.begin(), gc_map.end());
+    chunk->insert(chunk->begin(), padding, 0);
+    chunk->insert(chunk->end(), code->begin(), code->end());
+    CHECK_EQ(padding + size, chunk->size());
+    const void* code_ptr = &(*chunk)[code_offset];
     MakeExecutable(code_ptr, code->size());
     const void* method_code = CompiledMethod::CodePointer(code_ptr,
                                                           compiled_method->GetInstructionSet());
     LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
-    class_linker_->SetEntryPointsToCompiledCode(method, method_code, is_portable);
+    class_linker_->SetEntryPointsToCompiledCode(method, method_code);
   } else {
     // No code? You must mean to go into the interpreter.
     // Or the generic JNI...
@@ -155,7 +148,7 @@
     }
 
     // TODO: make selectable
-    Compiler::Kind compiler_kind = kUsePortableCompiler ? Compiler::kPortable : Compiler::kQuick;
+    Compiler::Kind compiler_kind = Compiler::kQuick;
     timer_.reset(new CumulativeLogger("Compilation times"));
     compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
                                               verification_results_.get(),
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc
index e292834..060af72 100644
--- a/compiler/compiled_method.cc
+++ b/compiler/compiled_method.cc
@@ -22,33 +22,11 @@
 CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
                            const std::vector<uint8_t>& quick_code)
     : compiler_driver_(compiler_driver), instruction_set_(instruction_set),
-      portable_code_(nullptr), quick_code_(nullptr) {
-  SetCode(&quick_code, nullptr);
+      quick_code_(nullptr) {
+  SetCode(&quick_code);
 }
 
-CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
-                           const std::string& elf_object, const std::string& symbol)
-    : compiler_driver_(compiler_driver), instruction_set_(instruction_set),
-      portable_code_(nullptr), quick_code_(nullptr), symbol_(symbol) {
-  CHECK_NE(elf_object.size(), 0U);
-  CHECK_NE(symbol.size(), 0U);
-  std::vector<uint8_t> temp_code(elf_object.size());
-  for (size_t i = 0; i < elf_object.size(); ++i) {
-    temp_code[i] = elf_object[i];
-  }
-  // TODO: we shouldn't just shove ELF objects in as "code" but
-  // change to have different kinds of compiled methods.  This is
-  // being deferred until we work on hybrid execution or at least
-  // until we work on batch compilation.
-  SetCode(nullptr, &temp_code);
-}
-
-void CompiledCode::SetCode(const std::vector<uint8_t>* quick_code,
-                           const std::vector<uint8_t>* portable_code) {
-  if (portable_code != nullptr) {
-    CHECK(!portable_code->empty());
-    portable_code_ = compiler_driver_->DeduplicateCode(*portable_code);
-  }
+void CompiledCode::SetCode(const std::vector<uint8_t>* quick_code) {
   if (quick_code != nullptr) {
     CHECK(!quick_code->empty());
     quick_code_ = compiler_driver_->DeduplicateCode(*quick_code);
@@ -64,17 +42,8 @@
     } else {
       return std::equal(quick_code_->begin(), quick_code_->end(), rhs.quick_code_->begin());
     }
-  } else if (portable_code_ != nullptr) {
-    if (rhs.portable_code_ == nullptr) {
-      return false;
-    } else if (portable_code_->size() != rhs.portable_code_->size()) {
-      return false;
-    } else {
-      return std::equal(portable_code_->begin(), portable_code_->end(),
-                        rhs.portable_code_->begin());
-    }
   }
-  return (rhs.quick_code_ == nullptr) && (rhs.portable_code_ == nullptr);
+  return (rhs.quick_code_ == nullptr);
 }
 
 uint32_t CompiledCode::AlignCode(uint32_t offset) const {
@@ -128,13 +97,8 @@
   }
 }
 
-const std::string& CompiledCode::GetSymbol() const {
-  CHECK_NE(0U, symbol_.size());
-  return symbol_;
-}
-
 const std::vector<uint32_t>& CompiledCode::GetOatdataOffsetsToCompliledCodeOffset() const {
-  CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size()) << symbol_;
+  CHECK_NE(0U, oatdata_offsets_to_compiled_code_offset_.size());
   return oatdata_offsets_to_compiled_code_offset_;
 }
 
@@ -201,32 +165,4 @@
       patches_() {
 }
 
-// Constructs a CompiledMethod for the Portable compiler.
-CompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set,
-                               const std::string& code, const std::vector<uint8_t>& gc_map,
-                               const std::string& symbol)
-    : CompiledCode(driver, instruction_set, code, symbol),
-      frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
-      fp_spill_mask_(0),
-      src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())),
-      mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())),
-      vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())),
-      gc_map_(driver->DeduplicateGCMap(gc_map)),
-      cfi_info_(nullptr),
-      patches_() {
-}
-
-CompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set,
-                               const std::string& code, const std::string& symbol)
-    : CompiledCode(driver, instruction_set, code, symbol),
-      frame_size_in_bytes_(kStackAlignment), core_spill_mask_(0),
-      fp_spill_mask_(0),
-      src_mapping_table_(driver->DeduplicateSrcMappingTable(SrcMap())),
-      mapping_table_(driver->DeduplicateMappingTable(std::vector<uint8_t>())),
-      vmap_table_(driver->DeduplicateVMapTable(std::vector<uint8_t>())),
-      gc_map_(driver->DeduplicateGCMap(std::vector<uint8_t>())),
-      cfi_info_(nullptr),
-      patches_() {
-}
-
 }  // namespace art
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index d2f5d01..d93db03 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -40,23 +40,15 @@
   CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
                const std::vector<uint8_t>& quick_code);
 
-  // For Portable to supply an ELF object
-  CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set,
-               const std::string& elf_object, const std::string &symbol);
-
   InstructionSet GetInstructionSet() const {
     return instruction_set_;
   }
 
-  const std::vector<uint8_t>* GetPortableCode() const {
-    return portable_code_;
-  }
-
   const std::vector<uint8_t>* GetQuickCode() const {
     return quick_code_;
   }
 
-  void SetCode(const std::vector<uint8_t>* quick_code, const std::vector<uint8_t>* portable_code);
+  void SetCode(const std::vector<uint8_t>* quick_code);
 
   bool operator==(const CompiledCode& rhs) const;
 
@@ -77,7 +69,6 @@
   static const void* CodePointer(const void* code_pointer,
                                  InstructionSet instruction_set);
 
-  const std::string& GetSymbol() const;
   const std::vector<uint32_t>& GetOatdataOffsetsToCompliledCodeOffset() const;
   void AddOatdataOffsetToCompliledCodeOffset(uint32_t offset);
 
@@ -86,15 +77,9 @@
 
   const InstructionSet instruction_set_;
 
-  // The ELF image for portable.
-  std::vector<uint8_t>* portable_code_;
-
   // Used to store the PIC code for Quick.
   std::vector<uint8_t>* quick_code_;
 
-  // Used for the Portable ELF symbol name.
-  const std::string symbol_;
-
   // There are offsets from the oatdata symbol to where the offset to
   // the compiled method will be found. These are computed by the
   // OatWriter and then used by the ElfWriter to add relocations so
@@ -302,14 +287,6 @@
                  const uint32_t fp_spill_mask,
                  const std::vector<uint8_t>* cfi_info);
 
-  // Constructs a CompiledMethod for the Portable compiler.
-  CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const std::string& code,
-                 const std::vector<uint8_t>& gc_map, const std::string& symbol);
-
-  // Constructs a CompiledMethod for the Portable JniCompiler.
-  CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const std::string& code,
-                 const std::string& symbol);
-
   ~CompiledMethod() {}
 
   size_t GetFrameSizeInBytes() const {
@@ -365,7 +342,7 @@
   // For quick code, a uleb128 encoded map from GPR/FPR register to dex register. Size prefixed.
   std::vector<uint8_t>* vmap_table_;
   // For quick code, a map keyed by native PC indices to bitmaps describing what dalvik registers
-  // are live. For portable code, the key is a dalvik PC.
+  // are live.
   std::vector<uint8_t>* gc_map_;
   // For quick code, a FDE entry for the debug_frame section.
   std::vector<uint8_t>* cfi_info_;
diff --git a/compiler/compiler.cc b/compiler/compiler.cc
index b9fcf5b..baa6688 100644
--- a/compiler/compiler.cc
+++ b/compiler/compiler.cc
@@ -19,55 +19,10 @@
 #include "base/logging.h"
 #include "dex/quick/quick_compiler.h"
 #include "driver/compiler_driver.h"
-#include "llvm/llvm_compiler.h"
 #include "optimizing/optimizing_compiler.h"
 
 namespace art {
 
-#ifdef ART_SEA_IR_MODE
-constexpr bool kCanUseSeaIR = true;
-#else
-constexpr bool kCanUseSeaIR = false;
-#endif
-
-extern "C" art::CompiledMethod* SeaIrCompileMethod(const art::DexFile::CodeItem* code_item ATTRIBUTE_UNUSED,
-                                                   uint32_t access_flags ATTRIBUTE_UNUSED,
-                                                   art::InvokeType invoke_type ATTRIBUTE_UNUSED,
-                                                   uint16_t class_def_idx ATTRIBUTE_UNUSED,
-                                                   uint32_t method_idx ATTRIBUTE_UNUSED,
-                                                   jobject class_loader ATTRIBUTE_UNUSED,
-                                                   const art::DexFile& dex_file ATTRIBUTE_UNUSED)
-#ifdef ART_SEA_IR_MODE
-;   // NOLINT(whitespace/semicolon)
-#else
-{
-  UNREACHABLE();
-}
-#endif
-
-
-CompiledMethod* Compiler::TryCompileWithSeaIR(const art::DexFile::CodeItem* code_item,
-                                              uint32_t access_flags,
-                                              art::InvokeType invoke_type,
-                                              uint16_t class_def_idx,
-                                              uint32_t method_idx,
-                                              jobject class_loader,
-                                              const art::DexFile& dex_file) {
-  bool use_sea = kCanUseSeaIR &&
-      (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
-  if (use_sea) {
-    LOG(INFO) << "Using SEA IR to compile..." << std::endl;
-    return SeaIrCompileMethod(code_item,
-                              access_flags,
-                              invoke_type,
-                              class_def_idx,
-                              method_idx,
-                              class_loader,
-                              dex_file);
-  }
-  return nullptr;
-}
-
 Compiler* Compiler::Create(CompilerDriver* driver, Compiler::Kind kind) {
   switch (kind) {
     case kQuick:
@@ -76,13 +31,6 @@
     case kOptimizing:
       return CreateOptimizingCompiler(driver);
 
-    case kPortable:
-      {
-        Compiler* compiler = CreateLLVMCompiler(driver);
-        CHECK(compiler != nullptr) << "Portable compiler not compiled";
-        return compiler;
-      }
-
     default:
       LOG(FATAL) << "UNREACHABLE";
       UNREACHABLE();
diff --git a/compiler/compiler.h b/compiler/compiler.h
index c2c15ff..07e2fd6 100644
--- a/compiler/compiler.h
+++ b/compiler/compiler.h
@@ -32,19 +32,11 @@
   class ArtMethod;
 }
 
-// Base class for compiler-specific thread-local storage for compiler worker threads
-class CompilerTls {
-  public:
-    CompilerTls() {}
-    ~CompilerTls() {}
-};
-
 class Compiler {
  public:
   enum Kind {
     kQuick,
-    kOptimizing,
-    kPortable
+    kOptimizing
   };
 
   static Compiler* Create(CompilerDriver* driver, Kind kind);
@@ -64,14 +56,6 @@
                                   jobject class_loader,
                                   const DexFile& dex_file) const = 0;
 
-  static CompiledMethod* TryCompileWithSeaIR(const art::DexFile::CodeItem* code_item,
-                                             uint32_t access_flags,
-                                             art::InvokeType invoke_type,
-                                             uint16_t class_def_idx,
-                                             uint32_t method_idx,
-                                             jobject class_loader,
-                                             const art::DexFile& dex_file);
-
   virtual CompiledMethod* JniCompile(uint32_t access_flags,
                                      uint32_t method_idx,
                                      const DexFile& dex_file) const = 0;
@@ -92,15 +76,6 @@
     return maximum_compilation_time_before_warning_;
   }
 
-  virtual bool IsPortable() const {
-    return false;
-  }
-
-  void SetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) {
-    UNUSED(driver);
-    UNUSED(filename);
-  }
-
   virtual void InitCompilationUnit(CompilationUnit& cu) const = 0;
 
   virtual ~Compiler() {}
@@ -119,10 +94,6 @@
     return nullptr;
   }
 
-  virtual CompilerTls* CreateNewCompilerTls() {
-    return nullptr;
-  }
-
   // Returns whether the method to compile is such a pathological case that
   // it's not worth compiling.
   static bool IsPathologicalCase(const DexFile::CodeItem& code_item,
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index fb5dc9c..dd8b4c8 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -69,8 +69,6 @@
   // (1 << kDebugShowNops) |
   // (1 << kDebugCountOpcodes) |
   // (1 << kDebugDumpCheckStats) |
-  // (1 << kDebugDumpBitcodeFile) |
-  // (1 << kDebugVerifyBitcode) |
   // (1 << kDebugShowSummaryMemoryUsage) |
   // (1 << kDebugShowFilterStats) |
   // (1 << kDebugTimings) |
diff --git a/compiler/dex/frontend.h b/compiler/dex/frontend.h
index 1145818..4266535 100644
--- a/compiler/dex/frontend.h
+++ b/compiler/dex/frontend.h
@@ -70,8 +70,6 @@
   kDebugShowNops,
   kDebugCountOpcodes,
   kDebugDumpCheckStats,
-  kDebugDumpBitcodeFile,
-  kDebugVerifyBitcode,
   kDebugShowSummaryMemoryUsage,
   kDebugShowFilterStats,
   kDebugTimings,
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index f78b39f..6e9844c 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -552,8 +552,7 @@
       // Is this the select pattern?
       // TODO: flesh out support for Mips.  NOTE: llvm's select op doesn't quite work here.
       // TUNING: expand to support IF_xx compare & branches
-      if (!cu_->compiler->IsPortable() &&
-          (cu_->instruction_set == kArm64 || cu_->instruction_set == kThumb2 ||
+      if ((cu_->instruction_set == kArm64 || cu_->instruction_set == kThumb2 ||
            cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) &&
           IsInstructionIfCcZ(mir->dalvikInsn.opcode)) {
         BasicBlock* ft = GetBasicBlock(bb->fall_through);
diff --git a/compiler/dex/portable/mir_to_gbc.cc b/compiler/dex/portable/mir_to_gbc.cc
deleted file mode 100644
index ba255e0..0000000
--- a/compiler/dex/portable/mir_to_gbc.cc
+++ /dev/null
@@ -1,2003 +0,0 @@
-/*
- * Copyright (C) 2011 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 "object_utils.h"
-
-#include <llvm/ADT/DepthFirstIterator.h>
-#include <llvm/Analysis/Verifier.h>
-#include <llvm/Bitcode/ReaderWriter.h>
-#include <llvm/IR/Instruction.h>
-#include <llvm/IR/Instructions.h>
-#include <llvm/IR/Metadata.h>
-#include <llvm/IR/Type.h>
-#include <llvm/Support/Casting.h>
-#include <llvm/Support/InstIterator.h>
-#include <llvm/Support/ToolOutputFile.h>
-
-#include "dex/compiler_internals.h"
-#include "dex/dataflow_iterator-inl.h"
-#include "dex/frontend.h"
-#include "llvm/ir_builder.h"
-#include "llvm/llvm_compilation_unit.h"
-#include "llvm/utils_llvm.h"
-#include "mir_to_gbc.h"
-#include "thread-inl.h"
-
-const char* kLabelFormat = "%c0x%x_%d";
-const char kInvalidBlock = 0xff;
-const char kNormalBlock = 'L';
-const char kCatchBlock = 'C';
-
-namespace art {
-namespace llvm {
-::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
-}
-
-LLVMInfo::LLVMInfo() {
-  // Create context, module, intrinsic helper & ir builder
-  llvm_context_.reset(new ::llvm::LLVMContext());
-  llvm_module_ = new ::llvm::Module("art", *llvm_context_);
-  ::llvm::StructType::create(*llvm_context_, "JavaObject");
-  art::llvm::makeLLVMModuleContents(llvm_module_);
-  intrinsic_helper_.reset(new art::llvm::IntrinsicHelper(*llvm_context_, *llvm_module_));
-  ir_builder_.reset(new art::llvm::IRBuilder(*llvm_context_, *llvm_module_, *intrinsic_helper_));
-}
-
-LLVMInfo::~LLVMInfo() {
-}
-
-::llvm::BasicBlock* MirConverter::GetLLVMBlock(int id) {
-  return id_to_block_map_.Get(id);
-}
-
-::llvm::Value* MirConverter::GetLLVMValue(int s_reg) {
-  return llvm_values_[s_reg];
-}
-
-void MirConverter::SetVregOnValue(::llvm::Value* val, int s_reg) {
-  // Set vreg for debugging
-  art::llvm::IntrinsicHelper::IntrinsicId id = art::llvm::IntrinsicHelper::SetVReg;
-  ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id);
-  int v_reg = mir_graph_->SRegToVReg(s_reg);
-  ::llvm::Value* table_slot = irb_->getInt32(v_reg);
-  ::llvm::Value* args[] = { table_slot, val };
-  irb_->CreateCall(func, args);
-}
-
-// Replace the placeholder value with the real definition
-void MirConverter::DefineValueOnly(::llvm::Value* val, int s_reg) {
-  ::llvm::Value* placeholder = GetLLVMValue(s_reg);
-  if (placeholder == NULL) {
-    // This can happen on instruction rewrite on verification failure
-    LOG(WARNING) << "Null placeholder";
-    return;
-  }
-  placeholder->replaceAllUsesWith(val);
-  val->takeName(placeholder);
-  llvm_values_[s_reg] = val;
-  ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(placeholder);
-  DCHECK(inst != NULL);
-  inst->eraseFromParent();
-}
-
-void MirConverter::DefineValue(::llvm::Value* val, int s_reg) {
-  DefineValueOnly(val, s_reg);
-  SetVregOnValue(val, s_reg);
-}
-
-::llvm::Type* MirConverter::LlvmTypeFromLocRec(RegLocation loc) {
-  ::llvm::Type* res = NULL;
-  if (loc.wide) {
-    if (loc.fp)
-        res = irb_->getDoubleTy();
-    else
-        res = irb_->getInt64Ty();
-  } else {
-    if (loc.fp) {
-      res = irb_->getFloatTy();
-    } else {
-      if (loc.ref)
-        res = irb_->getJObjectTy();
-      else
-        res = irb_->getInt32Ty();
-    }
-  }
-  return res;
-}
-
-void MirConverter::InitIR() {
-  if (llvm_info_ == NULL) {
-    CompilerTls* tls = cu_->compiler_driver->GetTls();
-    CHECK(tls != NULL);
-    llvm_info_ = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
-    if (llvm_info_ == NULL) {
-      llvm_info_ = new LLVMInfo();
-      tls->SetLLVMInfo(llvm_info_);
-    }
-  }
-  context_ = llvm_info_->GetLLVMContext();
-  module_ = llvm_info_->GetLLVMModule();
-  intrinsic_helper_ = llvm_info_->GetIntrinsicHelper();
-  irb_ = llvm_info_->GetIRBuilder();
-}
-
-::llvm::BasicBlock* MirConverter::FindCaseTarget(uint32_t vaddr) {
-  BasicBlock* bb = mir_graph_->FindBlock(vaddr);
-  DCHECK(bb != NULL);
-  return GetLLVMBlock(bb->id);
-}
-
-void MirConverter::ConvertPackedSwitch(BasicBlock* bb, MIR* mir,
-                                int32_t table_offset, RegLocation rl_src) {
-  const Instruction::PackedSwitchPayload* payload =
-      reinterpret_cast<const Instruction::PackedSwitchPayload*>(
-      mir_graph_->GetTable(mir, table_offset));
-
-  ::llvm::Value* value = GetLLVMValue(rl_src.orig_sreg);
-
-  ::llvm::SwitchInst* sw =
-    irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through),
-                             payload->case_count);
-
-  for (uint16_t i = 0; i < payload->case_count; ++i) {
-    ::llvm::BasicBlock* llvm_bb =
-        FindCaseTarget(current_dalvik_offset_ + payload->targets[i]);
-    sw->addCase(irb_->getInt32(payload->first_key + i), llvm_bb);
-  }
-  ::llvm::MDNode* switch_node =
-      ::llvm::MDNode::get(*context_, irb_->getInt32(table_offset));
-  sw->setMetadata("SwitchTable", switch_node);
-  bb->taken = NullBasicBlockId;
-  bb->fall_through = NullBasicBlockId;
-}
-
-void MirConverter::ConvertSparseSwitch(BasicBlock* bb, MIR* mir,
-                                int32_t table_offset, RegLocation rl_src) {
-  const Instruction::SparseSwitchPayload* payload =
-      reinterpret_cast<const Instruction::SparseSwitchPayload*>(
-      mir_graph_->GetTable(mir, table_offset));
-
-  const int32_t* keys = payload->GetKeys();
-  const int32_t* targets = payload->GetTargets();
-
-  ::llvm::Value* value = GetLLVMValue(rl_src.orig_sreg);
-
-  ::llvm::SwitchInst* sw =
-    irb_->CreateSwitch(value, GetLLVMBlock(bb->fall_through),
-                             payload->case_count);
-
-  for (size_t i = 0; i < payload->case_count; ++i) {
-    ::llvm::BasicBlock* llvm_bb =
-        FindCaseTarget(current_dalvik_offset_ + targets[i]);
-    sw->addCase(irb_->getInt32(keys[i]), llvm_bb);
-  }
-  ::llvm::MDNode* switch_node =
-      ::llvm::MDNode::get(*context_, irb_->getInt32(table_offset));
-  sw->setMetadata("SwitchTable", switch_node);
-  bb->taken = NullBasicBlockId;
-  bb->fall_through = NullBasicBlockId;
-}
-
-void MirConverter::ConvertSget(int32_t field_index,
-                        art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) {
-  ::llvm::Constant* field_idx = irb_->getInt32(field_index);
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* res = irb_->CreateCall(intr, field_idx);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertSput(int32_t field_index,
-                        art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src) {
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(field_index));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  irb_->CreateCall(intr, args);
-}
-
-void MirConverter::ConvertFillArrayData(int32_t offset, RegLocation rl_array) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  id = art::llvm::IntrinsicHelper::HLFillArrayData;
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(offset));
-  args.push_back(GetLLVMValue(rl_array.orig_sreg));
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  irb_->CreateCall(intr, args);
-}
-
-::llvm::Value* MirConverter::EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
-                              RegLocation loc) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  if (loc.wide) {
-    if (loc.fp) {
-      id = art::llvm::IntrinsicHelper::ConstDouble;
-    } else {
-      id = art::llvm::IntrinsicHelper::ConstLong;
-    }
-  } else {
-    if (loc.fp) {
-      id = art::llvm::IntrinsicHelper::ConstFloat;
-    } else if (loc.ref) {
-      id = art::llvm::IntrinsicHelper::ConstObj;
-    } else {
-      id = art::llvm::IntrinsicHelper::ConstInt;
-    }
-  }
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  return irb_->CreateCall(intr, src);
-}
-
-void MirConverter::EmitPopShadowFrame() {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
-      art::llvm::IntrinsicHelper::PopShadowFrame);
-  irb_->CreateCall(intr);
-}
-
-::llvm::Value* MirConverter::EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
-                             RegLocation loc) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  if (loc.wide) {
-    if (loc.fp) {
-      id = art::llvm::IntrinsicHelper::CopyDouble;
-    } else {
-      id = art::llvm::IntrinsicHelper::CopyLong;
-    }
-  } else {
-    if (loc.fp) {
-      id = art::llvm::IntrinsicHelper::CopyFloat;
-    } else if (loc.ref) {
-      id = art::llvm::IntrinsicHelper::CopyObj;
-    } else {
-      id = art::llvm::IntrinsicHelper::CopyInt;
-    }
-  }
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  return irb_->CreateCall(intr, src);
-}
-
-void MirConverter::ConvertMoveException(RegLocation rl_dest) {
-  ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(
-      art::llvm::IntrinsicHelper::GetException);
-  ::llvm::Value* res = irb_->CreateCall(func);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertThrow(RegLocation rl_src) {
-  ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
-  ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(
-      art::llvm::IntrinsicHelper::HLThrowException);
-  irb_->CreateCall(func, src);
-}
-
-void MirConverter::ConvertMonitorEnterExit(int opt_flags,
-                                    art::llvm::IntrinsicHelper::IntrinsicId id,
-                                    RegLocation rl_src) {
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(opt_flags));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id);
-  irb_->CreateCall(func, args);
-}
-
-void MirConverter::ConvertArrayLength(int opt_flags,
-                               RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(opt_flags));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(
-      art::llvm::IntrinsicHelper::OptArrayLength);
-  ::llvm::Value* res = irb_->CreateCall(func, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::EmitSuspendCheck() {
-  art::llvm::IntrinsicHelper::IntrinsicId id =
-      art::llvm::IntrinsicHelper::CheckSuspend;
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  irb_->CreateCall(intr);
-}
-
-::llvm::Value* MirConverter::ConvertCompare(ConditionCode cc,
-                                   ::llvm::Value* src1, ::llvm::Value* src2) {
-  ::llvm::Value* res = NULL;
-  DCHECK_EQ(src1->getType(), src2->getType());
-  switch (cc) {
-    case kCondEq: res = irb_->CreateICmpEQ(src1, src2); break;
-    case kCondNe: res = irb_->CreateICmpNE(src1, src2); break;
-    case kCondLt: res = irb_->CreateICmpSLT(src1, src2); break;
-    case kCondGe: res = irb_->CreateICmpSGE(src1, src2); break;
-    case kCondGt: res = irb_->CreateICmpSGT(src1, src2); break;
-    case kCondLe: res = irb_->CreateICmpSLE(src1, src2); break;
-    default: LOG(FATAL) << "Unexpected cc value " << cc;
-  }
-  return res;
-}
-
-void MirConverter::ConvertCompareAndBranch(BasicBlock* bb, MIR* mir,
-                                    ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2) {
-  if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) {
-    EmitSuspendCheck();
-  }
-  ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
-  ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
-  ::llvm::Value* cond_value = ConvertCompare(cc, src1, src2);
-  cond_value->setName(StringPrintf("t%d", temp_name_++));
-  irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken),
-                           GetLLVMBlock(bb->fall_through));
-  // Don't redo the fallthrough branch in the BB driver
-  bb->fall_through = NullBasicBlockId;
-}
-
-void MirConverter::ConvertCompareZeroAndBranch(BasicBlock* bb,
-                                        MIR* mir, ConditionCode cc, RegLocation rl_src1) {
-  if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= mir->offset) {
-    EmitSuspendCheck();
-  }
-  ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
-  ::llvm::Value* src2;
-  if (rl_src1.ref) {
-    src2 = irb_->getJNull();
-  } else {
-    src2 = irb_->getInt32(0);
-  }
-  ::llvm::Value* cond_value = ConvertCompare(cc, src1, src2);
-  irb_->CreateCondBr(cond_value, GetLLVMBlock(bb->taken),
-                           GetLLVMBlock(bb->fall_through));
-  // Don't redo the fallthrough branch in the BB driver
-  bb->fall_through = NullBasicBlockId;
-}
-
-::llvm::Value* MirConverter::GenDivModOp(bool is_div, bool is_long,
-                                ::llvm::Value* src1, ::llvm::Value* src2) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  if (is_long) {
-    if (is_div) {
-      id = art::llvm::IntrinsicHelper::DivLong;
-    } else {
-      id = art::llvm::IntrinsicHelper::RemLong;
-    }
-  } else {
-    if (is_div) {
-      id = art::llvm::IntrinsicHelper::DivInt;
-    } else {
-      id = art::llvm::IntrinsicHelper::RemInt;
-    }
-  }
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2>args;
-  args.push_back(src1);
-  args.push_back(src2);
-  return irb_->CreateCall(intr, args);
-}
-
-::llvm::Value* MirConverter::GenArithOp(OpKind op, bool is_long,
-                               ::llvm::Value* src1, ::llvm::Value* src2) {
-  ::llvm::Value* res = NULL;
-  switch (op) {
-    case kOpAdd: res = irb_->CreateAdd(src1, src2); break;
-    case kOpSub: res = irb_->CreateSub(src1, src2); break;
-    case kOpRsub: res = irb_->CreateSub(src2, src1); break;
-    case kOpMul: res = irb_->CreateMul(src1, src2); break;
-    case kOpOr: res = irb_->CreateOr(src1, src2); break;
-    case kOpAnd: res = irb_->CreateAnd(src1, src2); break;
-    case kOpXor: res = irb_->CreateXor(src1, src2); break;
-    case kOpDiv: res = GenDivModOp(true, is_long, src1, src2); break;
-    case kOpRem: res = GenDivModOp(false, is_long, src1, src2); break;
-    case kOpLsl: res = irb_->CreateShl(src1, src2); break;
-    case kOpLsr: res = irb_->CreateLShr(src1, src2); break;
-    case kOpAsr: res = irb_->CreateAShr(src1, src2); break;
-    default:
-      LOG(FATAL) << "Invalid op " << op;
-  }
-  return res;
-}
-
-void MirConverter::ConvertFPArithOp(OpKind op, RegLocation rl_dest,
-                             RegLocation rl_src1, RegLocation rl_src2) {
-  ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
-  ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
-  ::llvm::Value* res = NULL;
-  switch (op) {
-    case kOpAdd: res = irb_->CreateFAdd(src1, src2); break;
-    case kOpSub: res = irb_->CreateFSub(src1, src2); break;
-    case kOpMul: res = irb_->CreateFMul(src1, src2); break;
-    case kOpDiv: res = irb_->CreateFDiv(src1, src2); break;
-    case kOpRem: res = irb_->CreateFRem(src1, src2); break;
-    default:
-      LOG(FATAL) << "Invalid op " << op;
-  }
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
-                         RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2) {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2>args;
-  args.push_back(GetLLVMValue(rl_src1.orig_sreg));
-  args.push_back(GetLLVMValue(rl_src2.orig_sreg));
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
-                            RegLocation rl_dest, RegLocation rl_src, int shift_amount) {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2>args;
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  args.push_back(irb_->getInt32(shift_amount));
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertArithOp(OpKind op, RegLocation rl_dest,
-                           RegLocation rl_src1, RegLocation rl_src2) {
-  ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
-  ::llvm::Value* src2 = GetLLVMValue(rl_src2.orig_sreg);
-  DCHECK_EQ(src1->getType(), src2->getType());
-  ::llvm::Value* res = GenArithOp(op, rl_dest.wide, src1, src2);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertArithOpLit(OpKind op, RegLocation rl_dest,
-                              RegLocation rl_src1, int32_t imm) {
-  ::llvm::Value* src1 = GetLLVMValue(rl_src1.orig_sreg);
-  ::llvm::Value* src2 = irb_->getInt32(imm);
-  ::llvm::Value* res = GenArithOp(op, rl_dest.wide, src1, src2);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-/*
- * Process arguments for invoke.  Note: this code is also used to
- * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
- * The requirements are similar.
- */
-void MirConverter::ConvertInvoke(BasicBlock* bb, MIR* mir,
-                          InvokeType invoke_type, bool is_range, bool is_filled_new_array) {
-  CallInfo* info = mir_graph_->NewMemCallInfo(bb, mir, invoke_type, is_range);
-  ::llvm::SmallVector< ::llvm::Value*, 10> args;
-  // Insert the invoke_type
-  args.push_back(irb_->getInt32(static_cast<int>(invoke_type)));
-  // Insert the method_idx
-  args.push_back(irb_->getInt32(info->index));
-  // Insert the optimization flags
-  args.push_back(irb_->getInt32(info->opt_flags));
-  // Now, insert the actual arguments
-  for (int i = 0; i < info->num_arg_words;) {
-    ::llvm::Value* val = GetLLVMValue(info->args[i].orig_sreg);
-    args.push_back(val);
-    i += info->args[i].wide ? 2 : 1;
-  }
-  /*
-   * Choose the invoke return type based on actual usage.  Note: may
-   * be different than shorty.  For example, if a function return value
-   * is not used, we'll treat this as a void invoke.
-   */
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  if (is_filled_new_array) {
-    id = art::llvm::IntrinsicHelper::HLFilledNewArray;
-  } else if (info->result.location == kLocInvalid) {
-    id = art::llvm::IntrinsicHelper::HLInvokeVoid;
-  } else {
-    if (info->result.wide) {
-      if (info->result.fp) {
-        id = art::llvm::IntrinsicHelper::HLInvokeDouble;
-      } else {
-        id = art::llvm::IntrinsicHelper::HLInvokeLong;
-      }
-    } else if (info->result.ref) {
-        id = art::llvm::IntrinsicHelper::HLInvokeObj;
-    } else if (info->result.fp) {
-        id = art::llvm::IntrinsicHelper::HLInvokeFloat;
-    } else {
-        id = art::llvm::IntrinsicHelper::HLInvokeInt;
-    }
-  }
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  if (info->result.location != kLocInvalid) {
-    DefineValue(res, info->result.orig_sreg);
-  }
-}
-
-void MirConverter::ConvertConstObject(uint32_t idx,
-                               art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest) {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* index = irb_->getInt32(idx);
-  ::llvm::Value* res = irb_->CreateCall(intr, index);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertCheckCast(uint32_t type_idx, RegLocation rl_src) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  id = art::llvm::IntrinsicHelper::HLCheckCast;
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(type_idx));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  irb_->CreateCall(intr, args);
-}
-
-void MirConverter::ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  id = art::llvm::IntrinsicHelper::NewInstance;
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* index = irb_->getInt32(type_idx);
-  ::llvm::Value* res = irb_->CreateCall(intr, index);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertNewArray(uint32_t type_idx,
-                            RegLocation rl_dest, RegLocation rl_src) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  id = art::llvm::IntrinsicHelper::NewArray;
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(type_idx));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertAget(int opt_flags,
-                        art::llvm::IntrinsicHelper::IntrinsicId id,
-                        RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index) {
-  ::llvm::SmallVector< ::llvm::Value*, 3> args;
-  args.push_back(irb_->getInt32(opt_flags));
-  args.push_back(GetLLVMValue(rl_array.orig_sreg));
-  args.push_back(GetLLVMValue(rl_index.orig_sreg));
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertAput(int opt_flags,
-                        art::llvm::IntrinsicHelper::IntrinsicId id,
-                        RegLocation rl_src, RegLocation rl_array, RegLocation rl_index) {
-  ::llvm::SmallVector< ::llvm::Value*, 4> args;
-  args.push_back(irb_->getInt32(opt_flags));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  args.push_back(GetLLVMValue(rl_array.orig_sreg));
-  args.push_back(GetLLVMValue(rl_index.orig_sreg));
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  irb_->CreateCall(intr, args);
-}
-
-void MirConverter::ConvertIget(int opt_flags,
-                        art::llvm::IntrinsicHelper::IntrinsicId id,
-                        RegLocation rl_dest, RegLocation rl_obj, int field_index) {
-  ::llvm::SmallVector< ::llvm::Value*, 3> args;
-  args.push_back(irb_->getInt32(opt_flags));
-  args.push_back(GetLLVMValue(rl_obj.orig_sreg));
-  args.push_back(irb_->getInt32(field_index));
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertIput(int opt_flags,
-                        art::llvm::IntrinsicHelper::IntrinsicId id,
-                        RegLocation rl_src, RegLocation rl_obj, int field_index) {
-  ::llvm::SmallVector< ::llvm::Value*, 4> args;
-  args.push_back(irb_->getInt32(opt_flags));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  args.push_back(GetLLVMValue(rl_obj.orig_sreg));
-  args.push_back(irb_->getInt32(field_index));
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  irb_->CreateCall(intr, args);
-}
-
-void MirConverter::ConvertInstanceOf(uint32_t type_idx,
-                              RegLocation rl_dest, RegLocation rl_src) {
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  id = art::llvm::IntrinsicHelper::InstanceOf;
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(irb_->getInt32(type_idx));
-  args.push_back(GetLLVMValue(rl_src.orig_sreg));
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* res = irb_->CreateSExt(GetLLVMValue(rl_src.orig_sreg),
-                                            irb_->getInt64Ty());
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
-  ::llvm::Value* res = irb_->CreateTrunc(src, irb_->getInt32Ty());
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
-  ::llvm::Value* res = irb_->CreateFPExt(src, irb_->getDoubleTy());
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
-  ::llvm::Value* res = irb_->CreateFPTrunc(src, irb_->getFloatTy());
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
-                                         RegLocation rl_dest, RegLocation rl_src1,
-                                         RegLocation rl_src2) {
-  DCHECK_EQ(rl_src1.fp, rl_src2.fp);
-  DCHECK_EQ(rl_src1.wide, rl_src2.wide);
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::SmallVector< ::llvm::Value*, 2> args;
-  args.push_back(GetLLVMValue(rl_src1.orig_sreg));
-  args.push_back(GetLLVMValue(rl_src2.orig_sreg));
-  ::llvm::Value* res = irb_->CreateCall(intr, args);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
-                                art::llvm::IntrinsicHelper::IntrinsicId id) {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* res =
-      irb_->CreateCall(intr, GetLLVMValue(rl_src.orig_sreg));
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertNeg(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* res = irb_->CreateNeg(GetLLVMValue(rl_src.orig_sreg));
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest,
-                           RegLocation rl_src) {
-  ::llvm::Value* res =
-      irb_->CreateSIToFP(GetLLVMValue(rl_src.orig_sreg), ty);
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
-                           RegLocation rl_dest,
-                    RegLocation rl_src) {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Value* res = irb_->CreateCall(intr, GetLLVMValue(rl_src.orig_sreg));
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-
-void MirConverter::ConvertNegFP(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* res =
-      irb_->CreateFNeg(GetLLVMValue(rl_src.orig_sreg));
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::ConvertNot(RegLocation rl_dest, RegLocation rl_src) {
-  ::llvm::Value* src = GetLLVMValue(rl_src.orig_sreg);
-  ::llvm::Value* res = irb_->CreateXor(src, static_cast<uint64_t>(-1));
-  DefineValue(res, rl_dest.orig_sreg);
-}
-
-void MirConverter::EmitConstructorBarrier() {
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
-      art::llvm::IntrinsicHelper::ConstructorBarrier);
-  irb_->CreateCall(intr);
-}
-
-/*
- * Target-independent code generation.  Use only high-level
- * load/store utilities here, or target-dependent genXX() handlers
- * when necessary.
- */
-bool MirConverter::ConvertMIRNode(MIR* mir, BasicBlock* bb,
-                           ::llvm::BasicBlock* llvm_bb) {
-  bool res = false;   // Assume success
-  RegLocation rl_src[3];
-  RegLocation rl_dest = mir_graph_->GetBadLoc();
-  Instruction::Code opcode = mir->dalvikInsn.opcode;
-  int op_val = opcode;
-  uint32_t vB = mir->dalvikInsn.vB;
-  uint32_t vC = mir->dalvikInsn.vC;
-  int opt_flags = mir->optimization_flags;
-
-  if (cu_->verbose) {
-    if (!IsPseudoMirOp(op_val)) {
-      LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
-    } else {
-      LOG(INFO) << mir_graph_->extended_mir_op_names_[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
-    }
-  }
-
-  /* Prep Src and Dest locations */
-  int next_sreg = 0;
-  int next_loc = 0;
-  uint64_t attrs = MirGraph::GetDataFlowAttributes(opcode);
-  rl_src[0] = rl_src[1] = rl_src[2] = mir_graph_->GetBadLoc();
-  if (attrs & DF_UA) {
-    if (attrs & DF_A_WIDE) {
-      rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
-      next_sreg+= 2;
-    } else {
-      rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
-      next_sreg++;
-    }
-  }
-  if (attrs & DF_UB) {
-    if (attrs & DF_B_WIDE) {
-      rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
-      next_sreg+= 2;
-    } else {
-      rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
-      next_sreg++;
-    }
-  }
-  if (attrs & DF_UC) {
-    if (attrs & DF_C_WIDE) {
-      rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
-    } else {
-      rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
-    }
-  }
-  if (attrs & DF_DA) {
-    if (attrs & DF_A_WIDE) {
-      rl_dest = mir_graph_->GetDestWide(mir);
-    } else {
-      rl_dest = mir_graph_->GetDest(mir);
-    }
-  }
-
-  switch (opcode) {
-    case Instruction::NOP:
-      break;
-
-    case Instruction::MOVE:
-    case Instruction::MOVE_OBJECT:
-    case Instruction::MOVE_16:
-    case Instruction::MOVE_OBJECT_16:
-    case Instruction::MOVE_OBJECT_FROM16:
-    case Instruction::MOVE_FROM16:
-    case Instruction::MOVE_WIDE:
-    case Instruction::MOVE_WIDE_16:
-    case Instruction::MOVE_WIDE_FROM16: {
-        /*
-         * Moves/copies are meaningless in pure SSA register form,
-         * but we need to preserve them for the conversion back into
-         * MIR (at least until we stop using the Dalvik register maps).
-         * Insert a dummy intrinsic copy call, which will be recognized
-         * by the quick path and removed by the portable path.
-         */
-        ::llvm::Value* src = GetLLVMValue(rl_src[0].orig_sreg);
-        ::llvm::Value* res = EmitCopy(src, rl_dest);
-        DefineValue(res, rl_dest.orig_sreg);
-      }
-      break;
-
-    case Instruction::CONST:
-    case Instruction::CONST_4:
-    case Instruction::CONST_16: {
-        ::llvm::Constant* imm_value = irb_->getJInt(vB);
-        ::llvm::Value* res = EmitConst(imm_value, rl_dest);
-        DefineValue(res, rl_dest.orig_sreg);
-      }
-      break;
-
-    case Instruction::CONST_WIDE_16:
-    case Instruction::CONST_WIDE_32: {
-        // Sign extend to 64 bits
-        int64_t imm = static_cast<int32_t>(vB);
-        ::llvm::Constant* imm_value = irb_->getJLong(imm);
-        ::llvm::Value* res = EmitConst(imm_value, rl_dest);
-        DefineValue(res, rl_dest.orig_sreg);
-      }
-      break;
-
-    case Instruction::CONST_HIGH16: {
-        ::llvm::Constant* imm_value = irb_->getJInt(vB << 16);
-        ::llvm::Value* res = EmitConst(imm_value, rl_dest);
-        DefineValue(res, rl_dest.orig_sreg);
-      }
-      break;
-
-    case Instruction::CONST_WIDE: {
-        ::llvm::Constant* imm_value =
-            irb_->getJLong(mir->dalvikInsn.vB_wide);
-        ::llvm::Value* res = EmitConst(imm_value, rl_dest);
-        DefineValue(res, rl_dest.orig_sreg);
-      }
-      break;
-    case Instruction::CONST_WIDE_HIGH16: {
-        int64_t imm = static_cast<int64_t>(vB) << 48;
-        ::llvm::Constant* imm_value = irb_->getJLong(imm);
-        ::llvm::Value* res = EmitConst(imm_value, rl_dest);
-        DefineValue(res, rl_dest.orig_sreg);
-      }
-      break;
-
-    case Instruction::SPUT_OBJECT:
-      ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputObject,
-                  rl_src[0]);
-      break;
-    case Instruction::SPUT:
-      if (rl_src[0].fp) {
-        ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputFloat,
-                    rl_src[0]);
-      } else {
-        ConvertSput(vB, art::llvm::IntrinsicHelper::HLSput, rl_src[0]);
-      }
-      break;
-    case Instruction::SPUT_BOOLEAN:
-      ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputBoolean,
-                  rl_src[0]);
-      break;
-    case Instruction::SPUT_BYTE:
-      ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputByte, rl_src[0]);
-      break;
-    case Instruction::SPUT_CHAR:
-      ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputChar, rl_src[0]);
-      break;
-    case Instruction::SPUT_SHORT:
-      ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputShort, rl_src[0]);
-      break;
-    case Instruction::SPUT_WIDE:
-      if (rl_src[0].fp) {
-        ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputDouble,
-                    rl_src[0]);
-      } else {
-        ConvertSput(vB, art::llvm::IntrinsicHelper::HLSputWide,
-                    rl_src[0]);
-      }
-      break;
-
-    case Instruction::SGET_OBJECT:
-      ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetObject, rl_dest);
-      break;
-    case Instruction::SGET:
-      if (rl_dest.fp) {
-        ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetFloat, rl_dest);
-      } else {
-        ConvertSget(vB, art::llvm::IntrinsicHelper::HLSget, rl_dest);
-      }
-      break;
-    case Instruction::SGET_BOOLEAN:
-      ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetBoolean, rl_dest);
-      break;
-    case Instruction::SGET_BYTE:
-      ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetByte, rl_dest);
-      break;
-    case Instruction::SGET_CHAR:
-      ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetChar, rl_dest);
-      break;
-    case Instruction::SGET_SHORT:
-      ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetShort, rl_dest);
-      break;
-    case Instruction::SGET_WIDE:
-      if (rl_dest.fp) {
-        ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetDouble,
-                    rl_dest);
-      } else {
-        ConvertSget(vB, art::llvm::IntrinsicHelper::HLSgetWide, rl_dest);
-      }
-      break;
-
-    case Instruction::RETURN_WIDE:
-    case Instruction::RETURN:
-    case Instruction::RETURN_OBJECT: {
-        if (!mir_graph_->MethodIsLeaf()) {
-          EmitSuspendCheck();
-        }
-        EmitPopShadowFrame();
-        irb_->CreateRet(GetLLVMValue(rl_src[0].orig_sreg));
-        DCHECK(bb->terminated_by_return);
-      }
-      break;
-
-    case Instruction::RETURN_VOID: {
-        if (((cu_->access_flags & kAccConstructor) != 0) &&
-            cu_->compiler_driver->RequiresConstructorBarrier(Thread::Current(),
-                                                            cu_->dex_file,
-                                                            cu_->class_def_idx)) {
-          EmitConstructorBarrier();
-        }
-        if (!mir_graph_->MethodIsLeaf()) {
-          EmitSuspendCheck();
-        }
-        EmitPopShadowFrame();
-        irb_->CreateRetVoid();
-        DCHECK(bb->terminated_by_return);
-      }
-      break;
-
-    case Instruction::IF_EQ:
-      ConvertCompareAndBranch(bb, mir, kCondEq, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::IF_NE:
-      ConvertCompareAndBranch(bb, mir, kCondNe, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::IF_LT:
-      ConvertCompareAndBranch(bb, mir, kCondLt, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::IF_GE:
-      ConvertCompareAndBranch(bb, mir, kCondGe, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::IF_GT:
-      ConvertCompareAndBranch(bb, mir, kCondGt, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::IF_LE:
-      ConvertCompareAndBranch(bb, mir, kCondLe, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::IF_EQZ:
-      ConvertCompareZeroAndBranch(bb, mir, kCondEq, rl_src[0]);
-      break;
-    case Instruction::IF_NEZ:
-      ConvertCompareZeroAndBranch(bb, mir, kCondNe, rl_src[0]);
-      break;
-    case Instruction::IF_LTZ:
-      ConvertCompareZeroAndBranch(bb, mir, kCondLt, rl_src[0]);
-      break;
-    case Instruction::IF_GEZ:
-      ConvertCompareZeroAndBranch(bb, mir, kCondGe, rl_src[0]);
-      break;
-    case Instruction::IF_GTZ:
-      ConvertCompareZeroAndBranch(bb, mir, kCondGt, rl_src[0]);
-      break;
-    case Instruction::IF_LEZ:
-      ConvertCompareZeroAndBranch(bb, mir, kCondLe, rl_src[0]);
-      break;
-
-    case Instruction::GOTO:
-    case Instruction::GOTO_16:
-    case Instruction::GOTO_32: {
-        if (mir_graph_->GetBasicBlock(bb->taken)->start_offset <= bb->start_offset) {
-          EmitSuspendCheck();
-        }
-        irb_->CreateBr(GetLLVMBlock(bb->taken));
-      }
-      break;
-
-    case Instruction::ADD_LONG:
-    case Instruction::ADD_LONG_2ADDR:
-    case Instruction::ADD_INT:
-    case Instruction::ADD_INT_2ADDR:
-      ConvertArithOp(kOpAdd, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::SUB_LONG:
-    case Instruction::SUB_LONG_2ADDR:
-    case Instruction::SUB_INT:
-    case Instruction::SUB_INT_2ADDR:
-      ConvertArithOp(kOpSub, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::MUL_LONG:
-    case Instruction::MUL_LONG_2ADDR:
-    case Instruction::MUL_INT:
-    case Instruction::MUL_INT_2ADDR:
-      ConvertArithOp(kOpMul, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::DIV_LONG:
-    case Instruction::DIV_LONG_2ADDR:
-    case Instruction::DIV_INT:
-    case Instruction::DIV_INT_2ADDR:
-      ConvertArithOp(kOpDiv, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::REM_LONG:
-    case Instruction::REM_LONG_2ADDR:
-    case Instruction::REM_INT:
-    case Instruction::REM_INT_2ADDR:
-      ConvertArithOp(kOpRem, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::AND_LONG:
-    case Instruction::AND_LONG_2ADDR:
-    case Instruction::AND_INT:
-    case Instruction::AND_INT_2ADDR:
-      ConvertArithOp(kOpAnd, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::OR_LONG:
-    case Instruction::OR_LONG_2ADDR:
-    case Instruction::OR_INT:
-    case Instruction::OR_INT_2ADDR:
-      ConvertArithOp(kOpOr, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::XOR_LONG:
-    case Instruction::XOR_LONG_2ADDR:
-    case Instruction::XOR_INT:
-    case Instruction::XOR_INT_2ADDR:
-      ConvertArithOp(kOpXor, rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::SHL_LONG:
-    case Instruction::SHL_LONG_2ADDR:
-      ConvertShift(art::llvm::IntrinsicHelper::SHLLong,
-                    rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::SHL_INT:
-    case Instruction::SHL_INT_2ADDR:
-      ConvertShift(art::llvm::IntrinsicHelper::SHLInt,
-                   rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::SHR_LONG:
-    case Instruction::SHR_LONG_2ADDR:
-      ConvertShift(art::llvm::IntrinsicHelper::SHRLong,
-                   rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::SHR_INT:
-    case Instruction::SHR_INT_2ADDR:
-      ConvertShift(art::llvm::IntrinsicHelper::SHRInt,
-                   rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::USHR_LONG:
-    case Instruction::USHR_LONG_2ADDR:
-      ConvertShift(art::llvm::IntrinsicHelper::USHRLong,
-                   rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::USHR_INT:
-    case Instruction::USHR_INT_2ADDR:
-      ConvertShift(art::llvm::IntrinsicHelper::USHRInt,
-                   rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::ADD_INT_LIT16:
-    case Instruction::ADD_INT_LIT8:
-      ConvertArithOpLit(kOpAdd, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::RSUB_INT:
-    case Instruction::RSUB_INT_LIT8:
-      ConvertArithOpLit(kOpRsub, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::MUL_INT_LIT16:
-    case Instruction::MUL_INT_LIT8:
-      ConvertArithOpLit(kOpMul, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::DIV_INT_LIT16:
-    case Instruction::DIV_INT_LIT8:
-      ConvertArithOpLit(kOpDiv, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::REM_INT_LIT16:
-    case Instruction::REM_INT_LIT8:
-      ConvertArithOpLit(kOpRem, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::AND_INT_LIT16:
-    case Instruction::AND_INT_LIT8:
-      ConvertArithOpLit(kOpAnd, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::OR_INT_LIT16:
-    case Instruction::OR_INT_LIT8:
-      ConvertArithOpLit(kOpOr, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::XOR_INT_LIT16:
-    case Instruction::XOR_INT_LIT8:
-      ConvertArithOpLit(kOpXor, rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::SHL_INT_LIT8:
-      ConvertShiftLit(art::llvm::IntrinsicHelper::SHLInt,
-                      rl_dest, rl_src[0], vC & 0x1f);
-      break;
-    case Instruction::SHR_INT_LIT8:
-      ConvertShiftLit(art::llvm::IntrinsicHelper::SHRInt,
-                      rl_dest, rl_src[0], vC & 0x1f);
-      break;
-    case Instruction::USHR_INT_LIT8:
-      ConvertShiftLit(art::llvm::IntrinsicHelper::USHRInt,
-                      rl_dest, rl_src[0], vC & 0x1f);
-      break;
-
-    case Instruction::ADD_FLOAT:
-    case Instruction::ADD_FLOAT_2ADDR:
-    case Instruction::ADD_DOUBLE:
-    case Instruction::ADD_DOUBLE_2ADDR:
-      ConvertFPArithOp(kOpAdd, rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::SUB_FLOAT:
-    case Instruction::SUB_FLOAT_2ADDR:
-    case Instruction::SUB_DOUBLE:
-    case Instruction::SUB_DOUBLE_2ADDR:
-      ConvertFPArithOp(kOpSub, rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::MUL_FLOAT:
-    case Instruction::MUL_FLOAT_2ADDR:
-    case Instruction::MUL_DOUBLE:
-    case Instruction::MUL_DOUBLE_2ADDR:
-      ConvertFPArithOp(kOpMul, rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::DIV_FLOAT:
-    case Instruction::DIV_FLOAT_2ADDR:
-    case Instruction::DIV_DOUBLE:
-    case Instruction::DIV_DOUBLE_2ADDR:
-      ConvertFPArithOp(kOpDiv, rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::REM_FLOAT:
-    case Instruction::REM_FLOAT_2ADDR:
-    case Instruction::REM_DOUBLE:
-    case Instruction::REM_DOUBLE_2ADDR:
-      ConvertFPArithOp(kOpRem, rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::INVOKE_STATIC:
-      ConvertInvoke(bb, mir, kStatic, false /*range*/,
-                    false /* NewFilledArray */);
-      break;
-    case Instruction::INVOKE_STATIC_RANGE:
-      ConvertInvoke(bb, mir, kStatic, true /*range*/,
-                    false /* NewFilledArray */);
-      break;
-
-    case Instruction::INVOKE_DIRECT:
-      ConvertInvoke(bb,  mir, kDirect, false /*range*/,
-                    false /* NewFilledArray */);
-      break;
-    case Instruction::INVOKE_DIRECT_RANGE:
-      ConvertInvoke(bb, mir, kDirect, true /*range*/,
-                    false /* NewFilledArray */);
-      break;
-
-    case Instruction::INVOKE_VIRTUAL:
-      ConvertInvoke(bb, mir, kVirtual, false /*range*/,
-                    false /* NewFilledArray */);
-      break;
-    case Instruction::INVOKE_VIRTUAL_RANGE:
-      ConvertInvoke(bb, mir, kVirtual, true /*range*/,
-                    false /* NewFilledArray */);
-      break;
-
-    case Instruction::INVOKE_SUPER:
-      ConvertInvoke(bb, mir, kSuper, false /*range*/,
-                    false /* NewFilledArray */);
-      break;
-    case Instruction::INVOKE_SUPER_RANGE:
-      ConvertInvoke(bb, mir, kSuper, true /*range*/,
-                    false /* NewFilledArray */);
-      break;
-
-    case Instruction::INVOKE_INTERFACE:
-      ConvertInvoke(bb, mir, kInterface, false /*range*/,
-                    false /* NewFilledArray */);
-      break;
-    case Instruction::INVOKE_INTERFACE_RANGE:
-      ConvertInvoke(bb, mir, kInterface, true /*range*/,
-                    false /* NewFilledArray */);
-      break;
-    case Instruction::FILLED_NEW_ARRAY:
-      ConvertInvoke(bb, mir, kInterface, false /*range*/,
-                    true /* NewFilledArray */);
-      break;
-    case Instruction::FILLED_NEW_ARRAY_RANGE:
-      ConvertInvoke(bb, mir, kInterface, true /*range*/,
-                    true /* NewFilledArray */);
-      break;
-
-    case Instruction::CONST_STRING:
-    case Instruction::CONST_STRING_JUMBO:
-      ConvertConstObject(vB, art::llvm::IntrinsicHelper::ConstString,
-                         rl_dest);
-      break;
-
-    case Instruction::CONST_CLASS:
-      ConvertConstObject(vB, art::llvm::IntrinsicHelper::ConstClass,
-                         rl_dest);
-      break;
-
-    case Instruction::CHECK_CAST:
-      ConvertCheckCast(vB, rl_src[0]);
-      break;
-
-    case Instruction::NEW_INSTANCE:
-      ConvertNewInstance(vB, rl_dest);
-      break;
-
-    case Instruction::MOVE_EXCEPTION:
-      ConvertMoveException(rl_dest);
-      break;
-
-    case Instruction::THROW:
-      ConvertThrow(rl_src[0]);
-      /*
-       * If this throw is standalone, terminate.
-       * If it might rethrow, force termination
-       * of the following block.
-       */
-      if (bb->fall_through == NullBasicBlockId) {
-        irb_->CreateUnreachable();
-      } else {
-        mir_graph_->GetBasicBlock(bb->fall_through)->fall_through = NullBasicBlockId;
-        mir_graph_->GetBasicBlock(bb->fall_through)->taken = NullBasicBlockId;
-      }
-      break;
-
-    case Instruction::MOVE_RESULT_WIDE:
-    case Instruction::MOVE_RESULT:
-    case Instruction::MOVE_RESULT_OBJECT:
-      /*
-       * All move_results should have been folded into the preceeding invoke.
-       */
-      LOG(FATAL) << "Unexpected move_result";
-      break;
-
-    case Instruction::MONITOR_ENTER:
-      ConvertMonitorEnterExit(opt_flags,
-                              art::llvm::IntrinsicHelper::MonitorEnter,
-                              rl_src[0]);
-      break;
-
-    case Instruction::MONITOR_EXIT:
-      ConvertMonitorEnterExit(opt_flags,
-                              art::llvm::IntrinsicHelper::MonitorExit,
-                              rl_src[0]);
-      break;
-
-    case Instruction::ARRAY_LENGTH:
-      ConvertArrayLength(opt_flags, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::NEW_ARRAY:
-      ConvertNewArray(vC, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::INSTANCE_OF:
-      ConvertInstanceOf(vC, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::AGET:
-      if (rl_dest.fp) {
-        ConvertAget(opt_flags,
-                    art::llvm::IntrinsicHelper::HLArrayGetFloat,
-                    rl_dest, rl_src[0], rl_src[1]);
-      } else {
-        ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGet,
-                    rl_dest, rl_src[0], rl_src[1]);
-      }
-      break;
-    case Instruction::AGET_OBJECT:
-      ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetObject,
-                  rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::AGET_BOOLEAN:
-      ConvertAget(opt_flags,
-                  art::llvm::IntrinsicHelper::HLArrayGetBoolean,
-                  rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::AGET_BYTE:
-      ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetByte,
-                  rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::AGET_CHAR:
-      ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetChar,
-                  rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::AGET_SHORT:
-      ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetShort,
-                  rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::AGET_WIDE:
-      if (rl_dest.fp) {
-        ConvertAget(opt_flags,
-                    art::llvm::IntrinsicHelper::HLArrayGetDouble,
-                    rl_dest, rl_src[0], rl_src[1]);
-      } else {
-        ConvertAget(opt_flags, art::llvm::IntrinsicHelper::HLArrayGetWide,
-                    rl_dest, rl_src[0], rl_src[1]);
-      }
-      break;
-
-    case Instruction::APUT:
-      if (rl_src[0].fp) {
-        ConvertAput(opt_flags,
-                    art::llvm::IntrinsicHelper::HLArrayPutFloat,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      } else {
-        ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPut,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      }
-      break;
-    case Instruction::APUT_OBJECT:
-      ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutObject,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      break;
-    case Instruction::APUT_BOOLEAN:
-      ConvertAput(opt_flags,
-                  art::llvm::IntrinsicHelper::HLArrayPutBoolean,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      break;
-    case Instruction::APUT_BYTE:
-      ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutByte,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      break;
-    case Instruction::APUT_CHAR:
-      ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutChar,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      break;
-    case Instruction::APUT_SHORT:
-      ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutShort,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      break;
-    case Instruction::APUT_WIDE:
-      if (rl_src[0].fp) {
-        ConvertAput(opt_flags,
-                    art::llvm::IntrinsicHelper::HLArrayPutDouble,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      } else {
-        ConvertAput(opt_flags, art::llvm::IntrinsicHelper::HLArrayPutWide,
-                    rl_src[0], rl_src[1], rl_src[2]);
-      }
-      break;
-
-    case Instruction::IGET:
-      if (rl_dest.fp) {
-        ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetFloat,
-                    rl_dest, rl_src[0], vC);
-      } else {
-        ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGet,
-                    rl_dest, rl_src[0], vC);
-      }
-      break;
-    case Instruction::IGET_OBJECT:
-      ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetObject,
-                  rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::IGET_BOOLEAN:
-      ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetBoolean,
-                  rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::IGET_BYTE:
-      ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetByte,
-                  rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::IGET_CHAR:
-      ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetChar,
-                  rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::IGET_SHORT:
-      ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetShort,
-                  rl_dest, rl_src[0], vC);
-      break;
-    case Instruction::IGET_WIDE:
-      if (rl_dest.fp) {
-        ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetDouble,
-                    rl_dest, rl_src[0], vC);
-      } else {
-        ConvertIget(opt_flags, art::llvm::IntrinsicHelper::HLIGetWide,
-                    rl_dest, rl_src[0], vC);
-      }
-      break;
-    case Instruction::IPUT:
-      if (rl_src[0].fp) {
-        ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutFloat,
-                    rl_src[0], rl_src[1], vC);
-      } else {
-        ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPut,
-                    rl_src[0], rl_src[1], vC);
-      }
-      break;
-    case Instruction::IPUT_OBJECT:
-      ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutObject,
-                  rl_src[0], rl_src[1], vC);
-      break;
-    case Instruction::IPUT_BOOLEAN:
-      ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutBoolean,
-                  rl_src[0], rl_src[1], vC);
-      break;
-    case Instruction::IPUT_BYTE:
-      ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutByte,
-                  rl_src[0], rl_src[1], vC);
-      break;
-    case Instruction::IPUT_CHAR:
-      ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutChar,
-                  rl_src[0], rl_src[1], vC);
-      break;
-    case Instruction::IPUT_SHORT:
-      ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutShort,
-                  rl_src[0], rl_src[1], vC);
-      break;
-    case Instruction::IPUT_WIDE:
-      if (rl_src[0].fp) {
-        ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutDouble,
-                    rl_src[0], rl_src[1], vC);
-      } else {
-        ConvertIput(opt_flags, art::llvm::IntrinsicHelper::HLIPutWide,
-                    rl_src[0], rl_src[1], vC);
-      }
-      break;
-
-    case Instruction::FILL_ARRAY_DATA:
-      ConvertFillArrayData(vB, rl_src[0]);
-      break;
-
-    case Instruction::LONG_TO_INT:
-      ConvertLongToInt(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::INT_TO_LONG:
-      ConvertIntToLong(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::INT_TO_CHAR:
-      ConvertIntNarrowing(rl_dest, rl_src[0],
-                          art::llvm::IntrinsicHelper::IntToChar);
-      break;
-    case Instruction::INT_TO_BYTE:
-      ConvertIntNarrowing(rl_dest, rl_src[0],
-                          art::llvm::IntrinsicHelper::IntToByte);
-      break;
-    case Instruction::INT_TO_SHORT:
-      ConvertIntNarrowing(rl_dest, rl_src[0],
-                          art::llvm::IntrinsicHelper::IntToShort);
-      break;
-
-    case Instruction::INT_TO_FLOAT:
-    case Instruction::LONG_TO_FLOAT:
-      ConvertIntToFP(irb_->getFloatTy(), rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::INT_TO_DOUBLE:
-    case Instruction::LONG_TO_DOUBLE:
-      ConvertIntToFP(irb_->getDoubleTy(), rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::FLOAT_TO_DOUBLE:
-      ConvertFloatToDouble(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::DOUBLE_TO_FLOAT:
-      ConvertDoubleToFloat(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::NEG_LONG:
-    case Instruction::NEG_INT:
-      ConvertNeg(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::NEG_FLOAT:
-    case Instruction::NEG_DOUBLE:
-      ConvertNegFP(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::NOT_LONG:
-    case Instruction::NOT_INT:
-      ConvertNot(rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::FLOAT_TO_INT:
-      ConvertFPToInt(art::llvm::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::DOUBLE_TO_INT:
-      ConvertFPToInt(art::llvm::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::FLOAT_TO_LONG:
-      ConvertFPToInt(art::llvm::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::DOUBLE_TO_LONG:
-      ConvertFPToInt(art::llvm::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
-      break;
-
-    case Instruction::CMPL_FLOAT:
-      ConvertWideComparison(art::llvm::IntrinsicHelper::CmplFloat,
-                            rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::CMPG_FLOAT:
-      ConvertWideComparison(art::llvm::IntrinsicHelper::CmpgFloat,
-                            rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::CMPL_DOUBLE:
-      ConvertWideComparison(art::llvm::IntrinsicHelper::CmplDouble,
-                            rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::CMPG_DOUBLE:
-      ConvertWideComparison(art::llvm::IntrinsicHelper::CmpgDouble,
-                            rl_dest, rl_src[0], rl_src[1]);
-      break;
-    case Instruction::CMP_LONG:
-      ConvertWideComparison(art::llvm::IntrinsicHelper::CmpLong,
-                            rl_dest, rl_src[0], rl_src[1]);
-      break;
-
-    case Instruction::PACKED_SWITCH:
-      ConvertPackedSwitch(bb, vB, rl_src[0]);
-      break;
-
-    case Instruction::SPARSE_SWITCH:
-      ConvertSparseSwitch(bb, vB, rl_src[0]);
-      break;
-
-    default:
-      UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
-      res = true;
-  }
-  return res;
-}  // NOLINT(readability/fn_size)
-
-void MirConverter::SetDexOffset(int32_t offset) {
-  current_dalvik_offset_ = offset;
-  ::llvm::SmallVector< ::llvm::Value*, 1> array_ref;
-  array_ref.push_back(irb_->getInt32(offset));
-  ::llvm::MDNode* node = ::llvm::MDNode::get(*context_, array_ref);
-  irb_->SetDexOffset(node);
-}
-
-// Attach method info as metadata to special intrinsic
-void MirConverter::SetMethodInfo() {
-  // We don't want dex offset on this
-  irb_->SetDexOffset(NULL);
-  art::llvm::IntrinsicHelper::IntrinsicId id;
-  id = art::llvm::IntrinsicHelper::MethodInfo;
-  ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(id);
-  ::llvm::Instruction* inst = irb_->CreateCall(intr);
-  ::llvm::SmallVector< ::llvm::Value*, 2> reg_info;
-  reg_info.push_back(irb_->getInt32(mir_graph_->GetNumOfInVRs()));
-  reg_info.push_back(irb_->getInt32(mir_graph_->GetNumOfLocalCodeVRs()));
-  reg_info.push_back(irb_->getInt32(mir_graph_->GetNumOfOutVRs()));
-  reg_info.push_back(irb_->getInt32(mir_graph_->GetNumUsedCompilerTemps()));
-  reg_info.push_back(irb_->getInt32(mir_graph_->GetNumSSARegs()));
-  ::llvm::MDNode* reg_info_node = ::llvm::MDNode::get(*context_, reg_info);
-  inst->setMetadata("RegInfo", reg_info_node);
-  SetDexOffset(current_dalvik_offset_);
-}
-
-void MirConverter::HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb) {
-  SetDexOffset(bb->start_offset);
-  for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
-    int opcode = mir->dalvikInsn.opcode;
-    if (!IsPseudoMirOp(opcode)) {
-      // Stop after first non-pseudo MIR op.
-      continue;
-    }
-    if (opcode != kMirOpPhi) {
-      // Skip other mir Pseudos.
-      continue;
-    }
-    RegLocation rl_dest = mir_graph_->reg_location_[mir->ssa_rep->defs[0]];
-    /*
-     * The Art compiler's Phi nodes only handle 32-bit operands,
-     * representing wide values using a matched set of Phi nodes
-     * for the lower and upper halves.  In the llvm world, we only
-     * want a single Phi for wides.  Here we will simply discard
-     * the Phi node representing the high word.
-     */
-    if (rl_dest.high_word) {
-      continue;  // No Phi node - handled via low word
-    }
-    BasicBlockId* incoming = mir->meta.phi_incoming;
-    ::llvm::Type* phi_type =
-        LlvmTypeFromLocRec(rl_dest);
-    ::llvm::PHINode* phi = irb_->CreatePHI(phi_type, mir->ssa_rep->num_uses);
-    for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
-      RegLocation loc;
-      // Don't check width here.
-      loc = mir_graph_->GetRawSrc(mir, i);
-      DCHECK_EQ(rl_dest.wide, loc.wide);
-      DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
-      DCHECK_EQ(rl_dest.fp, loc.fp);
-      DCHECK_EQ(rl_dest.core, loc.core);
-      DCHECK_EQ(rl_dest.ref, loc.ref);
-      SafeMap<unsigned int, unsigned int>::iterator it;
-      it = mir_graph_->block_id_map_.find(incoming[i]);
-      DCHECK(it != mir_graph_->block_id_map_.end());
-      DCHECK(GetLLVMValue(loc.orig_sreg) != NULL);
-      DCHECK(GetLLVMBlock(it->second) != NULL);
-      phi->addIncoming(GetLLVMValue(loc.orig_sreg),
-                       GetLLVMBlock(it->second));
-    }
-    DefineValueOnly(phi, rl_dest.orig_sreg);
-  }
-}
-
-/* Extended MIR instructions like PHI */
-void MirConverter::ConvertExtendedMIR(BasicBlock* bb, MIR* mir,
-                                      ::llvm::BasicBlock* llvm_bb) {
-  switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
-    case kMirOpPhi: {
-      // The llvm Phi node already emitted - just DefineValue() here.
-      RegLocation rl_dest = mir_graph_->reg_location_[mir->ssa_rep->defs[0]];
-      if (!rl_dest.high_word) {
-        // Only consider low word of pairs.
-        DCHECK(GetLLVMValue(rl_dest.orig_sreg) != NULL);
-        ::llvm::Value* phi = GetLLVMValue(rl_dest.orig_sreg);
-        if (1) SetVregOnValue(phi, rl_dest.orig_sreg);
-      }
-      break;
-    }
-    case kMirOpCopy: {
-      UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
-      break;
-    }
-    case kMirOpNop:
-      if ((mir == bb->last_mir_insn) && (bb->taken == NullBasicBlockId) &&
-          (bb->fall_through == NullBasicBlockId)) {
-        irb_->CreateUnreachable();
-      }
-      break;
-
-    // TODO: need GBC intrinsic to take advantage of fused operations
-    case kMirOpFusedCmplFloat:
-      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
-      break;
-    case kMirOpFusedCmpgFloat:
-      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
-      break;
-    case kMirOpFusedCmplDouble:
-      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
-      break;
-    case kMirOpFusedCmpgDouble:
-      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
-      break;
-    case kMirOpFusedCmpLong:
-      UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
-      break;
-    default:
-      break;
-  }
-}
-
-/* Handle the content in each basic block */
-bool MirConverter::BlockBitcodeConversion(BasicBlock* bb) {
-  if (bb->block_type == kDead) return false;
-  ::llvm::BasicBlock* llvm_bb = GetLLVMBlock(bb->id);
-  if (llvm_bb == NULL) {
-    CHECK(bb->block_type == kExitBlock);
-  } else {
-    irb_->SetInsertPoint(llvm_bb);
-    SetDexOffset(bb->start_offset);
-  }
-
-  if (cu_->verbose) {
-    LOG(INFO) << "................................";
-    LOG(INFO) << "Block id " << bb->id;
-    if (llvm_bb != NULL) {
-      LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
-    } else {
-      LOG(INFO) << "llvm_bb is NULL";
-    }
-  }
-
-  if (bb->block_type == kEntryBlock) {
-    SetMethodInfo();
-
-    {  // Allocate shadowframe.
-      art::llvm::IntrinsicHelper::IntrinsicId id =
-              art::llvm::IntrinsicHelper::AllocaShadowFrame;
-      ::llvm::Function* func = intrinsic_helper_->GetIntrinsicFunction(id);
-      ::llvm::Value* entries = irb_->getInt32(mir_graph_->GetNumOfCodeVRs());
-      irb_->CreateCall(func, entries);
-    }
-
-    {  // Store arguments to vregs.
-      uint16_t arg_reg = mir_graph_->GetFirstInVR();
-
-      ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
-
-      const char* shorty = cu_->shorty;
-      uint32_t shorty_size = strlen(shorty);
-      CHECK_GE(shorty_size, 1u);
-
-      ++arg_iter;  // skip method object
-
-      if ((cu_->access_flags & kAccStatic) == 0) {
-        SetVregOnValue(arg_iter, arg_reg);
-        ++arg_iter;
-        ++arg_reg;
-      }
-
-      for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
-        SetVregOnValue(arg_iter, arg_reg);
-
-        ++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;
-        }
-      }
-    }
-  } else if (bb->block_type == kExitBlock) {
-    /*
-     * Because of the differences between how MIR/LIR and llvm handle exit
-     * blocks, we won't explicitly covert them.  On the llvm-to-lir
-     * path, it will need to be regenereated.
-     */
-    return false;
-  } else if (bb->block_type == kExceptionHandling) {
-    /*
-     * Because we're deferring null checking, delete the associated empty
-     * exception block.
-     */
-    llvm_bb->eraseFromParent();
-    return false;
-  }
-
-  HandlePhiNodes(bb, llvm_bb);
-
-  for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
-    SetDexOffset(mir->offset);
-
-    int opcode = mir->dalvikInsn.opcode;
-    Instruction::Format dalvik_format =
-        Instruction::FormatOf(mir->dalvikInsn.opcode);
-
-    if (opcode == kMirOpCheck) {
-      // Combine check and work halves of throwing instruction.
-      MIR* work_half = mir->meta.throw_insn;
-      mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
-      opcode = mir->dalvikInsn.opcode;
-      SSARepresentation* ssa_rep = work_half->ssa_rep;
-      work_half->ssa_rep = mir->ssa_rep;
-      mir->ssa_rep = ssa_rep;
-      work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
-      if (bb->successor_block_list_type == kCatch) {
-        ::llvm::Function* intr = intrinsic_helper_->GetIntrinsicFunction(
-            art::llvm::IntrinsicHelper::CatchTargets);
-        ::llvm::Value* switch_key =
-            irb_->CreateCall(intr, irb_->getInt32(mir->offset));
-        // New basic block to use for work half
-        ::llvm::BasicBlock* work_bb =
-            ::llvm::BasicBlock::Create(*context_, "", func_);
-        ::llvm::SwitchInst* sw =
-            irb_->CreateSwitch(switch_key, work_bb, bb->successor_blocks.size());
-        for (SuccessorBlockInfo *successor_block_info : bb->successor_blocks) {
-          ::llvm::BasicBlock *target =
-              GetLLVMBlock(successor_block_info->block);
-          int type_index = successor_block_info->key;
-          sw->addCase(irb_->getInt32(type_index), target);
-        }
-        llvm_bb = work_bb;
-        irb_->SetInsertPoint(llvm_bb);
-      }
-    }
-
-    if (IsPseudoMirOp(opcode)) {
-      ConvertExtendedMIR(bb, mir, llvm_bb);
-      continue;
-    }
-
-    bool not_handled = ConvertMIRNode(mir, bb, llvm_bb);
-    if (not_handled) {
-      Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
-      LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
-                                   mir->offset, opcode,
-                                   Instruction::Name(dalvik_opcode),
-                                   dalvik_format);
-    }
-  }
-
-  if (bb->block_type == kEntryBlock) {
-    entry_target_bb_ = GetLLVMBlock(bb->fall_through);
-  } else if ((bb->fall_through != NullBasicBlockId) && !bb->terminated_by_return) {
-    irb_->CreateBr(GetLLVMBlock(bb->fall_through));
-  }
-
-  return false;
-}
-
-char RemapShorty(char shorty_type) {
-  /*
-   * TODO: might want to revisit this.  Dalvik registers are 32-bits wide,
-   * and longs/doubles are represented as a pair of registers.  When sub-word
-   * arguments (and method results) are passed, they are extended to Dalvik
-   * virtual register containers.  Because llvm is picky about type consistency,
-   * we must either cast the "real" type to 32-bit container multiple Dalvik
-   * register types, or always use the expanded values.
-   * Here, we're doing the latter.  We map the shorty signature to container
-   * types (which is valid so long as we always do a real expansion of passed
-   * arguments and field loads).
-   */
-  switch (shorty_type) {
-    case 'Z' : shorty_type = 'I'; break;
-    case 'B' : shorty_type = 'I'; break;
-    case 'S' : shorty_type = 'I'; break;
-    case 'C' : shorty_type = 'I'; break;
-    default: break;
-  }
-  return shorty_type;
-}
-
-::llvm::FunctionType* MirConverter::GetFunctionType() {
-  // Get return type
-  ::llvm::Type* ret_type = irb_->getJType(RemapShorty(cu_->shorty[0]));
-
-  // Get argument type
-  std::vector< ::llvm::Type*> args_type;
-
-  // method object
-  args_type.push_back(irb_->getJMethodTy());
-
-  // Do we have  a "this"?
-  if ((cu_->access_flags & kAccStatic) == 0) {
-    args_type.push_back(irb_->getJObjectTy());
-  }
-
-  for (uint32_t i = 1; i < strlen(cu_->shorty); ++i) {
-    args_type.push_back(irb_->getJType(RemapShorty(cu_->shorty[i])));
-  }
-
-  return ::llvm::FunctionType::get(ret_type, args_type, false);
-}
-
-bool MirConverter::CreateFunction() {
-  ::llvm::FunctionType* func_type = GetFunctionType();
-  if (func_type == NULL) {
-    return false;
-  }
-
-  func_ = ::llvm::Function::Create(func_type,
-                                      ::llvm::Function::InternalLinkage,
-                                      symbol_, module_);
-
-  ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
-  ::llvm::Function::arg_iterator arg_end(func_->arg_end());
-
-  arg_iter->setName("method");
-  ++arg_iter;
-
-  int start_sreg = mir_graph_->GetFirstInVR();
-
-  for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
-    arg_iter->setName(StringPrintf("v%i_0", start_sreg));
-    start_sreg += mir_graph_->reg_location_[start_sreg].wide ? 2 : 1;
-  }
-
-  return true;
-}
-
-bool MirConverter::CreateLLVMBasicBlock(BasicBlock* bb) {
-  // Skip the exit block
-  if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
-    id_to_block_map_.Put(bb->id, NULL);
-  } else {
-    int offset = bb->start_offset;
-    bool entry_block = (bb->block_type == kEntryBlock);
-    ::llvm::BasicBlock* llvm_bb =
-        ::llvm::BasicBlock::Create(*context_, entry_block ? "entry" :
-                                 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
-                                              kNormalBlock, offset, bb->id), func_);
-    if (entry_block) {
-        entry_bb_ = llvm_bb;
-        placeholder_bb_ =
-            ::llvm::BasicBlock::Create(*context_, "placeholder",
-                                     func_);
-    }
-    id_to_block_map_.Put(bb->id, llvm_bb);
-  }
-  return false;
-}
-
-
-/*
- * Convert MIR to LLVM_IR
- *  o For each ssa name, create LLVM named value.  Type these
- *    appropriately, and ignore high half of wide and double operands.
- *  o For each MIR basic block, create an LLVM basic block.
- *  o Iterate through the MIR a basic block at a time, setting arguments
- *    to recovered ssa name.
- */
-void MirConverter::MethodMIR2Bitcode() {
-  InitIR();
-
-  // Create the function
-  CreateFunction();
-
-  // Create an LLVM basic block for each MIR block in dfs preorder
-  PreOrderDfsIterator iter(mir_graph_);
-  for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) {
-    CreateLLVMBasicBlock(bb);
-  }
-
-  /*
-   * Create an llvm named value for each MIR SSA name.  Note: we'll use
-   * placeholders for all non-argument values (because we haven't seen
-   * the definition yet).
-   */
-  irb_->SetInsertPoint(placeholder_bb_);
-  ::llvm::Function::arg_iterator arg_iter(func_->arg_begin());
-  arg_iter++;  /* Skip path method */
-  for (int i = 0; i < mir_graph_->GetNumSSARegs(); i++) {
-    ::llvm::Value* val;
-    RegLocation rl_temp = mir_graph_->reg_location_[i];
-    if ((mir_graph_->SRegToVReg(i) < 0) || rl_temp.high_word) {
-      llvm_values_.push_back(0);
-    } else if ((i < mir_graph_->GetFirstInVR()) ||
-               (i >= (mir_graph_->GetFirstTempVR()))) {
-      ::llvm::Constant* imm_value = mir_graph_->reg_location_[i].wide ?
-         irb_->getJLong(0) : irb_->getJInt(0);
-      val = EmitConst(imm_value, mir_graph_->reg_location_[i]);
-      val->setName(mir_graph_->GetSSAName(i));
-      llvm_values_.push_back(val);
-    } else {
-      // Recover previously-created argument values
-      ::llvm::Value* arg_val = arg_iter++;
-      llvm_values_.push_back(arg_val);
-    }
-  }
-
-  PreOrderDfsIterator iter2(mir_graph_);
-  for (BasicBlock* bb = iter2.Next(); bb != NULL; bb = iter2.Next()) {
-    BlockBitcodeConversion(bb);
-  }
-
-  /*
-   * In a few rare cases of verification failure, the verifier will
-   * replace one or more Dalvik opcodes with the special
-   * throw-verification-failure opcode.  This can leave the SSA graph
-   * in an invalid state, as definitions may be lost, while uses retained.
-   * To work around this problem, we insert placeholder definitions for
-   * all Dalvik SSA regs in the "placeholder" block.  Here, after
-   * bitcode conversion is complete, we examine those placeholder definitions
-   * and delete any with no references (which normally is all of them).
-   *
-   * If any definitions remain, we link the placeholder block into the
-   * CFG.  Otherwise, it is deleted.
-   */
-  for (::llvm::BasicBlock::iterator it = placeholder_bb_->begin(),
-       it_end = placeholder_bb_->end(); it != it_end;) {
-    ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(it++);
-    DCHECK(inst != NULL);
-    ::llvm::Value* val = ::llvm::dyn_cast< ::llvm::Value>(inst);
-    DCHECK(val != NULL);
-    if (val->getNumUses() == 0) {
-      inst->eraseFromParent();
-    }
-  }
-  SetDexOffset(0);
-  if (placeholder_bb_->empty()) {
-    placeholder_bb_->eraseFromParent();
-  } else {
-    irb_->SetInsertPoint(placeholder_bb_);
-    irb_->CreateBr(entry_target_bb_);
-    entry_target_bb_ = placeholder_bb_;
-  }
-  irb_->SetInsertPoint(entry_bb_);
-  irb_->CreateBr(entry_target_bb_);
-
-  if (cu_->enable_debug & (1 << kDebugVerifyBitcode)) {
-     if (::llvm::verifyFunction(*func_, ::llvm::PrintMessageAction)) {
-       LOG(INFO) << "Bitcode verification FAILED for "
-                 << PrettyMethod(cu_->method_idx, *cu_->dex_file)
-                 << " of size " << mir_graph_->GetNumDalvikInsns();
-       cu_->enable_debug |= (1 << kDebugDumpBitcodeFile);
-     }
-  }
-
-  if (cu_->enable_debug & (1 << kDebugDumpBitcodeFile)) {
-    // Write bitcode to file
-    std::string errmsg;
-    std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file));
-    mir_graph_->ReplaceSpecialChars(fname);
-    // TODO: make configurable change naming mechanism to avoid fname length issues.
-    fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
-
-    if (fname.size() > 240) {
-      LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
-      fname.resize(240);
-    }
-
-    ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
-        new ::llvm::tool_output_file(fname.c_str(), errmsg,
-                                   ::llvm::sys::fs::F_Binary));
-
-    if (!errmsg.empty()) {
-      LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
-    }
-
-    ::llvm::WriteBitcodeToFile(module_, out_file->os());
-    out_file->keep();
-  }
-}
-
-Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
-                               ArenaAllocator* const arena,
-                               llvm::LlvmCompilationUnit* const llvm_compilation_unit) {
-  return new MirConverter(cu, mir_graph, arena, llvm_compilation_unit);
-}
-
-}  // namespace art
diff --git a/compiler/dex/portable/mir_to_gbc.h b/compiler/dex/portable/mir_to_gbc.h
deleted file mode 100644
index bc4f5c4..0000000
--- a/compiler/dex/portable/mir_to_gbc.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (C) 2011 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_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
-#define ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
-
-#include <llvm/ADT/ArrayRef.h>
-#include <llvm/IR/BasicBlock.h>
-#include <llvm/IR/IRBuilder.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Module.h>
-
-#include "invoke_type.h"
-#include "compiled_method.h"
-#include "dex/compiler_enums.h"
-#include "dex/compiler_ir.h"
-#include "dex/backend.h"
-#include "llvm/intrinsic_helper.h"
-#include "llvm/llvm_compilation_unit.h"
-#include "safe_map.h"
-#include "utils/arena_containers.h"
-
-namespace llvm {
-  class Module;
-  class LLVMContext;
-}
-
-namespace art {
-
-namespace llvm {
-  class IntrinsicHelper;
-  class IRBuilder;
-}
-
-class LLVMInfo {
-  public:
-    LLVMInfo();
-    ~LLVMInfo();
-
-    ::llvm::LLVMContext* GetLLVMContext() {
-      return llvm_context_.get();
-    }
-
-    ::llvm::Module* GetLLVMModule() {
-      return llvm_module_;
-    }
-
-    art::llvm::IntrinsicHelper* GetIntrinsicHelper() {
-      return intrinsic_helper_.get();
-    }
-
-    art::llvm::IRBuilder* GetIRBuilder() {
-      return ir_builder_.get();
-    }
-
-  private:
-    std::unique_ptr< ::llvm::LLVMContext> llvm_context_;
-    ::llvm::Module* llvm_module_;  // Managed by context_.
-    std::unique_ptr<art::llvm::IntrinsicHelper> intrinsic_helper_;
-    std::unique_ptr<art::llvm::IRBuilder> ir_builder_;
-};
-
-class BasicBlock;
-struct CallInfo;
-struct CompilationUnit;
-struct MIR;
-struct RegLocation;
-struct RegisterInfo;
-class MIRGraph;
-
-// Target-specific initialization.
-Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
-                               ArenaAllocator* const arena,
-                               llvm::LlvmCompilationUnit* const llvm_compilation_unit);
-
-class MirConverter : public Backend {
-  public:
-    // TODO: flesh out and integrate into new world order.
-    MirConverter(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena,
-                 llvm::LlvmCompilationUnit* llvm_compilation_unit)
-      : Backend(arena),
-        cu_(cu),
-        mir_graph_(mir_graph),
-        llvm_compilation_unit_(llvm_compilation_unit),
-        llvm_info_(llvm_compilation_unit->GetQuickContext()),
-        symbol_(llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol()),
-        context_(NULL),
-        module_(NULL),
-        func_(NULL),
-        intrinsic_helper_(NULL),
-        irb_(NULL),
-        placeholder_bb_(NULL),
-        entry_bb_(NULL),
-        entry_target_bb_(NULL),
-        llvm_values_(arena->Adapter()),
-        temp_name_(0),
-        current_dalvik_offset_(0) {
-      llvm_values_.reserve(mir_graph->GetNumSSARegs());
-      if (kIsDebugBuild) {
-        cu->enable_debug |= (1 << kDebugVerifyBitcode);
-      }
-    }
-
-    void Materialize() {
-      MethodMIR2Bitcode();
-    }
-
-    CompiledMethod* GetCompiledMethod() {
-      return NULL;
-    }
-
-  private:
-    ::llvm::BasicBlock* GetLLVMBlock(int id);
-    ::llvm::Value* GetLLVMValue(int s_reg);
-    void SetVregOnValue(::llvm::Value* val, int s_reg);
-    void DefineValueOnly(::llvm::Value* val, int s_reg);
-    void DefineValue(::llvm::Value* val, int s_reg);
-    ::llvm::Type* LlvmTypeFromLocRec(RegLocation loc);
-    void InitIR();
-    ::llvm::BasicBlock* FindCaseTarget(uint32_t vaddr);
-    void ConvertPackedSwitch(BasicBlock* bb, MIR* mir, int32_t table_offset,
-                             RegLocation rl_src);
-    void ConvertSparseSwitch(BasicBlock* bb, MIR* mir, int32_t table_offset,
-                             RegLocation rl_src);
-    void ConvertSget(int32_t field_index,
-                     art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
-    void ConvertSput(int32_t field_index,
-                     art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
-    void ConvertFillArrayData(int32_t offset, RegLocation rl_array);
-    ::llvm::Value* EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
-                             RegLocation loc);
-    void EmitPopShadowFrame();
-    ::llvm::Value* EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
-                            RegLocation loc);
-    void ConvertMoveException(RegLocation rl_dest);
-    void ConvertThrow(RegLocation rl_src);
-    void ConvertMonitorEnterExit(int opt_flags,
-                                 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
-    void ConvertArrayLength(int opt_flags, RegLocation rl_dest,
-                            RegLocation rl_src);
-    void EmitSuspendCheck();
-    ::llvm::Value* ConvertCompare(ConditionCode cc,
-                                  ::llvm::Value* src1, ::llvm::Value* src2);
-    void ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
-                                 RegLocation rl_src1, RegLocation rl_src2);
-    void ConvertCompareZeroAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
-                                     RegLocation rl_src1);
-    ::llvm::Value* GenDivModOp(bool is_div, bool is_long, ::llvm::Value* src1,
-                               ::llvm::Value* src2);
-    ::llvm::Value* GenArithOp(OpKind op, bool is_long, ::llvm::Value* src1,
-                              ::llvm::Value* src2);
-    void ConvertFPArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
-                          RegLocation rl_src2);
-    void ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
-                      RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
-    void ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
-                         RegLocation rl_dest, RegLocation rl_src, int shift_amount);
-    void ConvertArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
-                        RegLocation rl_src2);
-    void ConvertArithOpLit(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
-                           int32_t imm);
-    void ConvertInvoke(BasicBlock* bb, MIR* mir, InvokeType invoke_type,
-                       bool is_range, bool is_filled_new_array);
-    void ConvertConstObject(uint32_t idx,
-                            art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
-    void ConvertCheckCast(uint32_t type_idx, RegLocation rl_src);
-    void ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest);
-    void ConvertNewArray(uint32_t type_idx, RegLocation rl_dest,
-                         RegLocation rl_src);
-    void ConvertAget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
-                     RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index);
-    void ConvertAput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
-                     RegLocation rl_src, RegLocation rl_array, RegLocation rl_index);
-    void ConvertIget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
-                     RegLocation rl_dest, RegLocation rl_obj, int field_index);
-    void ConvertIput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
-                     RegLocation rl_src, RegLocation rl_obj, int field_index);
-    void ConvertInstanceOf(uint32_t type_idx, RegLocation rl_dest,
-                           RegLocation rl_src);
-    void ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src);
-    void ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src);
-    void ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src);
-    void ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src);
-    void ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
-                               RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
-    void ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
-                             art::llvm::IntrinsicHelper::IntrinsicId id);
-    void ConvertNeg(RegLocation rl_dest, RegLocation rl_src);
-    void ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, RegLocation rl_src);
-    void ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
-                        RegLocation rl_dest, RegLocation rl_src);
-    void ConvertNegFP(RegLocation rl_dest, RegLocation rl_src);
-    void ConvertNot(RegLocation rl_dest, RegLocation rl_src);
-    void EmitConstructorBarrier();
-    bool ConvertMIRNode(MIR* mir, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
-    void SetDexOffset(int32_t offset);
-    void SetMethodInfo();
-    void HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
-    void ConvertExtendedMIR(BasicBlock* bb, MIR* mir, ::llvm::BasicBlock* llvm_bb);
-    bool BlockBitcodeConversion(BasicBlock* bb);
-    ::llvm::FunctionType* GetFunctionType();
-    bool CreateFunction();
-    bool CreateLLVMBasicBlock(BasicBlock* bb);
-    void MethodMIR2Bitcode();
-
-    CompilationUnit* cu_;
-    MIRGraph* mir_graph_;
-    llvm::LlvmCompilationUnit* const llvm_compilation_unit_;
-    LLVMInfo* llvm_info_;
-    std::string symbol_;
-    ::llvm::LLVMContext* context_;
-    ::llvm::Module* module_;
-    ::llvm::Function* func_;
-    art::llvm::IntrinsicHelper* intrinsic_helper_;
-    art::llvm::IRBuilder* irb_;
-    ::llvm::BasicBlock* placeholder_bb_;
-    ::llvm::BasicBlock* entry_bb_;
-    ::llvm::BasicBlock* entry_target_bb_;
-    std::string bitcode_filename_;
-    ArenaVector< ::llvm::Value*> llvm_values_;
-    int32_t temp_name_;
-    SafeMap<int32_t, ::llvm::BasicBlock*> id_to_block_map_;  // block id -> llvm bb.
-    int current_dalvik_offset_;
-};  // Class MirConverter
-
-}  // namespace art
-
-#endif  // ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc
index fb098c3..c14e22e 100644
--- a/compiler/dex/quick/quick_compiler.cc
+++ b/compiler/dex/quick/quick_compiler.cc
@@ -19,6 +19,7 @@
 #include <cstdint>
 
 #include "compiler.h"
+#include "dex_file-inl.h"
 #include "dex/frontend.h"
 #include "dex/mir_graph.h"
 #include "dex/quick/mir_to_lir.h"
@@ -588,17 +589,6 @@
                                        uint32_t method_idx,
                                        jobject class_loader,
                                        const DexFile& dex_file) const {
-  CompiledMethod* method = TryCompileWithSeaIR(code_item,
-                                               access_flags,
-                                               invoke_type,
-                                               class_def_idx,
-                                               method_idx,
-                                               class_loader,
-                                               dex_file);
-  if (method != nullptr) {
-    return method;
-  }
-
   // TODO: check method fingerprint here to determine appropriate backend type.  Until then, use
   // build default.
   CompilerDriver* driver = GetCompilerDriver();
diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc
index 932a532..60d2406 100644
--- a/compiler/dex/verification_results.cc
+++ b/compiler/dex/verification_results.cc
@@ -106,18 +106,8 @@
   return (rejected_classes_.find(ref) != rejected_classes_.end());
 }
 
-bool VerificationResults::IsCandidateForCompilation(MethodReference& method_ref,
+bool VerificationResults::IsCandidateForCompilation(MethodReference&,
                                                     const uint32_t access_flags) {
-#ifdef ART_SEA_IR_MODE
-  bool use_sea = compiler_options_->GetSeaIrMode();
-  use_sea = use_sea && (std::string::npos != PrettyMethod(
-                        method_ref.dex_method_index, *(method_ref.dex_file)).find("fibonacci"));
-  if (use_sea) {
-    return true;
-  }
-#else
-  UNUSED(method_ref);
-#endif
   if (!compiler_options_->IsCompilationEnabled()) {
     return false;
   }
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index e427471..cd9280c 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -371,8 +371,6 @@
   DCHECK(verification_results_ != nullptr);
   DCHECK(method_inliner_map_ != nullptr);
 
-  CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, nullptr), "compiler tls key");
-
   dex_to_dex_compiler_ = reinterpret_cast<DexToDexCompilerFn>(ArtCompileDEX);
 
   compiler_->Init();
@@ -432,20 +430,9 @@
     MutexLock mu(self, compiled_methods_lock_);
     STLDeleteValues(&compiled_methods_);
   }
-  CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key");
   compiler_->UnInit();
 }
 
-CompilerTls* CompilerDriver::GetTls() {
-  // Lazily create thread-local storage
-  CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_));
-  if (res == nullptr) {
-    res = compiler_->CreateNewCompilerTls();
-    CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls");
-  }
-  return res;
-}
-
 #define CREATE_TRAMPOLINE(type, abi, offset) \
     if (Is64BitInstructionSet(instruction_set_)) { \
       return CreateTrampoline64(instruction_set_, abi, \
@@ -467,18 +454,6 @@
   CREATE_TRAMPOLINE(JNI, kJniAbi, pDlsymLookup)
 }
 
-const std::vector<uint8_t>* CompilerDriver::CreatePortableImtConflictTrampoline() const {
-  CREATE_TRAMPOLINE(PORTABLE, kPortableAbi, pPortableImtConflictTrampoline)
-}
-
-const std::vector<uint8_t>* CompilerDriver::CreatePortableResolutionTrampoline() const {
-  CREATE_TRAMPOLINE(PORTABLE, kPortableAbi, pPortableResolutionTrampoline)
-}
-
-const std::vector<uint8_t>* CompilerDriver::CreatePortableToInterpreterBridge() const {
-  CREATE_TRAMPOLINE(PORTABLE, kPortableAbi, pPortableToInterpreterBridge)
-}
-
 const std::vector<uint8_t>* CompilerDriver::CreateQuickGenericJniTrampoline() const {
   CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickGenericJniTrampoline)
 }
@@ -1283,18 +1258,11 @@
   // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
   const bool force_relocations = (compiling_boot ||
                                   GetCompilerOptions().GetIncludePatchInformation());
-  if (compiler_->IsPortable()) {
-    if (sharp_type != kStatic && sharp_type != kDirect) {
-      return;
-    }
-    use_dex_cache = true;
-  } else {
-    if (sharp_type != kStatic && sharp_type != kDirect) {
-      return;
-    }
-    // TODO: support patching on all architectures.
-    use_dex_cache = use_dex_cache || (force_relocations && !support_boot_image_fixup_);
+  if (sharp_type != kStatic && sharp_type != kDirect) {
+    return;
   }
+  // TODO: support patching on all architectures.
+  use_dex_cache = use_dex_cache || (force_relocations && !support_boot_image_fixup_);
   bool method_code_in_boot = (method->GetDeclaringClass()->GetClassLoader() == nullptr);
   if (!use_dex_cache) {
     if (!method_code_in_boot) {
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 615e0d0..edc6468 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -66,8 +66,6 @@
   kInterpreterAbi,
   // ABI of calls to a method's native code, only used for native methods.
   kJniAbi,
-  // ABI of calls to a method's portable code entry point.
-  kPortableAbi,
   // ABI of calls to a method's quick code entry point.
   kQuickAbi
 };
@@ -144,8 +142,6 @@
     return image_classes_.get();
   }
 
-  CompilerTls* GetTls();
-
   // Generate the trampolines that are invoked by unresolved direct methods.
   const std::vector<uint8_t>* CreateInterpreterToInterpreterBridge() const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -153,12 +149,6 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateJniDlsymLookup() const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  const std::vector<uint8_t>* CreatePortableImtConflictTrampoline() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  const std::vector<uint8_t>* CreatePortableResolutionTrampoline() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  const std::vector<uint8_t>* CreatePortableToInterpreterBridge() const
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateQuickGenericJniTrampoline() const
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   const std::vector<uint8_t>* CreateQuickImtConflictTrampoline() const
@@ -555,8 +545,6 @@
 
   void* compiler_context_;
 
-  pthread_key_t tls_key_;
-
   // Arena pool used by the compiler.
   ArenaPool arena_pool_;
 
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 5a0ec2f..c30cc04 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -129,10 +129,6 @@
                                            << " "
                                            << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
                                            << " " << dex->GetMethodName(dex->GetMethodId(i));
-    EXPECT_TRUE(method->GetEntryPointFromPortableCompiledCode() != NULL) << "method_idx=" << i
-                                           << " "
-                                           << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
-                                           << " " << dex->GetMethodName(dex->GetMethodId(i));
   }
   EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
   for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
@@ -148,7 +144,6 @@
 }
 
 TEST_F(CompilerDriverTest, AbstractMethodErrorStub) {
-  TEST_DISABLED_FOR_PORTABLE();
   TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING();
   jobject class_loader;
   {
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index aec7d24..97699e5 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -68,9 +68,6 @@
     implicit_so_checks_(false),
     implicit_suspend_checks_(false),
     compile_pic_(false),
-#ifdef ART_SEA_IR_MODE
-    sea_ir_mode_(false),
-#endif
     verbose_methods_(nullptr),
     init_failure_output_(nullptr) {
   }
@@ -89,9 +86,6 @@
                   bool implicit_so_checks,
                   bool implicit_suspend_checks,
                   bool compile_pic,
-#ifdef ART_SEA_IR_MODE
-                  bool sea_ir_mode,
-#endif
                   const std::vector<std::string>* verbose_methods,
                   std::ostream* init_failure_output
                   ) :  // NOLINT(whitespace/parens)
@@ -109,9 +103,6 @@
     implicit_so_checks_(implicit_so_checks),
     implicit_suspend_checks_(implicit_suspend_checks),
     compile_pic_(compile_pic),
-#ifdef ART_SEA_IR_MODE
-    sea_ir_mode_(sea_ir_mode),
-#endif
     verbose_methods_(verbose_methods),
     init_failure_output_(init_failure_output) {
   }
@@ -189,12 +180,6 @@
     return implicit_suspend_checks_;
   }
 
-#ifdef ART_SEA_IR_MODE
-  bool GetSeaIrMode() const {
-    return sea_ir_mode_;
-  }
-#endif
-
   bool GetGenerateGDBInformation() const {
     return generate_gdb_information_;
   }
@@ -242,10 +227,6 @@
   const bool implicit_suspend_checks_;
   const bool compile_pic_;
 
-#ifdef ART_SEA_IR_MODE
-  const bool sea_ir_mode_;
-#endif
-
   // Vector of methods to have verbose output enabled for.
   const std::vector<std::string>* const verbose_methods_;
 
diff --git a/compiler/elf_writer_mclinker.cc b/compiler/elf_writer_mclinker.cc
deleted file mode 100644
index 7705b9c..0000000
--- a/compiler/elf_writer_mclinker.cc
+++ /dev/null
@@ -1,411 +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 "elf_writer_mclinker.h"
-
-#include <llvm/Support/ELF.h>
-#include <llvm/Support/TargetSelect.h>
-
-#include <mcld/Environment.h>
-#include <mcld/IRBuilder.h>
-#include <mcld/Linker.h>
-#include <mcld/LinkerConfig.h>
-#include <mcld/LinkerScript.h>
-#include <mcld/MC/ZOption.h>
-#include <mcld/Module.h>
-#include <mcld/Support/Path.h>
-#include <mcld/Support/TargetSelect.h>
-
-#include "base/unix_file/fd_file.h"
-#include "class_linker.h"
-#include "dex_method_iterator.h"
-#include "driver/compiler_driver.h"
-#include "elf_file.h"
-#include "globals.h"
-#include "mirror/art_method.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-#include "oat_writer.h"
-#include "scoped_thread_state_change.h"
-#include "vector_output_stream.h"
-
-namespace art {
-
-ElfWriterMclinker::ElfWriterMclinker(const CompilerDriver& driver, File* elf_file)
-  : ElfWriter(driver, elf_file), oat_input_(nullptr) {
-}
-
-ElfWriterMclinker::~ElfWriterMclinker() {
-}
-
-bool ElfWriterMclinker::Create(File* elf_file,
-                               OatWriter* oat_writer,
-                               const std::vector<const DexFile*>& dex_files,
-                               const std::string& android_root,
-                               bool is_host,
-                               const CompilerDriver& driver) {
-  ElfWriterMclinker elf_writer(driver, elf_file);
-  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
-}
-
-bool ElfWriterMclinker::Write(OatWriter* oat_writer,
-                              const std::vector<const DexFile*>& dex_files,
-                              const std::string& android_root,
-                              bool is_host) {
-  std::vector<uint8_t> oat_contents;
-  oat_contents.reserve(oat_writer->GetSize());
-
-  Init();
-  mcld::LDSection* oat_section = AddOatInput(oat_writer, &oat_contents);
-  if (kUsePortableCompiler) {
-    AddMethodInputs(dex_files);
-    AddRuntimeInputs(android_root, is_host);
-  }
-
-  // link inputs
-  if (!linker_->link(*module_.get(), *ir_builder_.get())) {
-    LOG(ERROR) << "Failed to link " << elf_file_->GetPath();
-    return false;
-  }
-
-  // Fill oat_contents.
-  VectorOutputStream output_stream("oat contents", &oat_contents);
-  oat_writer->SetOatDataOffset(oat_section->offset());
-  CHECK(oat_writer->Write(&output_stream));
-  CHECK_EQ(oat_writer->GetSize(), oat_contents.size());
-
-  // emit linked output
-  // TODO: avoid dup of fd by fixing Linker::emit to not close the argument fd.
-  int fd = dup(elf_file_->Fd());
-  if (fd == -1) {
-    PLOG(ERROR) << "Failed to dup file descriptor for " << elf_file_->GetPath();
-    return false;
-  }
-  if (!linker_->emit(*module_.get(), fd)) {
-    LOG(ERROR) << "Failed to emit " << elf_file_->GetPath();
-    return false;
-  }
-  mcld::Finalize();
-  LOG(INFO) << "ELF file written successfully: " << elf_file_->GetPath();
-
-  oat_contents.clear();
-  if (kUsePortableCompiler) {
-    FixupOatMethodOffsets(dex_files);
-  }
-  return true;
-}
-
-static void InitializeLLVM() {
-  // TODO: this is lifted from art's compiler_llvm.cc, should be factored out
-  if (kIsTargetBuild) {
-    llvm::InitializeNativeTarget();
-    // TODO: odd that there is no InitializeNativeTargetMC?
-  } else {
-    llvm::InitializeAllTargets();
-    llvm::InitializeAllTargetMCs();
-  }
-}
-
-void ElfWriterMclinker::Init() {
-  std::string target_triple;
-  std::string target_cpu;
-  std::string target_attr;
-  CompilerDriver::InstructionSetToLLVMTarget(compiler_driver_->GetInstructionSet(),
-                                             &target_triple,
-                                             &target_cpu,
-                                             &target_attr);
-
-  // Based on mclinker's llvm-mcld.cpp main() and LinkerTest
-  //
-  // TODO: LinkerTest uses mcld::Initialize(), but it does an
-  // llvm::InitializeAllTargets, which we don't want. Basically we
-  // want mcld::InitializeNative, but it doesn't exist yet, so we
-  // inline the minimal we need here.
-  InitializeLLVM();
-  mcld::InitializeAllTargets();
-  mcld::InitializeAllLinkers();
-  mcld::InitializeAllEmulations();
-  mcld::InitializeAllDiagnostics();
-
-  linker_config_.reset(new mcld::LinkerConfig(target_triple));
-  CHECK(linker_config_.get() != NULL);
-  linker_config_->setCodeGenType(mcld::LinkerConfig::DynObj);
-  linker_config_->options().setSOName(elf_file_->GetPath());
-
-  // error on undefined symbols.
-  // TODO: should this just be set if kIsDebugBuild?
-  linker_config_->options().setNoUndefined(true);
-
-  if (compiler_driver_->GetInstructionSet() == kMips) {
-     // MCLinker defaults MIPS section alignment to 0x10000, not
-     // 0x1000.  The ABI says this is because the max page size is
-     // general is 64k but that isn't true on Android.
-     mcld::ZOption z_option;
-     z_option.setKind(mcld::ZOption::MaxPageSize);
-     z_option.setPageSize(kPageSize);
-     linker_config_->options().addZOption(z_option);
-  }
-
-  // TODO: Wire up mcld DiagnosticEngine to LOG?
-  linker_config_->options().setColor(false);
-  if (false) {
-    // enables some tracing of input file processing
-    linker_config_->options().setTrace(true);
-  }
-
-  // Based on alone::Linker::config
-  linker_script_.reset(new mcld::LinkerScript());
-  module_.reset(new mcld::Module(linker_config_->options().soname(), *linker_script_.get()));
-  CHECK(module_.get() != NULL);
-  ir_builder_.reset(new mcld::IRBuilder(*module_.get(), *linker_config_.get()));
-  CHECK(ir_builder_.get() != NULL);
-  linker_.reset(new mcld::Linker());
-  CHECK(linker_.get() != NULL);
-  linker_->emulate(*linker_script_.get(), *linker_config_.get());
-}
-
-mcld::LDSection* ElfWriterMclinker::AddOatInput(OatWriter* oat_writer,
-                                                std::vector<uint8_t>* oat_contents) {
-  // NOTE: oat_contents has sufficient reserved space but it doesn't contain the data yet.
-  const char* oat_data_start = reinterpret_cast<const char*>(&(*oat_contents)[0]);
-  const size_t oat_data_length = oat_writer->GetOatHeader().GetExecutableOffset();
-  const char* oat_code_start = oat_data_start + oat_data_length;
-  const size_t oat_code_length = oat_writer->GetSize() - oat_data_length;
-
-  // TODO: ownership of oat_input?
-  oat_input_ = ir_builder_->CreateInput("oat contents",
-                                        mcld::sys::fs::Path("oat contents path"),
-                                        mcld::Input::Object);
-  CHECK(oat_input_ != NULL);
-
-  // TODO: ownership of null_section?
-  mcld::LDSection* null_section = ir_builder_->CreateELFHeader(*oat_input_,
-                                                               "",
-                                                               mcld::LDFileFormat::Null,
-                                                               SHT_NULL,
-                                                               0);
-  CHECK(null_section != NULL);
-
-  // TODO: we should split readonly data from readonly executable
-  // code like .oat does.  We need to control section layout with
-  // linker script like functionality to guarantee references
-  // between sections maintain relative position which isn't
-  // possible right now with the mclinker APIs.
-  CHECK(oat_code_start != NULL);
-
-  // we need to ensure that oatdata is page aligned so when we
-  // fixup the segment load addresses, they remain page aligned.
-  uint32_t alignment = kPageSize;
-
-  // TODO: ownership of text_section?
-  mcld::LDSection* text_section = ir_builder_->CreateELFHeader(*oat_input_,
-                                                               ".text",
-                                                               SHT_PROGBITS,
-                                                               SHF_EXECINSTR | SHF_ALLOC,
-                                                               alignment);
-  CHECK(text_section != NULL);
-
-  mcld::SectionData* text_sectiondata = ir_builder_->CreateSectionData(*text_section);
-  CHECK(text_sectiondata != NULL);
-
-  // TODO: why does IRBuilder::CreateRegion take a non-const pointer?
-  mcld::Fragment* text_fragment = ir_builder_->CreateRegion(const_cast<char*>(oat_data_start),
-                                                            oat_writer->GetSize());
-  CHECK(text_fragment != NULL);
-  ir_builder_->AppendFragment(*text_fragment, *text_sectiondata);
-
-  ir_builder_->AddSymbol(*oat_input_,
-                         "oatdata",
-                         mcld::ResolveInfo::Object,
-                         mcld::ResolveInfo::Define,
-                         mcld::ResolveInfo::Global,
-                         oat_data_length,  // size
-                         0,                // offset
-                         text_section);
-
-  ir_builder_->AddSymbol(*oat_input_,
-                         "oatexec",
-                         mcld::ResolveInfo::Function,
-                         mcld::ResolveInfo::Define,
-                         mcld::ResolveInfo::Global,
-                         oat_code_length,  // size
-                         oat_data_length,  // offset
-                         text_section);
-
-  ir_builder_->AddSymbol(*oat_input_,
-                         "oatlastword",
-                         mcld::ResolveInfo::Object,
-                         mcld::ResolveInfo::Define,
-                         mcld::ResolveInfo::Global,
-                         0,                // size
-                         // subtract a word so symbol is within section
-                         (oat_data_length + oat_code_length) - sizeof(uint32_t),  // offset
-                         text_section);
-
-  return text_section;
-}
-
-void ElfWriterMclinker::AddMethodInputs(const std::vector<const DexFile*>& dex_files) {
-  DCHECK(oat_input_ != NULL);
-
-  DexMethodIterator it(dex_files);
-  while (it.HasNext()) {
-    const DexFile& dex_file = it.GetDexFile();
-    uint32_t method_idx = it.GetMemberIndex();
-    const CompiledMethod* compiled_method =
-      compiler_driver_->GetCompiledMethod(MethodReference(&dex_file, method_idx));
-    if (compiled_method != NULL) {
-      AddCompiledCodeInput(*compiled_method);
-    }
-    it.Next();
-  }
-  added_symbols_.clear();
-}
-
-void ElfWriterMclinker::AddCompiledCodeInput(const CompiledCode& compiled_code) {
-  // Check if we've seen this compiled code before. If so skip
-  // it. This can happen for reused code such as invoke stubs.
-  const std::string& symbol = compiled_code.GetSymbol();
-  SafeMap<const std::string*, const std::string*>::iterator it = added_symbols_.find(&symbol);
-  if (it != added_symbols_.end()) {
-    return;
-  }
-  added_symbols_.Put(&symbol, &symbol);
-
-  // Add input to supply code for symbol
-  const std::vector<uint8_t>* code = compiled_code.GetPortableCode();
-  // TODO: ownership of code_input?
-  // TODO: why does IRBuilder::ReadInput take a non-const pointer?
-  mcld::Input* code_input = ir_builder_->ReadInput(symbol,
-                                                   const_cast<uint8_t*>(&(*code)[0]),
-                                                   code->size());
-  CHECK(code_input != NULL);
-}
-
-void ElfWriterMclinker::AddRuntimeInputs(const std::string& android_root, bool is_host) {
-  std::string libart_so(android_root);
-  libart_so += kIsDebugBuild ? "/lib/libartd.so" : "/lib/libart.so";
-  // TODO: ownership of libart_so_input?
-  mcld::Input* libart_so_input = ir_builder_->ReadInput(libart_so, libart_so);
-  CHECK(libart_so_input != NULL);
-
-  std::string host_prebuilt_dir("prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6");
-
-  std::string compiler_runtime_lib;
-  if (is_host) {
-    compiler_runtime_lib += host_prebuilt_dir;
-    compiler_runtime_lib += "/lib/gcc/i686-linux/4.6.x-google/libgcc.a";
-  } else {
-    compiler_runtime_lib += android_root;
-    compiler_runtime_lib += "/lib/libcompiler_rt.a";
-  }
-  // TODO: ownership of compiler_runtime_lib_input?
-  mcld::Input* compiler_runtime_lib_input = ir_builder_->ReadInput(compiler_runtime_lib,
-                                                                   compiler_runtime_lib);
-  CHECK(compiler_runtime_lib_input != NULL);
-
-  std::string libc_lib;
-  if (is_host) {
-    libc_lib += host_prebuilt_dir;
-    libc_lib += "/sysroot/usr/lib/libc.so.6";
-  } else {
-    libc_lib += android_root;
-    libc_lib += "/lib/libc.so";
-  }
-  // TODO: ownership of libc_lib_input?
-  mcld::Input* libc_lib_input_input = ir_builder_->ReadInput(libc_lib, libc_lib);
-  CHECK(libc_lib_input_input != NULL);
-
-  std::string libm_lib;
-  if (is_host) {
-    libm_lib += host_prebuilt_dir;
-    libm_lib += "/sysroot/usr/lib/libm.so";
-  } else {
-    libm_lib += android_root;
-    libm_lib += "/lib/libm.so";
-  }
-  // TODO: ownership of libm_lib_input?
-  mcld::Input* libm_lib_input_input = ir_builder_->ReadInput(libm_lib, libm_lib);
-  CHECK(libm_lib_input_input != NULL);
-}
-
-void ElfWriterMclinker::FixupOatMethodOffsets(const std::vector<const DexFile*>& dex_files) {
-  std::string error_msg;
-  std::unique_ptr<ElfFile> elf_file(ElfFile::Open(elf_file_, true, false, &error_msg));
-  CHECK(elf_file.get() != NULL) << elf_file_->GetPath() << ": " << error_msg;
-
-  uint32_t oatdata_address = GetOatDataAddress(elf_file.get());
-  DexMethodIterator it(dex_files);
-  while (it.HasNext()) {
-    const DexFile& dex_file = it.GetDexFile();
-    uint32_t method_idx = it.GetMemberIndex();
-    InvokeType invoke_type = it.GetInvokeType();
-    mirror::ArtMethod* method = NULL;
-    if (compiler_driver_->IsImage()) {
-      ClassLinker* linker = Runtime::Current()->GetClassLinker();
-      // Unchecked as we hold mutator_lock_ on entry.
-      ScopedObjectAccessUnchecked soa(Thread::Current());
-      StackHandleScope<1> hs(soa.Self());
-      Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(dex_file)));
-      method = linker->ResolveMethod(dex_file, method_idx, dex_cache,
-                                     NullHandle<mirror::ClassLoader>(),
-                                     NullHandle<mirror::ArtMethod>(), invoke_type);
-      CHECK(method != NULL);
-    }
-    const CompiledMethod* compiled_method =
-      compiler_driver_->GetCompiledMethod(MethodReference(&dex_file, method_idx));
-    if (compiled_method != NULL) {
-      uint32_t offset = FixupCompiledCodeOffset(*elf_file.get(), oatdata_address, *compiled_method);
-      // Don't overwrite static method trampoline
-      if (method != NULL &&
-          (!method->IsStatic() ||
-           method->IsConstructor() ||
-           method->GetDeclaringClass()->IsInitialized())) {
-        method->SetPortableOatCodeOffset(offset);
-      }
-    }
-    it.Next();
-  }
-  symbol_to_compiled_code_offset_.clear();
-}
-
-uint32_t ElfWriterMclinker::FixupCompiledCodeOffset(ElfFile& elf_file,
-                                                    Elf32_Addr oatdata_address,
-                                                    const CompiledCode& compiled_code) {
-  const std::string& symbol = compiled_code.GetSymbol();
-  SafeMap<const std::string*, uint32_t>::iterator it = symbol_to_compiled_code_offset_.find(&symbol);
-  if (it != symbol_to_compiled_code_offset_.end()) {
-    return it->second;
-  }
-
-  Elf32_Addr compiled_code_address = elf_file.FindSymbolAddress(SHT_SYMTAB,
-                                                                symbol,
-                                                                true);
-  CHECK_NE(0U, compiled_code_address) << symbol;
-  CHECK_LT(oatdata_address, compiled_code_address) << symbol;
-  uint32_t compiled_code_offset = compiled_code_address - oatdata_address;
-  symbol_to_compiled_code_offset_.Put(&symbol, compiled_code_offset);
-
-  const std::vector<uint32_t>& offsets = compiled_code.GetOatdataOffsetsToCompliledCodeOffset();
-  for (uint32_t i = 0; i < offsets.size(); i++) {
-    uint32_t oatdata_offset = oatdata_address + offsets[i];
-    uint32_t* addr = reinterpret_cast<uint32_t*>(elf_file.Begin() + oatdata_offset);
-    *addr = compiled_code_offset;
-  }
-  return compiled_code_offset;
-}
-
-}  // namespace art
diff --git a/compiler/elf_writer_mclinker.h b/compiler/elf_writer_mclinker.h
deleted file mode 100644
index 489fefb..0000000
--- a/compiler/elf_writer_mclinker.h
+++ /dev/null
@@ -1,98 +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_COMPILER_ELF_WRITER_MCLINKER_H_
-#define ART_COMPILER_ELF_WRITER_MCLINKER_H_
-
-#include <memory>
-
-#include "elf_writer.h"
-#include "safe_map.h"
-
-namespace mcld {
-class IRBuilder;
-class Input;
-class LDSection;
-class LDSymbol;
-class Linker;
-class LinkerConfig;
-class LinkerScript;
-class Module;
-}  // namespace mcld
-
-namespace art {
-
-class CompiledCode;
-
-class ElfWriterMclinker FINAL : public ElfWriter {
- public:
-  // Write an ELF file. Returns true on success, false on failure.
-  static bool Create(File* file,
-                     OatWriter* oat_writer,
-                     const std::vector<const DexFile*>& dex_files,
-                     const std::string& android_root,
-                     bool is_host,
-                     const CompilerDriver& driver)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- protected:
-  bool Write(OatWriter* oat_writer,
-             const std::vector<const DexFile*>& dex_files,
-             const std::string& android_root,
-             bool is_host)
-      OVERRIDE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- private:
-  ElfWriterMclinker(const CompilerDriver& driver, File* elf_file);
-  ~ElfWriterMclinker();
-
-  void Init();
-  mcld::LDSection* AddOatInput(OatWriter* oat_writer, std::vector<uint8_t>* oat_contents);
-  void AddMethodInputs(const std::vector<const DexFile*>& dex_files);
-  void AddCompiledCodeInput(const CompiledCode& compiled_code);
-  void AddRuntimeInputs(const std::string& android_root, bool is_host);
-  void FixupOatMethodOffsets(const std::vector<const DexFile*>& dex_files)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  uint32_t FixupCompiledCodeOffset(ElfFile& elf_file,
-                                   uint32_t oatdata_address,
-                                   const CompiledCode& compiled_code);
-
-  // Setup by Init()
-  std::unique_ptr<mcld::LinkerConfig> linker_config_;
-  std::unique_ptr<mcld::LinkerScript> linker_script_;
-  std::unique_ptr<mcld::Module> module_;
-  std::unique_ptr<mcld::IRBuilder> ir_builder_;
-  std::unique_ptr<mcld::Linker> linker_;
-
-  // Setup by AddOatInput()
-  // TODO: ownership of oat_input_?
-  mcld::Input* oat_input_;
-
-  // Setup by AddCompiledCodeInput
-  // set of symbols for already added mcld::Inputs
-  SafeMap<const std::string*, const std::string*> added_symbols_;
-
-  // Setup by FixupCompiledCodeOffset
-  // map of symbol names to oatdata offset
-  SafeMap<const std::string*, uint32_t> symbol_to_compiled_code_offset_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterMclinker);
-};
-
-}  // namespace art
-
-#endif  // ART_COMPILER_ELF_WRITER_MCLINKER_H_
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index 5488e2f..7fabc30 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -67,28 +67,6 @@
   void* dl_oatexec = NULL;
   void* dl_oatlastword = NULL;
 
-#if defined(ART_USE_PORTABLE_COMPILER)
-  {
-    // We only use dlopen for loading with portable. See OatFile::Open.
-    void* dl_oat_so = dlopen(elf_filename.c_str(), RTLD_NOW);
-    ASSERT_TRUE(dl_oat_so != NULL) << dlerror();
-    dl_oatdata = dlsym(dl_oat_so, "oatdata");
-    ASSERT_TRUE(dl_oatdata != NULL);
-
-    OatHeader* dl_oat_header = reinterpret_cast<OatHeader*>(dl_oatdata);
-    ASSERT_TRUE(dl_oat_header->IsValid());
-    dl_oatexec = dlsym(dl_oat_so, "oatexec");
-    ASSERT_TRUE(dl_oatexec != NULL);
-    ASSERT_LT(dl_oatdata, dl_oatexec);
-
-    dl_oatlastword = dlsym(dl_oat_so, "oatlastword");
-    ASSERT_TRUE(dl_oatlastword != NULL);
-    ASSERT_LT(dl_oatexec, dl_oatlastword);
-
-    ASSERT_EQ(0, dlclose(dl_oat_so));
-  }
-#endif
-
   std::unique_ptr<File> file(OS::OpenFileForReading(elf_filename.c_str()));
   ASSERT_TRUE(file.get() != NULL);
   {
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index dac1ef4..cf97943 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -72,11 +72,6 @@
       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
       TimingLogger timings("ImageTest::WriteRead", false, false);
       TimingLogger::ScopedTiming t("CompileAll", &timings);
-      if (kUsePortableCompiler) {
-        // TODO: we disable this for portable so the test executes in a reasonable amount of time.
-        //       We shouldn't need to do this.
-        compiler_options_->SetCompilerFilter(CompilerOptions::kInterpretOnly);
-      }
       for (const DexFile* dex_file : class_linker->GetBootClassPath()) {
         dex_file->EnableWrite();
       }
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index eb1b5db..8c7d611 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -127,13 +127,6 @@
 
   jni_dlsym_lookup_offset_ = oat_file_->GetOatHeader().GetJniDlsymLookupOffset();
 
-  portable_imt_conflict_trampoline_offset_ =
-      oat_file_->GetOatHeader().GetPortableImtConflictTrampolineOffset();
-  portable_resolution_trampoline_offset_ =
-      oat_file_->GetOatHeader().GetPortableResolutionTrampolineOffset();
-  portable_to_interpreter_bridge_offset_ =
-      oat_file_->GetOatHeader().GetPortableToInterpreterBridgeOffset();
-
   quick_generic_jni_trampoline_offset_ =
       oat_file_->GetOatHeader().GetQuickGenericJniTrampolineOffset();
   quick_imt_conflict_trampoline_offset_ =
@@ -1099,8 +1092,6 @@
   // locations.
   // Copy all of the fields from the runtime methods to the target methods first since we did a
   // bytewise copy earlier.
-  copy->SetEntryPointFromPortableCompiledCodePtrSize<kVerifyNone>(
-      orig->GetEntryPointFromPortableCompiledCode(), target_ptr_size_);
   copy->SetEntryPointFromInterpreterPtrSize<kVerifyNone>(orig->GetEntryPointFromInterpreter(),
                                                          target_ptr_size_);
   copy->SetEntryPointFromJniPtrSize<kVerifyNone>(orig->GetEntryPointFromJni(), target_ptr_size_);
@@ -1110,14 +1101,10 @@
   // The resolution method has a special trampoline to call.
   Runtime* runtime = Runtime::Current();
   if (UNLIKELY(orig == runtime->GetResolutionMethod())) {
-    copy->SetEntryPointFromPortableCompiledCodePtrSize<kVerifyNone>(
-        GetOatAddress(portable_resolution_trampoline_offset_), target_ptr_size_);
     copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(
         GetOatAddress(quick_resolution_trampoline_offset_), target_ptr_size_);
   } else if (UNLIKELY(orig == runtime->GetImtConflictMethod() ||
                       orig == runtime->GetImtUnimplementedMethod())) {
-    copy->SetEntryPointFromPortableCompiledCodePtrSize<kVerifyNone>(
-        GetOatAddress(portable_imt_conflict_trampoline_offset_), target_ptr_size_);
     copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(
         GetOatAddress(quick_imt_conflict_trampoline_offset_), target_ptr_size_);
   } else {
@@ -1125,8 +1112,6 @@
     // resolution trampoline. Abstract methods never have code and so we need to make sure their
     // use results in an AbstractMethodError. We use the interpreter to achieve this.
     if (UNLIKELY(orig->IsAbstract())) {
-      copy->SetEntryPointFromPortableCompiledCodePtrSize<kVerifyNone>(
-          GetOatAddress(portable_to_interpreter_bridge_offset_), target_ptr_size_);
       copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(
           GetOatAddress(quick_to_interpreter_bridge_offset_), target_ptr_size_);
       copy->SetEntryPointFromInterpreterPtrSize<kVerifyNone>(
@@ -1137,29 +1122,6 @@
       const uint8_t* quick_code = GetQuickCode(orig, &quick_is_interpreted);
       copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(quick_code, target_ptr_size_);
 
-      // Portable entrypoint:
-      const uint8_t* portable_code = GetOatAddress(orig->GetPortableOatCodeOffset());
-      bool portable_is_interpreted = false;
-      if (portable_code != nullptr &&
-          (!orig->IsStatic() || orig->IsConstructor() || orig->GetDeclaringClass()->IsInitialized())) {
-        // We have code for a non-static or initialized method, just use the code.
-      } else if (portable_code == nullptr && orig->IsNative() &&
-          (!orig->IsStatic() || orig->GetDeclaringClass()->IsInitialized())) {
-        // Non-static or initialized native method missing compiled code, use generic JNI version.
-        // TODO: generic JNI support for LLVM.
-        portable_code = GetOatAddress(portable_resolution_trampoline_offset_);
-      } else if (portable_code == nullptr && !orig->IsNative()) {
-        // We don't have code at all for a non-native method, use the interpreter.
-        portable_code = GetOatAddress(portable_to_interpreter_bridge_offset_);
-        portable_is_interpreted = true;
-      } else {
-        CHECK(!orig->GetDeclaringClass()->IsInitialized());
-        // We have code for a static method, but need to go through the resolution stub for class
-        // initialization.
-        portable_code = GetOatAddress(portable_resolution_trampoline_offset_);
-      }
-      copy->SetEntryPointFromPortableCompiledCodePtrSize<kVerifyNone>(
-          portable_code, target_ptr_size_);
       // JNI entrypoint:
       if (orig->IsNative()) {
         // The native method's pointer is set to a stub to lookup via dlsym.
@@ -1170,7 +1132,7 @@
 
       // Interpreter entrypoint:
       // Set the interpreter entrypoint depending on whether there is compiled code or not.
-      uint32_t interpreter_code = (quick_is_interpreted && portable_is_interpreted)
+      uint32_t interpreter_code = (quick_is_interpreted)
           ? interpreter_to_interpreter_bridge_offset_
           : interpreter_to_compiled_code_bridge_offset_;
       EntryPointFromInterpreter* interpreter_entrypoint =
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index 4418879..53f5ce4 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -48,8 +48,7 @@
         image_end_(0), image_objects_offset_begin_(0), image_roots_address_(0), oat_file_(nullptr),
         oat_data_begin_(nullptr), interpreter_to_interpreter_bridge_offset_(0),
         interpreter_to_compiled_code_bridge_offset_(0), jni_dlsym_lookup_offset_(0),
-        portable_imt_conflict_trampoline_offset_(0), portable_resolution_trampoline_offset_(0),
-        portable_to_interpreter_bridge_offset_(0), quick_generic_jni_trampoline_offset_(0),
+        quick_generic_jni_trampoline_offset_(0),
         quick_imt_conflict_trampoline_offset_(0), quick_resolution_trampoline_offset_(0),
         quick_to_interpreter_bridge_offset_(0), compile_pic_(compile_pic),
         target_ptr_size_(InstructionSetPointerSize(compiler_driver_.GetInstructionSet())),
@@ -178,12 +177,9 @@
   }
 
   const uint8_t* GetOatAddress(uint32_t offset) const {
-#if !defined(ART_USE_PORTABLE_COMPILER)
     // With Quick, code is within the OatFile, as there are all in one
-    // .o ELF object. However with Portable, the code is always in
-    // different .o ELF objects.
+    // .o ELF object.
     DCHECK_LT(offset, oat_file_->Size());
-#endif
     if (offset == 0u) {
       return nullptr;
     }
@@ -302,9 +298,6 @@
   uint32_t interpreter_to_interpreter_bridge_offset_;
   uint32_t interpreter_to_compiled_code_bridge_offset_;
   uint32_t jni_dlsym_lookup_offset_;
-  uint32_t portable_imt_conflict_trampoline_offset_;
-  uint32_t portable_resolution_trampoline_offset_;
-  uint32_t portable_to_interpreter_bridge_offset_;
   uint32_t quick_generic_jni_trampoline_offset_;
   uint32_t quick_imt_conflict_trampoline_offset_;
   uint32_t quick_resolution_trampoline_offset_;
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 2755442..281e3fe 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -80,8 +80,6 @@
         CompileMethod(method);
         ASSERT_TRUE(method->GetEntryPointFromQuickCompiledCode() != nullptr)
             << method_name << " " << method_sig;
-        ASSERT_TRUE(method->GetEntryPointFromPortableCompiledCode() != nullptr)
-            << method_name << " " << method_sig;
       }
     }
   }
@@ -204,7 +202,6 @@
 }
 
 void JniCompilerTest::CompileAndRunNoArgMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo));
 
   EXPECT_EQ(0, gJava_MyClassNatives_foo_calls);
@@ -219,7 +216,6 @@
 JNI_TEST(CompileAndRunNoArgMethod)
 
 void JniCompilerTest::CompileAndRunIntMethodThroughStubImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "bar", "(I)I", nullptr);
   // calling through stub will link with &Java_MyClassNatives_bar
 
@@ -234,7 +230,6 @@
 JNI_TEST(CompileAndRunIntMethodThroughStub)
 
 void JniCompilerTest::CompileAndRunStaticIntMethodThroughStubImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "sbar", "(I)I", nullptr);
   // calling through stub will link with &Java_MyClassNatives_sbar
 
@@ -262,7 +257,6 @@
 }
 
 void JniCompilerTest::CompileAndRunIntMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooI", "(I)I",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooI));
 
@@ -293,7 +287,6 @@
 }
 
 void JniCompilerTest::CompileAndRunIntIntMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooII", "(II)I",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooII));
 
@@ -325,7 +318,6 @@
 }
 
 void JniCompilerTest::CompileAndRunLongLongMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooJJ", "(JJ)J",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooJJ));
 
@@ -358,7 +350,6 @@
 }
 
 void JniCompilerTest::CompileAndRunDoubleDoubleMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooDD", "(DD)D",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooDD));
 
@@ -390,7 +381,6 @@
 }
 
 void JniCompilerTest::CompileAndRun_fooJJ_synchronizedImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooJJ_synchronized", "(JJ)J",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooJJ_synchronized));
 
@@ -430,7 +420,6 @@
 }
 
 void JniCompilerTest::CompileAndRunIntObjectObjectMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooIOO",
                "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooIOO));
@@ -479,7 +468,6 @@
 }
 
 void JniCompilerTest::CompileAndRunStaticIntIntMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "fooSII", "(II)I",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooSII));
 
@@ -507,7 +495,6 @@
 }
 
 void JniCompilerTest::CompileAndRunStaticDoubleDoubleMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "fooSDD", "(DD)D",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooSDD));
 
@@ -535,7 +522,6 @@
 }
 
 void JniCompilerTest::RunStaticLogDoubleMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "logD", "(D)D", reinterpret_cast<void*>(&Java_MyClassNatives_logD));
 
   jdouble result = env_->CallStaticDoubleMethod(jklass_, jmethod_, 2.0);
@@ -549,7 +535,6 @@
 }
 
 void JniCompilerTest::RunStaticLogFloatMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "logF", "(F)F", reinterpret_cast<void*>(&Java_MyClassNatives_logF));
 
   jfloat result = env_->CallStaticFloatMethod(jklass_, jmethod_, 2.0);
@@ -571,7 +556,6 @@
 }
 
 void JniCompilerTest::RunStaticReturnTrueImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "returnTrue", "()Z", reinterpret_cast<void*>(&Java_MyClassNatives_returnTrue));
 
   jboolean result = env_->CallStaticBooleanMethod(jklass_, jmethod_);
@@ -581,7 +565,6 @@
 JNI_TEST(RunStaticReturnTrue)
 
 void JniCompilerTest::RunStaticReturnFalseImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "returnFalse", "()Z",
                reinterpret_cast<void*>(&Java_MyClassNatives_returnFalse));
 
@@ -592,7 +575,6 @@
 JNI_TEST(RunStaticReturnFalse)
 
 void JniCompilerTest::RunGenericStaticReturnIntImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "returnInt", "()I", reinterpret_cast<void*>(&Java_MyClassNatives_returnInt));
 
   jint result = env_->CallStaticIntMethod(jklass_, jmethod_);
@@ -626,7 +608,6 @@
 
 
 void JniCompilerTest::CompileAndRunStaticIntObjectObjectMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "fooSIOO",
                "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooSIOO));
@@ -684,7 +665,6 @@
 }
 
 void JniCompilerTest::CompileAndRunStaticSynchronizedIntObjectObjectMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "fooSSIOO",
                "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooSSIOO));
@@ -725,7 +705,6 @@
 }
 
 void JniCompilerTest::ExceptionHandlingImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   {
     ASSERT_FALSE(runtime_->IsStarted());
     ScopedObjectAccess soa(Thread::Current());
@@ -810,7 +789,6 @@
 }
 
 void JniCompilerTest::NativeStackTraceElementImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooI", "(I)I",
                reinterpret_cast<void*>(&Java_MyClassNatives_nativeUpCall));
   jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 10);
@@ -824,7 +802,6 @@
 }
 
 void JniCompilerTest::ReturnGlobalRefImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooO", "(Ljava/lang/Object;)Ljava/lang/Object;",
                reinterpret_cast<void*>(&Java_MyClassNatives_fooO));
   jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, jobj_);
@@ -844,7 +821,6 @@
 }
 
 void JniCompilerTest::LocalReferenceTableClearingTestImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "fooI", "(I)I", reinterpret_cast<void*>(&local_ref_test));
   // 1000 invocations of a method that adds 10 local references
   for (int i = 0; i < 1000; i++) {
@@ -865,7 +841,6 @@
 }
 
 void JniCompilerTest::JavaLangSystemArrayCopyImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V",
                reinterpret_cast<void*>(&my_arraycopy));
   env_->CallStaticVoidMethod(jklass_, jmethod_, jobj_, 1234, jklass_, 5678, 9876);
@@ -883,7 +858,6 @@
 }
 
 void JniCompilerTest::CompareAndSwapIntImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "compareAndSwapInt", "(Ljava/lang/Object;JII)Z",
                reinterpret_cast<void*>(&my_casi));
   jboolean result = env_->CallBooleanMethod(jobj_, jmethod_, jobj_, INT64_C(0x12345678ABCDEF88),
@@ -903,7 +877,6 @@
 }
 
 void JniCompilerTest::GetTextImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "getText", "(JLjava/lang/Object;JLjava/lang/Object;)I",
                reinterpret_cast<void*>(&my_gettext));
   jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 0x12345678ABCDEF88ll, jobj_,
@@ -931,7 +904,6 @@
 }
 
 void JniCompilerTest::GetSinkPropertiesNativeImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
                reinterpret_cast<void*>(&Java_MyClassNatives_GetSinkProperties));
 
@@ -957,12 +929,10 @@
 }
 
 void JniCompilerTest::UpcallReturnTypeChecking_InstanceImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "instanceMethodThatShouldReturnClass", "()Ljava/lang/Class;",
                reinterpret_cast<void*>(&Java_MyClassNatives_instanceMethodThatShouldReturnClass));
 
   CheckJniAbortCatcher check_jni_abort_catcher;
-  // TODO: check type of returns with portable JNI compiler.
   // This native method is bad, and tries to return a jstring as a jclass.
   env_->CallObjectMethod(jobj_, jmethod_);
   check_jni_abort_catcher.Check("attempt to return an instance of java.lang.String from java.lang.Class MyClassNatives.instanceMethodThatShouldReturnClass()");
@@ -977,12 +947,10 @@
 JNI_TEST(UpcallReturnTypeChecking_Instance)
 
 void JniCompilerTest::UpcallReturnTypeChecking_StaticImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "staticMethodThatShouldReturnClass", "()Ljava/lang/Class;",
                reinterpret_cast<void*>(&Java_MyClassNatives_staticMethodThatShouldReturnClass));
 
   CheckJniAbortCatcher check_jni_abort_catcher;
-  // TODO: check type of returns with portable JNI compiler.
   // This native method is bad, and tries to return a jstring as a jclass.
   env_->CallStaticObjectMethod(jklass_, jmethod_);
   check_jni_abort_catcher.Check("attempt to return an instance of java.lang.String from java.lang.Class MyClassNatives.staticMethodThatShouldReturnClass()");
@@ -1005,7 +973,6 @@
 }
 
 void JniCompilerTest::UpcallArgumentTypeChecking_InstanceImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "instanceMethodThatShouldTakeClass", "(ILjava/lang/Class;)V",
                reinterpret_cast<void*>(&Java_MyClassNatives_instanceMethodThatShouldTakeClass));
 
@@ -1018,7 +985,6 @@
 JNI_TEST(UpcallArgumentTypeChecking_Instance)
 
 void JniCompilerTest::UpcallArgumentTypeChecking_StaticImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "staticMethodThatShouldTakeClass", "(ILjava/lang/Class;)V",
                reinterpret_cast<void*>(&Java_MyClassNatives_staticMethodThatShouldTakeClass));
 
@@ -1041,7 +1007,6 @@
 }
 
 void JniCompilerTest::CompileAndRunFloatFloatMethodImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "checkFloats", "(FF)F",
                reinterpret_cast<void*>(&Java_MyClassNatives_checkFloats));
 
@@ -1071,7 +1036,6 @@
 }
 
 void JniCompilerTest::CheckParameterAlignImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "checkParameterAlign", "(IJ)V",
                reinterpret_cast<void*>(&Java_MyClassNatives_checkParameterAlign));
 
@@ -1486,7 +1450,6 @@
     "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V";
 
 void JniCompilerTest::MaxParamNumberImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "maxParamNumber", longSig,
                reinterpret_cast<void*>(&Java_MyClassNatives_maxParamNumber));
 
@@ -1512,7 +1475,6 @@
 JNI_TEST(MaxParamNumber)
 
 void JniCompilerTest::WithoutImplementationImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(false, "withoutImplementation", "()V", nullptr);
 
   env_->CallVoidMethod(jobj_, jmethod_);
@@ -1562,7 +1524,6 @@
 }
 
 void JniCompilerTest::StackArgsIntsFirstImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "stackArgsIntsFirst", "(IIIIIIIIIIFFFFFFFFFF)V",
                reinterpret_cast<void*>(&Java_MyClassNatives_stackArgsIntsFirst));
 
@@ -1633,7 +1594,6 @@
 }
 
 void JniCompilerTest::StackArgsFloatsFirstImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "stackArgsFloatsFirst", "(FFFFFFFFFFIIIIIIIIII)V",
                reinterpret_cast<void*>(&Java_MyClassNatives_stackArgsFloatsFirst));
 
@@ -1703,7 +1663,6 @@
 }
 
 void JniCompilerTest::StackArgsMixedImpl() {
-  TEST_DISABLED_FOR_PORTABLE();
   SetUpForTest(true, "stackArgsMixed", "(IFIFIFIFIFIFIFIFIFIF)V",
                reinterpret_cast<void*>(&Java_MyClassNatives_stackArgsMixed));
 
diff --git a/compiler/jni/portable/jni_compiler.cc b/compiler/jni/portable/jni_compiler.cc
deleted file mode 100644
index ff37d85..0000000
--- a/compiler/jni/portable/jni_compiler.cc
+++ /dev/null
@@ -1,322 +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 "jni_compiler.h"
-
-#include "base/logging.h"
-#include "class_linker.h"
-#include "compiled_method.h"
-#include "dex_file-inl.h"
-#include "driver/compiler_driver.h"
-#include "driver/dex_compilation_unit.h"
-#include "llvm/compiler_llvm.h"
-#include "llvm/ir_builder.h"
-#include "llvm/llvm_compilation_unit.h"
-#include "llvm/runtime_support_llvm_func.h"
-#include "llvm/utils_llvm.h"
-#include "mirror/art_method.h"
-#include "runtime.h"
-#include "stack.h"
-#include "thread.h"
-
-#include <llvm/ADT/SmallVector.h>
-#include <llvm/IR/BasicBlock.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/Type.h>
-
-namespace art {
-namespace llvm {
-
-using ::art::llvm::runtime_support::JniMethodEnd;
-using ::art::llvm::runtime_support::JniMethodEndSynchronized;
-using ::art::llvm::runtime_support::JniMethodEndWithReference;
-using ::art::llvm::runtime_support::JniMethodEndWithReferenceSynchronized;
-using ::art::llvm::runtime_support::JniMethodStart;
-using ::art::llvm::runtime_support::JniMethodStartSynchronized;
-using ::art::llvm::runtime_support::RuntimeId;
-
-JniCompiler::JniCompiler(LlvmCompilationUnit* cunit,
-                         CompilerDriver* driver,
-                         const DexCompilationUnit* dex_compilation_unit)
-    : cunit_(cunit), driver_(driver), module_(cunit_->GetModule()),
-      context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()),
-      dex_compilation_unit_(dex_compilation_unit),
-      func_(NULL), elf_func_idx_(0) {
-  // Check: Ensure that JNI compiler will only get "native" method
-  CHECK(dex_compilation_unit->IsNative());
-}
-
-CompiledMethod* JniCompiler::Compile() {
-  const bool is_static = dex_compilation_unit_->IsStatic();
-  const bool is_synchronized = dex_compilation_unit_->IsSynchronized();
-  const DexFile* dex_file = dex_compilation_unit_->GetDexFile();
-  DexFile::MethodId const& method_id =
-      dex_file->GetMethodId(dex_compilation_unit_->GetDexMethodIndex());
-  char const return_shorty = dex_file->GetMethodShorty(method_id)[0];
-  ::llvm::Value* this_object_or_class_object;
-
-  uint32_t method_idx = dex_compilation_unit_->GetDexMethodIndex();
-  std::string func_name(StringPrintf("jni_%s",
-                                     MangleForJni(PrettyMethod(method_idx, *dex_file)).c_str()));
-  CreateFunction(func_name);
-
-  // Set argument name
-  ::llvm::Function::arg_iterator arg_begin(func_->arg_begin());
-  ::llvm::Function::arg_iterator arg_end(func_->arg_end());
-  ::llvm::Function::arg_iterator arg_iter(arg_begin);
-
-  DCHECK_NE(arg_iter, arg_end);
-  arg_iter->setName("method");
-  ::llvm::Value* method_object_addr = arg_iter++;
-
-  if (!is_static) {
-    // Non-static, the second argument is "this object"
-    this_object_or_class_object = arg_iter++;
-  } else {
-    // Load class object
-    this_object_or_class_object =
-        irb_.LoadFromObjectOffset(method_object_addr,
-                                  mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
-                                  irb_.getJObjectTy(),
-                                  kTBAAConstJObject);
-  }
-  // Actual argument (ignore method and this object)
-  arg_begin = arg_iter;
-
-  // Count the number of Object* arguments
-  uint32_t handle_scope_size = 1;
-  // "this" object pointer for non-static
-  // "class" object pointer for static
-  for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
-#if !defined(NDEBUG)
-    arg_iter->setName(StringPrintf("a%u", i));
-#endif
-    if (arg_iter->getType() == irb_.getJObjectTy()) {
-      ++handle_scope_size;
-    }
-  }
-
-  // Shadow stack
-  ::llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(handle_scope_size);
-  ::llvm::AllocaInst* shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
-
-  // Store the dex pc
-  irb_.StoreToObjectOffset(shadow_frame_,
-                           ShadowFrame::DexPCOffset(),
-                           irb_.getInt32(DexFile::kDexNoIndex),
-                           kTBAAShadowFrame);
-
-  // Push the shadow frame
-  ::llvm::Value* shadow_frame_upcast = irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
-  ::llvm::Value* old_shadow_frame =
-      irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, handle_scope_size);
-
-  // Get JNIEnv
-  ::llvm::Value* jni_env_object_addr =
-      irb_.Runtime().EmitLoadFromThreadOffset(Thread::JniEnvOffset().Int32Value(),
-                                              irb_.getJObjectTy(),
-                                              kTBAARuntimeInfo);
-
-  // Get callee code_addr
-  ::llvm::Value* code_addr =
-      irb_.LoadFromObjectOffset(method_object_addr,
-                                mirror::ArtMethod::NativeMethodOffset().Int32Value(),
-                                GetFunctionType(dex_compilation_unit_->GetDexMethodIndex(),
-                                                is_static, true)->getPointerTo(),
-                                kTBAARuntimeInfo);
-
-  // Load actual parameters
-  std::vector< ::llvm::Value*> args;
-
-  // The 1st parameter: JNIEnv*
-  args.push_back(jni_env_object_addr);
-
-  // Variables for GetElementPtr
-  ::llvm::Value* gep_index[] = {
-    irb_.getInt32(0),  // No displacement for shadow frame pointer
-    irb_.getInt32(1),  // handle scope
-    NULL,
-  };
-
-  size_t handle_scope_member_index = 0;
-
-  // Store the "this object or class object" to handle scope
-  gep_index[2] = irb_.getInt32(handle_scope_member_index++);
-  ::llvm::Value* handle_scope_field_addr = irb_.CreateBitCast(irb_.CreateGEP(shadow_frame_, gep_index),
-                                                    irb_.getJObjectTy()->getPointerTo());
-  irb_.CreateStore(this_object_or_class_object, handle_scope_field_addr, kTBAAShadowFrame);
-  // Push the "this object or class object" to out args
-  this_object_or_class_object = irb_.CreateBitCast(handle_scope_field_addr, irb_.getJObjectTy());
-  args.push_back(this_object_or_class_object);
-  // Store arguments to handle scope, and push back to args
-  for (arg_iter = arg_begin; arg_iter != arg_end; ++arg_iter) {
-    if (arg_iter->getType() == irb_.getJObjectTy()) {
-      // Store the reference type arguments to handle scope
-      gep_index[2] = irb_.getInt32(handle_scope_member_index++);
-      ::llvm::Value* handle_scope_field_addr = irb_.CreateBitCast(irb_.CreateGEP(shadow_frame_, gep_index),
-                                                        irb_.getJObjectTy()->getPointerTo());
-      irb_.CreateStore(arg_iter, handle_scope_field_addr, kTBAAShadowFrame);
-      // Note null is placed in the handle scope but the jobject passed to the native code must be null
-      // (not a pointer into the handle scope as with regular references).
-      ::llvm::Value* equal_null = irb_.CreateICmpEQ(arg_iter, irb_.getJNull());
-      ::llvm::Value* arg =
-          irb_.CreateSelect(equal_null,
-                            irb_.getJNull(),
-                            irb_.CreateBitCast(handle_scope_field_addr, irb_.getJObjectTy()));
-      args.push_back(arg);
-    } else {
-      args.push_back(arg_iter);
-    }
-  }
-
-  ::llvm::Value* saved_local_ref_cookie;
-  {  // JniMethodStart
-    RuntimeId func_id = is_synchronized ? JniMethodStartSynchronized
-                                        : JniMethodStart;
-    ::llvm::SmallVector< ::llvm::Value*, 2> args;
-    if (is_synchronized) {
-      args.push_back(this_object_or_class_object);
-    }
-    args.push_back(irb_.Runtime().EmitGetCurrentThread());
-    saved_local_ref_cookie =
-        irb_.CreateCall(irb_.GetRuntime(func_id), args);
-  }
-
-  // Call!!!
-  ::llvm::Value* retval = irb_.CreateCall(code_addr, args);
-
-  {  // JniMethodEnd
-    bool is_return_ref = return_shorty == 'L';
-    RuntimeId func_id =
-        is_return_ref ? (is_synchronized ? JniMethodEndWithReferenceSynchronized
-                                         : JniMethodEndWithReference)
-                      : (is_synchronized ? JniMethodEndSynchronized
-                                         : JniMethodEnd);
-    ::llvm::SmallVector< ::llvm::Value*, 4> args;
-    if (is_return_ref) {
-      args.push_back(retval);
-    }
-    args.push_back(saved_local_ref_cookie);
-    if (is_synchronized) {
-      args.push_back(this_object_or_class_object);
-    }
-    args.push_back(irb_.Runtime().EmitGetCurrentThread());
-
-    ::llvm::Value* decoded_jobject =
-        irb_.CreateCall(irb_.GetRuntime(func_id), args);
-
-    // Return decoded jobject if return reference.
-    if (is_return_ref) {
-      retval = decoded_jobject;
-    }
-  }
-
-  // Pop the shadow frame
-  irb_.Runtime().EmitPopShadowFrame(old_shadow_frame);
-
-  // Return!
-  switch (return_shorty) {
-    case 'V':
-      irb_.CreateRetVoid();
-      break;
-    case 'Z':
-    case 'C':
-      irb_.CreateRet(irb_.CreateZExt(retval, irb_.getInt32Ty()));
-      break;
-    case 'B':
-    case 'S':
-      irb_.CreateRet(irb_.CreateSExt(retval, irb_.getInt32Ty()));
-      break;
-    default:
-      irb_.CreateRet(retval);
-      break;
-  }
-
-  // Verify the generated bitcode
-  VERIFY_LLVM_FUNCTION(*func_);
-
-  cunit_->Materialize();
-
-  return new CompiledMethod(*driver_, cunit_->GetInstructionSet(), cunit_->GetElfObject(),
-                            func_name);
-}
-
-
-void JniCompiler::CreateFunction(const std::string& func_name) {
-  CHECK_NE(0U, func_name.size());
-
-  const bool is_static = dex_compilation_unit_->IsStatic();
-
-  // Get function type
-  ::llvm::FunctionType* func_type =
-    GetFunctionType(dex_compilation_unit_->GetDexMethodIndex(), is_static, false);
-
-  // Create function
-  func_ = ::llvm::Function::Create(func_type, ::llvm::Function::InternalLinkage,
-                                   func_name, module_);
-
-  // Create basic block
-  ::llvm::BasicBlock* basic_block = ::llvm::BasicBlock::Create(*context_, "B0", func_);
-
-  // Set insert point
-  irb_.SetInsertPoint(basic_block);
-}
-
-
-::llvm::FunctionType* JniCompiler::GetFunctionType(uint32_t method_idx,
-                                                   bool is_static, bool is_native_function) {
-  // Get method signature
-  uint32_t shorty_size;
-  const char* shorty = dex_compilation_unit_->GetShorty(&shorty_size);
-  CHECK_GE(shorty_size, 1u);
-
-  // Get return type
-  ::llvm::Type* ret_type = NULL;
-  switch (shorty[0]) {
-    case 'V': ret_type =  irb_.getJVoidTy(); break;
-    case 'Z':
-    case 'B':
-    case 'C':
-    case 'S':
-    case 'I': ret_type =  irb_.getJIntTy(); break;
-    case 'F': ret_type =  irb_.getJFloatTy(); break;
-    case 'J': ret_type =  irb_.getJLongTy(); break;
-    case 'D': ret_type =  irb_.getJDoubleTy(); break;
-    case 'L': ret_type =  irb_.getJObjectTy(); break;
-    default: LOG(FATAL)  << "Unreachable: unexpected return type in shorty " << shorty;
-      UNREACHABLE();
-  }
-  // Get argument type
-  std::vector< ::llvm::Type*> args_type;
-
-  args_type.push_back(irb_.getJObjectTy());  // method object pointer
-
-  if (!is_static || is_native_function) {
-    // "this" object pointer for non-static
-    // "class" object pointer for static naitve
-    args_type.push_back(irb_.getJType('L'));
-  }
-
-  for (uint32_t i = 1; i < shorty_size; ++i) {
-    args_type.push_back(irb_.getJType(shorty[i]));
-  }
-
-  return ::llvm::FunctionType::get(ret_type, args_type, false);
-}
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/jni/portable/jni_compiler.h b/compiler/jni/portable/jni_compiler.h
deleted file mode 100644
index ffabfe6..0000000
--- a/compiler/jni/portable/jni_compiler.h
+++ /dev/null
@@ -1,87 +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_COMPILER_JNI_PORTABLE_JNI_COMPILER_H_
-#define ART_COMPILER_JNI_PORTABLE_JNI_COMPILER_H_
-
-#include <stdint.h>
-
-#include <string>
-
-namespace art {
-  class ClassLinker;
-  class CompiledMethod;
-  class CompilerDriver;
-  class DexFile;
-  class DexCompilationUnit;
-  namespace mirror {
-    class ArtMethod;
-    class ClassLoader;
-    class DexCache;
-  }  // namespace mirror
-}  // namespace art
-
-namespace llvm {
-  class AllocaInst;
-  class Function;
-  class FunctionType;
-  class BasicBlock;
-  class LLVMContext;
-  class Module;
-  class Type;
-  class Value;
-}  // namespace llvm
-
-namespace art {
-namespace llvm {
-
-class LlvmCompilationUnit;
-class IRBuilder;
-
-class JniCompiler {
- public:
-  JniCompiler(LlvmCompilationUnit* cunit,
-              CompilerDriver* driver,
-              const DexCompilationUnit* dex_compilation_unit);
-
-  CompiledMethod* Compile();
-
- private:
-  void CreateFunction(const std::string& symbol);
-
-  ::llvm::FunctionType* GetFunctionType(uint32_t method_idx,
-                                        bool is_static, bool is_target_function);
-
- private:
-  LlvmCompilationUnit* cunit_;
-  CompilerDriver* const driver_;
-
-  ::llvm::Module* module_;
-  ::llvm::LLVMContext* context_;
-  IRBuilder& irb_;
-
-  const DexCompilationUnit* const dex_compilation_unit_;
-
-  ::llvm::Function* func_;
-  uint16_t elf_func_idx_;
-};
-
-
-}  // namespace llvm
-}  // namespace art
-
-
-#endif  // ART_COMPILER_JNI_PORTABLE_JNI_COMPILER_H_
diff --git a/compiler/llvm/art_module.ll b/compiler/llvm/art_module.ll
deleted file mode 100644
index 233692c..0000000
--- a/compiler/llvm/art_module.ll
+++ /dev/null
@@ -1,153 +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.
-;;
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Type
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-%JavaObject = type opaque
-
-%ShadowFrame = type { i32                  ; Number of VRegs
-                    , %ShadowFrame*        ; Previous frame
-                    , %JavaObject*         ; Method object pointer
-                    , i32                  ; Line number for stack backtrace
-                    ; [0 x i32]            ; VRegs
-                    }
-
-declare void @__art_type_list(%JavaObject*, %ShadowFrame*)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Thread
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare %JavaObject* @art_portable_get_current_thread_from_code()
-declare %JavaObject* @art_portable_set_current_thread_from_code(%JavaObject*)
-
-declare void @art_portable_lock_object_from_code(%JavaObject*, %JavaObject*)
-declare void @art_portable_unlock_object_from_code(%JavaObject*, %JavaObject*)
-
-declare void @art_portable_test_suspend_from_code(%JavaObject*)
-
-declare %ShadowFrame* @art_portable_push_shadow_frame_from_code(%JavaObject*, %ShadowFrame*, %JavaObject*, i32)
-declare void @art_portable_pop_shadow_frame_from_code(%ShadowFrame*)
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Exception
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare %JavaObject* @art_portable_get_and_clear_exception(%JavaObject*)
-declare void @art_portable_throw_div_zero_from_code()
-declare void @art_portable_throw_array_bounds_from_code(i32, i32)
-declare void @art_portable_throw_no_such_method_from_code(i32)
-declare void @art_portable_throw_null_pointer_exception_from_code(i32)
-declare void @art_portable_throw_stack_overflow_from_code()
-declare void @art_portable_throw_exception_from_code(%JavaObject*)
-
-declare i32 @art_portable_find_catch_block_from_code(%JavaObject*, i32)
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Object Space
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare %JavaObject* @art_portable_alloc_object_from_code(i32, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_alloc_object_from_code_with_access_check(i32, %JavaObject*, %JavaObject*)
-
-declare %JavaObject* @art_portable_alloc_array_from_code(i32, %JavaObject*, i32, %JavaObject*)
-declare %JavaObject* @art_portable_alloc_array_from_code_with_access_check(i32, %JavaObject*, i32, %JavaObject*)
-declare %JavaObject* @art_portable_check_and_alloc_array_from_code(i32, %JavaObject*, i32, %JavaObject*)
-declare %JavaObject* @art_portable_check_and_alloc_array_from_code_with_access_check(i32, %JavaObject*, i32, %JavaObject*)
-
-declare void @art_portable_find_instance_field_from_code(i32, %JavaObject*)
-declare void @art_portable_find_static_field_from_code(i32, %JavaObject*)
-
-declare %JavaObject* @art_portable_find_static_method_from_code_with_access_check(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_find_direct_method_from_code_with_access_check(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_find_virtual_method_from_code_with_access_check(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_find_super_method_from_code_with_access_check(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_find_interface_method_from_code_with_access_check(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_find_interface_method_from_code(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-
-declare %JavaObject* @art_portable_initialize_static_storage_from_code(i32, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_initialize_type_from_code(i32, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_initialize_type_and_verify_access_from_code(i32, %JavaObject*, %JavaObject*)
-
-declare %JavaObject* @art_portable_resolve_string_from_code(%JavaObject*, i32)
-
-declare i32 @art_portable_set32_static_from_code(i32, %JavaObject*, i32)
-declare i32 @art_portable_set64_static_from_code(i32, %JavaObject*, i64)
-declare i32 @art_portable_set_obj_static_from_code(i32, %JavaObject*, %JavaObject*)
-
-declare i32 @art_portable_get32_static_from_code(i32, %JavaObject*)
-declare i64 @art_portable_get64_static_from_code(i32, %JavaObject*)
-declare %JavaObject* @art_portable_get_obj_static_from_code(i32, %JavaObject*)
-
-declare i32 @art_portable_set32_instance_from_code(i32, %JavaObject*, %JavaObject*, i32)
-declare i32 @art_portable_set64_instance_from_code(i32, %JavaObject*, %JavaObject*, i64)
-declare i32 @art_portable_set_obj_instance_from_code(i32, %JavaObject*, %JavaObject*, %JavaObject*)
-
-declare i32 @art_portable_get32_instance_from_code(i32, %JavaObject*, %JavaObject*)
-declare i64 @art_portable_get64_instance_from_code(i32, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_get_obj_instance_from_code(i32, %JavaObject*, %JavaObject*)
-
-declare %JavaObject* @art_portable_decode_jobject_in_thread(%JavaObject*, %JavaObject*)
-
-declare void @art_portable_fill_array_data_from_code(%JavaObject*, i32, %JavaObject*, i32)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Type Checking, in the nature of casting
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare i32 @art_portable_is_assignable_from_code(%JavaObject*, %JavaObject*)
-declare void @art_portable_check_cast_from_code(%JavaObject*, %JavaObject*)
-declare void @art_portable_check_put_array_element_from_code(%JavaObject*, %JavaObject*)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Math
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare i64 @art_d2l(double)
-declare i32 @art_d2i(double)
-declare i64 @art_f2l(float)
-declare i32 @art_f2i(float)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; JNI
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare i32 @art_portable_jni_method_start(%JavaObject*)
-declare i32 @art_portable_jni_method_start_synchronized(%JavaObject*, %JavaObject*)
-
-declare void @art_portable_jni_method_end(i32, %JavaObject*)
-declare void @art_portable_jni_method_end_synchronized(i32, %JavaObject*, %JavaObject*)
-declare %JavaObject* @art_portable_jni_method_end_with_reference(%JavaObject*, i32, %JavaObject*)
-declare %JavaObject* @art_portable_jni_method_end_with_reference_synchronized(%JavaObject*, i32, %JavaObject*, %JavaObject*)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Temporary runtime support, will be removed in the future
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-declare i1 @art_portable_is_exception_pending_from_code()
-
-declare void @art_portable_mark_gc_card_from_code(%JavaObject*, %JavaObject*)
-
-declare void @art_portable_proxy_invoke_handler_from_code(%JavaObject*, ...)
diff --git a/compiler/llvm/backend_options.h b/compiler/llvm/backend_options.h
deleted file mode 100644
index 2a08bda..0000000
--- a/compiler/llvm/backend_options.h
+++ /dev/null
@@ -1,50 +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_COMPILER_LLVM_BACKEND_OPTIONS_H_
-#define ART_COMPILER_LLVM_BACKEND_OPTIONS_H_
-
-#include <llvm/Support/CommandLine.h>
-
-#define DECLARE_ARM_BACKEND_OPTIONS \
-extern llvm::cl::opt<bool> EnableARMLongCalls; \
-extern llvm::cl::opt<bool> ReserveR9;
-
-#define INITIAL_ARM_BACKEND_OPTIONS \
-EnableARMLongCalls = true; \
-ReserveR9 = true;
-
-#define DECLARE_X86_BACKEND_OPTIONS
-#define INITIAL_X86_BACKEND_OPTIONS
-
-#define DECLARE_Mips_BACKEND_OPTIONS
-#define INITIAL_Mips_BACKEND_OPTIONS
-
-#define LLVM_TARGET(TargetName) DECLARE_##TargetName##_BACKEND_OPTIONS
-#include "llvm/Config/Targets.def"
-
-namespace art {
-namespace llvm {
-
-inline void InitialBackendOptions() {
-#define LLVM_TARGET(TargetName) INITIAL_##TargetName##_BACKEND_OPTIONS
-#include "llvm/Config/Targets.def"
-}
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_BACKEND_OPTIONS_H_
diff --git a/compiler/llvm/backend_types.h b/compiler/llvm/backend_types.h
deleted file mode 100644
index 8ca88dd..0000000
--- a/compiler/llvm/backend_types.h
+++ /dev/null
@@ -1,104 +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_COMPILER_LLVM_BACKEND_TYPES_H_
-#define ART_COMPILER_LLVM_BACKEND_TYPES_H_
-
-#include "base/logging.h"
-
-
-namespace art {
-namespace llvm {
-
-
-enum JType {
-  kVoid,
-  kBoolean,
-  kByte,
-  kChar,
-  kShort,
-  kInt,
-  kLong,
-  kFloat,
-  kDouble,
-  kObject,
-  MAX_JTYPE
-};
-
-enum TBAASpecialType {
-  kTBAARegister,
-  kTBAAStackTemp,
-  kTBAAHeapArray,
-  kTBAAHeapInstance,
-  kTBAAHeapStatic,
-  kTBAAJRuntime,
-  kTBAARuntimeInfo,
-  kTBAAShadowFrame,
-  kTBAAConstJObject,
-  MAX_TBAA_SPECIAL_TYPE
-};
-
-
-enum ExpectCond {
-  kLikely,
-  kUnlikely,
-  MAX_EXPECT
-};
-
-
-inline JType GetJTypeFromShorty(char shorty_jty) {
-  switch (shorty_jty) {
-  case 'V':
-    return kVoid;
-
-  case 'Z':
-    return kBoolean;
-
-  case 'B':
-    return kByte;
-
-  case 'C':
-    return kChar;
-
-  case 'S':
-    return kShort;
-
-  case 'I':
-    return kInt;
-
-  case 'J':
-    return kLong;
-
-  case 'F':
-    return kFloat;
-
-  case 'D':
-    return kDouble;
-
-  case 'L':
-    return kObject;
-
-  default:
-    LOG(FATAL) << "Unknown Dalvik shorty descriptor: " << shorty_jty;
-    return kVoid;
-  }
-}
-
-}  // namespace llvm
-}  // namespace art
-
-
-#endif  // ART_COMPILER_LLVM_BACKEND_TYPES_H_
diff --git a/compiler/llvm/compiler_llvm.cc b/compiler/llvm/compiler_llvm.cc
deleted file mode 100644
index 3aeecad..0000000
--- a/compiler/llvm/compiler_llvm.cc
+++ /dev/null
@@ -1,233 +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 "compiler_llvm.h"
-
-#include "backend_options.h"
-#include "base/stl_util.h"
-#include "class_linker.h"
-#include "compiled_method.h"
-#include "dex/verification_results.h"
-#include "dex/verified_method.h"
-#include "driver/compiler_driver.h"
-#include "driver/dex_compilation_unit.h"
-#include "globals.h"
-#include "ir_builder.h"
-#include "jni/portable/jni_compiler.h"
-#include "llvm_compilation_unit.h"
-#include "thread-inl.h"
-#include "utils_llvm.h"
-#include "verifier/method_verifier.h"
-
-#include <llvm/LinkAllPasses.h>
-#include <llvm/Support/ManagedStatic.h>
-#include <llvm/Support/TargetSelect.h>
-#include <llvm/Support/Threading.h>
-
-namespace art {
-void CompileOneMethod(CompilerDriver& driver,
-                      Compiler* compiler,
-                      const DexFile::CodeItem* code_item,
-                      uint32_t access_flags, InvokeType invoke_type,
-                      uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
-                      const DexFile& dex_file,
-                      void* llvm_info);
-}
-
-namespace llvm {
-  extern bool TimePassesIsEnabled;
-}
-
-namespace {
-
-pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;
-
-void InitializeLLVM() {
-  // Initialize LLVM internal data structure for multithreading
-  llvm::llvm_start_multithreaded();
-
-  // NOTE: Uncomment following line to show the time consumption of LLVM passes
-  // llvm::TimePassesIsEnabled = true;
-
-  // Initialize LLVM target-specific options.
-  art::llvm::InitialBackendOptions();
-
-  // Initialize LLVM target, MC subsystem, asm printer, and asm parser.
-  if (art::kIsTargetBuild) {
-    // Don't initialize all targets on device. Just initialize the device's native target
-    llvm::InitializeNativeTarget();
-    llvm::InitializeNativeTargetAsmPrinter();
-    llvm::InitializeNativeTargetAsmParser();
-  } else {
-    llvm::InitializeAllTargets();
-    llvm::InitializeAllTargetMCs();
-    llvm::InitializeAllAsmPrinters();
-    llvm::InitializeAllAsmParsers();
-  }
-
-  // Initialize LLVM optimization passes
-  llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();
-
-  llvm::initializeCore(registry);
-  llvm::initializeScalarOpts(registry);
-  llvm::initializeIPO(registry);
-  llvm::initializeAnalysis(registry);
-  llvm::initializeIPA(registry);
-  llvm::initializeTransformUtils(registry);
-  llvm::initializeInstCombine(registry);
-  llvm::initializeInstrumentation(registry);
-  llvm::initializeTarget(registry);
-}
-
-// The Guard to Shutdown LLVM
-// llvm::llvm_shutdown_obj llvm_guard;
-// TODO: We are commenting out this line because this will cause SEGV from
-// time to time.
-// Two reasons: (1) the order of the destruction of static objects, or
-//              (2) dlopen/dlclose side-effect on static objects.
-
-}  // anonymous namespace
-
-
-namespace art {
-namespace llvm {
-
-
-::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
-
-
-CompilerLLVM::CompilerLLVM(CompilerDriver* driver, InstructionSet insn_set)
-    : compiler_driver_(driver), insn_set_(insn_set),
-      next_cunit_id_lock_("compilation unit id lock"), next_cunit_id_(1) {
-
-  // Initialize LLVM libraries
-  pthread_once(&llvm_initialized, InitializeLLVM);
-}
-
-
-CompilerLLVM::~CompilerLLVM() {
-}
-
-
-LlvmCompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
-  MutexLock GUARD(Thread::Current(), next_cunit_id_lock_);
-  LlvmCompilationUnit* cunit = new LlvmCompilationUnit(this, next_cunit_id_++);
-  if (!bitcode_filename_.empty()) {
-    cunit->SetBitcodeFileName(StringPrintf("%s-%u",
-                                           bitcode_filename_.c_str(),
-                                           cunit->GetCompilationUnitId()));
-  }
-  return cunit;
-}
-
-
-CompiledMethod* CompilerLLVM::
-CompileDexMethod(DexCompilationUnit* dex_compilation_unit, InvokeType invoke_type) {
-  std::unique_ptr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
-
-  cunit->SetDexCompilationUnit(dex_compilation_unit);
-  cunit->SetCompilerDriver(compiler_driver_);
-  // TODO: consolidate ArtCompileMethods
-  CompileOneMethod(compiler_driver_,
-                   compiler_driver_->GetCompiler(),
-                   dex_compilation_unit->GetCodeItem(),
-                   dex_compilation_unit->GetAccessFlags(),
-                   invoke_type,
-                   dex_compilation_unit->GetClassDefIndex(),
-                   dex_compilation_unit->GetDexMethodIndex(),
-                   dex_compilation_unit->GetClassLoader(),
-                   *dex_compilation_unit->GetDexFile(),
-                   cunit.get());
-
-  cunit->Materialize();
-
-  return new CompiledMethod(*compiler_driver_, compiler_driver_->GetInstructionSet(),
-                            cunit->GetElfObject(),
-                            dex_compilation_unit->GetVerifiedMethod()->GetDexGcMap(),
-                            cunit->GetDexCompilationUnit()->GetSymbol());
-}
-
-
-CompiledMethod* CompilerLLVM::
-CompileNativeMethod(DexCompilationUnit* dex_compilation_unit) {
-  std::unique_ptr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
-
-  std::unique_ptr<JniCompiler> jni_compiler(
-      new JniCompiler(cunit.get(), compiler_driver_, dex_compilation_unit));
-
-  return jni_compiler->Compile();
-}
-
-
-static CompilerLLVM* ContextOf(art::CompilerDriver* driver) {
-  void *compiler_context = driver->GetCompilerContext();
-  CHECK(compiler_context != NULL);
-  return reinterpret_cast<CompilerLLVM*>(compiler_context);
-}
-
-static CompilerLLVM* ContextOf(const art::CompilerDriver& driver) {
-  void *compiler_context = driver.GetCompilerContext();
-  CHECK(compiler_context != NULL);
-  return reinterpret_cast<CompilerLLVM*>(compiler_context);
-}
-
-void ArtInitCompilerContext(CompilerDriver* driver) {
-  CHECK(driver->GetCompilerContext() == nullptr);
-
-  CompilerLLVM* compiler_llvm = new CompilerLLVM(driver, driver->GetInstructionSet());
-
-  driver->SetCompilerContext(compiler_llvm);
-}
-
-void ArtUnInitCompilerContext(CompilerDriver* driver) {
-  delete ContextOf(driver);
-  driver->SetCompilerContext(nullptr);
-}
-
-CompiledMethod* ArtCompileMethod(CompilerDriver* driver, const DexFile::CodeItem* code_item,
-                                 uint32_t access_flags, InvokeType invoke_type,
-                                 uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
-                                 const DexFile& dex_file) {
-  UNUSED(class_def_idx);  // TODO: this is used with Compiler::RequiresConstructorBarrier.
-  ClassLinker *class_linker = Runtime::Current()->GetClassLinker();
-
-  DexCompilationUnit dex_compilation_unit(nullptr, class_loader, class_linker, dex_file, code_item,
-                                          class_def_idx, method_idx, access_flags,
-                                          driver->GetVerifiedMethod(&dex_file, method_idx));
-  CompilerLLVM* compiler_llvm = ContextOf(driver);
-  CompiledMethod* result = compiler_llvm->CompileDexMethod(&dex_compilation_unit, invoke_type);
-  return result;
-}
-
-CompiledMethod* ArtLLVMJniCompileMethod(CompilerDriver* driver, uint32_t access_flags,
-                                        uint32_t method_idx, const DexFile& dex_file) {
-  ClassLinker *class_linker = Runtime::Current()->GetClassLinker();
-
-  DexCompilationUnit dex_compilation_unit(nullptr, nullptr, class_linker, dex_file, nullptr,
-                                          0, method_idx, access_flags, nullptr);
-
-  CompilerLLVM* compiler_llvm = ContextOf(driver);
-  CompiledMethod* result = compiler_llvm->CompileNativeMethod(&dex_compilation_unit);
-  return result;
-}
-
-void compilerLLVMSetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) {
-  ContextOf(driver)->SetBitcodeFileName(filename);
-}
-
-}  // namespace llvm
-}  // namespace art
-
diff --git a/compiler/llvm/compiler_llvm.h b/compiler/llvm/compiler_llvm.h
deleted file mode 100644
index 7d29198..0000000
--- a/compiler/llvm/compiler_llvm.h
+++ /dev/null
@@ -1,115 +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_COMPILER_LLVM_COMPILER_LLVM_H_
-#define ART_COMPILER_LLVM_COMPILER_LLVM_H_
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "dex_file.h"
-#include "driver/compiler_driver.h"
-#include "instruction_set.h"
-#include "mirror/object.h"
-
-namespace art {
-  class CompiledMethod;
-  class CompilerDriver;
-  class DexCompilationUnit;
-  namespace mirror {
-    class ArtMethod;
-    class ClassLoader;
-  }  // namespace mirror
-}  // namespace art
-
-
-namespace llvm {
-  class Function;
-  class LLVMContext;
-  class Module;
-  class PointerType;
-  class StructType;
-  class Type;
-}  // namespace llvm
-
-
-namespace art {
-namespace llvm {
-
-class LlvmCompilationUnit;
-class IRBuilder;
-
-class CompilerLLVM {
- public:
-  CompilerLLVM(CompilerDriver* driver, InstructionSet insn_set);
-
-  ~CompilerLLVM();
-
-  CompilerDriver* GetCompiler() const {
-    return compiler_driver_;
-  }
-
-  InstructionSet GetInstructionSet() const {
-    return insn_set_;
-  }
-
-  void SetBitcodeFileName(const std::string& filename) {
-    bitcode_filename_ = filename;
-  }
-
-  CompiledMethod* CompileDexMethod(DexCompilationUnit* dex_compilation_unit,
-                                   InvokeType invoke_type);
-
-  CompiledMethod* CompileGBCMethod(DexCompilationUnit* dex_compilation_unit, std::string* func);
-
-  CompiledMethod* CompileNativeMethod(DexCompilationUnit* dex_compilation_unit);
-
- private:
-  LlvmCompilationUnit* AllocateCompilationUnit();
-
-  CompilerDriver* const compiler_driver_;
-
-  const InstructionSet insn_set_;
-
-  Mutex next_cunit_id_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
-  size_t next_cunit_id_ GUARDED_BY(next_cunit_id_lock_);
-
-  std::string bitcode_filename_;
-
-  DISALLOW_COPY_AND_ASSIGN(CompilerLLVM);
-};
-
-void ArtInitCompilerContext(CompilerDriver* driver);
-
-void ArtUnInitCompilerContext(CompilerDriver* driver);
-
-CompiledMethod* ArtCompileMethod(CompilerDriver* driver, const DexFile::CodeItem* code_item,
-                                 uint32_t access_flags, InvokeType invoke_type,
-                                 uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
-                                 const DexFile& dex_file);
-
-CompiledMethod* ArtLLVMJniCompileMethod(CompilerDriver* driver, uint32_t access_flags,
-                                        uint32_t method_idx, const DexFile& dex_file);
-
-void compilerLLVMSetBitcodeFileName(const CompilerDriver& driver, const std::string& filename);
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_COMPILER_LLVM_H_
diff --git a/compiler/llvm/gbc_expander.cc b/compiler/llvm/gbc_expander.cc
deleted file mode 100644
index 902f8dd..0000000
--- a/compiler/llvm/gbc_expander.cc
+++ /dev/null
@@ -1,3796 +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 "dex_file.h"
-#include "dex_file-inl.h"
-#include "driver/compiler_driver.h"
-#include "driver/dex_compilation_unit.h"
-#include "intrinsic_helper.h"
-#include "ir_builder.h"
-#include "method_reference.h"
-#include "mirror/art_method.h"
-#include "mirror/array.h"
-#include "mirror/string.h"
-#include "thread.h"
-#include "utils_llvm.h"
-#include "verifier/method_verifier.h"
-
-#include "dex/compiler_ir.h"
-#include "dex/mir_graph.h"
-#include "dex/quick/mir_to_lir.h"
-
-#include <llvm/ADT/STLExtras.h>
-#include <llvm/IR/Intrinsics.h>
-#include <llvm/IR/Metadata.h>
-#include <llvm/Pass.h>
-#include <llvm/Support/CFG.h>
-#include <llvm/Support/InstIterator.h>
-
-#include <vector>
-#include <map>
-#include <utility>
-
-using ::art::kMIRIgnoreNullCheck;
-using ::art::kMIRIgnoreRangeCheck;
-using ::art::llvm::IRBuilder;
-using ::art::llvm::IntrinsicHelper;
-using ::art::llvm::JType;
-using ::art::llvm::RuntimeSupportBuilder;
-using ::art::llvm::kBoolean;
-using ::art::llvm::kByte;
-using ::art::llvm::kChar;
-using ::art::llvm::kDouble;
-using ::art::llvm::kFloat;
-using ::art::llvm::kInt;
-using ::art::llvm::kLikely;
-using ::art::llvm::kLong;
-using ::art::llvm::kObject;
-using ::art::llvm::kShort;
-using ::art::llvm::kTBAAConstJObject;
-using ::art::llvm::kTBAAHeapArray;
-using ::art::llvm::kTBAAHeapInstance;
-using ::art::llvm::kTBAAHeapStatic;
-using ::art::llvm::kTBAARegister;
-using ::art::llvm::kTBAARuntimeInfo;
-using ::art::llvm::kTBAAShadowFrame;
-using ::art::llvm::kUnlikely;
-using ::art::llvm::kVoid;
-using ::art::llvm::runtime_support::AllocArray;
-using ::art::llvm::runtime_support::AllocArrayWithAccessCheck;
-using ::art::llvm::runtime_support::AllocObject;
-using ::art::llvm::runtime_support::AllocObjectWithAccessCheck;
-using ::art::llvm::runtime_support::CheckAndAllocArray;
-using ::art::llvm::runtime_support::CheckAndAllocArrayWithAccessCheck;
-using ::art::llvm::runtime_support::CheckCast;
-using ::art::llvm::runtime_support::CheckPutArrayElement;
-using ::art::llvm::runtime_support::FillArrayData;
-using ::art::llvm::runtime_support::FindCatchBlock;
-using ::art::llvm::runtime_support::FindDirectMethodWithAccessCheck;
-using ::art::llvm::runtime_support::FindInterfaceMethod;
-using ::art::llvm::runtime_support::FindInterfaceMethodWithAccessCheck;
-using ::art::llvm::runtime_support::FindStaticMethodWithAccessCheck;
-using ::art::llvm::runtime_support::FindSuperMethodWithAccessCheck;
-using ::art::llvm::runtime_support::FindVirtualMethodWithAccessCheck;
-using ::art::llvm::runtime_support::Get32Instance;
-using ::art::llvm::runtime_support::Get32Static;
-using ::art::llvm::runtime_support::Get64Instance;
-using ::art::llvm::runtime_support::Get64Static;
-using ::art::llvm::runtime_support::GetObjectInstance;
-using ::art::llvm::runtime_support::GetObjectStatic;
-using ::art::llvm::runtime_support::InitializeStaticStorage;
-using ::art::llvm::runtime_support::InitializeType;
-using ::art::llvm::runtime_support::InitializeTypeAndVerifyAccess;
-using ::art::llvm::runtime_support::IsAssignable;
-using ::art::llvm::runtime_support::ResolveString;
-using ::art::llvm::runtime_support::RuntimeId;
-using ::art::llvm::runtime_support::Set32Instance;
-using ::art::llvm::runtime_support::Set32Static;
-using ::art::llvm::runtime_support::Set64Instance;
-using ::art::llvm::runtime_support::Set64Static;
-using ::art::llvm::runtime_support::SetObjectInstance;
-using ::art::llvm::runtime_support::SetObjectStatic;
-using ::art::llvm::runtime_support::ThrowDivZeroException;
-using ::art::llvm::runtime_support::ThrowException;
-using ::art::llvm::runtime_support::ThrowIndexOutOfBounds;
-using ::art::llvm::runtime_support::ThrowNullPointerException;
-using ::art::llvm::runtime_support::ThrowStackOverflowException;
-using ::art::llvm::runtime_support::art_d2i;
-using ::art::llvm::runtime_support::art_d2l;
-using ::art::llvm::runtime_support::art_f2i;
-using ::art::llvm::runtime_support::art_f2l;
-
-namespace art {
-extern char RemapShorty(char shortyType);
-}  // namespace art
-
-namespace {
-
-class GBCExpanderPass : public llvm::FunctionPass {
- private:
-  const IntrinsicHelper& intrinsic_helper_;
-  IRBuilder& irb_;
-
-  llvm::LLVMContext& context_;
-  RuntimeSupportBuilder& rtb_;
-
- private:
-  llvm::AllocaInst* shadow_frame_;
-  llvm::Value* old_shadow_frame_;
-
- private:
-  art::CompilerDriver* const driver_;
-
-  const art::DexCompilationUnit* const dex_compilation_unit_;
-
-  llvm::Function* func_;
-
-  std::vector<llvm::BasicBlock*> basic_blocks_;
-
-  std::vector<llvm::BasicBlock*> basic_block_landing_pads_;
-  llvm::BasicBlock* current_bb_;
-  std::map<llvm::BasicBlock*, std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*>>>
-      landing_pad_phi_mapping_;
-  llvm::BasicBlock* basic_block_unwind_;
-
-  // Maps each vreg to its shadow frame address.
-  std::vector<llvm::Value*> shadow_frame_vreg_addresses_;
-
-  bool changed_;
-
- private:
-  //----------------------------------------------------------------------------
-  // Constant for GBC expansion
-  //----------------------------------------------------------------------------
-  enum IntegerShiftKind {
-    kIntegerSHL,
-    kIntegerSHR,
-    kIntegerUSHR,
-  };
-
- private:
-  //----------------------------------------------------------------------------
-  // Helper function for GBC expansion
-  //----------------------------------------------------------------------------
-
-  llvm::Value* ExpandToRuntime(RuntimeId rt, llvm::CallInst& inst);
-
-  uint64_t LV2UInt(llvm::Value* lv) {
-    return llvm::cast<llvm::ConstantInt>(lv)->getZExtValue();
-  }
-
-  int64_t LV2SInt(llvm::Value* lv) {
-    return llvm::cast<llvm::ConstantInt>(lv)->getSExtValue();
-  }
-
- private:
-  // TODO: Almost all Emit* are directly copy-n-paste from MethodCompiler.
-  // Refactor these utility functions from MethodCompiler to avoid forking.
-
-  void EmitStackOverflowCheck(llvm::Instruction* first_non_alloca);
-
-  void RewriteFunction();
-
-  void RewriteBasicBlock(llvm::BasicBlock* original_block);
-
-  void UpdatePhiInstruction(llvm::BasicBlock* old_basic_block,
-                            llvm::BasicBlock* new_basic_block);
-
-
-  // Sign or zero extend category 1 types < 32bits in size to 32bits.
-  llvm::Value* SignOrZeroExtendCat1Types(llvm::Value* value, JType jty);
-
-  // Truncate category 1 types from 32bits to the given JType size.
-  llvm::Value* TruncateCat1Types(llvm::Value* value, JType jty);
-
-  //----------------------------------------------------------------------------
-  // Dex cache code generation helper function
-  //----------------------------------------------------------------------------
-  llvm::Value* EmitLoadDexCacheAddr(art::MemberOffset dex_cache_offset);
-
-  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::Value* EmitLoadArrayLength(llvm::Value* array);
-
-  llvm::Value* EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx);
-
-  llvm::Value* EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx,
-                                                     llvm::Value* this_addr);
-
-  llvm::Value* EmitArrayGEP(llvm::Value* array_addr,
-                            llvm::Value* index_value,
-                            JType elem_jty);
-
-  //----------------------------------------------------------------------------
-  // Invoke helper function
-  //----------------------------------------------------------------------------
-  llvm::Value* EmitInvoke(llvm::CallInst& call_inst);
-
-  //----------------------------------------------------------------------------
-  // Inlining helper functions
-  //----------------------------------------------------------------------------
-  bool EmitIntrinsic(llvm::CallInst& call_inst, llvm::Value** result);
-
-  bool EmitIntrinsicStringLengthOrIsEmpty(llvm::CallInst& call_inst,
-                                          llvm::Value** result, bool is_empty);
-
- private:
-  //----------------------------------------------------------------------------
-  // Expand Greenland intrinsics
-  //----------------------------------------------------------------------------
-  void Expand_TestSuspend(llvm::CallInst& call_inst);
-
-  void Expand_MarkGCCard(llvm::CallInst& call_inst);
-
-  llvm::Value* Expand_LoadStringFromDexCache(llvm::Value* string_idx_value);
-
-  llvm::Value* Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value);
-
-  void Expand_LockObject(llvm::Value* obj);
-
-  void Expand_UnlockObject(llvm::Value* obj);
-
-  llvm::Value* Expand_ArrayGet(llvm::Value* array_addr,
-                               llvm::Value* index_value,
-                               JType elem_jty);
-
-  void Expand_ArrayPut(llvm::Value* new_value,
-                       llvm::Value* array_addr,
-                       llvm::Value* index_value,
-                       JType elem_jty);
-
-  void Expand_FilledNewArray(llvm::CallInst& call_inst);
-
-  llvm::Value* Expand_IGetFast(llvm::Value* field_offset_value,
-                               llvm::Value* is_volatile_value,
-                               llvm::Value* object_addr,
-                               JType field_jty);
-
-  void Expand_IPutFast(llvm::Value* field_offset_value,
-                       llvm::Value* is_volatile_value,
-                       llvm::Value* object_addr,
-                       llvm::Value* new_value,
-                       JType field_jty);
-
-  llvm::Value* Expand_SGetFast(llvm::Value* static_storage_addr,
-                               llvm::Value* field_offset_value,
-                               llvm::Value* is_volatile_value,
-                               JType field_jty);
-
-  void Expand_SPutFast(llvm::Value* static_storage_addr,
-                       llvm::Value* field_offset_value,
-                       llvm::Value* is_volatile_value,
-                       llvm::Value* new_value,
-                       JType field_jty);
-
-  llvm::Value* Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr);
-
-  llvm::Value*
-  Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value);
-
-  llvm::Value*
-  Expand_GetVirtualCalleeMethodObjAddrFast(llvm::Value* vtable_idx_value,
-                                           llvm::Value* this_addr);
-
-  llvm::Value* Expand_Invoke(llvm::CallInst& call_inst);
-
-  llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty);
-
-  void Expand_AllocaShadowFrame(llvm::Value* num_vregs_value);
-
-  void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj);
-
-  void Expand_PopShadowFrame();
-
-  void Expand_UpdateDexPC(llvm::Value* dex_pc_value);
-
-  //----------------------------------------------------------------------------
-  // Quick
-  //----------------------------------------------------------------------------
-
-  llvm::Value* Expand_FPCompare(llvm::Value* src1_value,
-                                llvm::Value* src2_value,
-                                bool gt_bias);
-
-  llvm::Value* Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value);
-
-  llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq,
-                                          llvm::Value* cmp_lt);
-
-  llvm::Value* EmitLoadConstantClass(uint32_t dex_pc, uint32_t type_idx);
-  llvm::Value* EmitLoadStaticStorage(uint32_t dex_pc, uint32_t type_idx);
-
-  llvm::Value* Expand_HLIGet(llvm::CallInst& call_inst, JType field_jty);
-  void Expand_HLIPut(llvm::CallInst& call_inst, JType field_jty);
-
-  llvm::Value* Expand_HLSget(llvm::CallInst& call_inst, JType field_jty);
-  void Expand_HLSput(llvm::CallInst& call_inst, JType field_jty);
-
-  llvm::Value* Expand_HLArrayGet(llvm::CallInst& call_inst, JType field_jty);
-  void Expand_HLArrayPut(llvm::CallInst& call_inst, JType field_jty);
-
-  llvm::Value* Expand_ConstString(llvm::CallInst& call_inst);
-  llvm::Value* Expand_ConstClass(llvm::CallInst& call_inst);
-
-  void Expand_MonitorEnter(llvm::CallInst& call_inst);
-  void Expand_MonitorExit(llvm::CallInst& call_inst);
-
-  void Expand_HLCheckCast(llvm::CallInst& call_inst);
-  llvm::Value* Expand_InstanceOf(llvm::CallInst& call_inst);
-
-  llvm::Value* Expand_NewInstance(llvm::CallInst& call_inst);
-
-  llvm::Value* Expand_HLInvoke(llvm::CallInst& call_inst);
-
-  llvm::Value* Expand_OptArrayLength(llvm::CallInst& call_inst);
-  llvm::Value* Expand_NewArray(llvm::CallInst& call_inst);
-  llvm::Value* Expand_HLFilledNewArray(llvm::CallInst& call_inst);
-  void Expand_HLFillArrayData(llvm::CallInst& call_inst);
-
-  llvm::Value* EmitAllocNewArray(uint32_t dex_pc,
-                                 llvm::Value* array_length_value,
-                                 uint32_t type_idx,
-                                 bool is_filled_new_array);
-
-  llvm::Value* EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
-                                                        art::InvokeType invoke_type,
-                                                        llvm::Value* this_addr,
-                                                        uint32_t dex_pc,
-                                                        bool is_fast_path);
-
-  void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr);
-
-  void EmitUpdateDexPC(uint32_t dex_pc);
-
-  void EmitGuard_DivZeroException(uint32_t dex_pc,
-                                  llvm::Value* denominator,
-                                  JType op_jty);
-
-  void EmitGuard_NullPointerException(uint32_t dex_pc, llvm::Value* object,
-                                      int opt_flags);
-
-  void EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
-                                                llvm::Value* array,
-                                                llvm::Value* index,
-                                                int opt_flags);
-
-  llvm::FunctionType* GetFunctionType(llvm::Type* ret_type, uint32_t method_idx, bool is_static);
-
-  llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc);
-
-  llvm::BasicBlock* CreateBasicBlockWithDexPC(uint32_t dex_pc,
-                                              const char* postfix);
-
-  int32_t GetTryItemOffset(uint32_t dex_pc);
-
-  llvm::BasicBlock* GetLandingPadBasicBlock(uint32_t dex_pc);
-
-  llvm::BasicBlock* GetUnwindBasicBlock();
-
-  void EmitGuard_ExceptionLandingPad(uint32_t dex_pc);
-
-  void EmitBranchExceptionLandingPad(uint32_t dex_pc);
-
-  //----------------------------------------------------------------------------
-  // Expand Arithmetic Helper Intrinsics
-  //----------------------------------------------------------------------------
-
-  llvm::Value* Expand_IntegerShift(llvm::Value* src1_value,
-                                   llvm::Value* src2_value,
-                                   IntegerShiftKind kind,
-                                   JType op_jty);
-
- public:
-  static char ID;
-
-  GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
-                  art::CompilerDriver* driver, const art::DexCompilationUnit* dex_compilation_unit)
-      : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb),
-        context_(irb.getContext()), rtb_(irb.Runtime()),
-        shadow_frame_(NULL), old_shadow_frame_(NULL),
-        driver_(driver),
-        dex_compilation_unit_(dex_compilation_unit),
-        func_(NULL), current_bb_(NULL), basic_block_unwind_(NULL), changed_(false) {}
-
-  bool runOnFunction(llvm::Function& func);
-
- private:
-  void InsertStackOverflowCheck(llvm::Function& func);
-
-  llvm::Value* ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
-                               llvm::CallInst& call_inst);
-};
-
-char GBCExpanderPass::ID = 0;
-
-bool GBCExpanderPass::runOnFunction(llvm::Function& func) {
-  VLOG(compiler) << "GBC expansion on " << func.getName().str();
-
-  // Runtime support or stub
-  if (dex_compilation_unit_ == NULL) {
-    return false;
-  }
-
-  // Setup rewrite context
-  shadow_frame_ = NULL;
-  old_shadow_frame_ = NULL;
-  func_ = &func;
-  changed_ = false;  // Assume unchanged
-
-  shadow_frame_vreg_addresses_.resize(dex_compilation_unit_->GetCodeItem()->registers_size_, NULL);
-  basic_blocks_.resize(dex_compilation_unit_->GetCodeItem()->insns_size_in_code_units_);
-  basic_block_landing_pads_.resize(dex_compilation_unit_->GetCodeItem()->tries_size_, NULL);
-  basic_block_unwind_ = NULL;
-  for (llvm::Function::iterator bb_iter = func_->begin(), bb_end = func_->end();
-       bb_iter != bb_end;
-       ++bb_iter) {
-    if (bb_iter->begin()->getMetadata("DexOff") == NULL) {
-      continue;
-    }
-    uint32_t dex_pc = LV2UInt(bb_iter->begin()->getMetadata("DexOff")->getOperand(0));
-    basic_blocks_[dex_pc] = bb_iter;
-  }
-
-  // Insert stack overflow check
-  InsertStackOverflowCheck(func);  // TODO: Use intrinsic.
-
-  // Rewrite the intrinsics
-  RewriteFunction();
-
-  VERIFY_LLVM_FUNCTION(func);
-
-  return changed_;
-}
-
-void GBCExpanderPass::RewriteBasicBlock(llvm::BasicBlock* original_block) {
-  llvm::BasicBlock* curr_basic_block = original_block;
-
-  llvm::BasicBlock::iterator inst_iter = original_block->begin();
-  llvm::BasicBlock::iterator inst_end = original_block->end();
-
-  while (inst_iter != inst_end) {
-    llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst_iter);
-    IntrinsicHelper::IntrinsicId intr_id = IntrinsicHelper::UnknownId;
-
-    if (call_inst) {
-      llvm::Function* callee_func = call_inst->getCalledFunction();
-      intr_id = intrinsic_helper_.GetIntrinsicId(callee_func);
-    }
-
-    if (intr_id == IntrinsicHelper::UnknownId) {
-      // This is not intrinsic call.  Skip this instruction.
-      ++inst_iter;
-      continue;
-    }
-
-    // Rewrite the intrinsic and change the function
-    changed_ = true;
-    irb_.SetInsertPoint(inst_iter);
-
-    // Expand the intrinsic
-    if (llvm::Value* new_value = ExpandIntrinsic(intr_id, *call_inst)) {
-      inst_iter->replaceAllUsesWith(new_value);
-    }
-
-    // Remove the old intrinsic call instruction
-    llvm::BasicBlock::iterator old_inst = inst_iter++;
-    old_inst->eraseFromParent();
-
-    // Splice the instruction to the new basic block
-    llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock();
-    if (next_basic_block != curr_basic_block) {
-      next_basic_block->getInstList().splice(
-          irb_.GetInsertPoint(), curr_basic_block->getInstList(),
-          inst_iter, inst_end);
-      curr_basic_block = next_basic_block;
-      inst_end = curr_basic_block->end();
-    }
-  }
-}
-
-
-void GBCExpanderPass::RewriteFunction() {
-  size_t num_basic_blocks = func_->getBasicBlockList().size();
-  // NOTE: We are not using (bb_iter != bb_end) as the for-loop condition,
-  // because we will create new basic block while expanding the intrinsics.
-  // We only want to iterate through the input basic blocks.
-
-  landing_pad_phi_mapping_.clear();
-
-  for (llvm::Function::iterator bb_iter = func_->begin();
-       num_basic_blocks > 0; ++bb_iter, --num_basic_blocks) {
-    // Set insert point to current basic block.
-    irb_.SetInsertPoint(bb_iter);
-
-    current_bb_ = bb_iter;
-
-    // Rewrite the basic block
-    RewriteBasicBlock(bb_iter);
-
-    // Update the phi-instructions in the successor basic block
-    llvm::BasicBlock* last_block = irb_.GetInsertBlock();
-    if (last_block != bb_iter) {
-      UpdatePhiInstruction(bb_iter, last_block);
-    }
-  }
-
-  typedef std::map<llvm::PHINode*, llvm::PHINode*> HandlerPHIMap;
-  HandlerPHIMap handler_phi;
-  // Iterate every used landing pad basic block
-  for (size_t i = 0, ei = basic_block_landing_pads_.size(); i != ei; ++i) {
-    llvm::BasicBlock* lbb = basic_block_landing_pads_[i];
-    if (lbb == NULL) {
-      continue;
-    }
-
-    llvm::TerminatorInst* term_inst = lbb->getTerminator();
-    std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*>>& rewrite_pair
-        = landing_pad_phi_mapping_[lbb];
-    irb_.SetInsertPoint(lbb->begin());
-
-    // Iterate every succeeding basic block (catch block)
-    for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors();
-         succ_iter != succ_end; ++succ_iter) {
-      llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter);
-
-      // Iterate every phi instructions in the succeeding basic block
-      for (llvm::BasicBlock::iterator
-           inst_iter = succ_basic_block->begin(),
-           inst_end = succ_basic_block->end();
-           inst_iter != inst_end; ++inst_iter) {
-        llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter);
-
-        if (!phi) {
-          break;  // Meet non-phi instruction.  Done.
-        }
-
-        if (handler_phi[phi] == NULL) {
-          handler_phi[phi] = llvm::PHINode::Create(phi->getType(), 1);
-        }
-
-        // Create new_phi in landing pad
-        llvm::PHINode* new_phi = irb_.CreatePHI(phi->getType(), rewrite_pair.size());
-        // Insert all incoming value into new_phi by rewrite_pair
-        for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) {
-          llvm::BasicBlock* old_bb = rewrite_pair[j].first;
-          llvm::BasicBlock* new_bb = rewrite_pair[j].second;
-          new_phi->addIncoming(phi->getIncomingValueForBlock(old_bb), new_bb);
-        }
-        // Delete all incoming value from phi by rewrite_pair
-        for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) {
-          llvm::BasicBlock* old_bb = rewrite_pair[j].first;
-          int old_bb_idx = phi->getBasicBlockIndex(old_bb);
-          if (old_bb_idx >= 0) {
-            phi->removeIncomingValue(old_bb_idx, false);
-          }
-        }
-        // Insert new_phi into new handler phi
-        handler_phi[phi]->addIncoming(new_phi, lbb);
-      }
-    }
-  }
-
-  // Replace all handler phi
-  // We can't just use the old handler phi, because some exception edges will disappear after we
-  // compute fast-path.
-  for (HandlerPHIMap::iterator it = handler_phi.begin(); it != handler_phi.end(); ++it) {
-    llvm::PHINode* old_phi = it->first;
-    llvm::PHINode* new_phi = it->second;
-    new_phi->insertBefore(old_phi);
-    old_phi->replaceAllUsesWith(new_phi);
-    old_phi->eraseFromParent();
-  }
-}
-
-void GBCExpanderPass::UpdatePhiInstruction(llvm::BasicBlock* old_basic_block,
-                                           llvm::BasicBlock* new_basic_block) {
-  llvm::TerminatorInst* term_inst = new_basic_block->getTerminator();
-
-  if (!term_inst) {
-    return;  // No terminating instruction in new_basic_block.  Nothing to do.
-  }
-
-  // Iterate every succeeding basic block
-  for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors();
-       succ_iter != succ_end; ++succ_iter) {
-    llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter);
-
-    // Iterate every phi instructions in the succeeding basic block
-    for (llvm::BasicBlock::iterator
-         inst_iter = succ_basic_block->begin(),
-         inst_end = succ_basic_block->end();
-         inst_iter != inst_end; ++inst_iter) {
-      llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter);
-
-      if (!phi) {
-        break;  // Meet non-phi instruction.  Done.
-      }
-
-      // Update the incoming block of this phi instruction
-      for (llvm::PHINode::block_iterator
-           ibb_iter = phi->block_begin(), ibb_end = phi->block_end();
-           ibb_iter != ibb_end; ++ibb_iter) {
-        if (*ibb_iter == old_basic_block) {
-          *ibb_iter = new_basic_block;
-        }
-      }
-    }
-  }
-}
-
-llvm::Value* GBCExpanderPass::ExpandToRuntime(RuntimeId rt, llvm::CallInst& inst) {
-  // Some GBC intrinsic can directly replace with IBC runtime. "Directly" means
-  // the arguments passed to the GBC intrinsic are as the same as IBC runtime
-  // function, therefore only called function is needed to change.
-  unsigned num_args = inst.getNumArgOperands();
-
-  if (num_args <= 0) {
-    return irb_.CreateCall(irb_.GetRuntime(rt));
-  } else {
-    std::vector<llvm::Value*> args;
-    for (unsigned i = 0; i < num_args; i++) {
-      args.push_back(inst.getArgOperand(i));
-    }
-
-    return irb_.CreateCall(irb_.GetRuntime(rt), args);
-  }
-}
-
-void
-GBCExpanderPass::EmitStackOverflowCheck(llvm::Instruction* first_non_alloca) {
-  llvm::Function* func = first_non_alloca->getParent()->getParent();
-  llvm::Module* module = func->getParent();
-
-  // 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(art::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.
-  llvm::Type* ret_type = func->getReturnType();
-  if (ret_type->isVoidTy()) {
-    irb_.CreateRetVoid();
-  } else {
-    // The return value is ignored when there's an exception. MethodCompiler
-    // returns zero value under the the corresponding return type  in this case.
-    // GBCExpander returns LLVM undef value here for brevity
-    irb_.CreateRet(llvm::UndefValue::get(ret_type));
-  }
-
-  irb_.SetInsertPoint(block_continue);
-}
-
-llvm::Value* GBCExpanderPass::EmitLoadDexCacheAddr(art::MemberOffset offset) {
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  return irb_.LoadFromObjectOffset(method_object_addr,
-                                   offset.Int32Value(),
-                                   irb_.getJObjectTy(),
-                                   kTBAAConstJObject);
-}
-
-llvm::Value*
-GBCExpanderPass::EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) {
-  llvm::Value* resolved_type_dex_cache_addr =
-    EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheResolvedTypesOffset());
-
-  llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx);
-
-  return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value, kObject);
-}
-
-llvm::Value* GBCExpanderPass::
-EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) {
-  llvm::Value* resolved_method_dex_cache_addr =
-    EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheResolvedMethodsOffset());
-
-  llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx);
-
-  return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value, kObject);
-}
-
-llvm::Value* GBCExpanderPass::
-EmitLoadDexCacheStringFieldAddr(uint32_t string_idx) {
-  llvm::Value* string_dex_cache_addr =
-    EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheStringsOffset());
-
-  llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx);
-
-  return EmitArrayGEP(string_dex_cache_addr, string_idx_value, kObject);
-}
-
-llvm::Value* GBCExpanderPass::EmitLoadMethodObjectAddr() {
-  llvm::Function* parent_func = irb_.GetInsertBlock()->getParent();
-  return parent_func->arg_begin();
-}
-
-llvm::Value* GBCExpanderPass::EmitLoadArrayLength(llvm::Value* array) {
-  // Load array length
-  return irb_.LoadFromObjectOffset(array,
-                                   art::mirror::Array::LengthOffset().Int32Value(),
-                                   irb_.getJIntTy(),
-                                   kTBAAConstJObject);
-}
-
-llvm::Value*
-GBCExpanderPass::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* GBCExpanderPass::
-EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, llvm::Value* this_addr) {
-  // Load class object of *this* pointer
-  llvm::Value* class_object_addr =
-    irb_.LoadFromObjectOffset(this_addr,
-                              art::mirror::Object::ClassOffset().Int32Value(),
-                              irb_.getJObjectTy(),
-                              kTBAAConstJObject);
-
-  // Load vtable address
-  llvm::Value* vtable_addr =
-    irb_.LoadFromObjectOffset(class_object_addr,
-                              art::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);
-}
-
-// Emit Array GetElementPtr
-llvm::Value* GBCExpanderPass::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(art::mirror::Object*))) {
-    data_offset = art::mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
-  } else {
-    data_offset = art::mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
-  }
-
-  llvm::Constant* data_offset_value =
-    irb_.getPtrEquivInt(data_offset);
-
-  llvm::Type* elem_type = irb_.getJType(elem_jty);
-
-  llvm::Value* array_data_addr =
-    irb_.CreatePtrDisp(array_addr, data_offset_value,
-                       elem_type->getPointerTo());
-
-  return irb_.CreateGEP(array_data_addr, index_value);
-}
-
-llvm::Value* GBCExpanderPass::EmitInvoke(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  art::InvokeType invoke_type =
-      static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0)));
-  bool is_static = (invoke_type == art::kStatic);
-  art::MethodReference target_method(dex_compilation_unit_->GetDexFile(),
-                                     LV2UInt(call_inst.getArgOperand(1)));
-
-  // Load *this* actual parameter
-  llvm::Value* this_addr = (!is_static) ? call_inst.getArgOperand(3) : NULL;
-
-  // 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 = driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc,
-                                                 true, true,
-                                                 &invoke_type, &target_method,
-                                                 &vtable_idx,
-                                                 &direct_code, &direct_method);
-  // Load the method object
-  llvm::Value* callee_method_object_addr = NULL;
-
-  if (!is_fast_path) {
-    callee_method_object_addr =
-        EmitCallRuntimeForCalleeMethodObjectAddr(target_method.dex_method_index, invoke_type,
-                                                 this_addr, dex_pc, is_fast_path);
-  } else {
-    switch (invoke_type) {
-      case art::kStatic:
-      case art::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(target_method.dex_method_index);
-        }
-        break;
-
-      case art::kVirtual:
-        DCHECK_NE(vtable_idx, -1);
-        callee_method_object_addr =
-            EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr);
-        break;
-
-      case art::kSuper:
-        LOG(FATAL) << "invoke-super should be promoted to invoke-direct in "
-        "the fast path.";
-        break;
-
-      case art::kInterface:
-        callee_method_object_addr =
-            EmitCallRuntimeForCalleeMethodObjectAddr(target_method.dex_method_index,
-                                                     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
-
-  for (uint32_t i = 3; i < call_inst.getNumArgOperands(); ++i) {
-    args.push_back(call_inst.getArgOperand(i));
-  }
-
-  llvm::Value* code_addr;
-  llvm::Type* func_type = GetFunctionType(call_inst.getType(),
-                                          target_method.dex_method_index, is_static);
-  if (direct_code != 0u && direct_code != static_cast<uintptr_t>(-1)) {
-    code_addr =
-        irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_code),
-                            func_type->getPointerTo());
-  } else {
-    code_addr =
-        irb_.LoadFromObjectOffset(callee_method_object_addr,
-                                  art::mirror::ArtMethod::EntryPointFromPortableCompiledCodeOffset().Int32Value(),
-                                  func_type->getPointerTo(), kTBAARuntimeInfo);
-  }
-
-  // Invoke callee
-  EmitUpdateDexPC(dex_pc);
-  llvm::Value* retval = irb_.CreateCall(code_addr, args);
-  EmitGuard_ExceptionLandingPad(dex_pc);
-
-  return retval;
-}
-
-bool GBCExpanderPass::EmitIntrinsic(llvm::CallInst& call_inst,
-                                    llvm::Value** result) {
-  DCHECK(result != NULL);
-
-  uint32_t callee_method_idx = LV2UInt(call_inst.getArgOperand(1));
-  std::string callee_method_name(
-      PrettyMethod(callee_method_idx, *dex_compilation_unit_->GetDexFile()));
-
-  if (callee_method_name == "int java.lang.String.length()") {
-    return EmitIntrinsicStringLengthOrIsEmpty(call_inst, result,
-                                              false /* is_empty */);
-  }
-  if (callee_method_name == "boolean java.lang.String.isEmpty()") {
-    return EmitIntrinsicStringLengthOrIsEmpty(call_inst, result,
-                                              true /* is_empty */);
-  }
-
-  *result = NULL;
-  return false;
-}
-
-bool GBCExpanderPass::EmitIntrinsicStringLengthOrIsEmpty(llvm::CallInst& call_inst,
-                                                         llvm::Value** result,
-                                                         bool is_empty) {
-  art::InvokeType invoke_type =
-        static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0)));
-  DCHECK_NE(invoke_type, art::kStatic);
-  DCHECK_EQ(call_inst.getNumArgOperands(), 4U);
-
-  llvm::Value* this_object = call_inst.getArgOperand(3);
-  llvm::Value* string_count =
-      irb_.LoadFromObjectOffset(this_object,
-                                art::mirror::String::CountOffset().Int32Value(),
-                                irb_.getJIntTy(),
-                                kTBAAConstJObject);
-  if (is_empty) {
-    llvm::Value* count_equals_zero = irb_.CreateICmpEQ(string_count,
-                                                       irb_.getJInt(0));
-    llvm::Value* is_empty = irb_.CreateSelect(count_equals_zero,
-                                              irb_.getJBoolean(true),
-                                              irb_.getJBoolean(false));
-    is_empty = SignOrZeroExtendCat1Types(is_empty, kBoolean);
-    *result = is_empty;
-  } else {
-    *result = string_count;
-  }
-  return true;
-}
-
-void GBCExpanderPass::Expand_TestSuspend(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-
-  llvm::Value* suspend_count =
-      irb_.Runtime().EmitLoadFromThreadOffset(art::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 != art::DexFile::kDexNoIndex) {
-    EmitUpdateDexPC(dex_pc);
-  }
-  irb_.Runtime().EmitTestSuspend();
-
-  llvm::BasicBlock* basic_block_exception = CreateBasicBlockWithDexPC(dex_pc, "exception");
-  llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
-  irb_.CreateCondBr(exception_pending, basic_block_exception, basic_block_cont, kUnlikely);
-
-  irb_.SetInsertPoint(basic_block_exception);
-  llvm::Type* ret_type = call_inst.getParent()->getParent()->getReturnType();
-  if (ret_type->isVoidTy()) {
-    irb_.CreateRetVoid();
-  } else {
-    // The return value is ignored when there's an exception.
-    irb_.CreateRet(llvm::UndefValue::get(ret_type));
-  }
-
-  irb_.SetInsertPoint(basic_block_cont);
-  return;
-}
-
-void GBCExpanderPass::Expand_MarkGCCard(llvm::CallInst& call_inst) {
-  irb_.Runtime().EmitMarkGCCard(call_inst.getArgOperand(0), call_inst.getArgOperand(1));
-  return;
-}
-
-llvm::Value*
-GBCExpanderPass::Expand_LoadStringFromDexCache(llvm::Value* string_idx_value) {
-  uint32_t string_idx =
-    llvm::cast<llvm::ConstantInt>(string_idx_value)->getZExtValue();
-
-  llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
-
-  return irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
-}
-
-llvm::Value*
-GBCExpanderPass::Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value) {
-  uint32_t type_idx =
-    llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue();
-
-  llvm::Value* type_field_addr =
-    EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
-
-  return irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo);
-}
-
-void GBCExpanderPass::Expand_LockObject(llvm::Value* obj) {
-  rtb_.EmitLockObject(obj);
-  return;
-}
-
-void GBCExpanderPass::Expand_UnlockObject(llvm::Value* obj) {
-  rtb_.EmitUnlockObject(obj);
-  return;
-}
-
-llvm::Value* GBCExpanderPass::Expand_ArrayGet(llvm::Value* array_addr,
-                                              llvm::Value* index_value,
-                                              JType elem_jty) {
-  llvm::Value* array_elem_addr =
-    EmitArrayGEP(array_addr, index_value, elem_jty);
-
-  return irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty);
-}
-
-void GBCExpanderPass::Expand_ArrayPut(llvm::Value* new_value,
-                                      llvm::Value* array_addr,
-                                      llvm::Value* index_value,
-                                      JType elem_jty) {
-  llvm::Value* array_elem_addr =
-    EmitArrayGEP(array_addr, index_value, elem_jty);
-
-  irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty);
-
-  return;
-}
-
-void GBCExpanderPass::Expand_FilledNewArray(llvm::CallInst& call_inst) {
-  // Most of the codes refer to MethodCompiler::EmitInsn_FilledNewArray
-  llvm::Value* array = call_inst.getArgOperand(0);
-
-  uint32_t element_jty =
-    llvm::cast<llvm::ConstantInt>(call_inst.getArgOperand(1))->getZExtValue();
-
-  DCHECK_GT(call_inst.getNumArgOperands(), 2U);
-  unsigned num_elements = (call_inst.getNumArgOperands() - 2);
-
-  bool is_elem_int_ty = (static_cast<JType>(element_jty) == kInt);
-
-  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(art::mirror::Array::DataOffset(alignment).Int32Value());
-
-  llvm::Value* data_field_addr =
-    irb_.CreatePtrDisp(array, data_field_offset, field_type);
-
-  for (unsigned i = 0; i < num_elements; ++i) {
-    // Values to fill the array begin at the 3rd argument
-    llvm::Value* reg_value = call_inst.getArgOperand(2 + i);
-
-    irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray);
-
-    data_field_addr =
-      irb_.CreatePtrDisp(data_field_addr, elem_size, field_type);
-  }
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::Expand_IGetFast(llvm::Value* field_offset_value,
-                                              llvm::Value* /*is_volatile_value*/,
-                                              llvm::Value* object_addr,
-                                              JType field_jty) {
-  int field_offset =
-    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
-
-  DCHECK_GE(field_offset, 0);
-
-  llvm::PointerType* field_type =
-    irb_.getJType(field_jty)->getPointerTo();
-
-  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.
-  return irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty);
-}
-
-void GBCExpanderPass::Expand_IPutFast(llvm::Value* field_offset_value,
-                                      llvm::Value* /* is_volatile_value */,
-                                      llvm::Value* object_addr,
-                                      llvm::Value* new_value,
-                                      JType field_jty) {
-  int field_offset =
-    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
-
-  DCHECK_GE(field_offset, 0);
-
-  llvm::PointerType* field_type =
-    irb_.getJType(field_jty)->getPointerTo();
-
-  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);
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::Expand_SGetFast(llvm::Value* static_storage_addr,
-                                              llvm::Value* field_offset_value,
-                                              llvm::Value* /*is_volatile_value*/,
-                                              JType field_jty) {
-  int field_offset =
-    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
-
-  DCHECK_GE(field_offset, 0);
-
-  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)->getPointerTo());
-
-  // TODO: Check is_volatile.  We need to generate atomic store instruction
-  // when is_volatile is true.
-  return irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty);
-}
-
-void GBCExpanderPass::Expand_SPutFast(llvm::Value* static_storage_addr,
-                                      llvm::Value* field_offset_value,
-                                      llvm::Value* /* is_volatile_value */,
-                                      llvm::Value* new_value,
-                                      JType field_jty) {
-  int field_offset =
-    llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue();
-
-  DCHECK_GE(field_offset, 0);
-
-  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)->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);
-
-  return;
-}
-
-llvm::Value*
-GBCExpanderPass::Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr) {
-  return irb_.LoadFromObjectOffset(method_object_addr,
-                                   art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(),
-                                   irb_.getJObjectTy(),
-                                   kTBAAConstJObject);
-}
-
-llvm::Value*
-GBCExpanderPass::Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value) {
-  uint32_t callee_method_idx =
-    llvm::cast<llvm::ConstantInt>(callee_method_idx_value)->getZExtValue();
-
-  return EmitLoadSDCalleeMethodObjectAddr(callee_method_idx);
-}
-
-llvm::Value* GBCExpanderPass::Expand_GetVirtualCalleeMethodObjAddrFast(
-    llvm::Value* vtable_idx_value,
-    llvm::Value* this_addr) {
-  int vtable_idx =
-    llvm::cast<llvm::ConstantInt>(vtable_idx_value)->getSExtValue();
-
-  return EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr);
-}
-
-llvm::Value* GBCExpanderPass::Expand_Invoke(llvm::CallInst& call_inst) {
-  // Most of the codes refer to MethodCompiler::EmitInsn_Invoke
-  llvm::Value* callee_method_object_addr = call_inst.getArgOperand(0);
-  unsigned num_args = call_inst.getNumArgOperands();
-  llvm::Type* ret_type = call_inst.getType();
-
-  // Determine the function type of the callee method
-  std::vector<llvm::Type*> args_type;
-  std::vector<llvm::Value*> args;
-  for (unsigned i = 0; i < num_args; i++) {
-    args.push_back(call_inst.getArgOperand(i));
-    args_type.push_back(args[i]->getType());
-  }
-
-  llvm::FunctionType* callee_method_type =
-    llvm::FunctionType::get(ret_type, args_type, false);
-
-  llvm::Value* code_addr =
-    irb_.LoadFromObjectOffset(callee_method_object_addr,
-                              art::mirror::ArtMethod::EntryPointFromPortableCompiledCodeOffset().Int32Value(),
-                              callee_method_type->getPointerTo(),
-                              kTBAARuntimeInfo);
-
-  // Invoke callee
-  llvm::Value* retval = irb_.CreateCall(code_addr, args);
-
-  return retval;
-}
-
-llvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst,
-                                            bool is_div, JType op_jty) {
-  llvm::Value* dividend = call_inst.getArgOperand(0);
-  llvm::Value* divisor = call_inst.getArgOperand(1);
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  EmitGuard_DivZeroException(dex_pc, divisor, op_jty);
-  // Most of the codes refer to MethodCompiler::EmitIntDivRemResultComputation
-
-  // 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);
-  llvm::Value* zero = irb_.getJZero(op_jty);
-  llvm::Value* neg_one = llvm::ConstantInt::getSigned(op_type, -1);
-
-  llvm::Function* parent = irb_.GetInsertBlock()->getParent();
-  llvm::BasicBlock* eq_neg_one = llvm::BasicBlock::Create(context_, "", parent);
-  llvm::BasicBlock* ne_neg_one = llvm::BasicBlock::Create(context_, "", parent);
-  llvm::BasicBlock* neg_one_cont =
-    llvm::BasicBlock::Create(context_, "", parent);
-
-  llvm::Value* is_equal_neg_one = irb_.CreateICmpEQ(divisor, neg_one);
-  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 (is_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_.CreateBr(neg_one_cont);
-
-  // If divisor != -1, just do the division.
-  irb_.SetInsertPoint(ne_neg_one);
-  llvm::Value* ne_result;
-  if (is_div) {
-    ne_result = irb_.CreateSDiv(dividend, divisor);
-  } else {
-    ne_result = irb_.CreateSRem(dividend, divisor);
-  }
-  irb_.CreateBr(neg_one_cont);
-
-  irb_.SetInsertPoint(neg_one_cont);
-  llvm::PHINode* result = irb_.CreatePHI(op_type, 2);
-  result->addIncoming(eq_result, eq_neg_one);
-  result->addIncoming(ne_result, ne_neg_one);
-
-  return result;
-}
-
-void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_vregs_value) {
-  // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and
-  // MethodCompiler::EmitPushShadowFrame
-  uint16_t num_vregs =
-    llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue();
-
-  llvm::StructType* shadow_frame_type =
-    irb_.getShadowFrameTy(num_vregs);
-
-  // Create allocas at the start of entry block.
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  llvm::BasicBlock* entry_block = &func_->front();
-  irb_.SetInsertPoint(&entry_block->front());
-
-  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_.restoreIP(irb_ip_original);
-
-  // Push the shadow frame
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* shadow_frame_upcast =
-    irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
-
-  llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast,
-                                                 method_object_addr,
-                                                 num_vregs);
-
-  irb_.CreateStore(result, old_shadow_frame_, kTBAARegister);
-
-  return;
-}
-
-void GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx,
-                                     llvm::Value* value) {
-  unsigned vreg_idx = LV2UInt(entry_idx);
-  DCHECK_LT(vreg_idx, dex_compilation_unit_->GetCodeItem()->registers_size_);
-
-  llvm::Value* vreg_addr = shadow_frame_vreg_addresses_[vreg_idx];
-  if (UNLIKELY(vreg_addr == NULL)) {
-    DCHECK(shadow_frame_ != NULL);
-
-    llvm::Value* gep_index[] = {
-      irb_.getInt32(0),  // No pointer displacement
-      irb_.getInt32(1),  // VRegs
-      entry_idx  // Pointer field
-    };
-
-    // A shadow frame address must dominate every use in the function so we
-    // place it in the entry block right after the allocas.
-    llvm::BasicBlock::iterator first_non_alloca = func_->getEntryBlock().begin();
-    while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) {
-      ++first_non_alloca;
-    }
-
-    llvm::IRBuilderBase::InsertPoint ip = irb_.saveIP();
-    irb_.SetInsertPoint(static_cast<llvm::Instruction*>(first_non_alloca));
-    vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index);
-    shadow_frame_vreg_addresses_[vreg_idx] = vreg_addr;
-    irb_.restoreIP(ip);
-  }
-
-  irb_.CreateStore(value,
-                   irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()),
-                   kTBAAShadowFrame);
-  return;
-}
-
-void GBCExpanderPass::Expand_PopShadowFrame() {
-  if (old_shadow_frame_ == NULL) {
-    return;
-  }
-  rtb_.EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister));
-  return;
-}
-
-void GBCExpanderPass::Expand_UpdateDexPC(llvm::Value* dex_pc_value) {
-  irb_.StoreToObjectOffset(shadow_frame_,
-                           art::ShadowFrame::DexPCOffset(),
-                           dex_pc_value,
-                           kTBAAShadowFrame);
-  return;
-}
-
-void GBCExpanderPass::InsertStackOverflowCheck(llvm::Function& func) {
-  // All alloca instructions are generated in the first basic block of the
-  // function, and there are no alloca instructions after the first non-alloca
-  // instruction.
-
-  llvm::BasicBlock* first_basic_block = &func.front();
-
-  // Look for first non-alloca instruction
-  llvm::BasicBlock::iterator first_non_alloca = first_basic_block->begin();
-  while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) {
-    ++first_non_alloca;
-  }
-
-  irb_.SetInsertPoint(first_non_alloca);
-
-  // Insert stack overflow check codes before first_non_alloca (i.e., after all
-  // alloca instructions)
-  EmitStackOverflowCheck(&*first_non_alloca);
-
-  irb_.Runtime().EmitTestSuspend();
-
-  llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock();
-  if (next_basic_block != first_basic_block) {
-    // Splice the rest of the instruction to the continuing basic block
-    next_basic_block->getInstList().splice(
-        irb_.GetInsertPoint(), first_basic_block->getInstList(),
-        first_non_alloca, first_basic_block->end());
-
-    // Rewrite the basic block
-    RewriteBasicBlock(next_basic_block);
-
-    // Update the phi-instructions in the successor basic block
-    UpdatePhiInstruction(first_basic_block, irb_.GetInsertBlock());
-  }
-
-  // We have changed the basic block
-  changed_ = true;
-}
-
-// ==== High-level intrinsic expander ==========================================
-
-llvm::Value* GBCExpanderPass::Expand_FPCompare(llvm::Value* src1_value,
-                                               llvm::Value* src2_value,
-                                               bool gt_bias) {
-  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);
-  }
-
-  return EmitCompareResultSelection(cmp_eq, cmp_lt);
-}
-
-llvm::Value* GBCExpanderPass::Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value) {
-  llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value);
-  llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value);
-
-  return EmitCompareResultSelection(cmp_eq, cmp_lt);
-}
-
-llvm::Value* GBCExpanderPass::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;
-}
-
-llvm::Value* GBCExpanderPass::Expand_IntegerShift(llvm::Value* src1_value,
-                                                  llvm::Value* src2_value,
-                                                  IntegerShiftKind kind,
-                                                  JType op_jty) {
-  DCHECK(op_jty == kInt || op_jty == kLong);
-
-  // Mask and zero-extend RHS properly
-  if (op_jty == kInt) {
-    src2_value = irb_.CreateAnd(src2_value, 0x1f);
-  } else {
-    llvm::Value* masked_src2_value = irb_.CreateAnd(src2_value, 0x3f);
-    src2_value = irb_.CreateZExt(masked_src2_value, irb_.getJLongTy());
-  }
-
-  // Create integer shift llvm instruction
-  switch (kind) {
-  case kIntegerSHL:
-    return irb_.CreateShl(src1_value, src2_value);
-
-  case kIntegerSHR:
-    return irb_.CreateAShr(src1_value, src2_value);
-
-  case kIntegerUSHR:
-    return irb_.CreateLShr(src1_value, src2_value);
-
-  default:
-    LOG(FATAL) << "Unknown integer shift kind: " << kind;
-    return NULL;
-  }
-}
-
-llvm::Value* GBCExpanderPass::SignOrZeroExtendCat1Types(llvm::Value* value, JType jty) {
-  switch (jty) {
-    case kBoolean:
-    case kChar:
-      return irb_.CreateZExt(value, irb_.getJType(kInt));
-    case kByte:
-    case kShort:
-      return irb_.CreateSExt(value, irb_.getJType(kInt));
-    case kVoid:
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kObject:
-      return value;  // Nothing to do.
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-      return NULL;
-  }
-}
-
-llvm::Value* GBCExpanderPass::TruncateCat1Types(llvm::Value* value, JType jty) {
-  switch (jty) {
-    case kBoolean:
-    case kChar:
-    case kByte:
-    case kShort:
-      return irb_.CreateTrunc(value, irb_.getJType(jty));
-    case kVoid:
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kObject:
-      return value;  // Nothing to do.
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-      return NULL;
-  }
-}
-
-llvm::Value* GBCExpanderPass::Expand_HLArrayGet(llvm::CallInst& call_inst,
-                                                JType elem_jty) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* array_addr = call_inst.getArgOperand(1);
-  llvm::Value* index_value = call_inst.getArgOperand(2);
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags);
-  EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value,
-                                           opt_flags);
-
-  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);
-
-  return SignOrZeroExtendCat1Types(array_elem_value, elem_jty);
-}
-
-
-void GBCExpanderPass::Expand_HLArrayPut(llvm::CallInst& call_inst,
-                                        JType elem_jty) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* new_value = call_inst.getArgOperand(1);
-  llvm::Value* array_addr = call_inst.getArgOperand(2);
-  llvm::Value* index_value = call_inst.getArgOperand(3);
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags);
-  EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value,
-                                           opt_flags);
-
-  new_value = TruncateCat1Types(new_value, elem_jty);
-
-  llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty);
-
-  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);
-
-    EmitMarkGCCard(new_value, array_addr);
-  }
-
-  irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty);
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::Expand_HLIGet(llvm::CallInst& call_inst,
-                                            JType field_jty) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* object_addr = call_inst.getArgOperand(1);
-  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(2));
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags);
-
-  llvm::Value* field_value;
-
-  art::MemberOffset field_offset(0u);
-  bool is_volatile;
-  bool is_fast_path = driver_->ComputeInstanceFieldInfo(
-    field_idx, dex_compilation_unit_, false, &field_offset, &is_volatile);
-
-  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);
-
-    if (field_jty == kFloat || field_jty == kDouble) {
-      field_value = irb_.CreateBitCast(field_value, irb_.getJType(field_jty));
-    }
-  } else {
-    DCHECK_GE(field_offset.Int32Value(), 0);
-
-    llvm::PointerType* field_type =
-      irb_.getJType(field_jty)->getPointerTo();
-
-    llvm::ConstantInt* field_offset_value = irb_.getPtrEquivInt(field_offset.Int32Value());
-
-    llvm::Value* field_addr =
-      irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
-
-    field_value = irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty);
-    field_value = SignOrZeroExtendCat1Types(field_value, field_jty);
-
-    if (is_volatile) {
-      irb_.CreateMemoryBarrier(art::kLoadAny);
-    }
-  }
-
-  return field_value;
-}
-
-void GBCExpanderPass::Expand_HLIPut(llvm::CallInst& call_inst,
-                                    JType field_jty) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* new_value = call_inst.getArgOperand(1);
-  llvm::Value* object_addr = call_inst.getArgOperand(2);
-  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(3));
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags);
-
-  art::MemberOffset field_offset(0u);
-  bool is_volatile;
-  bool is_fast_path = driver_->ComputeInstanceFieldInfo(
-    field_idx, dex_compilation_unit_, true, &field_offset, &is_volatile);
-
-  if (!is_fast_path) {
-    llvm::Function* runtime_func;
-
-    if (field_jty == kFloat) {
-      new_value = irb_.CreateBitCast(new_value, irb_.getJType(kInt));
-    } else if (field_jty == kDouble) {
-      new_value = irb_.CreateBitCast(new_value, irb_.getJType(kLong));
-    }
-
-    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);
-
-  } else {
-    DCHECK_GE(field_offset.Int32Value(), 0);
-
-    if (is_volatile) {
-      irb_.CreateMemoryBarrier(art::kAnyStore);
-    }
-
-    llvm::PointerType* field_type =
-      irb_.getJType(field_jty)->getPointerTo();
-
-    llvm::Value* field_offset_value = irb_.getPtrEquivInt(field_offset.Int32Value());
-
-    llvm::Value* field_addr =
-      irb_.CreatePtrDisp(object_addr, field_offset_value, field_type);
-
-    new_value = TruncateCat1Types(new_value, field_jty);
-    irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty);
-
-    if (is_volatile) {
-      irb_.CreateMemoryBarrier(art::kAnyAny);
-    }
-
-    if (field_jty == kObject) {  // If put an object, mark the GC card table.
-      EmitMarkGCCard(new_value, object_addr);
-    }
-  }
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::EmitLoadConstantClass(uint32_t dex_pc,
-                                                    uint32_t type_idx) {
-  if (!driver_->CanAccessTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(),
-                                           *dex_compilation_unit_->GetDexFile(), 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);
-
-    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 (driver_->CanAssumeTypeIsPresentInDexCache(*dex_compilation_unit_->GetDexFile(), 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);
-
-    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;
-  }
-}
-
-llvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc,
-                                                    uint32_t type_idx) {
-  llvm::BasicBlock* block_load_static =
-    CreateBasicBlockWithDexPC(dex_pc, "load_static");
-
-  llvm::BasicBlock* block_check_init = CreateBasicBlockWithDexPC(dex_pc, "init");
-  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  // Load static storage from dex cache
-  llvm::Value* storage_field_addr = EmitLoadDexCacheResolvedTypeFieldAddr(type_idx);
-
-  llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo);
-
-  // Test: Is the class resolved?
-  llvm::Value* equal_null = irb_.CreateICmpEQ(storage_object_addr, irb_.getJNull());
-
-  irb_.CreateCondBr(equal_null, block_load_static, block_check_init, kUnlikely);
-
-  // storage_object_addr != null, so check if its initialized.
-  irb_.SetInsertPoint(block_check_init);
-
-  llvm::Value* class_status =
-      irb_.LoadFromObjectOffset(storage_object_addr,
-                                art::mirror::Class::StatusOffset().Int32Value(),
-                                irb_.getJIntTy(), kTBAAHeapInstance);
-
-  llvm::Value* is_not_initialized =
-      irb_.CreateICmpULT(class_status, irb_.getInt32(art::mirror::Class::kStatusInitialized));
-
-  irb_.CreateCondBr(is_not_initialized, 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);
-
-  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_check_init);
-  phi->addIncoming(loaded_storage_object_addr, block_after_load_static);
-
-  // Ensure load of status and load of value don't re-order.
-  irb_.CreateMemoryBarrier(art::kLoadAny);
-
-  return phi;
-}
-
-llvm::Value* GBCExpanderPass::Expand_HLSget(llvm::CallInst& call_inst,
-                                            JType field_jty) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0));
-
-  art::MemberOffset field_offset(0u);
-  uint32_t ssb_index;
-  bool is_referrers_class;
-  bool is_volatile;
-  bool is_initialized;
-
-  bool is_fast_path = driver_->ComputeStaticFieldInfo(
-    field_idx, dex_compilation_unit_, false,
-    &field_offset, &ssb_index, &is_referrers_class, &is_volatile, &is_initialized);
-
-  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(field_idx);
-
-    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);
-
-    if (field_jty == kFloat || field_jty == kDouble) {
-      static_field_value = irb_.CreateBitCast(static_field_value, irb_.getJType(field_jty));
-    }
-  } else {
-    DCHECK_GE(field_offset.Int32Value(), 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,
-                                  art::mirror::ArtMethod::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_NE(ssb_index, art::DexFile::kDexNoIndex);
-      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
-    }
-
-    llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset.Int32Value());
-
-    llvm::Value* static_field_addr =
-      irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
-                         irb_.getJType(field_jty)->getPointerTo());
-
-    static_field_value = irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty);
-    static_field_value = SignOrZeroExtendCat1Types(static_field_value, field_jty);
-
-    if (is_volatile) {
-      irb_.CreateMemoryBarrier(art::kLoadAny);
-    }
-  }
-
-  return static_field_value;
-}
-
-void GBCExpanderPass::Expand_HLSput(llvm::CallInst& call_inst,
-                                    JType field_jty) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0));
-  llvm::Value* new_value = call_inst.getArgOperand(1);
-
-  if (field_jty == kFloat || field_jty == kDouble) {
-    new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty));
-  }
-
-  art::MemberOffset field_offset(0u);
-  uint32_t ssb_index;
-  bool is_referrers_class;
-  bool is_volatile;
-  bool is_initialized;
-
-  bool is_fast_path = driver_->ComputeStaticFieldInfo(
-    field_idx, dex_compilation_unit_, true,
-    &field_offset, &ssb_index, &is_referrers_class, &is_volatile, &is_initialized);
-
-  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);
-    }
-
-    if (field_jty == kFloat) {
-      new_value = irb_.CreateBitCast(new_value, irb_.getJType(kInt));
-    } else if (field_jty == kDouble) {
-      new_value = irb_.CreateBitCast(new_value, irb_.getJType(kLong));
-    }
-
-    llvm::Constant* field_idx_value = irb_.getInt32(field_idx);
-
-    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);
-
-  } else {
-    DCHECK_GE(field_offset.Int32Value(), 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,
-                                  art::mirror::ArtMethod::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_NE(ssb_index, art::DexFile::kDexNoIndex);
-      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
-    }
-
-    if (is_volatile) {
-      irb_.CreateMemoryBarrier(art::kAnyStore);
-    }
-
-    llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset.Int32Value());
-
-    llvm::Value* static_field_addr =
-      irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value,
-                         irb_.getJType(field_jty)->getPointerTo());
-
-    new_value = TruncateCat1Types(new_value, field_jty);
-    irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty);
-
-    if (is_volatile) {
-      irb_.CreateMemoryBarrier(art::kAnyAny);
-    }
-
-    if (field_jty == kObject) {  // If put an object, mark the GC card table.
-      EmitMarkGCCard(new_value, static_storage_addr);
-    }
-  }
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::Expand_ConstString(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t string_idx = LV2UInt(call_inst.getArgOperand(0));
-
-  llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx);
-
-  llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo);
-
-  if (!driver_->CanAssumeStringIsPresentInDexCache(*dex_compilation_unit_->GetDexFile(),
-                                                   string_idx)) {
-    llvm::BasicBlock* block_str_exist =
-      CreateBasicBlockWithDexPC(dex_pc, "str_exist");
-
-    llvm::BasicBlock* block_str_resolve =
-      CreateBasicBlockWithDexPC(dex_pc, "str_resolve");
-
-    llvm::BasicBlock* block_cont =
-      CreateBasicBlockWithDexPC(dex_pc, "str_cont");
-
-    // 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);
-    irb_.CreateBr(block_cont);
-
-    // 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);
-
-    llvm::Value* result = irb_.CreateCall2(runtime_func, method_object_addr,
-                                           string_idx_value);
-
-    EmitGuard_ExceptionLandingPad(dex_pc);
-
-    irb_.CreateBr(block_cont);
-
-
-    llvm::BasicBlock* block_pre_cont = irb_.GetInsertBlock();
-
-    irb_.SetInsertPoint(block_cont);
-
-    llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2);
-
-    phi->addIncoming(string_addr, block_str_exist);
-    phi->addIncoming(result, block_pre_cont);
-
-    string_addr = phi;
-  }
-
-  return string_addr;
-}
-
-llvm::Value* GBCExpanderPass::Expand_ConstClass(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
-
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx);
-
-  return type_object_addr;
-}
-
-void GBCExpanderPass::Expand_MonitorEnter(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* object_addr = call_inst.getArgOperand(1);
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags);
-
-  EmitUpdateDexPC(dex_pc);
-
-  irb_.Runtime().EmitLockObject(object_addr);
-
-  return;
-}
-
-void GBCExpanderPass::Expand_MonitorExit(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  llvm::Value* object_addr = call_inst.getArgOperand(1);
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags);
-
-  EmitUpdateDexPC(dex_pc);
-
-  irb_.Runtime().EmitUnlockObject(object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc);
-
-  return;
-}
-
-void GBCExpanderPass::Expand_HLCheckCast(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
-  llvm::Value* object_addr = call_inst.getArgOperand(1);
-
-  llvm::BasicBlock* block_test_class =
-    CreateBasicBlockWithDexPC(dex_pc, "test_class");
-
-  llvm::BasicBlock* block_test_sub_class =
-    CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
-
-  llvm::BasicBlock* block_cont =
-    CreateBasicBlockWithDexPC(dex_pc, "checkcast_cont");
-
-  // 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, block_cont, block_test_class, kUnlikely);
-
-  // Test: Is the object instantiated from the given class?
-  irb_.SetInsertPoint(block_test_class);
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx);
-  DCHECK_EQ(art::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_cont, block_test_sub_class, kLikely);
-
-  // 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);
-
-  irb_.CreateBr(block_cont);
-
-  irb_.SetInsertPoint(block_cont);
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::Expand_InstanceOf(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
-  llvm::Value* object_addr = call_inst.getArgOperand(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::BasicBlock* block_cont =
-      CreateBasicBlockWithDexPC(dex_pc, "instance_of_cont");
-
-  // 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, kUnlikely);
-
-  irb_.SetInsertPoint(block_nullp);
-  irb_.CreateBr(block_cont);
-
-  // Test: Is the object instantiated from the given class?
-  irb_.SetInsertPoint(block_test_class);
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx);
-  DCHECK_EQ(art::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, kLikely);
-
-  irb_.SetInsertPoint(block_class_equals);
-  irb_.CreateBr(block_cont);
-
-  // 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);
-  irb_.CreateBr(block_cont);
-
-  irb_.SetInsertPoint(block_cont);
-
-  llvm::PHINode* phi = irb_.CreatePHI(irb_.getJIntTy(), 3);
-
-  phi->addIncoming(irb_.getJInt(0), block_nullp);
-  phi->addIncoming(irb_.getJInt(1), block_class_equals);
-  phi->addIncoming(result, block_test_sub_class);
-
-  return phi;
-}
-
-llvm::Value* GBCExpanderPass::Expand_NewInstance(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
-
-  llvm::Function* runtime_func;
-  if (driver_->CanAccessInstantiableTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(),
-                                                      *dex_compilation_unit_->GetDexFile(),
-                                                      type_idx)) {
-    runtime_func = irb_.GetRuntime(AllocObject);
-  } else {
-    runtime_func = irb_.GetRuntime(AllocObjectWithAccessCheck);
-  }
-
-  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_.CreateCall3(runtime_func, type_index_value, method_object_addr, thread_object_addr);
-
-  EmitGuard_ExceptionLandingPad(dex_pc);
-
-  return object_addr;
-}
-
-llvm::Value* GBCExpanderPass::Expand_HLInvoke(llvm::CallInst& call_inst) {
-  art::InvokeType invoke_type = static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0)));
-  bool is_static = (invoke_type == art::kStatic);
-
-  if (!is_static) {
-    // Test: Is *this* parameter equal to null?
-    uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-    llvm::Value* this_addr = call_inst.getArgOperand(3);
-    int opt_flags = LV2UInt(call_inst.getArgOperand(2));
-
-    EmitGuard_NullPointerException(dex_pc, this_addr, opt_flags);
-  }
-
-  llvm::Value* result = NULL;
-  if (EmitIntrinsic(call_inst, &result)) {
-    return result;
-  }
-
-  return EmitInvoke(call_inst);
-}
-
-llvm::Value* GBCExpanderPass::Expand_OptArrayLength(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  // Get the array object address
-  llvm::Value* array_addr = call_inst.getArgOperand(1);
-  int opt_flags = LV2UInt(call_inst.getArgOperand(0));
-
-  EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags);
-
-  // Get the array length and store it to the register
-  return EmitLoadArrayLength(array_addr);
-}
-
-llvm::Value* GBCExpanderPass::Expand_NewArray(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0));
-  llvm::Value* length = call_inst.getArgOperand(1);
-
-  return EmitAllocNewArray(dex_pc, length, type_idx, false);
-}
-
-llvm::Value* GBCExpanderPass::Expand_HLFilledNewArray(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  uint32_t type_idx = LV2UInt(call_inst.getArgOperand(1));
-  uint32_t length = call_inst.getNumArgOperands() - 3;
-
-  llvm::Value* object_addr =
-    EmitAllocNewArray(dex_pc, irb_.getInt32(length), type_idx, true);
-
-  if (length > 0) {
-    // Check for the element type
-    uint32_t type_desc_len = 0;
-    const char* type_desc =
-        dex_compilation_unit_->GetDexFile()->StringByTypeIdx(type_idx, &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(art::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 < length; ++i) {
-      llvm::Value* reg_value = call_inst.getArgOperand(i+3);
-
-      irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray);
-
-      data_field_addr =
-        irb_.CreatePtrDisp(data_field_addr, elem_size, field_type);
-    }
-  }
-
-  return object_addr;
-}
-
-void GBCExpanderPass::Expand_HLFillArrayData(llvm::CallInst& call_inst) {
-  uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           LV2SInt(call_inst.getArgOperand(0));
-  llvm::Value* array_addr = call_inst.getArgOperand(1);
-
-  const art::Instruction::ArrayDataPayload* payload =
-    reinterpret_cast<const art::Instruction::ArrayDataPayload*>(
-        dex_compilation_unit_->GetCodeItem()->insns_ + payload_offset);
-
-  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, 0);
-  } 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);
-  }
-
-  return;
-}
-
-llvm::Value* GBCExpanderPass::EmitAllocNewArray(uint32_t dex_pc,
-                                                llvm::Value* array_length_value,
-                                                uint32_t type_idx,
-                                                bool is_filled_new_array) {
-  llvm::Function* runtime_func;
-
-  bool skip_access_check =
-    driver_->CanAccessTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(),
-                                        *dex_compilation_unit_->GetDexFile(), type_idx);
-
-
-  if (is_filled_new_array) {
-    runtime_func = skip_access_check ?
-      irb_.GetRuntime(CheckAndAllocArray) :
-      irb_.GetRuntime(CheckAndAllocArrayWithAccessCheck);
-  } else {
-    runtime_func = skip_access_check ?
-      irb_.GetRuntime(AllocArray) :
-      irb_.GetRuntime(AllocArrayWithAccessCheck);
-  }
-
-  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);
-
-  return object_addr;
-}
-
-llvm::Value* GBCExpanderPass::
-EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx,
-                                         art::InvokeType invoke_type,
-                                         llvm::Value* this_addr,
-                                         uint32_t dex_pc,
-                                         bool is_fast_path) {
-  llvm::Function* runtime_func = NULL;
-
-  switch (invoke_type) {
-  case art::kStatic:
-    runtime_func = irb_.GetRuntime(FindStaticMethodWithAccessCheck);
-    break;
-
-  case art::kDirect:
-    runtime_func = irb_.GetRuntime(FindDirectMethodWithAccessCheck);
-    break;
-
-  case art::kVirtual:
-    runtime_func = irb_.GetRuntime(FindVirtualMethodWithAccessCheck);
-    break;
-
-  case art::kSuper:
-    runtime_func = irb_.GetRuntime(FindSuperMethodWithAccessCheck);
-    break;
-
-  case art::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, art::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);
-
-  return callee_method_object_addr;
-}
-
-void GBCExpanderPass::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 GBCExpanderPass::EmitUpdateDexPC(uint32_t dex_pc) {
-  if (shadow_frame_ == NULL) {
-    return;
-  }
-  irb_.StoreToObjectOffset(shadow_frame_,
-                           art::ShadowFrame::DexPCOffset(),
-                           irb_.getInt32(dex_pc),
-                           kTBAAShadowFrame);
-}
-
-void GBCExpanderPass::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 GBCExpanderPass::EmitGuard_NullPointerException(uint32_t dex_pc,
-                                                     llvm::Value* object,
-                                                     int opt_flags) {
-  bool ignore_null_check = ((opt_flags & MIR_IGNORE_NULL_CHECK) != 0);
-  if (ignore_null_check) {
-    llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc);
-    if (lpad) {
-      // There is at least one catch: create a "fake" conditional branch to
-      // keep the exception edge to the catch block.
-      landing_pad_phi_mapping_[lpad].push_back(
-          std::make_pair(current_bb_->getUniquePredecessor(),
-                         irb_.GetInsertBlock()));
-
-      llvm::BasicBlock* block_continue =
-          CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-      irb_.CreateCondBr(irb_.getFalse(), lpad, block_continue, kUnlikely);
-
-      irb_.SetInsertPoint(block_continue);
-    }
-  } else {
-    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);
-  }
-}
-
-void
-GBCExpanderPass::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc,
-                                                          llvm::Value* array,
-                                                          llvm::Value* index,
-                                                          int opt_flags) {
-  bool ignore_range_check = ((opt_flags & MIR_IGNORE_RANGE_CHECK) != 0);
-  if (ignore_range_check) {
-    llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc);
-    if (lpad) {
-      // There is at least one catch: create a "fake" conditional branch to
-      // keep the exception edge to the catch block.
-      landing_pad_phi_mapping_[lpad].push_back(
-          std::make_pair(current_bb_->getUniquePredecessor(),
-                         irb_.GetInsertBlock()));
-
-      llvm::BasicBlock* block_continue =
-          CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-      irb_.CreateCondBr(irb_.getFalse(), lpad, block_continue, kUnlikely);
-
-      irb_.SetInsertPoint(block_continue);
-    }
-  } else {
-    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);
-  }
-}
-
-llvm::FunctionType* GBCExpanderPass::GetFunctionType(llvm::Type* ret_type, uint32_t method_idx,
-                                                     bool is_static) {
-  // Get method signature
-  art::DexFile::MethodId const& method_id =
-      dex_compilation_unit_->GetDexFile()->GetMethodId(method_idx);
-
-  uint32_t shorty_size;
-  const char* shorty = dex_compilation_unit_->GetDexFile()->GetMethodShorty(method_id, &shorty_size);
-  CHECK_GE(shorty_size, 1u);
-
-  // 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'));  // "this" object pointer
-  }
-
-  for (uint32_t i = 1; i < shorty_size; ++i) {
-    char shorty_type = art::RemapShorty(shorty[i]);
-    args_type.push_back(irb_.getJType(shorty_type));
-  }
-
-  return llvm::FunctionType::get(ret_type, args_type, false);
-}
-
-
-llvm::BasicBlock* GBCExpanderPass::
-CreateBasicBlockWithDexPC(uint32_t dex_pc, const char* postfix) {
-  std::string name;
-
-#if !defined(NDEBUG)
-  art::StringAppendF(&name, "B%04x.%s", dex_pc, postfix);
-#endif
-
-  return llvm::BasicBlock::Create(context_, name, func_);
-}
-
-llvm::BasicBlock* GBCExpanderPass::GetBasicBlock(uint32_t dex_pc) {
-  DCHECK(dex_pc < dex_compilation_unit_->GetCodeItem()->insns_size_in_code_units_);
-  CHECK(basic_blocks_[dex_pc] != NULL);
-  return basic_blocks_[dex_pc];
-}
-
-int32_t GBCExpanderPass::GetTryItemOffset(uint32_t dex_pc) {
-  int32_t min = 0;
-  int32_t max = dex_compilation_unit_->GetCodeItem()->tries_size_ - 1;
-
-  while (min <= max) {
-    int32_t mid = min + (max - min) / 2;
-
-    const art::DexFile::TryItem* ti =
-        art::DexFile::GetTryItems(*dex_compilation_unit_->GetCodeItem(), 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* GBCExpanderPass::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 art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*dex_compilation_unit_->GetCodeItem(),
-                                                              ti_offset);
-
-  std::string lpadname;
-
-#if !defined(NDEBUG)
-  art::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
-  art::CatchHandlerIterator iter(*dex_compilation_unit_->GetCodeItem(), 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* GBCExpanderPass::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
-  Expand_PopShadowFrame();
-
-  // Emit the code to return default value (zero) for the given return type.
-  char ret_shorty = dex_compilation_unit_->GetShorty()[0];
-  ret_shorty = art::RemapShorty(ret_shorty);
-  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_;
-}
-
-void GBCExpanderPass::EmitBranchExceptionLandingPad(uint32_t dex_pc) {
-  if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
-    landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(),
-                                                            irb_.GetInsertBlock()));
-    irb_.CreateBr(lpad);
-  } else {
-    irb_.CreateBr(GetUnwindBasicBlock());
-  }
-}
-
-void GBCExpanderPass::EmitGuard_ExceptionLandingPad(uint32_t dex_pc) {
-  llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending();
-
-  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
-    landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(),
-                                                            irb_.GetInsertBlock()));
-    irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely);
-  } else {
-    irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely);
-  }
-
-  irb_.SetInsertPoint(block_cont);
-}
-
-llvm::Value*
-GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id,
-                                 llvm::CallInst& call_inst) {
-  switch (intr_id) {
-    //==- Thread -----------------------------------------------------------==//
-    case IntrinsicHelper::GetCurrentThread: {
-      return irb_.Runtime().EmitGetCurrentThread();
-    }
-    case IntrinsicHelper::CheckSuspend: {
-      Expand_TestSuspend(call_inst);
-      return NULL;
-    }
-    case IntrinsicHelper::TestSuspend: {
-      Expand_TestSuspend(call_inst);
-      return NULL;
-    }
-    case IntrinsicHelper::MarkGCCard: {
-      Expand_MarkGCCard(call_inst);
-      return NULL;
-    }
-
-    //==- Exception --------------------------------------------------------==//
-    case IntrinsicHelper::ThrowException: {
-      return ExpandToRuntime(ThrowException, call_inst);
-    }
-    case IntrinsicHelper::HLThrowException: {
-      uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0));
-
-      EmitUpdateDexPC(dex_pc);
-
-      irb_.CreateCall(irb_.GetRuntime(ThrowException),
-                      call_inst.getArgOperand(0));
-
-      EmitGuard_ExceptionLandingPad(dex_pc);
-      return NULL;
-    }
-    case IntrinsicHelper::GetException: {
-      return irb_.Runtime().EmitGetAndClearException();
-    }
-    case IntrinsicHelper::IsExceptionPending: {
-      return irb_.Runtime().EmitIsExceptionPending();
-    }
-    case IntrinsicHelper::FindCatchBlock: {
-      return ExpandToRuntime(FindCatchBlock, call_inst);
-    }
-    case IntrinsicHelper::ThrowDivZeroException: {
-      return ExpandToRuntime(ThrowDivZeroException, call_inst);
-    }
-    case IntrinsicHelper::ThrowNullPointerException: {
-      return ExpandToRuntime(ThrowNullPointerException, call_inst);
-    }
-    case IntrinsicHelper::ThrowIndexOutOfBounds: {
-      return ExpandToRuntime(ThrowIndexOutOfBounds, call_inst);
-    }
-
-    //==- Const String -----------------------------------------------------==//
-    case IntrinsicHelper::ConstString: {
-      return Expand_ConstString(call_inst);
-    }
-    case IntrinsicHelper::LoadStringFromDexCache: {
-      return Expand_LoadStringFromDexCache(call_inst.getArgOperand(0));
-    }
-    case IntrinsicHelper::ResolveString: {
-      return ExpandToRuntime(ResolveString, call_inst);
-    }
-
-    //==- Const Class ------------------------------------------------------==//
-    case IntrinsicHelper::ConstClass: {
-      return Expand_ConstClass(call_inst);
-    }
-    case IntrinsicHelper::InitializeTypeAndVerifyAccess: {
-      return ExpandToRuntime(InitializeTypeAndVerifyAccess, call_inst);
-    }
-    case IntrinsicHelper::LoadTypeFromDexCache: {
-      return Expand_LoadTypeFromDexCache(call_inst.getArgOperand(0));
-    }
-    case IntrinsicHelper::InitializeType: {
-      return ExpandToRuntime(InitializeType, call_inst);
-    }
-
-    //==- Lock -------------------------------------------------------------==//
-    case IntrinsicHelper::LockObject: {
-      Expand_LockObject(call_inst.getArgOperand(0));
-      return NULL;
-    }
-    case IntrinsicHelper::UnlockObject: {
-      Expand_UnlockObject(call_inst.getArgOperand(0));
-      return NULL;
-    }
-
-    //==- Cast -------------------------------------------------------------==//
-    case IntrinsicHelper::CheckCast: {
-      return ExpandToRuntime(CheckCast, call_inst);
-    }
-    case IntrinsicHelper::HLCheckCast: {
-      Expand_HLCheckCast(call_inst);
-      return NULL;
-    }
-    case IntrinsicHelper::IsAssignable: {
-      return ExpandToRuntime(IsAssignable, call_inst);
-    }
-
-    //==- Alloc ------------------------------------------------------------==//
-    case IntrinsicHelper::AllocObject: {
-      return ExpandToRuntime(AllocObject, call_inst);
-    }
-    case IntrinsicHelper::AllocObjectWithAccessCheck: {
-      return ExpandToRuntime(AllocObjectWithAccessCheck, call_inst);
-    }
-
-    //==- Instance ---------------------------------------------------------==//
-    case IntrinsicHelper::NewInstance: {
-      return Expand_NewInstance(call_inst);
-    }
-    case IntrinsicHelper::InstanceOf: {
-      return Expand_InstanceOf(call_inst);
-    }
-
-    //==- Array ------------------------------------------------------------==//
-    case IntrinsicHelper::NewArray: {
-      return Expand_NewArray(call_inst);
-    }
-    case IntrinsicHelper::OptArrayLength: {
-      return Expand_OptArrayLength(call_inst);
-    }
-    case IntrinsicHelper::ArrayLength: {
-      return EmitLoadArrayLength(call_inst.getArgOperand(0));
-    }
-    case IntrinsicHelper::AllocArray: {
-      return ExpandToRuntime(AllocArray, call_inst);
-    }
-    case IntrinsicHelper::AllocArrayWithAccessCheck: {
-      return ExpandToRuntime(AllocArrayWithAccessCheck,
-                             call_inst);
-    }
-    case IntrinsicHelper::CheckAndAllocArray: {
-      return ExpandToRuntime(CheckAndAllocArray, call_inst);
-    }
-    case IntrinsicHelper::CheckAndAllocArrayWithAccessCheck: {
-      return ExpandToRuntime(CheckAndAllocArrayWithAccessCheck,
-                             call_inst);
-    }
-    case IntrinsicHelper::ArrayGet: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kInt);
-    }
-    case IntrinsicHelper::ArrayGetWide: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kLong);
-    }
-    case IntrinsicHelper::ArrayGetObject: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kObject);
-    }
-    case IntrinsicHelper::ArrayGetBoolean: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kBoolean);
-    }
-    case IntrinsicHelper::ArrayGetByte: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kByte);
-    }
-    case IntrinsicHelper::ArrayGetChar: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kChar);
-    }
-    case IntrinsicHelper::ArrayGetShort: {
-      return Expand_ArrayGet(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             kShort);
-    }
-    case IntrinsicHelper::ArrayPut: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kInt);
-      return NULL;
-    }
-    case IntrinsicHelper::ArrayPutWide: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kLong);
-      return NULL;
-    }
-    case IntrinsicHelper::ArrayPutObject: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kObject);
-      return NULL;
-    }
-    case IntrinsicHelper::ArrayPutBoolean: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kBoolean);
-      return NULL;
-    }
-    case IntrinsicHelper::ArrayPutByte: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kByte);
-      return NULL;
-    }
-    case IntrinsicHelper::ArrayPutChar: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kChar);
-      return NULL;
-    }
-    case IntrinsicHelper::ArrayPutShort: {
-      Expand_ArrayPut(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      kShort);
-      return NULL;
-    }
-    case IntrinsicHelper::CheckPutArrayElement: {
-      return ExpandToRuntime(CheckPutArrayElement, call_inst);
-    }
-    case IntrinsicHelper::FilledNewArray: {
-      Expand_FilledNewArray(call_inst);
-      return NULL;
-    }
-    case IntrinsicHelper::FillArrayData: {
-      return ExpandToRuntime(FillArrayData, call_inst);
-    }
-    case IntrinsicHelper::HLFillArrayData: {
-      Expand_HLFillArrayData(call_inst);
-      return NULL;
-    }
-    case IntrinsicHelper::HLFilledNewArray: {
-      return Expand_HLFilledNewArray(call_inst);
-    }
-
-    //==- Instance Field ---------------------------------------------------==//
-    case IntrinsicHelper::InstanceFieldGet:
-    case IntrinsicHelper::InstanceFieldGetBoolean:
-    case IntrinsicHelper::InstanceFieldGetByte:
-    case IntrinsicHelper::InstanceFieldGetChar:
-    case IntrinsicHelper::InstanceFieldGetShort: {
-      return ExpandToRuntime(Get32Instance, call_inst);
-    }
-    case IntrinsicHelper::InstanceFieldGetWide: {
-      return ExpandToRuntime(Get64Instance, call_inst);
-    }
-    case IntrinsicHelper::InstanceFieldGetObject: {
-      return ExpandToRuntime(GetObjectInstance, call_inst);
-    }
-    case IntrinsicHelper::InstanceFieldGetFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kInt);
-    }
-    case IntrinsicHelper::InstanceFieldGetWideFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kLong);
-    }
-    case IntrinsicHelper::InstanceFieldGetObjectFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kObject);
-    }
-    case IntrinsicHelper::InstanceFieldGetBooleanFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kBoolean);
-    }
-    case IntrinsicHelper::InstanceFieldGetByteFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kByte);
-    }
-    case IntrinsicHelper::InstanceFieldGetCharFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kChar);
-    }
-    case IntrinsicHelper::InstanceFieldGetShortFast: {
-      return Expand_IGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kShort);
-    }
-    case IntrinsicHelper::InstanceFieldPut:
-    case IntrinsicHelper::InstanceFieldPutBoolean:
-    case IntrinsicHelper::InstanceFieldPutByte:
-    case IntrinsicHelper::InstanceFieldPutChar:
-    case IntrinsicHelper::InstanceFieldPutShort: {
-      return ExpandToRuntime(Set32Instance, call_inst);
-    }
-    case IntrinsicHelper::InstanceFieldPutWide: {
-      return ExpandToRuntime(Set64Instance, call_inst);
-    }
-    case IntrinsicHelper::InstanceFieldPutObject: {
-      return ExpandToRuntime(SetObjectInstance, call_inst);
-    }
-    case IntrinsicHelper::InstanceFieldPutFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kInt);
-      return NULL;
-    }
-    case IntrinsicHelper::InstanceFieldPutWideFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kLong);
-      return NULL;
-    }
-    case IntrinsicHelper::InstanceFieldPutObjectFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kObject);
-      return NULL;
-    }
-    case IntrinsicHelper::InstanceFieldPutBooleanFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kBoolean);
-      return NULL;
-    }
-    case IntrinsicHelper::InstanceFieldPutByteFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kByte);
-      return NULL;
-    }
-    case IntrinsicHelper::InstanceFieldPutCharFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kChar);
-      return NULL;
-    }
-    case IntrinsicHelper::InstanceFieldPutShortFast: {
-      Expand_IPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kShort);
-      return NULL;
-    }
-
-    //==- Static Field -----------------------------------------------------==//
-    case IntrinsicHelper::StaticFieldGet:
-    case IntrinsicHelper::StaticFieldGetBoolean:
-    case IntrinsicHelper::StaticFieldGetByte:
-    case IntrinsicHelper::StaticFieldGetChar:
-    case IntrinsicHelper::StaticFieldGetShort: {
-      return ExpandToRuntime(Get32Static, call_inst);
-    }
-    case IntrinsicHelper::StaticFieldGetWide: {
-      return ExpandToRuntime(Get64Static, call_inst);
-    }
-    case IntrinsicHelper::StaticFieldGetObject: {
-      return ExpandToRuntime(GetObjectStatic, call_inst);
-    }
-    case IntrinsicHelper::StaticFieldGetFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kInt);
-    }
-    case IntrinsicHelper::StaticFieldGetWideFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kLong);
-    }
-    case IntrinsicHelper::StaticFieldGetObjectFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kObject);
-    }
-    case IntrinsicHelper::StaticFieldGetBooleanFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kBoolean);
-    }
-    case IntrinsicHelper::StaticFieldGetByteFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kByte);
-    }
-    case IntrinsicHelper::StaticFieldGetCharFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kChar);
-    }
-    case IntrinsicHelper::StaticFieldGetShortFast: {
-      return Expand_SGetFast(call_inst.getArgOperand(0),
-                             call_inst.getArgOperand(1),
-                             call_inst.getArgOperand(2),
-                             kShort);
-    }
-    case IntrinsicHelper::StaticFieldPut:
-    case IntrinsicHelper::StaticFieldPutBoolean:
-    case IntrinsicHelper::StaticFieldPutByte:
-    case IntrinsicHelper::StaticFieldPutChar:
-    case IntrinsicHelper::StaticFieldPutShort: {
-      return ExpandToRuntime(Set32Static, call_inst);
-    }
-    case IntrinsicHelper::StaticFieldPutWide: {
-      return ExpandToRuntime(Set64Static, call_inst);
-    }
-    case IntrinsicHelper::StaticFieldPutObject: {
-      return ExpandToRuntime(SetObjectStatic, call_inst);
-    }
-    case IntrinsicHelper::StaticFieldPutFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kInt);
-      return NULL;
-    }
-    case IntrinsicHelper::StaticFieldPutWideFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kLong);
-      return NULL;
-    }
-    case IntrinsicHelper::StaticFieldPutObjectFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kObject);
-      return NULL;
-    }
-    case IntrinsicHelper::StaticFieldPutBooleanFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kBoolean);
-      return NULL;
-    }
-    case IntrinsicHelper::StaticFieldPutByteFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kByte);
-      return NULL;
-    }
-    case IntrinsicHelper::StaticFieldPutCharFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kChar);
-      return NULL;
-    }
-    case IntrinsicHelper::StaticFieldPutShortFast: {
-      Expand_SPutFast(call_inst.getArgOperand(0),
-                      call_inst.getArgOperand(1),
-                      call_inst.getArgOperand(2),
-                      call_inst.getArgOperand(3),
-                      kShort);
-      return NULL;
-    }
-    case IntrinsicHelper::LoadDeclaringClassSSB: {
-      return Expand_LoadDeclaringClassSSB(call_inst.getArgOperand(0));
-    }
-    case IntrinsicHelper::InitializeAndLoadClassSSB: {
-      return ExpandToRuntime(InitializeStaticStorage, call_inst);
-    }
-
-    //==- High-level Array -------------------------------------------------==//
-    case IntrinsicHelper::HLArrayGet: {
-      return Expand_HLArrayGet(call_inst, kInt);
-    }
-    case IntrinsicHelper::HLArrayGetBoolean: {
-      return Expand_HLArrayGet(call_inst, kBoolean);
-    }
-    case IntrinsicHelper::HLArrayGetByte: {
-      return Expand_HLArrayGet(call_inst, kByte);
-    }
-    case IntrinsicHelper::HLArrayGetChar: {
-      return Expand_HLArrayGet(call_inst, kChar);
-    }
-    case IntrinsicHelper::HLArrayGetShort: {
-      return Expand_HLArrayGet(call_inst, kShort);
-    }
-    case IntrinsicHelper::HLArrayGetFloat: {
-      return Expand_HLArrayGet(call_inst, kFloat);
-    }
-    case IntrinsicHelper::HLArrayGetWide: {
-      return Expand_HLArrayGet(call_inst, kLong);
-    }
-    case IntrinsicHelper::HLArrayGetDouble: {
-      return Expand_HLArrayGet(call_inst, kDouble);
-    }
-    case IntrinsicHelper::HLArrayGetObject: {
-      return Expand_HLArrayGet(call_inst, kObject);
-    }
-    case IntrinsicHelper::HLArrayPut: {
-      Expand_HLArrayPut(call_inst, kInt);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutBoolean: {
-      Expand_HLArrayPut(call_inst, kBoolean);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutByte: {
-      Expand_HLArrayPut(call_inst, kByte);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutChar: {
-      Expand_HLArrayPut(call_inst, kChar);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutShort: {
-      Expand_HLArrayPut(call_inst, kShort);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutFloat: {
-      Expand_HLArrayPut(call_inst, kFloat);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutWide: {
-      Expand_HLArrayPut(call_inst, kLong);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutDouble: {
-      Expand_HLArrayPut(call_inst, kDouble);
-      return NULL;
-    }
-    case IntrinsicHelper::HLArrayPutObject: {
-      Expand_HLArrayPut(call_inst, kObject);
-      return NULL;
-    }
-
-    //==- High-level Instance ----------------------------------------------==//
-    case IntrinsicHelper::HLIGet: {
-      return Expand_HLIGet(call_inst, kInt);
-    }
-    case IntrinsicHelper::HLIGetBoolean: {
-      return Expand_HLIGet(call_inst, kBoolean);
-    }
-    case IntrinsicHelper::HLIGetByte: {
-      return Expand_HLIGet(call_inst, kByte);
-    }
-    case IntrinsicHelper::HLIGetChar: {
-      return Expand_HLIGet(call_inst, kChar);
-    }
-    case IntrinsicHelper::HLIGetShort: {
-      return Expand_HLIGet(call_inst, kShort);
-    }
-    case IntrinsicHelper::HLIGetFloat: {
-      return Expand_HLIGet(call_inst, kFloat);
-    }
-    case IntrinsicHelper::HLIGetWide: {
-      return Expand_HLIGet(call_inst, kLong);
-    }
-    case IntrinsicHelper::HLIGetDouble: {
-      return Expand_HLIGet(call_inst, kDouble);
-    }
-    case IntrinsicHelper::HLIGetObject: {
-      return Expand_HLIGet(call_inst, kObject);
-    }
-    case IntrinsicHelper::HLIPut: {
-      Expand_HLIPut(call_inst, kInt);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutBoolean: {
-      Expand_HLIPut(call_inst, kBoolean);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutByte: {
-      Expand_HLIPut(call_inst, kByte);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutChar: {
-      Expand_HLIPut(call_inst, kChar);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutShort: {
-      Expand_HLIPut(call_inst, kShort);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutFloat: {
-      Expand_HLIPut(call_inst, kFloat);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutWide: {
-      Expand_HLIPut(call_inst, kLong);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutDouble: {
-      Expand_HLIPut(call_inst, kDouble);
-      return NULL;
-    }
-    case IntrinsicHelper::HLIPutObject: {
-      Expand_HLIPut(call_inst, kObject);
-      return NULL;
-    }
-
-    //==- High-level Invoke ------------------------------------------------==//
-    case IntrinsicHelper::HLInvokeVoid:
-    case IntrinsicHelper::HLInvokeObj:
-    case IntrinsicHelper::HLInvokeInt:
-    case IntrinsicHelper::HLInvokeFloat:
-    case IntrinsicHelper::HLInvokeLong:
-    case IntrinsicHelper::HLInvokeDouble: {
-      return Expand_HLInvoke(call_inst);
-    }
-
-    //==- Invoke -----------------------------------------------------------==//
-    case IntrinsicHelper::FindStaticMethodWithAccessCheck: {
-      return ExpandToRuntime(FindStaticMethodWithAccessCheck, call_inst);
-    }
-    case IntrinsicHelper::FindDirectMethodWithAccessCheck: {
-      return ExpandToRuntime(FindDirectMethodWithAccessCheck, call_inst);
-    }
-    case IntrinsicHelper::FindVirtualMethodWithAccessCheck: {
-      return ExpandToRuntime(FindVirtualMethodWithAccessCheck, call_inst);
-    }
-    case IntrinsicHelper::FindSuperMethodWithAccessCheck: {
-      return ExpandToRuntime(FindSuperMethodWithAccessCheck, call_inst);
-    }
-    case IntrinsicHelper::FindInterfaceMethodWithAccessCheck: {
-      return ExpandToRuntime(FindInterfaceMethodWithAccessCheck, call_inst);
-    }
-    case IntrinsicHelper::GetSDCalleeMethodObjAddrFast: {
-      return Expand_GetSDCalleeMethodObjAddrFast(call_inst.getArgOperand(0));
-    }
-    case IntrinsicHelper::GetVirtualCalleeMethodObjAddrFast: {
-      return Expand_GetVirtualCalleeMethodObjAddrFast(
-                call_inst.getArgOperand(0), call_inst.getArgOperand(1));
-    }
-    case IntrinsicHelper::GetInterfaceCalleeMethodObjAddrFast: {
-      return ExpandToRuntime(FindInterfaceMethod, call_inst);
-    }
-    case IntrinsicHelper::InvokeRetVoid:
-    case IntrinsicHelper::InvokeRetBoolean:
-    case IntrinsicHelper::InvokeRetByte:
-    case IntrinsicHelper::InvokeRetChar:
-    case IntrinsicHelper::InvokeRetShort:
-    case IntrinsicHelper::InvokeRetInt:
-    case IntrinsicHelper::InvokeRetLong:
-    case IntrinsicHelper::InvokeRetFloat:
-    case IntrinsicHelper::InvokeRetDouble:
-    case IntrinsicHelper::InvokeRetObject: {
-      return Expand_Invoke(call_inst);
-    }
-
-    //==- Math -------------------------------------------------------------==//
-    case IntrinsicHelper::DivInt: {
-      return Expand_DivRem(call_inst, /* is_div */true, kInt);
-    }
-    case IntrinsicHelper::RemInt: {
-      return Expand_DivRem(call_inst, /* is_div */false, kInt);
-    }
-    case IntrinsicHelper::DivLong: {
-      return Expand_DivRem(call_inst, /* is_div */true, kLong);
-    }
-    case IntrinsicHelper::RemLong: {
-      return Expand_DivRem(call_inst, /* is_div */false, kLong);
-    }
-    case IntrinsicHelper::D2L: {
-      return ExpandToRuntime(art_d2l, call_inst);
-    }
-    case IntrinsicHelper::D2I: {
-      return ExpandToRuntime(art_d2i, call_inst);
-    }
-    case IntrinsicHelper::F2L: {
-      return ExpandToRuntime(art_f2l, call_inst);
-    }
-    case IntrinsicHelper::F2I: {
-      return ExpandToRuntime(art_f2i, call_inst);
-    }
-
-    //==- High-level Static ------------------------------------------------==//
-    case IntrinsicHelper::HLSget: {
-      return Expand_HLSget(call_inst, kInt);
-    }
-    case IntrinsicHelper::HLSgetBoolean: {
-      return Expand_HLSget(call_inst, kBoolean);
-    }
-    case IntrinsicHelper::HLSgetByte: {
-      return Expand_HLSget(call_inst, kByte);
-    }
-    case IntrinsicHelper::HLSgetChar: {
-      return Expand_HLSget(call_inst, kChar);
-    }
-    case IntrinsicHelper::HLSgetShort: {
-      return Expand_HLSget(call_inst, kShort);
-    }
-    case IntrinsicHelper::HLSgetFloat: {
-      return Expand_HLSget(call_inst, kFloat);
-    }
-    case IntrinsicHelper::HLSgetWide: {
-      return Expand_HLSget(call_inst, kLong);
-    }
-    case IntrinsicHelper::HLSgetDouble: {
-      return Expand_HLSget(call_inst, kDouble);
-    }
-    case IntrinsicHelper::HLSgetObject: {
-      return Expand_HLSget(call_inst, kObject);
-    }
-    case IntrinsicHelper::HLSput: {
-      Expand_HLSput(call_inst, kInt);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputBoolean: {
-      Expand_HLSput(call_inst, kBoolean);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputByte: {
-      Expand_HLSput(call_inst, kByte);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputChar: {
-      Expand_HLSput(call_inst, kChar);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputShort: {
-      Expand_HLSput(call_inst, kShort);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputFloat: {
-      Expand_HLSput(call_inst, kFloat);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputWide: {
-      Expand_HLSput(call_inst, kLong);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputDouble: {
-      Expand_HLSput(call_inst, kDouble);
-      return NULL;
-    }
-    case IntrinsicHelper::HLSputObject: {
-      Expand_HLSput(call_inst, kObject);
-      return NULL;
-    }
-
-    //==- High-level Monitor -----------------------------------------------==//
-    case IntrinsicHelper::MonitorEnter: {
-      Expand_MonitorEnter(call_inst);
-      return NULL;
-    }
-    case IntrinsicHelper::MonitorExit: {
-      Expand_MonitorExit(call_inst);
-      return NULL;
-    }
-
-    //==- Shadow Frame -----------------------------------------------------==//
-    case IntrinsicHelper::AllocaShadowFrame: {
-      Expand_AllocaShadowFrame(call_inst.getArgOperand(0));
-      return NULL;
-    }
-    case IntrinsicHelper::SetVReg: {
-      Expand_SetVReg(call_inst.getArgOperand(0),
-                     call_inst.getArgOperand(1));
-      return NULL;
-    }
-    case IntrinsicHelper::PopShadowFrame: {
-      Expand_PopShadowFrame();
-      return NULL;
-    }
-    case IntrinsicHelper::UpdateDexPC: {
-      Expand_UpdateDexPC(call_inst.getArgOperand(0));
-      return NULL;
-    }
-
-    //==- Comparison -------------------------------------------------------==//
-    case IntrinsicHelper::CmplFloat:
-    case IntrinsicHelper::CmplDouble: {
-      return Expand_FPCompare(call_inst.getArgOperand(0),
-                              call_inst.getArgOperand(1),
-                              false);
-    }
-    case IntrinsicHelper::CmpgFloat:
-    case IntrinsicHelper::CmpgDouble: {
-      return Expand_FPCompare(call_inst.getArgOperand(0),
-                              call_inst.getArgOperand(1),
-                              true);
-    }
-    case IntrinsicHelper::CmpLong: {
-      return Expand_LongCompare(call_inst.getArgOperand(0),
-                                call_inst.getArgOperand(1));
-    }
-
-    //==- Const ------------------------------------------------------------==//
-    case IntrinsicHelper::ConstInt:
-    case IntrinsicHelper::ConstLong: {
-      return call_inst.getArgOperand(0);
-    }
-    case IntrinsicHelper::ConstFloat: {
-      return irb_.CreateBitCast(call_inst.getArgOperand(0),
-                                irb_.getJFloatTy());
-    }
-    case IntrinsicHelper::ConstDouble: {
-      return irb_.CreateBitCast(call_inst.getArgOperand(0),
-                                irb_.getJDoubleTy());
-    }
-    case IntrinsicHelper::ConstObj: {
-      CHECK_EQ(LV2UInt(call_inst.getArgOperand(0)), 0U);
-      return irb_.getJNull();
-    }
-
-    //==- Method Info ------------------------------------------------------==//
-    case IntrinsicHelper::MethodInfo: {
-      // Nothing to be done, because MethodInfo carries optional hints that are
-      // not needed by the portable path.
-      return NULL;
-    }
-
-    //==- Copy -------------------------------------------------------------==//
-    case IntrinsicHelper::CopyInt:
-    case IntrinsicHelper::CopyFloat:
-    case IntrinsicHelper::CopyLong:
-    case IntrinsicHelper::CopyDouble:
-    case IntrinsicHelper::CopyObj: {
-      return call_inst.getArgOperand(0);
-    }
-
-    //==- Shift ------------------------------------------------------------==//
-    case IntrinsicHelper::SHLLong: {
-      return Expand_IntegerShift(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1),
-                                 kIntegerSHL, kLong);
-    }
-    case IntrinsicHelper::SHRLong: {
-      return Expand_IntegerShift(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1),
-                                 kIntegerSHR, kLong);
-    }
-    case IntrinsicHelper::USHRLong: {
-      return Expand_IntegerShift(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1),
-                                 kIntegerUSHR, kLong);
-    }
-    case IntrinsicHelper::SHLInt: {
-      return Expand_IntegerShift(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1),
-                                 kIntegerSHL, kInt);
-    }
-    case IntrinsicHelper::SHRInt: {
-      return Expand_IntegerShift(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1),
-                                 kIntegerSHR, kInt);
-    }
-    case IntrinsicHelper::USHRInt: {
-      return Expand_IntegerShift(call_inst.getArgOperand(0),
-                                 call_inst.getArgOperand(1),
-                                 kIntegerUSHR, kInt);
-    }
-
-    //==- Conversion -------------------------------------------------------==//
-    case IntrinsicHelper::IntToChar: {
-      return irb_.CreateZExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJCharTy()),
-                             irb_.getJIntTy());
-    }
-    case IntrinsicHelper::IntToShort: {
-      return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJShortTy()),
-                             irb_.getJIntTy());
-    }
-    case IntrinsicHelper::IntToByte: {
-      return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJByteTy()),
-                             irb_.getJIntTy());
-    }
-
-    //==- Exception --------------------------------------------------------==//
-    case IntrinsicHelper::CatchTargets: {
-      UpdatePhiInstruction(current_bb_, irb_.GetInsertBlock());
-      llvm::SwitchInst* si = llvm::dyn_cast<llvm::SwitchInst>(call_inst.getNextNode());
-      CHECK(si != NULL);
-      irb_.CreateBr(si->getDefaultDest());
-      si->eraseFromParent();
-      return call_inst.getArgOperand(0);
-    }
-
-    //==- Constructor barrier-----------------------------------------------==//
-    case IntrinsicHelper::ConstructorBarrier: {
-      irb_.CreateMemoryBarrier(art::kStoreStore);
-      return NULL;
-    }
-
-    //==- Unknown Cases ----------------------------------------------------==//
-    case IntrinsicHelper::MaxIntrinsicId:
-    case IntrinsicHelper::UnknownId:
-    // default:
-      // NOTE: "default" is intentionally commented so that C/C++ compiler will
-      // give some warning on unmatched cases.
-      // NOTE: We should not implement these cases.
-      break;
-  }
-  UNIMPLEMENTED(FATAL) << "Unexpected GBC intrinsic: " << static_cast<int>(intr_id);
-  return NULL;
-}  // NOLINT(readability/fn_size)
-
-}  // anonymous namespace
-
-namespace art {
-namespace llvm {
-
-::llvm::FunctionPass*
-CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
-                      CompilerDriver* driver, const DexCompilationUnit* dex_compilation_unit) {
-  return new GBCExpanderPass(intrinsic_helper, irb, driver, dex_compilation_unit);
-}
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/generated/art_module.cc b/compiler/llvm/generated/art_module.cc
deleted file mode 100644
index f3c5a5a..0000000
--- a/compiler/llvm/generated/art_module.cc
+++ /dev/null
@@ -1,1096 +0,0 @@
-// Generated with ./gen_art_module_cc.sh
-
-
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
-// TODO: Remove this pragma after llc can generate makeLLVMModuleContents()
-// with smaller frame size.
-
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/Module.h>
-#include <llvm/IR/Type.h>
-
-#include <vector>
-
-using namespace llvm;
-
-namespace art {
-namespace llvm {
-
-
-// Generated by llvm2cpp - DO NOT MODIFY!
-
-
-Module* makeLLVMModuleContents(Module *mod) {
-
-mod->setModuleIdentifier("art_module.ll");
-
-// Type Definitions
-std::vector<Type*>FuncTy_0_args;
-StructType *StructTy_JavaObject = mod->getTypeByName("JavaObject");
-if (!StructTy_JavaObject) {
-StructTy_JavaObject = StructType::create(mod->getContext(), "JavaObject");
-}
-std::vector<Type*>StructTy_JavaObject_fields;
-if (StructTy_JavaObject->isOpaque()) {
-StructTy_JavaObject->setBody(StructTy_JavaObject_fields, /*isPacked=*/false);
-}
-
-PointerType* PointerTy_1 = PointerType::get(StructTy_JavaObject, 0);
-
-FuncTy_0_args.push_back(PointerTy_1);
-StructType *StructTy_ShadowFrame = mod->getTypeByName("ShadowFrame");
-if (!StructTy_ShadowFrame) {
-StructTy_ShadowFrame = StructType::create(mod->getContext(), "ShadowFrame");
-}
-std::vector<Type*>StructTy_ShadowFrame_fields;
-StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
-PointerType* PointerTy_2 = PointerType::get(StructTy_ShadowFrame, 0);
-
-StructTy_ShadowFrame_fields.push_back(PointerTy_2);
-StructTy_ShadowFrame_fields.push_back(PointerTy_1);
-StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
-if (StructTy_ShadowFrame->isOpaque()) {
-StructTy_ShadowFrame->setBody(StructTy_ShadowFrame_fields, /*isPacked=*/false);
-}
-
-
-FuncTy_0_args.push_back(PointerTy_2);
-FunctionType* FuncTy_0 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_0_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_3_args;
-FunctionType* FuncTy_3 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_3_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_4_args;
-FuncTy_4_args.push_back(PointerTy_1);
-FunctionType* FuncTy_4 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_4_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_5_args;
-FuncTy_5_args.push_back(PointerTy_1);
-FuncTy_5_args.push_back(PointerTy_1);
-FunctionType* FuncTy_5 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_5_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_6_args;
-FuncTy_6_args.push_back(PointerTy_1);
-FunctionType* FuncTy_6 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_6_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_7_args;
-FuncTy_7_args.push_back(PointerTy_1);
-FuncTy_7_args.push_back(PointerTy_2);
-FuncTy_7_args.push_back(PointerTy_1);
-FuncTy_7_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_7 = FunctionType::get(
- /*Result=*/PointerTy_2,
- /*Params=*/FuncTy_7_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_8_args;
-FuncTy_8_args.push_back(PointerTy_2);
-FunctionType* FuncTy_8 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_8_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_9_args;
-FunctionType* FuncTy_9 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_9_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_10_args;
-FuncTy_10_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_10_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_10 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_10_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_11_args;
-FuncTy_11_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_11 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_11_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_12_args;
-FuncTy_12_args.push_back(PointerTy_1);
-FuncTy_12_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_12 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_12_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_13_args;
-FuncTy_13_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_13_args.push_back(PointerTy_1);
-FuncTy_13_args.push_back(PointerTy_1);
-FunctionType* FuncTy_13 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_13_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_14_args;
-FuncTy_14_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_14_args.push_back(PointerTy_1);
-FuncTy_14_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_14_args.push_back(PointerTy_1);
-FunctionType* FuncTy_14 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_14_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_15_args;
-FuncTy_15_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_15_args.push_back(PointerTy_1);
-FunctionType* FuncTy_15 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_15_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_16_args;
-FuncTy_16_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_16_args.push_back(PointerTy_1);
-FuncTy_16_args.push_back(PointerTy_1);
-FuncTy_16_args.push_back(PointerTy_1);
-FunctionType* FuncTy_16 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_16_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_17_args;
-FuncTy_17_args.push_back(PointerTy_1);
-FuncTy_17_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_17 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_17_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_18_args;
-FuncTy_18_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_18_args.push_back(PointerTy_1);
-FuncTy_18_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_18 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_18_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_19_args;
-FuncTy_19_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_19_args.push_back(PointerTy_1);
-FuncTy_19_args.push_back(IntegerType::get(mod->getContext(), 64));
-FunctionType* FuncTy_19 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_19_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_20_args;
-FuncTy_20_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_20_args.push_back(PointerTy_1);
-FuncTy_20_args.push_back(PointerTy_1);
-FunctionType* FuncTy_20 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_20_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_21_args;
-FuncTy_21_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_21_args.push_back(PointerTy_1);
-FunctionType* FuncTy_21 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_21_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_22_args;
-FuncTy_22_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_22_args.push_back(PointerTy_1);
-FunctionType* FuncTy_22 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 64),
- /*Params=*/FuncTy_22_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_23_args;
-FuncTy_23_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_23_args.push_back(PointerTy_1);
-FunctionType* FuncTy_23 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_23_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_24_args;
-FuncTy_24_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_24_args.push_back(PointerTy_1);
-FuncTy_24_args.push_back(PointerTy_1);
-FuncTy_24_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_24 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_24_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_25_args;
-FuncTy_25_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_25_args.push_back(PointerTy_1);
-FuncTy_25_args.push_back(PointerTy_1);
-FuncTy_25_args.push_back(IntegerType::get(mod->getContext(), 64));
-FunctionType* FuncTy_25 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_25_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_26_args;
-FuncTy_26_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_26_args.push_back(PointerTy_1);
-FuncTy_26_args.push_back(PointerTy_1);
-FuncTy_26_args.push_back(PointerTy_1);
-FunctionType* FuncTy_26 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_26_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_27_args;
-FuncTy_27_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_27_args.push_back(PointerTy_1);
-FuncTy_27_args.push_back(PointerTy_1);
-FunctionType* FuncTy_27 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 64),
- /*Params=*/FuncTy_27_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_28_args;
-FuncTy_28_args.push_back(PointerTy_1);
-FuncTy_28_args.push_back(PointerTy_1);
-FunctionType* FuncTy_28 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_28_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_29_args;
-FuncTy_29_args.push_back(PointerTy_1);
-FuncTy_29_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_29_args.push_back(PointerTy_1);
-FuncTy_29_args.push_back(IntegerType::get(mod->getContext(), 32));
-FunctionType* FuncTy_29 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_29_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_30_args;
-FuncTy_30_args.push_back(PointerTy_1);
-FuncTy_30_args.push_back(PointerTy_1);
-FunctionType* FuncTy_30 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_30_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_31_args;
-FuncTy_31_args.push_back(Type::getDoubleTy(mod->getContext()));
-FunctionType* FuncTy_31 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 64),
- /*Params=*/FuncTy_31_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_32_args;
-FuncTy_32_args.push_back(Type::getDoubleTy(mod->getContext()));
-FunctionType* FuncTy_32 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_32_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_33_args;
-FuncTy_33_args.push_back(Type::getFloatTy(mod->getContext()));
-FunctionType* FuncTy_33 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 64),
- /*Params=*/FuncTy_33_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_34_args;
-FuncTy_34_args.push_back(Type::getFloatTy(mod->getContext()));
-FunctionType* FuncTy_34 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_34_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_35_args;
-FuncTy_35_args.push_back(PointerTy_1);
-FunctionType* FuncTy_35 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
- /*Params=*/FuncTy_35_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_36_args;
-FuncTy_36_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_36_args.push_back(PointerTy_1);
-FuncTy_36_args.push_back(PointerTy_1);
-FunctionType* FuncTy_36 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_36_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_37_args;
-FuncTy_37_args.push_back(PointerTy_1);
-FuncTy_37_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_37_args.push_back(PointerTy_1);
-FunctionType* FuncTy_37 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_37_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_38_args;
-FuncTy_38_args.push_back(PointerTy_1);
-FuncTy_38_args.push_back(IntegerType::get(mod->getContext(), 32));
-FuncTy_38_args.push_back(PointerTy_1);
-FuncTy_38_args.push_back(PointerTy_1);
-FunctionType* FuncTy_38 = FunctionType::get(
- /*Result=*/PointerTy_1,
- /*Params=*/FuncTy_38_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_39_args;
-FunctionType* FuncTy_39 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 1),
- /*Params=*/FuncTy_39_args,
- /*isVarArg=*/false);
-
-std::vector<Type*>FuncTy_40_args;
-FuncTy_40_args.push_back(PointerTy_1);
-FunctionType* FuncTy_40 = FunctionType::get(
- /*Result=*/Type::getVoidTy(mod->getContext()),
- /*Params=*/FuncTy_40_args,
- /*isVarArg=*/true);
-
-
-// Function Declarations
-
-Function* func___art_type_list = mod->getFunction("__art_type_list");
-if (!func___art_type_list) {
-func___art_type_list = Function::Create(
- /*Type=*/FuncTy_0,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"__art_type_list", mod);  // (external, no body)
-func___art_type_list->setCallingConv(CallingConv::C);
-}
-AttributeSet func___art_type_list_PAL;
-func___art_type_list->setAttributes(func___art_type_list_PAL);
-
-Function* func_art_portable_get_current_thread_from_code = mod->getFunction("art_portable_get_current_thread_from_code");
-if (!func_art_portable_get_current_thread_from_code) {
-func_art_portable_get_current_thread_from_code = Function::Create(
- /*Type=*/FuncTy_3,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get_current_thread_from_code", mod);  // (external, no body)
-func_art_portable_get_current_thread_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get_current_thread_from_code_PAL;
-func_art_portable_get_current_thread_from_code->setAttributes(func_art_portable_get_current_thread_from_code_PAL);
-
-Function* func_art_portable_set_current_thread_from_code = mod->getFunction("art_portable_set_current_thread_from_code");
-if (!func_art_portable_set_current_thread_from_code) {
-func_art_portable_set_current_thread_from_code = Function::Create(
- /*Type=*/FuncTy_4,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set_current_thread_from_code", mod);  // (external, no body)
-func_art_portable_set_current_thread_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set_current_thread_from_code_PAL;
-func_art_portable_set_current_thread_from_code->setAttributes(func_art_portable_set_current_thread_from_code_PAL);
-
-Function* func_art_portable_lock_object_from_code = mod->getFunction("art_portable_lock_object_from_code");
-if (!func_art_portable_lock_object_from_code) {
-func_art_portable_lock_object_from_code = Function::Create(
- /*Type=*/FuncTy_5,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_lock_object_from_code", mod);  // (external, no body)
-func_art_portable_lock_object_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_lock_object_from_code_PAL;
-func_art_portable_lock_object_from_code->setAttributes(func_art_portable_lock_object_from_code_PAL);
-
-Function* func_art_portable_unlock_object_from_code = mod->getFunction("art_portable_unlock_object_from_code");
-if (!func_art_portable_unlock_object_from_code) {
-func_art_portable_unlock_object_from_code = Function::Create(
- /*Type=*/FuncTy_5,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_unlock_object_from_code", mod);  // (external, no body)
-func_art_portable_unlock_object_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_unlock_object_from_code_PAL;
-func_art_portable_unlock_object_from_code->setAttributes(func_art_portable_unlock_object_from_code_PAL);
-
-Function* func_art_portable_test_suspend_from_code = mod->getFunction("art_portable_test_suspend_from_code");
-if (!func_art_portable_test_suspend_from_code) {
-func_art_portable_test_suspend_from_code = Function::Create(
- /*Type=*/FuncTy_6,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_test_suspend_from_code", mod);  // (external, no body)
-func_art_portable_test_suspend_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_test_suspend_from_code_PAL;
-func_art_portable_test_suspend_from_code->setAttributes(func_art_portable_test_suspend_from_code_PAL);
-
-Function* func_art_portable_push_shadow_frame_from_code = mod->getFunction("art_portable_push_shadow_frame_from_code");
-if (!func_art_portable_push_shadow_frame_from_code) {
-func_art_portable_push_shadow_frame_from_code = Function::Create(
- /*Type=*/FuncTy_7,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_push_shadow_frame_from_code", mod);  // (external, no body)
-func_art_portable_push_shadow_frame_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_push_shadow_frame_from_code_PAL;
-func_art_portable_push_shadow_frame_from_code->setAttributes(func_art_portable_push_shadow_frame_from_code_PAL);
-
-Function* func_art_portable_pop_shadow_frame_from_code = mod->getFunction("art_portable_pop_shadow_frame_from_code");
-if (!func_art_portable_pop_shadow_frame_from_code) {
-func_art_portable_pop_shadow_frame_from_code = Function::Create(
- /*Type=*/FuncTy_8,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_pop_shadow_frame_from_code", mod);  // (external, no body)
-func_art_portable_pop_shadow_frame_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_pop_shadow_frame_from_code_PAL;
-func_art_portable_pop_shadow_frame_from_code->setAttributes(func_art_portable_pop_shadow_frame_from_code_PAL);
-
-Function* func_art_portable_get_and_clear_exception = mod->getFunction("art_portable_get_and_clear_exception");
-if (!func_art_portable_get_and_clear_exception) {
-func_art_portable_get_and_clear_exception = Function::Create(
- /*Type=*/FuncTy_4,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get_and_clear_exception", mod);  // (external, no body)
-func_art_portable_get_and_clear_exception->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get_and_clear_exception_PAL;
-func_art_portable_get_and_clear_exception->setAttributes(func_art_portable_get_and_clear_exception_PAL);
-
-Function* func_art_portable_throw_div_zero_from_code = mod->getFunction("art_portable_throw_div_zero_from_code");
-if (!func_art_portable_throw_div_zero_from_code) {
-func_art_portable_throw_div_zero_from_code = Function::Create(
- /*Type=*/FuncTy_9,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_throw_div_zero_from_code", mod);  // (external, no body)
-func_art_portable_throw_div_zero_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_throw_div_zero_from_code_PAL;
-func_art_portable_throw_div_zero_from_code->setAttributes(func_art_portable_throw_div_zero_from_code_PAL);
-
-Function* func_art_portable_throw_array_bounds_from_code = mod->getFunction("art_portable_throw_array_bounds_from_code");
-if (!func_art_portable_throw_array_bounds_from_code) {
-func_art_portable_throw_array_bounds_from_code = Function::Create(
- /*Type=*/FuncTy_10,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_throw_array_bounds_from_code", mod);  // (external, no body)
-func_art_portable_throw_array_bounds_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_throw_array_bounds_from_code_PAL;
-func_art_portable_throw_array_bounds_from_code->setAttributes(func_art_portable_throw_array_bounds_from_code_PAL);
-
-Function* func_art_portable_throw_no_such_method_from_code = mod->getFunction("art_portable_throw_no_such_method_from_code");
-if (!func_art_portable_throw_no_such_method_from_code) {
-func_art_portable_throw_no_such_method_from_code = Function::Create(
- /*Type=*/FuncTy_11,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_throw_no_such_method_from_code", mod);  // (external, no body)
-func_art_portable_throw_no_such_method_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_throw_no_such_method_from_code_PAL;
-func_art_portable_throw_no_such_method_from_code->setAttributes(func_art_portable_throw_no_such_method_from_code_PAL);
-
-Function* func_art_portable_throw_null_pointer_exception_from_code = mod->getFunction("art_portable_throw_null_pointer_exception_from_code");
-if (!func_art_portable_throw_null_pointer_exception_from_code) {
-func_art_portable_throw_null_pointer_exception_from_code = Function::Create(
- /*Type=*/FuncTy_11,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_throw_null_pointer_exception_from_code", mod);  // (external, no body)
-func_art_portable_throw_null_pointer_exception_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_throw_null_pointer_exception_from_code_PAL;
-func_art_portable_throw_null_pointer_exception_from_code->setAttributes(func_art_portable_throw_null_pointer_exception_from_code_PAL);
-
-Function* func_art_portable_throw_stack_overflow_from_code = mod->getFunction("art_portable_throw_stack_overflow_from_code");
-if (!func_art_portable_throw_stack_overflow_from_code) {
-func_art_portable_throw_stack_overflow_from_code = Function::Create(
- /*Type=*/FuncTy_9,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_throw_stack_overflow_from_code", mod);  // (external, no body)
-func_art_portable_throw_stack_overflow_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_throw_stack_overflow_from_code_PAL;
-func_art_portable_throw_stack_overflow_from_code->setAttributes(func_art_portable_throw_stack_overflow_from_code_PAL);
-
-Function* func_art_portable_throw_exception_from_code = mod->getFunction("art_portable_throw_exception_from_code");
-if (!func_art_portable_throw_exception_from_code) {
-func_art_portable_throw_exception_from_code = Function::Create(
- /*Type=*/FuncTy_6,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_throw_exception_from_code", mod);  // (external, no body)
-func_art_portable_throw_exception_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_throw_exception_from_code_PAL;
-func_art_portable_throw_exception_from_code->setAttributes(func_art_portable_throw_exception_from_code_PAL);
-
-Function* func_art_portable_find_catch_block_from_code = mod->getFunction("art_portable_find_catch_block_from_code");
-if (!func_art_portable_find_catch_block_from_code) {
-func_art_portable_find_catch_block_from_code = Function::Create(
- /*Type=*/FuncTy_12,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_catch_block_from_code", mod);  // (external, no body)
-func_art_portable_find_catch_block_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_catch_block_from_code_PAL;
-func_art_portable_find_catch_block_from_code->setAttributes(func_art_portable_find_catch_block_from_code_PAL);
-
-Function* func_art_portable_alloc_object_from_code = mod->getFunction("art_portable_alloc_object_from_code");
-if (!func_art_portable_alloc_object_from_code) {
-func_art_portable_alloc_object_from_code = Function::Create(
- /*Type=*/FuncTy_13,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_alloc_object_from_code", mod);  // (external, no body)
-func_art_portable_alloc_object_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_alloc_object_from_code_PAL;
-func_art_portable_alloc_object_from_code->setAttributes(func_art_portable_alloc_object_from_code_PAL);
-
-Function* func_art_portable_alloc_object_from_code_with_access_check = mod->getFunction("art_portable_alloc_object_from_code_with_access_check");
-if (!func_art_portable_alloc_object_from_code_with_access_check) {
-func_art_portable_alloc_object_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_13,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_alloc_object_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_alloc_object_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_alloc_object_from_code_with_access_check_PAL;
-func_art_portable_alloc_object_from_code_with_access_check->setAttributes(func_art_portable_alloc_object_from_code_with_access_check_PAL);
-
-Function* func_art_portable_alloc_array_from_code = mod->getFunction("art_portable_alloc_array_from_code");
-if (!func_art_portable_alloc_array_from_code) {
-func_art_portable_alloc_array_from_code = Function::Create(
- /*Type=*/FuncTy_14,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_alloc_array_from_code", mod);  // (external, no body)
-func_art_portable_alloc_array_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_alloc_array_from_code_PAL;
-func_art_portable_alloc_array_from_code->setAttributes(func_art_portable_alloc_array_from_code_PAL);
-
-Function* func_art_portable_alloc_array_from_code_with_access_check = mod->getFunction("art_portable_alloc_array_from_code_with_access_check");
-if (!func_art_portable_alloc_array_from_code_with_access_check) {
-func_art_portable_alloc_array_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_14,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_alloc_array_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_alloc_array_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_alloc_array_from_code_with_access_check_PAL;
-func_art_portable_alloc_array_from_code_with_access_check->setAttributes(func_art_portable_alloc_array_from_code_with_access_check_PAL);
-
-Function* func_art_portable_check_and_alloc_array_from_code = mod->getFunction("art_portable_check_and_alloc_array_from_code");
-if (!func_art_portable_check_and_alloc_array_from_code) {
-func_art_portable_check_and_alloc_array_from_code = Function::Create(
- /*Type=*/FuncTy_14,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_check_and_alloc_array_from_code", mod);  // (external, no body)
-func_art_portable_check_and_alloc_array_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_check_and_alloc_array_from_code_PAL;
-func_art_portable_check_and_alloc_array_from_code->setAttributes(func_art_portable_check_and_alloc_array_from_code_PAL);
-
-Function* func_art_portable_check_and_alloc_array_from_code_with_access_check = mod->getFunction("art_portable_check_and_alloc_array_from_code_with_access_check");
-if (!func_art_portable_check_and_alloc_array_from_code_with_access_check) {
-func_art_portable_check_and_alloc_array_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_14,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_check_and_alloc_array_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_check_and_alloc_array_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_check_and_alloc_array_from_code_with_access_check_PAL;
-func_art_portable_check_and_alloc_array_from_code_with_access_check->setAttributes(func_art_portable_check_and_alloc_array_from_code_with_access_check_PAL);
-
-Function* func_art_portable_find_instance_field_from_code = mod->getFunction("art_portable_find_instance_field_from_code");
-if (!func_art_portable_find_instance_field_from_code) {
-func_art_portable_find_instance_field_from_code = Function::Create(
- /*Type=*/FuncTy_15,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_instance_field_from_code", mod);  // (external, no body)
-func_art_portable_find_instance_field_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_instance_field_from_code_PAL;
-func_art_portable_find_instance_field_from_code->setAttributes(func_art_portable_find_instance_field_from_code_PAL);
-
-Function* func_art_portable_find_static_field_from_code = mod->getFunction("art_portable_find_static_field_from_code");
-if (!func_art_portable_find_static_field_from_code) {
-func_art_portable_find_static_field_from_code = Function::Create(
- /*Type=*/FuncTy_15,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_static_field_from_code", mod);  // (external, no body)
-func_art_portable_find_static_field_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_static_field_from_code_PAL;
-func_art_portable_find_static_field_from_code->setAttributes(func_art_portable_find_static_field_from_code_PAL);
-
-Function* func_art_portable_find_static_method_from_code_with_access_check = mod->getFunction("art_portable_find_static_method_from_code_with_access_check");
-if (!func_art_portable_find_static_method_from_code_with_access_check) {
-func_art_portable_find_static_method_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_16,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_static_method_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_find_static_method_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_static_method_from_code_with_access_check_PAL;
-func_art_portable_find_static_method_from_code_with_access_check->setAttributes(func_art_portable_find_static_method_from_code_with_access_check_PAL);
-
-Function* func_art_portable_find_direct_method_from_code_with_access_check = mod->getFunction("art_portable_find_direct_method_from_code_with_access_check");
-if (!func_art_portable_find_direct_method_from_code_with_access_check) {
-func_art_portable_find_direct_method_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_16,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_direct_method_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_find_direct_method_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_direct_method_from_code_with_access_check_PAL;
-func_art_portable_find_direct_method_from_code_with_access_check->setAttributes(func_art_portable_find_direct_method_from_code_with_access_check_PAL);
-
-Function* func_art_portable_find_virtual_method_from_code_with_access_check = mod->getFunction("art_portable_find_virtual_method_from_code_with_access_check");
-if (!func_art_portable_find_virtual_method_from_code_with_access_check) {
-func_art_portable_find_virtual_method_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_16,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_virtual_method_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_find_virtual_method_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_virtual_method_from_code_with_access_check_PAL;
-func_art_portable_find_virtual_method_from_code_with_access_check->setAttributes(func_art_portable_find_virtual_method_from_code_with_access_check_PAL);
-
-Function* func_art_portable_find_super_method_from_code_with_access_check = mod->getFunction("art_portable_find_super_method_from_code_with_access_check");
-if (!func_art_portable_find_super_method_from_code_with_access_check) {
-func_art_portable_find_super_method_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_16,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_super_method_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_find_super_method_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_super_method_from_code_with_access_check_PAL;
-func_art_portable_find_super_method_from_code_with_access_check->setAttributes(func_art_portable_find_super_method_from_code_with_access_check_PAL);
-
-Function* func_art_portable_find_interface_method_from_code_with_access_check = mod->getFunction("art_portable_find_interface_method_from_code_with_access_check");
-if (!func_art_portable_find_interface_method_from_code_with_access_check) {
-func_art_portable_find_interface_method_from_code_with_access_check = Function::Create(
- /*Type=*/FuncTy_16,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_interface_method_from_code_with_access_check", mod);  // (external, no body)
-func_art_portable_find_interface_method_from_code_with_access_check->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_interface_method_from_code_with_access_check_PAL;
-func_art_portable_find_interface_method_from_code_with_access_check->setAttributes(func_art_portable_find_interface_method_from_code_with_access_check_PAL);
-
-Function* func_art_portable_find_interface_method_from_code = mod->getFunction("art_portable_find_interface_method_from_code");
-if (!func_art_portable_find_interface_method_from_code) {
-func_art_portable_find_interface_method_from_code = Function::Create(
- /*Type=*/FuncTy_16,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_find_interface_method_from_code", mod);  // (external, no body)
-func_art_portable_find_interface_method_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_find_interface_method_from_code_PAL;
-func_art_portable_find_interface_method_from_code->setAttributes(func_art_portable_find_interface_method_from_code_PAL);
-
-Function* func_art_portable_initialize_static_storage_from_code = mod->getFunction("art_portable_initialize_static_storage_from_code");
-if (!func_art_portable_initialize_static_storage_from_code) {
-func_art_portable_initialize_static_storage_from_code = Function::Create(
- /*Type=*/FuncTy_13,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_initialize_static_storage_from_code", mod);  // (external, no body)
-func_art_portable_initialize_static_storage_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_initialize_static_storage_from_code_PAL;
-func_art_portable_initialize_static_storage_from_code->setAttributes(func_art_portable_initialize_static_storage_from_code_PAL);
-
-Function* func_art_portable_initialize_type_from_code = mod->getFunction("art_portable_initialize_type_from_code");
-if (!func_art_portable_initialize_type_from_code) {
-func_art_portable_initialize_type_from_code = Function::Create(
- /*Type=*/FuncTy_13,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_initialize_type_from_code", mod);  // (external, no body)
-func_art_portable_initialize_type_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_initialize_type_from_code_PAL;
-func_art_portable_initialize_type_from_code->setAttributes(func_art_portable_initialize_type_from_code_PAL);
-
-Function* func_art_portable_initialize_type_and_verify_access_from_code = mod->getFunction("art_portable_initialize_type_and_verify_access_from_code");
-if (!func_art_portable_initialize_type_and_verify_access_from_code) {
-func_art_portable_initialize_type_and_verify_access_from_code = Function::Create(
- /*Type=*/FuncTy_13,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_initialize_type_and_verify_access_from_code", mod);  // (external, no body)
-func_art_portable_initialize_type_and_verify_access_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_initialize_type_and_verify_access_from_code_PAL;
-func_art_portable_initialize_type_and_verify_access_from_code->setAttributes(func_art_portable_initialize_type_and_verify_access_from_code_PAL);
-
-Function* func_art_portable_resolve_string_from_code = mod->getFunction("art_portable_resolve_string_from_code");
-if (!func_art_portable_resolve_string_from_code) {
-func_art_portable_resolve_string_from_code = Function::Create(
- /*Type=*/FuncTy_17,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_resolve_string_from_code", mod);  // (external, no body)
-func_art_portable_resolve_string_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_resolve_string_from_code_PAL;
-func_art_portable_resolve_string_from_code->setAttributes(func_art_portable_resolve_string_from_code_PAL);
-
-Function* func_art_portable_set32_static_from_code = mod->getFunction("art_portable_set32_static_from_code");
-if (!func_art_portable_set32_static_from_code) {
-func_art_portable_set32_static_from_code = Function::Create(
- /*Type=*/FuncTy_18,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set32_static_from_code", mod);  // (external, no body)
-func_art_portable_set32_static_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set32_static_from_code_PAL;
-func_art_portable_set32_static_from_code->setAttributes(func_art_portable_set32_static_from_code_PAL);
-
-Function* func_art_portable_set64_static_from_code = mod->getFunction("art_portable_set64_static_from_code");
-if (!func_art_portable_set64_static_from_code) {
-func_art_portable_set64_static_from_code = Function::Create(
- /*Type=*/FuncTy_19,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set64_static_from_code", mod);  // (external, no body)
-func_art_portable_set64_static_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set64_static_from_code_PAL;
-func_art_portable_set64_static_from_code->setAttributes(func_art_portable_set64_static_from_code_PAL);
-
-Function* func_art_portable_set_obj_static_from_code = mod->getFunction("art_portable_set_obj_static_from_code");
-if (!func_art_portable_set_obj_static_from_code) {
-func_art_portable_set_obj_static_from_code = Function::Create(
- /*Type=*/FuncTy_20,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set_obj_static_from_code", mod);  // (external, no body)
-func_art_portable_set_obj_static_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set_obj_static_from_code_PAL;
-func_art_portable_set_obj_static_from_code->setAttributes(func_art_portable_set_obj_static_from_code_PAL);
-
-Function* func_art_portable_get32_static_from_code = mod->getFunction("art_portable_get32_static_from_code");
-if (!func_art_portable_get32_static_from_code) {
-func_art_portable_get32_static_from_code = Function::Create(
- /*Type=*/FuncTy_21,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get32_static_from_code", mod);  // (external, no body)
-func_art_portable_get32_static_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get32_static_from_code_PAL;
-func_art_portable_get32_static_from_code->setAttributes(func_art_portable_get32_static_from_code_PAL);
-
-Function* func_art_portable_get64_static_from_code = mod->getFunction("art_portable_get64_static_from_code");
-if (!func_art_portable_get64_static_from_code) {
-func_art_portable_get64_static_from_code = Function::Create(
- /*Type=*/FuncTy_22,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get64_static_from_code", mod);  // (external, no body)
-func_art_portable_get64_static_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get64_static_from_code_PAL;
-func_art_portable_get64_static_from_code->setAttributes(func_art_portable_get64_static_from_code_PAL);
-
-Function* func_art_portable_get_obj_static_from_code = mod->getFunction("art_portable_get_obj_static_from_code");
-if (!func_art_portable_get_obj_static_from_code) {
-func_art_portable_get_obj_static_from_code = Function::Create(
- /*Type=*/FuncTy_23,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get_obj_static_from_code", mod);  // (external, no body)
-func_art_portable_get_obj_static_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get_obj_static_from_code_PAL;
-func_art_portable_get_obj_static_from_code->setAttributes(func_art_portable_get_obj_static_from_code_PAL);
-
-Function* func_art_portable_set32_instance_from_code = mod->getFunction("art_portable_set32_instance_from_code");
-if (!func_art_portable_set32_instance_from_code) {
-func_art_portable_set32_instance_from_code = Function::Create(
- /*Type=*/FuncTy_24,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set32_instance_from_code", mod);  // (external, no body)
-func_art_portable_set32_instance_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set32_instance_from_code_PAL;
-func_art_portable_set32_instance_from_code->setAttributes(func_art_portable_set32_instance_from_code_PAL);
-
-Function* func_art_portable_set64_instance_from_code = mod->getFunction("art_portable_set64_instance_from_code");
-if (!func_art_portable_set64_instance_from_code) {
-func_art_portable_set64_instance_from_code = Function::Create(
- /*Type=*/FuncTy_25,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set64_instance_from_code", mod);  // (external, no body)
-func_art_portable_set64_instance_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set64_instance_from_code_PAL;
-func_art_portable_set64_instance_from_code->setAttributes(func_art_portable_set64_instance_from_code_PAL);
-
-Function* func_art_portable_set_obj_instance_from_code = mod->getFunction("art_portable_set_obj_instance_from_code");
-if (!func_art_portable_set_obj_instance_from_code) {
-func_art_portable_set_obj_instance_from_code = Function::Create(
- /*Type=*/FuncTy_26,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_set_obj_instance_from_code", mod);  // (external, no body)
-func_art_portable_set_obj_instance_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_set_obj_instance_from_code_PAL;
-func_art_portable_set_obj_instance_from_code->setAttributes(func_art_portable_set_obj_instance_from_code_PAL);
-
-Function* func_art_portable_get32_instance_from_code = mod->getFunction("art_portable_get32_instance_from_code");
-if (!func_art_portable_get32_instance_from_code) {
-func_art_portable_get32_instance_from_code = Function::Create(
- /*Type=*/FuncTy_20,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get32_instance_from_code", mod);  // (external, no body)
-func_art_portable_get32_instance_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get32_instance_from_code_PAL;
-func_art_portable_get32_instance_from_code->setAttributes(func_art_portable_get32_instance_from_code_PAL);
-
-Function* func_art_portable_get64_instance_from_code = mod->getFunction("art_portable_get64_instance_from_code");
-if (!func_art_portable_get64_instance_from_code) {
-func_art_portable_get64_instance_from_code = Function::Create(
- /*Type=*/FuncTy_27,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get64_instance_from_code", mod);  // (external, no body)
-func_art_portable_get64_instance_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get64_instance_from_code_PAL;
-func_art_portable_get64_instance_from_code->setAttributes(func_art_portable_get64_instance_from_code_PAL);
-
-Function* func_art_portable_get_obj_instance_from_code = mod->getFunction("art_portable_get_obj_instance_from_code");
-if (!func_art_portable_get_obj_instance_from_code) {
-func_art_portable_get_obj_instance_from_code = Function::Create(
- /*Type=*/FuncTy_13,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_get_obj_instance_from_code", mod);  // (external, no body)
-func_art_portable_get_obj_instance_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_get_obj_instance_from_code_PAL;
-func_art_portable_get_obj_instance_from_code->setAttributes(func_art_portable_get_obj_instance_from_code_PAL);
-
-Function* func_art_portable_decode_jobject_in_thread = mod->getFunction("art_portable_decode_jobject_in_thread");
-if (!func_art_portable_decode_jobject_in_thread) {
-func_art_portable_decode_jobject_in_thread = Function::Create(
- /*Type=*/FuncTy_28,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_decode_jobject_in_thread", mod);  // (external, no body)
-func_art_portable_decode_jobject_in_thread->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_decode_jobject_in_thread_PAL;
-func_art_portable_decode_jobject_in_thread->setAttributes(func_art_portable_decode_jobject_in_thread_PAL);
-
-Function* func_art_portable_fill_array_data_from_code = mod->getFunction("art_portable_fill_array_data_from_code");
-if (!func_art_portable_fill_array_data_from_code) {
-func_art_portable_fill_array_data_from_code = Function::Create(
- /*Type=*/FuncTy_29,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_fill_array_data_from_code", mod);  // (external, no body)
-func_art_portable_fill_array_data_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_fill_array_data_from_code_PAL;
-func_art_portable_fill_array_data_from_code->setAttributes(func_art_portable_fill_array_data_from_code_PAL);
-
-Function* func_art_portable_is_assignable_from_code = mod->getFunction("art_portable_is_assignable_from_code");
-if (!func_art_portable_is_assignable_from_code) {
-func_art_portable_is_assignable_from_code = Function::Create(
- /*Type=*/FuncTy_30,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_is_assignable_from_code", mod);  // (external, no body)
-func_art_portable_is_assignable_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_is_assignable_from_code_PAL;
-func_art_portable_is_assignable_from_code->setAttributes(func_art_portable_is_assignable_from_code_PAL);
-
-Function* func_art_portable_check_cast_from_code = mod->getFunction("art_portable_check_cast_from_code");
-if (!func_art_portable_check_cast_from_code) {
-func_art_portable_check_cast_from_code = Function::Create(
- /*Type=*/FuncTy_5,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_check_cast_from_code", mod);  // (external, no body)
-func_art_portable_check_cast_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_check_cast_from_code_PAL;
-func_art_portable_check_cast_from_code->setAttributes(func_art_portable_check_cast_from_code_PAL);
-
-Function* func_art_portable_check_put_array_element_from_code = mod->getFunction("art_portable_check_put_array_element_from_code");
-if (!func_art_portable_check_put_array_element_from_code) {
-func_art_portable_check_put_array_element_from_code = Function::Create(
- /*Type=*/FuncTy_5,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_check_put_array_element_from_code", mod);  // (external, no body)
-func_art_portable_check_put_array_element_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_check_put_array_element_from_code_PAL;
-func_art_portable_check_put_array_element_from_code->setAttributes(func_art_portable_check_put_array_element_from_code_PAL);
-
-Function* func_art_d2l = mod->getFunction("art_d2l");
-if (!func_art_d2l) {
-func_art_d2l = Function::Create(
- /*Type=*/FuncTy_31,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_d2l", mod);  // (external, no body)
-func_art_d2l->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_d2l_PAL;
-func_art_d2l->setAttributes(func_art_d2l_PAL);
-
-Function* func_art_d2i = mod->getFunction("art_d2i");
-if (!func_art_d2i) {
-func_art_d2i = Function::Create(
- /*Type=*/FuncTy_32,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_d2i", mod);  // (external, no body)
-func_art_d2i->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_d2i_PAL;
-func_art_d2i->setAttributes(func_art_d2i_PAL);
-
-Function* func_art_f2l = mod->getFunction("art_f2l");
-if (!func_art_f2l) {
-func_art_f2l = Function::Create(
- /*Type=*/FuncTy_33,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_f2l", mod);  // (external, no body)
-func_art_f2l->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_f2l_PAL;
-func_art_f2l->setAttributes(func_art_f2l_PAL);
-
-Function* func_art_f2i = mod->getFunction("art_f2i");
-if (!func_art_f2i) {
-func_art_f2i = Function::Create(
- /*Type=*/FuncTy_34,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_f2i", mod);  // (external, no body)
-func_art_f2i->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_f2i_PAL;
-func_art_f2i->setAttributes(func_art_f2i_PAL);
-
-Function* func_art_portable_jni_method_start = mod->getFunction("art_portable_jni_method_start");
-if (!func_art_portable_jni_method_start) {
-func_art_portable_jni_method_start = Function::Create(
- /*Type=*/FuncTy_35,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_jni_method_start", mod);  // (external, no body)
-func_art_portable_jni_method_start->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_jni_method_start_PAL;
-func_art_portable_jni_method_start->setAttributes(func_art_portable_jni_method_start_PAL);
-
-Function* func_art_portable_jni_method_start_synchronized = mod->getFunction("art_portable_jni_method_start_synchronized");
-if (!func_art_portable_jni_method_start_synchronized) {
-func_art_portable_jni_method_start_synchronized = Function::Create(
- /*Type=*/FuncTy_30,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_jni_method_start_synchronized", mod);  // (external, no body)
-func_art_portable_jni_method_start_synchronized->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_jni_method_start_synchronized_PAL;
-func_art_portable_jni_method_start_synchronized->setAttributes(func_art_portable_jni_method_start_synchronized_PAL);
-
-Function* func_art_portable_jni_method_end = mod->getFunction("art_portable_jni_method_end");
-if (!func_art_portable_jni_method_end) {
-func_art_portable_jni_method_end = Function::Create(
- /*Type=*/FuncTy_15,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_jni_method_end", mod);  // (external, no body)
-func_art_portable_jni_method_end->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_jni_method_end_PAL;
-func_art_portable_jni_method_end->setAttributes(func_art_portable_jni_method_end_PAL);
-
-Function* func_art_portable_jni_method_end_synchronized = mod->getFunction("art_portable_jni_method_end_synchronized");
-if (!func_art_portable_jni_method_end_synchronized) {
-func_art_portable_jni_method_end_synchronized = Function::Create(
- /*Type=*/FuncTy_36,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_jni_method_end_synchronized", mod);  // (external, no body)
-func_art_portable_jni_method_end_synchronized->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_jni_method_end_synchronized_PAL;
-func_art_portable_jni_method_end_synchronized->setAttributes(func_art_portable_jni_method_end_synchronized_PAL);
-
-Function* func_art_portable_jni_method_end_with_reference = mod->getFunction("art_portable_jni_method_end_with_reference");
-if (!func_art_portable_jni_method_end_with_reference) {
-func_art_portable_jni_method_end_with_reference = Function::Create(
- /*Type=*/FuncTy_37,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_jni_method_end_with_reference", mod);  // (external, no body)
-func_art_portable_jni_method_end_with_reference->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_jni_method_end_with_reference_PAL;
-func_art_portable_jni_method_end_with_reference->setAttributes(func_art_portable_jni_method_end_with_reference_PAL);
-
-Function* func_art_portable_jni_method_end_with_reference_synchronized = mod->getFunction("art_portable_jni_method_end_with_reference_synchronized");
-if (!func_art_portable_jni_method_end_with_reference_synchronized) {
-func_art_portable_jni_method_end_with_reference_synchronized = Function::Create(
- /*Type=*/FuncTy_38,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_jni_method_end_with_reference_synchronized", mod);  // (external, no body)
-func_art_portable_jni_method_end_with_reference_synchronized->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_jni_method_end_with_reference_synchronized_PAL;
-func_art_portable_jni_method_end_with_reference_synchronized->setAttributes(func_art_portable_jni_method_end_with_reference_synchronized_PAL);
-
-Function* func_art_portable_is_exception_pending_from_code = mod->getFunction("art_portable_is_exception_pending_from_code");
-if (!func_art_portable_is_exception_pending_from_code) {
-func_art_portable_is_exception_pending_from_code = Function::Create(
- /*Type=*/FuncTy_39,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_is_exception_pending_from_code", mod);  // (external, no body)
-func_art_portable_is_exception_pending_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_is_exception_pending_from_code_PAL;
-func_art_portable_is_exception_pending_from_code->setAttributes(func_art_portable_is_exception_pending_from_code_PAL);
-
-Function* func_art_portable_mark_gc_card_from_code = mod->getFunction("art_portable_mark_gc_card_from_code");
-if (!func_art_portable_mark_gc_card_from_code) {
-func_art_portable_mark_gc_card_from_code = Function::Create(
- /*Type=*/FuncTy_5,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_mark_gc_card_from_code", mod);  // (external, no body)
-func_art_portable_mark_gc_card_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_mark_gc_card_from_code_PAL;
-func_art_portable_mark_gc_card_from_code->setAttributes(func_art_portable_mark_gc_card_from_code_PAL);
-
-Function* func_art_portable_proxy_invoke_handler_from_code = mod->getFunction("art_portable_proxy_invoke_handler_from_code");
-if (!func_art_portable_proxy_invoke_handler_from_code) {
-func_art_portable_proxy_invoke_handler_from_code = Function::Create(
- /*Type=*/FuncTy_40,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"art_portable_proxy_invoke_handler_from_code", mod);  // (external, no body)
-func_art_portable_proxy_invoke_handler_from_code->setCallingConv(CallingConv::C);
-}
-AttributeSet func_art_portable_proxy_invoke_handler_from_code_PAL;
-func_art_portable_proxy_invoke_handler_from_code->setAttributes(func_art_portable_proxy_invoke_handler_from_code_PAL);
-
-// Global Variable Declarations
-
-
-// Constant Definitions
-
-// Global Variable Definitions
-
-// Function Definitions
-
-return mod;
-
-}
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/intrinsic_func_list.def b/compiler/llvm/intrinsic_func_list.def
deleted file mode 100644
index 887a626..0000000
--- a/compiler/llvm/intrinsic_func_list.def
+++ /dev/null
@@ -1,1796 +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.
- */
-
-// DEF_INTRINSICS_FUNC(ID, NAME, ATTR, RET_TYPE,
-//                     ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE)
-#ifndef DEF_INTRINSICS_FUNC
-#  error "missing DEF_INTRINSICS_FUNC definition!"
-#endif
-
-#define _EVAL_DEF_INTRINSICS_FUNC(ID, NAME, ATTR, RET_TYPE, ...) \
-    DEF_INTRINSICS_FUNC(ID, NAME, ATTR, RET_TYPE, __VA_ARGS__)
-
-#define _EXPAND_ARG0()                         kNone, kNone, kNone, kNone, kNone
-#define _EXPAND_ARG1(ARG1)                      ARG1, kNone, kNone, kNone, kNone
-#define _EXPAND_ARG2(ARG1, ARG2)                ARG1,  ARG2, kNone, kNone, kNone
-#define _EXPAND_ARG3(ARG1, ARG2, ARG3)          ARG1,  ARG2,  ARG3, kNone, kNone
-#define _EXPAND_ARG4(ARG1, ARG2, ARG3, ARG4)    ARG1,  ARG2,  ARG3,  ARG4, kNone
-#define _EXPAND_ARG5(ARG1, ARG2, ARG3, ARG4, ARG5) \
-                                                ARG1,  ARG2,  ARG3,  ARG4,  ARG5
-
-#define _JTYPE(TYPE, SPACE) _JTYPE_OF_ ## TYPE ## _UNDER_ ## SPACE
-
-// Note: These should be consistent with the type return from
-// IRBuilder::GetJType([type], kArray).
-#define _JTYPE_OF_kInt1Ty_UNDER_kArray        kInt8Ty
-#define _JTYPE_OF_kInt8Ty_UNDER_kArray        kInt8Ty
-#define _JTYPE_OF_kInt16Ty_UNDER_kArray       kInt16Ty
-#define _JTYPE_OF_kInt32Ty_UNDER_kArray       kInt32Ty
-#define _JTYPE_OF_kInt64Ty_UNDER_kArray       kInt64Ty
-#define _JTYPE_OF_kJavaObjectTy_UNDER_kArray  kJavaObjectTy
-
-// Note: These should be consistent with the type return from
-// IRBuilder::GetJType([type], kField).
-#define _JTYPE_OF_kInt1Ty_UNDER_kField        kInt32Ty
-#define _JTYPE_OF_kInt8Ty_UNDER_kField        kInt32Ty
-#define _JTYPE_OF_kInt16Ty_UNDER_kField       kInt32Ty
-#define _JTYPE_OF_kInt32Ty_UNDER_kField       kInt32Ty
-#define _JTYPE_OF_kInt64Ty_UNDER_kField       kInt64Ty
-#define _JTYPE_OF_kJavaObjectTy_UNDER_kField  kJavaObjectTy
-
-//----------------------------------------------------------------------------
-// Thread
-//----------------------------------------------------------------------------
-
-// Thread* art_portable_get_current_thread()
-_EVAL_DEF_INTRINSICS_FUNC(GetCurrentThread,
-                          art_portable_get_current_thread,
-                          kAttrReadNone | kAttrNoThrow,
-                          kJavaThreadTy,
-                          _EXPAND_ARG0())
-
-// void art_portable_test_suspend(Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(TestSuspend,
-                          art_portable_test_suspend,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG1(kJavaThreadTy))
-
-// void art_portable_check_suspend() /* Expands to GetCurrentThread/TestSuspend */
-_EVAL_DEF_INTRINSICS_FUNC(CheckSuspend,
-                          art_portable_check_suspend,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG0())
-
-// void art_portable_mark_gc_card(Object* new_value, Object* object)
-_EVAL_DEF_INTRINSICS_FUNC(MarkGCCard,
-                          art_portable_mark_gc_card,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kJavaObjectTy, kJavaObjectTy))
-
-//----------------------------------------------------------------------------
-// Exception
-//----------------------------------------------------------------------------
-
-// Should not expand - introduces the catch targets for a potentially
-// throwing instruction.  The result is a switch key and this
-// instruction will be followed by a switch statement.  The catch
-// targets will be enumerated as cases of the switch, with the fallthrough
-// designating the block containing the potentially throwing instruction.
-// bool art_portable_catch_targets(int dex_pc)
-_EVAL_DEF_INTRINSICS_FUNC(CatchTargets,
-                          art_portable_catch_targets,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// void art_portable_throw_exception(JavaObject* exception)
-_EVAL_DEF_INTRINSICS_FUNC(ThrowException,
-                          art_portable_throw_exception,
-                          kAttrDoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG1(kJavaObjectTy))
-
-// void art_portable_hl_throw_exception(JavaObject* exception)
-_EVAL_DEF_INTRINSICS_FUNC(HLThrowException,
-                          art_portable_hl_throw_exception,
-                          kAttrDoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG1(kJavaObjectTy))
-
-// JavaObject* art_portable_get_current_exception()
-_EVAL_DEF_INTRINSICS_FUNC(GetException,
-                          art_portable_get_current_exception,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG0())
-
-// bool art_portable_is_exception_pending()
-_EVAL_DEF_INTRINSICS_FUNC(IsExceptionPending,
-                          art_portable_is_exception_pending,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt1Ty,
-                          _EXPAND_ARG0())
-
-// int art_portable_find_catch_block(Method* method, int try_item_offset)
-_EVAL_DEF_INTRINSICS_FUNC(FindCatchBlock,
-                          art_portable_find_catch_block,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kInt32ConstantTy))
-
-// void art_portable_throw_div_zero()
-_EVAL_DEF_INTRINSICS_FUNC(ThrowDivZeroException,
-                          art_portable_throw_div_zero,
-                          kAttrDoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG0())
-
-// void art_portable_throw_null_pointer_exception(uint32_t dex_pc)
-_EVAL_DEF_INTRINSICS_FUNC(ThrowNullPointerException,
-                          art_portable_throw_null_pointer_exception,
-                          kAttrDoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// void art_portable_throw_array_bounds(int index, int array_len)
-_EVAL_DEF_INTRINSICS_FUNC(ThrowIndexOutOfBounds,
-                          art_portable_throw_array_bounds,
-                          kAttrDoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-//----------------------------------------------------------------------------
-// ConstString
-//----------------------------------------------------------------------------
-
-// JavaObject* art_portable_const_string(uint32_t string_idx)
-_EVAL_DEF_INTRINSICS_FUNC(ConstString,
-                          art_portable_const_string,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// JavaObject* art_portable_load_string_from_dex_cache(Method* method, uint32_t string_idx)
-_EVAL_DEF_INTRINSICS_FUNC(LoadStringFromDexCache,
-                          art_portable_load_string_from_dex_cache,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// JavaObject* art_portable_resolve_string(Method* method, uint32_t string_idx)
-_EVAL_DEF_INTRINSICS_FUNC(ResolveString,
-                          art_portable_resolve_string,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG2(kJavaMethodTy, kInt32ConstantTy))
-
-//----------------------------------------------------------------------------
-// ConstClass
-//----------------------------------------------------------------------------
-
-// JavaObject* art_portable_const_class(uint32_t type_idx)
-_EVAL_DEF_INTRINSICS_FUNC(ConstClass,
-                          art_portable_const_class,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// JavaObject* art_portable_initialize_type_and_verify_access(uint32_t type_idx,
-//                                                        Method* referrer,
-//                                                        Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(InitializeTypeAndVerifyAccess,
-                          art_portable_initialize_type_and_verify_access,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
-
-// JavaObject* art_portable_load_type_from_dex_cache(uint32_t type_idx)
-_EVAL_DEF_INTRINSICS_FUNC(LoadTypeFromDexCache,
-                          art_portable_load_type_from_dex_cache,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// JavaObject* art_portable_initialize_type(uint32_t type_idx,
-//                                      Method* referrer,
-//                                      Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(InitializeType,
-                          art_portable_initialize_type,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
-
-//----------------------------------------------------------------------------
-// Lock
-//----------------------------------------------------------------------------
-
-// void art_portable_lock_object(JavaObject* obj, Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(LockObject,
-                          art_portable_lock_object,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kJavaObjectTy, kJavaThreadTy))
-
-// void art_portable_unlock_object(JavaObject* obj, Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(UnlockObject,
-                          art_portable_unlock_object,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG2(kJavaObjectTy, kJavaThreadTy))
-
-//----------------------------------------------------------------------------
-// Cast
-//----------------------------------------------------------------------------
-
-// void art_portable_check_cast(JavaObject* dest_type, JavaObject* src_type)
-_EVAL_DEF_INTRINSICS_FUNC(CheckCast,
-                          art_portable_check_cast,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG2(kJavaObjectTy, kJavaObjectTy))
-
-// void art_portable_hl_check_cast(uint32_t type_idx, JavaObject* obj)
-_EVAL_DEF_INTRINSICS_FUNC(HLCheckCast,
-                          art_portable_hl_check_cast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaObjectTy))
-
-// int art_portable_is_assignable(JavaObject* dest_type, JavaObject* src_type)
-_EVAL_DEF_INTRINSICS_FUNC(IsAssignable,
-                          art_portable_is_assignable,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kJavaObjectTy, kJavaObjectTy))
-
-//----------------------------------------------------------------------------
-// Allocation
-//----------------------------------------------------------------------------
-
-// JavaObject* art_portable_alloc_object(uint32_t type_idx,
-//                                   Method* referrer,
-//                                   Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(AllocObject,
-                          art_portable_alloc_object,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
-
-// JavaObject* art_portable_alloc_object_with_access_check(uint32_t type_idx,
-//                                                     Method* referrer,
-//                                                     Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(AllocObjectWithAccessCheck,
-                          art_portable_alloc_object_with_access_check,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
-
-//----------------------------------------------------------------------------
-// Instance
-//----------------------------------------------------------------------------
-
-// JavaObject* art_portable_new_instance(uint32_t type_idx)
-_EVAL_DEF_INTRINSICS_FUNC(NewInstance,
-                          art_portable_new_instance,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// bool art_portable_instance_of(uint32_t type_idx, JavaObject* ref)
-_EVAL_DEF_INTRINSICS_FUNC(InstanceOf,
-                          art_portable_instance_of,
-                          kAttrNone,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
-
-//----------------------------------------------------------------------------
-// Array
-//----------------------------------------------------------------------------
-
-// JavaObject* art_portable_new_array(uint32_t type_idx, uint32_t array_size)
-_EVAL_DEF_INTRINSICS_FUNC(NewArray,
-                          art_portable_new_array,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG2(kInt32ConstantTy, kInt32Ty))
-
-// uint32_t art_portable_opt_array_length(int32_t opt_flags, JavaObject* array)
-_EVAL_DEF_INTRINSICS_FUNC(OptArrayLength,
-                          art_portable_opt_array_length,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
-
-// uint32_t art_portable_array_length(JavaObject* array)
-_EVAL_DEF_INTRINSICS_FUNC(ArrayLength,
-                          art_portable_array_length,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kJavaObjectTy))
-
-// JavaObject* art_portable_alloc_array(uint32_t type_idx,
-//                                  Method* referrer,
-//                                  uint32_t length,
-//                                  Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(AllocArray,
-                          art_portable_alloc_array,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kInt32Ty, kJavaThreadTy))
-
-// JavaObject* art_portable_alloc_array_with_access_check(uint32_t type_idx,
-//                                                    Method* referrer,
-//                                                    uint32_t length,
-//                                                    Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(AllocArrayWithAccessCheck,
-                          art_portable_alloc_array_with_access_check,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kInt32Ty, kJavaThreadTy))
-
-// JavaObject* art_portable_check_and_alloc_array(uint32_t type_idx,
-//                                            Method* referrer,
-//                                            uint32_t length,
-//                                            Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(CheckAndAllocArray,
-                          art_portable_check_and_alloc_array,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kInt32ConstantTy, kJavaThreadTy))
-
-// JavaObject* art_portable_check_and_alloc_array_with_access_check(uint32_t type_idx,
-//                                                              Method* referrer,
-//                                                              uint32_t length,
-//                                                              Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(CheckAndAllocArrayWithAccessCheck,
-                          art_portable_check_and_alloc_array_with_access_check,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kInt32ConstantTy, kJavaThreadTy))
-
-// art_portable_aget_* and art_portable_aput_* never generate exception since the
-// necessary checking on arguments (e.g., array and index) has already done
-// before invocation of these intrinsics.
-//
-// [type] void art_portable_aget_[type](JavaObject* array, uint32_t index)
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGet,
-                          art_portable_aget,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt32Ty, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGetWide,
-                          art_portable_aget_wide,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt64Ty, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGetObject,
-                          art_portable_aget_object,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kJavaObjectTy, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGetBoolean,
-                          art_portable_aget_boolean,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt1Ty, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGetByte,
-                          art_portable_aget_byte,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt8Ty, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGetChar,
-                          art_portable_aget_char,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt16Ty, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayGetShort,
-                          art_portable_aget_short,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt16Ty, kArray),
-                          _EXPAND_ARG2(kJavaObjectTy, kInt32Ty))
-
-// void art_portable_aput_[type]([type] value, JavaObject* array, uint32_t index)
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPut,
-                          art_portable_aput,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kInt32Ty, kArray), kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPutWide,
-                          art_portable_aput_wide,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kInt64Ty, kArray), kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPutObject,
-                          art_portable_aput_object,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kJavaObjectTy, kArray), kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPutBoolean,
-                          art_portable_aput_boolean,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kInt1Ty, kArray), kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPutByte,
-                          art_portable_aput_byte,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kInt8Ty, kArray), kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPutChar,
-                          art_portable_aput_char,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kInt16Ty, kArray), kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(ArrayPutShort,
-                          art_portable_aput_short,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(_JTYPE(kInt16Ty, kArray), kJavaObjectTy, kInt32Ty))
-
-// void art_portable_check_put_array_element(JavaObject* value, JavaObject* array)
-_EVAL_DEF_INTRINSICS_FUNC(CheckPutArrayElement,
-                          art_portable_check_put_array_element,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG2(kJavaObjectTy, kJavaObjectTy))
-
-// void art_portable_filled_new_array(Array* array,
-//                                uint32_t elem_jty, ...)
-_EVAL_DEF_INTRINSICS_FUNC(FilledNewArray,
-                          art_portable_filled_new_array,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kVarArgTy))
-
-// void art_portable_fill_array_data(Method* referrer,
-//                               uint32_t dex_pc,
-//                               Array* array,
-//                               uint32_t payload_offset)
-_EVAL_DEF_INTRINSICS_FUNC(FillArrayData,
-                          art_portable_fill_array_data,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaMethodTy, kInt32ConstantTy, kJavaObjectTy, kInt32ConstantTy))
-
-// void art_portable_hl_fill_array_data(int32_t offset, JavaObject* array)
-_EVAL_DEF_INTRINSICS_FUNC(HLFillArrayData,
-                          art_portable_hl_fill_array_data,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaObjectTy))
-
-//----------------------------------------------------------------------------
-// Instance Field
-//----------------------------------------------------------------------------
-
-// [type] art_portable_iget_[type](uint32_t field_idx,
-//                             Method* referrer,
-//                             JavaObject* obj)
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGet,
-                          art_portable_iget,
-                          kAttrNone,
-                          _JTYPE(kInt32Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetWide,
-                          art_portable_iget_wide,
-                          kAttrNone,
-                          _JTYPE(kInt64Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetObject,
-                          art_portable_iget_object,
-                          kAttrNone,
-                          _JTYPE(kJavaObjectTy, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetBoolean,
-                          art_portable_iget_boolean,
-                          kAttrNone,
-                          _JTYPE(kInt1Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetByte,
-                          art_portable_iget_byte,
-                          kAttrNone,
-                          _JTYPE(kInt8Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetChar,
-                          art_portable_iget_char,
-                          kAttrNone,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetShort,
-                          art_portable_iget_short,
-                          kAttrNone,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy))
-
-// [type] art_portable_iget_[type].fast(int field_offset,
-//                                  bool is_volatile,
-//                                  JavaObject* obj)
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetFast,
-                          art_portable_iget.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt32Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetWideFast,
-                          art_portable_iget_wide.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt64Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetObjectFast,
-                          art_portable_iget_object.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kJavaObjectTy, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetBooleanFast,
-                          art_portable_iget_boolean.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt1Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetByteFast,
-                          art_portable_iget_byte.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt8Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetCharFast,
-                          art_portable_iget_char.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldGetShortFast,
-                          art_portable_iget_short.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG3(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy))
-
-// void art_portable_iput_[type](uint32_t field_idx,
-//                           Method* referrer,
-//                           JavaObject* obj,
-//                           [type] new_value)
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPut,
-                          art_portable_iput,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kInt32Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutWide,
-                          art_portable_iput_wide,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kInt64Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutObject,
-                          art_portable_iput_object,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kJavaObjectTy, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutBoolean,
-                          art_portable_iput_boolean,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kInt1Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutByte,
-                          art_portable_iput_byte,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kInt8Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutChar,
-                          art_portable_iput_char,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kInt16Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutShort,
-                          art_portable_iput_short,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaMethodTy, kJavaObjectTy, _JTYPE(kInt16Ty, kField)))
-
-// void art_portable_iput_[type].fast(int field_offset,
-//                                bool is_volatile,
-//                                JavaObject* obj,
-//                                [type] new_value)
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutFast,
-                          art_portable_iput.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kInt32Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutWideFast,
-                          art_portable_iput_wide.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kInt64Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutObjectFast,
-                          art_portable_iput_object.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kJavaObjectTy, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutBooleanFast,
-                          art_portable_iput_boolean.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kInt1Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutByteFast,
-                          art_portable_iput_byte.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kInt8Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutCharFast,
-                          art_portable_iput_char.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kInt16Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(InstanceFieldPutShortFast,
-                          art_portable_iput_short.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kInt1ConstantTy, kJavaObjectTy, _JTYPE(kInt16Ty, kField)))
-
-//----------------------------------------------------------------------------
-// Static Field
-//----------------------------------------------------------------------------
-
-// [type] art_portable_sget_[type](uint32_t field_idx, Method* referrer)
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGet,
-                          art_portable_sget,
-                          kAttrNone,
-                          _JTYPE(kInt32Ty, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetWide,
-                          art_portable_sget_wide,
-                          kAttrNone,
-                          _JTYPE(kInt64Ty, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetObject,
-                          art_portable_sget_object,
-                          kAttrNone,
-                          _JTYPE(kJavaObjectTy, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetBoolean,
-                          art_portable_sget_boolean,
-                          kAttrNone,
-                          _JTYPE(kInt1Ty, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetByte,
-                          art_portable_sget_byte,
-                          kAttrNone,
-                          _JTYPE(kInt8Ty, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetChar,
-                          art_portable_sget_char,
-                          kAttrNone,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetShort,
-                          art_portable_sget_short,
-                          kAttrNone,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaMethodTy))
-
-// [type] art_portable_sget_[type].fast(JavaObject* ssb,
-//                                  int field_offset,
-//                                  bool is_volatile)
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetFast,
-                          art_portable_sget.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt32Ty, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetWideFast,
-                          art_portable_sget_wide.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt64Ty, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetObjectFast,
-                          art_portable_sget_object.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kJavaObjectTy, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetBooleanFast,
-                          art_portable_sget_boolean.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt1Ty, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetByteFast,
-                          art_portable_sget_byte.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt8Ty, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetCharFast,
-                          art_portable_sget_char.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldGetShortFast,
-                          art_portable_sget_short.fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          _JTYPE(kInt16Ty, kField),
-                          _EXPAND_ARG3(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy))
-
-// void art_portable_sput_[type](uint32_t field_idx,
-//                           Method* referrer,
-//                           [type] new_value)
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPut,
-                          art_portable_sput,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kInt32Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutWide,
-                          art_portable_sput_wide,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kInt64Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutObject,
-                          art_portable_sput_object,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kJavaObjectTy, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutBoolean,
-                          art_portable_sput_boolean,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kInt1Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutByte,
-                          art_portable_sput_byte,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kInt8Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutChar,
-                          art_portable_sput_char,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kInt16Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutShort,
-                          art_portable_sput_short,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, _JTYPE(kInt16Ty, kField)))
-
-// void art_portable_sput_[type].fast(JavaObject* ssb,
-//                                int field_offset,
-//                                bool is_volatile,
-//                                [type] new_value)
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutFast,
-                          art_portable_sput.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kInt32Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutWideFast,
-                          art_portable_sput_wide.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kInt64Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutObjectFast,
-                          art_portable_sput_object.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kJavaObjectTy, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutBooleanFast,
-                          art_portable_sput_boolean.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kInt1Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutByteFast,
-                          art_portable_sput_byte.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kInt8Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutCharFast,
-                          art_portable_sput_char.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kInt16Ty, kField)))
-
-_EVAL_DEF_INTRINSICS_FUNC(StaticFieldPutShortFast,
-                          art_portable_sput_short.fast,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kJavaObjectTy, kInt32ConstantTy, kInt1ConstantTy, _JTYPE(kInt16Ty, kField)))
-
-// JavaObject* art_portable_load_declaring_class_ssb(Method* method)
-// Load the static storage base of the class that given method resides
-_EVAL_DEF_INTRINSICS_FUNC(LoadDeclaringClassSSB,
-                          art_portable_load_declaring_class_ssb,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kJavaMethodTy))
-
-// JavaObject* art_portable_init_and_load_class_ssb(uint32_t type_idx,
-//                                              Method* referrer,
-//                                              Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(InitializeAndLoadClassSSB,
-                          art_portable_init_and_load_class_ssb,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32ConstantTy, kJavaMethodTy, kJavaThreadTy))
-
-//----------------------------------------------------------------------------
-// High-level Array get/put
-//
-// Similar to art_portable_aget/aput_xxx, but checks not yet performed.
-// OptFlags contain info describing whether frontend has determined that
-// null check and/or array bounds check may be skipped.
-//
-// [type] void art_portable_hl_aget_[type](int optFlags, JavaObject* array, uint32_t index)
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGet,
-                          art_portable_hl_aget,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetFloat,
-                          art_portable_hl_aget_float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kFloatTy,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetWide,
-                          art_portable_hl_aget_wide,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetDouble,
-                          art_portable_hl_aget_double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kDoubleTy,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetObject,
-                          art_portable_hl_aget_object,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetBoolean,
-                          art_portable_hl_aget_boolean,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetByte,
-                          art_portable_hl_aget_byte,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetChar,
-                          art_portable_hl_aget_char,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayGetShort,
-                          art_portable_hl_aget_short,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-// void art_portable_aput_[type](int optFlags, [type] value, JavaObject* array, uint32_t index)
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPut,
-                          art_portable_hl_aput,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutFloat,
-                          art_portable_hl_aput_float,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kFloatTy, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutWide,
-                          art_portable_hl_aput_wide,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt64Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutDouble,
-                          art_portable_hl_aput_double,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kDoubleTy, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutObject,
-                          art_portable_hl_aput_object,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kJavaObjectTy, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutBoolean,
-                          art_portable_hl_aput_boolean,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutByte,
-                          art_portable_hl_aput_byte,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutChar,
-                          art_portable_hl_aput_char,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLArrayPutShort,
-                          art_portable_hl_aput_short,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-//----------------------------------------------------------------------------
-// High-level Instance get/put
-//
-// Similar to art_portable_iget/iput_xxx, but checks not yet performed.
-// OptFlags contain info describing whether frontend has determined that
-// null check may be skipped.
-//
-// [type] void art_portable_hl_iget_[type](int optFlags, JavaObject* obj, uint32_t field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLIGet,
-                          art_portable_hl_iget,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetFloat,
-                          art_portable_hl_iget_float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kFloatTy,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetWide,
-                          art_portable_hl_iget_wide,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetDouble,
-                          art_portable_hl_iget_double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kDoubleTy,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetObject,
-                          art_portable_hl_iget_object,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetBoolean,
-                          art_portable_hl_iget_boolean,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetByte,
-                          art_portable_hl_iget_byte,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetChar,
-                          art_portable_hl_iget_char,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIGetShort,
-                          art_portable_hl_iget_short,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG3(kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-// void art_portable_iput_[type](int optFlags, [type] value, JavaObject* obj, uint32_t field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLIPut,
-                          art_portable_hl_iput,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutFloat,
-                          art_portable_hl_iput_float,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kFloatTy, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutWide,
-                          art_portable_hl_iput_wide,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt64Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutDouble,
-                          art_portable_hl_iput_double,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kDoubleTy, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutObject,
-                          art_portable_hl_iput_object,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kJavaObjectTy, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutBoolean,
-                          art_portable_hl_iput_boolean,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutByte,
-                          art_portable_hl_iput_byte,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutChar,
-                          art_portable_hl_iput_char,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(HLIPutShort,
-                          art_portable_hl_iput_short,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG4(kInt32Ty, kInt32Ty, kJavaObjectTy, kInt32Ty))
-
-//----------------------------------------------------------------------------
-// High-level Invokes (fast-path determination not yet performed)
-//
-// NOTE: We expect these intrinsics to be temporary.  Once calling conventions are
-//       fully merged, the unified front end will lower down to the
-//       InvokeRetxxx() intrinsics in the next section and these will be
-//       removed.
-//
-// arg0: InvokeType [ignored if FilledNewArray]
-// arg1: method_idx [ignored if FilledNewArray]
-// arg2: optimization_flags (primary to note whether null checking is needed)
-// [arg3..argN]: actual arguments
-//----------------------------------------------------------------------------
-// INVOKE method returns void
-_EVAL_DEF_INTRINSICS_FUNC(HLInvokeVoid,
-                          art_portable_hl_invoke.void,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG1(kVarArgTy))
-
-// INVOKE method returns object
-_EVAL_DEF_INTRINSICS_FUNC(HLInvokeObj,
-                          art_portable_hl_invoke.obj,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kVarArgTy))
-
-// INVOKE method returns int
-_EVAL_DEF_INTRINSICS_FUNC(HLInvokeInt,
-                          art_portable_hl_invoke.i32,
-                          kAttrNone,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kVarArgTy))
-
-// INVOKE method returns float
-_EVAL_DEF_INTRINSICS_FUNC(HLInvokeFloat,
-                          art_portable_hl_invoke.f32,
-                          kAttrNone,
-                          kFloatTy,
-                          _EXPAND_ARG1(kVarArgTy))
-
-// INVOKE method returns long
-_EVAL_DEF_INTRINSICS_FUNC(HLInvokeLong,
-                          art_portable_hl_invoke.i64,
-                          kAttrNone,
-                          kInt64Ty,
-                          _EXPAND_ARG1(kVarArgTy))
-
-// INVOKE method returns double
-_EVAL_DEF_INTRINSICS_FUNC(HLInvokeDouble,
-                          art_portable_hl_invoke.f64,
-                          kAttrNone,
-                          kDoubleTy,
-                          _EXPAND_ARG1(kVarArgTy))
-
-// FILLED_NEW_ARRAY returns object
-_EVAL_DEF_INTRINSICS_FUNC(HLFilledNewArray,
-                          art_portable_hl_filled_new_array,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kVarArgTy))
-
-//----------------------------------------------------------------------------
-// Invoke
-//----------------------------------------------------------------------------
-
-// Method* art_portable_find_static_method_with_access_check(uint32_t method_idx,
-//                                                       JavaObject* this,
-//                                                       Method* referrer,
-//                                                       Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(FindStaticMethodWithAccessCheck,
-                          art_portable_find_static_method_with_access_check,
-                          kAttrNone,
-                          kJavaMethodTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaObjectTy, kJavaMethodTy, kJavaThreadTy))
-
-// Method* art_portable_find_direct_method_with_access_check(uint32_t method_idx,
-//                                                       JavaObject* this,
-//                                                       Method* referrer,
-//                                                       Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(FindDirectMethodWithAccessCheck,
-                          art_portable_find_direct_method_with_access_check,
-                          kAttrNone,
-                          kJavaMethodTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaObjectTy, kJavaMethodTy, kJavaThreadTy))
-
-// Method* art_portable_find_virtual_method_with_access_check(uint32_t method_idx,
-//                                                        JavaObject* this,
-//                                                        Method* referrer,
-//                                                        Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(FindVirtualMethodWithAccessCheck,
-                          art_portable_find_virtual_method_with_access_check,
-                          kAttrNone,
-                          kJavaMethodTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaObjectTy, kJavaMethodTy, kJavaThreadTy))
-
-// Method* art_portable_find_super_method_with_access_check(uint32_t method_idx,
-//                                                      JavaObject* this,
-//                                                      Method* referrer,
-//                                                      Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(FindSuperMethodWithAccessCheck,
-                          art_portable_find_super_method_with_access_check,
-                          kAttrNone,
-                          kJavaMethodTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaObjectTy, kJavaMethodTy, kJavaThreadTy))
-
-// Method* art_portable_find_interface_method_with_access_check(uint32_t method_idx,
-//                                                          JavaObject* this,
-//                                                          Method* referrer,
-//                                                          Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(FindInterfaceMethodWithAccessCheck,
-                          art_portable_find_interface_method_with_access_check,
-                          kAttrNone,
-                          kJavaMethodTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaObjectTy, kJavaMethodTy, kJavaThreadTy))
-
-// Method* art_portable_get_sd_callee_method_obj_addr(uint32_t method_idx)
-_EVAL_DEF_INTRINSICS_FUNC(GetSDCalleeMethodObjAddrFast,
-                          art_portable_get_sd_callee_method_obj_addr_fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaMethodTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// Method* art_portable_get_virtual_callee_method_obj_addr(uint32_t vtable_idx,
-//                                                     JavaObject* this)
-_EVAL_DEF_INTRINSICS_FUNC(GetVirtualCalleeMethodObjAddrFast,
-                          art_portable_get_virtual_callee_method_obj_addr_fast,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaMethodTy,
-                          _EXPAND_ARG2(kInt32ConstantTy, kJavaObjectTy))
-
-// Method* art_portable_get_interface_callee_method_obj_addr(uint32_t method_idx,
-//                                                       JavaObject* this,
-//                                                       Method* referrer,
-//                                                       Thread* thread)
-_EVAL_DEF_INTRINSICS_FUNC(GetInterfaceCalleeMethodObjAddrFast,
-                          art_portable_get_interface_callee_method_obj_addr_fast,
-                          kAttrNone,
-                          kJavaMethodTy,
-                          _EXPAND_ARG4(kInt32ConstantTy, kJavaObjectTy, kJavaMethodTy, kJavaThreadTy))
-
-// [type] art_portable_invoke.[type](Method* callee, ...)
-// INVOKE method returns void
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetVoid,
-                          art_portable_invoke.void,
-                          kAttrNone,
-                          kVoidTy,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type boolean
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetBoolean,
-                          art_portable_invoke.bool,
-                          kAttrNone,
-                          kInt1Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type byte
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetByte,
-                          art_portable_invoke.byte,
-                          kAttrNone,
-                          kInt8Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type char
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetChar,
-                          art_portable_invoke.char,
-                          kAttrNone,
-                          kInt16Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type short
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetShort,
-                          art_portable_invoke.short,
-                          kAttrNone,
-                          kInt16Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type int
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetInt,
-                          art_portable_invoke.int,
-                          kAttrNone,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type long
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetLong,
-                          art_portable_invoke.long,
-                          kAttrNone,
-                          kInt64Ty,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type float
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetFloat,
-                          art_portable_invoke.float,
-                          kAttrNone,
-                          kFloatTy,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type double
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetDouble,
-                          art_portable_invoke.double,
-                          kAttrNone,
-                          kDoubleTy,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-// INVOKE method returns the value of type "object"
-_EVAL_DEF_INTRINSICS_FUNC(InvokeRetObject,
-                          art_portable_invoke.object,
-                          kAttrNone,
-                          kJavaObjectTy,
-                          _EXPAND_ARG2(kJavaMethodTy, kVarArgTy))
-
-//----------------------------------------------------------------------------
-// Math
-//----------------------------------------------------------------------------
-
-// int art_portable_{div,rem}_int(int a, int b)
-_EVAL_DEF_INTRINSICS_FUNC(DivInt,
-                          art_portable_div_int,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(RemInt,
-                          art_portable_rem_int,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-// long art_portable_{div,rem}_long(long a, long b)
-_EVAL_DEF_INTRINSICS_FUNC(DivLong,
-                          art_portable_div_long,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG2(kInt64Ty, kInt64Ty))
-
-_EVAL_DEF_INTRINSICS_FUNC(RemLong,
-                          art_portable_rem_long,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG2(kInt64Ty, kInt64Ty))
-
-// int64_t art_portable_d2l(double f)
-_EVAL_DEF_INTRINSICS_FUNC(D2L,
-                          art_portable_d2l,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG1(kDoubleTy))
-
-// int32_t art_portable_d2l(double f)
-_EVAL_DEF_INTRINSICS_FUNC(D2I,
-                          art_portable_d2i,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kDoubleTy))
-
-// int64_t art_portable_f2l(float f)
-_EVAL_DEF_INTRINSICS_FUNC(F2L,
-                          art_portable_f2l,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG1(kFloatTy))
-
-// int32_t art_portable_f2i(float f)
-_EVAL_DEF_INTRINSICS_FUNC(F2I,
-                          art_portable_f2i,
-                          kAttrReadNone | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kFloatTy))
-
-//----------------------------------------------------------------------------
-// sput intrinsics to assist MIR to Greenland_ir conversion.
-// "HL" versions - will be deprecated when fast/slow path handling done
-// in the common frontend.
-//----------------------------------------------------------------------------
-
-// void sput_hl(int field_idx, int val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSput,
-                          art_portable_hl_sput,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-// void sput_hl_object(int field_idx, object* val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputObject,
-                          art_portable_hl_sput_object,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
-
-// void sput_hl_boolean(int field_idx, kInt1Ty)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputBoolean,
-                          art_portable_hl_sput_boolean,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-// void sput_hl_byte(int field_idx, int val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputByte,
-                          art_portable_hl_sput_byte,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-// void sput_hl_char(int field_idx, kInt16Ty val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputChar,
-                          art_portable_hl_sput_char,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-// void sput_hl_short(int field_idx, int val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputShort,
-                          art_portable_hl_sput_short,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt32Ty))
-
-// void sput_hl_wide(int field_idx, long val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputWide,
-                          art_portable_hl_sput_wide,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kInt64Ty))
-
-// void sput_hl_double(int field_idx, double val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputDouble,
-                          art_portable_hl_sput_double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kDoubleTy))
-
-// void sput_hl_float(int field_idx, float val)
-_EVAL_DEF_INTRINSICS_FUNC(HLSputFloat,
-                          art_portable_hl_sput_float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kFloatTy))
-
-//----------------------------------------------------------------------------
-// sget intrinsics to assist MIR to Greenland_ir conversion.
-// "HL" versions - will be deprecated when fast/slow path handling done
-// in the common frontend.
-//----------------------------------------------------------------------------
-
-// int sget_hl(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSget,
-                          art_portable_hl_sget,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// object* sget_hl_object(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetObject,
-                          art_portable_hl_sget_object,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// boolean sget_hl_boolean(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetBoolean,
-                          art_portable_hl_sget_boolean,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// byte sget_hl_byte(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetByte,
-                          art_portable_hl_sget_byte,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// char sget_hl_char(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetChar,
-                          art_portable_hl_sget_char,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// char sget_hl_short(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetShort,
-                          art_portable_hl_sget_short,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// char sget_hl_wide(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetWide,
-                          art_portable_hl_sget_wide,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// char sget_hl_double(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetDouble,
-                          art_portable_hl_sget_double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kDoubleTy,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// char sget_hl_float(int field_idx)
-_EVAL_DEF_INTRINSICS_FUNC(HLSgetFloat,
-                          art_portable_hl_sget_float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kFloatTy,
-                          _EXPAND_ARG1(kInt32Ty))
-//----------------------------------------------------------------------------
-// Monitor enter/exit
-//----------------------------------------------------------------------------
-// uint32_t art_portable_monitor_enter(int optFlags, JavaObject* obj)
-_EVAL_DEF_INTRINSICS_FUNC(MonitorEnter,
-                          art_portable_monitor_enter,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
-
-// uint32_t art_portable_monitor_exit(int optFlags, JavaObject* obj)
-_EVAL_DEF_INTRINSICS_FUNC(MonitorExit,
-                          art_portable_monitor_exit,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32Ty, kJavaObjectTy))
-
-//----------------------------------------------------------------------------
-// Shadow Frame
-//----------------------------------------------------------------------------
-
-// void art_portable_alloca_shadow_frame(int num_entry)
-_EVAL_DEF_INTRINSICS_FUNC(AllocaShadowFrame,
-                          art_portable_alloca_shadow_frame,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-// void art_portable_set_vreg(int entry_idx, ...)
-_EVAL_DEF_INTRINSICS_FUNC(SetVReg,
-                          art_portable_set_vreg,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG2(kInt32ConstantTy, kVarArgTy))
-
-// void art_portable_pop_shadow_frame()
-_EVAL_DEF_INTRINSICS_FUNC(PopShadowFrame,
-                          art_portable_pop_shadow_frame,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG0())
-
-// void art_portable_update_dex_pc(uint32_t dex_pc)
-_EVAL_DEF_INTRINSICS_FUNC(UpdateDexPC,
-                          art_portable_update_dex_pc,
-                          kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG1(kInt32ConstantTy))
-
-//----------------------------------------------------------------------------
-// FP Comparison
-//----------------------------------------------------------------------------
-// int cmpl_float(float, float)
-_EVAL_DEF_INTRINSICS_FUNC(CmplFloat,
-                          art_portable_cmpl_float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kFloatTy, kFloatTy))
-
-// int cmpg_float(float, float)
-_EVAL_DEF_INTRINSICS_FUNC(CmpgFloat,
-                          art_portable_cmpg_float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kFloatTy, kFloatTy))
-
-// int cmpl_double(double, double)
-_EVAL_DEF_INTRINSICS_FUNC(CmplDouble,
-                          art_portable_cmpl_double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kDoubleTy, kDoubleTy))
-
-// int cmpg_double(double, double)
-_EVAL_DEF_INTRINSICS_FUNC(CmpgDouble,
-                          art_portable_cmpg_double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kDoubleTy, kDoubleTy))
-
-//----------------------------------------------------------------------------
-// Long Comparison
-//----------------------------------------------------------------------------
-// int cmp_long(long, long)
-_EVAL_DEF_INTRINSICS_FUNC(CmpLong,
-                          art_portable_cmp_long,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt64Ty, kInt64Ty))
-
-//----------------------------------------------------------------------------
-// Const intrinsics to assist MIR to Greenland_ir conversion.  Should not materialize
-// For simplicity, all use integer input
-//----------------------------------------------------------------------------
-// int const_int(int)
-_EVAL_DEF_INTRINSICS_FUNC(ConstInt,
-                          art_portable_const_int,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// JavaObject* const_obj(int)
-_EVAL_DEF_INTRINSICS_FUNC(ConstObj,
-                          art_portable_const_obj,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// long const_long(long)
-_EVAL_DEF_INTRINSICS_FUNC(ConstLong,
-                          art_portable_const_long,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG1(kInt64Ty))
-
-// float const_float(int)
-_EVAL_DEF_INTRINSICS_FUNC(ConstFloat,
-                          art_portable_const_Float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kFloatTy,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// double const_double(long)
-_EVAL_DEF_INTRINSICS_FUNC(ConstDouble,
-                          art_portable_const_Double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kDoubleTy,
-                          _EXPAND_ARG1(kInt64Ty))
-
-
-//----------------------------------------------------------------------------
-// Copy intrinsics to assist MIR to Greenland_ir conversion.  Should not materialize
-//----------------------------------------------------------------------------
-
-// void method_info(void)
-_EVAL_DEF_INTRINSICS_FUNC(MethodInfo,
-                          art_portable_method_info,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG0())
-
-// int copy_int(int)
-_EVAL_DEF_INTRINSICS_FUNC(CopyInt,
-                          art_portable_copy_int,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// JavaObject* copy_obj(obj)
-_EVAL_DEF_INTRINSICS_FUNC(CopyObj,
-                          art_portable_copy_obj,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kJavaObjectTy,
-                          _EXPAND_ARG1(kJavaObjectTy))
-
-// long copy_long(long)
-_EVAL_DEF_INTRINSICS_FUNC(CopyLong,
-                          art_portable_copy_long,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG1(kInt64Ty))
-
-// float copy_float(float)
-_EVAL_DEF_INTRINSICS_FUNC(CopyFloat,
-                          art_portable_copy_Float,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kFloatTy,
-                          _EXPAND_ARG1(kFloatTy))
-
-// double copy_double(double)
-_EVAL_DEF_INTRINSICS_FUNC(CopyDouble,
-                          art_portable_copy_Double,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kDoubleTy,
-                          _EXPAND_ARG1(kDoubleTy))
-
-//----------------------------------------------------------------------------
-// Shift intrinsics.  Shift semantics for Dalvik are a bit different than
-// the llvm shift operators.  For 32-bit shifts, the shift count is constrained
-// to the range of 0..31, while for 64-bit shifts we limit to 0..63.
-// Further, the shift count for Long shifts in Dalvik is 32 bits, while
-// llvm requires a 64-bit shift count. For GBC, we represent shifts as an
-//  intrinsic to allow most efficient target-dependent lowering.
-//----------------------------------------------------------------------------
-// long shl_long(long,int)
-_EVAL_DEF_INTRINSICS_FUNC(SHLLong,
-                          art_portable_shl_long,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG2(kInt64Ty,kInt32Ty))
-// long shr_long(long,int)
-_EVAL_DEF_INTRINSICS_FUNC(SHRLong,
-                          art_portable_shr_long,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG2(kInt64Ty,kInt32Ty))
-// long ushr_long(long,int)
-_EVAL_DEF_INTRINSICS_FUNC(USHRLong,
-                          art_portable_ushl_long,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt64Ty,
-                          _EXPAND_ARG2(kInt64Ty,kInt32Ty))
-// int shl_int(int,int)
-_EVAL_DEF_INTRINSICS_FUNC(SHLInt,
-                          art_portable_shl_int,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty,kInt32Ty))
-// long shr_int(int,int)
-_EVAL_DEF_INTRINSICS_FUNC(SHRInt,
-                          art_portable_shr_int,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty,kInt32Ty))
-// int ushr_long(int,int)
-_EVAL_DEF_INTRINSICS_FUNC(USHRInt,
-                          art_portable_ushl_int,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG2(kInt32Ty,kInt32Ty))
-//----------------------------------------------------------------------------
-// Conversion instrinsics.  Note: these should eventually be removed.  We
-// can express these directly in bitcode, but by using intrinsics the
-// Quick compiler can be more efficient.  Some extra optimization infrastructure
-// will have to be developed to undo the bitcode verbosity when these are
-// done inline.
-//----------------------------------------------------------------------------
-// int int_to_byte(int)
-_EVAL_DEF_INTRINSICS_FUNC(IntToByte,
-                          art_portable_int_to_byte,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// int int_to_char(int)
-_EVAL_DEF_INTRINSICS_FUNC(IntToChar,
-                          art_portable_int_to_char,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-// int int_to_short(int)
-_EVAL_DEF_INTRINSICS_FUNC(IntToShort,
-                          art_portable_int_to_short,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kInt32Ty,
-                          _EXPAND_ARG1(kInt32Ty))
-
-//----------------------------------------------------------------------------
-// Memory barrier
-//----------------------------------------------------------------------------
-// void constructor_barrier()
-_EVAL_DEF_INTRINSICS_FUNC(ConstructorBarrier,
-                          art_portable_constructor_barrier,
-                          kAttrReadOnly | kAttrNoThrow,
-                          kVoidTy,
-                          _EXPAND_ARG0())
-
-// Clean up all internal used macros
-#undef _EXPAND_ARG0
-#undef _EXPAND_ARG1
-#undef _EXPAND_ARG2
-#undef _EXPAND_ARG3
-#undef _EXPAND_ARG4
-#undef _EXPAND_ARG5
-
-#undef _JTYPE_OF_kInt1Ty_UNDER_kArray
-#undef _JTYPE_OF_kInt8Ty_UNDER_kArray
-#undef _JTYPE_OF_kInt16Ty_UNDER_kArray
-#undef _JTYPE_OF_kInt32Ty_UNDER_kArray
-#undef _JTYPE_OF_kInt64Ty_UNDER_kArray
-#undef _JTYPE_OF_kJavaObjectTy_UNDER_kArray
-
-#undef _JTYPE_OF_kInt1Ty_UNDER_kField
-#undef _JTYPE_OF_kInt8Ty_UNDER_kField
-#undef _JTYPE_OF_kInt16Ty_UNDER_kField
-#undef _JTYPE_OF_kInt32Ty_UNDER_kField
-#undef _JTYPE_OF_kInt64Ty_UNDER_kField
-#undef _JTYPE_OF_kJavaObjectTy_UNDER_kField
-
-#undef DEF_INTRINSICS_FUNC
diff --git a/compiler/llvm/intrinsic_helper.cc b/compiler/llvm/intrinsic_helper.cc
deleted file mode 100644
index e5e7998..0000000
--- a/compiler/llvm/intrinsic_helper.cc
+++ /dev/null
@@ -1,178 +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 "intrinsic_helper.h"
-
-#include "ir_builder.h"
-
-#include <llvm/IR/Attributes.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/IRBuilder.h>
-#include <llvm/IR/Intrinsics.h>
-
-namespace art {
-namespace llvm {
-
-const IntrinsicHelper::IntrinsicInfo IntrinsicHelper::Info[] = {
-#define DEF_INTRINSICS_FUNC(_, NAME, ATTR, RET_TYPE, ARG1_TYPE, ARG2_TYPE, \
-                                                     ARG3_TYPE, ARG4_TYPE, \
-                                                     ARG5_TYPE) \
-  { #NAME, ATTR, RET_TYPE, { ARG1_TYPE, ARG2_TYPE, \
-                             ARG3_TYPE, ARG4_TYPE, \
-                             ARG5_TYPE} },
-#include "intrinsic_func_list.def"
-};
-
-static ::llvm::Type* GetLLVMTypeOfIntrinsicValType(IRBuilder& irb,
-                                                   IntrinsicHelper::IntrinsicValType type) {
-  switch (type) {
-    case IntrinsicHelper::kVoidTy: {
-      return irb.getVoidTy();
-    }
-    case IntrinsicHelper::kJavaObjectTy: {
-      return irb.getJObjectTy();
-    }
-    case IntrinsicHelper::kJavaMethodTy: {
-      return irb.getJMethodTy();
-    }
-    case IntrinsicHelper::kJavaThreadTy: {
-      return irb.getJThreadTy();
-    }
-    case IntrinsicHelper::kInt1Ty:
-    case IntrinsicHelper::kInt1ConstantTy: {
-      return irb.getInt1Ty();
-    }
-    case IntrinsicHelper::kInt8Ty:
-    case IntrinsicHelper::kInt8ConstantTy: {
-      return irb.getInt8Ty();
-    }
-    case IntrinsicHelper::kInt16Ty:
-    case IntrinsicHelper::kInt16ConstantTy: {
-      return irb.getInt16Ty();
-    }
-    case IntrinsicHelper::kInt32Ty:
-    case IntrinsicHelper::kInt32ConstantTy: {
-      return irb.getInt32Ty();
-    }
-    case IntrinsicHelper::kInt64Ty:
-    case IntrinsicHelper::kInt64ConstantTy: {
-      return irb.getInt64Ty();
-    }
-    case IntrinsicHelper::kFloatTy:
-    case IntrinsicHelper::kFloatConstantTy: {
-      return irb.getFloatTy();
-    }
-    case IntrinsicHelper::kDoubleTy:
-    case IntrinsicHelper::kDoubleConstantTy: {
-      return irb.getDoubleTy();
-    }
-    case IntrinsicHelper::kNone:
-    case IntrinsicHelper::kVarArgTy:
-    default: {
-      LOG(FATAL) << "Invalid intrinsic type " << type << "to get LLVM type!";
-      return NULL;
-    }
-  }
-  // unreachable
-}
-
-IntrinsicHelper::IntrinsicHelper(::llvm::LLVMContext& context,
-                                 ::llvm::Module& module) {
-  IRBuilder irb(context, module, *this);
-
-  ::memset(intrinsic_funcs_, 0, sizeof(intrinsic_funcs_));
-
-  // This loop does the following things:
-  // 1. Introduce the intrinsic function into the module
-  // 2. Add "nocapture" and "noalias" attribute to the arguments in all
-  //    intrinsics functions.
-  // 3. Initialize intrinsic_funcs_map_.
-  for (unsigned i = 0; i < MaxIntrinsicId; i++) {
-    IntrinsicId id = static_cast<IntrinsicId>(i);
-    const IntrinsicInfo& info = Info[i];
-
-    // Parse and construct the argument type from IntrinsicInfo
-    ::llvm::Type* arg_type[kIntrinsicMaxArgc];
-    unsigned num_args = 0;
-    bool is_var_arg = false;
-    for (unsigned arg_iter = 0; arg_iter < kIntrinsicMaxArgc; arg_iter++) {
-      IntrinsicValType type = info.arg_type_[arg_iter];
-
-      if (type == kNone) {
-        break;
-      } else if (type == kVarArgTy) {
-        // Variable argument type must be the last argument
-        is_var_arg = true;
-        break;
-      }
-
-      arg_type[num_args++] = GetLLVMTypeOfIntrinsicValType(irb, type);
-    }
-
-    // Construct the function type
-    ::llvm::Type* ret_type =
-        GetLLVMTypeOfIntrinsicValType(irb, info.ret_val_type_);
-
-    ::llvm::FunctionType* type =
-        ::llvm::FunctionType::get(ret_type,
-                                  ::llvm::ArrayRef< ::llvm::Type*>(arg_type, num_args),
-                                  is_var_arg);
-
-    // Declare the function
-    ::llvm::Function *fn = ::llvm::Function::Create(type,
-                                                    ::llvm::Function::ExternalLinkage,
-                                                     info.name_, &module);
-
-    if (info.attr_ & kAttrReadOnly) {
-        fn->setOnlyReadsMemory();
-    }
-    if (info.attr_ & kAttrReadNone) {
-        fn->setDoesNotAccessMemory();
-    }
-    // None of the intrinsics throws exception
-    fn->setDoesNotThrow();
-
-    intrinsic_funcs_[id] = fn;
-
-    DCHECK_NE(fn, static_cast< ::llvm::Function*>(NULL)) << "Intrinsic `"
-        << GetName(id) << "' was not defined!";
-
-    // Add "noalias" and "nocapture" attribute to all arguments of pointer type
-    for (::llvm::Function::arg_iterator arg_iter = fn->arg_begin(),
-            arg_end = fn->arg_end(); arg_iter != arg_end; arg_iter++) {
-      if (arg_iter->getType()->isPointerTy()) {
-        std::vector< ::llvm::Attribute::AttrKind> attributes;
-        attributes.push_back(::llvm::Attribute::NoCapture);
-        attributes.push_back(::llvm::Attribute::NoAlias);
-        ::llvm::AttributeSet attribute_set = ::llvm::AttributeSet::get(fn->getContext(),
-                                                                       arg_iter->getArgNo(),
-                                                                       attributes);
-        arg_iter->addAttr(attribute_set);
-      }
-    }
-
-    // Insert the newly created intrinsic to intrinsic_funcs_map_
-    if (!intrinsic_funcs_map_.insert(std::make_pair(fn, id)).second) {
-      LOG(FATAL) << "Duplicate entry in intrinsic functions map?";
-    }
-  }
-
-  return;
-}
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/intrinsic_helper.h b/compiler/llvm/intrinsic_helper.h
deleted file mode 100644
index 657db40..0000000
--- a/compiler/llvm/intrinsic_helper.h
+++ /dev/null
@@ -1,157 +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_COMPILER_LLVM_INTRINSIC_HELPER_H_
-#define ART_COMPILER_LLVM_INTRINSIC_HELPER_H_
-
-#include "base/logging.h"
-
-#include <llvm/ADT/DenseMap.h>
-
-namespace llvm {
-  class Function;
-  class FunctionType;
-  class LLVMContext;
-  class Module;
-}  // namespace llvm
-
-namespace art {
-namespace llvm {
-
-class IRBuilder;
-
-class IntrinsicHelper {
- public:
-  enum IntrinsicId {
-#define DEF_INTRINSICS_FUNC(ID, ...) ID,
-#include "intrinsic_func_list.def"
-    MaxIntrinsicId,
-
-    // Pseudo-intrinsics Id
-    UnknownId
-  };
-
-  enum IntrinsicAttribute {
-    kAttrNone     = 0,
-
-    // Intrinsic that neither modified the memory state nor refer to the global
-    // state
-    kAttrReadNone = 1 << 0,
-
-    // Intrinsic that doesn't modify the memory state. Note that one should set
-    // this flag carefully when the intrinsic may throw exception. Since the
-    // thread state is implicitly modified when an exception is thrown.
-    kAttrReadOnly = 1 << 1,
-
-    // Note that intrinsic without kAttrNoThrow and kAttrDoThrow set means that
-    // intrinsic generates exception in some cases
-
-    // Intrinsic that never generates exception
-    kAttrNoThrow  = 1 << 2,
-    // Intrinsic that always generate exception
-    kAttrDoThrow  = 1 << 3,
-  };
-
-  enum IntrinsicValType {
-    kNone,
-
-    kVoidTy,
-
-    kJavaObjectTy,
-    kJavaMethodTy,
-    kJavaThreadTy,
-
-    kInt1Ty,
-    kInt8Ty,
-    kInt16Ty,
-    kInt32Ty,
-    kInt64Ty,
-    kFloatTy,
-    kDoubleTy,
-
-    kInt1ConstantTy,
-    kInt8ConstantTy,
-    kInt16ConstantTy,
-    kInt32ConstantTy,
-    kInt64ConstantTy,
-    kFloatConstantTy,
-    kDoubleConstantTy,
-
-    kVarArgTy,
-  };
-
-  enum {
-    kIntrinsicMaxArgc = 5
-  };
-
-  typedef struct IntrinsicInfo {
-    const char* name_;
-    unsigned attr_;
-    IntrinsicValType ret_val_type_;
-    IntrinsicValType arg_type_[kIntrinsicMaxArgc];
-  } IntrinsicInfo;
-
- private:
-  static const IntrinsicInfo Info[];
-
- public:
-  static const IntrinsicInfo& GetInfo(IntrinsicId id) {
-    DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: "
-                                           << id;
-    return Info[id];
-  }
-
-  static const char* GetName(IntrinsicId id) {
-    return (id <= MaxIntrinsicId) ? GetInfo(id).name_ : "InvalidIntrinsic";
-  }
-
-  static unsigned GetAttr(IntrinsicId id) {
-    return GetInfo(id).attr_;
-  }
-
- public:
-  IntrinsicHelper(::llvm::LLVMContext& context, ::llvm::Module& module);
-
-  ::llvm::Function* GetIntrinsicFunction(IntrinsicId id) {
-    DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: "
-                                           << id;
-    return intrinsic_funcs_[id];
-  }
-
-  IntrinsicId GetIntrinsicId(const ::llvm::Function* func) const {
-    ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId>::const_iterator
-        i = intrinsic_funcs_map_.find(func);
-    if (i == intrinsic_funcs_map_.end()) {
-      return UnknownId;
-    } else {
-      return i->second;
-    }
-  }
-
- private:
-  // FIXME: "+1" is to workaround the GCC bugs:
-  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
-  // Remove this when uses newer GCC (> 4.4.3)
-  ::llvm::Function* intrinsic_funcs_[MaxIntrinsicId + 1];
-
-  // Map a llvm::Function to its intrinsic id
-  ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId> intrinsic_funcs_map_;
-};
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_INTRINSIC_HELPER_H_
diff --git a/compiler/llvm/ir_builder.cc b/compiler/llvm/ir_builder.cc
deleted file mode 100644
index 9644ebd..0000000
--- a/compiler/llvm/ir_builder.cc
+++ /dev/null
@@ -1,130 +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 "ir_builder.h"
-
-#include "base/stringprintf.h"
-
-#include <llvm/IR/Module.h>
-
-namespace art {
-namespace llvm {
-
-
-//----------------------------------------------------------------------------
-// General
-//----------------------------------------------------------------------------
-
-IRBuilder::IRBuilder(::llvm::LLVMContext& context, ::llvm::Module& module,
-                     IntrinsicHelper& intrinsic_helper)
-    : LLVMIRBuilder(context), module_(&module), mdb_(context), java_object_type_(NULL),
-      java_method_type_(NULL), java_thread_type_(NULL), intrinsic_helper_(intrinsic_helper) {
-  // Get java object type from module
-  ::llvm::Type* jobject_struct_type = module.getTypeByName("JavaObject");
-  CHECK(jobject_struct_type != NULL);
-  java_object_type_ = jobject_struct_type->getPointerTo();
-
-  // If type of Method is not explicitly defined in the module, use JavaObject*
-  ::llvm::Type* type = module.getTypeByName("Method");
-  if (type != NULL) {
-    java_method_type_ = type->getPointerTo();
-  } else {
-    java_method_type_ = java_object_type_;
-  }
-
-  // If type of Thread is not explicitly defined in the module, use JavaObject*
-  type = module.getTypeByName("Thread");
-  if (type != NULL) {
-    java_thread_type_ = type->getPointerTo();
-  } else {
-    java_thread_type_ = java_object_type_;
-  }
-
-  // Create JEnv* type
-  ::llvm::Type* jenv_struct_type = ::llvm::StructType::create(context, "JEnv");
-  jenv_type_ = jenv_struct_type->getPointerTo();
-
-  // Get Art shadow frame struct type from module
-  art_frame_type_ = module.getTypeByName("ShadowFrame");
-  CHECK(art_frame_type_ != NULL);
-
-  runtime_support_ = NULL;
-}
-
-
-//----------------------------------------------------------------------------
-// Type Helper Function
-//----------------------------------------------------------------------------
-
-::llvm::Type* IRBuilder::getJType(JType jty) {
-  switch (jty) {
-  case kVoid:
-    return getJVoidTy();
-
-  case kBoolean:
-    return getJBooleanTy();
-
-  case kByte:
-    return getJByteTy();
-
-  case kChar:
-    return getJCharTy();
-
-  case kShort:
-    return getJShortTy();
-
-  case kInt:
-    return getJIntTy();
-
-  case kLong:
-    return getJLongTy();
-
-  case kFloat:
-    return getJFloatTy();
-
-  case kDouble:
-    return getJDoubleTy();
-
-  case kObject:
-    return getJObjectTy();
-
-  default:
-    LOG(FATAL) << "Unknown java type: " << jty;
-    return NULL;
-  }
-}
-
-::llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t vreg_size) {
-  std::string name(StringPrintf("ShadowFrame%u", vreg_size));
-
-  // Try to find the existing struct type definition
-  if (::llvm::Type* type = module_->getTypeByName(name)) {
-    CHECK(::llvm::isa< ::llvm::StructType>(type));
-    return static_cast< ::llvm::StructType*>(type);
-  }
-
-  // Create new struct type definition
-  ::llvm::Type* elem_types[] = {
-    art_frame_type_,
-    ::llvm::ArrayType::get(getInt32Ty(), vreg_size),
-  };
-
-  return ::llvm::StructType::create(elem_types, name);
-}
-
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/ir_builder.h b/compiler/llvm/ir_builder.h
deleted file mode 100644
index 990ba02..0000000
--- a/compiler/llvm/ir_builder.h
+++ /dev/null
@@ -1,486 +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_COMPILER_LLVM_IR_BUILDER_H_
-#define ART_COMPILER_LLVM_IR_BUILDER_H_
-
-#include "backend_types.h"
-#include "dex/compiler_enums.h"
-#include "intrinsic_helper.h"
-#include "md_builder.h"
-#include "runtime_support_builder.h"
-#include "runtime_support_llvm_func.h"
-
-#include <llvm/IR/Constants.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/IRBuilder.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Type.h>
-#include <llvm/Support/NoFolder.h>
-
-#include <stdint.h>
-
-
-namespace art {
-namespace llvm {
-
-class InserterWithDexOffset : public ::llvm::IRBuilderDefaultInserter<true> {
-  public:
-    InserterWithDexOffset() : node_(NULL) {}
-
-    void InsertHelper(::llvm::Instruction *I, const ::llvm::Twine &Name,
-                      ::llvm::BasicBlock *BB,
-                      ::llvm::BasicBlock::iterator InsertPt) const {
-      ::llvm::IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB, InsertPt);
-      if (node_ != NULL) {
-        I->setMetadata("DexOff", node_);
-      }
-    }
-
-    void SetDexOffset(::llvm::MDNode* node) {
-      node_ = node;
-    }
-  private:
-    ::llvm::MDNode* node_;
-};
-
-typedef ::llvm::IRBuilder<true, ::llvm::ConstantFolder, InserterWithDexOffset> LLVMIRBuilder;
-// NOTE: Here we define our own LLVMIRBuilder type alias, so that we can
-// switch "preserveNames" template parameter easily.
-
-
-class IRBuilder : public LLVMIRBuilder {
- public:
-  //--------------------------------------------------------------------------
-  // General
-  //--------------------------------------------------------------------------
-
-  IRBuilder(::llvm::LLVMContext& context, ::llvm::Module& module,
-            IntrinsicHelper& intrinsic_helper);
-
-
-  //--------------------------------------------------------------------------
-  // Extend load & store for TBAA
-  //--------------------------------------------------------------------------
-
-  ::llvm::LoadInst* CreateLoad(::llvm::Value* ptr, ::llvm::MDNode* tbaa_info) {
-    ::llvm::LoadInst* inst = LLVMIRBuilder::CreateLoad(ptr);
-    inst->setMetadata(::llvm::LLVMContext::MD_tbaa, tbaa_info);
-    return inst;
-  }
-
-  ::llvm::StoreInst* CreateStore(::llvm::Value* val, ::llvm::Value* ptr, ::llvm::MDNode* tbaa_info) {
-    ::llvm::StoreInst* inst = LLVMIRBuilder::CreateStore(val, ptr);
-    inst->setMetadata(::llvm::LLVMContext::MD_tbaa, tbaa_info);
-    return inst;
-  }
-
-  ::llvm::AtomicCmpXchgInst*
-  CreateAtomicCmpXchgInst(::llvm::Value* ptr, ::llvm::Value* cmp, ::llvm::Value* val,
-                          ::llvm::MDNode* tbaa_info) {
-    ::llvm::AtomicCmpXchgInst* inst =
-        LLVMIRBuilder::CreateAtomicCmpXchg(ptr, cmp, val, ::llvm::Acquire);
-    inst->setMetadata(::llvm::LLVMContext::MD_tbaa, tbaa_info);
-    return inst;
-  }
-
-  //--------------------------------------------------------------------------
-  // Extend memory barrier
-  //--------------------------------------------------------------------------
-  void CreateMemoryBarrier(MemBarrierKind barrier_kind) {
-    // TODO: select atomic ordering according to given barrier kind.
-    CreateFence(::llvm::SequentiallyConsistent);
-  }
-
-  //--------------------------------------------------------------------------
-  // TBAA
-  //--------------------------------------------------------------------------
-
-  // TODO: After we design the non-special TBAA info, re-design the TBAA interface.
-  ::llvm::LoadInst* CreateLoad(::llvm::Value* ptr, TBAASpecialType special_ty) {
-    return CreateLoad(ptr, mdb_.GetTBAASpecialType(special_ty));
-  }
-
-  ::llvm::StoreInst* CreateStore(::llvm::Value* val, ::llvm::Value* ptr, TBAASpecialType special_ty) {
-    DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    return CreateStore(val, ptr, mdb_.GetTBAASpecialType(special_ty));
-  }
-
-  ::llvm::LoadInst* CreateLoad(::llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
-    return CreateLoad(ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
-  }
-
-  ::llvm::StoreInst* CreateStore(::llvm::Value* val, ::llvm::Value* ptr,
-                               TBAASpecialType special_ty, JType j_ty) {
-    DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    return CreateStore(val, ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
-  }
-
-  ::llvm::LoadInst* LoadFromObjectOffset(::llvm::Value* object_addr,
-                                       int64_t offset,
-                                       ::llvm::Type* type,
-                                       TBAASpecialType special_ty) {
-    return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAASpecialType(special_ty));
-  }
-
-  void StoreToObjectOffset(::llvm::Value* object_addr,
-                           int64_t offset,
-                           ::llvm::Value* new_value,
-                           TBAASpecialType special_ty) {
-    DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAASpecialType(special_ty));
-  }
-
-  ::llvm::LoadInst* LoadFromObjectOffset(::llvm::Value* object_addr,
-                                       int64_t offset,
-                                       ::llvm::Type* type,
-                                       TBAASpecialType special_ty, JType j_ty) {
-    return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
-  }
-
-  void StoreToObjectOffset(::llvm::Value* object_addr,
-                           int64_t offset,
-                           ::llvm::Value* new_value,
-                           TBAASpecialType special_ty, JType j_ty) {
-    DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
-  }
-
-  ::llvm::AtomicCmpXchgInst*
-  CompareExchangeObjectOffset(::llvm::Value* object_addr,
-                              int64_t offset,
-                              ::llvm::Value* cmp_value,
-                              ::llvm::Value* new_value,
-                              TBAASpecialType special_ty) {
-    DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    return CompareExchangeObjectOffset(object_addr, offset, cmp_value, new_value,
-                                       mdb_.GetTBAASpecialType(special_ty));
-  }
-
-  void SetTBAA(::llvm::Instruction* inst, TBAASpecialType special_ty) {
-    inst->setMetadata(::llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
-  }
-
-
-  //--------------------------------------------------------------------------
-  // Static Branch Prediction
-  //--------------------------------------------------------------------------
-
-  // Import the orignal conditional branch
-  using LLVMIRBuilder::CreateCondBr;
-  ::llvm::BranchInst* CreateCondBr(::llvm::Value *cond,
-                                 ::llvm::BasicBlock* true_bb,
-                                 ::llvm::BasicBlock* false_bb,
-                                 ExpectCond expect) {
-    ::llvm::BranchInst* branch_inst = CreateCondBr(cond, true_bb, false_bb);
-    if (false) {
-      // TODO: http://b/8511695 Restore branch weight metadata
-      branch_inst->setMetadata(::llvm::LLVMContext::MD_prof, mdb_.GetBranchWeights(expect));
-    }
-    return branch_inst;
-  }
-
-
-  //--------------------------------------------------------------------------
-  // Pointer Arithmetic Helper Function
-  //--------------------------------------------------------------------------
-
-  ::llvm::IntegerType* getPtrEquivIntTy() {
-    return getInt32Ty();
-  }
-
-  size_t getSizeOfPtrEquivInt() {
-    return 4;
-  }
-
-  ::llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
-    return getPtrEquivInt(getSizeOfPtrEquivInt());
-  }
-
-  ::llvm::ConstantInt* getPtrEquivInt(int64_t i) {
-    return ::llvm::ConstantInt::get(getPtrEquivIntTy(), i);
-  }
-
-  ::llvm::Value* CreatePtrDisp(::llvm::Value* base,
-                             ::llvm::Value* offset,
-                             ::llvm::PointerType* ret_ty) {
-    ::llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
-    ::llvm::Value* result_int = CreateAdd(base_int, offset);
-    ::llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
-
-    return result;
-  }
-
-  ::llvm::Value* CreatePtrDisp(::llvm::Value* base,
-                             ::llvm::Value* bs,
-                             ::llvm::Value* count,
-                             ::llvm::Value* offset,
-                             ::llvm::PointerType* ret_ty) {
-    ::llvm::Value* block_offset = CreateMul(bs, count);
-    ::llvm::Value* total_offset = CreateAdd(block_offset, offset);
-
-    return CreatePtrDisp(base, total_offset, ret_ty);
-  }
-
-  ::llvm::LoadInst* LoadFromObjectOffset(::llvm::Value* object_addr,
-                                       int64_t offset,
-                                       ::llvm::Type* type,
-                                       ::llvm::MDNode* tbaa_info) {
-    // Convert offset to ::llvm::value
-    ::llvm::Value* llvm_offset = getPtrEquivInt(offset);
-    // Calculate the value's address
-    ::llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
-    // Load
-    return CreateLoad(value_addr, tbaa_info);
-  }
-
-  void StoreToObjectOffset(::llvm::Value* object_addr,
-                           int64_t offset,
-                           ::llvm::Value* new_value,
-                           ::llvm::MDNode* tbaa_info) {
-    // Convert offset to ::llvm::value
-    ::llvm::Value* llvm_offset = getPtrEquivInt(offset);
-    // Calculate the value's address
-    ::llvm::Value* value_addr = CreatePtrDisp(object_addr,
-                                            llvm_offset,
-                                            new_value->getType()->getPointerTo());
-    // Store
-    CreateStore(new_value, value_addr, tbaa_info);
-  }
-
-  ::llvm::AtomicCmpXchgInst* CompareExchangeObjectOffset(::llvm::Value* object_addr,
-                                                       int64_t offset,
-                                                       ::llvm::Value* cmp_value,
-                                                       ::llvm::Value* new_value,
-                                                       ::llvm::MDNode* tbaa_info) {
-    // Convert offset to ::llvm::value
-    ::llvm::Value* llvm_offset = getPtrEquivInt(offset);
-    // Calculate the value's address
-    ::llvm::Value* value_addr = CreatePtrDisp(object_addr,
-                                            llvm_offset,
-                                            new_value->getType()->getPointerTo());
-    // Atomic compare and exchange
-    return CreateAtomicCmpXchgInst(value_addr, cmp_value, new_value, tbaa_info);
-  }
-
-
-  //--------------------------------------------------------------------------
-  // Runtime Helper Function
-  //--------------------------------------------------------------------------
-
-  RuntimeSupportBuilder& Runtime() {
-    return *runtime_support_;
-  }
-
-  // TODO: Deprecate
-  ::llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
-    return runtime_support_->GetRuntimeSupportFunction(rt);
-  }
-
-  // TODO: Deprecate
-  void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
-    // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
-    // IRBuilder.
-    if (runtime_support_ == NULL && runtime_support != NULL) {
-      runtime_support_ = runtime_support;
-    }
-  }
-
-
-  //--------------------------------------------------------------------------
-  // Type Helper Function
-  //--------------------------------------------------------------------------
-
-  ::llvm::Type* getJType(char shorty_jty) {
-    return getJType(GetJTypeFromShorty(shorty_jty));
-  }
-
-  ::llvm::Type* getJType(JType jty);
-
-  ::llvm::Type* getJVoidTy() {
-    return getVoidTy();
-  }
-
-  ::llvm::IntegerType* getJBooleanTy() {
-    return getInt8Ty();
-  }
-
-  ::llvm::IntegerType* getJByteTy() {
-    return getInt8Ty();
-  }
-
-  ::llvm::IntegerType* getJCharTy() {
-    return getInt16Ty();
-  }
-
-  ::llvm::IntegerType* getJShortTy() {
-    return getInt16Ty();
-  }
-
-  ::llvm::IntegerType* getJIntTy() {
-    return getInt32Ty();
-  }
-
-  ::llvm::IntegerType* getJLongTy() {
-    return getInt64Ty();
-  }
-
-  ::llvm::Type* getJFloatTy() {
-    return getFloatTy();
-  }
-
-  ::llvm::Type* getJDoubleTy() {
-    return getDoubleTy();
-  }
-
-  ::llvm::PointerType* getJObjectTy() {
-    return java_object_type_;
-  }
-
-  ::llvm::PointerType* getJMethodTy() {
-    return java_method_type_;
-  }
-
-  ::llvm::PointerType* getJThreadTy() {
-    return java_thread_type_;
-  }
-
-  ::llvm::Type* getArtFrameTy() {
-    return art_frame_type_;
-  }
-
-  ::llvm::PointerType* getJEnvTy() {
-    return jenv_type_;
-  }
-
-  ::llvm::Type* getJValueTy() {
-    // NOTE: JValue is an union type, which may contains boolean, byte, char,
-    // short, int, long, float, double, Object.  However, LLVM itself does
-    // not support union type, so we have to return a type with biggest size,
-    // then bitcast it before we use it.
-    return getJLongTy();
-  }
-
-  ::llvm::StructType* getShadowFrameTy(uint32_t vreg_size);
-
-
-  //--------------------------------------------------------------------------
-  // Constant Value Helper Function
-  //--------------------------------------------------------------------------
-
-  ::llvm::ConstantInt* getJBoolean(bool is_true) {
-    return (is_true) ? getTrue() : getFalse();
-  }
-
-  ::llvm::ConstantInt* getJByte(int8_t i) {
-    return ::llvm::ConstantInt::getSigned(getJByteTy(), i);
-  }
-
-  ::llvm::ConstantInt* getJChar(int16_t i) {
-    return ::llvm::ConstantInt::getSigned(getJCharTy(), i);
-  }
-
-  ::llvm::ConstantInt* getJShort(int16_t i) {
-    return ::llvm::ConstantInt::getSigned(getJShortTy(), i);
-  }
-
-  ::llvm::ConstantInt* getJInt(int32_t i) {
-    return ::llvm::ConstantInt::getSigned(getJIntTy(), i);
-  }
-
-  ::llvm::ConstantInt* getJLong(int64_t i) {
-    return ::llvm::ConstantInt::getSigned(getJLongTy(), i);
-  }
-
-  ::llvm::Constant* getJFloat(float f) {
-    return ::llvm::ConstantFP::get(getJFloatTy(), f);
-  }
-
-  ::llvm::Constant* getJDouble(double d) {
-    return ::llvm::ConstantFP::get(getJDoubleTy(), d);
-  }
-
-  ::llvm::ConstantPointerNull* getJNull() {
-    return ::llvm::ConstantPointerNull::get(getJObjectTy());
-  }
-
-  ::llvm::Constant* getJZero(char shorty_jty) {
-    return getJZero(GetJTypeFromShorty(shorty_jty));
-  }
-
-  ::llvm::Constant* getJZero(JType jty) {
-    switch (jty) {
-    case kVoid:
-      LOG(FATAL) << "Zero is not a value of void type";
-      return NULL;
-
-    case kBoolean:
-      return getJBoolean(false);
-
-    case kByte:
-      return getJByte(0);
-
-    case kChar:
-      return getJChar(0);
-
-    case kShort:
-      return getJShort(0);
-
-    case kInt:
-      return getJInt(0);
-
-    case kLong:
-      return getJLong(0);
-
-    case kFloat:
-      return getJFloat(0.0f);
-
-    case kDouble:
-      return getJDouble(0.0);
-
-    case kObject:
-      return getJNull();
-
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-      return NULL;
-    }
-  }
-
-
- private:
-  ::llvm::Module* module_;
-
-  MDBuilder mdb_;
-
-  ::llvm::PointerType* java_object_type_;
-  ::llvm::PointerType* java_method_type_;
-  ::llvm::PointerType* java_thread_type_;
-
-  ::llvm::PointerType* jenv_type_;
-
-  ::llvm::StructType* art_frame_type_;
-
-  RuntimeSupportBuilder* runtime_support_;
-
-  IntrinsicHelper& intrinsic_helper_;
-};
-
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_IR_BUILDER_H_
diff --git a/compiler/llvm/llvm_compilation_unit.cc b/compiler/llvm/llvm_compilation_unit.cc
deleted file mode 100644
index 741c2d7..0000000
--- a/compiler/llvm/llvm_compilation_unit.cc
+++ /dev/null
@@ -1,323 +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.
- */
-
-// TODO: TargetLibraryInfo is included before sys/... because on Android bionic does #define tricks like:
-//
-// #define  stat64    stat
-// #define  fstat64   fstat
-// #define  lstat64   lstat
-//
-// which causes grief. bionic probably should not do that.
-#include <llvm/Target/TargetLibraryInfo.h>
-
-#include "llvm_compilation_unit.h"
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <llvm/ADT/OwningPtr.h>
-#include <llvm/ADT/StringSet.h>
-#include <llvm/ADT/Triple.h>
-#include <llvm/Analysis/CallGraph.h>
-#include <llvm/Analysis/CallGraphSCCPass.h>
-#include <llvm/Analysis/Dominators.h>
-#include <llvm/Analysis/LoopInfo.h>
-#include <llvm/Analysis/LoopPass.h>
-#include <llvm/Analysis/RegionPass.h>
-#include <llvm/Analysis/ScalarEvolution.h>
-#include <llvm/Analysis/Verifier.h>
-#include <llvm/Assembly/PrintModulePass.h>
-#include <llvm/Bitcode/ReaderWriter.h>
-#include <llvm/CodeGen/MachineFrameInfo.h>
-#include <llvm/CodeGen/MachineFunction.h>
-#include <llvm/CodeGen/MachineFunctionPass.h>
-#include <llvm/DebugInfo.h>
-#include <llvm/IR/DataLayout.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Module.h>
-#include <llvm/Object/ObjectFile.h>
-#include <llvm/PassManager.h>
-#include <llvm/Support/Debug.h>
-#include <llvm/Support/ELF.h>
-#include <llvm/Support/FormattedStream.h>
-#include <llvm/Support/ManagedStatic.h>
-#include <llvm/Support/MemoryBuffer.h>
-#include <llvm/Support/PassNameParser.h>
-#include <llvm/Support/PluginLoader.h>
-#include <llvm/Support/PrettyStackTrace.h>
-#include <llvm/Support/Signals.h>
-#include <llvm/Support/SystemUtils.h>
-#include <llvm/Support/TargetRegistry.h>
-#include <llvm/Support/TargetSelect.h>
-#include <llvm/Support/ToolOutputFile.h>
-#include <llvm/Support/raw_ostream.h>
-#include <llvm/Support/system_error.h>
-#include <llvm/Target/TargetMachine.h>
-#include <llvm/Transforms/IPO.h>
-#include <llvm/Transforms/IPO/PassManagerBuilder.h>
-#include <llvm/Transforms/Scalar.h>
-
-#include "base/logging.h"
-#include "base/unix_file/fd_file.h"
-#include "compiled_method.h"
-#include "compiler_llvm.h"
-#include "instruction_set.h"
-#include "ir_builder.h"
-#include "os.h"
-#include "runtime_support_builder_arm.h"
-#include "runtime_support_builder_x86.h"
-#include "utils_llvm.h"
-
-namespace art {
-namespace llvm {
-
-::llvm::FunctionPass*
-CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
-                      CompilerDriver* compiler, const DexCompilationUnit* dex_compilation_unit);
-
-::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
-
-
-LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_id)
-    : compiler_llvm_(compiler_llvm), cunit_id_(cunit_id) {
-  driver_ = NULL;
-  dex_compilation_unit_ = NULL;
-  llvm_info_.reset(new LLVMInfo());
-  context_.reset(llvm_info_->GetLLVMContext());
-  module_ = llvm_info_->GetLLVMModule();
-
-  // Include the runtime function declaration
-  makeLLVMModuleContents(module_);
-
-
-  intrinsic_helper_.reset(new IntrinsicHelper(*context_, *module_));
-
-  // Create IRBuilder
-  irb_.reset(new IRBuilder(*context_, *module_, *intrinsic_helper_));
-
-  // We always need a switch case, so just use a normal function.
-  switch (GetInstructionSet()) {
-  default:
-    runtime_support_.reset(new RuntimeSupportBuilder(*context_, *module_, *irb_));
-    break;
-  case kThumb2:
-  case kArm:
-    runtime_support_.reset(new RuntimeSupportBuilderARM(*context_, *module_, *irb_));
-    break;
-  case kX86:
-    runtime_support_.reset(new RuntimeSupportBuilderX86(*context_, *module_, *irb_));
-    break;
-  }
-
-  irb_->SetRuntimeSupport(runtime_support_.get());
-}
-
-
-LlvmCompilationUnit::~LlvmCompilationUnit() {
-  ::llvm::LLVMContext* llvm_context = context_.release();  // Managed by llvm_info_
-  CHECK(llvm_context != NULL);
-}
-
-
-InstructionSet LlvmCompilationUnit::GetInstructionSet() const {
-  return compiler_llvm_->GetInstructionSet();
-}
-
-
-static std::string DumpDirectory() {
-  if (kIsTargetBuild) {
-    return GetDalvikCacheOrDie("llvm-dump");
-  }
-  return "/tmp";
-}
-
-void LlvmCompilationUnit::DumpBitcodeToFile() {
-  std::string bitcode;
-  DumpBitcodeToString(bitcode);
-  std::string filename(StringPrintf("%s/Art%zu.bc", DumpDirectory().c_str(), cunit_id_));
-  std::unique_ptr<File> output(OS::CreateEmptyFile(filename.c_str()));
-  output->WriteFully(bitcode.data(), bitcode.size());
-  LOG(INFO) << ".bc file written successfully: " << filename;
-}
-
-void LlvmCompilationUnit::DumpBitcodeToString(std::string& str_buffer) {
-  ::llvm::raw_string_ostream str_os(str_buffer);
-  ::llvm::WriteBitcodeToFile(module_, str_os);
-}
-
-bool LlvmCompilationUnit::Materialize() {
-  const bool kDumpBitcode = false;
-  if (kDumpBitcode) {
-    // Dump the bitcode for debugging
-    DumpBitcodeToFile();
-  }
-
-  // Compile and prelink ::llvm::Module
-  if (!MaterializeToString(elf_object_)) {
-    LOG(ERROR) << "Failed to materialize compilation unit " << cunit_id_;
-    return false;
-  }
-
-  const bool kDumpELF = false;
-  if (kDumpELF) {
-    // Dump the ELF image for debugging
-    std::string filename(StringPrintf("%s/Art%zu.o", DumpDirectory().c_str(), cunit_id_));
-    std::unique_ptr<File> output(OS::CreateEmptyFile(filename.c_str()));
-    output->WriteFully(elf_object_.data(), elf_object_.size());
-    LOG(INFO) << ".o file written successfully: " << filename;
-  }
-
-  return true;
-}
-
-
-bool LlvmCompilationUnit::MaterializeToString(std::string& str_buffer) {
-  ::llvm::raw_string_ostream str_os(str_buffer);
-  return MaterializeToRawOStream(str_os);
-}
-
-
-bool LlvmCompilationUnit::MaterializeToRawOStream(::llvm::raw_ostream& out_stream) {
-  // Lookup the LLVM target
-  std::string target_triple;
-  std::string target_cpu;
-  std::string target_attr;
-  CompilerDriver::InstructionSetToLLVMTarget(GetInstructionSet(), &target_triple, &target_cpu,
-                                             &target_attr);
-
-  std::string errmsg;
-  const ::llvm::Target* target =
-    ::llvm::TargetRegistry::lookupTarget(target_triple, errmsg);
-
-  CHECK(target != NULL) << errmsg;
-
-  // Target options
-  ::llvm::TargetOptions target_options;
-  target_options.FloatABIType = ::llvm::FloatABI::Soft;
-  target_options.NoFramePointerElim = true;
-  target_options.UseSoftFloat = false;
-  target_options.EnableFastISel = false;
-
-  // Create the ::llvm::TargetMachine
-  ::llvm::OwningPtr< ::llvm::TargetMachine> target_machine(
-    target->createTargetMachine(target_triple, target_cpu, target_attr, target_options,
-                                ::llvm::Reloc::Static, ::llvm::CodeModel::Small,
-                                ::llvm::CodeGenOpt::Aggressive));
-
-  CHECK(target_machine.get() != NULL) << "Failed to create target machine";
-
-  // Add target data
-  const ::llvm::DataLayout* data_layout = target_machine->getDataLayout();
-
-  // PassManager for code generation passes
-  ::llvm::PassManager pm;
-  pm.add(new ::llvm::DataLayout(*data_layout));
-
-  // FunctionPassManager for optimization pass
-  ::llvm::FunctionPassManager fpm(module_);
-  fpm.add(new ::llvm::DataLayout(*data_layout));
-
-  if (bitcode_filename_.empty()) {
-    // If we don't need write the bitcode to file, add the AddSuspendCheckToLoopLatchPass to the
-    // regular FunctionPass.
-    fpm.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
-                                  driver_, dex_compilation_unit_));
-  } else {
-    ::llvm::FunctionPassManager fpm2(module_);
-    fpm2.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
-                                   driver_, dex_compilation_unit_));
-    fpm2.doInitialization();
-    for (::llvm::Module::iterator F = module_->begin(), E = module_->end();
-         F != E; ++F) {
-      fpm2.run(*F);
-    }
-    fpm2.doFinalization();
-
-    // Write bitcode to file
-    std::string errmsg;
-
-    ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
-      new ::llvm::tool_output_file(bitcode_filename_.c_str(), errmsg,
-                                 ::llvm::sys::fs::F_Binary));
-
-
-    if (!errmsg.empty()) {
-      LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
-      return false;
-    }
-
-    ::llvm::WriteBitcodeToFile(module_, out_file->os());
-    out_file->keep();
-  }
-
-  // Add optimization pass
-  ::llvm::PassManagerBuilder pm_builder;
-  // TODO: Use inliner after we can do IPO.
-  pm_builder.Inliner = NULL;
-  // pm_builder.Inliner = ::llvm::createFunctionInliningPass();
-  // pm_builder.Inliner = ::llvm::createAlwaysInlinerPass();
-  // pm_builder.Inliner = ::llvm::createPartialInliningPass();
-  pm_builder.OptLevel = 3;
-  pm_builder.DisableUnitAtATime = 1;
-  pm_builder.populateFunctionPassManager(fpm);
-  pm_builder.populateModulePassManager(pm);
-  pm.add(::llvm::createStripDeadPrototypesPass());
-
-  // Add passes to emit ELF image
-  {
-    ::llvm::formatted_raw_ostream formatted_os(out_stream, false);
-
-    // Ask the target to add backend passes as necessary.
-    if (target_machine->addPassesToEmitFile(pm,
-                                            formatted_os,
-                                            ::llvm::TargetMachine::CGFT_ObjectFile,
-                                            true)) {
-      LOG(FATAL) << "Unable to generate ELF for this target";
-      return false;
-    }
-
-    // Run the per-function optimization
-    fpm.doInitialization();
-    for (::llvm::Module::iterator F = module_->begin(), E = module_->end();
-         F != E; ++F) {
-      fpm.run(*F);
-    }
-    fpm.doFinalization();
-
-    // Run the code generation passes
-    pm.run(*module_);
-  }
-
-  return true;
-}
-
-// Check whether the align is less than or equal to the code alignment of
-// that architecture.  Since the Oat writer only guarantee that the compiled
-// method being aligned to kArchAlignment, we have no way to align the ELf
-// section if the section alignment is greater than kArchAlignment.
-void LlvmCompilationUnit::CheckCodeAlign(uint32_t align) const {
-  InstructionSet insn_set = GetInstructionSet();
-  size_t insn_set_align = GetInstructionSetAlignment(insn_set);
-  CHECK_LE(align, static_cast<uint32_t>(insn_set_align));
-}
-
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/llvm_compilation_unit.h b/compiler/llvm/llvm_compilation_unit.h
deleted file mode 100644
index f11fb6e..0000000
--- a/compiler/llvm/llvm_compilation_unit.h
+++ /dev/null
@@ -1,138 +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_COMPILER_LLVM_LLVM_COMPILATION_UNIT_H_
-#define ART_COMPILER_LLVM_LLVM_COMPILATION_UNIT_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/mutex.h"
-#include "dex/compiler_internals.h"
-#include "driver/compiler_driver.h"
-#include "driver/dex_compilation_unit.h"
-#include "globals.h"
-#include "instruction_set.h"
-#include "runtime_support_builder.h"
-#include "runtime_support_llvm_func.h"
-#include "safe_map.h"
-
-namespace art {
-  class CompiledMethod;
-}
-
-namespace llvm {
-  class Function;
-  class LLVMContext;
-  class Module;
-  class raw_ostream;
-}
-
-namespace art {
-namespace llvm {
-
-class CompilerLLVM;
-class IRBuilder;
-
-class LlvmCompilationUnit {
- public:
-  ~LlvmCompilationUnit();
-
-  uint32_t GetCompilationUnitId() const {
-    return cunit_id_;
-  }
-
-  InstructionSet GetInstructionSet() const;
-
-  ::llvm::LLVMContext* GetLLVMContext() const {
-    return context_.get();
-  }
-
-  ::llvm::Module* GetModule() const {
-    return module_;
-  }
-
-  IRBuilder* GetIRBuilder() const {
-    return irb_.get();
-  }
-
-  void SetBitcodeFileName(const std::string& bitcode_filename) {
-    bitcode_filename_ = bitcode_filename;
-  }
-
-  LLVMInfo* GetQuickContext() const {
-    return llvm_info_.get();
-  }
-  void SetCompilerDriver(CompilerDriver* driver) {
-    driver_ = driver;
-  }
-  DexCompilationUnit* GetDexCompilationUnit() {
-    return dex_compilation_unit_;
-  }
-  void SetDexCompilationUnit(DexCompilationUnit* dex_compilation_unit) {
-    dex_compilation_unit_ = dex_compilation_unit;
-  }
-
-  bool Materialize();
-
-  bool IsMaterialized() const {
-    return !elf_object_.empty();
-  }
-
-  const std::string& GetElfObject() const {
-    DCHECK(IsMaterialized());
-    return elf_object_;
-  }
-
- private:
-  LlvmCompilationUnit(const CompilerLLVM* compiler_llvm,
-                      size_t cunit_id);
-
-  const CompilerLLVM* compiler_llvm_;
-  const size_t cunit_id_;
-
-  std::unique_ptr< ::llvm::LLVMContext> context_;
-  std::unique_ptr<IRBuilder> irb_;
-  std::unique_ptr<RuntimeSupportBuilder> runtime_support_;
-  ::llvm::Module* module_;  // Managed by context_
-  std::unique_ptr<IntrinsicHelper> intrinsic_helper_;
-  std::unique_ptr<LLVMInfo> llvm_info_;
-  CompilerDriver* driver_;
-  DexCompilationUnit* dex_compilation_unit_;
-
-  std::string bitcode_filename_;
-
-  std::string elf_object_;
-
-  SafeMap<const ::llvm::Function*, CompiledMethod*> compiled_methods_map_;
-
-  void CheckCodeAlign(uint32_t offset) const;
-
-  void DumpBitcodeToFile();
-  void DumpBitcodeToString(std::string& str_buffer);
-
-  bool MaterializeToString(std::string& str_buffer);
-  bool MaterializeToRawOStream(::llvm::raw_ostream& out_stream);
-
-  friend class CompilerLLVM;  // For LlvmCompilationUnit constructor
-};
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_LLVM_COMPILATION_UNIT_H_
diff --git a/compiler/llvm/llvm_compiler.cc b/compiler/llvm/llvm_compiler.cc
deleted file mode 100644
index fa93e00..0000000
--- a/compiler/llvm/llvm_compiler.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2014 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 "llvm_compiler.h"
-
-#include "base/macros.h"
-#ifdef ART_USE_PORTABLE_COMPILER
-#include "compiler.h"
-#include "compiler_llvm.h"
-#include "dex/portable/mir_to_gbc.h"
-#include "dex_file.h"
-#include "elf_writer_mclinker.h"
-#include "mirror/art_method-inl.h"
-#endif
-
-namespace art {
-
-#ifdef ART_USE_PORTABLE_COMPILER
-
-namespace llvm {
-
-// Thread-local storage compiler worker threads
-class LLVMCompilerTls : public CompilerTls {
-  public:
-    LLVMCompilerTls() : llvm_info_(nullptr) {}
-    ~LLVMCompilerTls() {}
-
-    void* GetLLVMInfo() { return llvm_info_; }
-
-    void SetLLVMInfo(void* llvm_info) { llvm_info_ = llvm_info; }
-
-  private:
-    void* llvm_info_;
-};
-
-
-
-class LLVMCompiler FINAL : public Compiler {
- public:
-  explicit LLVMCompiler(CompilerDriver* driver) : Compiler(driver, 1000) {}
-
-  CompilerTls* CreateNewCompilerTls() {
-    return new LLVMCompilerTls();
-  }
-
-  void Init() const OVERRIDE {
-    ArtInitCompilerContext(GetCompilerDriver());
-  }
-
-  void UnInit() const OVERRIDE {
-    ArtUnInitCompilerContext(GetCompilerDriver());
-  }
-
-  bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const
-      OVERRIDE {
-    return true;
-  }
-
-  CompiledMethod* Compile(const DexFile::CodeItem* code_item,
-                          uint32_t access_flags,
-                          InvokeType invoke_type,
-                          uint16_t class_def_idx,
-                          uint32_t method_idx,
-                          jobject class_loader,
-                          const DexFile& dex_file) const OVERRIDE {
-    CompiledMethod* method = TryCompileWithSeaIR(code_item,
-                                                 access_flags,
-                                                 invoke_type,
-                                                 class_def_idx,
-                                                 method_idx,
-                                                 class_loader,
-                                                 dex_file);
-    if (method != nullptr) {
-      return method;
-    }
-
-    return ArtCompileMethod(GetCompilerDriver(),
-                            code_item,
-                            access_flags,
-                            invoke_type,
-                            class_def_idx,
-                            method_idx,
-                            class_loader,
-                            dex_file);
-  }
-
-  CompiledMethod* JniCompile(uint32_t access_flags,
-                             uint32_t method_idx,
-                             const DexFile& dex_file) const OVERRIDE {
-    return ArtLLVMJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
-  }
-
-  uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const {
-    return reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode());
-  }
-
-  bool WriteElf(art::File* file,
-                OatWriter* oat_writer,
-                const std::vector<const art::DexFile*>& dex_files,
-                const std::string& android_root,
-                bool is_host, const CompilerDriver& driver) const
-      OVERRIDE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return art::ElfWriterMclinker::Create(
-        file, oat_writer, dex_files, android_root, is_host, driver);
-  }
-
-  Backend* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
-    return PortableCodeGenerator(
-        cu, cu->mir_graph.get(), &cu->arena,
-        reinterpret_cast<art::llvm::LlvmCompilationUnit*>(compilation_unit));
-  }
-
-  void InitCompilationUnit(CompilationUnit& cu) const {
-      // Fused long branches not currently useful in bitcode.
-    cu.disable_opt |=
-        (1 << kBranchFusing) |
-        (1 << kSuppressExceptionEdges);
-  }
-
-  bool IsPortable() const OVERRIDE {
-    return true;
-  }
-
-  void SetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) {
-    typedef void (*SetBitcodeFileNameFn)(const CompilerDriver&, const std::string&);
-
-    SetBitcodeFileNameFn set_bitcode_file_name =
-      reinterpret_cast<SetBitcodeFileNameFn>(compilerLLVMSetBitcodeFileName);
-
-    set_bitcode_file_name(driver, filename);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(LLVMCompiler);
-};
-
-}  // namespace llvm
-#endif
-
-Compiler* CreateLLVMCompiler(CompilerDriver* driver) {
-#ifdef ART_USE_PORTABLE_COMPILER
-  return new llvm::LLVMCompiler(driver);
-#else
-  UNUSED(driver);
-  return nullptr;
-#endif
-}
-
-}  // namespace art
diff --git a/compiler/llvm/llvm_compiler.h b/compiler/llvm/llvm_compiler.h
deleted file mode 100644
index da6d0e9..0000000
--- a/compiler/llvm/llvm_compiler.h
+++ /dev/null
@@ -1,29 +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_COMPILER_LLVM_LLVM_COMPILER_H_
-#define ART_COMPILER_LLVM_LLVM_COMPILER_H_
-
-namespace art {
-
-class Compiler;
-class CompilerDriver;
-
-Compiler* CreateLLVMCompiler(CompilerDriver* driver);
-
-}
-
-#endif  // ART_COMPILER_LLVM_LLVM_COMPILER_H_
diff --git a/compiler/llvm/md_builder.cc b/compiler/llvm/md_builder.cc
deleted file mode 100644
index 4331557..0000000
--- a/compiler/llvm/md_builder.cc
+++ /dev/null
@@ -1,117 +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 "md_builder.h"
-
-#include "llvm/IR/MDBuilder.h"
-
-#include <string>
-
-namespace art {
-namespace llvm {
-
-
-::llvm::MDNode* MDBuilder::GetTBAASpecialType(TBAASpecialType sty_id) {
-  DCHECK_GE(sty_id, 0) << "Unknown TBAA special type: " << sty_id;
-  DCHECK_LT(sty_id, MAX_TBAA_SPECIAL_TYPE) << "Unknown TBAA special type: " << sty_id;
-  DCHECK(tbaa_root_ != NULL);
-
-  ::llvm::MDNode*& spec_ty = tbaa_special_type_[sty_id];
-  if (spec_ty == NULL) {
-    switch (sty_id) {
-    case kTBAARegister:
-      spec_ty = createTBAANode("Register", tbaa_root_);
-      break;
-    case kTBAAStackTemp:
-      spec_ty = createTBAANode("StackTemp", tbaa_root_);
-      break;
-    case kTBAAHeapArray:
-      spec_ty = createTBAANode("HeapArray", tbaa_root_);
-      break;
-    case kTBAAHeapInstance:
-      spec_ty = createTBAANode("HeapInstance", tbaa_root_);
-      break;
-    case kTBAAHeapStatic:
-      spec_ty = createTBAANode("HeapStatic", tbaa_root_);
-      break;
-    case kTBAAJRuntime:
-      spec_ty = createTBAANode("JRuntime", tbaa_root_);
-      break;
-    case kTBAARuntimeInfo:
-      spec_ty = createTBAANode("RuntimeInfo", GetTBAASpecialType(kTBAAJRuntime));
-      break;
-    case kTBAAShadowFrame:
-      spec_ty = createTBAANode("ShadowFrame", GetTBAASpecialType(kTBAAJRuntime));
-      break;
-    case kTBAAConstJObject:
-      spec_ty = createTBAANode("ConstJObject", tbaa_root_, true);
-      break;
-    default:
-      LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
-      break;
-    }
-  }
-  return spec_ty;
-}
-
-::llvm::MDNode* MDBuilder::GetTBAAMemoryJType(TBAASpecialType sty_id, JType jty_id) {
-  DCHECK(sty_id == kTBAAHeapArray ||
-         sty_id == kTBAAHeapInstance ||
-         sty_id == kTBAAHeapStatic) << "SpecialType must be array, instance, or static";
-
-  DCHECK_GE(jty_id, 0) << "Unknown JType: " << jty_id;
-  DCHECK_LT(jty_id, MAX_JTYPE) << "Unknown JType: " << jty_id;
-  DCHECK_NE(jty_id, kVoid) << "Can't load/store Void type!";
-
-  std::string name;
-  size_t sty_mapped_index = 0;
-  switch (sty_id) {
-  case kTBAAHeapArray:    sty_mapped_index = 0; name = "HeapArray "; break;
-  case kTBAAHeapInstance: sty_mapped_index = 1; name = "HeapInstance "; break;
-  case kTBAAHeapStatic:   sty_mapped_index = 2; name = "HeapStatic "; break;
-  default:
-    LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
-    break;
-  }
-
-  ::llvm::MDNode*& spec_ty = tbaa_memory_jtype_[sty_mapped_index][jty_id];
-  if (spec_ty != NULL) {
-    return spec_ty;
-  }
-
-  switch (jty_id) {
-  case kBoolean: name += "Boolean"; break;
-  case kByte:    name += "Byte"; break;
-  case kChar:    name += "Char"; break;
-  case kShort:   name += "Short"; break;
-  case kInt:     name += "Int"; break;
-  case kLong:    name += "Long"; break;
-  case kFloat:   name += "Float"; break;
-  case kDouble:  name += "Double"; break;
-  case kObject:  name += "Object"; break;
-  default:
-    LOG(FATAL) << "Unknown JType: " << jty_id;
-    break;
-  }
-
-  spec_ty = createTBAANode(name, GetTBAASpecialType(sty_id));
-  return spec_ty;
-}
-
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/md_builder.h b/compiler/llvm/md_builder.h
deleted file mode 100644
index 1246f9b..0000000
--- a/compiler/llvm/md_builder.h
+++ /dev/null
@@ -1,71 +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_COMPILER_LLVM_MD_BUILDER_H_
-#define ART_COMPILER_LLVM_MD_BUILDER_H_
-
-#include "backend_types.h"
-
-#include "llvm/IR/MDBuilder.h"
-
-#include <cstring>
-
-namespace llvm {
-  class LLVMContext;
-  class MDNode;
-}
-
-namespace art {
-namespace llvm {
-
-typedef ::llvm::MDBuilder LLVMMDBuilder;
-
-class MDBuilder : public LLVMMDBuilder {
- public:
-  explicit MDBuilder(::llvm::LLVMContext& context)
-     : LLVMMDBuilder(context), tbaa_root_(createTBAARoot("Art TBAA Root")) {
-    std::memset(tbaa_special_type_, 0, sizeof(tbaa_special_type_));
-    std::memset(tbaa_memory_jtype_, 0, sizeof(tbaa_memory_jtype_));
-
-    // Pre-generate the MDNode for static branch prediction
-    // 64 and 4 are the llvm.expect's default values
-    expect_cond_[kLikely] = createBranchWeights(64, 4);
-    expect_cond_[kUnlikely] = createBranchWeights(4, 64);
-  }
-
-  ::llvm::MDNode* GetTBAASpecialType(TBAASpecialType special_ty);
-  ::llvm::MDNode* GetTBAAMemoryJType(TBAASpecialType special_ty, JType j_ty);
-
-  ::llvm::MDNode* GetBranchWeights(ExpectCond expect) {
-    DCHECK_LT(expect, MAX_EXPECT) << "MAX_EXPECT is not for branch weight";
-    return expect_cond_[expect];
-  }
-
- private:
-  ::llvm::MDNode* const tbaa_root_;
-  ::llvm::MDNode* tbaa_special_type_[MAX_TBAA_SPECIAL_TYPE];
-  // There are 3 categories of memory types will not alias: array element, instance field, and
-  // static field.
-  ::llvm::MDNode* tbaa_memory_jtype_[3][MAX_JTYPE];
-
-  ::llvm::MDNode* expect_cond_[MAX_EXPECT];
-};
-
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_MD_BUILDER_H_
diff --git a/compiler/llvm/runtime_support_builder.cc b/compiler/llvm/runtime_support_builder.cc
deleted file mode 100644
index c825fbf..0000000
--- a/compiler/llvm/runtime_support_builder.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2011 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 "runtime_support_builder.h"
-
-#include "gc/accounting/card_table.h"
-#include "ir_builder.h"
-#include "monitor.h"
-#include "mirror/object.h"
-#include "runtime_support_llvm_func_list.h"
-#include "thread.h"
-
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/Module.h>
-#include <llvm/IR/Type.h>
-
-using ::llvm::BasicBlock;
-using ::llvm::CallInst;
-using ::llvm::Function;
-using ::llvm::Value;
-
-namespace art {
-namespace llvm {
-
-RuntimeSupportBuilder::RuntimeSupportBuilder(::llvm::LLVMContext& context,
-                                             ::llvm::Module& module,
-                                             IRBuilder& irb)
-    : context_(context), module_(module), irb_(irb) {
-  memset(target_runtime_support_func_, 0, sizeof(target_runtime_support_func_));
-#define GET_RUNTIME_SUPPORT_FUNC_DECL(ID, NAME) \
-  do { \
-    ::llvm::Function* fn = module_.getFunction(#NAME); \
-    DCHECK(fn != NULL) << "Function not found: " << #NAME; \
-    runtime_support_func_decls_[runtime_support::ID] = fn; \
-  } while (0);
-
-  RUNTIME_SUPPORT_FUNC_LIST(GET_RUNTIME_SUPPORT_FUNC_DECL)
-}
-
-
-/* Thread */
-
-::llvm::Value* RuntimeSupportBuilder::EmitGetCurrentThread() {
-  Function* func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
-  CallInst* call_inst = irb_.CreateCall(func);
-  call_inst->setOnlyReadsMemory();
-  irb_.SetTBAA(call_inst, kTBAAConstJObject);
-  return call_inst;
-}
-
-::llvm::Value* RuntimeSupportBuilder::EmitLoadFromThreadOffset(int64_t offset, ::llvm::Type* type,
-                                                             TBAASpecialType s_ty) {
-  Value* thread = EmitGetCurrentThread();
-  return irb_.LoadFromObjectOffset(thread, offset, type, s_ty);
-}
-
-void RuntimeSupportBuilder::EmitStoreToThreadOffset(int64_t offset, ::llvm::Value* value,
-                                                    TBAASpecialType s_ty) {
-  Value* thread = EmitGetCurrentThread();
-  irb_.StoreToObjectOffset(thread, offset, value, s_ty);
-}
-
-::llvm::Value* RuntimeSupportBuilder::EmitSetCurrentThread(::llvm::Value* thread) {
-  Function* func = GetRuntimeSupportFunction(runtime_support::SetCurrentThread);
-  return irb_.CreateCall(func, thread);
-}
-
-
-/* ShadowFrame */
-
-::llvm::Value* RuntimeSupportBuilder::EmitPushShadowFrame(::llvm::Value* new_shadow_frame,
-                                                        ::llvm::Value* method,
-                                                        uint32_t num_vregs) {
-  Value* old_shadow_frame = EmitLoadFromThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
-                                                     irb_.getArtFrameTy()->getPointerTo(),
-                                                     kTBAARuntimeInfo);
-  EmitStoreToThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
-                          new_shadow_frame,
-                          kTBAARuntimeInfo);
-
-  // Store the method pointer
-  irb_.StoreToObjectOffset(new_shadow_frame,
-                           ShadowFrame::MethodOffset(),
-                           method,
-                           kTBAAShadowFrame);
-
-  // Store the number of vregs
-  irb_.StoreToObjectOffset(new_shadow_frame,
-                           ShadowFrame::NumberOfVRegsOffset(),
-                           irb_.getInt32(num_vregs),
-                           kTBAAShadowFrame);
-
-  // Store the link to previous shadow frame
-  irb_.StoreToObjectOffset(new_shadow_frame,
-                           ShadowFrame::LinkOffset(),
-                           old_shadow_frame,
-                           kTBAAShadowFrame);
-
-  return old_shadow_frame;
-}
-
-::llvm::Value*
-RuntimeSupportBuilder::EmitPushShadowFrameNoInline(::llvm::Value* new_shadow_frame,
-                                                   ::llvm::Value* method,
-                                                   uint32_t num_vregs) {
-  Function* func = GetRuntimeSupportFunction(runtime_support::PushShadowFrame);
-  ::llvm::CallInst* call_inst =
-      irb_.CreateCall4(func,
-                       EmitGetCurrentThread(),
-                       new_shadow_frame,
-                       method,
-                       irb_.getInt32(num_vregs));
-  irb_.SetTBAA(call_inst, kTBAARuntimeInfo);
-  return call_inst;
-}
-
-void RuntimeSupportBuilder::EmitPopShadowFrame(::llvm::Value* old_shadow_frame) {
-  // Store old shadow frame to TopShadowFrame
-  EmitStoreToThreadOffset(Thread::TopShadowFrameOffset().Int32Value(),
-                          old_shadow_frame,
-                          kTBAARuntimeInfo);
-}
-
-
-/* Exception */
-
-::llvm::Value* RuntimeSupportBuilder::EmitGetAndClearException() {
-  Function* slow_func = GetRuntimeSupportFunction(runtime_support::GetAndClearException);
-  return irb_.CreateCall(slow_func, EmitGetCurrentThread());
-}
-
-::llvm::Value* RuntimeSupportBuilder::EmitIsExceptionPending() {
-  Value* exception = EmitLoadFromThreadOffset(Thread::ExceptionOffset().Int32Value(),
-                                              irb_.getJObjectTy(),
-                                              kTBAARuntimeInfo);
-  // If exception not null
-  return irb_.CreateIsNotNull(exception);
-}
-
-
-/* Suspend */
-
-void RuntimeSupportBuilder::EmitTestSuspend() {
-  Function* slow_func = GetRuntimeSupportFunction(runtime_support::TestSuspend);
-  CallInst* call_inst = irb_.CreateCall(slow_func, EmitGetCurrentThread());
-  irb_.SetTBAA(call_inst, kTBAAJRuntime);
-}
-
-
-/* Monitor */
-
-void RuntimeSupportBuilder::EmitLockObject(::llvm::Value* object) {
-  Function* slow_func = GetRuntimeSupportFunction(runtime_support::LockObject);
-  irb_.CreateCall2(slow_func, object, EmitGetCurrentThread());
-}
-
-void RuntimeSupportBuilder::EmitUnlockObject(::llvm::Value* object) {
-  Function* slow_func = GetRuntimeSupportFunction(runtime_support::UnlockObject);
-  irb_.CreateCall2(slow_func, object, EmitGetCurrentThread());
-}
-
-
-void RuntimeSupportBuilder::EmitMarkGCCard(::llvm::Value* value, ::llvm::Value* target_addr) {
-  Function* parent_func = irb_.GetInsertBlock()->getParent();
-  BasicBlock* bb_mark_gc_card = BasicBlock::Create(context_, "mark_gc_card", parent_func);
-  BasicBlock* bb_cont = BasicBlock::Create(context_, "mark_gc_card_cont", parent_func);
-
-  ::llvm::Value* not_null = irb_.CreateIsNotNull(value);
-  irb_.CreateCondBr(not_null, bb_mark_gc_card, bb_cont);
-
-  irb_.SetInsertPoint(bb_mark_gc_card);
-  Value* card_table = EmitLoadFromThreadOffset(Thread::CardTableOffset().Int32Value(),
-                                               irb_.getInt8Ty()->getPointerTo(),
-                                               kTBAAConstJObject);
-  Value* target_addr_int = irb_.CreatePtrToInt(target_addr, irb_.getPtrEquivIntTy());
-  Value* card_no = irb_.CreateLShr(target_addr_int,
-                                   irb_.getPtrEquivInt(gc::accounting::CardTable::kCardShift));
-  Value* card_table_entry = irb_.CreateGEP(card_table, card_no);
-  irb_.CreateStore(irb_.getInt8(gc::accounting::CardTable::kCardDirty), card_table_entry,
-                   kTBAARuntimeInfo);
-  irb_.CreateBr(bb_cont);
-
-  irb_.SetInsertPoint(bb_cont);
-}
-
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/runtime_support_builder.h b/compiler/llvm/runtime_support_builder.h
deleted file mode 100644
index 898611a..0000000
--- a/compiler/llvm/runtime_support_builder.h
+++ /dev/null
@@ -1,98 +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_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_H_
-#define ART_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_H_
-
-#include "backend_types.h"
-#include "base/logging.h"
-#include "runtime_support_llvm_func.h"
-
-#include <stdint.h>
-
-namespace llvm {
-  class LLVMContext;
-  class Module;
-  class Function;
-  class Type;
-  class Value;
-}
-
-namespace art {
-namespace llvm {
-
-class IRBuilder;
-
-
-class RuntimeSupportBuilder {
- public:
-  RuntimeSupportBuilder(::llvm::LLVMContext& context, ::llvm::Module& module, IRBuilder& irb);
-
-  /* Thread */
-  virtual ::llvm::Value* EmitGetCurrentThread();
-  virtual ::llvm::Value* EmitLoadFromThreadOffset(int64_t offset, ::llvm::Type* type,
-                                                TBAASpecialType s_ty);
-  virtual void EmitStoreToThreadOffset(int64_t offset, ::llvm::Value* value,
-                                       TBAASpecialType s_ty);
-  virtual ::llvm::Value* EmitSetCurrentThread(::llvm::Value* thread);
-
-  /* ShadowFrame */
-  virtual ::llvm::Value* EmitPushShadowFrame(::llvm::Value* new_shadow_frame,
-                                           ::llvm::Value* method, uint32_t num_vregs);
-  virtual ::llvm::Value* EmitPushShadowFrameNoInline(::llvm::Value* new_shadow_frame,
-                                                   ::llvm::Value* method, uint32_t num_vregs);
-  virtual void EmitPopShadowFrame(::llvm::Value* old_shadow_frame);
-
-  /* Exception */
-  virtual ::llvm::Value* EmitGetAndClearException();
-  virtual ::llvm::Value* EmitIsExceptionPending();
-
-  /* Suspend */
-  virtual void EmitTestSuspend();
-
-  /* Monitor */
-  void EmitLockObject(::llvm::Value* object);
-  void EmitUnlockObject(::llvm::Value* object);
-
-  /* MarkGCCard */
-  virtual void EmitMarkGCCard(::llvm::Value* value, ::llvm::Value* target_addr);
-
-  ::llvm::Function* GetRuntimeSupportFunction(runtime_support::RuntimeId id) {
-    if (id >= 0 && id < runtime_support::MAX_ID) {
-      return runtime_support_func_decls_[id];
-    } else {
-      LOG(ERROR) << "Unknown runtime function id: " << id;
-      return NULL;
-    }
-  }
-
-  virtual ~RuntimeSupportBuilder() {}
-
- protected:
-  ::llvm::LLVMContext& context_;
-  ::llvm::Module& module_;
-  IRBuilder& irb_;
-
- private:
-  ::llvm::Function* runtime_support_func_decls_[runtime_support::MAX_ID];
-  bool target_runtime_support_func_[runtime_support::MAX_ID];
-};
-
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_H_
diff --git a/compiler/llvm/runtime_support_builder_arm.cc b/compiler/llvm/runtime_support_builder_arm.cc
deleted file mode 100644
index cad4624..0000000
--- a/compiler/llvm/runtime_support_builder_arm.cc
+++ /dev/null
@@ -1,120 +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 "runtime_support_builder_arm.h"
-
-#include "ir_builder.h"
-#include "thread.h"
-#include "utils_llvm.h"
-
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/InlineAsm.h>
-#include <llvm/IR/Module.h>
-#include <llvm/IR/Type.h>
-
-#include <vector>
-
-using ::llvm::CallInst;
-using ::llvm::Function;
-using ::llvm::FunctionType;
-using ::llvm::InlineAsm;
-using ::llvm::IntegerType;
-using ::llvm::Type;
-using ::llvm::Value;
-
-namespace {
-
-char LDRSTRSuffixByType(art::llvm::IRBuilder& irb, Type* type) {
-  int width = type->isPointerTy() ?
-              irb.getSizeOfPtrEquivInt()*8 :
-              ::llvm::cast<IntegerType>(type)->getBitWidth();
-  switch (width) {
-    case 8:  return 'b';
-    case 16: return 'h';
-    case 32: return ' ';
-    default:
-      LOG(FATAL) << "Unsupported width: " << width;
-      return ' ';
-  }
-}
-
-}  // namespace
-
-namespace art {
-namespace llvm {
-
-/* Thread */
-
-Value* RuntimeSupportBuilderARM::EmitGetCurrentThread() {
-  Function* ori_func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
-  InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), "mov $0, r9", "=r", false);
-  CallInst* thread = irb_.CreateCall(func);
-  thread->setDoesNotAccessMemory();
-  irb_.SetTBAA(thread, kTBAAConstJObject);
-  return thread;
-}
-
-Value* RuntimeSupportBuilderARM::EmitLoadFromThreadOffset(int64_t offset, ::llvm::Type* type,
-                                                          TBAASpecialType s_ty) {
-  FunctionType* func_ty = FunctionType::get(/*Result=*/type,
-                                            /*isVarArg=*/false);
-  std::string inline_asm(StringPrintf("ldr%c $0, [r9, #%d]",
-                                      LDRSTRSuffixByType(irb_, type),
-                                      static_cast<int>(offset)));
-  InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "=r", true);
-  CallInst* result = irb_.CreateCall(func);
-  result->setOnlyReadsMemory();
-  irb_.SetTBAA(result, s_ty);
-  return result;
-}
-
-void RuntimeSupportBuilderARM::EmitStoreToThreadOffset(int64_t offset, Value* value,
-                                                       TBAASpecialType s_ty) {
-  FunctionType* func_ty = FunctionType::get(/*Result=*/Type::getVoidTy(context_),
-                                            /*Params=*/value->getType(),
-                                            /*isVarArg=*/false);
-  std::string inline_asm(StringPrintf("str%c $0, [r9, #%d]",
-                                      LDRSTRSuffixByType(irb_, value->getType()),
-                                      static_cast<int>(offset)));
-  InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "r", true);
-  CallInst* call_inst = irb_.CreateCall(func, value);
-  irb_.SetTBAA(call_inst, s_ty);
-}
-
-Value* RuntimeSupportBuilderARM::EmitSetCurrentThread(Value* thread) {
-  // Separate to two InlineAsm: The first one produces the return value, while the second,
-  // sets the current thread.
-  // LLVM can delete the first one if the caller in LLVM IR doesn't use the return value.
-  //
-  // Here we don't call EmitGetCurrentThread, because we mark it as DoesNotAccessMemory and
-  // ConstJObject. We denote side effect to "true" below instead, so LLVM won't
-  // reorder these instructions incorrectly.
-  Function* ori_func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
-  InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), "mov $0, r9", "=r", true);
-  CallInst* old_thread_register = irb_.CreateCall(func);
-  old_thread_register->setOnlyReadsMemory();
-
-  FunctionType* func_ty = FunctionType::get(/*Result=*/Type::getVoidTy(context_),
-                                            /*Params=*/irb_.getJObjectTy(),
-                                            /*isVarArg=*/false);
-  func = InlineAsm::get(func_ty, "mov r9, $0", "r", true);
-  irb_.CreateCall(func, thread);
-  return old_thread_register;
-}
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/runtime_support_builder_arm.h b/compiler/llvm/runtime_support_builder_arm.h
deleted file mode 100644
index 0d01509..0000000
--- a/compiler/llvm/runtime_support_builder_arm.h
+++ /dev/null
@@ -1,42 +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_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_ARM_H_
-#define ART_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_ARM_H_
-
-#include "runtime_support_builder.h"
-
-namespace art {
-namespace llvm {
-
-class RuntimeSupportBuilderARM : public RuntimeSupportBuilder {
- public:
-  RuntimeSupportBuilderARM(::llvm::LLVMContext& context, ::llvm::Module& module, IRBuilder& irb)
-    : RuntimeSupportBuilder(context, module, irb) {}
-
-  /* Thread */
-  virtual ::llvm::Value* EmitGetCurrentThread();
-  virtual ::llvm::Value* EmitLoadFromThreadOffset(int64_t offset, ::llvm::Type* type,
-                                                TBAASpecialType s_ty);
-  virtual void EmitStoreToThreadOffset(int64_t offset, ::llvm::Value* value,
-                                       TBAASpecialType s_ty);
-  virtual ::llvm::Value* EmitSetCurrentThread(::llvm::Value* thread);
-};
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_ARM_H_
diff --git a/compiler/llvm/runtime_support_builder_x86.cc b/compiler/llvm/runtime_support_builder_x86.cc
deleted file mode 100644
index 3d11f9d..0000000
--- a/compiler/llvm/runtime_support_builder_x86.cc
+++ /dev/null
@@ -1,84 +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 "runtime_support_builder_x86.h"
-
-#include "base/stringprintf.h"
-#include "ir_builder.h"
-#include "thread.h"
-#include "utils_llvm.h"
-
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/InlineAsm.h>
-#include <llvm/IR/Module.h>
-#include <llvm/IR/Type.h>
-
-#include <vector>
-
-using ::llvm::CallInst;
-using ::llvm::Function;
-using ::llvm::FunctionType;
-using ::llvm::InlineAsm;
-using ::llvm::Type;
-using ::llvm::UndefValue;
-using ::llvm::Value;
-
-namespace art {
-namespace llvm {
-
-
-Value* RuntimeSupportBuilderX86::EmitGetCurrentThread() {
-  Function* ori_func = GetRuntimeSupportFunction(runtime_support::GetCurrentThread);
-  std::string inline_asm(StringPrintf("mov %%fs:%d, $0", Thread::SelfOffset().Int32Value()));
-  InlineAsm* func = InlineAsm::get(ori_func->getFunctionType(), inline_asm, "=r", false);
-  CallInst* thread = irb_.CreateCall(func);
-  thread->setDoesNotAccessMemory();
-  irb_.SetTBAA(thread, kTBAAConstJObject);
-  return thread;
-}
-
-Value* RuntimeSupportBuilderX86::EmitLoadFromThreadOffset(int64_t offset, Type* type,
-                                                          TBAASpecialType s_ty) {
-  FunctionType* func_ty = FunctionType::get(/*Result=*/type,
-                                            /*isVarArg=*/false);
-  std::string inline_asm(StringPrintf("mov %%fs:%d, $0", static_cast<int>(offset)));
-  InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "=r", true);
-  CallInst* result = irb_.CreateCall(func);
-  result->setOnlyReadsMemory();
-  irb_.SetTBAA(result, s_ty);
-  return result;
-}
-
-void RuntimeSupportBuilderX86::EmitStoreToThreadOffset(int64_t offset, Value* value,
-                                                       TBAASpecialType s_ty) {
-  FunctionType* func_ty = FunctionType::get(/*Result=*/Type::getVoidTy(context_),
-                                            /*Params=*/value->getType(),
-                                            /*isVarArg=*/false);
-  std::string inline_asm(StringPrintf("mov $0, %%fs:%d", static_cast<int>(offset)));
-  InlineAsm* func = InlineAsm::get(func_ty, inline_asm, "r", true);
-  CallInst* call_inst = irb_.CreateCall(func, value);
-  irb_.SetTBAA(call_inst, s_ty);
-}
-
-Value* RuntimeSupportBuilderX86::EmitSetCurrentThread(Value*) {
-  /* Nothing to be done. */
-  return UndefValue::get(irb_.getJObjectTy());
-}
-
-
-}  // namespace llvm
-}  // namespace art
diff --git a/compiler/llvm/runtime_support_builder_x86.h b/compiler/llvm/runtime_support_builder_x86.h
deleted file mode 100644
index 5f36e7c..0000000
--- a/compiler/llvm/runtime_support_builder_x86.h
+++ /dev/null
@@ -1,42 +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_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_X86_H_
-#define ART_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_X86_H_
-
-#include "runtime_support_builder.h"
-
-namespace art {
-namespace llvm {
-
-class RuntimeSupportBuilderX86 : public RuntimeSupportBuilder {
- public:
-  RuntimeSupportBuilderX86(::llvm::LLVMContext& context, ::llvm::Module& module, IRBuilder& irb)
-    : RuntimeSupportBuilder(context, module, irb) {}
-
-  /* Thread */
-  virtual ::llvm::Value* EmitGetCurrentThread();
-  virtual ::llvm::Value* EmitLoadFromThreadOffset(int64_t offset, ::llvm::Type* type,
-                                                TBAASpecialType s_ty);
-  virtual void EmitStoreToThreadOffset(int64_t offset, ::llvm::Value* value,
-                                       TBAASpecialType s_ty);
-  virtual ::llvm::Value* EmitSetCurrentThread(::llvm::Value* thread);
-};
-
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_RUNTIME_SUPPORT_BUILDER_X86_H_
diff --git a/compiler/llvm/runtime_support_llvm_func.h b/compiler/llvm/runtime_support_llvm_func.h
deleted file mode 100644
index a5ad852..0000000
--- a/compiler/llvm/runtime_support_llvm_func.h
+++ /dev/null
@@ -1,37 +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_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_FUNC_H_
-#define ART_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_FUNC_H_
-
-#include "runtime_support_llvm_func_list.h"
-
-namespace art {
-namespace llvm {
-namespace runtime_support {
-
-  enum RuntimeId {
-#define DEFINE_RUNTIME_SUPPORT_FUNC_ID(ID, NAME) ID,
-    RUNTIME_SUPPORT_FUNC_LIST(DEFINE_RUNTIME_SUPPORT_FUNC_ID)
-
-    MAX_ID
-  };
-
-}  // namespace runtime_support
-}  // namespace llvm
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_FUNC_H_
diff --git a/compiler/llvm/runtime_support_llvm_func_list.h b/compiler/llvm/runtime_support_llvm_func_list.h
deleted file mode 100644
index b5ac1ff..0000000
--- a/compiler/llvm/runtime_support_llvm_func_list.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_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_FUNC_LIST_H_
-#define ART_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_FUNC_LIST_H_
-
-#define RUNTIME_SUPPORT_FUNC_LIST(V) \
-  V(LockObject, art_portable_lock_object_from_code) \
-  V(UnlockObject, art_portable_unlock_object_from_code) \
-  V(GetCurrentThread, art_portable_get_current_thread_from_code) \
-  V(SetCurrentThread, art_portable_set_current_thread_from_code) \
-  V(PushShadowFrame, art_portable_push_shadow_frame_from_code) \
-  V(PopShadowFrame, art_portable_pop_shadow_frame_from_code) \
-  V(TestSuspend, art_portable_test_suspend_from_code) \
-  V(ThrowException, art_portable_throw_exception_from_code) \
-  V(ThrowStackOverflowException, art_portable_throw_stack_overflow_from_code) \
-  V(ThrowNullPointerException, art_portable_throw_null_pointer_exception_from_code) \
-  V(ThrowDivZeroException, art_portable_throw_div_zero_from_code) \
-  V(ThrowIndexOutOfBounds, art_portable_throw_array_bounds_from_code) \
-  V(InitializeTypeAndVerifyAccess, art_portable_initialize_type_and_verify_access_from_code) \
-  V(InitializeType, art_portable_initialize_type_from_code) \
-  V(IsAssignable, art_portable_is_assignable_from_code) \
-  V(CheckCast, art_portable_check_cast_from_code) \
-  V(CheckPutArrayElement, art_portable_check_put_array_element_from_code) \
-  V(AllocObject, art_portable_alloc_object_from_code) \
-  V(AllocObjectWithAccessCheck, art_portable_alloc_object_from_code_with_access_check) \
-  V(AllocArray, art_portable_alloc_array_from_code) \
-  V(AllocArrayWithAccessCheck, art_portable_alloc_array_from_code_with_access_check) \
-  V(CheckAndAllocArray, art_portable_check_and_alloc_array_from_code) \
-  V(CheckAndAllocArrayWithAccessCheck, art_portable_check_and_alloc_array_from_code_with_access_check) \
-  V(FindStaticMethodWithAccessCheck, art_portable_find_static_method_from_code_with_access_check) \
-  V(FindDirectMethodWithAccessCheck, art_portable_find_direct_method_from_code_with_access_check) \
-  V(FindVirtualMethodWithAccessCheck, art_portable_find_virtual_method_from_code_with_access_check) \
-  V(FindSuperMethodWithAccessCheck, art_portable_find_super_method_from_code_with_access_check) \
-  V(FindInterfaceMethodWithAccessCheck, art_portable_find_interface_method_from_code_with_access_check) \
-  V(FindInterfaceMethod, art_portable_find_interface_method_from_code) \
-  V(ResolveString, art_portable_resolve_string_from_code) \
-  V(Set32Static, art_portable_set32_static_from_code) \
-  V(Set64Static, art_portable_set64_static_from_code) \
-  V(SetObjectStatic, art_portable_set_obj_static_from_code) \
-  V(Get32Static, art_portable_get32_static_from_code) \
-  V(Get64Static, art_portable_get64_static_from_code) \
-  V(GetObjectStatic, art_portable_get_obj_static_from_code) \
-  V(Set32Instance, art_portable_set32_instance_from_code) \
-  V(Set64Instance, art_portable_set64_instance_from_code) \
-  V(SetObjectInstance, art_portable_set_obj_instance_from_code) \
-  V(Get32Instance, art_portable_get32_instance_from_code) \
-  V(Get64Instance, art_portable_get64_instance_from_code) \
-  V(GetObjectInstance, art_portable_get_obj_instance_from_code) \
-  V(InitializeStaticStorage, art_portable_initialize_static_storage_from_code) \
-  V(FillArrayData, art_portable_fill_array_data_from_code) \
-  V(GetAndClearException, art_portable_get_and_clear_exception) \
-  V(IsExceptionPending, art_portable_is_exception_pending_from_code) \
-  V(FindCatchBlock, art_portable_find_catch_block_from_code) \
-  V(MarkGCCard, art_portable_mark_gc_card_from_code) \
-  V(ProxyInvokeHandler, art_portable_proxy_invoke_handler_from_code) \
-  V(art_d2l, art_d2l) \
-  V(art_d2i, art_d2i) \
-  V(art_f2l, art_f2l) \
-  V(art_f2i, art_f2i) \
-  V(JniMethodStart,                        art_portable_jni_method_start) \
-  V(JniMethodStartSynchronized,            art_portable_jni_method_start_synchronized) \
-  V(JniMethodEnd,                          art_portable_jni_method_end) \
-  V(JniMethodEndSynchronized,              art_portable_jni_method_end_synchronized) \
-  V(JniMethodEndWithReference,             art_portable_jni_method_end_with_reference) \
-  V(JniMethodEndWithReferenceSynchronized, art_portable_jni_method_end_with_reference_synchronized)
-
-#endif  // ART_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_FUNC_LIST_H_
diff --git a/compiler/llvm/tools/gen_art_module_cc.sh b/compiler/llvm/tools/gen_art_module_cc.sh
deleted file mode 100755
index c5df333..0000000
--- a/compiler/llvm/tools/gen_art_module_cc.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/bash -e
-
-# 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.
-
-SCRIPTDIR=`dirname "$0"`
-cd "${SCRIPTDIR}/.."
-
-mkdir -p generated
-
-OUTPUT_FILE=generated/art_module.cc
-
-echo "// Generated with ${0}" > ${OUTPUT_FILE}
-
-echo '
-
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
-// TODO: Remove this pragma after llc can generate makeLLVMModuleContents()
-// with smaller frame size.
-
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/IR/Function.h>
-#include <llvm/IR/Module.h>
-#include <llvm/IR/Type.h>
-
-#include <vector>
-
-using namespace llvm;
-
-namespace art {
-namespace llvm {
-
-' >> ${OUTPUT_FILE}
-
-llc -march=cpp -cppgen=contents art_module.ll -o - >> ${OUTPUT_FILE}
-
-echo '
-} // namespace llvm
-} // namespace art' >> ${OUTPUT_FILE}
diff --git a/compiler/llvm/utils_llvm.h b/compiler/llvm/utils_llvm.h
deleted file mode 100644
index a606b91..0000000
--- a/compiler/llvm/utils_llvm.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2011 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_COMPILER_LLVM_UTILS_LLVM_H_
-#define ART_COMPILER_LLVM_UTILS_LLVM_H_
-
-#include <llvm/Analysis/Verifier.h>
-
-namespace art {
-
-#ifndef NDEBUG
-#define VERIFY_LLVM_FUNCTION(func) ::llvm::verifyFunction(func, ::llvm::AbortProcessAction)
-#else
-#define VERIFY_LLVM_FUNCTION(func)
-#endif
-
-}  // namespace art
-
-#endif  // ART_COMPILER_LLVM_UTILS_LLVM_H_
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 9fe98e3..3ca0cdf 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -48,40 +48,23 @@
     if (compiled_method == nullptr) {
       EXPECT_TRUE(oat_method.GetQuickCode() == nullptr) << PrettyMethod(method) << " "
                                                         << oat_method.GetQuickCode();
-      EXPECT_TRUE(oat_method.GetPortableCode() == nullptr) << PrettyMethod(method) << " "
-                                                           << oat_method.GetPortableCode();
       EXPECT_EQ(oat_method.GetFrameSizeInBytes(), 0U);
       EXPECT_EQ(oat_method.GetCoreSpillMask(), 0U);
       EXPECT_EQ(oat_method.GetFpSpillMask(), 0U);
     } else {
       const void* quick_oat_code = oat_method.GetQuickCode();
-      if (quick_oat_code != nullptr) {
-        EXPECT_EQ(oat_method.GetFrameSizeInBytes(), compiled_method->GetFrameSizeInBytes());
-        EXPECT_EQ(oat_method.GetCoreSpillMask(), compiled_method->GetCoreSpillMask());
-        EXPECT_EQ(oat_method.GetFpSpillMask(), compiled_method->GetFpSpillMask());
-        uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(quick_oat_code), 2);
-        quick_oat_code = reinterpret_cast<const void*>(oat_code_aligned);
-        const std::vector<uint8_t>* quick_code = compiled_method->GetQuickCode();
-        EXPECT_TRUE(quick_code != nullptr);
-        size_t code_size = quick_code->size() * sizeof(quick_code[0]);
-        EXPECT_EQ(0, memcmp(quick_oat_code, &quick_code[0], code_size))
-            << PrettyMethod(method) << " " << code_size;
-        CHECK_EQ(0, memcmp(quick_oat_code, &quick_code[0], code_size));
-      } else {
-        const void* portable_oat_code = oat_method.GetPortableCode();
-        EXPECT_TRUE(portable_oat_code != nullptr) << PrettyMethod(method);
-        EXPECT_EQ(oat_method.GetFrameSizeInBytes(), 0U);
-        EXPECT_EQ(oat_method.GetCoreSpillMask(), 0U);
-        EXPECT_EQ(oat_method.GetFpSpillMask(), 0U);
-        uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(portable_oat_code), 2);
-        portable_oat_code = reinterpret_cast<const void*>(oat_code_aligned);
-        const std::vector<uint8_t>* portable_code = compiled_method->GetPortableCode();
-        EXPECT_TRUE(portable_code != nullptr);
-        size_t code_size = portable_code->size() * sizeof(portable_code[0]);
-        EXPECT_EQ(0, memcmp(quick_oat_code, &portable_code[0], code_size))
-            << PrettyMethod(method) << " " << code_size;
-        CHECK_EQ(0, memcmp(quick_oat_code, &portable_code[0], code_size));
-      }
+      EXPECT_TRUE(quick_oat_code != nullptr) << PrettyMethod(method);
+      EXPECT_EQ(oat_method.GetFrameSizeInBytes(), compiled_method->GetFrameSizeInBytes());
+      EXPECT_EQ(oat_method.GetCoreSpillMask(), compiled_method->GetCoreSpillMask());
+      EXPECT_EQ(oat_method.GetFpSpillMask(), compiled_method->GetFpSpillMask());
+      uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(quick_oat_code), 2);
+      quick_oat_code = reinterpret_cast<const void*>(oat_code_aligned);
+      const std::vector<uint8_t>* quick_code = compiled_method->GetQuickCode();
+      EXPECT_TRUE(quick_code != nullptr);
+      size_t code_size = quick_code->size() * sizeof(quick_code[0]);
+      EXPECT_EQ(0, memcmp(quick_oat_code, &quick_code[0], code_size))
+          << PrettyMethod(method) << " " << code_size;
+      CHECK_EQ(0, memcmp(quick_oat_code, &quick_code[0], code_size));
     }
   }
 };
@@ -91,9 +74,7 @@
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 
   // TODO: make selectable.
-  Compiler::Kind compiler_kind = kUsePortableCompiler
-      ? Compiler::kPortable
-      : Compiler::kQuick;
+  Compiler::Kind compiler_kind = Compiler::kQuick;
   InstructionSet insn_set = kIsTargetBuild ? kThumb2 : kX86;
 
   std::string error_msg;
@@ -189,7 +170,7 @@
 TEST_F(OatTest, OatHeaderSizeCheck) {
   // If this test is failing and you have to update these constants,
   // it is time to update OatHeader::kOatVersion
-  EXPECT_EQ(84U, sizeof(OatHeader));
+  EXPECT_EQ(72U, sizeof(OatHeader));
   EXPECT_EQ(4U, sizeof(OatMethodOffsets));
   EXPECT_EQ(28U, sizeof(OatQuickMethodHeader));
   EXPECT_EQ(91 * GetInstructionSetPointerSize(kRuntimeISA), sizeof(QuickEntryPoints));
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 6bb526c..7d14de1 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -417,9 +417,6 @@
     size_interpreter_to_interpreter_bridge_(0),
     size_interpreter_to_compiled_code_bridge_(0),
     size_jni_dlsym_lookup_(0),
-    size_portable_imt_conflict_trampoline_(0),
-    size_portable_resolution_trampoline_(0),
-    size_portable_to_interpreter_bridge_(0),
     size_quick_generic_jni_trampoline_(0),
     size_quick_imt_conflict_trampoline_(0),
     size_quick_resolution_trampoline_(0),
@@ -722,110 +719,101 @@
       // Derived from CompiledMethod.
       uint32_t quick_code_offset = 0;
 
-      const std::vector<uint8_t>* portable_code = compiled_method->GetPortableCode();
       const std::vector<uint8_t>* quick_code = compiled_method->GetQuickCode();
-      if (portable_code != nullptr) {
-        CHECK(quick_code == nullptr);
-        size_t oat_method_offsets_offset =
-            oat_class->GetOatMethodOffsetsOffsetFromOatHeader(class_def_method_index);
-        compiled_method->AddOatdataOffsetToCompliledCodeOffset(
-            oat_method_offsets_offset + OFFSETOF_MEMBER(OatMethodOffsets, code_offset_));
+      CHECK(quick_code != nullptr);
+      offset_ = writer_->relative_call_patcher_->ReserveSpace(offset_, compiled_method);
+      offset_ = compiled_method->AlignCode(offset_);
+      DCHECK_ALIGNED_PARAM(offset_,
+                           GetInstructionSetAlignment(compiled_method->GetInstructionSet()));
+      uint32_t code_size = quick_code->size() * sizeof(uint8_t);
+      CHECK_NE(code_size, 0U);
+      uint32_t thumb_offset = compiled_method->CodeDelta();
+      quick_code_offset = offset_ + sizeof(OatQuickMethodHeader) + thumb_offset;
+
+      bool deduped = false;
+
+      // Deduplicate code arrays.
+      auto lb = dedupe_map_.lower_bound(compiled_method);
+      if (lb != dedupe_map_.end() && !dedupe_map_.key_comp()(compiled_method, lb->first)) {
+        quick_code_offset = lb->second;
+        deduped = true;
       } else {
-        CHECK(quick_code != nullptr);
-        offset_ = writer_->relative_call_patcher_->ReserveSpace(offset_, compiled_method);
-        offset_ = compiled_method->AlignCode(offset_);
-        DCHECK_ALIGNED_PARAM(offset_,
-                             GetInstructionSetAlignment(compiled_method->GetInstructionSet()));
-        uint32_t code_size = quick_code->size() * sizeof(uint8_t);
-        CHECK_NE(code_size, 0U);
-        uint32_t thumb_offset = compiled_method->CodeDelta();
-        quick_code_offset = offset_ + sizeof(OatQuickMethodHeader) + thumb_offset;
+        dedupe_map_.PutBefore(lb, compiled_method, quick_code_offset);
+      }
 
-        bool deduped = false;
+      MethodReference method_ref(dex_file_, it.GetMemberIndex());
+      auto method_lb = writer_->method_offset_map_.lower_bound(method_ref);
+      if (method_lb != writer_->method_offset_map_.end() &&
+          !writer_->method_offset_map_.key_comp()(method_ref, method_lb->first)) {
+        // TODO: Should this be a hard failure?
+        LOG(WARNING) << "Multiple definitions of "
+            << PrettyMethod(method_ref.dex_method_index, *method_ref.dex_file)
+            << ((method_lb->second != quick_code_offset) ? "; OFFSET MISMATCH" : "");
+      } else {
+        writer_->method_offset_map_.PutBefore(method_lb, method_ref, quick_code_offset);
+      }
 
-        // Deduplicate code arrays.
-        auto lb = dedupe_map_.lower_bound(compiled_method);
-        if (lb != dedupe_map_.end() && !dedupe_map_.key_comp()(compiled_method, lb->first)) {
-          quick_code_offset = lb->second;
-          deduped = true;
-        } else {
-          dedupe_map_.PutBefore(lb, compiled_method, quick_code_offset);
-        }
+      // Update quick method header.
+      DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size());
+      OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_];
+      uint32_t mapping_table_offset = method_header->mapping_table_offset_;
+      uint32_t vmap_table_offset = method_header->vmap_table_offset_;
+      uint32_t gc_map_offset = method_header->gc_map_offset_;
+      // The code offset was 0 when the mapping/vmap table offset was set, so it's set
+      // to 0-offset and we need to adjust it by code_offset.
+      uint32_t code_offset = quick_code_offset - thumb_offset;
+      if (mapping_table_offset != 0u) {
+        mapping_table_offset += code_offset;
+        DCHECK_LT(mapping_table_offset, code_offset);
+      }
+      if (vmap_table_offset != 0u) {
+        vmap_table_offset += code_offset;
+        DCHECK_LT(vmap_table_offset, code_offset);
+      }
+      if (gc_map_offset != 0u) {
+        gc_map_offset += code_offset;
+        DCHECK_LT(gc_map_offset, code_offset);
+      }
+      uint32_t frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
+      uint32_t core_spill_mask = compiled_method->GetCoreSpillMask();
+      uint32_t fp_spill_mask = compiled_method->GetFpSpillMask();
+      *method_header = OatQuickMethodHeader(mapping_table_offset, vmap_table_offset,
+                                            gc_map_offset, frame_size_in_bytes, core_spill_mask,
+                                            fp_spill_mask, code_size);
 
-        MethodReference method_ref(dex_file_, it.GetMemberIndex());
-        auto method_lb = writer_->method_offset_map_.lower_bound(method_ref);
-        if (method_lb != writer_->method_offset_map_.end() &&
-            !writer_->method_offset_map_.key_comp()(method_ref, method_lb->first)) {
-          // TODO: Should this be a hard failure?
-          LOG(WARNING) << "Multiple definitions of "
-              << PrettyMethod(method_ref.dex_method_index, *method_ref.dex_file)
-              << ((method_lb->second != quick_code_offset) ? "; OFFSET MISMATCH" : "");
-        } else {
-          writer_->method_offset_map_.PutBefore(method_lb, method_ref, quick_code_offset);
-        }
-
-        // Update quick method header.
-        DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size());
-        OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_];
-        uint32_t mapping_table_offset = method_header->mapping_table_offset_;
-        uint32_t vmap_table_offset = method_header->vmap_table_offset_;
-        uint32_t gc_map_offset = method_header->gc_map_offset_;
-        // The code offset was 0 when the mapping/vmap table offset was set, so it's set
-        // to 0-offset and we need to adjust it by code_offset.
-        uint32_t code_offset = quick_code_offset - thumb_offset;
-        if (mapping_table_offset != 0u) {
-          mapping_table_offset += code_offset;
-          DCHECK_LT(mapping_table_offset, code_offset);
-        }
-        if (vmap_table_offset != 0u) {
-          vmap_table_offset += code_offset;
-          DCHECK_LT(vmap_table_offset, code_offset);
-        }
-        if (gc_map_offset != 0u) {
-          gc_map_offset += code_offset;
-          DCHECK_LT(gc_map_offset, code_offset);
-        }
-        uint32_t frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
-        uint32_t core_spill_mask = compiled_method->GetCoreSpillMask();
-        uint32_t fp_spill_mask = compiled_method->GetFpSpillMask();
-        *method_header = OatQuickMethodHeader(mapping_table_offset, vmap_table_offset,
-                                              gc_map_offset, frame_size_in_bytes, core_spill_mask,
-                                              fp_spill_mask, code_size);
-
-        if (!deduped) {
-          // Update offsets. (Checksum is updated when writing.)
-          offset_ += sizeof(*method_header);  // Method header is prepended before code.
-          offset_ += code_size;
-          // Record absolute patch locations.
-          if (!compiled_method->GetPatches().empty()) {
-            uintptr_t base_loc = offset_ - code_size - writer_->oat_header_->GetExecutableOffset();
-            for (const LinkerPatch& patch : compiled_method->GetPatches()) {
-              if (patch.Type() != kLinkerPatchCallRelative) {
-                writer_->absolute_patch_locations_.push_back(base_loc + patch.LiteralOffset());
-              }
+      if (!deduped) {
+        // Update offsets. (Checksum is updated when writing.)
+        offset_ += sizeof(*method_header);  // Method header is prepended before code.
+        offset_ += code_size;
+        // Record absolute patch locations.
+        if (!compiled_method->GetPatches().empty()) {
+          uintptr_t base_loc = offset_ - code_size - writer_->oat_header_->GetExecutableOffset();
+          for (const LinkerPatch& patch : compiled_method->GetPatches()) {
+            if (patch.Type() != kLinkerPatchCallRelative) {
+              writer_->absolute_patch_locations_.push_back(base_loc + patch.LiteralOffset());
             }
           }
         }
+      }
 
-        if (writer_->compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
-          // Record debug information for this function if we are doing that.
+      if (writer_->compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
+        // Record debug information for this function if we are doing that.
 
-          std::string name = PrettyMethod(it.GetMemberIndex(), *dex_file_, true);
-          if (deduped) {
-            // TODO We should place the DEDUPED tag on the first instance of a deduplicated symbol
-            // so that it will show up in a debuggerd crash report.
-            name += " [ DEDUPED ]";
-          }
-
-          const uint32_t quick_code_start = quick_code_offset -
-              writer_->oat_header_->GetExecutableOffset();
-          const DexFile::CodeItem *code_item = it.GetMethodCodeItem();
-          writer_->method_info_.push_back(DebugInfo(name,
-                dex_file_->GetSourceFile(dex_file_->GetClassDef(class_def_index_)),
-                quick_code_start, quick_code_start + code_size,
-                code_item == nullptr ? nullptr : dex_file_->GetDebugInfoStream(code_item),
-                compiled_method));
+        std::string name = PrettyMethod(it.GetMemberIndex(), *dex_file_, true);
+        if (deduped) {
+          // TODO We should place the DEDUPED tag on the first instance of a deduplicated symbol
+          // so that it will show up in a debuggerd crash report.
+          name += " [ DEDUPED ]";
         }
+
+        const uint32_t quick_code_start = quick_code_offset -
+            writer_->oat_header_->GetExecutableOffset();
+        const DexFile::CodeItem *code_item = it.GetMethodCodeItem();
+        writer_->method_info_.push_back(DebugInfo(name,
+              dex_file_->GetSourceFile(dex_file_->GetClassDef(class_def_index_)),
+              quick_code_start, quick_code_start + code_size,
+              code_item == nullptr ? nullptr : dex_file_->GetDebugInfoStream(code_item),
+              compiled_method));
       }
 
       if (kIsDebugBuild) {
@@ -944,7 +932,6 @@
       std::string dump = exc->Dump();
       LOG(FATAL) << dump;
     }
-    // Portable code offsets are set by ElfWriterMclinker::FixupCompiledCodeOffset after linking.
     method->SetQuickOatCodeOffset(offsets.code_offset_);
 
     return true;
@@ -1005,7 +992,6 @@
 
       const std::vector<uint8_t>* quick_code = compiled_method->GetQuickCode();
       if (quick_code != nullptr) {
-        CHECK(compiled_method->GetPortableCode() == nullptr);
         offset_ = writer_->relative_call_patcher_->WriteThunks(out, offset_);
         if (offset_ == 0u) {
           ReportWriteFailure("relative call thunk", it);
@@ -1357,9 +1343,6 @@
     DO_TRAMPOLINE(interpreter_to_interpreter_bridge_, InterpreterToInterpreterBridge);
     DO_TRAMPOLINE(interpreter_to_compiled_code_bridge_, InterpreterToCompiledCodeBridge);
     DO_TRAMPOLINE(jni_dlsym_lookup_, JniDlsymLookup);
-    DO_TRAMPOLINE(portable_imt_conflict_trampoline_, PortableImtConflictTrampoline);
-    DO_TRAMPOLINE(portable_resolution_trampoline_, PortableResolutionTrampoline);
-    DO_TRAMPOLINE(portable_to_interpreter_bridge_, PortableToInterpreterBridge);
     DO_TRAMPOLINE(quick_generic_jni_trampoline_, QuickGenericJniTrampoline);
     DO_TRAMPOLINE(quick_imt_conflict_trampoline_, QuickImtConflictTrampoline);
     DO_TRAMPOLINE(quick_resolution_trampoline_, QuickResolutionTrampoline);
@@ -1370,9 +1353,6 @@
     oat_header_->SetInterpreterToInterpreterBridgeOffset(0);
     oat_header_->SetInterpreterToCompiledCodeBridgeOffset(0);
     oat_header_->SetJniDlsymLookupOffset(0);
-    oat_header_->SetPortableImtConflictTrampolineOffset(0);
-    oat_header_->SetPortableResolutionTrampolineOffset(0);
-    oat_header_->SetPortableToInterpreterBridgeOffset(0);
     oat_header_->SetQuickGenericJniTrampolineOffset(0);
     oat_header_->SetQuickImtConflictTrampolineOffset(0);
     oat_header_->SetQuickResolutionTrampolineOffset(0);
@@ -1467,9 +1447,6 @@
     DO_STAT(size_interpreter_to_interpreter_bridge_);
     DO_STAT(size_interpreter_to_compiled_code_bridge_);
     DO_STAT(size_jni_dlsym_lookup_);
-    DO_STAT(size_portable_imt_conflict_trampoline_);
-    DO_STAT(size_portable_resolution_trampoline_);
-    DO_STAT(size_portable_to_interpreter_bridge_);
     DO_STAT(size_quick_generic_jni_trampoline_);
     DO_STAT(size_quick_imt_conflict_trampoline_);
     DO_STAT(size_quick_resolution_trampoline_);
@@ -1612,9 +1589,6 @@
     DO_TRAMPOLINE(interpreter_to_interpreter_bridge_);
     DO_TRAMPOLINE(interpreter_to_compiled_code_bridge_);
     DO_TRAMPOLINE(jni_dlsym_lookup_);
-    DO_TRAMPOLINE(portable_imt_conflict_trampoline_);
-    DO_TRAMPOLINE(portable_resolution_trampoline_);
-    DO_TRAMPOLINE(portable_to_interpreter_bridge_);
     DO_TRAMPOLINE(quick_generic_jni_trampoline_);
     DO_TRAMPOLINE(quick_imt_conflict_trampoline_);
     DO_TRAMPOLINE(quick_resolution_trampoline_);
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index ea0dc66..e020d31 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -214,10 +214,7 @@
     }
 
     // Offset of start of OatClass from beginning of OatHeader. It is
-    // used to validate file position when writing. For Portable, it
-    // is also used to calculate the position of the OatMethodOffsets
-    // so that code pointers within the OatMethodOffsets can be
-    // patched to point to code in the Portable .o ELF objects.
+    // used to validate file position when writing.
     size_t offset_;
 
     // CompiledMethods for each class_def_method_index, or NULL if no method is available.
@@ -285,9 +282,6 @@
   std::unique_ptr<const std::vector<uint8_t>> interpreter_to_interpreter_bridge_;
   std::unique_ptr<const std::vector<uint8_t>> interpreter_to_compiled_code_bridge_;
   std::unique_ptr<const std::vector<uint8_t>> jni_dlsym_lookup_;
-  std::unique_ptr<const std::vector<uint8_t>> portable_imt_conflict_trampoline_;
-  std::unique_ptr<const std::vector<uint8_t>> portable_resolution_trampoline_;
-  std::unique_ptr<const std::vector<uint8_t>> portable_to_interpreter_bridge_;
   std::unique_ptr<const std::vector<uint8_t>> quick_generic_jni_trampoline_;
   std::unique_ptr<const std::vector<uint8_t>> quick_imt_conflict_trampoline_;
   std::unique_ptr<const std::vector<uint8_t>> quick_resolution_trampoline_;
@@ -302,9 +296,6 @@
   uint32_t size_interpreter_to_interpreter_bridge_;
   uint32_t size_interpreter_to_compiled_code_bridge_;
   uint32_t size_jni_dlsym_lookup_;
-  uint32_t size_portable_imt_conflict_trampoline_;
-  uint32_t size_portable_resolution_trampoline_;
-  uint32_t size_portable_to_interpreter_bridge_;
   uint32_t size_quick_generic_jni_trampoline_;
   uint32_t size_quick_imt_conflict_trampoline_;
   uint32_t size_quick_resolution_trampoline_;
diff --git a/compiler/sea_ir/code_gen/code_gen.cc b/compiler/sea_ir/code_gen/code_gen.cc
deleted file mode 100644
index 8d79c41..0000000
--- a/compiler/sea_ir/code_gen/code_gen.cc
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2013 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 <llvm/Support/raw_ostream.h>
-
-#include "base/logging.h"
-#include "utils.h"
-
-#include "sea_ir/ir/sea.h"
-#include "sea_ir/code_gen/code_gen.h"
-#include "sea_ir/types/type_inference.h"
-#include "sea_ir/types/types.h"
-
-namespace sea_ir {
-
-void CodeGenPrepassVisitor::Visit(PhiInstructionNode* phi) {
-  Region* r = phi->GetRegion();
-  const std::vector<Region*>* predecessors = r->GetPredecessors();
-  DCHECK(NULL != predecessors);
-  DCHECK_GT(predecessors->size(), 0u);
-  llvm::PHINode *llvm_phi  = llvm_data_->builder_.CreatePHI(
-      llvm::Type::getInt32Ty(*llvm_data_->context_), predecessors->size(), phi->StringId());
-  llvm_data_->AddValue(phi, llvm_phi);
-}
-
-void CodeGenPassVisitor::Initialize(SeaGraph* graph) {
-  Region* root_region;
-  ordered_regions_.clear();
-  for (std::vector<Region*>::const_iterator cit = graph->GetRegions()->begin();
-        cit != graph->GetRegions()->end(); cit++ ) {
-    if ((*cit)->GetIDominator() == (*cit)) {
-      root_region = *cit;
-    }
-  }
-  ordered_regions_.push_back(root_region);
-  for (unsigned int id = 0; id < ordered_regions_.size(); id++) {
-    Region* current_region = ordered_regions_.at(id);
-    const std::set<Region*>* dominated_regions = current_region->GetIDominatedSet();
-    for (std::set<Region*>::const_iterator cit = dominated_regions->begin();
-            cit != dominated_regions->end(); cit++ ) {
-      ordered_regions_.push_back(*cit);
-    }
-  }
-}
-
-void CodeGenPostpassVisitor::Visit(SeaGraph* graph) { }
-void CodeGenVisitor::Visit(SeaGraph* graph) { }
-void CodeGenPrepassVisitor::Visit(SeaGraph* graph) {
-  std::vector<SignatureNode*>* parameters = graph->GetParameterNodes();
-  // TODO: It may be better to extract correct types from dex
-  //       instead than from type inference.
-  DCHECK(parameters != NULL);
-  std::vector<llvm::Type*> parameter_types;
-  for (std::vector<SignatureNode*>::const_iterator param_iterator = parameters->begin();
-      param_iterator!= parameters->end(); param_iterator++) {
-    const Type* param_type = graph->ti_->type_data_.FindTypeOf((*param_iterator)->Id());
-    DCHECK(param_type->Equals(graph->ti_->type_cache_->Integer()))
-      << "Code generation for types other than integer not implemented.";
-    parameter_types.push_back(llvm::Type::getInt32Ty(*llvm_data_->context_));
-  }
-
-  // TODO: Get correct function return type.
-  const Type* return_type = graph->ti_->type_data_.FindTypeOf(-1);
-  DCHECK(return_type->Equals(graph->ti_->type_cache_->Integer()))
-    << "Code generation for types other than integer not implemented.";
-  llvm::FunctionType *function_type = llvm::FunctionType::get(
-      llvm::Type::getInt32Ty(*llvm_data_->context_),
-      parameter_types, false);
-
-  llvm_data_->function_ = llvm::Function::Create(function_type,
-      llvm::Function::ExternalLinkage, function_name_, &llvm_data_->module_);
-  unsigned param_id = 0;
-  for (llvm::Function::arg_iterator arg_it = llvm_data_->function_->arg_begin();
-      param_id != llvm_data_->function_->arg_size(); ++arg_it, ++param_id) {
-    // TODO: The "+1" is because of the Method parameter on position 0.
-    DCHECK(parameters->size() > param_id) << "Insufficient parameters for function signature";
-    // Build parameter register name for LLVM IR clarity.
-    std::string arg_name = art::StringPrintf("r%d", parameters->at(param_id)->GetResultRegister());
-    arg_it->setName(arg_name);
-    SignatureNode* parameter = parameters->at(param_id);
-    llvm_data_->AddValue(parameter, arg_it);
-  }
-
-  std::vector<Region*>* regions = &ordered_regions_;
-  DCHECK_GT(regions->size(), 0u);
-  // Then create all other basic blocks.
-  for (std::vector<Region*>::const_iterator cit = regions->begin(); cit != regions->end(); cit++) {
-    llvm::BasicBlock* new_basic_block = llvm::BasicBlock::Create(*llvm_data_->context_,
-        (*cit)->StringId(), llvm_data_->function_);
-    llvm_data_->AddBlock((*cit), new_basic_block);
-  }
-}
-
-void CodeGenPrepassVisitor::Visit(Region* region) {
-  llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
-}
-void CodeGenPostpassVisitor::Visit(Region* region) {
-  llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
-}
-void CodeGenVisitor::Visit(Region* region) {
-  llvm_data_->builder_.SetInsertPoint(llvm_data_->GetBlock(region));
-}
-
-
-void CodeGenVisitor::Visit(InstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  DCHECK(0);  // This whole function is useful only during development.
-}
-
-void CodeGenVisitor::Visit(UnnamedConstInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "1.Instruction: " << instr << std::endl;
-  llvm_data_->AddValue(instruction,
-      llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, instruction->GetConstValue())));
-}
-
-void CodeGenVisitor::Visit(ConstInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "1.Instruction: " << instr << std::endl;
-  llvm_data_->AddValue(instruction,
-      llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, instruction->GetConstValue())));
-}
-void CodeGenVisitor::Visit(ReturnInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "2.Instruction: " << instr << std::endl;
-  DCHECK_GT(instruction->GetSSAProducers().size(), 0u);
-  llvm::Value* return_value = llvm_data_->GetValue(instruction->GetSSAProducers().at(0));
-  llvm_data_->builder_.CreateRet(return_value);
-}
-void CodeGenVisitor::Visit(IfNeInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "3.Instruction: " << instr << std::endl;
-  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
-  DCHECK_GT(ssa_uses.size(), 1u);
-  InstructionNode* use_l = ssa_uses.at(0);
-  llvm::Value* left = llvm_data_->GetValue(use_l);
-
-  InstructionNode* use_r = ssa_uses.at(1);
-  llvm::Value* right = llvm_data_->GetValue(use_r);
-  llvm::Value* ifne = llvm_data_->builder_.CreateICmpNE(left, right, instruction->StringId());
-  DCHECK(instruction->GetRegion() != NULL);
-  std::vector<Region*>* successors = instruction->GetRegion()->GetSuccessors();
-  DCHECK_GT(successors->size(), 0u);
-  llvm::BasicBlock* then_block = llvm_data_->GetBlock(successors->at(0));
-  llvm::BasicBlock* else_block = llvm_data_->GetBlock(successors->at(1));
-
-  llvm_data_->builder_.CreateCondBr(ifne, then_block, else_block);
-}
-
-/*
-void CodeGenVisitor::Visit(AddIntLitInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "4.Instruction: " << instr << std::endl;
-  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAUses();
-  InstructionNode* use_l = ssa_uses.at(0);
-  llvm::Value* left = llvm_data->GetValue(use_l);
-  llvm::Value* right = llvm::ConstantInt::get(*llvm_data->context_,
-      llvm::APInt(32, instruction->GetConstValue()));
-  llvm::Value* result = llvm_data->builder_.CreateAdd(left, right);
-  llvm_data->AddValue(instruction, result);
-}
-*/
-void CodeGenVisitor::Visit(MoveResultInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "5.Instruction: " << instr << std::endl;
-  // TODO: Currently, this "mov" instruction is simulated by "res = return_register + 0".
-  // This is inefficient, but should be optimized out by the coalescing phase of the reg alloc.
-  // The TODO is to either ensure that this happens, or to
-  // remove the move-result instructions completely from the IR
-  // by merging them with the invoke-* instructions,
-  // since their purpose of minimizing the number of opcodes in dex is
-  // not relevant for the IR. (Will need to have different
-  // instruction subclasses for functions and procedures.)
-  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
-  InstructionNode* use_l = ssa_uses.at(0);
-  llvm::Value* left = llvm_data_->GetValue(use_l);
-  llvm::Value* right = llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, 0));
-  llvm::Value* result = llvm_data_->builder_.CreateAdd(left, right);
-  llvm_data_->AddValue(instruction, result);
-}
-void CodeGenVisitor::Visit(InvokeStaticInstructionNode* invoke) {
-  std::string instr = invoke->GetInstruction()->DumpString(NULL);
-  std::cout << "6.Instruction: " << instr << std::endl;
-  // TODO: Build callee LLVM function name.
-  std::string symbol = "dex_";
-  symbol += art::MangleForJni(PrettyMethod(invoke->GetCalledMethodIndex(), dex_file_));
-  std::string function_name = "dex_int_00020Main_fibonacci_00028int_00029";
-  llvm::Function *callee = llvm_data_->module_.getFunction(function_name);
-  // TODO: Add proper checking of the matching between formal and actual signature.
-  DCHECK(NULL != callee);
-  std::vector<llvm::Value*> parameter_values;
-  std::vector<InstructionNode*> parameter_sources = invoke->GetSSAProducers();
-  // TODO: Replace first parameter with Method argument instead of 0.
-  parameter_values.push_back(llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt(32, 0)));
-  for (std::vector<InstructionNode*>::const_iterator cit = parameter_sources.begin();
-      cit != parameter_sources.end(); ++cit) {
-    llvm::Value* parameter_value = llvm_data_->GetValue((*cit));
-    DCHECK(NULL != parameter_value);
-    parameter_values.push_back(parameter_value);
-  }
-  llvm::Value* return_value = llvm_data_->builder_.CreateCall(callee,
-      parameter_values, invoke->StringId());
-  llvm_data_->AddValue(invoke, return_value);
-}
-void CodeGenVisitor::Visit(AddIntInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "7.Instruction: " << instr << std::endl;
-  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
-  DCHECK_GT(ssa_uses.size(), 1u);
-  InstructionNode* use_l = ssa_uses.at(0);
-  InstructionNode* use_r = ssa_uses.at(1);
-  llvm::Value* left = llvm_data_->GetValue(use_l);
-  llvm::Value* right = llvm_data_->GetValue(use_r);
-  llvm::Value* result = llvm_data_->builder_.CreateAdd(left, right);
-  llvm_data_->AddValue(instruction, result);
-}
-void CodeGenVisitor::Visit(GotoInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "8.Instruction: " << instr << std::endl;
-  std::vector<sea_ir::Region*>* targets = instruction->GetRegion()->GetSuccessors();
-  DCHECK_EQ(targets->size(), 1u);
-  llvm::BasicBlock* target_block = llvm_data_->GetBlock(targets->at(0));
-  llvm_data_->builder_.CreateBr(target_block);
-}
-void CodeGenVisitor::Visit(IfEqzInstructionNode* instruction) {
-  std::string instr = instruction->GetInstruction()->DumpString(NULL);
-  std::cout << "9. Instruction: " << instr << "; Id: " <<instruction << std::endl;
-  std::vector<InstructionNode*> ssa_uses = instruction->GetSSAProducers();
-  DCHECK_GT(ssa_uses.size(), 0u);
-  InstructionNode* use_l = ssa_uses.at(0);
-  llvm::Value* left = llvm_data_->GetValue(use_l);
-  llvm::Value* ifeqz = llvm_data_->builder_.CreateICmpEQ(left,
-      llvm::ConstantInt::get(*llvm_data_->context_, llvm::APInt::getNullValue(32)),
-      instruction->StringId());
-  DCHECK(instruction->GetRegion() != NULL);
-  std::vector<Region*>* successors = instruction->GetRegion()->GetSuccessors();
-  DCHECK_GT(successors->size(), 0u);
-  llvm::BasicBlock* then_block = llvm_data_->GetBlock(successors->at(0));
-  llvm::BasicBlock* else_block = llvm_data_->GetBlock(successors->at(1));
-  llvm_data_->builder_.CreateCondBr(ifeqz, then_block, else_block);
-}
-
-void CodeGenPostpassVisitor::Visit(PhiInstructionNode* phi) {
-  std::cout << "10. Instruction: Phi(" << phi->GetRegisterNumber() << ")" << std::endl;
-  Region* r = phi->GetRegion();
-  const std::vector<Region*>* predecessors = r->GetPredecessors();
-  DCHECK(NULL != predecessors);
-  DCHECK_GT(predecessors->size(), 0u);
-  // Prepass (CodeGenPrepassVisitor) should create the phi function value.
-  llvm::PHINode* llvm_phi = (llvm::PHINode*) llvm_data_->GetValue(phi);
-  int predecessor_pos = 0;
-  for (std::vector<Region*>::const_iterator cit = predecessors->begin();
-      cit != predecessors->end(); ++cit) {
-    std::vector<InstructionNode*>* defining_instructions = phi->GetSSAUses(predecessor_pos++);
-    DCHECK_EQ(defining_instructions->size(), 1u);
-    InstructionNode* defining_instruction = defining_instructions->at(0);
-    DCHECK(NULL != defining_instruction);
-    Region* incoming_region = *cit;
-    llvm::BasicBlock* incoming_basic_block = llvm_data_->GetBlock(incoming_region);
-    llvm::Value* incoming_value = llvm_data_->GetValue(defining_instruction);
-    llvm_phi->addIncoming(incoming_value, incoming_basic_block);
-  }
-}
-
-void CodeGenVisitor::Visit(SignatureNode* signature) {
-  DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
-      "Signature nodes must correspond to a single parameter register.";
-}
-void CodeGenPrepassVisitor::Visit(SignatureNode* signature) {
-  DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
-      "Signature nodes must correspond to a single parameter register.";
-}
-void CodeGenPostpassVisitor::Visit(SignatureNode* signature) {
-  DCHECK_EQ(signature->GetDefinitions().size(), 1u) <<
-      "Signature nodes must correspond to a single parameter register.";
-}
-
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/code_gen/code_gen.h b/compiler/sea_ir/code_gen/code_gen.h
deleted file mode 100644
index 544e9f0..0000000
--- a/compiler/sea_ir/code_gen/code_gen.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_
-#define ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_
-
-#include "instruction_set.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Analysis/Verifier.h"
-#include "sea_ir/ir/visitor.h"
-
-namespace sea_ir {
-// Abstracts away the containers we use to map SEA IR objects to LLVM IR objects.
-class CodeGenData {
- public:
-  explicit CodeGenData(): context_(&llvm::getGlobalContext()), module_("sea_ir", *context_),
-      builder_(*context_), function_(), blocks_(), values_() { }
-  // Returns the llvm::BasicBlock* corresponding to the sea_ir::Region with id @region_id.
-  llvm::BasicBlock* GetBlock(int region_id) {
-    std::map<int, llvm::BasicBlock*>::iterator block_it = blocks_.find(region_id);
-    DCHECK(block_it != blocks_.end());
-    return block_it->second;
-  }
-  // Returns the llvm::BasicBlock* corresponding top the sea_ir::Region @region.
-  llvm::BasicBlock* GetBlock(Region* region) {
-    return GetBlock(region->Id());
-  }
-  // Records @block as corresponding to the sea_ir::Region with id @region_id.
-  void AddBlock(int region_id, llvm::BasicBlock* block) {
-    blocks_.insert(std::pair<int, llvm::BasicBlock*>(region_id, block));
-  }
-  // Records @block as corresponding to the sea_ir::Region with @region.
-  void AddBlock(Region* region, llvm::BasicBlock* block) {
-    AddBlock(region->Id(), block);
-  }
-
-  llvm::Value* GetValue(int instruction_id) {
-    std::map<int, llvm::Value*>::iterator value_it = values_.find(instruction_id);
-    DCHECK(value_it != values_.end());
-    return value_it->second;
-  }
-  // Returns the llvm::Value* corresponding to the output of @instruction.
-  llvm::Value* GetValue(InstructionNode* instruction) {
-    return GetValue(instruction->Id());
-  }
-  // Records @value as corresponding to the sea_ir::InstructionNode with id @instruction_id.
-  void AddValue(int instruction_id, llvm::Value* value) {
-    values_.insert(std::pair<int, llvm::Value*>(instruction_id, value));
-  }
-  // Records @value as corresponding to the sea_ir::InstructionNode  @instruction.
-  void AddValue(InstructionNode* instruction, llvm::Value* value) {
-      AddValue(instruction->Id(), value);
-  }
-  // Generates and returns in @elf the executable code corresponding to the llvm module
-  //
-  std::string GetElf(art::InstructionSet instruction_set);
-
-  llvm::LLVMContext* const context_;
-  llvm::Module module_;
-  llvm::IRBuilder<> builder_;
-  llvm::Function* function_;
-
- private:
-  std::map<int, llvm::BasicBlock*> blocks_;
-  std::map<int, llvm::Value*> values_;
-};
-
-class CodeGenPassVisitor: public IRVisitor {
- public:
-  explicit CodeGenPassVisitor(CodeGenData* cgd): llvm_data_(cgd) { }
-  CodeGenPassVisitor(): llvm_data_(new CodeGenData()) { }
-  // Initialize any data structure needed before the start of visiting.
-  virtual void Initialize(SeaGraph* graph);
-  CodeGenData* GetData() {
-    return llvm_data_;
-  }
-  void Write(std::string file) {
-      llvm_data_->module_.dump();
-      llvm::verifyFunction(*llvm_data_->function_);
-    }
-
- protected:
-  CodeGenData* const llvm_data_;
-};
-
-class CodeGenPrepassVisitor: public CodeGenPassVisitor {
- public:
-  explicit CodeGenPrepassVisitor(const std::string& function_name):
-    function_name_(function_name) { }
-  void Visit(SeaGraph* graph);
-  void Visit(SignatureNode* region);
-  void Visit(Region* region);
-  void Visit(InstructionNode* instruction) { }
-
-  void Visit(UnnamedConstInstructionNode* instruction) { }
-  void Visit(ConstInstructionNode* instruction) { }
-  void Visit(ReturnInstructionNode* instruction) { }
-  void Visit(IfNeInstructionNode* instruction) { }
-  // void Visit(AddIntLitInstructionNode* instruction) { }
-  void Visit(MoveResultInstructionNode* instruction) { }
-  void Visit(InvokeStaticInstructionNode* instruction) { }
-  void Visit(AddIntInstructionNode* instruction) { }
-  void Visit(GotoInstructionNode* instruction) { }
-  void Visit(IfEqzInstructionNode* instruction) { }
-  void Visit(PhiInstructionNode* region);
-
- private:
-  std::string function_name_;
-};
-
-class CodeGenPostpassVisitor: public CodeGenPassVisitor {
- public:
-  explicit CodeGenPostpassVisitor(CodeGenData* code_gen_data): CodeGenPassVisitor(code_gen_data) { }
-  void Visit(SeaGraph* graph);
-  void Visit(SignatureNode* region);
-  void Visit(Region* region);
-  void Visit(InstructionNode* region) { }
-  void Visit(UnnamedConstInstructionNode* instruction) { }
-  void Visit(ConstInstructionNode* instruction) { }
-  void Visit(ReturnInstructionNode* instruction) { }
-  void Visit(IfNeInstructionNode* instruction) { }
-  // void Visit(AddIntLitInstructionNode* instruction) { }
-  void Visit(MoveResultInstructionNode* instruction) { }
-  void Visit(InvokeStaticInstructionNode* instruction) { }
-  void Visit(AddIntInstructionNode* instruction) { }
-  void Visit(GotoInstructionNode* instruction) { }
-  void Visit(IfEqzInstructionNode* instruction) { }
-  void Visit(PhiInstructionNode* region);
-};
-
-class CodeGenVisitor: public CodeGenPassVisitor {
- public:
-  explicit CodeGenVisitor(CodeGenData* code_gen_data,
-      const art::DexFile& dex_file): CodeGenPassVisitor(code_gen_data), dex_file_(dex_file) { }
-  void Visit(SeaGraph* graph);
-  void Visit(SignatureNode* region);
-  void Visit(Region* region);
-  void Visit(InstructionNode* region);
-  void Visit(UnnamedConstInstructionNode* instruction);
-  void Visit(ConstInstructionNode* instruction);
-  void Visit(ReturnInstructionNode* instruction);
-  void Visit(IfNeInstructionNode* instruction);
-  void Visit(MoveResultInstructionNode* instruction);
-  void Visit(InvokeStaticInstructionNode* instruction);
-  void Visit(AddIntInstructionNode* instruction);
-  void Visit(GotoInstructionNode* instruction);
-  void Visit(IfEqzInstructionNode* instruction);
-  void Visit(PhiInstructionNode* region) { }
-
- private:
-  std::string function_name_;
-  const art::DexFile& dex_file_;
-};
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_CODE_GEN_CODE_GEN_H_
diff --git a/compiler/sea_ir/code_gen/code_gen_data.cc b/compiler/sea_ir/code_gen/code_gen_data.cc
deleted file mode 100644
index 17f64db..0000000
--- a/compiler/sea_ir/code_gen/code_gen_data.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2013 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 <string>
-#include <llvm/PassManager.h>
-#include <llvm/Support/TargetRegistry.h>
-#include <llvm/Support/FormattedStream.h>
-#include <llvm/Target/TargetMachine.h>
-#include <llvm/Transforms/IPO.h>
-#include <llvm/Transforms/IPO/PassManagerBuilder.h>
-
-#include "base/logging.h"
-#include "driver/compiler_driver.h"
-#include "sea_ir/ir/sea.h"
-#include "sea_ir/code_gen/code_gen.h"
-
-
-namespace sea_ir {
-std::string CodeGenData::GetElf(art::InstructionSet instruction_set) {
-  std::string elf;
-  ::llvm::raw_string_ostream out_stream(elf);
-  // Lookup the LLVM target
-  std::string target_triple;
-  std::string target_cpu;
-  std::string target_attr;
-  art::CompilerDriver::InstructionSetToLLVMTarget(instruction_set,
-      target_triple, target_cpu, target_attr);
-
-  std::string errmsg;
-  const ::llvm::Target* target =
-    ::llvm::TargetRegistry::lookupTarget(target_triple, errmsg);
-
-  CHECK(target != NULL) << errmsg;
-
-  // Target options
-  ::llvm::TargetOptions target_options;
-  target_options.FloatABIType = ::llvm::FloatABI::Soft;
-  target_options.NoFramePointerElim = true;
-  target_options.NoFramePointerElimNonLeaf = true;
-  target_options.UseSoftFloat = false;
-  target_options.EnableFastISel = false;
-
-  // Create the ::llvm::TargetMachine
-  ::llvm::OwningPtr< ::llvm::TargetMachine> target_machine(
-    target->createTargetMachine(target_triple, target_cpu, target_attr, target_options,
-                                ::llvm::Reloc::Static, ::llvm::CodeModel::Small,
-                                ::llvm::CodeGenOpt::Aggressive));
-
-  CHECK(target_machine.get() != NULL) << "Failed to create target machine";
-
-  // Add target data
-  const ::llvm::DataLayout* data_layout = target_machine->getDataLayout();
-
-  // PassManager for code generation passes
-  ::llvm::PassManager pm;
-  pm.add(new ::llvm::DataLayout(*data_layout));
-
-  // FunctionPassManager for optimization pass
-  ::llvm::FunctionPassManager fpm(&module_);
-  fpm.add(new ::llvm::DataLayout(*data_layout));
-
-  // Add optimization pass
-  ::llvm::PassManagerBuilder pm_builder;
-  // TODO: Use inliner after we can do IPO.
-  pm_builder.Inliner = NULL;
-  // pm_builder.Inliner = ::llvm::createFunctionInliningPass();
-  // pm_builder.Inliner = ::llvm::createAlwaysInlinerPass();
-  // pm_builder.Inliner = ::llvm::createPartialInliningPass();
-  pm_builder.OptLevel = 3;
-  pm_builder.DisableSimplifyLibCalls = 1;
-  pm_builder.DisableUnitAtATime = 1;
-  pm_builder.populateFunctionPassManager(fpm);
-  pm_builder.populateModulePassManager(pm);
-  pm.add(::llvm::createStripDeadPrototypesPass());
-  // Add passes to emit ELF image
-  {
-    ::llvm::formatted_raw_ostream formatted_os(out_stream, false);
-    // Ask the target to add backend passes as necessary.
-    if (target_machine->addPassesToEmitFile(pm,
-                                            formatted_os,
-                                            ::llvm::TargetMachine::CGFT_ObjectFile,
-                                            true)) {
-      LOG(FATAL) << "Unable to generate ELF for this target";
-    }
-
-    // Run the code generation passes
-    pm.run(module_);
-  }
-  return elf;
-}
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/debug/dot_gen.cc b/compiler/sea_ir/debug/dot_gen.cc
deleted file mode 100644
index 9442684..0000000
--- a/compiler/sea_ir/debug/dot_gen.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2013 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 "scoped_thread_state_change.h"
-#include "sea_ir/debug/dot_gen.h"
-
-namespace sea_ir {
-
-void DotGenerationVisitor::Initialize(SeaGraph* graph) {
-  graph_ = graph;
-  Region* root_region;
-  ordered_regions_.clear();
-  for (std::vector<Region*>::const_iterator cit = graph->GetRegions()->begin();
-      cit != graph->GetRegions()->end(); cit++ ) {
-    if ((*cit)->GetIDominator() == (*cit)) {
-      root_region = *cit;
-    }
-  }
-  ordered_regions_.push_back(root_region);
-  for (unsigned int id = 0; id < ordered_regions_.size(); id++) {
-    Region* current_region = ordered_regions_.at(id);
-    const std::set<Region*>* dominated_regions = current_region->GetIDominatedSet();
-    for (std::set<Region*>::const_iterator cit = dominated_regions->begin();
-        cit != dominated_regions->end(); cit++ ) {
-      ordered_regions_.push_back(*cit);
-    }
-  }
-}
-
-void DotGenerationVisitor::ToDotSSAEdges(InstructionNode* instruction) {
-  std::map<int, InstructionNode*>* definition_edges = instruction->GetSSAProducersMap();
-  // SSA definitions:
-  for (std::map<int, InstructionNode*>::const_iterator
-      def_it = definition_edges->begin();
-      def_it != definition_edges->end(); def_it++) {
-    if (NULL != def_it->second) {
-      dot_text_ += def_it->second->StringId() + " -> ";
-      dot_text_ += instruction->StringId() + "[color=gray,label=\"";
-      dot_text_ += art::StringPrintf("vR = %d", def_it->first);
-      art::SafeMap<int, const Type*>::const_iterator type_it = types_->find(def_it->second->Id());
-      if (type_it != types_->end()) {
-        art::ScopedObjectAccess soa(art::Thread::Current());
-        dot_text_ += "(" + type_it->second->Dump() + ")";
-      } else {
-        dot_text_ += "()";
-      }
-      dot_text_ += "\"] ; // SSA edge\n";
-    }
-  }
-
-  // SSA used-by:
-  if (options_->WillSaveUseEdges()) {
-    std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers();
-    for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin();
-        cit != used_in->end(); cit++) {
-      dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\"";
-      dot_text_ += "\"] ; // SSA used-by edge\n";
-    }
-  }
-}
-
-void DotGenerationVisitor::ToDotSSAEdges(PhiInstructionNode* instruction) {
-  std::vector<InstructionNode*> definition_edges = instruction->GetSSAProducers();
-  // SSA definitions:
-  for (std::vector<InstructionNode*>::const_iterator
-      def_it = definition_edges.begin();
-      def_it != definition_edges.end(); def_it++) {
-    if (NULL != *def_it) {
-      dot_text_ += (*def_it)->StringId() + " -> ";
-      dot_text_ += instruction->StringId() + "[color=gray,label=\"";
-      dot_text_ += art::StringPrintf("vR = %d", instruction->GetRegisterNumber());
-      art::SafeMap<int, const Type*>::const_iterator type_it = types_->find((*def_it)->Id());
-      if (type_it != types_->end()) {
-        art::ScopedObjectAccess soa(art::Thread::Current());
-        dot_text_ += "(" + type_it->second->Dump() + ")";
-      } else {
-        dot_text_ += "()";
-      }
-      dot_text_ += "\"] ; // SSA edge\n";
-    }
-  }
-
-  // SSA used-by:
-  if (options_->WillSaveUseEdges()) {
-    std::vector<InstructionNode*>* used_in = instruction->GetSSAConsumers();
-    for (std::vector<InstructionNode*>::const_iterator cit = used_in->begin();
-        cit != used_in->end(); cit++) {
-      dot_text_ += (*cit)->StringId() + " -> " + instruction->StringId() + "[color=gray,label=\"";
-      dot_text_ += "\"] ; // SSA used-by edge\n";
-    }
-  }
-}
-
-void DotGenerationVisitor::Visit(SignatureNode* parameter) {
-  dot_text_ += parameter->StringId() +" [label=\"[" + parameter->StringId() + "] signature:";
-  dot_text_ += art::StringPrintf("r%d", parameter->GetResultRegister());
-  dot_text_ += "\"] // signature node\n";
-  ToDotSSAEdges(parameter);
-}
-
-// Appends to @result a dot language formatted string representing the node and
-//    (by convention) outgoing edges, so that the composition of theToDot() of all nodes
-//    builds a complete dot graph (without prolog and epilog though).
-void DotGenerationVisitor::Visit(Region* region) {
-  dot_text_ += "\n// Region: \nsubgraph " + region->StringId();
-  dot_text_ += " { label=\"region " + region->StringId() + "(rpo=";
-  dot_text_ += art::StringPrintf("%d", region->GetRPO());
-  if (NULL != region->GetIDominator()) {
-    dot_text_ += " dom=" + region->GetIDominator()->StringId();
-  }
-  dot_text_ += ")\";\n";
-
-  std::vector<PhiInstructionNode*>* phi_instructions = region->GetPhiNodes();
-  for (std::vector<PhiInstructionNode*>::const_iterator cit = phi_instructions->begin();
-        cit != phi_instructions->end(); cit++) {
-    dot_text_ += (*cit)->StringId() +";\n";
-  }
-  std::vector<InstructionNode*>* instructions = region->GetInstructions();
-  for (std::vector<InstructionNode*>::const_iterator cit = instructions->begin();
-        cit != instructions->end(); cit++) {
-      dot_text_ += (*cit)->StringId() +";\n";
-    }
-
-  dot_text_ += "} // End Region.\n";
-  std::vector<Region*>* successors =  region->GetSuccessors();
-  for (std::vector<Region*>::const_iterator cit = successors->begin(); cit != successors->end();
-      cit++) {
-    DCHECK(NULL != *cit) << "Null successor found for SeaNode" <<
-        region->GetLastChild()->StringId() << ".";
-    dot_text_ += region->GetLastChild()->StringId() + " -> " +
-        (*cit)->GetLastChild()->StringId() +
-        "[lhead=" + (*cit)->StringId() + ", " + "ltail=" + region->StringId() + "];\n\n";
-  }
-}
-void DotGenerationVisitor::Visit(InstructionNode* instruction) {
-  dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() +
-      " [label=\"[" + instruction->StringId() + "] " +
-      instruction->GetInstruction()->DumpString(graph_->GetDexFile()) + "\"";
-  dot_text_ += "];\n";
-  ToDotSSAEdges(instruction);
-}
-
-void DotGenerationVisitor::Visit(UnnamedConstInstructionNode* instruction) {
-  dot_text_ += "// Instruction ("+instruction->StringId()+"): \n" + instruction->StringId() +
-        " [label=\"[" + instruction->StringId() + "] const/x v-3, #" +
-        art::StringPrintf("%d", instruction->GetConstValue()) + "\"";
-  dot_text_ += "];\n";
-  ToDotSSAEdges(instruction);
-}
-
-void DotGenerationVisitor::Visit(PhiInstructionNode* phi) {
-  dot_text_ += "// PhiInstruction: \n" + phi->StringId() +
-      " [label=\"[" + phi->StringId() + "] PHI(";
-  dot_text_ += art::StringPrintf("%d", phi->GetRegisterNumber());
-  dot_text_ += ")\"";
-  dot_text_ += "];\n";
-  ToDotSSAEdges(phi);
-}
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h
deleted file mode 100644
index a5d6819..0000000
--- a/compiler/sea_ir/debug/dot_gen.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_DEBUG_DOT_GEN_H_
-#define ART_COMPILER_SEA_IR_DEBUG_DOT_GEN_H_
-
-#include "safe_map.h"
-#include "base/stringprintf.h"
-#include "file_output_stream.h"
-#include "os.h"
-#include "sea_ir/ir/sea.h"
-#include "sea_ir/types/type_inference.h"
-
-namespace sea_ir {
-
-class DotConversionOptions {
- public:
-  DotConversionOptions(): save_use_edges_(false) { }
-  bool WillSaveUseEdges() const {
-    return save_use_edges_;
-  }
- private:
-  bool save_use_edges_;
-};
-
-class DotGenerationVisitor: public IRVisitor {
- public:
-  explicit DotGenerationVisitor(const DotConversionOptions* const options,
-      art::SafeMap<int, const Type*>* types): graph_(), types_(types), options_(options) { }
-
-  virtual void Initialize(SeaGraph* graph);
-  // Saves the ssa def->use edges corresponding to @instruction.
-  void ToDotSSAEdges(InstructionNode* instruction);
-  void ToDotSSAEdges(PhiInstructionNode* instruction);
-  void Visit(SeaGraph* graph) {
-    dot_text_ += "digraph seaOfNodes {\ncompound=true\n";
-  }
-  void Visit(SignatureNode* parameter);
-
-  // Appends to @result a dot language formatted string representing the node and
-  //    (by convention) outgoing edges, so that the composition of theToDot() of all nodes
-  //    builds a complete dot graph (without prolog and epilog though).
-  void Visit(Region* region);
-  void Visit(InstructionNode* instruction);
-  void Visit(PhiInstructionNode* phi);
-  void Visit(UnnamedConstInstructionNode* instruction);
-
-  void Visit(ConstInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(ReturnInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(IfNeInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(MoveResultInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(InvokeStaticInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(AddIntInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(GotoInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-  void Visit(IfEqzInstructionNode* instruction) {
-    Visit(reinterpret_cast<InstructionNode*>(instruction));
-  }
-
-  std::string GetResult() const {
-    return dot_text_;
-  }
-
- private:
-  std::string dot_text_;
-  SeaGraph* graph_;
-  art::SafeMap<int, const Type*>* types_;
-  const DotConversionOptions* const options_;
-};
-
-// Stores options for turning a SEA IR graph to a .dot file.
-class DotConversion {
- public:
-  DotConversion(): options_() { }
-  // Saves to @filename the .dot representation of @graph with the options @options.
-  void DumpSea(SeaGraph* graph, std::string filename,
-      art::SafeMap<int, const Type*>* types) const {
-    LOG(INFO) << "Starting to write SEA string to file " << filename << std::endl;
-    DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types);
-    graph->Accept(&dgv);
-    // TODO: std::unique_ptr to close file properly. Switch to BufferedOutputStream.
-    art::File* file = art::OS::CreateEmptyFile(filename.c_str());
-    art::FileOutputStream fos(file);
-    std::string graph_as_string = dgv.GetResult();
-    graph_as_string += "}";
-    fos.WriteFully(graph_as_string.c_str(), graph_as_string.size());
-    LOG(INFO) << "Written SEA string to file.";
-  }
-
- private:
-  DotConversionOptions options_;
-};
-
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_DEBUG_DOT_GEN_H_
diff --git a/compiler/sea_ir/frontend.cc b/compiler/sea_ir/frontend.cc
deleted file mode 100644
index b57007b..0000000
--- a/compiler/sea_ir/frontend.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifdef ART_SEA_IR_MODE
-#include <llvm/Support/Threading.h>
-#include <llvm/Support/raw_ostream.h>
-#include <llvm/Bitcode/ReaderWriter.h>
-
-#include "base/logging.h"
-#include "llvm/llvm_compilation_unit.h"
-#include "dex/portable/mir_to_gbc.h"
-#include "driver/compiler_driver.h"
-#include "verifier/method_verifier.h"
-#include "mirror/object.h"
-#include "utils.h"
-
-#include "runtime.h"
-#include "safe_map.h"
-
-#include "sea_ir/ir/sea.h"
-#include "sea_ir/debug/dot_gen.h"
-#include "sea_ir/types/types.h"
-#include "sea_ir/code_gen/code_gen.h"
-
-namespace art {
-
-static CompiledMethod* CompileMethodWithSeaIr(CompilerDriver& compiler,
-                                     CompilerBackend* compiler_backend,
-                                     const DexFile::CodeItem* code_item,
-                                     uint32_t method_access_flags, InvokeType invoke_type,
-                                     uint16_t class_def_idx, uint32_t method_idx,
-                                     jobject class_loader, const DexFile& dex_file,
-                                     void* llvm_compilation_unit) {
-  LOG(INFO) << "Compiling " << PrettyMethod(method_idx, dex_file) << ".";
-  sea_ir::SeaGraph* ir_graph = sea_ir::SeaGraph::GetGraph(dex_file);
-  std::string symbol = "dex_" + MangleForJni(PrettyMethod(method_idx, dex_file));
-  sea_ir::CodeGenData* llvm_data = ir_graph->CompileMethod(symbol,
-          code_item, class_def_idx, method_idx, method_access_flags, dex_file);
-  sea_ir::DotConversion dc;
-  SafeMap<int, const sea_ir::Type*>*  types = ir_graph->ti_->GetTypeMap();
-  dc.DumpSea(ir_graph, "/tmp/temp.dot", types);
-  MethodReference mref(&dex_file, method_idx);
-  std::string llvm_code = llvm_data->GetElf(compiler.GetInstructionSet());
-  CompiledMethod* compiled_method =
-      new CompiledMethod(compiler, compiler.GetInstructionSet(), llvm_code,
-                         *compiler.GetVerifiedMethodsData()->GetDexGcMap(mref), symbol);
-  LOG(INFO) << "Compiled SEA IR method " << PrettyMethod(method_idx, dex_file) << ".";
-  return compiled_method;
-}
-
-CompiledMethod* SeaIrCompileOneMethod(CompilerDriver& compiler,
-                                 CompilerBackend* backend,
-                                 const DexFile::CodeItem* code_item,
-                                 uint32_t method_access_flags,
-                                 InvokeType invoke_type,
-                                 uint16_t class_def_idx,
-                                 uint32_t method_idx,
-                                 jobject class_loader,
-                                 const DexFile& dex_file,
-                                 void* llvm_compilation_unit) {
-  return CompileMethodWithSeaIr(compiler, backend, code_item, method_access_flags, invoke_type,
-      class_def_idx, method_idx, class_loader, dex_file, llvm_compilation_unit);
-}
-
-extern "C" art::CompiledMethod*
-    SeaIrCompileMethod(art::CompilerDriver& compiler,
-                          const art::DexFile::CodeItem* code_item,
-                          uint32_t method_access_flags, art::InvokeType invoke_type,
-                          uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
-                          const art::DexFile& dex_file) {
-  // TODO: Check method fingerprint here to determine appropriate backend type.
-  //       Until then, use build default
-  art::CompilerBackend* backend = compiler.GetCompilerBackend();
-  return art::SeaIrCompileOneMethod(compiler, backend, code_item, method_access_flags, invoke_type,
-                               class_def_idx, method_idx, class_loader, dex_file,
-                               NULL /* use thread llvm_info */);
-}
-#endif
-
-}  // namespace art
diff --git a/compiler/sea_ir/ir/instruction_nodes.h b/compiler/sea_ir/ir/instruction_nodes.h
deleted file mode 100644
index 63e89e7..0000000
--- a/compiler/sea_ir/ir/instruction_nodes.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_IR_INSTRUCTION_NODES_H_
-#define ART_COMPILER_SEA_IR_IR_INSTRUCTION_NODES_H_
-#include "dex_instruction-inl.h"
-#include "sea_ir/ir/sea_node.h"
-#include "sea_ir/ir/visitor.h"
-
-
-namespace sea_ir {
-
-enum SpecialRegisters {
-  NO_REGISTER = -1,             // Usually signifies that there is no register
-                                // that respects the condition you asked for.
-  RETURN_REGISTER = -2,         // Written by the invoke* instructions, read by move-results.
-  UNNAMED_CONST_REGISTER = -3   // Written by UnnamedConst* instructions, read by *Lit* instruction.
-};
-
-class IRVisitor;
-
-// This class represents an instruction in SEA IR.
-// As we add support for specific classes of instructions,
-// the number of InstructionNode objects should dwindle, while the
-// number of subclasses and instances of subclasses will go up.
-class InstructionNode: public SeaNode {
- public:
-  static std::vector<sea_ir::InstructionNode*> Create(const art::Instruction* in);
-  // Returns the Dalvik instruction around which this InstructionNode is wrapped.
-  const art::Instruction* GetInstruction() const {
-    DCHECK(NULL != instruction_) << "Tried to access NULL instruction in an InstructionNode.";
-    return instruction_;
-  }
-  // Returns the register that is defined by the current instruction, or NO_REGISTER otherwise.
-  virtual int GetResultRegister() const;
-  // Returns the set of registers defined by the current instruction.
-  virtual std::vector<int> GetDefinitions() const;
-  // Returns the set of register numbers that are used by the instruction.
-  virtual std::vector<int> GetUses() const;
-  // Mark the current instruction as a downward exposed definition.
-  void MarkAsDEDef();
-  // Rename the use of @reg_no to refer to the instruction @definition,
-  // essentially creating SSA form.
-  void RenameToSSA(int reg_no, InstructionNode* definition) {
-    definition_edges_.insert(std::pair<int, InstructionNode*>(reg_no, definition));
-    DCHECK(NULL != definition) << "SSA definition for register " << reg_no
-        << " used in instruction " << Id() << " not found.";
-    definition->AddSSAUse(this);
-  }
-  // Returns the ordered set of Instructions that define the input operands of this instruction.
-  // Precondition: SeaGraph.ConvertToSSA().
-  virtual std::vector<InstructionNode*> GetSSAProducers() {
-    std::vector<int> uses = GetUses();
-    std::vector<InstructionNode*> ssa_uses;
-    for (std::vector<int>::const_iterator cit = uses.begin(); cit != uses.end(); cit++) {
-      ssa_uses.push_back((*definition_edges_.find(*cit)).second);
-    }
-    return ssa_uses;
-  }
-  std::map<int, InstructionNode* >* GetSSAProducersMap() {
-    return &definition_edges_;
-  }
-  std::vector<InstructionNode*>* GetSSAConsumers() {
-    return &used_in_;
-  }
-  virtual void AddSSAUse(InstructionNode* use) {
-    used_in_.push_back(use);
-  }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-  // Set the region to which this instruction belongs.
-  Region* GetRegion() {
-    DCHECK(NULL != region_);
-    return region_;
-  }
-  // Get the region to which this instruction belongs.
-  void SetRegion(Region* region) {
-    region_ = region;
-  }
-
- protected:
-  explicit InstructionNode(const art::Instruction* in):
-      SeaNode(), instruction_(in), used_in_(), de_def_(false), region_(NULL) { }
-
- protected:
-  const art::Instruction* const instruction_;
-  std::map<int, InstructionNode* > definition_edges_;  // Maps used registers to their definitions.
-  // Stores pointers to instructions that use the result of the current instruction.
-  std::vector<InstructionNode*> used_in_;
-  bool de_def_;
-  Region* region_;
-};
-
-class ConstInstructionNode: public InstructionNode {
- public:
-  explicit ConstInstructionNode(const art::Instruction* inst):
-      InstructionNode(inst) { }
-
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-
-  virtual int32_t GetConstValue() const {
-    return GetInstruction()->VRegB_11n();
-  }
-};
-
-class UnnamedConstInstructionNode: public ConstInstructionNode {
- public:
-  explicit UnnamedConstInstructionNode(const art::Instruction* inst, int32_t value):
-      ConstInstructionNode(inst), value_(value) { }
-
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-
-  int GetResultRegister() const {
-    return UNNAMED_CONST_REGISTER;
-  }
-
-  int32_t GetConstValue() const {
-    return value_;
-  }
-
- private:
-  const int32_t value_;
-};
-
-class ReturnInstructionNode: public InstructionNode {
- public:
-  explicit ReturnInstructionNode(const art::Instruction* inst): InstructionNode(inst) { }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-
-class IfNeInstructionNode: public InstructionNode {
- public:
-  explicit IfNeInstructionNode(const art::Instruction* inst): InstructionNode(inst) {
-    DCHECK(InstructionTools::IsDefinition(inst) == false);
-  }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-
-
-
-class MoveResultInstructionNode: public InstructionNode {
- public:
-  explicit MoveResultInstructionNode(const art::Instruction* inst): InstructionNode(inst) { }
-  std::vector<int> GetUses() const {
-    std::vector<int> uses;  // Using vector<> instead of set<> because order matters.
-    uses.push_back(RETURN_REGISTER);
-    return uses;
-  }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-
-class InvokeStaticInstructionNode: public InstructionNode {
- public:
-  explicit InvokeStaticInstructionNode(const art::Instruction* inst): InstructionNode(inst),
-    method_index_(inst->VRegB_35c()) { }
-  int GetResultRegister() const {
-    return RETURN_REGISTER;
-  }
-
-  int GetCalledMethodIndex() const {
-    return method_index_;
-  }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-
- private:
-  const uint32_t method_index_;
-};
-
-class AddIntInstructionNode: public InstructionNode {
- public:
-  explicit AddIntInstructionNode(const art::Instruction* inst): InstructionNode(inst) { }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-
-class AddIntLitInstructionNode: public AddIntInstructionNode {
- public:
-  explicit AddIntLitInstructionNode(const art::Instruction* inst):
-      AddIntInstructionNode(inst) { }
-
-  std::vector<int> GetUses() const {
-    std::vector<int> uses =  AddIntInstructionNode::GetUses();
-    uses.push_back(UNNAMED_CONST_REGISTER);
-    return uses;
-    }
-
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-
-class GotoInstructionNode: public InstructionNode {
- public:
-  explicit GotoInstructionNode(const art::Instruction* inst): InstructionNode(inst) { }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-
-class IfEqzInstructionNode: public InstructionNode {
- public:
-  explicit IfEqzInstructionNode(const art::Instruction* inst): InstructionNode(inst) {
-    DCHECK(InstructionTools::IsDefinition(inst) == false);
-  }
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-};
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_IR_INSTRUCTION_NODES_H_
diff --git a/compiler/sea_ir/ir/instruction_tools.cc b/compiler/sea_ir/ir/instruction_tools.cc
deleted file mode 100644
index 143209d..0000000
--- a/compiler/sea_ir/ir/instruction_tools.cc
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
- * Copyright (C) 2013 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 "sea_ir/ir/instruction_tools.h"
-
-namespace sea_ir {
-
-bool InstructionTools::IsDefinition(const art::Instruction* const instruction) {
-  if (0 != (InstructionTools::instruction_attributes_[instruction->Opcode()] & (1 << kDA))) {
-    return true;
-  }
-  return false;
-}
-
-const int InstructionTools::instruction_attributes_[] = {
-  // 00 NOP
-  DF_NOP,
-
-  // 01 MOVE vA, vB
-  DF_DA | DF_UB | DF_IS_MOVE,
-
-  // 02 MOVE_FROM16 vAA, vBBBB
-  DF_DA | DF_UB | DF_IS_MOVE,
-
-  // 03 MOVE_16 vAAAA, vBBBB
-  DF_DA | DF_UB | DF_IS_MOVE,
-
-  // 04 MOVE_WIDE vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_IS_MOVE,
-
-  // 05 MOVE_WIDE_FROM16 vAA, vBBBB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_IS_MOVE,
-
-  // 06 MOVE_WIDE_16 vAAAA, vBBBB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_IS_MOVE,
-
-  // 07 MOVE_OBJECT vA, vB
-  DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_REF_A | DF_REF_B,
-
-  // 08 MOVE_OBJECT_FROM16 vAA, vBBBB
-  DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_REF_A | DF_REF_B,
-
-  // 09 MOVE_OBJECT_16 vAAAA, vBBBB
-  DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_REF_A | DF_REF_B,
-
-  // 0A MOVE_RESULT vAA
-  DF_DA,
-
-  // 0B MOVE_RESULT_WIDE vAA
-  DF_DA | DF_A_WIDE,
-
-  // 0C MOVE_RESULT_OBJECT vAA
-  DF_DA | DF_REF_A,
-
-  // 0D MOVE_EXCEPTION vAA
-  DF_DA | DF_REF_A | DF_NON_NULL_DST,
-
-  // 0E RETURN_VOID
-  DF_NOP,
-
-  // 0F RETURN vAA
-  DF_UA,
-
-  // 10 RETURN_WIDE vAA
-  DF_UA | DF_A_WIDE,
-
-  // 11 RETURN_OBJECT vAA
-  DF_UA | DF_REF_A,
-
-  // 12 CONST_4 vA, #+B
-  DF_DA | DF_SETS_CONST,
-
-  // 13 CONST_16 vAA, #+BBBB
-  DF_DA | DF_SETS_CONST,
-
-  // 14 CONST vAA, #+BBBBBBBB
-  DF_DA | DF_SETS_CONST,
-
-  // 15 CONST_HIGH16 VAA, #+BBBB0000
-  DF_DA | DF_SETS_CONST,
-
-  // 16 CONST_WIDE_16 vAA, #+BBBB
-  DF_DA | DF_A_WIDE | DF_SETS_CONST,
-
-  // 17 CONST_WIDE_32 vAA, #+BBBBBBBB
-  DF_DA | DF_A_WIDE | DF_SETS_CONST,
-
-  // 18 CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
-  DF_DA | DF_A_WIDE | DF_SETS_CONST,
-
-  // 19 CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
-  DF_DA | DF_A_WIDE | DF_SETS_CONST,
-
-  // 1A CONST_STRING vAA, string@BBBB
-  DF_DA | DF_REF_A | DF_NON_NULL_DST,
-
-  // 1B CONST_STRING_JUMBO vAA, string@BBBBBBBB
-  DF_DA | DF_REF_A | DF_NON_NULL_DST,
-
-  // 1C CONST_CLASS vAA, type@BBBB
-  DF_DA | DF_REF_A | DF_NON_NULL_DST,
-
-  // 1D MONITOR_ENTER vAA
-  DF_UA | DF_NULL_CHK_0 | DF_REF_A,
-
-  // 1E MONITOR_EXIT vAA
-  DF_UA | DF_NULL_CHK_0 | DF_REF_A,
-
-  // 1F CHK_CAST vAA, type@BBBB
-  DF_UA | DF_REF_A | DF_UMS,
-
-  // 20 INSTANCE_OF vA, vB, type@CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_REF_B | DF_UMS,
-
-  // 21 ARRAY_LENGTH vA, vB
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_REF_B,
-
-  // 22 NEW_INSTANCE vAA, type@BBBB
-  DF_DA | DF_NON_NULL_DST | DF_REF_A | DF_UMS,
-
-  // 23 NEW_ARRAY vA, vB, type@CCCC
-  DF_DA | DF_UB | DF_NON_NULL_DST | DF_REF_A | DF_CORE_B | DF_UMS,
-
-  // 24 FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
-  DF_FORMAT_35C | DF_NON_NULL_RET | DF_UMS,
-
-  // 25 FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
-  DF_FORMAT_3RC | DF_NON_NULL_RET | DF_UMS,
-
-  // 26 FILL_ARRAY_DATA vAA, +BBBBBBBB
-  DF_UA | DF_REF_A | DF_UMS,
-
-  // 27 THROW vAA
-  DF_UA | DF_REF_A | DF_UMS,
-
-  // 28 GOTO
-  DF_NOP,
-
-  // 29 GOTO_16
-  DF_NOP,
-
-  // 2A GOTO_32
-  DF_NOP,
-
-  // 2B PACKED_SWITCH vAA, +BBBBBBBB
-  DF_UA,
-
-  // 2C SPARSE_SWITCH vAA, +BBBBBBBB
-  DF_UA,
-
-  // 2D CMPL_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
-
-  // 2E CMPG_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,
-
-  // 2F CMPL_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
-
-  // 30 CMPG_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,
-
-  // 31 CMP_LONG vAA, vBB, vCC
-  DF_DA | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 32 IF_EQ vA, vB, +CCCC
-  DF_UA | DF_UB,
-
-  // 33 IF_NE vA, vB, +CCCC
-  DF_UA | DF_UB,
-
-  // 34 IF_LT vA, vB, +CCCC
-  DF_UA | DF_UB,
-
-  // 35 IF_GE vA, vB, +CCCC
-  DF_UA | DF_UB,
-
-  // 36 IF_GT vA, vB, +CCCC
-  DF_UA | DF_UB,
-
-  // 37 IF_LE vA, vB, +CCCC
-  DF_UA | DF_UB,
-
-  // 38 IF_EQZ vAA, +BBBB
-  DF_UA,
-
-  // 39 IF_NEZ vAA, +BBBB
-  DF_UA,
-
-  // 3A IF_LTZ vAA, +BBBB
-  DF_UA,
-
-  // 3B IF_GEZ vAA, +BBBB
-  DF_UA,
-
-  // 3C IF_GTZ vAA, +BBBB
-  DF_UA,
-
-  // 3D IF_LEZ vAA, +BBBB
-  DF_UA,
-
-  // 3E UNUSED_3E
-  DF_NOP,
-
-  // 3F UNUSED_3F
-  DF_NOP,
-
-  // 40 UNUSED_40
-  DF_NOP,
-
-  // 41 UNUSED_41
-  DF_NOP,
-
-  // 42 UNUSED_42
-  DF_NOP,
-
-  // 43 UNUSED_43
-  DF_NOP,
-
-  // 44 AGET vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,
-
-  // 45 AGET_WIDE vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,
-
-  // 46 AGET_OBJECT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_A | DF_REF_B | DF_CORE_C,
-
-  // 47 AGET_BOOLEAN vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,
-
-  // 48 AGET_BYTE vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,
-
-  // 49 AGET_CHAR vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,
-
-  // 4A AGET_SHORT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,
-
-  // 4B APUT vAA, vBB, vCC
-  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,
-
-  // 4C APUT_WIDE vAA, vBB, vCC
-  DF_UA | DF_A_WIDE | DF_UB | DF_UC | DF_NULL_CHK_2 | DF_RANGE_CHK_3 | DF_REF_B | DF_CORE_C,
-
-  // 4D APUT_OBJECT vAA, vBB, vCC
-  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_A | DF_REF_B | DF_CORE_C,
-
-  // 4E APUT_BOOLEAN vAA, vBB, vCC
-  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,
-
-  // 4F APUT_BYTE vAA, vBB, vCC
-  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,
-
-  // 50 APUT_CHAR vAA, vBB, vCC
-  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,
-
-  // 51 APUT_SHORT vAA, vBB, vCC
-  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,
-
-  // 52 IGET vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // 53 IGET_WIDE vA, vB, field@CCCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // 54 IGET_OBJECT vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B,
-
-  // 55 IGET_BOOLEAN vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // 56 IGET_BYTE vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // 57 IGET_CHAR vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // 58 IGET_SHORT vA, vB, field@CCCC
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // 59 IPUT vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,
-
-  // 5A IPUT_WIDE vA, vB, field@CCCC
-  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B,
-
-  // 5B IPUT_OBJECT vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B,
-
-  // 5C IPUT_BOOLEAN vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,
-
-  // 5D IPUT_BYTE vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,
-
-  // 5E IPUT_CHAR vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,
-
-  // 5F IPUT_SHORT vA, vB, field@CCCC
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,
-
-  // 60 SGET vAA, field@BBBB
-  DF_DA | DF_UMS,
-
-  // 61 SGET_WIDE vAA, field@BBBB
-  DF_DA | DF_A_WIDE | DF_UMS,
-
-  // 62 SGET_OBJECT vAA, field@BBBB
-  DF_DA | DF_REF_A | DF_UMS,
-
-  // 63 SGET_BOOLEAN vAA, field@BBBB
-  DF_DA | DF_UMS,
-
-  // 64 SGET_BYTE vAA, field@BBBB
-  DF_DA | DF_UMS,
-
-  // 65 SGET_CHAR vAA, field@BBBB
-  DF_DA | DF_UMS,
-
-  // 66 SGET_SHORT vAA, field@BBBB
-  DF_DA | DF_UMS,
-
-  // 67 SPUT vAA, field@BBBB
-  DF_UA | DF_UMS,
-
-  // 68 SPUT_WIDE vAA, field@BBBB
-  DF_UA | DF_A_WIDE | DF_UMS,
-
-  // 69 SPUT_OBJECT vAA, field@BBBB
-  DF_UA | DF_REF_A | DF_UMS,
-
-  // 6A SPUT_BOOLEAN vAA, field@BBBB
-  DF_UA | DF_UMS,
-
-  // 6B SPUT_BYTE vAA, field@BBBB
-  DF_UA | DF_UMS,
-
-  // 6C SPUT_CHAR vAA, field@BBBB
-  DF_UA | DF_UMS,
-
-  // 6D SPUT_SHORT vAA, field@BBBB
-  DF_UA | DF_UMS,
-
-  // 6E INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
-  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 6F INVOKE_SUPER {vD, vE, vF, vG, vA}
-  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 70 INVOKE_DIRECT {vD, vE, vF, vG, vA}
-  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 71 INVOKE_STATIC {vD, vE, vF, vG, vA}
-  DF_FORMAT_35C | DF_UMS,
-
-  // 72 INVOKE_INTERFACE {vD, vE, vF, vG, vA}
-  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 73 UNUSED_73
-  DF_NOP,
-
-  // 74 INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
-  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 75 INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
-  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 76 INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
-  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 77 INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
-  DF_FORMAT_3RC | DF_UMS,
-
-  // 78 INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
-  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // 79 UNUSED_79
-  DF_NOP,
-
-  // 7A UNUSED_7A
-  DF_NOP,
-
-  // 7B NEG_INT vA, vB
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // 7C NOT_INT vA, vB
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // 7D NEG_LONG vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // 7E NOT_LONG vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // 7F NEG_FLOAT vA, vB
-  DF_DA | DF_UB | DF_FP_A | DF_FP_B,
-
-  // 80 NEG_DOUBLE vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // 81 INT_TO_LONG vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // 82 INT_TO_FLOAT vA, vB
-  DF_DA | DF_UB | DF_FP_A | DF_CORE_B,
-
-  // 83 INT_TO_DOUBLE vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_FP_A | DF_CORE_B,
-
-  // 84 LONG_TO_INT vA, vB
-  DF_DA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // 85 LONG_TO_FLOAT vA, vB
-  DF_DA | DF_UB | DF_B_WIDE | DF_FP_A | DF_CORE_B,
-
-  // 86 LONG_TO_DOUBLE vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_A | DF_CORE_B,
-
-  // 87 FLOAT_TO_INT vA, vB
-  DF_DA | DF_UB | DF_FP_B | DF_CORE_A,
-
-  // 88 FLOAT_TO_LONG vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_FP_B | DF_CORE_A,
-
-  // 89 FLOAT_TO_DOUBLE vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_FP_A | DF_FP_B,
-
-  // 8A DOUBLE_TO_INT vA, vB
-  DF_DA | DF_UB | DF_B_WIDE | DF_FP_B | DF_CORE_A,
-
-  // 8B DOUBLE_TO_LONG vA, vB
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_B | DF_CORE_A,
-
-  // 8C DOUBLE_TO_FLOAT vA, vB
-  DF_DA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // 8D INT_TO_BYTE vA, vB
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // 8E INT_TO_CHAR vA, vB
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // 8F INT_TO_SHORT vA, vB
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // 90 ADD_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 91 SUB_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 92 MUL_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 93 DIV_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 94 REM_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 95 AND_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 96 OR_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 97 XOR_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 98 SHL_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 99 SHR_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 9A USHR_INT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 9B ADD_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 9C SUB_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 9D MUL_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 9E DIV_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // 9F REM_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A0 AND_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A1 OR_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A2 XOR_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A3 SHL_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A4 SHR_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A5 USHR_LONG vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,
-
-  // A6 ADD_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // A7 SUB_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // A8 MUL_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // A9 DIV_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // AA REM_FLOAT vAA, vBB, vCC
-  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // AB ADD_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // AC SUB_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // AD MUL_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // AE DIV_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // AF REM_DOUBLE vAA, vBB, vCC
-  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
-
-  // B0 ADD_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B1 SUB_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B2 MUL_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B3 DIV_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B4 REM_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B5 AND_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B6 OR_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B7 XOR_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B8 SHL_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // B9 SHR_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // BA USHR_INT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // BB ADD_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // BC SUB_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // BD MUL_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // BE DIV_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // BF REM_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // C0 AND_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // C1 OR_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // C2 XOR_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,
-
-  // C3 SHL_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // C4 SHR_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // C5 USHR_LONG_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // C6 ADD_FLOAT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
-
-  // C7 SUB_FLOAT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
-
-  // C8 MUL_FLOAT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
-
-  // C9 DIV_FLOAT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
-
-  // CA REM_FLOAT_2ADDR vA, vB
-  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
-
-  // CB ADD_DOUBLE_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // CC SUB_DOUBLE_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // CD MUL_DOUBLE_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // CE DIV_DOUBLE_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // CF REM_DOUBLE_2ADDR vA, vB
-  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,
-
-  // D0 ADD_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D1 RSUB_INT vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D2 MUL_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D3 DIV_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D4 REM_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D5 AND_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D6 OR_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D7 XOR_INT_LIT16 vA, vB, #+CCCC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D8 ADD_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // D9 RSUB_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // DA MUL_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // DB DIV_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // DC REM_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // DD AND_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // DE OR_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // DF XOR_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // E0 SHL_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // E1 SHR_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // E2 USHR_INT_LIT8 vAA, vBB, #+CC
-  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,
-
-  // E3 IGET_VOLATILE
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // E4 IPUT_VOLATILE
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,
-
-  // E5 SGET_VOLATILE
-  DF_DA | DF_UMS,
-
-  // E6 SPUT_VOLATILE
-  DF_UA | DF_UMS,
-
-  // E7 IGET_OBJECT_VOLATILE
-  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B,
-
-  // E8 IGET_WIDE_VOLATILE
-  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B,
-
-  // E9 IPUT_WIDE_VOLATILE
-  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B,
-
-  // EA SGET_WIDE_VOLATILE
-  DF_DA | DF_A_WIDE | DF_UMS,
-
-  // EB SPUT_WIDE_VOLATILE
-  DF_UA | DF_A_WIDE | DF_UMS,
-
-  // EC BREAKPOINT
-  DF_NOP,
-
-  // ED THROW_VERIFICATION_ERROR
-  DF_NOP | DF_UMS,
-
-  // EE EXECUTE_INLINE
-  DF_FORMAT_35C,
-
-  // EF EXECUTE_INLINE_RANGE
-  DF_FORMAT_3RC,
-
-  // F0 INVOKE_OBJECT_INIT_RANGE
-  DF_NOP | DF_NULL_CHK_0,
-
-  // F1 RETURN_VOID_BARRIER
-  DF_NOP,
-
-  // F2 IGET_QUICK
-  DF_DA | DF_UB | DF_NULL_CHK_0,
-
-  // F3 IGET_WIDE_QUICK
-  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0,
-
-  // F4 IGET_OBJECT_QUICK
-  DF_DA | DF_UB | DF_NULL_CHK_0,
-
-  // F5 IPUT_QUICK
-  DF_UA | DF_UB | DF_NULL_CHK_1,
-
-  // F6 IPUT_WIDE_QUICK
-  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2,
-
-  // F7 IPUT_OBJECT_QUICK
-  DF_UA | DF_UB | DF_NULL_CHK_1,
-
-  // F8 INVOKE_VIRTUAL_QUICK
-  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // F9 INVOKE_VIRTUAL_QUICK_RANGE
-  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // FA INVOKE_SUPER_QUICK
-  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // FB INVOKE_SUPER_QUICK_RANGE
-  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,
-
-  // FC IPUT_OBJECT_VOLATILE
-  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B,
-
-  // FD SGET_OBJECT_VOLATILE
-  DF_DA | DF_REF_A | DF_UMS,
-
-  // FE SPUT_OBJECT_VOLATILE
-  DF_UA | DF_REF_A | DF_UMS,
-
-  // FF UNUSED_FF
-  DF_NOP
-};
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/ir/instruction_tools.h b/compiler/sea_ir/ir/instruction_tools.h
deleted file mode 100644
index 895e017..0000000
--- a/compiler/sea_ir/ir/instruction_tools.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2013 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 "sea.h"
-#include "dex_instruction.h"
-
-#ifndef ART_COMPILER_SEA_IR_IR_INSTRUCTION_TOOLS_H_
-#define ART_COMPILER_SEA_IR_IR_INSTRUCTION_TOOLS_H_
-
-
-// Note: This file has content cannibalized for SEA_IR from the MIR implementation,
-//       to avoid having a dependence on MIR.
-namespace sea_ir {
-
-#define DF_NOP                  0
-#define DF_UA                   (1 << kUA)
-#define DF_UB                   (1 << kUB)
-#define DF_UC                   (1 << kUC)
-#define DF_A_WIDE               (1 << kAWide)
-#define DF_B_WIDE               (1 << kBWide)
-#define DF_C_WIDE               (1 << kCWide)
-#define DF_DA                   (1 << kDA)
-#define DF_IS_MOVE              (1 << kIsMove)
-#define DF_SETS_CONST           (1 << kSetsConst)
-#define DF_FORMAT_35C           (1 << kFormat35c)
-#define DF_FORMAT_3RC           (1 << kFormat3rc)
-#define DF_NULL_CHK_0           (1 << kNullCheckSrc0)
-#define DF_NULL_CHK_1           (1 << kNullCheckSrc1)
-#define DF_NULL_CHK_2           (1 << kNullCheckSrc2)
-#define DF_NULL_CHK_OUT0        (1 << kNullCheckOut0)
-#define DF_NON_NULL_DST         (1 << kDstNonNull)
-#define DF_NON_NULL_RET         (1 << kRetNonNull)
-#define DF_NULL_TRANSFER_0      (1 << kNullTransferSrc0)
-#define DF_NULL_TRANSFER_N      (1 << kNullTransferSrcN)
-#define DF_RANGE_CHK_1          (1 << kRangeCheckSrc1)
-#define DF_RANGE_CHK_2          (1 << kRangeCheckSrc2)
-#define DF_RANGE_CHK_3          (1 << kRangeCheckSrc3)
-#define DF_FP_A                 (1 << kFPA)
-#define DF_FP_B                 (1 << kFPB)
-#define DF_FP_C                 (1 << kFPC)
-#define DF_CORE_A               (1 << kCoreA)
-#define DF_CORE_B               (1 << kCoreB)
-#define DF_CORE_C               (1 << kCoreC)
-#define DF_REF_A                (1 << kRefA)
-#define DF_REF_B                (1 << kRefB)
-#define DF_REF_C                (1 << kRefC)
-#define DF_UMS                  (1 << kUsesMethodStar)
-
-#define DF_HAS_USES             (DF_UA | DF_UB | DF_UC)
-
-#define DF_HAS_DEFS             (DF_DA)
-
-#define DF_HAS_NULL_CHKS        (DF_NULL_CHK_0 | \
-                                 DF_NULL_CHK_1 | \
-                                 DF_NULL_CHK_2 | \
-                                 DF_NULL_CHK_OUT0)
-
-#define DF_HAS_RANGE_CHKS       (DF_RANGE_CHK_1 | \
-                                 DF_RANGE_CHK_2 | \
-                                 DF_RANGE_CHK_3)
-
-#define DF_HAS_NR_CHKS          (DF_HAS_NULL_CHKS | \
-                                 DF_HAS_RANGE_CHKS)
-
-#define DF_A_IS_REG             (DF_UA | DF_DA)
-#define DF_B_IS_REG             (DF_UB)
-#define DF_C_IS_REG             (DF_UC)
-#define DF_IS_GETTER_OR_SETTER  (DF_IS_GETTER | DF_IS_SETTER)
-#define DF_USES_FP              (DF_FP_A | DF_FP_B | DF_FP_C)
-
-enum DataFlowAttributePos {
-  kUA = 0,
-  kUB,
-  kUC,
-  kAWide,
-  kBWide,
-  kCWide,
-  kDA,
-  kIsMove,
-  kSetsConst,
-  kFormat35c,
-  kFormat3rc,
-  kNullCheckSrc0,        // Null check of uses[0].
-  kNullCheckSrc1,        // Null check of uses[1].
-  kNullCheckSrc2,        // Null check of uses[2].
-  kNullCheckOut0,        // Null check out outgoing arg0.
-  kDstNonNull,           // May assume dst is non-null.
-  kRetNonNull,           // May assume retval is non-null.
-  kNullTransferSrc0,     // Object copy src[0] -> dst.
-  kNullTransferSrcN,     // Phi null check state transfer.
-  kRangeCheckSrc1,       // Range check of uses[1].
-  kRangeCheckSrc2,       // Range check of uses[2].
-  kRangeCheckSrc3,       // Range check of uses[3].
-  kFPA,
-  kFPB,
-  kFPC,
-  kCoreA,
-  kCoreB,
-  kCoreC,
-  kRefA,
-  kRefB,
-  kRefC,
-  kUsesMethodStar,       // Implicit use of Method*.
-};
-
-class InstructionTools {
- public:
-  static bool IsDefinition(const art::Instruction* instruction);
-  static const int instruction_attributes_[];
-};
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_IR_INSTRUCTION_TOOLS_H_
diff --git a/compiler/sea_ir/ir/regions_test.cc b/compiler/sea_ir/ir/regions_test.cc
deleted file mode 100644
index 95bd310..0000000
--- a/compiler/sea_ir/ir/regions_test.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 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 "common_compiler_test.h"
-#include "sea_ir/ir/sea.h"
-
-using utils::ScopedHashtable;
-
-namespace sea_ir {
-
-class RegionsTest : public art::CommonCompilerTest {};
-
-TEST_F(RegionsTest, Basics) {
-  sea_ir::SeaGraph sg(*java_lang_dex_file_);
-  sea_ir::Region* root = sg.GetNewRegion();
-  sea_ir::Region* then_region = sg.GetNewRegion();
-  sea_ir::Region* else_region = sg.GetNewRegion();
-  std::vector<sea_ir::Region*>* regions = sg.GetRegions();
-  // Test that regions have been registered correctly as children of the graph.
-  EXPECT_TRUE(std::find(regions->begin(), regions->end(), root) != regions->end());
-  EXPECT_TRUE(std::find(regions->begin(), regions->end(), then_region) != regions->end());
-  EXPECT_TRUE(std::find(regions->begin(), regions->end(), else_region) != regions->end());
-  // Check that an edge recorded correctly in both the head and the tail.
-  sg.AddEdge(root, then_region);
-  std::vector<sea_ir::Region*>* succs = root->GetSuccessors();
-  EXPECT_EQ(1U, succs->size());
-  EXPECT_EQ(then_region, succs->at(0));
-  std::vector<sea_ir::Region*>* preds = then_region->GetPredecessors();
-  EXPECT_EQ(1U, preds->size());
-  EXPECT_EQ(root, preds->at(0));
-  // Check that two edges are recorded properly for both head and tail.
-  sg.AddEdge(root, else_region);
-  succs = root->GetSuccessors();
-  EXPECT_EQ(2U, succs->size());
-  EXPECT_TRUE(std::find(succs->begin(), succs->end(), then_region) != succs->end());
-  EXPECT_TRUE(std::find(succs->begin(), succs->end(), else_region) != succs->end());
-  preds = then_region->GetPredecessors();
-  EXPECT_EQ(1U, preds->size());
-  EXPECT_EQ(root, preds->at(0));
-  preds = else_region->GetPredecessors();
-  EXPECT_EQ(1U, preds->size());
-  EXPECT_EQ(root, preds->at(0));
-}
-
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/ir/sea.cc b/compiler/sea_ir/ir/sea.cc
deleted file mode 100644
index 2b25f56..0000000
--- a/compiler/sea_ir/ir/sea.cc
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * Copyright (C) 2013 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 "base/stringprintf.h"
-#include "sea_ir/ir/instruction_tools.h"
-#include "sea_ir/ir/sea.h"
-#include "sea_ir/code_gen/code_gen.h"
-#include "sea_ir/types/type_inference.h"
-
-#define MAX_REACHING_DEF_ITERERATIONS (10)
-// TODO: When development is done, this define should not
-// be needed, it is currently used as a cutoff
-// for cases where the iterative fixed point algorithm
-// does not reach a fixed point because of a bug.
-
-namespace sea_ir {
-
-int SeaNode::current_max_node_id_ = 0;
-
-void IRVisitor::Traverse(Region* region) {
-  std::vector<PhiInstructionNode*>* phis = region->GetPhiNodes();
-  for (std::vector<PhiInstructionNode*>::const_iterator cit = phis->begin();
-      cit != phis->end(); cit++) {
-    (*cit)->Accept(this);
-  }
-  std::vector<InstructionNode*>* instructions = region->GetInstructions();
-  for (std::vector<InstructionNode*>::const_iterator cit = instructions->begin();
-      cit != instructions->end(); cit++) {
-    (*cit)->Accept(this);
-  }
-}
-
-void IRVisitor::Traverse(SeaGraph* graph) {
-  for (std::vector<Region*>::const_iterator cit = ordered_regions_.begin();
-          cit != ordered_regions_.end(); cit++ ) {
-    (*cit)->Accept(this);
-  }
-}
-
-SeaGraph* SeaGraph::GetGraph(const art::DexFile& dex_file) {
-  return new SeaGraph(dex_file);
-}
-
-void SeaGraph::AddEdge(Region* src, Region* dst) const {
-  src->AddSuccessor(dst);
-  dst->AddPredecessor(src);
-}
-
-void SeaGraph::ComputeRPO(Region* current_region, int& current_rpo) {
-  current_region->SetRPO(VISITING);
-  std::vector<sea_ir::Region*>* succs = current_region->GetSuccessors();
-  for (std::vector<sea_ir::Region*>::iterator succ_it = succs->begin();
-      succ_it != succs->end(); ++succ_it) {
-    if (NOT_VISITED == (*succ_it)->GetRPO()) {
-      SeaGraph::ComputeRPO(*succ_it, current_rpo);
-    }
-  }
-  current_region->SetRPO(current_rpo--);
-}
-
-void SeaGraph::ComputeIDominators() {
-  bool changed = true;
-  while (changed) {
-    changed = false;
-    // Entry node has itself as IDOM.
-    std::vector<Region*>::iterator crt_it;
-    std::set<Region*> processedNodes;
-    // Find and mark the entry node(s).
-    for (crt_it = regions_.begin(); crt_it != regions_.end(); ++crt_it) {
-      if ((*crt_it)->GetPredecessors()->size() == 0) {
-        processedNodes.insert(*crt_it);
-        (*crt_it)->SetIDominator(*crt_it);
-      }
-    }
-    for (crt_it = regions_.begin(); crt_it != regions_.end(); ++crt_it) {
-      if ((*crt_it)->GetPredecessors()->size() == 0) {
-        continue;
-      }
-      // NewIDom = first (processed) predecessor of b.
-      Region* new_dom = NULL;
-      std::vector<Region*>* preds = (*crt_it)->GetPredecessors();
-      DCHECK(NULL != preds);
-      Region* root_pred = NULL;
-      for (std::vector<Region*>::iterator pred_it = preds->begin();
-          pred_it != preds->end(); ++pred_it) {
-        if (processedNodes.end() != processedNodes.find((*pred_it))) {
-          root_pred = *pred_it;
-          new_dom = root_pred;
-          break;
-        }
-      }
-      // For all other predecessors p of b, if idom is not set,
-      // then NewIdom = Intersect(p, NewIdom)
-      for (std::vector<Region*>::const_iterator pred_it = preds->begin();
-          pred_it != preds->end(); ++pred_it) {
-        DCHECK(NULL != *pred_it);
-        // if IDOMS[p] != UNDEFINED
-        if ((*pred_it != root_pred) && (*pred_it)->GetIDominator() != NULL) {
-          DCHECK(NULL != new_dom);
-          new_dom = SeaGraph::Intersect(*pred_it, new_dom);
-        }
-      }
-      DCHECK(NULL != *crt_it);
-      if ((*crt_it)->GetIDominator() != new_dom) {
-        (*crt_it)->SetIDominator(new_dom);
-        changed = true;
-      }
-      processedNodes.insert(*crt_it);
-    }
-  }
-
-  // For easily ordering of regions we need edges dominator->dominated.
-  for (std::vector<Region*>::iterator region_it = regions_.begin();
-      region_it != regions_.end(); region_it++) {
-    Region* idom = (*region_it)->GetIDominator();
-    if (idom != *region_it) {
-      idom->AddToIDominatedSet(*region_it);
-    }
-  }
-}
-
-Region* SeaGraph::Intersect(Region* i, Region* j) {
-  Region* finger1 = i;
-  Region* finger2 = j;
-  while (finger1 != finger2) {
-    while (finger1->GetRPO() > finger2->GetRPO()) {
-      DCHECK(NULL != finger1);
-      finger1 = finger1->GetIDominator();  // should have: finger1 != NULL
-      DCHECK(NULL != finger1);
-    }
-    while (finger1->GetRPO() < finger2->GetRPO()) {
-      DCHECK(NULL != finger2);
-      finger2 = finger2->GetIDominator();  // should have: finger1 != NULL
-      DCHECK(NULL != finger2);
-    }
-  }
-  return finger1;  // finger1 should be equal to finger2 at this point.
-}
-
-void SeaGraph::ComputeDownExposedDefs() {
-  for (std::vector<Region*>::iterator region_it = regions_.begin();
-        region_it != regions_.end(); region_it++) {
-      (*region_it)->ComputeDownExposedDefs();
-    }
-}
-
-void SeaGraph::ComputeReachingDefs() {
-  // Iterate until the reaching definitions set doesn't change anymore.
-  // (See Cooper & Torczon, "Engineering a Compiler", second edition, page 487)
-  bool changed = true;
-  int iteration = 0;
-  while (changed && (iteration < MAX_REACHING_DEF_ITERERATIONS)) {
-    iteration++;
-    changed = false;
-    // TODO: optimize the ordering if this becomes performance bottleneck.
-    for (std::vector<Region*>::iterator regions_it = regions_.begin();
-        regions_it != regions_.end();
-        regions_it++) {
-      changed |= (*regions_it)->UpdateReachingDefs();
-    }
-  }
-  DCHECK(!changed) << "Reaching definitions computation did not reach a fixed point.";
-}
-
-void SeaGraph::InsertSignatureNodes(const art::DexFile::CodeItem* code_item, Region* r) {
-  // Insert a fake SignatureNode for the first parameter.
-  // TODO: Provide a register enum value for the fake parameter.
-  SignatureNode* parameter_def_node = new sea_ir::SignatureNode(0, 0);
-  AddParameterNode(parameter_def_node);
-  r->AddChild(parameter_def_node);
-  // Insert SignatureNodes for each Dalvik register parameter.
-  for (unsigned int crt_offset = 0; crt_offset < code_item->ins_size_; crt_offset++) {
-    int register_no = code_item->registers_size_ - crt_offset - 1;
-    int position = crt_offset + 1;
-    SignatureNode* parameter_def_node = new sea_ir::SignatureNode(register_no, position);
-    AddParameterNode(parameter_def_node);
-    r->AddChild(parameter_def_node);
-  }
-}
-
-void SeaGraph::BuildMethodSeaGraph(const art::DexFile::CodeItem* code_item,
-    const art::DexFile& dex_file, uint16_t class_def_idx,
-    uint32_t method_idx, uint32_t method_access_flags) {
-  code_item_ = code_item;
-  class_def_idx_ = class_def_idx;
-  method_idx_ = method_idx;
-  method_access_flags_ = method_access_flags;
-  const uint16_t* code = code_item->insns_;
-  const size_t size_in_code_units = code_item->insns_size_in_code_units_;
-  // This maps target instruction pointers to their corresponding region objects.
-  std::map<const uint16_t*, Region*> target_regions;
-  size_t i = 0;
-  // Pass: Find the start instruction of basic blocks
-  //         by locating targets and flow-though instructions of branches.
-  while (i < size_in_code_units) {
-    const art::Instruction* inst = art::Instruction::At(&code[i]);
-    if (inst->IsBranch() || inst->IsUnconditional()) {
-      int32_t offset = inst->GetTargetOffset();
-      if (target_regions.end() == target_regions.find(&code[i + offset])) {
-        Region* region = GetNewRegion();
-        target_regions.insert(std::pair<const uint16_t*, Region*>(&code[i + offset], region));
-      }
-      if (inst->CanFlowThrough()
-          && (target_regions.end() == target_regions.find(&code[i + inst->SizeInCodeUnits()]))) {
-        Region* region = GetNewRegion();
-        target_regions.insert(
-            std::pair<const uint16_t*, Region*>(&code[i + inst->SizeInCodeUnits()], region));
-      }
-    }
-    i += inst->SizeInCodeUnits();
-  }
-
-
-  Region* r = GetNewRegion();
-
-  InsertSignatureNodes(code_item, r);
-  // Pass: Assign instructions to region nodes and
-  //         assign branches their control flow successors.
-  i = 0;
-  sea_ir::InstructionNode* last_node = NULL;
-  sea_ir::InstructionNode* node = NULL;
-  while (i < size_in_code_units) {
-    const art::Instruction* inst = art::Instruction::At(&code[i]);
-    std::vector<InstructionNode*> sea_instructions_for_dalvik =
-        sea_ir::InstructionNode::Create(inst);
-    for (std::vector<InstructionNode*>::const_iterator cit = sea_instructions_for_dalvik.begin();
-        sea_instructions_for_dalvik.end() != cit; ++cit) {
-      last_node = node;
-      node = *cit;
-
-      if (inst->IsBranch() || inst->IsUnconditional()) {
-        int32_t offset = inst->GetTargetOffset();
-        std::map<const uint16_t*, Region*>::iterator it = target_regions.find(&code[i + offset]);
-        DCHECK(it != target_regions.end());
-        AddEdge(r, it->second);  // Add edge to branch target.
-      }
-      std::map<const uint16_t*, Region*>::iterator it = target_regions.find(&code[i]);
-      if (target_regions.end() != it) {
-        // Get the already created region because this is a branch target.
-        Region* nextRegion = it->second;
-        if (last_node->GetInstruction()->IsBranch()
-            && last_node->GetInstruction()->CanFlowThrough()) {
-          AddEdge(r, it->second);  // Add flow-through edge.
-        }
-        r = nextRegion;
-      }
-      r->AddChild(node);
-    }
-    i += inst->SizeInCodeUnits();
-  }
-}
-
-void SeaGraph::ComputeRPO() {
-  int rpo_id = regions_.size() - 1;
-  for (std::vector<Region*>::const_iterator crt_it = regions_.begin(); crt_it != regions_.end();
-      ++crt_it) {
-    if ((*crt_it)->GetPredecessors()->size() == 0) {
-      ComputeRPO(*crt_it, rpo_id);
-    }
-  }
-}
-
-// Performs the renaming phase in traditional SSA transformations.
-// See: Cooper & Torczon, "Engineering a Compiler", second edition, page 505.)
-void SeaGraph::RenameAsSSA() {
-  utils::ScopedHashtable<int, InstructionNode*> scoped_table;
-  scoped_table.OpenScope();
-  for (std::vector<Region*>::iterator region_it = regions_.begin(); region_it != regions_.end();
-      region_it++) {
-    if ((*region_it)->GetIDominator() == *region_it) {
-      RenameAsSSA(*region_it, &scoped_table);
-    }
-  }
-  scoped_table.CloseScope();
-}
-
-void SeaGraph::ConvertToSSA() {
-  // Pass: find global names.
-  // The map @block maps registers to the blocks in which they are defined.
-  std::map<int, std::set<Region*>> blocks;
-  // The set @globals records registers whose use
-  // is in a different block than the corresponding definition.
-  std::set<int> globals;
-  for (std::vector<Region*>::iterator region_it = regions_.begin(); region_it != regions_.end();
-      region_it++) {
-    std::set<int> var_kill;
-    std::vector<InstructionNode*>* instructions = (*region_it)->GetInstructions();
-    for (std::vector<InstructionNode*>::iterator inst_it = instructions->begin();
-        inst_it != instructions->end(); inst_it++) {
-      std::vector<int> used_regs = (*inst_it)->GetUses();
-      for (std::size_t i = 0; i < used_regs.size(); i++) {
-        int used_reg = used_regs[i];
-        if (var_kill.find(used_reg) == var_kill.end()) {
-          globals.insert(used_reg);
-        }
-      }
-      const int reg_def = (*inst_it)->GetResultRegister();
-      if (reg_def != NO_REGISTER) {
-        var_kill.insert(reg_def);
-      }
-
-      blocks.insert(std::pair<int, std::set<Region*>>(reg_def, std::set<Region*>()));
-      std::set<Region*>* reg_def_blocks = &(blocks.find(reg_def)->second);
-      reg_def_blocks->insert(*region_it);
-    }
-  }
-
-  // Pass: Actually add phi-nodes to regions.
-  for (std::set<int>::const_iterator globals_it = globals.begin();
-      globals_it != globals.end(); globals_it++) {
-    int global = *globals_it;
-    // Copy the set, because we will modify the worklist as we go.
-    std::set<Region*> worklist((*(blocks.find(global))).second);
-    for (std::set<Region*>::const_iterator b_it = worklist.begin();
-        b_it != worklist.end(); b_it++) {
-      std::set<Region*>* df = (*b_it)->GetDominanceFrontier();
-      for (std::set<Region*>::const_iterator df_it = df->begin(); df_it != df->end(); df_it++) {
-        if ((*df_it)->InsertPhiFor(global)) {
-          // Check that the dominance frontier element is in the worklist already
-          // because we only want to break if the element is actually not there yet.
-          if (worklist.find(*df_it) == worklist.end()) {
-            worklist.insert(*df_it);
-            b_it = worklist.begin();
-            break;
-          }
-        }
-      }
-    }
-  }
-  // Pass: Build edges to the definition corresponding to each use.
-  // (This corresponds to the renaming phase in traditional SSA transformations.
-  // See: Cooper & Torczon, "Engineering a Compiler", second edition, page 505.)
-  RenameAsSSA();
-}
-
-void SeaGraph::RenameAsSSA(Region* crt_region,
-    utils::ScopedHashtable<int, InstructionNode*>* scoped_table) {
-  scoped_table->OpenScope();
-  // Rename phi nodes defined in the current region.
-  std::vector<PhiInstructionNode*>* phis = crt_region->GetPhiNodes();
-  for (std::vector<PhiInstructionNode*>::iterator phi_it = phis->begin();
-      phi_it != phis->end(); phi_it++) {
-    int reg_no = (*phi_it)->GetRegisterNumber();
-    scoped_table->Add(reg_no, (*phi_it));
-  }
-  // Rename operands of instructions from the current region.
-  std::vector<InstructionNode*>* instructions = crt_region->GetInstructions();
-  for (std::vector<InstructionNode*>::const_iterator instructions_it = instructions->begin();
-      instructions_it != instructions->end(); instructions_it++) {
-    InstructionNode* current_instruction = (*instructions_it);
-    // Rename uses.
-    std::vector<int> used_regs = current_instruction->GetUses();
-    for (std::vector<int>::const_iterator reg_it = used_regs.begin();
-        reg_it != used_regs.end(); reg_it++) {
-      int current_used_reg = (*reg_it);
-      InstructionNode* definition = scoped_table->Lookup(current_used_reg);
-      current_instruction->RenameToSSA(current_used_reg, definition);
-    }
-    // Update scope table with latest definitions.
-    std::vector<int> def_regs = current_instruction->GetDefinitions();
-    for (std::vector<int>::const_iterator reg_it = def_regs.begin();
-            reg_it != def_regs.end(); reg_it++) {
-      int current_defined_reg = (*reg_it);
-      scoped_table->Add(current_defined_reg, current_instruction);
-    }
-  }
-  // Fill in uses of phi functions in CFG successor regions.
-  const std::vector<Region*>* successors = crt_region->GetSuccessors();
-  for (std::vector<Region*>::const_iterator successors_it = successors->begin();
-      successors_it != successors->end(); successors_it++) {
-    Region* successor = (*successors_it);
-    successor->SetPhiDefinitionsForUses(scoped_table, crt_region);
-  }
-
-  // Rename all successors in the dominators tree.
-  const std::set<Region*>* dominated_nodes = crt_region->GetIDominatedSet();
-  for (std::set<Region*>::const_iterator dominated_nodes_it = dominated_nodes->begin();
-      dominated_nodes_it != dominated_nodes->end(); dominated_nodes_it++) {
-    Region* dominated_node = (*dominated_nodes_it);
-    RenameAsSSA(dominated_node, scoped_table);
-  }
-  scoped_table->CloseScope();
-}
-
-CodeGenData* SeaGraph::GenerateLLVM(const std::string& function_name,
-    const art::DexFile& dex_file) {
-  // Pass: Generate LLVM IR.
-  CodeGenPrepassVisitor code_gen_prepass_visitor(function_name);
-  std::cout << "Generating code..." << std::endl;
-  Accept(&code_gen_prepass_visitor);
-  CodeGenVisitor code_gen_visitor(code_gen_prepass_visitor.GetData(),  dex_file);
-  Accept(&code_gen_visitor);
-  CodeGenPostpassVisitor code_gen_postpass_visitor(code_gen_visitor.GetData());
-  Accept(&code_gen_postpass_visitor);
-  return code_gen_postpass_visitor.GetData();
-}
-
-CodeGenData* SeaGraph::CompileMethod(
-    const std::string& function_name,
-    const art::DexFile::CodeItem* code_item, uint16_t class_def_idx,
-    uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file) {
-  // Two passes: Builds the intermediate structure (non-SSA) of the sea-ir for the function.
-  BuildMethodSeaGraph(code_item, dex_file, class_def_idx, method_idx, method_access_flags);
-  // Pass: Compute reverse post-order of regions.
-  ComputeRPO();
-  // Multiple passes: compute immediate dominators.
-  ComputeIDominators();
-  // Pass: compute downward-exposed definitions.
-  ComputeDownExposedDefs();
-  // Multiple Passes (iterative fixed-point algorithm): Compute reaching definitions
-  ComputeReachingDefs();
-  // Pass (O(nlogN)): Compute the dominance frontier for region nodes.
-  ComputeDominanceFrontier();
-  // Two Passes: Phi node insertion.
-  ConvertToSSA();
-  // Pass: type inference
-  ti_->ComputeTypes(this);
-  // Pass: Generate LLVM IR.
-  CodeGenData* cgd = GenerateLLVM(function_name, dex_file);
-  return cgd;
-}
-
-void SeaGraph::ComputeDominanceFrontier() {
-  for (std::vector<Region*>::iterator region_it = regions_.begin();
-      region_it != regions_.end(); region_it++) {
-    std::vector<Region*>* preds = (*region_it)->GetPredecessors();
-    if (preds->size() > 1) {
-      for (std::vector<Region*>::iterator pred_it = preds->begin();
-          pred_it != preds->end(); pred_it++) {
-        Region* runner = *pred_it;
-        while (runner != (*region_it)->GetIDominator()) {
-          runner->AddToDominanceFrontier(*region_it);
-          runner = runner->GetIDominator();
-        }
-      }
-    }
-  }
-}
-
-Region* SeaGraph::GetNewRegion() {
-  Region* new_region = new Region();
-  AddRegion(new_region);
-  return new_region;
-}
-
-void SeaGraph::AddRegion(Region* r) {
-  DCHECK(r) << "Tried to add NULL region to SEA graph.";
-  regions_.push_back(r);
-}
-
-SeaGraph::SeaGraph(const art::DexFile& df)
-    :ti_(new TypeInference()), class_def_idx_(0), method_idx_(0),  method_access_flags_(),
-     regions_(), parameters_(), dex_file_(df), code_item_(NULL) { }
-
-void Region::AddChild(sea_ir::InstructionNode* instruction) {
-  DCHECK(instruction) << "Tried to add NULL instruction to region node.";
-  instructions_.push_back(instruction);
-  instruction->SetRegion(this);
-}
-
-SeaNode* Region::GetLastChild() const {
-  if (instructions_.size() > 0) {
-    return instructions_.back();
-  }
-  return NULL;
-}
-
-void Region::ComputeDownExposedDefs() {
-  for (std::vector<InstructionNode*>::const_iterator inst_it = instructions_.begin();
-      inst_it != instructions_.end(); inst_it++) {
-    int reg_no = (*inst_it)->GetResultRegister();
-    std::map<int, InstructionNode*>::iterator res = de_defs_.find(reg_no);
-    if ((reg_no != NO_REGISTER) && (res == de_defs_.end())) {
-      de_defs_.insert(std::pair<int, InstructionNode*>(reg_no, *inst_it));
-    } else {
-      res->second = *inst_it;
-    }
-  }
-  for (std::map<int, sea_ir::InstructionNode*>::const_iterator cit = de_defs_.begin();
-      cit != de_defs_.end(); cit++) {
-    (*cit).second->MarkAsDEDef();
-  }
-}
-
-const std::map<int, sea_ir::InstructionNode*>* Region::GetDownExposedDefs() const {
-  return &de_defs_;
-}
-
-std::map<int, std::set<sea_ir::InstructionNode*>* >* Region::GetReachingDefs() {
-  return &reaching_defs_;
-}
-
-bool Region::UpdateReachingDefs() {
-  std::map<int, std::set<sea_ir::InstructionNode*>* > new_reaching;
-  for (std::vector<Region*>::const_iterator pred_it = predecessors_.begin();
-      pred_it != predecessors_.end(); pred_it++) {
-    // The reaching_defs variable will contain reaching defs __for current predecessor only__
-    std::map<int, std::set<sea_ir::InstructionNode*>* > reaching_defs;
-    std::map<int, std::set<sea_ir::InstructionNode*>* >* pred_reaching =
-        (*pred_it)->GetReachingDefs();
-    const std::map<int, InstructionNode*>* de_defs = (*pred_it)->GetDownExposedDefs();
-
-    // The definitions from the reaching set of the predecessor
-    // may be shadowed by downward exposed definitions from the predecessor,
-    // otherwise the defs from the reaching set are still good.
-    for (std::map<int, InstructionNode*>::const_iterator de_def = de_defs->begin();
-        de_def != de_defs->end(); de_def++) {
-      std::set<InstructionNode*>* solo_def;
-      solo_def = new std::set<InstructionNode*>();
-      solo_def->insert(de_def->second);
-      reaching_defs.insert(
-          std::pair<int const, std::set<InstructionNode*>*>(de_def->first, solo_def));
-    }
-    reaching_defs.insert(pred_reaching->begin(), pred_reaching->end());
-
-    // Now we combine the reaching map coming from the current predecessor (reaching_defs)
-    // with the accumulated set from all predecessors so far (from new_reaching).
-    std::map<int, std::set<sea_ir::InstructionNode*>*>::iterator reaching_it =
-        reaching_defs.begin();
-    for (; reaching_it != reaching_defs.end(); reaching_it++) {
-      std::map<int, std::set<sea_ir::InstructionNode*>*>::iterator crt_entry =
-          new_reaching.find(reaching_it->first);
-      if (new_reaching.end() != crt_entry) {
-        crt_entry->second->insert(reaching_it->second->begin(), reaching_it->second->end());
-      } else {
-        new_reaching.insert(
-            std::pair<int, std::set<sea_ir::InstructionNode*>*>(
-                reaching_it->first,
-                reaching_it->second) );
-      }
-    }
-  }
-  bool changed = false;
-  // Because the sets are monotonically increasing,
-  // we can compare sizes instead of using set comparison.
-  // TODO: Find formal proof.
-  int old_size = 0;
-  if (-1 == reaching_defs_size_) {
-    std::map<int, std::set<sea_ir::InstructionNode*>*>::iterator reaching_it =
-        reaching_defs_.begin();
-    for (; reaching_it != reaching_defs_.end(); reaching_it++) {
-      old_size += (*reaching_it).second->size();
-    }
-  } else {
-    old_size = reaching_defs_size_;
-  }
-  int new_size = 0;
-  std::map<int, std::set<sea_ir::InstructionNode*>*>::iterator reaching_it = new_reaching.begin();
-  for (; reaching_it != new_reaching.end(); reaching_it++) {
-    new_size += (*reaching_it).second->size();
-  }
-  if (old_size != new_size) {
-    changed = true;
-  }
-  if (changed) {
-    reaching_defs_ = new_reaching;
-    reaching_defs_size_ = new_size;
-  }
-  return changed;
-}
-
-bool Region::InsertPhiFor(int reg_no) {
-  if (!ContainsPhiFor(reg_no)) {
-    phi_set_.insert(reg_no);
-    PhiInstructionNode* new_phi = new PhiInstructionNode(reg_no);
-    new_phi->SetRegion(this);
-    phi_instructions_.push_back(new_phi);
-    return true;
-  }
-  return false;
-}
-
-void Region::SetPhiDefinitionsForUses(
-    const utils::ScopedHashtable<int, InstructionNode*>* scoped_table, Region* predecessor) {
-  int predecessor_id = -1;
-  for (unsigned int crt_pred_id = 0; crt_pred_id < predecessors_.size(); crt_pred_id++) {
-    if (predecessors_.at(crt_pred_id) == predecessor) {
-      predecessor_id = crt_pred_id;
-    }
-  }
-  DCHECK_NE(-1, predecessor_id);
-  for (std::vector<PhiInstructionNode*>::iterator phi_it = phi_instructions_.begin();
-      phi_it != phi_instructions_.end(); phi_it++) {
-    PhiInstructionNode* phi = (*phi_it);
-    int reg_no = phi->GetRegisterNumber();
-    InstructionNode* definition = scoped_table->Lookup(reg_no);
-    phi->RenameToSSA(reg_no, definition, predecessor_id);
-  }
-}
-
-std::vector<InstructionNode*> InstructionNode::Create(const art::Instruction* in) {
-  std::vector<InstructionNode*> sea_instructions;
-  switch (in->Opcode()) {
-    case art::Instruction::CONST_4:
-      sea_instructions.push_back(new ConstInstructionNode(in));
-      break;
-    case art::Instruction::RETURN:
-      sea_instructions.push_back(new ReturnInstructionNode(in));
-      break;
-    case art::Instruction::IF_NE:
-      sea_instructions.push_back(new IfNeInstructionNode(in));
-      break;
-    case art::Instruction::ADD_INT_LIT8:
-      sea_instructions.push_back(new UnnamedConstInstructionNode(in, in->VRegC_22b()));
-      sea_instructions.push_back(new AddIntLitInstructionNode(in));
-      break;
-    case art::Instruction::MOVE_RESULT:
-      sea_instructions.push_back(new MoveResultInstructionNode(in));
-      break;
-    case art::Instruction::INVOKE_STATIC:
-      sea_instructions.push_back(new InvokeStaticInstructionNode(in));
-      break;
-    case art::Instruction::ADD_INT:
-      sea_instructions.push_back(new AddIntInstructionNode(in));
-      break;
-    case art::Instruction::GOTO:
-      sea_instructions.push_back(new GotoInstructionNode(in));
-      break;
-    case art::Instruction::IF_EQZ:
-      sea_instructions.push_back(new IfEqzInstructionNode(in));
-      break;
-    default:
-      // Default, generic IR instruction node; default case should never be reached
-      // when support for all instructions ahs been added.
-      sea_instructions.push_back(new InstructionNode(in));
-  }
-  return sea_instructions;
-}
-
-void InstructionNode::MarkAsDEDef() {
-  de_def_ = true;
-}
-
-int InstructionNode::GetResultRegister() const {
-  if (instruction_->HasVRegA() && InstructionTools::IsDefinition(instruction_)) {
-    return instruction_->VRegA();
-  }
-  return NO_REGISTER;
-}
-
-std::vector<int> InstructionNode::GetDefinitions() const {
-  // TODO: Extend this to handle instructions defining more than one register (if any)
-  // The return value should be changed to pointer to field then; for now it is an object
-  // so that we avoid possible memory leaks from allocating objects dynamically.
-  std::vector<int> definitions;
-  int result = GetResultRegister();
-  if (NO_REGISTER != result) {
-    definitions.push_back(result);
-  }
-  return definitions;
-}
-
-std::vector<int> InstructionNode::GetUses() const {
-  std::vector<int> uses;  // Using vector<> instead of set<> because order matters.
-  if (!InstructionTools::IsDefinition(instruction_) && (instruction_->HasVRegA())) {
-    int vA = instruction_->VRegA();
-    uses.push_back(vA);
-  }
-  if (instruction_->HasVRegB()) {
-    int vB = instruction_->VRegB();
-    uses.push_back(vB);
-  }
-  if (instruction_->HasVRegC()) {
-    int vC = instruction_->VRegC();
-    uses.push_back(vC);
-  }
-  return uses;
-}
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/ir/sea.h b/compiler/sea_ir/ir/sea.h
deleted file mode 100644
index 26b16be..0000000
--- a/compiler/sea_ir/ir/sea.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_IR_SEA_H_
-#define ART_COMPILER_SEA_IR_IR_SEA_H_
-
-#include <set>
-#include <map>
-
-#include "utils/scoped_hashtable.h"
-#include "gtest/gtest_prod.h"
-#include "dex_file.h"
-#include "dex_instruction.h"
-#include "sea_ir/ir/instruction_tools.h"
-#include "sea_ir/ir/instruction_nodes.h"
-
-namespace sea_ir {
-
-// Reverse post-order numbering constants
-enum RegionNumbering {
-  NOT_VISITED = -1,
-  VISITING = -2
-};
-
-class TypeInference;
-class CodeGenData;
-
-class Region;
-class InstructionNode;
-class PhiInstructionNode;
-class SignatureNode;
-
-// A SignatureNode is a declaration of one parameter in the function signature.
-// This class is used to provide place-holder definitions to which instructions
-// can return from the GetSSAUses() calls, instead of having missing SSA edges.
-class SignatureNode: public InstructionNode {
- public:
-  // Creates a new signature node representing the initial definition of the
-  // register @register_no which is the @signature_position-th argument to the method.
-  explicit SignatureNode(unsigned int register_no, unsigned int signature_position):
-    InstructionNode(NULL), register_no_(register_no), position_(signature_position) { }
-
-  int GetResultRegister() const {
-    return register_no_;
-  }
-
-  unsigned int GetPositionInSignature() const {
-    return position_;
-  }
-
-  std::vector<int> GetUses() const {
-    return std::vector<int>();
-  }
-
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-
- private:
-  const unsigned int register_no_;
-  const unsigned int position_;     // The position of this parameter node is
-                                    // in the function parameter list.
-};
-
-class PhiInstructionNode: public InstructionNode {
- public:
-  explicit PhiInstructionNode(int register_no):
-    InstructionNode(NULL), register_no_(register_no), definition_edges_() {}
-  // Returns the register on which this phi-function is used.
-  int GetRegisterNumber() const {
-    return register_no_;
-  }
-
-  // Renames the use of @reg_no to refer to the instruction @definition.
-  // Phi-functions are different than normal instructions in that they
-  // have multiple predecessor regions; this is why RenameToSSA has
-  // the additional parameter specifying that @parameter_id is the incoming
-  // edge for @definition, essentially creating SSA form.
-  void RenameToSSA(int reg_no, InstructionNode* definition, unsigned int predecessor_id) {
-    DCHECK(NULL != definition) << "Tried to rename to SSA using a NULL definition for "
-        << StringId() << " register " << reg_no;
-    if (definition_edges_.size() < predecessor_id+1) {
-      definition_edges_.resize(predecessor_id+1, NULL);
-    }
-    if (NULL == definition_edges_.at(predecessor_id)) {
-      definition_edges_[predecessor_id] = new std::vector<InstructionNode*>();
-    }
-    definition_edges_[predecessor_id]->push_back(definition);
-    definition->AddSSAUse(this);
-  }
-
-  // Returns the ordered set of Instructions that define the input operands of this instruction.
-  // Precondition: SeaGraph.ConvertToSSA().
-  std::vector<InstructionNode*> GetSSAProducers() {
-    std::vector<InstructionNode*> producers;
-    for (std::vector<std::vector<InstructionNode*>*>::const_iterator
-        cit = definition_edges_.begin(); cit != definition_edges_.end(); cit++) {
-      producers.insert(producers.end(), (*cit)->begin(), (*cit)->end());
-    }
-    return producers;
-  }
-
-  // Returns the instruction that defines the phi register from predecessor
-  // on position @predecessor_pos. Note that the return value is vector<> just
-  // for consistency with the return value of GetSSAUses() on regular instructions,
-  // The returned vector should always have a single element because the IR is SSA.
-  std::vector<InstructionNode*>* GetSSAUses(int predecessor_pos) {
-    return definition_edges_.at(predecessor_pos);
-  }
-
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-
- private:
-  int register_no_;
-  // This vector has one entry for each predecessors, each with a single
-  // element, storing the id of the instruction that defines the register
-  // corresponding to this phi function.
-  std::vector<std::vector<InstructionNode*>*> definition_edges_;
-};
-
-// This class corresponds to a basic block in traditional compiler IRs.
-// The dataflow analysis relies on this class both during execution and
-// for storing its results.
-class Region : public SeaNode {
- public:
-  explicit Region():
-    SeaNode(), successors_(), predecessors_(), reaching_defs_size_(0),
-    rpo_number_(NOT_VISITED), idom_(NULL), idominated_set_(), df_(), phi_set_() {
-    string_id_ = "cluster_" + string_id_;
-  }
-  // Adds @instruction as an instruction node child in the current region.
-  void AddChild(sea_ir::InstructionNode* instruction);
-  // Returns the last instruction node child of the current region.
-  // This child has the CFG successors pointing to the new regions.
-  SeaNode* GetLastChild() const;
-  // Returns all the child instructions of this region, in program order.
-  std::vector<InstructionNode*>* GetInstructions() {
-    return &instructions_;
-  }
-
-  // Computes Downward Exposed Definitions for the current node.
-  void ComputeDownExposedDefs();
-  const std::map<int, sea_ir::InstructionNode*>* GetDownExposedDefs() const;
-  // Performs one iteration of the reaching definitions algorithm
-  // and returns true if the reaching definitions set changed.
-  bool UpdateReachingDefs();
-  // Returns the set of reaching definitions for the current region.
-  std::map<int, std::set<sea_ir::InstructionNode*>* >* GetReachingDefs();
-
-  void SetRPO(int rpo) {
-    rpo_number_ = rpo;
-  }
-
-  int GetRPO() {
-    return rpo_number_;
-  }
-
-  void SetIDominator(Region* dom) {
-    idom_ = dom;
-  }
-
-  Region* GetIDominator() const {
-    return idom_;
-  }
-
-  void AddToIDominatedSet(Region* dominated) {
-    idominated_set_.insert(dominated);
-  }
-
-  const std::set<Region*>* GetIDominatedSet() {
-    return &idominated_set_;
-  }
-  // Adds @df_reg to the dominance frontier of the current region.
-  void AddToDominanceFrontier(Region* df_reg) {
-    df_.insert(df_reg);
-  }
-  // Returns the dominance frontier of the current region.
-  // Preconditions: SeaGraph.ComputeDominanceFrontier()
-  std::set<Region*>* GetDominanceFrontier() {
-    return &df_;
-  }
-  // Returns true if the region contains a phi function for @reg_no.
-  bool ContainsPhiFor(int reg_no) {
-    return (phi_set_.end() != phi_set_.find(reg_no));
-  }
-  // Returns the phi-functions from the region.
-  std::vector<PhiInstructionNode*>* GetPhiNodes() {
-    return &phi_instructions_;
-  }
-  // Adds a phi-function for @reg_no to this region.
-  // Note: The insertion order does not matter, as phi-functions
-  //       are conceptually executed at the same time.
-  bool InsertPhiFor(int reg_no);
-  // Sets the phi-function uses to be as defined in @scoped_table for predecessor @@predecessor.
-  void SetPhiDefinitionsForUses(const utils::ScopedHashtable<int, InstructionNode*>* scoped_table,
-      Region* predecessor);
-
-  void Accept(IRVisitor* v) {
-    v->Visit(this);
-    v->Traverse(this);
-  }
-
-  void AddSuccessor(Region* successor) {
-    DCHECK(successor) << "Tried to add NULL successor to SEA node.";
-    successors_.push_back(successor);
-    return;
-  }
-  void AddPredecessor(Region* predecessor) {
-    DCHECK(predecessor) << "Tried to add NULL predecessor to SEA node.";
-    predecessors_.push_back(predecessor);
-  }
-
-  std::vector<sea_ir::Region*>* GetSuccessors() {
-    return &successors_;
-  }
-  std::vector<sea_ir::Region*>* GetPredecessors() {
-    return &predecessors_;
-  }
-
- private:
-  std::vector<sea_ir::Region*> successors_;    // CFG successor nodes (regions)
-  std::vector<sea_ir::Region*> predecessors_;  // CFG predecessor nodes (instructions/regions)
-  std::vector<sea_ir::InstructionNode*> instructions_;
-  std::map<int, sea_ir::InstructionNode*> de_defs_;
-  std::map<int, std::set<sea_ir::InstructionNode*>* > reaching_defs_;
-  int reaching_defs_size_;
-  int rpo_number_;                              // reverse postorder number of the region
-  // Immediate dominator node.
-  Region* idom_;
-  // The set of nodes immediately dominated by the region.
-  std::set<Region*> idominated_set_;
-  // Records the dominance frontier.
-  std::set<Region*> df_;
-  // Records the set of register numbers that have phi nodes in this region.
-  std::set<int> phi_set_;
-  std::vector<PhiInstructionNode*> phi_instructions_;
-};
-
-// A SeaGraph instance corresponds to a source code function.
-// Its main point is to encapsulate the SEA IR representation of it
-// and acts as starting point for visitors (ex: during code generation).
-class SeaGraph: IVisitable {
- public:
-  static SeaGraph* GetGraph(const art::DexFile&);
-
-  CodeGenData* CompileMethod(const std::string& function_name,
-      const art::DexFile::CodeItem* code_item, uint16_t class_def_idx,
-      uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file);
-  // Returns all regions corresponding to this SeaGraph.
-  std::vector<Region*>* GetRegions() {
-    return &regions_;
-  }
-  // Recursively computes the reverse postorder value for @crt_bb and successors.
-  static void ComputeRPO(Region* crt_bb, int& crt_rpo);
-  // Returns the "lowest common ancestor" of @i and @j in the dominator tree.
-  static Region* Intersect(Region* i, Region* j);
-  // Returns the vector of parameters of the function.
-  std::vector<SignatureNode*>* GetParameterNodes() {
-    return &parameters_;
-  }
-
-  const art::DexFile* GetDexFile() const {
-    return &dex_file_;
-  }
-
-  virtual void Accept(IRVisitor* visitor) {
-    visitor->Initialize(this);
-    visitor->Visit(this);
-    visitor->Traverse(this);
-  }
-
-  TypeInference* ti_;
-  uint16_t class_def_idx_;
-  uint32_t method_idx_;
-  uint32_t method_access_flags_;
-
- protected:
-  explicit SeaGraph(const art::DexFile& df);
-  virtual ~SeaGraph() { }
-
- private:
-  FRIEND_TEST(RegionsTest, Basics);
-  // Registers @childReg as a region belonging to the SeaGraph instance.
-  void AddRegion(Region* childReg);
-  // Returns new region and registers it with the  SeaGraph instance.
-  Region* GetNewRegion();
-  // Adds a (formal) parameter node to the vector of parameters of the function.
-  void AddParameterNode(SignatureNode* parameterNode) {
-    parameters_.push_back(parameterNode);
-  }
-  // Adds a CFG edge from @src node to @dst node.
-  void AddEdge(Region* src, Region* dst) const;
-  // Builds the non-SSA sea-ir representation of the function @code_item from @dex_file
-  // with class id @class_def_idx and method id @method_idx.
-  void BuildMethodSeaGraph(const art::DexFile::CodeItem* code_item,
-      const art::DexFile& dex_file, uint16_t class_def_idx,
-      uint32_t method_idx, uint32_t method_access_flags);
-  // Computes immediate dominators for each region.
-  // Precondition: ComputeMethodSeaGraph()
-  void ComputeIDominators();
-  // Computes Downward Exposed Definitions for all regions in the graph.
-  void ComputeDownExposedDefs();
-  // Computes the reaching definitions set following the equations from
-  // Cooper & Torczon, "Engineering a Compiler", second edition, page 491.
-  // Precondition: ComputeDEDefs()
-  void ComputeReachingDefs();
-  // Computes the reverse-postorder numbering for the region nodes.
-  // Precondition: ComputeDEDefs()
-  void ComputeRPO();
-  // Computes the dominance frontier for all regions in the graph,
-  // following the algorithm from
-  // Cooper & Torczon, "Engineering a Compiler", second edition, page 499.
-  // Precondition: ComputeIDominators()
-  void ComputeDominanceFrontier();
-  // Converts the IR to semi-pruned SSA form.
-  void ConvertToSSA();
-  // Performs the renaming phase of the SSA transformation during ConvertToSSA() execution.
-  void RenameAsSSA();
-  // Identifies the definitions corresponding to uses for region @node
-  // by using the scoped hashtable of names @ scoped_table.
-  void RenameAsSSA(Region* node, utils::ScopedHashtable<int, InstructionNode*>* scoped_table);
-  // Generate LLVM IR for the method.
-  // Precondition: ConvertToSSA().
-  CodeGenData* GenerateLLVM(const std::string& function_name, const art::DexFile& dex_file);
-  // Inserts one SignatureNode for each argument of the function in
-  void InsertSignatureNodes(const art::DexFile::CodeItem* code_item, Region* r);
-
-  static SeaGraph graph_;
-  std::vector<Region*> regions_;
-  std::vector<SignatureNode*> parameters_;
-  const art::DexFile& dex_file_;
-  const art::DexFile::CodeItem* code_item_;
-};
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_IR_SEA_H_
diff --git a/compiler/sea_ir/ir/sea_node.h b/compiler/sea_ir/ir/sea_node.h
deleted file mode 100644
index 4dab5cb..0000000
--- a/compiler/sea_ir/ir/sea_node.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_IR_SEA_NODE_H_
-#define ART_COMPILER_SEA_IR_IR_SEA_NODE_H_
-
-#include "base/stringprintf.h"
-
-namespace sea_ir {
-class Region;
-class IRVisitor;
-
-class IVisitable {
- public:
-  virtual void Accept(IRVisitor* visitor) = 0;
-  virtual ~IVisitable() {}
-};
-
-// This abstract class provides the essential services that
-// we want each SEA IR element to have.
-// At the moment, these are:
-// - an id and corresponding string representation.
-// - a .dot graph language representation for .dot output.
-//
-// Note that SEA IR nodes could also be Regions, Projects
-// which are not instructions.
-class SeaNode: public IVisitable {
- public:
-  explicit SeaNode():id_(GetNewId()), string_id_() {
-    string_id_ = art::StringPrintf("%d", id_);
-  }
-
-  // Adds CFG predecessors and successors to each block.
-  void AddSuccessor(Region* successor);
-  void AddPredecessor(Region* predecesor);
-
-  // Returns the id of the current block as string
-  const std::string& StringId() const {
-    return string_id_;
-  }
-  // Returns the id of this node as int. The id is supposed to be unique among
-  // all instances of all subclasses of this class.
-  int Id() const {
-    return id_;
-  }
-
-  virtual ~SeaNode() { }
-
- protected:
-  static int GetNewId() {
-    return current_max_node_id_++;
-  }
-
-  const int id_;
-  std::string string_id_;
-
- private:
-  static int current_max_node_id_;
-  // Creating new instances of sea node objects should not be done through copy or assignment
-  // operators because that would lead to duplication of their unique ids.
-  DISALLOW_COPY_AND_ASSIGN(SeaNode);
-};
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_IR_SEA_NODE_H_
diff --git a/compiler/sea_ir/ir/visitor.h b/compiler/sea_ir/ir/visitor.h
deleted file mode 100644
index cc7b5d1..0000000
--- a/compiler/sea_ir/ir/visitor.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_IR_VISITOR_H_
-#define ART_COMPILER_SEA_IR_IR_VISITOR_H_
-
-namespace sea_ir {
-
-class SeaGraph;
-class Region;
-class InstructionNode;
-class PhiInstructionNode;
-class SignatureNode;
-class UnnamedConstInstructionNode;
-class ConstInstructionNode;
-class ReturnInstructionNode;
-class IfNeInstructionNode;
-class AddIntLit8InstructionNode;
-class MoveResultInstructionNode;
-class InvokeStaticInstructionNode;
-class AddIntInstructionNode;
-class AddIntLitInstructionNode;
-class GotoInstructionNode;
-class IfEqzInstructionNode;
-
-
-
-
-class IRVisitor {
- public:
-  explicit IRVisitor(): ordered_regions_() { }
-  virtual void Initialize(SeaGraph* graph) = 0;
-  virtual void Visit(SeaGraph* graph) = 0;
-  virtual void Visit(Region* region) = 0;
-  virtual void Visit(PhiInstructionNode* region) = 0;
-  virtual void Visit(SignatureNode* region) = 0;
-
-  virtual void Visit(InstructionNode* region) = 0;
-  virtual void Visit(ConstInstructionNode* instruction) = 0;
-  virtual void Visit(UnnamedConstInstructionNode* instruction) = 0;
-  virtual void Visit(ReturnInstructionNode* instruction) = 0;
-  virtual void Visit(IfNeInstructionNode* instruction) = 0;
-  virtual void Visit(MoveResultInstructionNode* instruction) = 0;
-  virtual void Visit(InvokeStaticInstructionNode* instruction) = 0;
-  virtual void Visit(AddIntInstructionNode* instruction) = 0;
-  virtual void Visit(GotoInstructionNode* instruction) = 0;
-  virtual void Visit(IfEqzInstructionNode* instruction) = 0;
-
-  // Note: This flavor of visitor separates the traversal functions from the actual visiting part
-  //       so that the Visitor subclasses don't duplicate code and can't get the traversal wrong.
-  //       The disadvantage is the increased number of functions (and calls).
-  virtual void Traverse(SeaGraph* graph);
-  virtual void Traverse(Region* region);
-  // The following functions are meant to be empty and not pure virtual,
-  // because the parameter classes have no children to traverse.
-  virtual void Traverse(InstructionNode* region) { }
-  virtual void Traverse(ConstInstructionNode* instruction) { }
-  virtual void Traverse(ReturnInstructionNode* instruction) { }
-  virtual void Traverse(IfNeInstructionNode* instruction) { }
-  virtual void Traverse(AddIntLit8InstructionNode* instruction) { }
-  virtual void Traverse(MoveResultInstructionNode* instruction) { }
-  virtual void Traverse(InvokeStaticInstructionNode* instruction) { }
-  virtual void Traverse(AddIntInstructionNode* instruction) { }
-  virtual void Traverse(GotoInstructionNode* instruction) { }
-  virtual void Traverse(IfEqzInstructionNode* instruction) { }
-  virtual void Traverse(PhiInstructionNode* phi) { }
-  virtual void Traverse(SignatureNode* sig) { }
-  virtual ~IRVisitor() { }
-
- protected:
-  std::vector<Region*> ordered_regions_;
-};
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_IR_VISITOR_H_
diff --git a/compiler/sea_ir/types/type_data_test.cc b/compiler/sea_ir/types/type_data_test.cc
deleted file mode 100644
index 42c6973..0000000
--- a/compiler/sea_ir/types/type_data_test.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2013 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 "common_compiler_test.h"
-#include "sea_ir/types/types.h"
-
-namespace sea_ir {
-
-class TypeDataTest : public art::CommonCompilerTest {};
-
-TEST_F(TypeDataTest, Basics) {
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  int first_instruction_id = 1;
-  int second_instruction_id = 3;
-  EXPECT_TRUE(NULL == td.FindTypeOf(first_instruction_id));
-  const Type* int_type = &type_cache.Integer();
-  const Type* byte_type = &type_cache.Byte();
-  td.SetTypeOf(first_instruction_id, int_type);
-  EXPECT_TRUE(int_type == td.FindTypeOf(first_instruction_id));
-  EXPECT_TRUE(NULL == td.FindTypeOf(second_instruction_id));
-  td.SetTypeOf(second_instruction_id, byte_type);
-  EXPECT_TRUE(int_type == td.FindTypeOf(first_instruction_id));
-  EXPECT_TRUE(byte_type == td.FindTypeOf(second_instruction_id));
-}
-
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/types/type_inference.cc b/compiler/sea_ir/types/type_inference.cc
deleted file mode 100644
index 1731987..0000000
--- a/compiler/sea_ir/types/type_inference.cc
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2013 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 "scoped_thread_state_change.h"
-#include "sea_ir/types/type_inference.h"
-#include "sea_ir/types/type_inference_visitor.h"
-#include "sea_ir/ir/sea.h"
-
-namespace sea_ir {
-
-bool TypeInference::IsPrimitiveDescriptor(char descriptor) {
-  switch (descriptor) {
-  case 'I':
-  case 'C':
-  case 'S':
-  case 'B':
-  case 'Z':
-  case 'F':
-  case 'D':
-  case 'J':
-    return true;
-  default:
-    return false;
-  }
-}
-
-FunctionTypeInfo::FunctionTypeInfo(const SeaGraph* graph, art::verifier::RegTypeCache* types)
-    : dex_file_(graph->GetDexFile()), dex_method_idx_(graph->method_idx_), type_cache_(types),
-    method_access_flags_(graph->method_access_flags_) {
-  const art::DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
-  const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
-  declaring_class_ = &(type_cache_->FromDescriptor(NULL, descriptor, false));
-}
-
-FunctionTypeInfo::FunctionTypeInfo(const SeaGraph* graph, InstructionNode* inst,
-    art::verifier::RegTypeCache* types): dex_file_(graph->GetDexFile()),
-        dex_method_idx_(inst->GetInstruction()->VRegB_35c()), type_cache_(types),
-        method_access_flags_(0) {
-  // TODO: Test that GetDeclaredArgumentTypes() works correctly when using this constructor.
-  const art::DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
-  const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
-  declaring_class_ = &(type_cache_->FromDescriptor(NULL, descriptor, false));
-}
-
-const Type* FunctionTypeInfo::GetReturnValueType() {
-  const art::DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
-  uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
-  const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx);
-  art::ScopedObjectAccess soa(art::Thread::Current());
-  const Type& return_type = type_cache_->FromDescriptor(NULL, descriptor, false);
-  return &return_type;
-}
-
-
-
-std::vector<const Type*> FunctionTypeInfo::GetDeclaredArgumentTypes() {
-  art::ScopedObjectAccess soa(art::Thread::Current());
-  std::vector<const Type*> argument_types;
-  // TODO: The additional (fake) Method parameter is added on the first position,
-  //       but is represented as integer because we don't support  pointers yet.
-  argument_types.push_back(&(type_cache_->Integer()));
-  // Include the "this" pointer.
-  size_t cur_arg = 0;
-  if (!IsStatic()) {
-    // If this is a constructor for a class other than java.lang.Object, mark the first ("this")
-    // argument as uninitialized. This restricts field access until the superclass constructor is
-    // called.
-    const art::verifier::RegType& declaring_class = GetDeclaringClass();
-    if (IsConstructor() && !declaring_class.IsJavaLangObject()) {
-      argument_types.push_back(&(type_cache_->UninitializedThisArgument(declaring_class)));
-    } else {
-      argument_types.push_back(&declaring_class);
-    }
-    cur_arg++;
-  }
-  // Include the types of the parameters in the Java method signature.
-  const art::DexFile::ProtoId& proto_id =
-      dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
-  art::DexFileParameterIterator iterator(*dex_file_, proto_id);
-
-  for (; iterator.HasNext(); iterator.Next()) {
-    const char* descriptor = iterator.GetDescriptor();
-    if (descriptor == NULL) {
-      LOG(FATAL) << "Error: Encountered null type descriptor for function argument.";
-    }
-    switch (descriptor[0]) {
-      case 'L':
-      case '[':
-        // We assume that reference arguments are initialized. The only way it could be otherwise
-        // (assuming the caller was verified) is if the current method is <init>, but in that case
-        // it's effectively considered initialized the instant we reach here (in the sense that we
-        // can return without doing anything or call virtual methods).
-        {
-          const Type& reg_type = type_cache_->FromDescriptor(NULL, descriptor, false);
-          argument_types.push_back(&reg_type);
-        }
-        break;
-      case 'Z':
-        argument_types.push_back(&type_cache_->Boolean());
-        break;
-      case 'C':
-        argument_types.push_back(&type_cache_->Char());
-        break;
-      case 'B':
-        argument_types.push_back(&type_cache_->Byte());
-        break;
-      case 'I':
-        argument_types.push_back(&type_cache_->Integer());
-        break;
-      case 'S':
-        argument_types.push_back(&type_cache_->Short());
-        break;
-      case 'F':
-        argument_types.push_back(&type_cache_->Float());
-        break;
-      case 'J':
-      case 'D': {
-        // TODO: Figure out strategy for two-register operands (double, long)
-        LOG(FATAL) << "Error: Type inference for 64-bit variables has not been implemented.";
-        break;
-      }
-      default:
-        LOG(FATAL) << "Error: Unexpected signature encountered during type inference.";
-    }
-    cur_arg++;
-  }
-  return argument_types;
-}
-
-// TODO: Lock is only used for dumping types (during development). Remove this for performance.
-void TypeInference::ComputeTypes(SeaGraph* graph) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  std::vector<Region*>* regions = graph->GetRegions();
-  std::list<InstructionNode*> worklist;
-  // Fill the work-list with all instructions.
-  for (std::vector<Region*>::const_iterator region_it = regions->begin();
-      region_it != regions->end(); region_it++) {
-    std::vector<PhiInstructionNode*>* phi_instructions = (*region_it)->GetPhiNodes();
-    std::copy(phi_instructions->begin(), phi_instructions->end(), std::back_inserter(worklist));
-    std::vector<InstructionNode*>* instructions = (*region_it)->GetInstructions();
-    std::copy(instructions->begin(), instructions->end(), std::back_inserter(worklist));
-  }
-  TypeInferenceVisitor tiv(graph, &type_data_, type_cache_);
-  // Record return type of the function.
-  graph->Accept(&tiv);
-  const Type* new_type = tiv.GetType();
-  type_data_.SetTypeOf(-1, new_type);   // TODO: Record this info in a way that
-                                        //      does not need magic constants.
-                                        //      Make SeaGraph a SeaNode?
-
-  // Sparse (SSA) fixed-point algorithm that processes each instruction in the work-list,
-  // adding consumers of instructions whose result changed type back into the work-list.
-  // Note: According to [1] list iterators should not be invalidated on insertion,
-  //       which simplifies the implementation; not 100% sure other STL implementations
-  //       maintain this invariant, but they should.
-  //       [1] http://www.sgi.com/tech/stl/List.html
-  // TODO: Making this conditional (as in sparse conditional constant propagation) would be good.
-  // TODO: Remove elements as I go.
-  for (std::list<InstructionNode*>::const_iterator instruction_it = worklist.begin();
-        instruction_it != worklist.end(); instruction_it++) {
-    (*instruction_it)->Accept(&tiv);
-    const Type* old_type = type_data_.FindTypeOf((*instruction_it)->Id());
-    const Type* new_type = tiv.GetType();
-    bool type_changed = (old_type != new_type);
-    if (type_changed) {
-      type_data_.SetTypeOf((*instruction_it)->Id(), new_type);
-      // Add SSA consumers of the current instruction to the work-list.
-      std::vector<InstructionNode*>* consumers = (*instruction_it)->GetSSAConsumers();
-      for (std::vector<InstructionNode*>::iterator consumer = consumers->begin();
-          consumer != consumers->end(); consumer++) {
-        worklist.push_back(*consumer);
-      }
-    }
-  }
-}
-}   // namespace sea_ir
diff --git a/compiler/sea_ir/types/type_inference.h b/compiler/sea_ir/types/type_inference.h
deleted file mode 100644
index 7a178b2..0000000
--- a/compiler/sea_ir/types/type_inference.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2011 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_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_H_
-#define ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_H_
-
-#include "safe_map.h"
-#include "dex_file-inl.h"
-#include "sea_ir/types/types.h"
-
-namespace sea_ir {
-
-class SeaGraph;
-class InstructionNode;
-
-// The type inference in SEA IR is different from the verifier in that it is concerned
-// with a rich type hierarchy (TODO) usable in optimization and does not perform
-// precise verification (which is the job of the verifier).
-class TypeInference {
- public:
-  TypeInference() : type_cache_(new art::verifier::RegTypeCache(false)) {
-  }
-
-  // Computes the types for the method with SEA IR representation provided by @graph.
-  void ComputeTypes(SeaGraph* graph);
-
-  art::SafeMap<int, const Type*>* GetTypeMap() {
-    return type_data_.GetTypeMap();
-  }
-  // Returns true if @descriptor corresponds to a primitive type.
-  static bool IsPrimitiveDescriptor(char descriptor);
-  TypeData type_data_;    // TODO: Make private, add accessor and not publish a SafeMap above.
-  art::verifier::RegTypeCache* const type_cache_;    // TODO: Make private.
-};
-
-// Stores information about the exact type of  a function.
-class FunctionTypeInfo {
- public:
-  // Finds method information about the method encoded by a SEA IR graph.
-  // @graph provides the input method SEA IR representation.
-  // @types provides the input cache of types from which the
-  //        parameter types of the function are found.
-  FunctionTypeInfo(const SeaGraph* graph, art::verifier::RegTypeCache* types);
-  // Finds method information about the method encoded by
-  // an invocation instruction in a SEA IR graph.
-  // @graph provides the input method SEA IR representation.
-  // @inst  is an invocation instruction for the desired method.
-  // @types provides the input cache of types from which the
-  //        parameter types of the function are found.
-  FunctionTypeInfo(const SeaGraph* graph, InstructionNode* inst,
-      art::verifier::RegTypeCache* types);
-  // Returns the ordered vector of types corresponding to the function arguments.
-  std::vector<const Type*> GetDeclaredArgumentTypes();
-  // Returns the declared return value type.
-  const Type* GetReturnValueType();
-  // Returns the type corresponding to the class that declared the method.
-  const Type& GetDeclaringClass() {
-    return *declaring_class_;
-  }
-
-  bool IsConstructor() const {
-    return (method_access_flags_ & kAccConstructor) != 0;
-  }
-
-  bool IsStatic() const {
-    return (method_access_flags_ & kAccStatic) != 0;
-  }
-
- protected:
-  const Type* declaring_class_;
-  const art::DexFile* dex_file_;
-  const uint32_t dex_method_idx_;
-  art::verifier::RegTypeCache* type_cache_;
-  const uint32_t method_access_flags_;  // Method's access flags.
-};
-}  // namespace sea_ir
-
-#endif  // ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_H_
diff --git a/compiler/sea_ir/types/type_inference_visitor.cc b/compiler/sea_ir/types/type_inference_visitor.cc
deleted file mode 100644
index 27bb5d8..0000000
--- a/compiler/sea_ir/types/type_inference_visitor.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2013 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 "scoped_thread_state_change.h"
-#include "sea_ir/types/type_inference_visitor.h"
-#include "sea_ir/types/type_inference.h"
-#include "sea_ir/ir/sea.h"
-
-namespace sea_ir {
-
-void TypeInferenceVisitor::Visit(SeaGraph* graph) {
-  FunctionTypeInfo fti(graph_, type_cache_);
-  const Type* return_type = fti.GetReturnValueType();
-  crt_type_.push_back(return_type);
-}
-
-void TypeInferenceVisitor::Visit(SignatureNode* parameter) {
-  FunctionTypeInfo fti(graph_, type_cache_);
-  std::vector<const Type*> arguments = fti.GetDeclaredArgumentTypes();
-  DCHECK_LT(parameter->GetPositionInSignature(), arguments.size())
-    << "Signature node position not present in signature.";
-  crt_type_.push_back(arguments.at(parameter->GetPositionInSignature()));
-}
-
-void TypeInferenceVisitor::Visit(UnnamedConstInstructionNode* instruction) {
-  crt_type_.push_back(&type_cache_->Integer());
-}
-
-void TypeInferenceVisitor::Visit(PhiInstructionNode* instruction) {
-  std::vector<const Type*> types_to_merge = GetOperandTypes(instruction);
-  const Type* result_type = MergeTypes(types_to_merge);
-  crt_type_.push_back(result_type);
-}
-
-void TypeInferenceVisitor::Visit(AddIntInstructionNode* instruction) {
-  std::vector<const Type*> operand_types = GetOperandTypes(instruction);
-  for (std::vector<const Type*>::const_iterator cit = operand_types.begin();
-      cit != operand_types.end(); cit++) {
-    if (*cit != NULL) {
-      DCHECK((*cit)->IsInteger());
-    }
-  }
-  crt_type_.push_back(&type_cache_->Integer());
-}
-
-void TypeInferenceVisitor::Visit(MoveResultInstructionNode* instruction) {
-  std::vector<const Type*> operand_types = GetOperandTypes(instruction);
-  const Type* operand_type = operand_types.at(0);
-  crt_type_.push_back(operand_type);
-}
-
-void TypeInferenceVisitor::Visit(InvokeStaticInstructionNode* instruction) {
-  FunctionTypeInfo fti(graph_, instruction, type_cache_);
-  const Type* result_type = fti.GetReturnValueType();
-  crt_type_.push_back(result_type);
-}
-
-std::vector<const Type*> TypeInferenceVisitor::GetOperandTypes(
-    InstructionNode* instruction) const {
-  std::vector<InstructionNode*> sources = instruction->GetSSAProducers();
-  std::vector<const Type*> types_to_merge;
-  for (std::vector<InstructionNode*>::const_iterator cit = sources.begin(); cit != sources.end();
-      cit++) {
-    const Type* source_type = type_data_->FindTypeOf((*cit)->Id());
-    if (source_type != NULL) {
-      types_to_merge.push_back(source_type);
-    }
-  }
-  return types_to_merge;
-}
-
-const Type* TypeInferenceVisitor::MergeTypes(std::vector<const Type*>& types) const {
-  const Type* type = NULL;
-  if (types.size() > 0) {
-    type = *(types.begin());
-    if (types.size() > 1) {
-      for (std::vector<const Type*>::const_iterator cit = types.begin();
-          cit != types.end(); cit++) {
-        if (!type->Equals(**cit)) {
-          type = MergeTypes(type, *cit);
-        }
-      }
-    }
-  }
-  return type;
-}
-
-const Type* TypeInferenceVisitor::MergeTypes(const Type* t1, const Type* t2) const {
-  DCHECK(t2 != NULL);
-  DCHECK(t1 != NULL);
-  art::ScopedObjectAccess soa(art::Thread::Current());
-  const Type* result = &(t1->Merge(*t2, type_cache_));
-  return result;
-}
-
-}   // namespace sea_ir
diff --git a/compiler/sea_ir/types/type_inference_visitor.h b/compiler/sea_ir/types/type_inference_visitor.h
deleted file mode 100644
index d715151..0000000
--- a/compiler/sea_ir/types/type_inference_visitor.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 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_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_VISITOR_H_
-#define ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_VISITOR_H_
-
-
-#include "dex_file-inl.h"
-#include "sea_ir/ir/visitor.h"
-#include "sea_ir/types/types.h"
-
-namespace sea_ir {
-
-// The TypeInferenceVisitor visits each instruction and computes its type taking into account
-//   the current type of the operands. The type is stored in the visitor.
-// We may be better off by using a separate visitor type hierarchy that has return values
-//   or that passes data as parameters, than to use fields to store information that should
-//   in fact be returned after visiting each element. Ideally, I would prefer to use templates
-//   to specify the returned value type, but I am not aware of a possible implementation
-//   that does not horribly duplicate the visitor infrastructure code (version 1: no return value,
-//   version 2: with template return value).
-class TypeInferenceVisitor: public IRVisitor {
- public:
-  TypeInferenceVisitor(SeaGraph* graph, TypeData* type_data,
-      art::verifier::RegTypeCache* types):
-    graph_(graph), type_data_(type_data), type_cache_(types), crt_type_() {
-  }
-  // There are no type related actions to be performed on these classes.
-  void Initialize(SeaGraph* graph) { }
-  void Visit(SeaGraph* graph);
-  void Visit(Region* region) { }
-
-  void Visit(PhiInstructionNode* instruction);
-  void Visit(SignatureNode* parameter);
-  void Visit(InstructionNode* instruction) { }
-  void Visit(UnnamedConstInstructionNode* instruction);
-  void Visit(ConstInstructionNode* instruction) { }
-  void Visit(ReturnInstructionNode* instruction) { }
-  void Visit(IfNeInstructionNode* instruction) { }
-  void Visit(MoveResultInstructionNode* instruction);
-  void Visit(InvokeStaticInstructionNode* instruction);
-  void Visit(AddIntInstructionNode* instruction);
-  void Visit(GotoInstructionNode* instruction) { }
-  void Visit(IfEqzInstructionNode* instruction) { }
-
-  const Type* MergeTypes(std::vector<const Type*>& types) const;
-  const Type* MergeTypes(const Type* t1, const Type* t2) const;
-  std::vector<const Type*> GetOperandTypes(InstructionNode* instruction) const;
-  const Type* GetType() {
-    // TODO: Currently multiple defined types are not supported.
-    if (!crt_type_.empty()) {
-      const Type* single_type = crt_type_.at(0);
-      crt_type_.clear();
-      return single_type;
-    }
-    return NULL;
-  }
-
- protected:
-  const SeaGraph* const graph_;
-  TypeData* type_data_;
-  art::verifier::RegTypeCache* type_cache_;
-  std::vector<const Type*> crt_type_;             // Stored temporarily between two calls to Visit.
-};
-
-}  // namespace sea_ir
-
-#endif  // ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_VISITOR_H_
diff --git a/compiler/sea_ir/types/type_inference_visitor_test.cc b/compiler/sea_ir/types/type_inference_visitor_test.cc
deleted file mode 100644
index ccb6991..0000000
--- a/compiler/sea_ir/types/type_inference_visitor_test.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2013 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 "common_compiler_test.h"
-#include "sea_ir/types/type_inference_visitor.h"
-#include "sea_ir/ir/sea.h"
-
-namespace sea_ir {
-
-class TestInstructionNode:public InstructionNode {
- public:
-  explicit TestInstructionNode(std::vector<InstructionNode*> prods): InstructionNode(NULL),
-      producers_(prods) { }
-  std::vector<InstructionNode*> GetSSAProducers() {
-    return producers_;
-  }
- protected:
-  std::vector<InstructionNode*> producers_;
-};
-
-class TypeInferenceVisitorTest : public art::CommonCompilerTest {};
-
-TEST_F(TypeInferenceVisitorTest, MergeIntWithByte) {
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  TypeInferenceVisitor tiv(NULL, &td, &type_cache);
-  const Type* int_type = &type_cache.Integer();
-  const Type* byte_type = &type_cache.Byte();
-  const Type* ib_type = tiv.MergeTypes(int_type, byte_type);
-  const Type* bi_type = tiv.MergeTypes(byte_type, int_type);
-  EXPECT_TRUE(ib_type == int_type);
-  EXPECT_TRUE(bi_type == int_type);
-}
-
-TEST_F(TypeInferenceVisitorTest, MergeIntWithShort) {
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  TypeInferenceVisitor tiv(NULL, &td, &type_cache);
-  const Type* int_type = &type_cache.Integer();
-  const Type* short_type = &type_cache.Short();
-  const Type* is_type = tiv.MergeTypes(int_type, short_type);
-  const Type* si_type = tiv.MergeTypes(short_type, int_type);
-  EXPECT_TRUE(is_type == int_type);
-  EXPECT_TRUE(si_type == int_type);
-}
-
-TEST_F(TypeInferenceVisitorTest, MergeMultipleInts) {
-  int N = 10;  // Number of types to merge.
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  TypeInferenceVisitor tiv(NULL, &td, &type_cache);
-  std::vector<const Type*> types;
-  for (int i = 0; i < N; i++) {
-    const Type* new_type = &type_cache.Integer();
-    types.push_back(new_type);
-  }
-  const Type* merged_type = tiv.MergeTypes(types);
-  EXPECT_TRUE(merged_type == &type_cache.Integer());
-}
-
-TEST_F(TypeInferenceVisitorTest, MergeMultipleShorts) {
-  int N = 10;  // Number of types to merge.
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  TypeInferenceVisitor tiv(NULL, &td, &type_cache);
-  std::vector<const Type*> types;
-  for (int i = 0; i < N; i++) {
-    const Type* new_type = &type_cache.Short();
-    types.push_back(new_type);
-  }
-  const Type* merged_type = tiv.MergeTypes(types);
-  EXPECT_TRUE(merged_type == &type_cache.Short());
-}
-
-TEST_F(TypeInferenceVisitorTest, MergeMultipleIntsWithShorts) {
-  int N = 10;  // Number of types to merge.
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  TypeInferenceVisitor tiv(NULL, &td, &type_cache);
-  std::vector<const Type*> types;
-  for (int i = 0; i < N; i++) {
-    const Type* short_type = &type_cache.Short();
-    const Type* int_type = &type_cache.Integer();
-    types.push_back(short_type);
-    types.push_back(int_type);
-  }
-  const Type* merged_type = tiv.MergeTypes(types);
-  EXPECT_TRUE(merged_type == &type_cache.Integer());
-}
-
-TEST_F(TypeInferenceVisitorTest, GetOperandTypes) {
-  int N = 10;  // Number of types to merge.
-  TypeData td;
-  art::verifier::RegTypeCache type_cache(false);
-  TypeInferenceVisitor tiv(NULL, &td, &type_cache);
-  std::vector<const Type*> types;
-  std::vector<InstructionNode*> preds;
-  for (int i = 0; i < N; i++) {
-    const Type* short_type = &type_cache.Short();
-    const Type* int_type = &type_cache.Integer();
-    TestInstructionNode* short_inst =
-        new TestInstructionNode(std::vector<InstructionNode*>());
-    TestInstructionNode* int_inst =
-        new TestInstructionNode(std::vector<InstructionNode*>());
-    preds.push_back(short_inst);
-    preds.push_back(int_inst);
-    td.SetTypeOf(short_inst->Id(), short_type);
-    td.SetTypeOf(int_inst->Id(), int_type);
-    types.push_back(short_type);
-    types.push_back(int_type);
-  }
-  TestInstructionNode* inst_to_test = new TestInstructionNode(preds);
-  std::vector<const Type*> result = tiv.GetOperandTypes(inst_to_test);
-  EXPECT_TRUE(result.size() == types.size());
-  EXPECT_TRUE(true == std::equal(types.begin(), types.begin() + 2, result.begin()));
-}
-
-
-}  // namespace sea_ir
diff --git a/compiler/sea_ir/types/types.h b/compiler/sea_ir/types/types.h
deleted file mode 100644
index 64f2524..0000000
--- a/compiler/sea_ir/types/types.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 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_COMPILER_SEA_IR_TYPES_TYPES_H_
-#define ART_COMPILER_SEA_IR_TYPES_TYPES_H_
-
-#include "safe_map.h"
-#include "verifier/reg_type.h"
-#include "verifier/reg_type_cache.h"
-
-namespace sea_ir {
-
-// TODO: Replace typedef with an actual class implementation when we have more types.
-typedef art::verifier::RegType Type;
-
-// Stores information about the result type of each instruction.
-// Note: Main purpose is to encapsulate the map<instruction id, type*>,
-//       so that we can replace the underlying storage at any time.
-class TypeData {
- public:
-  art::SafeMap<int, const Type*>* GetTypeMap() {
-    return &type_map_;
-  }
-  // Returns the type associated with instruction with @instruction_id.
-  const Type* FindTypeOf(int instruction_id) {
-    art::SafeMap<int, const Type*>::const_iterator result_it = type_map_.find(instruction_id);
-    if (type_map_.end() != result_it) {
-      return result_it->second;
-    }
-    return NULL;
-  }
-
-  // Saves the fact that instruction @instruction_id produces a value of type @type.
-  void SetTypeOf(int instruction_id, const Type* type) {
-    type_map_.Overwrite(instruction_id, type);
-  }
-
- private:
-  art::SafeMap<int, const Type*> type_map_;
-};
-
-
-
-}  // namespace sea_ir
-#endif  // ART_COMPILER_SEA_IR_TYPES_TYPES_H_
diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc
index cb07ffa..385d134 100644
--- a/compiler/trampolines/trampoline_compiler.cc
+++ b/compiler/trampolines/trampoline_compiler.cc
@@ -40,8 +40,7 @@
       __ LoadFromOffset(kLoadWord, IP, R0, JNIEnvExt::SelfOffset().Int32Value());
       __ LoadFromOffset(kLoadWord, PC, IP, offset.Int32Value());
       break;
-    case kPortableAbi:  // R9 holds Thread*.
-    case kQuickAbi:  // Fall-through.
+    case kQuickAbi:  // R9 holds Thread*.
       __ LoadFromOffset(kLoadWord, PC, R9, offset.Int32Value());
   }
   __ bkpt(0);
@@ -75,8 +74,7 @@
                 Arm64ManagedRegister::FromXRegister(IP0));
 
       break;
-    case kPortableAbi:  // X18 holds Thread*.
-    case kQuickAbi:  // Fall-through.
+    case kQuickAbi:  // X18 holds Thread*.
       __ JumpTo(Arm64ManagedRegister::FromXRegister(TR), Offset(offset.Int32Value()),
                 Arm64ManagedRegister::FromXRegister(IP0));
 
@@ -106,8 +104,7 @@
       __ LoadFromOffset(kLoadWord, T9, A0, JNIEnvExt::SelfOffset().Int32Value());
       __ LoadFromOffset(kLoadWord, T9, T9, offset.Int32Value());
       break;
-    case kPortableAbi:  // S1 holds Thread*.
-    case kQuickAbi:  // Fall-through.
+    case kQuickAbi:  // S1 holds Thread*.
       __ LoadFromOffset(kLoadWord, T9, S1, offset.Int32Value());
   }
   __ Jr(T9);
diff --git a/compiler/utils/scoped_hashtable.h b/compiler/utils/scoped_hashtable.h
deleted file mode 100644
index bf8dd1f..0000000
--- a/compiler/utils/scoped_hashtable.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2013 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 <stddef.h>
-#include <map>
-#include <list>
-
-#ifndef ART_COMPILER_UTILS_SCOPED_HASHTABLE_H_
-#define ART_COMPILER_UTILS_SCOPED_HASHTABLE_H_
-
-namespace utils {
-template <typename K, typename V>
-class ScopedHashtable {
- public:
-  explicit ScopedHashtable():scopes() {
-  }
-
-  void OpenScope() {
-    scopes.push_front(std::map<K, V>());
-  }
-
-  // Lookups entry K starting from the current (topmost) scope
-  // and returns its value if found or NULL.
-  V Lookup(K k) const {
-    for (typename std::list<std::map<K, V>>::const_iterator scopes_it = scopes.begin();
-        scopes_it != scopes.end(); scopes_it++) {
-      typename std::map<K, V>::const_iterator result_it = (*scopes_it).find(k);
-      if (result_it != (*scopes_it).end()) {
-        return (*result_it).second;
-      }
-    }
-    return NULL;
-  }
-
-  // Adds a new entry in the current (topmost) scope.
-  void Add(K k, V v) {
-    scopes.front().erase(k);
-    scopes.front().insert(std::pair< K, V >(k, v));
-  }
-
-  // Removes the topmost scope.
-  bool CloseScope() {
-    // Added check to uniformly handle undefined behavior
-    // when removing scope and the list of scopes is empty.
-    if (scopes.size() > 0) {
-      scopes.pop_front();
-      return true;
-    }
-    return false;
-  }
-
- private:
-  std::list<std::map<K, V>> scopes;
-};
-}  // namespace utils
-
-#endif  // ART_COMPILER_UTILS_SCOPED_HASHTABLE_H_
diff --git a/compiler/utils/scoped_hashtable_test.cc b/compiler/utils/scoped_hashtable_test.cc
deleted file mode 100644
index 1c843eb..0000000
--- a/compiler/utils/scoped_hashtable_test.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013 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 "scoped_hashtable.h"
-
-#include "common_runtime_test.h"
-
-using utils::ScopedHashtable;
-
-namespace art {
-
-class Value {
- public:
-  explicit Value(int v):value_(v) {}
-  int value_;
-};
-
-class ScopedHashtableTest : public testing::Test {};
-
-TEST_F(ScopedHashtableTest, Basics) {
-  ScopedHashtable<int, Value*> sht;
-  // Check table is empty when no scope is open.
-  EXPECT_TRUE(NULL == sht.Lookup(1));
-
-  // Check table is empty when scope open.
-  sht.OpenScope();
-  EXPECT_TRUE(NULL == sht.Lookup(1));
-  // Check table is empty after closing scope.
-  EXPECT_EQ(sht.CloseScope(), true);
-  // Check closing scope on empty table is no-op.
-  EXPECT_EQ(sht.CloseScope(), false);
-  // Check that find in current scope works.
-  sht.OpenScope();
-  sht.Add(1, new Value(1));
-  EXPECT_EQ(sht.Lookup(1)->value_, 1);
-  // Check that updating values in current scope works.
-  sht.Add(1, new Value(2));
-  EXPECT_EQ(sht.Lookup(1)->value_, 2);
-  // Check that find works in previous scope.
-  sht.OpenScope();
-  EXPECT_EQ(sht.Lookup(1)->value_, 2);
-  // Check that shadowing scopes works.
-  sht.Add(1, new Value(3));
-  EXPECT_EQ(sht.Lookup(1)->value_, 3);
-  // Check that having multiple keys work correctly.
-  sht.Add(2, new Value(4));
-  EXPECT_EQ(sht.Lookup(1)->value_, 3);
-  EXPECT_EQ(sht.Lookup(2)->value_, 4);
-  // Check that scope removal works corectly.
-  sht.CloseScope();
-  EXPECT_EQ(sht.Lookup(1)->value_, 2);
-  EXPECT_TRUE(NULL == sht.Lookup(2));
-}
-
-}  // namespace art
