diff --git a/src/greenland/arm/arm_codegen_machine.cc b/src/greenland/arm/arm_codegen_machine.cc
deleted file mode 100644
index c85aeed..0000000
--- a/src/greenland/arm/arm_codegen_machine.cc
+++ /dev/null
@@ -1,36 +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 "arm_codegen_machine.h"
-
-#include "greenland/target_registry.h"
-
-namespace art {
-namespace greenland {
-
-ARMCodeGenMachine::ARMCodeGenMachine() : TargetCodeGenMachine() {
-}
-
-ARMCodeGenMachine::~ARMCodeGenMachine() {
-}
-
-void InitializeARMCodeGenMachine() {
-  RegisterTargetCodeGenMachine<ARMCodeGenMachine> X(kArm);
-  RegisterTargetCodeGenMachine<ARMCodeGenMachine> Y(kThumb2);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/arm/arm_codegen_machine.h b/src/greenland/arm/arm_codegen_machine.h
deleted file mode 100644
index 8639417..0000000
--- a/src/greenland/arm/arm_codegen_machine.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_ARM_CODEGEN_MACHINE_H_
-#define ART_SRC_GREENLAND_ARM_CODEGEN_MACHINE_H_
-
-#include "greenland/target_codegen_machine.h"
-
-namespace art {
-namespace greenland {
-
-class ARMCodeGenMachine : public TargetCodeGenMachine {
- private:
-
- public:
-  ARMCodeGenMachine();
-  virtual ~ARMCodeGenMachine();
-
-  virtual TargetLIREmitter* CreateLIREmitter() {
-    return NULL;
-  }
-
-  virtual const TargetDataLayout* GetDataLayout() const {
-    return NULL;
-  }
-
-  virtual const TargetLIRInfo* GetLIRInfo() const {
-    return NULL;
-  }
-
-  virtual const TargetRegisterInfo* GetRegisterInfo() const {
-    return NULL;
-  }
-
-  virtual const char* GetConditionCodeName(unsigned cond) const {
-    return NULL;
-  }
-
-  virtual TargetLIRBuilder* CreateLIRBuilder() {
-    return NULL;
-  }
-
-  virtual RegisterAllocator* GetRegisterAllocator() {
-    return NULL;
-  }
-
-  virtual TargetAssembler* GetAssembler() {
-    return NULL;
-  }
-
-  virtual std::string PrettyTargeteLIR(const LIR& lir) const {
-    return "";
-  }
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_ARM_CODEGEN_MACHINE_H_
diff --git a/src/greenland/arm/arm_invoke_stub_compiler.cc b/src/greenland/arm/arm_invoke_stub_compiler.cc
deleted file mode 100644
index 2360ed7..0000000
--- a/src/greenland/arm/arm_invoke_stub_compiler.cc
+++ /dev/null
@@ -1,184 +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 "asm_support.h"
-#include "compiled_method.h"
-#include "compiler.h"
-#include "greenland/target_registry.h"
-#include "oat/utils/arm/assembler_arm.h"
-#include "oat/utils/assembler.h"
-#include "object.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-
-using namespace art;
-using namespace art::arm;
-
-namespace {
-
-// Creates a function which invokes a managed method with an array of
-// arguments.
-//
-// At the time of call, the environment looks something like this:
-//
-// R0 = method pointer
-// R1 = receiver pointer or NULL for static methods
-// R2 = (managed) thread pointer
-// R3 = argument array or NULL for no argument methods
-// [SP] = JValue* result or NULL for void returns
-//
-// As the JNI call has already transitioned the thread into the
-// "running" state the remaining responsibilities of this routine are
-// to save the native register value and restore the managed thread
-// register and transfer arguments from the array into register and on
-// the stack, if needed.  On return, the thread register must be
-// shuffled and the return value must be store into the result JValue.
-CompiledInvokeStub* CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len) {
-  UniquePtr<ArmAssembler> assembler(down_cast<ArmAssembler*>(Assembler::Create(kArm)));
-#define __ assembler->
-  size_t num_arg_array_bytes = NumArgArrayBytes(shorty, shorty_len);
-  // Size of frame = spill of R4,R9/LR + Method* + possible receiver + arg array size
-  // Note, space is left in the frame to flush arguments in registers back to out locations.
-  size_t unpadded_frame_size = (4 * kPointerSize) +
-                               (is_static ? 0 : kPointerSize) +
-                               num_arg_array_bytes;
-  size_t frame_size = RoundUp(unpadded_frame_size, kStackAlignment);
-
-  // Spill R4,R9 and LR
-  RegList save = (1 << R9) | (1 << R4);
-  __ PushList(save | (1 << LR));
-
-  // Move the managed thread pointer into R9.
-  __ mov(R9, ShifterOperand(R2));
-
-  // Reset R4 to suspend check interval
-  __ LoadImmediate(R4, SUSPEND_CHECK_INTERVAL);
-
-  // Move frame down for arguments less 3 pushed values above
-  __ AddConstant(SP, -frame_size + (3 * kPointerSize));
-
-  // Can either get 3 or 2 arguments into registers
-  size_t reg_bytes = (is_static ? 3 : 2) * kPointerSize;
-  // Bytes passed by stack
-  size_t stack_bytes;
-  if (num_arg_array_bytes > reg_bytes) {
-    stack_bytes = num_arg_array_bytes - reg_bytes;
-  } else {
-    stack_bytes = 0;
-    reg_bytes = num_arg_array_bytes;
-  }
-
-  // Method* at bottom of frame is null thereby terminating managed stack crawls
-  __ LoadImmediate(IP, 0, AL);
-  __ StoreToOffset(kStoreWord, IP, SP, 0);
-
-  // Copy values onto the stack.
-  size_t src_offset = 0;
-  size_t dst_offset = (is_static ? 1 : 2) * kPointerSize;
-  for (size_t i = 1; i < shorty_len; ++i) {
-    switch (shorty[i]) {
-      case 'D':
-      case 'J':
-        // Move both pointers 64 bits.
-        __ LoadFromOffset(kLoadWord, IP, R3, src_offset);
-        src_offset += kPointerSize;
-        __ StoreToOffset(kStoreWord, IP, SP, dst_offset);
-        dst_offset += kPointerSize;
-
-        __ LoadFromOffset(kLoadWord, IP, R3, src_offset);
-        src_offset += kPointerSize;
-        __ StoreToOffset(kStoreWord, IP, SP, dst_offset);
-        dst_offset += kPointerSize;
-        break;
-      default:
-        // Move the source pointer sizeof(JValue) and the destination pointer 32 bits.
-        __ LoadFromOffset(kLoadWord, IP, R3, src_offset);
-        src_offset += sizeof(JValue);
-        __ StoreToOffset(kStoreWord, IP, SP, dst_offset);
-        dst_offset += kPointerSize;
-        break;
-    }
-  }
-
-  // Move all the register arguments into place.
-  dst_offset = (is_static ? 1 : 2) * kPointerSize;
-  if (is_static) {
-    if (reg_bytes > 0 && num_arg_array_bytes > 0) {
-      __ LoadFromOffset(kLoadWord, R1, SP, dst_offset + 0);
-      if (reg_bytes > 4 && num_arg_array_bytes > 4) {
-        __ LoadFromOffset(kLoadWord, R2, SP, dst_offset + 4);
-        if (reg_bytes > 8 && num_arg_array_bytes > 8) {
-          __ LoadFromOffset(kLoadWord, R3, SP, dst_offset + 8);
-        }
-      }
-    }
-  } else {
-    if (reg_bytes > 0 && num_arg_array_bytes > 0) {
-      __ LoadFromOffset(kLoadWord, R2, SP, dst_offset + 0);
-      if (reg_bytes > 4 && num_arg_array_bytes > 4) {
-        __ LoadFromOffset(kLoadWord, R3, SP, dst_offset + 4);
-      }
-    }
-  }
-
-  // Load the code pointer we are about to call.
-  __ LoadFromOffset(kLoadWord, IP, R0, AbstractMethod::GetCodeOffset().Int32Value());
-
-  // Do the call.
-  __ blx(IP);
-
-  // If the method returns a value, store it to the result pointer.
-  if (shorty[0] != 'V') {
-    // Load the result JValue pointer of the stub caller's out args.
-    __ LoadFromOffset(kLoadWord, IP, SP, frame_size);
-    StoreOperandType type = (shorty[0] == 'J' || shorty[0] == 'D') ? kStoreWordPair : kStoreWord;
-    __ StoreToOffset(type, R0, IP, 0);
-  }
-
-  // Remove the frame less the spilled R4, R9 and LR
-  __ AddConstant(SP, frame_size - (3 * kPointerSize));
-
-  // Pop R4, R9 and the LR into PC
-  __ PopList(save | (1 << PC));
-  // TODO: store native_entry in the stub table
-  std::vector<uint8_t> code(assembler->CodeSize());
-  MemoryRegion region(&code[0], code.size());
-  assembler->FinalizeInstructions(region);
-  return new CompiledInvokeStub(code);
-#undef __
-}
-
-CompiledInvokeStub* ARMInvokeStubCompiler(art::Compiler& /*compiler*/,
-                                          bool is_static,
-                                          const char* shorty,
-                                          uint32_t shorty_len) {
-  return CreateInvokeStub(is_static, shorty, shorty_len);
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitializeARMInvokeStubCompiler() {
-  TargetRegistry::RegisterInvokeStubCompiler(kArm, ARMInvokeStubCompiler);
-  TargetRegistry::RegisterInvokeStubCompiler(kThumb2, ARMInvokeStubCompiler);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/dalvik_reg.cc b/src/greenland/dalvik_reg.cc
deleted file mode 100644
index a97a646..0000000
--- a/src/greenland/dalvik_reg.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "dalvik_reg.h"
-
-#include "ir_builder.h"
-#include "dex_lang.h"
-
-namespace art {
-namespace greenland {
-
-//----------------------------------------------------------------------------
-// Dalvik Register
-//----------------------------------------------------------------------------
-
-DalvikReg::DalvikReg(DexLang& dex_lang, unsigned reg_idx)
-: dex_lang_(dex_lang), irb_(dex_lang.GetIRBuilder()),
-  reg_idx_(reg_idx), reg_32_(NULL), reg_64_(NULL), reg_obj_(NULL) {
-}
-
-DalvikReg::~DalvikReg() {
-}
-
-llvm::Type* DalvikReg::GetRegCategoryEquivSizeTy(IRBuilder& irb, RegCategory reg_cat) {
-  switch (reg_cat) {
-  case kRegCat1nr:  return irb.GetJIntTy();
-  case kRegCat2:    return irb.GetJLongTy();
-  case kRegObject:  return irb.GetJObjectTy();
-  default:
-    LOG(FATAL) << "Unknown register category: " << reg_cat;
-    return NULL;
-  }
-}
-
-char DalvikReg::GetRegCategoryNamePrefix(RegCategory reg_cat) {
-  switch (reg_cat) {
-  case kRegCat1nr:  return 'r';
-  case kRegCat2:    return 'w';
-  case kRegObject:  return 'p';
-  default:
-    LOG(FATAL) << "Unknown register category: " << reg_cat;
-    return '\0';
-  }
-}
-
-inline llvm::Value* DalvikReg::RegCat1SExt(llvm::Value* value) {
-  return irb_.CreateSExt(value, irb_.GetJIntTy());
-}
-
-inline llvm::Value* DalvikReg::RegCat1ZExt(llvm::Value* value) {
-  return irb_.CreateZExt(value, irb_.GetJIntTy());
-}
-
-inline llvm::Value* DalvikReg::RegCat1Trunc(llvm::Value* value,
-                                            llvm::Type* ty) {
-  return irb_.CreateTrunc(value, ty);
-}
-
-llvm::Value* DalvikReg::GetValue(JType jty, JTypeSpace space) {
-  DCHECK_NE(jty, kVoid) << "Dalvik register will never be void type";
-
-  llvm::Value* value = NULL;
-  switch (space) {
-  case kReg:
-  case kField:
-    value = irb_.CreateLoad(GetAddr(jty));
-    break;
-
-  case kAccurate:
-  case kArray:
-    switch (jty) {
-    case kVoid:
-      LOG(FATAL) << "Dalvik register with void type has no value";
-      return NULL;
-
-    case kBoolean:
-    case kChar:
-    case kByte:
-    case kShort:
-      // NOTE: In array type space, boolean is truncated from i32 to i8, while
-      // in accurate type space, boolean is truncated from i32 to i1.
-      // For the other cases, array type space is equal to accurate type space.
-      value = RegCat1Trunc(irb_.CreateLoad(GetAddr(jty)),
-                           irb_.GetJType(jty, space));
-      break;
-
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kObject:
-      value = irb_.CreateLoad(GetAddr(jty));
-      break;
-
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-      return NULL;
-    }
-    break;
-
-  default:
-    LOG(FATAL) << "Couldn't GetValue of JType " << jty;
-    return NULL;
-  }
-
-  if (jty == kFloat || jty == kDouble) {
-    value = irb_.CreateBitCast(value, irb_.GetJType(jty, space));
-  }
-  return value;
-}
-
-void DalvikReg::SetValue(JType jty, JTypeSpace space, llvm::Value* value) {
-  DCHECK_NE(jty, kVoid) << "Dalvik register will never be void type";
-
-  if (jty == kFloat || jty == kDouble) {
-    value = irb_.CreateBitCast(value, irb_.GetJType(jty, kReg));
-  }
-
-  switch (space) {
-  case kReg:
-  case kField:
-    irb_.CreateStore(value, GetAddr(jty));
-    return;
-
-  case kAccurate:
-  case kArray:
-    switch (jty) {
-    case kVoid:
-      break;
-
-    case kBoolean:
-    case kChar:
-      // NOTE: In accurate type space, we have to zero extend boolean from
-      // i1 to i32, and char from i16 to i32.  In array type space, we have
-      // to zero extend boolean from i8 to i32, and char from i16 to i32.
-      irb_.CreateStore(RegCat1ZExt(value), GetAddr(jty));
-      break;
-
-    case kByte:
-    case kShort:
-      // NOTE: In accurate type space, we have to signed extend byte from
-      // i8 to i32, and short from i16 to i32.  In array type space, we have
-      // to sign extend byte from i8 to i32, and short from i16 to i32.
-      irb_.CreateStore(RegCat1SExt(value), GetAddr(jty));
-      break;
-
-    case kInt:
-    case kLong:
-    case kFloat:
-    case kDouble:
-    case kObject:
-      irb_.CreateStore(value, GetAddr(jty));
-      break;
-
-    default:
-      LOG(FATAL) << "Unknown java type: " << jty;
-    }
-  }
-}
-
-llvm::Value* DalvikReg::GetAddr(JType jty) {
-  switch (GetRegCategoryFromJType(jty)) {
-  case kRegCat1nr:
-    if (reg_32_ == NULL) {
-      reg_32_ = dex_lang_.AllocateDalvikReg(kRegCat1nr, reg_idx_);
-    }
-    return reg_32_;
-
-  case kRegCat2:
-    if (reg_64_ == NULL) {
-      reg_64_ = dex_lang_.AllocateDalvikReg(kRegCat2, reg_idx_);
-    }
-    return reg_64_;
-
-  case kRegObject:
-    if (reg_obj_ == NULL) {
-      reg_obj_ = dex_lang_.AllocateDalvikReg(kRegObject, reg_idx_);
-    }
-    return reg_obj_;
-
-  default:
-    LOG(FATAL) << "Unexpected register category: "
-               << GetRegCategoryFromJType(jty);
-    return NULL;
-  }
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/dalvik_reg.h b/src/greenland/dalvik_reg.h
deleted file mode 100644
index 83157f3..0000000
--- a/src/greenland/dalvik_reg.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_DALVIK_REG_H_
-#define ART_SRC_GREENLAND_DALVIK_REG_H_
-
-#include "backend_types.h"
-
-#include <stdint.h>
-#include <string>
-
-namespace llvm {
-  class Type;
-  class Value;
-}
-
-namespace art {
-namespace greenland {
-
-class IRBuilder;
-class DexLang;
-
-class DalvikReg {
- public:
-  static llvm::Type* GetRegCategoryEquivSizeTy(IRBuilder& irb, RegCategory reg_cat);
-
-  static char GetRegCategoryNamePrefix(RegCategory reg_cat);
-
-  DalvikReg(DexLang& dex_lang, unsigned reg_idx);
-
-  ~DalvikReg();
-
-  llvm::Value* GetValue(JType jty, JTypeSpace space);
-
-  llvm::Value* GetValue(char shorty, JTypeSpace space) {
-    return GetValue(GetJTypeFromShorty(shorty), space);
-  }
-
-  void SetValue(JType jty, JTypeSpace space, llvm::Value* value);
-
-  void SetValue(char shorty, JTypeSpace space, llvm::Value* value) {
-    return SetValue(GetJTypeFromShorty(shorty), space, value);
-  }
-
- private:
-  llvm::Value* GetAddr(JType jty);
-
-  llvm::Value* RegCat1SExt(llvm::Value* value);
-  llvm::Value* RegCat1ZExt(llvm::Value* value);
-
-  llvm::Value* RegCat1Trunc(llvm::Value* value, llvm::Type* ty);
-
-  DexLang& dex_lang_;
-  IRBuilder& irb_;
-
-  unsigned reg_idx_;
-
-  llvm::Value* reg_32_;
-  llvm::Value* reg_64_;
-  llvm::Value* reg_obj_;
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_DALVIK_REG_H_
diff --git a/src/greenland/dex_lang.cc b/src/greenland/dex_lang.cc
deleted file mode 100644
index f0ecdc6..0000000
--- a/src/greenland/dex_lang.cc
+++ /dev/null
@@ -1,4353 +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_lang.h"
-
-#include "intrinsic_helper.h"
-
-#include "greenland/inferred_reg_category_map.h"
-#include "object.h" // FIXME: include this in oat_compilation_unit.h
-#include "oat_compilation_unit.h"
-#include "stl_util.h"
-#include "stringprintf.h"
-#include "verifier/method_verifier.h"
-
-#include <llvm/Analysis/Passes.h>
-#include <llvm/Analysis/Verifier.h>
-#include <llvm/BasicBlock.h>
-#include <llvm/Function.h>
-#include <llvm/Module.h>
-#include <llvm/PassManager.h>
-#include <llvm/Support/InstIterator.h>
-#include <llvm/Transforms/Scalar.h>
-
-namespace art {
-namespace greenland {
-
-//----------------------------------------------------------------------------
-// DexLang::Context
-//----------------------------------------------------------------------------
-DexLang::Context::Context(llvm::Module& module)
-    : module_(module), intrinsic_helper_(NULL) {
-  // Initalize the DexLang intrinsics
-  intrinsic_helper_ = new IntrinsicHelper(GetLLVMContext(), module_);
-  return;
-}
-
-DexLang::Context::~Context() {
-  delete intrinsic_helper_;
-  return;
-}
-
-//----------------------------------------------------------------------------
-// Constructor, Destructor and APIs
-//----------------------------------------------------------------------------
-DexLang::DexLang(DexLang::Context& context, Compiler& compiler,
-                 OatCompilationUnit& cunit)
-    : dex_lang_ctx_(context), compiler_(compiler), cunit_(cunit),
-      dex_file_(cunit.GetDexFile()), code_item_(cunit.GetCodeItem()),
-      method_idx_(cunit.GetDexMethodIndex()),
-      context_(context.GetLLVMContext()), module_(context.GetOutputModule()),
-      intrinsic_helper_(context.GetIntrinsicHelper()),
-      irb_(context.GetLLVMContext(), context.GetOutputModule(),
-           context.GetIntrinsicHelper()),
-      func_(NULL), reg_alloc_bb_(NULL), arg_reg_init_bb_(NULL),
-      basic_blocks_(cunit.GetCodeItem()->insns_size_in_code_units_),
-      retval_reg_(NULL),
-      num_shadow_frame_entries_(0),
-      reg_to_shadow_frame_index_(code_item_->registers_size_, -1),
-      landing_pads_bb_(cunit.GetCodeItem()->tries_size_, NULL),
-      exception_unwind_bb_(NULL), cur_try_item_offset(-1)
-{
-  if (cunit.GetCodeItem()->tries_size_ > 0) {
-    cur_try_item_offset = 0;
-  }
-  return;
-}
-
-DexLang::~DexLang() {
-  delete retval_reg_;
-  return;
-}
-
-llvm::Function* DexLang::Build() {
-  if (!CreateFunction() ||
-      !EmitPrologue() ||
-      !EmitInstructions() ||
-      !EmitPrologueAllcaShadowFrame() ||
-      !EmitPrologueLinkBasicBlocks() ||
-      !PrettyLayoutExceptionBasicBlocks() ||
-      !VerifyFunction() ||
-      // CompilerLLVM has its own optimizer
-#ifndef ART_USE_LLVM_COMPILER
-      !OptimizeFunction() ||
-      !RemoveRedundantPendingExceptionChecks() ||
-#endif
-      0) {
-    return NULL;
-  }
-
-  return func_;
-}
-
-llvm::Value* DexLang::AllocateDalvikReg(RegCategory cat, unsigned reg_idx) {
-  // Get reg_type and reg_name from DalvikReg
-  llvm::Type* reg_type = DalvikReg::GetRegCategoryEquivSizeTy(irb_, cat);
-  std::string reg_name;
-
-#if !defined(NDEBUG)
-  StringAppendF(&reg_name, "%c%u",
-                DalvikReg::GetRegCategoryNamePrefix(cat), reg_idx);
-#endif
-
-  // Save current IR builder insert point
-  DCHECK(reg_alloc_bb_ != NULL);
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  irb_.SetInsertPoint(reg_alloc_bb_);
-
-  // Alloca
-  llvm::Value* reg_addr = irb_.CreateAlloca(reg_type, 0, reg_name);
-
-  // Restore IRBuilder insert point
-  irb_.restoreIP(irb_ip_original);
-
-  DCHECK_NE(reg_addr, static_cast<llvm::Value*>(NULL));
-  return reg_addr;
-}
-
-//----------------------------------------------------------------------------
-// Basic Block Helper Functions
-//----------------------------------------------------------------------------
-llvm::BasicBlock* DexLang::GetBasicBlock(unsigned dex_pc) {
-  DCHECK(dex_pc < code_item_->insns_size_in_code_units_);
-
-  llvm::BasicBlock* basic_block = basic_blocks_[dex_pc];
-
-  if (!basic_block) {
-    basic_block = CreateBasicBlockWithDexPC(dex_pc);
-    basic_blocks_[dex_pc] = basic_block;
-  }
-
-  return basic_block;
-}
-
-llvm::BasicBlock* DexLang::CreateBasicBlockWithDexPC(unsigned dex_pc,
-                                                     const char* postfix) {
-  std::string name;
-
-  if (postfix) {
-    StringAppendF(&name, "B%04x.%s", dex_pc, postfix);
-  } else {
-    StringAppendF(&name, "B%04x", dex_pc);
-  }
-
-  return llvm::BasicBlock::Create(context_, name, func_);
-}
-
-llvm::BasicBlock* DexLang::GetNextBasicBlock(unsigned dex_pc) {
-  const Instruction* insn = Instruction::At(code_item_->insns_ + dex_pc);
-  return GetBasicBlock(dex_pc + insn->SizeInCodeUnits());
-}
-
-//----------------------------------------------------------------------------
-// Exception Handling
-//----------------------------------------------------------------------------
-int32_t DexLang::GetTryItemOffset(unsigned dex_pc) {
-  if (cur_try_item_offset >= 0) {
-    // Search over the try item.
-    do {
-      const DexFile::TryItem* ti =
-          DexFile::GetTryItems(*code_item_, cur_try_item_offset);
-      if (dex_pc < ti->start_addr_) {
-        return -1;
-      }
-
-      if (dex_pc < (ti->start_addr_ + ti->insn_count_)) {
-        return cur_try_item_offset;
-      }
-
-      cur_try_item_offset++;
-    } while (cur_try_item_offset < code_item_->tries_size_);
-
-    // Search to the end of try items and Cannot find any try item corresponding
-    // to the dex_pc.
-    cur_try_item_offset = -1;
-  }
-
-  return cur_try_item_offset;
-}
-
-llvm::BasicBlock* DexLang::GetLandingPadBasicBlock(unsigned 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(landing_pads_bb_.size(), static_cast<size_t>(ti_offset));
-  llvm::BasicBlock* block_lpad = landing_pads_bb_[ti_offset];
-
-  if (block_lpad != NULL) {
-    // We have generated landing pad for this try item already.  Return the
-    // same basic block.
-    return block_lpad;
-  }
-
-  // Get try item from code item
-  const DexFile::TryItem* ti = DexFile::GetTryItems(*code_item_, ti_offset);
-
-  std::string lpadname;
-
-#ifndef NDEBUG
-  StringAppendF(&lpadname, "lpad%d_%04x_to_%04x",
-                ti_offset, ti->start_addr_, ti->handler_off_);
-#endif
-
-  // Create landing pad basic block
-  block_lpad = llvm::BasicBlock::Create(context_, lpadname, func_);
-
-  // Change IRBuilder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  irb_.SetInsertPoint(block_lpad);
-
-  // Find catch block with matching type
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  // Find catch block with matching type
-  llvm::Value* ti_offset_value = irb_.getInt32(ti_offset);
-
-  llvm::Value* catch_handler_index_value =
-      EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::FindCatchBlock,
-                                  method_object_addr, ti_offset_value);
-
-  // Switch instruction (Go to unwind basic block by default)
-  llvm::SwitchInst* sw =
-      irb_.CreateSwitch(catch_handler_index_value, GetUnwindBasicBlock());
-
-  // Cases with matched catch block
-  CatchHandlerIterator iter(*code_item_, ti->start_addr_);
-
-  for (uint32_t c = 0; iter.HasNext(); iter.Next(), ++c) {
-    sw->addCase(irb_.getInt32(c), GetBasicBlock(iter.GetHandlerAddress()));
-  }
-
-  // Restore the orignal insert point for IRBuilder
-  irb_.restoreIP(irb_ip_original);
-
-  // Cache this landing pad
-  landing_pads_bb_[ti_offset] = block_lpad;
-
-  return block_lpad;
-}
-
-llvm::BasicBlock* DexLang::GetUnwindBasicBlock() {
-  // Check the existing unwinding baisc block block
-  if (exception_unwind_bb_ != NULL) {
-    return exception_unwind_bb_;
-  }
-
-  // Create new basic block for unwinding
-  exception_unwind_bb_ =
-      llvm::BasicBlock::Create(context_, "exception_unwind", func_);
-
-  // Change IRBuilder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-  irb_.SetInsertPoint(exception_unwind_bb_);
-
-  // Pop the shadow frame
-  EmitPopShadowFrame();
-
-  // Emit the code to return default value (zero) for the given return type.
-  char ret_shorty = cunit_.GetShorty()[0];
-  if (ret_shorty == 'V') {
-    irb_.CreateRetVoid();
-  } else {
-    irb_.CreateRet(irb_.GetJZero(ret_shorty));
-  }
-
-  // Restore the orignal insert point for IRBuilder
-  irb_.restoreIP(irb_ip_original);
-
-  return exception_unwind_bb_;
-}
-
-void DexLang::EmitBranchExceptionLandingPad(unsigned dex_pc) {
-  if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) {
-    irb_.CreateBr(lpad);
-  } else {
-    irb_.CreateBr(GetUnwindBasicBlock());
-  }
-}
-
-void DexLang::EmitGuard_DivZeroException(unsigned 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);
-
-  irb_.SetInsertPoint(block_exception);
-  EmitInvokeIntrinsic(dex_pc, false, IntrinsicHelper::ThrowDivZeroException);
-
-  irb_.SetInsertPoint(block_continue);
-  return;
-}
-
-void DexLang::EmitGuard_NullPointerException(unsigned dex_pc,
-                                             llvm::Value* object) {
-  llvm::Value* equal_null = irb_.CreateICmpEQ(object, irb_.GetJNull());
-
-  llvm::BasicBlock* block_exception =
-    CreateBasicBlockWithDexPC(dex_pc, "nullp");
-
-  llvm::BasicBlock* block_continue =
-    CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  irb_.CreateCondBr(equal_null, block_exception, block_continue);
-
-  irb_.SetInsertPoint(block_exception);
-
-  EmitInvokeIntrinsic(dex_pc, false, IntrinsicHelper::ThrowNullPointerException,
-                      irb_.getInt32(dex_pc));
-
-  irb_.SetInsertPoint(block_continue);
-  return;
-}
-
-void
-DexLang::EmitGuard_ArrayIndexOutOfBoundsException(unsigned dex_pc,
-                                                  llvm::Value* array,
-                                                  llvm::Value* index) {
-  llvm::Value* array_len = EmitLoadArrayLength(array);
-
-  llvm::Value* cmp = irb_.CreateICmpUGE(index, array_len);
-
-  llvm::BasicBlock* block_exception =
-    CreateBasicBlockWithDexPC(dex_pc, "overflow");
-
-  llvm::BasicBlock* block_continue =
-    CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  irb_.CreateCondBr(cmp, block_exception, block_continue);
-
-  irb_.SetInsertPoint(block_exception);
-
-  EmitInvokeIntrinsic2(dex_pc, false, IntrinsicHelper::ThrowIndexOutOfBounds,
-                       index, array_len);
-
-  irb_.SetInsertPoint(block_continue);
-  return;
-}
-
-void DexLang::EmitGuard_ArrayException(unsigned dex_pc,
-                                       llvm::Value* array, llvm::Value* index) {
-  EmitGuard_NullPointerException(dex_pc, array);
-  EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array, index);
-}
-
-void DexLang::EmitGuard_ExceptionLandingPad(unsigned dex_pc, bool can_skip_unwind) {
-  llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc);
-  Instruction const* insn = Instruction::At(code_item_->insns_ + dex_pc);
-  if (lpad == NULL && can_skip_unwind &&
-      IsInstructionDirectToReturn(dex_pc + insn->SizeInCodeUnits())) {
-    return;
-  }
-
-  llvm::Value* exception_pending =
-      EmitInvokeIntrinsicNoThrow(IntrinsicHelper::IsExceptionPending);
-
-  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  if (lpad) {
-    irb_.CreateCondBr(exception_pending, lpad, block_cont);
-  } else {
-    irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont);
-  }
-
-  irb_.SetInsertPoint(block_cont);
-  return;
-}
-
-//----------------------------------------------------------------------------
-// Garbage Collection Safe Point
-//----------------------------------------------------------------------------
-void DexLang::EmitGuard_GarbageCollectionSuspend() {
-  if (!method_info_.has_invoke) {
-    return;
-  }
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-  EmitInvokeIntrinsicNoThrow(IntrinsicHelper::TestSuspend, thread_object_addr);
-  return;
-}
-
-//----------------------------------------------------------------------------
-// Register Helper Functions
-//----------------------------------------------------------------------------
-llvm::Value* DexLang::EmitLoadDalvikReg(unsigned reg_idx, JType jty, JTypeSpace space) {
-  return regs_[reg_idx]->GetValue(jty, space);
-}
-
-llvm::Value* DexLang::EmitLoadDalvikReg(unsigned reg_idx, char shorty, JTypeSpace space) {
-  return EmitLoadDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space);
-}
-
-void DexLang::EmitStoreDalvikReg(unsigned reg_idx, JType jty,
-                                 JTypeSpace space, llvm::Value* new_value) {
-  regs_[reg_idx]->SetValue(jty, space, new_value);
-  if (jty == kObject && reg_to_shadow_frame_index_[reg_idx] != -1) {
-    EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::SetShadowFrameEntry,
-                                new_value, irb_.getInt32(reg_to_shadow_frame_index_[reg_idx]));
-  }
-}
-
-void DexLang::EmitStoreDalvikReg(unsigned reg_idx, char shorty,
-                                 JTypeSpace space, llvm::Value* new_value) {
-  EmitStoreDalvikReg(reg_idx, GetJTypeFromShorty(shorty), space, new_value);
-}
-
-llvm::Value* DexLang::EmitLoadDalvikRetValReg(JType jty, JTypeSpace space) {
-  return retval_reg_->GetValue(jty, space);
-}
-
-llvm::Value* DexLang::EmitLoadDalvikRetValReg(char shorty, JTypeSpace space) {
-  return EmitLoadDalvikRetValReg(GetJTypeFromShorty(shorty), space);
-}
-
-void DexLang::EmitStoreDalvikRetValReg(JType jty, JTypeSpace space,
-                                              llvm::Value* new_value) {
-  retval_reg_->SetValue(jty, space, new_value);
-}
-
-void DexLang::EmitStoreDalvikRetValReg(char shorty, JTypeSpace space,
-                                              llvm::Value* new_value) {
-  EmitStoreDalvikRetValReg(GetJTypeFromShorty(shorty), space, new_value);
-}
-
-//----------------------------------------------------------------------------
-// Shadow Frame
-//----------------------------------------------------------------------------
-void DexLang::EmitUpdateDexPC(unsigned dex_pc) {
-  if (!method_info_.need_shadow_frame) {
-    return;
-  }
-  EmitInvokeIntrinsicNoThrow(IntrinsicHelper::UpdateDexPC,
-                             irb_.getInt32(dex_pc));
-  return;
-}
-
-void DexLang::EmitPopShadowFrame() {
-  if (!method_info_.need_shadow_frame) {
-    return;
-  }
-  EmitInvokeIntrinsicNoThrow(IntrinsicHelper::PopShadowFrame);
-  return;
-}
-
-//----------------------------------------------------------------------------
-// Code Generation
-//----------------------------------------------------------------------------
-bool DexLang::CreateFunction() {
-  std::string func_name(PrettyMethod(method_idx_, *dex_file_,
-                                     /* with_signature */true));
-  llvm::FunctionType* func_type = GetFunctionType();
-
-  if (func_type == NULL) {
-    return false;
-  }
-
-  func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
-                                 func_name, &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;
-
-  if (!cunit_.IsStatic()) {
-    DCHECK_NE(arg_iter, arg_end);
-    arg_iter->setName("this");
-    ++arg_iter;
-  }
-
-  for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
-    arg_iter->setName(StringPrintf("a%u", i));
-  }
-
-  return true;
-}
-
-llvm::FunctionType* DexLang::GetFunctionType() {
-  uint32_t shorty_size;
-  const char* shorty = cunit_.GetShorty(&shorty_size);
-  CHECK_GE(shorty_size, 1u);
-
-  // Get return type
-  llvm::Type* ret_type = irb_.GetJType(shorty[0], kAccurate);
-
-  // Get argument type
-  std::vector<llvm::Type*> args_type;
-
-  // method object
-  args_type.push_back(irb_.GetJMethodTy());
-
-  if (!cunit_.IsStatic()) {
-    // The first argument to non-static method is "this" object pointer
-    args_type.push_back(irb_.GetJObjectTy());
-  }
-
-  for (uint32_t i = 1; i < shorty_size; ++i) {
-    args_type.push_back(irb_.GetJType(shorty[i], kAccurate));
-  }
-
-  return llvm::FunctionType::get(ret_type, args_type, false);
-}
-
-bool DexLang::EmitPrologue() {
-  reg_alloc_bb_ = llvm::BasicBlock::Create(context_, "prologue.alloca", func_);
-
-  arg_reg_init_bb_ =
-      llvm::BasicBlock::Create(context_, "prologue.arginit", func_);
-
-  ComputeMethodInfo();
-
-  // Create register array
-  const unsigned num_regs = code_item_->registers_size_;
-  for (unsigned i = 0; i < num_regs; i++) {
-    regs_.push_back(new DalvikReg(*this, i));
-  }
-
-  // Register hold return value from invoke and filled-new-array
-  retval_reg_ = new DalvikReg(*this, num_regs);
-
-  // Store argument to dalvik register
-  irb_.SetInsertPoint(arg_reg_init_bb_);
-  // TODO: Don't emit this at init_bb
-  // Garbage collection safe-point
-  EmitGuard_GarbageCollectionSuspend();
-  if (!EmitPrologueAssignArgRegister()) {
-    return false;
-  }
-
-  irb_.CreateBr(GetBasicBlock(0));
-
-  // DalvikReg index to shadow frame index
-  num_shadow_frame_entries_ = 0;
-  uint16_t arg_reg_start = code_item_->registers_size_ - code_item_->ins_size_;
-  if (method_info_.need_shadow_frame_entry) {
-    for (uint32_t i = 0, num_of_regs = code_item_->registers_size_; i < num_of_regs; ++i) {
-      if (i >= arg_reg_start && !method_info_.set_to_another_object[i]) {
-        // If we don't set argument registers to another object, we don't need the shadow frame
-        // entry for it. Because the arguments must have been in the caller's shadow frame.
-        continue;
-      }
-
-      if (IsRegCanBeObject(i)) {
-        reg_to_shadow_frame_index_[i] = num_shadow_frame_entries_++;
-      }
-    }
-  }
-
-  return true;
-}
-
-bool DexLang::EmitPrologueAssignArgRegister() {
-  llvm::Function::arg_iterator arg_iter(func_->arg_begin());
-
-  const unsigned num_regs = code_item_->registers_size_;
-  const unsigned num_ins = code_item_->ins_size_;
-  unsigned reg_idx = num_regs - num_ins;
-
-  uint32_t shorty_size;
-  const char* shorty = cunit_.GetShorty(&shorty_size);
-
-  // skip method object
-  ++arg_iter;
-
-  if (!cunit_.IsStatic()) {
-    // The first argument to non-static method is "this" object pointer.
-    EmitStoreDalvikReg(reg_idx, kObject, kAccurate, arg_iter);
-    arg_iter++;
-    reg_idx++;
-  }
-
-  for (unsigned i = 1; i < shorty_size; i++, arg_iter++) {
-    JType jty = GetJTypeFromShorty(shorty[i]);
-    EmitStoreDalvikReg(reg_idx, jty, kAccurate, arg_iter);
-    reg_idx++;
-
-    if (GetRegCategoryFromJType(jty) == kRegCat2) {
-      // Wide types
-      reg_idx++;
-    }
-  }
-
-  DCHECK_EQ(arg_iter, func_->arg_end());
-  DCHECK_EQ(reg_idx, num_regs);
-
-  return true;
-}
-
-bool DexLang::EmitPrologueAllcaShadowFrame() {
-  if (!method_info_.need_shadow_frame) {
-    return true;
-  }
-
-  // Save current IR builder insert point
-  llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP();
-
-  irb_.SetInsertPoint(reg_alloc_bb_);
-  EmitInvokeIntrinsicNoThrow(IntrinsicHelper::AllocaShadowFrame,
-                             irb_.getInt32(num_shadow_frame_entries_));
-
-  // Restore IRBuilder insert point
-  irb_.restoreIP(irb_ip_original);
-
-  return true;
-}
-
-bool DexLang::EmitPrologueLinkBasicBlocks() {
-  irb_.SetInsertPoint(reg_alloc_bb_);
-  irb_.CreateBr(arg_reg_init_bb_);
-  return true;
-}
-
-bool DexLang::PrettyLayoutExceptionBasicBlocks()  {
-  llvm::BasicBlock* last_non_exception_bb = &func_->back();
-  DCHECK(last_non_exception_bb != NULL);
-
-  if (last_non_exception_bb == exception_unwind_bb_) {
-    // There's no other expcetion landing pads therefore the only exception
-    // basic blocks is for exception unwinding which is already the tail basic
-    // block of the function
-    return true;
-  }
-
-  if (exception_unwind_bb_ != NULL) {
-    exception_unwind_bb_->moveAfter(last_non_exception_bb);
-  }
-
-  for (std::vector<llvm::BasicBlock*>::reverse_iterator
-          landing_pads_bb_iter = landing_pads_bb_.rbegin(),
-          landing_pads_bb_end = landing_pads_bb_.rend();
-       landing_pads_bb_iter != landing_pads_bb_end; landing_pads_bb_iter++) {
-    llvm::BasicBlock* landing_pads_bb = *landing_pads_bb_iter;
-    if (landing_pads_bb == NULL) {
-      continue;
-    }
-
-    // Move the successors (the cache handlers) first
-    llvm::TerminatorInst* inst = landing_pads_bb->getTerminator();
-    CHECK(inst != NULL);
-
-    for (unsigned i = 0, e = inst->getNumSuccessors(); i != e; i++) {
-      llvm::BasicBlock* catch_handler = inst->getSuccessor(i);
-      // One of the catch handler is the unwind basic block which is settled
-      // down earlier
-      if (catch_handler != exception_unwind_bb_) {
-        catch_handler->moveAfter(last_non_exception_bb);
-      }
-    }
-    if (last_non_exception_bb != landing_pads_bb) {
-      landing_pads_bb->moveAfter(last_non_exception_bb);
-    }
-  }
-
-  return true;
-}
-
-bool DexLang::VerifyFunction() {
-  if (llvm::verifyFunction(*func_, llvm::PrintMessageAction)) {
-    LOG(INFO) << "Verification failed on function: "
-              << PrettyMethod(method_idx_, *dex_file_);
-    return false;
-  }
-  return true;
-}
-
-bool DexLang::OptimizeFunction() {
-  // Add optimization pass
-  llvm::FunctionPassManager fpm(&module_);
-
-  fpm.add(llvm::createTypeBasedAliasAnalysisPass());
-  fpm.add(llvm::createBasicAliasAnalysisPass());
-
-  // Perform simple optimizations first to enable the later optimization passes
-  // running fast
-  {
-    fpm.add(llvm::createCFGSimplificationPass());
-
-    // mem2reg
-    fpm.add(llvm::createPromoteMemoryToRegisterPass());
-
-    // Remove redundant instructions
-    fpm.add(llvm::createInstructionSimplifierPass());
-
-    // Fast CSE
-    fpm.add(llvm::createEarlyCSEPass());
-    fpm.add(llvm::createCorrelatedValuePropagationPass());
-
-    // 4 + (x + 5)  ->  x + (4 + 5)
-    fpm.add(llvm::createReassociatePass());
-
-    // Clean up
-    fpm.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
-    fpm.add(llvm::createInstructionCombiningPass());// Clean up after everything
-  }
-
-  {
-    // SCCP - Sparse conditional constant propagation
-    fpm.add(llvm::createSCCPPass());
-
-    // Global value numbering and redundant load elimination
-    fpm.add(llvm::createGVNPass());
-
-    // Clean up
-    fpm.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
-    fpm.add(llvm::createInstructionCombiningPass());// Clean up after everything
-  }
-
-  {
-    // Reorders basic blocks to increase the number of fall-through conditional
-    // branches
-    fpm.add(llvm::createBlockPlacementPass());
-
-    // Clean up
-    fpm.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
-  }
-
-  // DexLang doesn't use static branch prediction in the mean time
-  //fpm.add(llvm::createLowerExpectIntrinsicPass());
-  {
-    // Constant propagation
-    fpm.add(llvm::createConstantPropagationPass());
-
-    // Clean up
-    fpm.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
-    fpm.add(llvm::createInstructionCombiningPass());// Clean up after everything
-  }
-
-  {
-    // Dead code elimination
-    fpm.add(llvm::createDeadCodeEliminationPass());
-    fpm.add(llvm::createDeadStoreEliminationPass());
-    fpm.add(llvm::createAggressiveDCEPass());
-
-    // Do constant propagation again
-    fpm.add(llvm::createConstantPropagationPass());
-
-    // Clean up
-    fpm.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
-    fpm.add(llvm::createInstructionCombiningPass());// Clean up after everything
-  }
-
-  // Run the per-function optimization
-  fpm.doInitialization();
-  fpm.run(*func_);
-  fpm.doFinalization();
-
-  return true;
-}
-
-bool DexLang::RemoveRedundantPendingExceptionChecks() {
-#if 0
-  const llvm::Function* exception_checking_function =
-      irb_.GetIntrinsics(IntrinsicHelper::IsExceptionPending);
-
-  std::vector<llvm::Instruction*> work_list;
-
-  unsigned num_removed = 0;
-
-  for (llvm::inst_iterator i = llvm::inst_begin(func_),
-          e = llvm::inst_end(func_); i != e; ++i) {
-    if (llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(&*i)) {
-      if (call_inst->getCalledFunction() != exception_checking_function) {
-        continue;
-      }
-    }
-  }
-
-  num_removed = work_list.size();
-
-  for (std::vector<llvm::Instruction*>::iterator inst_iter = work_list.begin(),
-          inst_end = work_list.end(); inst_iter != inst_end; inst_iter++) {
-    llvm::Instruction* inst = *inst_iter;
-    if (!inst->use_empty()) {
-      inst->replaceAllUsesWith(irb_.getFalse());
-    }
-    inst->eraseFromParent();
-  }
-
-  LOG(INFO) << num_removed << " redundant pending exception check removed.";
-#endif
-
-  return true;
-}
-
-//----------------------------------------------------------------------------
-// Emit* Helper Functions
-//----------------------------------------------------------------------------
-llvm::Value* DexLang::EmitLoadMethodObjectAddr() {
-  return func_->arg_begin();
-}
-
-llvm::Value* DexLang::EmitGetCurrentThread() {
-  return EmitInvokeIntrinsicNoThrow(IntrinsicHelper::GetCurrentThread);
-}
-
-void DexLang::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) {
-  EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::MarkGCCard, value, target_addr);
-  return;
-}
-
-llvm::Value*
-DexLang::EmitInvokeIntrinsicNoThrow(IntrinsicHelper::IntrinsicId intr_id,
-                                    llvm::ArrayRef<llvm::Value*> args) {
-  DCHECK(IntrinsicHelper::GetAttr(intr_id) & IntrinsicHelper::kAttrNoThrow);
-
-  llvm::Function* intr = intrinsic_helper_.GetIntrinsicFunction(intr_id);
-  return ((args.empty()) ? irb_.CreateCall(intr) : irb_.CreateCall(intr, args));
-}
-
-llvm::Value* DexLang::EmitInvokeIntrinsic(unsigned dex_pc, bool can_skip_unwind,
-                                          IntrinsicHelper::IntrinsicId intr_id,
-                                          llvm::ArrayRef<llvm::Value*> args) {
-  llvm::Function* intr = intrinsic_helper_.GetIntrinsicFunction(intr_id);
-  unsigned intr_attr = IntrinsicHelper::GetAttr(intr_id);
-  DCHECK(!(intr_attr & IntrinsicHelper::kAttrNoThrow));
-
-  // Setup PC before invocation when the intrinsics may generate the exception
-  EmitUpdateDexPC(dex_pc);
-
-  llvm::Value* ret_val = ((args.empty()) ? irb_.CreateCall(intr) :
-                                           irb_.CreateCall(intr, args));
-
-  if (intr_attr & IntrinsicHelper::kAttrDoThrow) {
-    // Directly branch to exception landingpad when the intrinsic is known to
-    // throw exception always
-    EmitBranchExceptionLandingPad(dex_pc);
-  } else {
-    EmitGuard_ExceptionLandingPad(dex_pc, can_skip_unwind);
-  }
-
-  return ret_val;
-}
-
-InferredRegCategoryMap const* DexLang::GetInferredRegCategoryMap() {
-  Compiler::MethodReference mref(dex_file_, method_idx_);
-
-  InferredRegCategoryMap const* map =
-    verifier::MethodVerifier::GetInferredRegCategoryMap(mref);
-
-  CHECK_NE(map, static_cast<InferredRegCategoryMap*>(NULL));
-
-  return map;
-}
-
-RegCategory DexLang::GetInferredRegCategory(unsigned dex_pc,
-                                            unsigned reg_idx) {
-  InferredRegCategoryMap const* map = GetInferredRegCategoryMap();
-
-  return map->GetRegCategory(dex_pc, reg_idx);
-}
-
-bool DexLang::IsRegCanBeObject(unsigned reg_idx) {
-  InferredRegCategoryMap const* map = GetInferredRegCategoryMap();
-
-  return map->IsRegCanBeObject(reg_idx);
-}
-
-llvm::Value* DexLang::EmitLoadConstantClass(unsigned dex_pc,
-                                            uint32_t type_idx) {
-  llvm::Value* type_idx_value = irb_.getInt32(type_idx);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-  if (!compiler_.CanAccessTypeWithoutChecks(method_idx_, *dex_file_, type_idx)) {
-    return EmitInvokeIntrinsic3(dex_pc, false, IntrinsicHelper::InitializeTypeAndVerifyAccess,
-                                type_idx_value, method_object_addr,
-                                thread_object_addr);
-  } else {
-    // Try to load the class (type) object from the dex cache
-    llvm::Value* type_object_addr =
-        EmitInvokeIntrinsicNoThrow(IntrinsicHelper::LoadTypeFromDexCache,
-                                   type_idx_value);
-
-    if (compiler_.CanAssumeTypeIsPresentInDexCache(*dex_file_, type_idx)) {
-      return type_object_addr;
-    }
-
-    llvm::BasicBlock* block_original = irb_.GetInsertBlock();
-
-    // Test whether class (type) object is in the dex cache or not
-    llvm::Value* equal_null =
-        irb_.CreateICmpEQ(type_object_addr, irb_.GetJNull());
-
-    llvm::BasicBlock* block_cont =
-      CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-    llvm::BasicBlock* block_load_class =
-      CreateBasicBlockWithDexPC(dex_pc, "load_class");
-
-    irb_.CreateCondBr(equal_null, block_load_class, block_cont);
-
-    // Failback routine to load the class object
-    irb_.SetInsertPoint(block_load_class);
-
-    llvm::Value* loaded_type_object_addr =
-        EmitInvokeIntrinsic3(dex_pc, false, IntrinsicHelper::InitializeType,
-                             type_idx_value, method_object_addr,
-                             thread_object_addr);
-
-    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* DexLang::EmitLoadArrayLength(llvm::Value* array) {
-  // Load array length
-  return EmitInvokeIntrinsicNoThrow(IntrinsicHelper::ArrayLength, array);
-}
-
-llvm::Value* DexLang::EmitAllocNewArray(unsigned dex_pc, int32_t length,
-                                        uint32_t type_idx,
-                                        bool is_filled_new_array) {
-  bool skip_access_check = compiler_.CanAccessTypeWithoutChecks(method_idx_,
-                                                                *dex_file_,
-                                                                type_idx);
-
-  llvm::Value* array_length_value;
-  IntrinsicHelper::IntrinsicId intrinsic;
-
-  // Select intrinsic and load the array length
-  if (is_filled_new_array) {
-    intrinsic =
-        skip_access_check ? IntrinsicHelper::CheckAndAllocArray :
-                            IntrinsicHelper::CheckAndAllocArrayWithAccessCheck;
-    array_length_value = irb_.getInt32(length);
-  } else {
-    intrinsic =
-        skip_access_check ? IntrinsicHelper::AllocArray :
-                            IntrinsicHelper::AllocArrayWithAccessCheck;
-    array_length_value = EmitLoadDalvikReg(length, kInt, kAccurate);
-  }
-
-  llvm::Constant* type_index_value = irb_.getInt32(type_idx);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-  llvm::Value* array_addr = EmitInvokeIntrinsic4(dex_pc, false, intrinsic,
-                                                 type_index_value,
-                                                 method_object_addr,
-                                                 array_length_value,
-                                                 thread_object_addr);
-
-  return array_addr;
-}
-
-llvm::Value* DexLang::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*
-DexLang::EmitLoadStaticStorage(unsigned dex_pc, unsigned type_idx) {
-  llvm::BasicBlock* block_load_static =
-    CreateBasicBlockWithDexPC(dex_pc, "load_static");
-
-  llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont");
-
-  llvm::Constant* type_idx_value = irb_.getInt32(type_idx);
-
-  // Load static storage from dex cache
-  llvm::Value* storage_object_addr =
-      EmitInvokeIntrinsicNoThrow(IntrinsicHelper::LoadClassSSBFromDexCache,
-                                 type_idx_value);
-
-  llvm::BasicBlock* block_original = irb_.GetInsertBlock();
-
-  // Test: Is the static storage of this class initialized?
-  llvm::Value* equal_null =
-    irb_.CreateICmpEQ(storage_object_addr, irb_.GetJNull());
-
-  irb_.CreateCondBr(equal_null, block_load_static, block_cont);
-
-  // Failback routine to load the class object
-  irb_.SetInsertPoint(block_load_static);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-  llvm::Value* loaded_storage_object_addr =
-      EmitInvokeIntrinsic3(dex_pc, false, IntrinsicHelper::InitializeAndLoadClassSSB,
-                           type_idx_value, method_object_addr,
-                           thread_object_addr);
-
-  llvm::BasicBlock* block_after_load_static = irb_.GetInsertBlock();
-
-  irb_.CreateBr(block_cont);
-
-  // Now the class object must be loaded
-  irb_.SetInsertPoint(block_cont);
-
-  llvm::PHINode* phi = irb_.CreatePHI(irb_.GetJObjectTy(), 2);
-
-  phi->addIncoming(storage_object_addr, block_original);
-  phi->addIncoming(loaded_storage_object_addr, block_after_load_static);
-
-  return phi;
-}
-
-llvm::Value* DexLang::EmitConditionResult(llvm::Value* lhs, llvm::Value* rhs,
-                                          CondBranchKind cond) {
-  switch (cond) {
-    case kCondBranch_EQ: {
-      return irb_.CreateICmpEQ(lhs, rhs);
-    }
-    case kCondBranch_NE: {
-      return irb_.CreateICmpNE(lhs, rhs);
-    }
-    case kCondBranch_LT: {
-      return irb_.CreateICmpSLT(lhs, rhs);
-    }
-    case kCondBranch_GE: {
-      return irb_.CreateICmpSGE(lhs, rhs);
-    }
-    case kCondBranch_GT: {
-      return irb_.CreateICmpSGT(lhs, rhs);
-    }
-    case kCondBranch_LE: {
-      return irb_.CreateICmpSLE(lhs, rhs);
-    }
-    default: {
-      // Unreachable
-      LOG(FATAL) << "Unknown conditional branch kind: " << cond;
-      break;
-    }
-  }
-  return NULL;
-}
-
-llvm::Value* DexLang::EmitIntArithmResultComputation(unsigned dex_pc,
-                                                     llvm::Value* lhs,
-                                                     llvm::Value* rhs,
-                                                     IntArithmKind arithm,
-                                                     JType op_jty) {
-  DCHECK((op_jty == kInt) || (op_jty == kLong)) << op_jty;
-
-  switch (arithm) {
-    case kIntArithm_Add: {
-      return irb_.CreateAdd(lhs, rhs);
-    }
-    case kIntArithm_Sub: {
-      return irb_.CreateSub(lhs, rhs);
-    }
-    case kIntArithm_Mul: {
-      return irb_.CreateMul(lhs, rhs);
-    }
-    case kIntArithm_Div:
-    case kIntArithm_Rem: {
-      return EmitIntDivRemResultComputation(dex_pc, lhs, rhs, arithm, op_jty);
-    }
-    case kIntArithm_And: {
-      return irb_.CreateAnd(lhs, rhs);
-    }
-    case kIntArithm_Or: {
-      return irb_.CreateOr(lhs, rhs);
-    }
-    case kIntArithm_Xor: {
-      return irb_.CreateXor(lhs, rhs);
-    }
-    default: {
-      LOG(FATAL) << "Unknown integer arithmetic kind: " << arithm;
-      break;
-    }
-  }
-  return NULL;
-}
-
-llvm::Value*
-DexLang::EmitIntShiftArithmResultComputation(uint32_t dex_pc,
-                                             llvm::Value* lhs,
-                                             llvm::Value* rhs,
-                                             IntShiftArithmKind arithm,
-                                             JType op_jty) {
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  if (op_jty == kInt) {
-    rhs = irb_.CreateAnd(rhs, 0x1f);
-  } else {
-    llvm::Value* masked_rhs = irb_.CreateAnd(rhs, 0x3f);
-    rhs = irb_.CreateZExt(masked_rhs, irb_.GetJLongTy());
-  }
-
-  switch (arithm) {
-    case kIntArithm_Shl: {
-      return irb_.CreateShl(lhs, rhs);
-    }
-    case kIntArithm_Shr: {
-      return irb_.CreateAShr(lhs, rhs);
-    }
-    case kIntArithm_UShr: {
-      return irb_.CreateLShr(lhs, rhs);
-    }
-    default: {
-      LOG(FATAL) << "Unknown integer shift arithmetic kind: " << arithm;
-      return NULL;
-    }
-  }
-}
-
-llvm::Value* DexLang::EmitIntDivRemResultComputation(unsigned dex_pc,
-                                                     llvm::Value* dividend,
-                                                     llvm::Value* divisor,
-                                                     IntArithmKind arithm,
-                                                     JType op_jty) {
-  // Throw exception if the divisor is 0.
-  EmitGuard_DivZeroException(dex_pc, divisor, op_jty);
-
-  // Note that it's not trivial to translate integer div/rem to sdiv/srem in
-  // LLVM IR since (MININT / -1) leads undefined behavior in LLVM due to
-  // overflow.
-
-  // Select intrinsic
-  bool is_div = (arithm == kIntArithm_Div);
-  IntrinsicHelper::IntrinsicId arithm_intrinsic = IntrinsicHelper::UnknownId;
-  switch (op_jty) {
-    case kInt: {
-      arithm_intrinsic = (is_div) ? IntrinsicHelper::DivInt :
-                                    IntrinsicHelper::RemInt;
-      break;
-    }
-    case kLong: {
-      arithm_intrinsic = (is_div) ? IntrinsicHelper::DivLong :
-                                    IntrinsicHelper::RemLong;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unsupported " << ((is_div) ? "div" : "rem") << " operation"
-                    " for type: " << op_jty;
-      return NULL;
-    }
-  }
-
-  return EmitInvokeIntrinsic2NoThrow(arithm_intrinsic, dividend, divisor);
-}
-
-//----------------------------------------------------------------------------
-// EmitInsn* Functions
-//----------------------------------------------------------------------------
-void DexLang::EmitInsn_Nop(unsigned dex_pc, const Instruction* insn) {
-  uint16_t insn_signature = code_item_->insns_[dex_pc];
-
-  if (insn_signature == Instruction::kPackedSwitchSignature ||
-      insn_signature == Instruction::kSparseSwitchSignature ||
-      insn_signature == Instruction::kArrayDataSignature) {
-    irb_.CreateUnreachable();
-  } else {
-    irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  }
-  return;
-}
-
-void DexLang::EmitInsn_Move(unsigned dex_pc, const Instruction* insn,
-                            JType jty) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, jty, kReg);
-  EmitStoreDalvikReg(dec_insn.vA, jty, kReg, src_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_MoveResult(unsigned dex_pc, const Instruction* insn,
-                                  JType jty) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikRetValReg(jty, kReg);
-  EmitStoreDalvikReg(dec_insn.vA, jty, kReg, src_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_MoveException(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* exception_object_addr =
-      EmitInvokeIntrinsicNoThrow(IntrinsicHelper::GetException);
-
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, exception_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_ThrowException(unsigned dex_pc,
-                                      const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* exception_addr =
-      EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  EmitInvokeIntrinsic(dex_pc, false, IntrinsicHelper::ThrowException, exception_addr);
-
-  return;
-}
-
-void DexLang::EmitInsn_ReturnVoid(unsigned dex_pc, const Instruction* insn) {
-  // Pop the shadow frame
-  EmitPopShadowFrame();
-
-  // Return!
-  irb_.CreateRetVoid();
-  return;
-}
-
-void DexLang::EmitInsn_Return(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  // Pop the shadow frame
-  //
-  // NOTE: It is important to keep this AFTER the GC safe-point.  Otherwise,
-  // the return value might be collected since the shadow stack is popped.
-  EmitPopShadowFrame();
-
-  // Return!
-  char ret_shorty = cunit_.GetShorty()[0];
-  llvm::Value* retval = EmitLoadDalvikReg(dec_insn.vA, ret_shorty, kAccurate);
-
-  irb_.CreateRet(retval);
-  return;
-}
-
-void DexLang::EmitInsn_LoadConstant(unsigned dex_pc, const Instruction* insn,
-                                    JType imm_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(imm_jty == kInt || imm_jty == kLong) << imm_jty;
-
-  int64_t imm = 0;
-
-  switch (insn->Opcode()) {
-    // 32-bit Immediate
-    case Instruction::CONST_4:
-    case Instruction::CONST_16:
-    case Instruction::CONST:
-    case Instruction::CONST_WIDE_16:
-    case Instruction::CONST_WIDE_32: {
-      imm = static_cast<int64_t>(static_cast<int32_t>(dec_insn.vB));
-      break;
-    }
-    case Instruction::CONST_HIGH16: {
-      imm = static_cast<int64_t>(static_cast<int32_t>(
-            static_cast<uint32_t>(static_cast<uint16_t>(dec_insn.vB)) << 16));
-      break;
-    }
-    // 64-bit Immediate
-    case Instruction::CONST_WIDE: {
-      imm = static_cast<int64_t>(dec_insn.vB_wide);
-      break;
-    }
-    case Instruction::CONST_WIDE_HIGH16: {
-      imm = static_cast<int64_t>(
-            static_cast<uint64_t>(static_cast<uint16_t>(dec_insn.vB)) << 48);
-      break;
-    }
-    // Unknown opcode for load constant (unreachable)
-    default: {
-      LOG(FATAL) << "Unknown opcode for load constant: " << insn->Opcode();
-      break;
-    }
-  }
-
-  // Store the non-object register
-  llvm::Type* imm_type = irb_.GetJType(imm_jty, kAccurate);
-  llvm::Constant* imm_value = llvm::ConstantInt::getSigned(imm_type, imm);
-  EmitStoreDalvikReg(dec_insn.vA, imm_jty, kAccurate, imm_value);
-
-  // Store the object register if it is possible to be null.
-  //
-  // FIXME: Should we use GetInferredRegCategory() here to avoid store the value
-  // twice?
-  if (imm_jty == kInt && imm == 0) {
-    EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, irb_.GetJNull());
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_LoadConstantString(unsigned dex_pc,
-                                          const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t string_idx = dec_insn.vB;
-  llvm::Value* string_idx_value = irb_.getInt32(string_idx);
-
-  llvm::Value* string_addr =
-      EmitInvokeIntrinsicNoThrow(IntrinsicHelper::LoadStringFromDexCache,
-                                 string_idx_value);
-
-  if (!compiler_.CanAssumeStringIsPresentInDexCache(*dex_file_, string_idx)) {
-    llvm::BasicBlock* block_str_exist =
-        CreateBasicBlockWithDexPC(dex_pc, "str_exist");
-
-    llvm::BasicBlock* block_str_resolve =
-        CreateBasicBlockWithDexPC(dex_pc, "str_resolve");
-
-    // Test: Is the string resolved and in the dex cache?
-    llvm::Value* equal_null = irb_.CreateICmpEQ(string_addr, irb_.GetJNull());
-
-    irb_.CreateCondBr(equal_null, block_str_resolve, block_str_exist);
-
-    // String is resolved, go to next basic block.
-    irb_.SetInsertPoint(block_str_exist);
-    EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, string_addr);
-    irb_.CreateBr(GetNextBasicBlock(dex_pc));
-
-    // String is not resolved yet, resolve it now.
-    irb_.SetInsertPoint(block_str_resolve);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    string_addr = EmitInvokeIntrinsic2(dex_pc, true, IntrinsicHelper::ResolveString,
-                                       method_object_addr, string_idx_value);
-  }
-
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, string_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_LoadConstantClass(unsigned dex_pc,
-                                         const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, dec_insn.vB);
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, type_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_MonitorEnter(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr =
-      EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && dec_insn.vA == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-  EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::LockObject,
-                              object_addr, thread_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_MonitorExit(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr =
-      EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && dec_insn.vA == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-  EmitInvokeIntrinsic2(dex_pc, true, IntrinsicHelper::UnlockObject,
-                       object_addr, thread_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_CheckCast(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::BasicBlock* block_test_class =
-      CreateBasicBlockWithDexPC(dex_pc, "test_class");
-
-  llvm::BasicBlock* block_test_sub_class =
-      CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
-
-  llvm::Value* object_addr =
-      EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  // Test: Is the reference equal to null?  Act as no-op when it is null.
-  llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.GetJNull());
-
-  irb_.CreateCondBr(equal_null,
-                    GetNextBasicBlock(dex_pc),
-                    block_test_class);
-
-  // Test: Is the object instantiated from the given class?
-  irb_.SetInsertPoint(block_test_class);
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, dec_insn.vB);
-  DCHECK_EQ(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);
-
-  llvm::Value* equal_class =
-      irb_.CreateICmpEQ(type_object_addr, object_type_object_addr);
-
-  irb_.CreateCondBr(equal_class,
-                    GetNextBasicBlock(dex_pc),
-                    block_test_sub_class);
-
-  // Test: Is the object instantiated from the subclass of the given class?
-  irb_.SetInsertPoint(block_test_sub_class);
-
-  EmitInvokeIntrinsic2(dex_pc, true, IntrinsicHelper::CheckCast,
-                       type_object_addr, object_type_object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_InstanceOf(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Constant* zero = irb_.GetJInt(0);
-  llvm::Constant* one = irb_.GetJInt(1);
-
-  llvm::BasicBlock* block_nullp = CreateBasicBlockWithDexPC(dex_pc, "nullp");
-
-  llvm::BasicBlock* block_test_class =
-      CreateBasicBlockWithDexPC(dex_pc, "test_class");
-
-  llvm::BasicBlock* block_class_equals =
-      CreateBasicBlockWithDexPC(dex_pc, "class_eq");
-
-  llvm::BasicBlock* block_test_sub_class =
-      CreateBasicBlockWithDexPC(dex_pc, "test_sub_class");
-
-  llvm::Value* object_addr =
-      EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-
-  // Overview of the following code :
-  // We check for null, if so, then false, otherwise check for class == . If so
-  // then true, otherwise do callout slowpath.
-  //
-  // Test: Is the reference equal to null?  Set 0 when it is null.
-  llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.GetJNull());
-
-  irb_.CreateCondBr(equal_null, block_nullp, block_test_class);
-
-  irb_.SetInsertPoint(block_nullp);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, zero);
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-
-  // Test: Is the object instantiated from the given class?
-  irb_.SetInsertPoint(block_test_class);
-  llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, dec_insn.vC);
-  DCHECK_EQ(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);
-
-  llvm::Value* equal_class =
-      irb_.CreateICmpEQ(type_object_addr, object_type_object_addr);
-
-  irb_.CreateCondBr(equal_class, block_class_equals, block_test_sub_class);
-
-  irb_.SetInsertPoint(block_class_equals);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, one);
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-
-  // Test: Is the object instantiated from the subclass of the given class?
-  irb_.SetInsertPoint(block_test_sub_class);
-
-  llvm::Value* result =
-      EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::IsAssignable,
-                                  type_object_addr, object_type_object_addr);
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_NewInstance(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  IntrinsicHelper::IntrinsicId alloc_intrinsic;
-  if (compiler_.CanAccessInstantiableTypeWithoutChecks(method_idx_,
-                                                       *dex_file_,
-                                                       dec_insn.vB)) {
-    alloc_intrinsic = IntrinsicHelper::AllocObject;
-  } else {
-    alloc_intrinsic = IntrinsicHelper::AllocObjectWithAccessCheck;
-  }
-
-  llvm::Constant* type_index_value = irb_.getInt32(dec_insn.vB);
-
-  llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-  llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-  llvm::Value* object_addr = EmitInvokeIntrinsic3(dex_pc, true, alloc_intrinsic,
-                                                  type_index_value,
-                                                  method_object_addr,
-                                                  thread_object_addr);
-
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_UnconditionalBranch(unsigned dex_pc,
-                                           const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  int32_t branch_offset = dec_insn.vA;
-
-  irb_.CreateBr(GetBasicBlock(dex_pc + branch_offset));
-  return;
-}
-
-void DexLang::EmitInsn_ArrayLength(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  // Get the array object address
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-
-  // Check whether the array address is null
-  EmitGuard_NullPointerException(dex_pc, array_addr);
-
-  // Get the array length and store it to the register
-  llvm::Value* array_len = EmitLoadArrayLength(array_addr);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, array_len);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_NewArray(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* array_addr = EmitAllocNewArray(dex_pc, dec_insn.vB, dec_insn.vC,
-                                              /* is_filled_new_array */false);
-
-  EmitStoreDalvikReg(dec_insn.vA, kObject, kAccurate, array_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FilledNewArray(unsigned dex_pc, const Instruction* insn,
-                                      bool is_range) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* object_addr = EmitAllocNewArray(dex_pc, dec_insn.vA, dec_insn.vB,
-                                               /* is_filled_new_array */true);
-
-  if (dec_insn.vA > 0) {
-    // Check for the element type
-    uint32_t type_desc_len = 0;
-    const char* type_desc =
-        dex_file_->StringByTypeIdx(dec_insn.vB, &type_desc_len);
-
-    DCHECK_GE(type_desc_len, 2u); // should be guaranteed by verifier
-    DCHECK_EQ(type_desc[0], '['); // should be guaranteed by verifier
-
-    // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' as the
-    // element, therefore the element is either a primitive int or a reference
-    JType element_jty = ((type_desc[1] == 'I') ? kInt : kObject);
-
-    std::vector<llvm::Value*> args;
-    // Destination array object
-    args.push_back(object_addr);
-    // Type of the array element
-    //
-    // FIXME: Actually, dec_insn.vB (type_idx of the element) should be here to
-    // the intrinsic instead of element_jty. However, since GBCExpander cannot
-    // know which dex_file this filled-new-array instruction associated with, it
-    // is unable to know the exact type of the type_idx is. In the near future,
-    // metadata will be used to record the type information (i.e., type_desc)
-    args.push_back(irb_.getInt32(element_jty));
-
-    for (uint32_t i = 0; i < dec_insn.vA; ++i) {
-      int reg_index;
-      if (is_range) {
-        reg_index = dec_insn.vC + i;
-      } else {
-        reg_index = dec_insn.arg[i];
-      }
-
-      llvm::Value* reg_value =
-          EmitLoadDalvikReg(reg_index, element_jty, kAccurate);
-
-      args.push_back(reg_value);
-    }
-
-    EmitInvokeIntrinsicNoThrow(IntrinsicHelper::FilledNewArray, args);
-  }
-
-  EmitStoreDalvikRetValReg(kObject, kAccurate, object_addr);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FillArrayData(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  // Read the payload
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           static_cast<int32_t>(dec_insn.vB);
-
-  const Instruction::ArrayDataPayload* payload =
-    reinterpret_cast<const Instruction::ArrayDataPayload*>(
-        code_item_->insns_ + payload_offset);
-
-  // Load array object
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-
-  if (payload->element_count == 0) {
-    // When the number of the elements in the payload is zero, we don't have
-    // to copy any numbers.  However, we should check whether the array object
-    // address is equal to null or not.
-    EmitGuard_NullPointerException(dex_pc, array_addr);
-  } else {
-    // To save the code size, we are going to call the runtime function to
-    // copy the content from DexFile.
-
-    // NOTE: We will check for the NullPointerException in the runtime.
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitInvokeIntrinsic4(dex_pc, true, IntrinsicHelper::FillArrayData,
-                         method_object_addr, irb_.getInt32(dex_pc), array_addr,
-                         irb_.getInt32(payload_offset));
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_UnaryConditionalBranch(unsigned dex_pc,
-                                              const Instruction* insn,
-                                              CondBranchKind cond) {
-  DecodedInstruction dec_insn(insn);
-
-  RegCategory src_reg_cat = GetInferredRegCategory(dex_pc, dec_insn.vA);
-
-  DCHECK_NE(kRegUnknown, src_reg_cat);
-  DCHECK_NE(kRegCat2, src_reg_cat);
-
-  int32_t branch_offset = dec_insn.vB;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (src_reg_cat == kRegZero) {
-    src1_value = irb_.getInt32(0);
-    src2_value = irb_.getInt32(0);
-  } else if (src_reg_cat == kRegCat1nr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kReg);
-    src2_value = irb_.getInt32(0);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-    src2_value = irb_.GetJNull();
-  }
-
-  llvm::Value* cond_value = EmitConditionResult(src1_value, src2_value, cond);
-
-  irb_.CreateCondBr(cond_value,
-                    GetBasicBlock(dex_pc + branch_offset),
-                    GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_BinaryConditionalBranch(unsigned dex_pc,
-                                               const Instruction* insn,
-                                               CondBranchKind cond) {
-  DecodedInstruction dec_insn(insn);
-
-  int8_t src1_reg_cat = GetInferredRegCategory(dex_pc, dec_insn.vA);
-  int8_t src2_reg_cat = GetInferredRegCategory(dex_pc, dec_insn.vB);
-
-  DCHECK_NE(kRegUnknown, src1_reg_cat);
-  DCHECK_NE(kRegUnknown, src2_reg_cat);
-  DCHECK_NE(kRegCat2, src1_reg_cat);
-  DCHECK_NE(kRegCat2, src2_reg_cat);
-
-  int32_t branch_offset = dec_insn.vC;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (src1_reg_cat == kRegZero && src2_reg_cat == kRegZero) {
-    src1_value = irb_.getInt32(0);
-    src2_value = irb_.getInt32(0);
-  } else if (src1_reg_cat != kRegZero && src2_reg_cat != kRegZero) {
-    CHECK_EQ(src1_reg_cat, src2_reg_cat);
-
-    if (src1_reg_cat == kRegCat1nr) {
-      src1_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-      src2_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-    } else {
-      src1_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-      src2_value = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-    }
-  } else {
-    DCHECK(src1_reg_cat == kRegZero ||
-           src2_reg_cat == kRegZero);
-
-    if (src1_reg_cat == kRegZero) {
-      if (src2_reg_cat == kRegCat1nr) {
-        src1_value = irb_.GetJInt(0);
-        src2_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-      } else {
-        src1_value = irb_.GetJNull();
-        src2_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-      }
-    } else { // src2_reg_cat == kRegZero
-      if (src2_reg_cat == kRegCat1nr) {
-        src1_value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-        src2_value = irb_.GetJInt(0);
-      } else {
-        src1_value = EmitLoadDalvikReg(dec_insn.vA, kObject, kAccurate);
-        src2_value = irb_.GetJNull();
-      }
-    }
-  }
-
-  llvm::Value* cond_value = EmitConditionResult(src1_value, src2_value, cond);
-
-  irb_.CreateCondBr(cond_value,
-                    GetBasicBlock(dex_pc + branch_offset),
-                    GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_PackedSwitch(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           static_cast<int32_t>(dec_insn.vB);
-
-  const Instruction::PackedSwitchPayload* payload =
-    reinterpret_cast<const Instruction::PackedSwitchPayload*>(
-        code_item_->insns_ + payload_offset);
-
-  llvm::Value* value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-
-  llvm::SwitchInst* sw =
-    irb_.CreateSwitch(value, GetNextBasicBlock(dex_pc), payload->case_count);
-
-  for (uint16_t i = 0; i < payload->case_count; ++i) {
-    sw->addCase(irb_.getInt32(payload->first_key + i),
-                GetBasicBlock(dex_pc + payload->targets[i]));
-  }
-  return;
-}
-
-void DexLang::EmitInsn_SparseSwitch(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  int32_t payload_offset = static_cast<int32_t>(dex_pc) +
-                           static_cast<int32_t>(dec_insn.vB);
-
-  const Instruction::SparseSwitchPayload* payload =
-    reinterpret_cast<const Instruction::SparseSwitchPayload*>(
-        code_item_->insns_ + payload_offset);
-
-  const int32_t* keys = payload->GetKeys();
-  const int32_t* targets = payload->GetTargets();
-
-  llvm::Value* value = EmitLoadDalvikReg(dec_insn.vA, kInt, kAccurate);
-
-  llvm::SwitchInst* sw =
-    irb_.CreateSwitch(value, GetNextBasicBlock(dex_pc), payload->case_count);
-
-  for (size_t i = 0; i < payload->case_count; ++i) {
-    sw->addCase(irb_.getInt32(keys[i]), GetBasicBlock(dex_pc + targets[i]));
-  }
-  return;
-}
-
-void DexLang::EmitInsn_FPCompare(unsigned dex_pc, const Instruction* insn,
-                                 JType fp_jty, bool gt_bias) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(fp_jty == kFloat || fp_jty == kDouble) << "JType: " << fp_jty;
-
-  llvm::Value* src1_value = EmitLoadDalvikReg(dec_insn.vB, fp_jty, kAccurate);
-  llvm::Value* src2_value = EmitLoadDalvikReg(dec_insn.vC, fp_jty, kAccurate);
-
-  llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value);
-  llvm::Value* cmp_lt;
-
-  if (gt_bias) {
-    cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value);
-  } else {
-    cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value);
-  }
-
-  llvm::Value* result = EmitCompareResultSelection(cmp_eq, cmp_lt);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_LongCompare(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src1_value = EmitLoadDalvikReg(dec_insn.vB, kLong, kAccurate);
-  llvm::Value* src2_value = EmitLoadDalvikReg(dec_insn.vC, kLong, kAccurate);
-
-  llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value);
-  llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value);
-
-  llvm::Value* result = EmitCompareResultSelection(cmp_eq, cmp_lt);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_AGet(unsigned dex_pc, const Instruction* insn,
-                            JType elem_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  // Select corresponding intrinsic
-  IntrinsicHelper::IntrinsicId aget_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (elem_jty) {
-    case kInt: {
-      aget_intrinsic = IntrinsicHelper::ArrayGet;
-      break;
-    }
-    case kLong: {
-      aget_intrinsic = IntrinsicHelper::ArrayGetWide;
-      break;
-    }
-    case kObject: {
-      aget_intrinsic = IntrinsicHelper::ArrayGetObject;
-      break;
-    }
-    case kBoolean: {
-      aget_intrinsic = IntrinsicHelper::ArrayGetBoolean;
-      break;
-    }
-    case kByte: {
-      aget_intrinsic = IntrinsicHelper::ArrayGetByte;
-      break;
-    }
-    case kChar: {
-      aget_intrinsic = IntrinsicHelper::ArrayGetChar;
-      break;
-    }
-    case kShort: {
-      aget_intrinsic = IntrinsicHelper::ArrayGetShort;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unexpected element type got in aget instruction!";
-      return;
-    }
-  }
-
-  // Construct argument list passed to the intrinsic
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-  llvm::Value* index_value = EmitLoadDalvikReg(dec_insn.vC, kInt, kAccurate);
-
-  EmitGuard_ArrayException(dex_pc, array_addr, index_value);
-
-  llvm::Value* array_element_value = EmitInvokeIntrinsic2NoThrow(aget_intrinsic,
-                                                                 array_addr,
-                                                                 index_value);
-
-  EmitStoreDalvikReg(dec_insn.vA, elem_jty, kArray, array_element_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_APut(unsigned dex_pc, const Instruction* insn,
-                            JType elem_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  // Select corresponding intrinsic
-  IntrinsicHelper::IntrinsicId aput_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (elem_jty) {
-    case kInt: {
-      aput_intrinsic = IntrinsicHelper::ArrayPut;
-      break;
-    }
-    case kLong: {
-      aput_intrinsic = IntrinsicHelper::ArrayPutWide;
-      break;
-    }
-    case kObject: {
-      aput_intrinsic = IntrinsicHelper::ArrayPutObject;
-      break;
-    }
-    case kBoolean: {
-      aput_intrinsic = IntrinsicHelper::ArrayPutBoolean;
-      break;
-    }
-    case kByte: {
-      aput_intrinsic = IntrinsicHelper::ArrayPutByte;
-      break;
-    }
-    case kChar: {
-      aput_intrinsic = IntrinsicHelper::ArrayPutChar;
-      break;
-    }
-    case kShort: {
-      aput_intrinsic = IntrinsicHelper::ArrayPutShort;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unexpected element type got in aput instruction!";
-      return;
-    }
-  }
-
-  llvm::Value* array_addr = EmitLoadDalvikReg(dec_insn.vB, kObject, kAccurate);
-  llvm::Value* index_value = EmitLoadDalvikReg(dec_insn.vC, kInt, kAccurate);
-
-  EmitGuard_ArrayException(dex_pc, array_addr, index_value);
-
-  llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, elem_jty, kArray);
-
-  // Check the type if an object is putting
-  if (elem_jty == kObject) {
-    EmitInvokeIntrinsic2(dex_pc, false, IntrinsicHelper::CheckPutArrayElement,
-                         new_value, array_addr);
-
-    EmitMarkGCCard(new_value, array_addr);
-  }
-
-  EmitInvokeIntrinsic3NoThrow(aput_intrinsic, new_value, array_addr, index_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IGet(unsigned dex_pc, const Instruction* insn,
-                            JType field_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t reg_idx = dec_insn.vB;
-  uint32_t field_idx = dec_insn.vC;
-
-  llvm::Value* object_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && reg_idx == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  int field_offset;
-  bool is_volatile;
-  bool is_fast_path = compiler_.ComputeInstanceFieldInfo(field_idx, &cunit_,
-                                                         field_offset,
-                                                         is_volatile,
-                                                         /* is_put */false);
-
-  // Select corresponding intrinsic accroding to the field type and is_fast_path
-  IntrinsicHelper::IntrinsicId iget_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (field_jty) {
-    case kInt: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetFast :
-                           IntrinsicHelper::InstanceFieldGet;
-      break;
-    }
-    case kLong: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetWideFast :
-                           IntrinsicHelper::InstanceFieldGetWide;
-      break;
-    }
-    case kObject: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetObjectFast :
-                           IntrinsicHelper::InstanceFieldGetObject;
-      break;
-    }
-    case kBoolean: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetBooleanFast :
-                           IntrinsicHelper::InstanceFieldGetBoolean;
-      break;
-    }
-    case kByte: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetByteFast :
-                           IntrinsicHelper::InstanceFieldGetByte;
-      break;
-    }
-    case kChar: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetCharFast :
-                           IntrinsicHelper::InstanceFieldGetChar;
-      break;
-    }
-    case kShort: {
-      iget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldGetShortFast :
-                           IntrinsicHelper::InstanceFieldGetShort;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unexpected element type got in iget instruction!";
-      return;
-    }
-  }
-
-  llvm::Value* instance_field_value;
-
-  if (!is_fast_path) {
-    llvm::Constant* field_idx_value = irb_.getInt32(field_idx);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    instance_field_value = EmitInvokeIntrinsic3(dex_pc, true, iget_intrinsic,
-                                                field_idx_value,
-                                                method_object_addr,
-                                                object_addr);
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    instance_field_value =
-        EmitInvokeIntrinsic3NoThrow(iget_intrinsic,
-                                    irb_.getInt32(field_offset),
-                                    irb_.getInt1(is_volatile),
-                                    object_addr);
-  }
-
-  EmitStoreDalvikReg(dec_insn.vA, field_jty, kField, instance_field_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IPut(unsigned dex_pc, const Instruction* insn,
-                            JType field_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t reg_idx = dec_insn.vB;
-  uint32_t field_idx = dec_insn.vC;
-
-  llvm::Value* object_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate);
-
-  if (!(method_info_.this_will_not_be_null && reg_idx == method_info_.this_reg_idx)) {
-    EmitGuard_NullPointerException(dex_pc, object_addr);
-  }
-
-  llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, field_jty, kField);
-
-  int field_offset;
-  bool is_volatile;
-  bool is_fast_path = compiler_.ComputeInstanceFieldInfo(field_idx, &cunit_,
-                                                         field_offset,
-                                                         is_volatile,
-                                                         /* is_iput */true);
-
-  // Select corresponding intrinsic accroding to the field type and is_fast_path
-  IntrinsicHelper::IntrinsicId iput_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (field_jty) {
-    case kInt: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutFast :
-                           IntrinsicHelper::InstanceFieldPut;
-      break;
-    }
-    case kLong: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutWideFast :
-                           IntrinsicHelper::InstanceFieldPutWide;
-      break;
-    }
-    case kObject: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutObjectFast :
-                           IntrinsicHelper::InstanceFieldPutObject;
-      break;
-    }
-    case kBoolean: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutBooleanFast :
-                           IntrinsicHelper::InstanceFieldPutBoolean;
-      break;
-    }
-    case kByte: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutByteFast :
-                           IntrinsicHelper::InstanceFieldPutByte;
-      break;
-    }
-    case kChar: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutCharFast :
-                           IntrinsicHelper::InstanceFieldPutChar;
-      break;
-    }
-    case kShort: {
-      iput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::InstanceFieldPutShortFast :
-                           IntrinsicHelper::InstanceFieldPutShort;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unexpected element type got in iput instruction!";
-      return;
-    }
-  }
-
-  if (!is_fast_path) {
-    llvm::Value* field_idx_value = irb_.getInt32(field_idx);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitInvokeIntrinsic4(dex_pc, true, iput_intrinsic, field_idx_value,
-                         method_object_addr, object_addr, new_value);
-
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    EmitInvokeIntrinsic4NoThrow(iput_intrinsic, irb_.getInt32(field_offset),
-                                irb_.getInt1(is_volatile), object_addr,
-                                new_value);
-
-    // If put an object, mark the GC card table
-    if (field_jty == kObject) {
-      EmitMarkGCCard(new_value, object_addr);
-    }
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_SGet(unsigned dex_pc, const Instruction* insn,
-                            JType field_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t field_idx = dec_insn.vB;
-
-  int field_offset;
-  int ssb_index;
-  bool is_referrers_class;
-  bool is_volatile;
-  bool is_fast_path = compiler_.ComputeStaticFieldInfo(field_idx, &cunit_,
-                                                       field_offset, ssb_index,
-                                                       is_referrers_class,
-                                                       is_volatile,
-                                                       /* is_put */false);
-
-  // Select corresponding intrinsic accroding to the field type and is_fast_path
-  IntrinsicHelper::IntrinsicId sget_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (field_jty) {
-    case kInt: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetFast :
-                           IntrinsicHelper::StaticFieldGet;
-      break;
-    }
-    case kLong: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetWideFast :
-                           IntrinsicHelper::StaticFieldGetWide;
-      break;
-    }
-    case kObject: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetObjectFast :
-                           IntrinsicHelper::StaticFieldGetObject;
-      break;
-    }
-    case kBoolean: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetBooleanFast :
-                           IntrinsicHelper::StaticFieldGetBoolean;
-      break;
-    }
-    case kByte: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetByteFast :
-                           IntrinsicHelper::StaticFieldGetByte;
-      break;
-    }
-    case kChar: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetCharFast :
-                           IntrinsicHelper::StaticFieldGetChar;
-      break;
-    }
-    case kShort: {
-      sget_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldGetShortFast :
-                           IntrinsicHelper::StaticFieldGetShort;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unexpected element type got in sget instruction!";
-      return;
-    }
-  }
-
-  llvm::Constant* field_idx_value = irb_.getInt32(field_idx);
-
-  llvm::Value* static_field_value;
-
-  if (!is_fast_path) {
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    static_field_value =
-        EmitInvokeIntrinsic2(dex_pc, true, sget_intrinsic,
-                             field_idx_value, method_object_addr);
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    llvm::Value* static_storage_addr = NULL;
-
-    if (is_referrers_class) {
-      // Fast path, static storage base is this method's class
-      llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-      static_storage_addr =
-          EmitInvokeIntrinsicNoThrow(IntrinsicHelper::LoadDeclaringClassSSB,
-                                     method_object_addr);
-    } else {
-      // Medium path, static storage base in a different class which
-      // requires checks that the other class is initialized
-      DCHECK_GE(ssb_index, 0);
-      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
-    }
-
-    static_field_value =
-        EmitInvokeIntrinsic3NoThrow(sget_intrinsic,
-                                    static_storage_addr,
-                                    irb_.getInt32(field_offset),
-                                    irb_.getInt1(is_volatile));
-  }
-
-  EmitStoreDalvikReg(dec_insn.vA, field_jty, kField, static_field_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_SPut(unsigned dex_pc, const Instruction* insn,
-                            JType field_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  uint32_t field_idx = dec_insn.vB;
-
-  llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA, field_jty, kField);
-
-  int field_offset;
-  int ssb_index;
-  bool is_referrers_class;
-  bool is_volatile;
-  bool is_fast_path = compiler_.ComputeStaticFieldInfo(field_idx, &cunit_,
-                                                       field_offset, ssb_index,
-                                                       is_referrers_class,
-                                                       is_volatile,
-                                                       /* is_put */true);
-
-  // Select corresponding intrinsic accroding to the field type and is_fast_path
-  IntrinsicHelper::IntrinsicId sput_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (field_jty) {
-    case kInt: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutFast :
-                           IntrinsicHelper::StaticFieldPut;
-      break;
-    }
-    case kLong: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutWideFast :
-                           IntrinsicHelper::StaticFieldPutWide;
-      break;
-    }
-    case kObject: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutObjectFast :
-                           IntrinsicHelper::StaticFieldPutObject;
-      break;
-    }
-    case kBoolean: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutBooleanFast :
-                           IntrinsicHelper::StaticFieldPutBoolean;
-      break;
-    }
-    case kByte: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutByteFast :
-                           IntrinsicHelper::StaticFieldPutByte;
-      break;
-    }
-    case kChar: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutCharFast :
-                           IntrinsicHelper::StaticFieldPutChar;
-      break;
-    }
-    case kShort: {
-      sput_intrinsic =
-          (is_fast_path) ? IntrinsicHelper::StaticFieldPutShortFast :
-                           IntrinsicHelper::StaticFieldPutShort;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unexpected element type got in sput instruction!";
-      return;
-    }
-  }
-
-  if (!is_fast_path) {
-    llvm::Constant* field_idx_value = irb_.getInt32(dec_insn.vB);
-
-    llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-    EmitInvokeIntrinsic3(dex_pc, true, sput_intrinsic,
-                         field_idx_value, method_object_addr, new_value);
-  } else {
-    DCHECK_GE(field_offset, 0);
-
-    llvm::Value* static_storage_addr = NULL;
-
-    if (is_referrers_class) {
-      // Fast path, static storage base is this method's class
-      llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
-
-      static_storage_addr =
-        EmitInvokeIntrinsicNoThrow(IntrinsicHelper::LoadDeclaringClassSSB,
-                                   method_object_addr);
-    } else {
-      // Medium path, static storage base in a different class which
-      // requires checks that the other class is initialized
-      DCHECK_GE(ssb_index, 0);
-      static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index);
-    }
-
-    EmitInvokeIntrinsic4NoThrow(sput_intrinsic, static_storage_addr,
-                                irb_.getInt32(field_offset),
-                                irb_.getInt1(is_volatile), new_value);
-
-    // If put an object, mark the GC card table
-    if (field_jty == kObject) {
-      EmitMarkGCCard(new_value, static_storage_addr);
-    }
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_Invoke(unsigned dex_pc, const Instruction* insn,
-                              InvokeType invoke_type, InvokeArgFmt arg_fmt) {
-  DecodedInstruction dec_insn(insn);
-
-  bool is_static = (invoke_type == kStatic);
-  uint32_t callee_method_idx = dec_insn.vB;
-
-  // Compute invoke related information for compiler decision
-  int vtable_idx = -1;
-  uintptr_t direct_code = 0; // Currently unused
-  uintptr_t direct_method = 0;
-  bool is_fast_path = compiler_.ComputeInvokeInfo(callee_method_idx, &cunit_,
-                                                  invoke_type, vtable_idx,
-                                                  direct_code, direct_method);
-
-  // Load *this* actual parameter
-  uint32_t this_reg = -1u;
-  llvm::Value* this_addr = NULL;
-
-  if (is_static) {
-    this_addr = irb_.GetJNull();
-  } else {
-    this_reg = (arg_fmt == kArgReg) ? dec_insn.arg[0] : (dec_insn.vC + 0);
-    this_addr = EmitLoadDalvikReg(this_reg, kObject, kAccurate);
-  }
-
-  // Load the method object
-  llvm::Value* callee_method_object_addr = NULL;
-
-  llvm::Value* callee_method_idx_value = irb_.getInt32(callee_method_idx);
-
-  if (!is_fast_path) {
-    llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr();
-
-    llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-    // Select intrinsic according to the invoke_type
-    IntrinsicHelper::IntrinsicId invoke_intr = IntrinsicHelper::UnknownId;
-    switch (invoke_type) {
-      case kStatic: {
-        invoke_intr = IntrinsicHelper::FindStaticMethodWithAccessCheck;
-        break;
-      }
-      case kDirect: {
-        invoke_intr = IntrinsicHelper::FindDirectMethodWithAccessCheck;
-        break;
-      }
-      case kVirtual: {
-        invoke_intr = IntrinsicHelper::FindVirtualMethodWithAccessCheck;
-        break;
-      }
-      case kSuper: {
-        invoke_intr = IntrinsicHelper::FindSuperMethodWithAccessCheck;
-        break;
-      }
-      case kInterface: {
-        invoke_intr = IntrinsicHelper::FindInterfaceMethodWithAccessCheck;
-        break;
-      }
-      default: {
-        LOG(FATAL) << "Unknown type of invoke: " << invoke_type;
-      }
-    }
-
-    callee_method_object_addr =
-        EmitInvokeIntrinsic4(dex_pc, false, invoke_intr,
-                             callee_method_idx_value,
-                             this_addr,
-                             caller_method_object_addr,
-                             thread_object_addr);
-
-    if (!is_static && (!method_info_.this_will_not_be_null ||
-                       this_reg != method_info_.this_reg_idx)) {
-      // NOTE: The null pointer test should come after the method resolution.
-      // So that the "NoSuchMethodError" can be thrown before the
-      // "NullPointerException".
-      EmitGuard_NullPointerException(dex_pc, this_addr);
-    }
-  } else {
-    if (!is_static && (!method_info_.this_will_not_be_null ||
-                       this_reg != method_info_.this_reg_idx)) {
-      // NOTE: In the fast path, we should do the null pointer check
-      // before the access to the class object and/or direct invocation.
-      EmitGuard_NullPointerException(dex_pc, this_addr);
-    }
-
-    switch (invoke_type) {
-      case kStatic:
-      case kDirect: {
-        if (direct_method != 0u &&
-            direct_method != static_cast<uintptr_t>(-1)) {
-          callee_method_object_addr =
-            irb_.CreateIntToPtr(irb_.GetPtrEquivInt(direct_method),
-                                irb_.GetJMethodTy());
-        } else {
-          callee_method_object_addr =
-              EmitInvokeIntrinsicNoThrow(IntrinsicHelper::GetSDCalleeMethodObjAddrFast,
-                                         callee_method_idx_value);
-        }
-        break;
-      }
-      case kVirtual: {
-        DCHECK(vtable_idx != -1);
-        callee_method_object_addr =
-            EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::GetVirtualCalleeMethodObjAddrFast,
-                                        irb_.getInt32(vtable_idx), this_addr);
-        break;
-      }
-      case kSuper: {
-        LOG(FATAL) << "invoke-super should be promoted to invoke-direct in "
-                      "the fast path.";
-        break;
-      }
-      case kInterface: {
-        llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr();
-
-        llvm::Value* thread_object_addr = EmitGetCurrentThread();
-
-        callee_method_object_addr =
-            EmitInvokeIntrinsic4(dex_pc, false,
-                                 IntrinsicHelper::GetInterfaceCalleeMethodObjAddrFast,
-                                 callee_method_idx_value,
-                                 this_addr,
-                                 caller_method_object_addr,
-                                 thread_object_addr);
-        break;
-      }
-    }
-  }
-
-  // Get the shorty of the callee
-  uint32_t callee_shorty_size;
-  const DexFile::MethodId& callee_method_id =
-      dex_file_->GetMethodId(callee_method_idx);
-  const char* callee_shorty =
-      dex_file_->GetMethodShorty(callee_method_id, &callee_shorty_size);
-  CHECK_GE(callee_shorty_size, 1u);
-
-  JType callee_ret_jty = GetJTypeFromShorty(callee_shorty[0]);
-
-  // Select the corresponding intrinsic according to the return type
-  IntrinsicHelper::IntrinsicId invoke_intrinsic = IntrinsicHelper::UnknownId;
-
-  switch (callee_ret_jty) {
-    case kVoid: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetVoid;
-      break;
-    }
-    case kBoolean: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetBoolean;
-      break;
-    }
-    case kByte: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetByte;
-      break;
-    }
-    case kChar: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetChar;
-      break;
-    }
-    case kShort: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetShort;
-      break;
-    }
-    case kInt: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetInt;
-      break;
-    }
-    case kLong: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetLong;
-      break;
-    }
-    case kFloat: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetFloat;
-      break;
-    }
-    case kDouble: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetDouble;
-      break;
-    }
-    case kObject: {
-      invoke_intrinsic = IntrinsicHelper::InvokeRetObject;
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unknown register category for type: " << callee_ret_jty;
-      break;
-    }
-  }
-
-  // Load arguments for invoke intrinsics
-  std::vector<llvm::Value*> args;
-
-  // Callee's method id goes first
-  args.push_back(callee_method_object_addr);
-
-  // Load arguments listing in the dec_insn
-  unsigned arg_idx = 0;
-
-  if (!is_static) {
-    // Push "this" for non-static method
-    args.push_back(this_addr);
-    arg_idx++;
-  }
-
-  // Load argument values according to the shorty
-  for (uint32_t i = 1; i < callee_shorty_size; i++) {
-    unsigned reg_idx = (arg_fmt == kArgRange) ? (dec_insn.vC + arg_idx) :
-                                                (dec_insn.arg[arg_idx]);
-    JType jty = GetJTypeFromShorty(callee_shorty[i]);
-    args.push_back(EmitLoadDalvikReg(reg_idx, jty, kAccurate));
-    arg_idx++;
-
-    if (GetRegCategoryFromJType(jty) == kRegCat2) {
-      // Wide types occupied two registers
-      arg_idx++;
-    }
-  }
-
-  DCHECK_EQ(arg_idx, dec_insn.vA)
-    << "Actual argument mismatch for callee: "
-    << PrettyMethod(callee_method_idx, *dex_file_);
-
-  llvm::Value* retval = EmitInvokeIntrinsic(dex_pc, true, invoke_intrinsic, args);
-
-  // Store the return value for the subsequent move-result
-  if (callee_shorty[0] != 'V') {
-    EmitStoreDalvikRetValReg(callee_ret_jty, kAccurate, retval);
-  }
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_Neg(unsigned dex_pc, const Instruction* insn,
-                           JType op_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  llvm::Value* result_value = irb_.CreateNeg(src_value);
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_Not(unsigned dex_pc, const Instruction* insn,
-                           JType op_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  llvm::Value* result_value = irb_.CreateXor(src_value, 0xFFFFFFFFFFFFFFFFLL);
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_SExt(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-  llvm::Value* result_value = irb_.CreateSExt(src_value, irb_.GetJLongTy());
-  EmitStoreDalvikReg(dec_insn.vA, kLong, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_Trunc(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kLong, kAccurate);
-  llvm::Value* result_value = irb_.CreateTrunc(src_value, irb_.GetJIntTy());
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_TruncAndSExt(unsigned dex_pc, const Instruction* insn,
-                                    unsigned N) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* trunc_value =
-    irb_.CreateTrunc(src_value, llvm::Type::getIntNTy(context_, N));
-
-  llvm::Value* result_value = irb_.CreateSExt(trunc_value, irb_.GetJIntTy());
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_TruncAndZExt(unsigned dex_pc, const Instruction* insn,
-                                    unsigned N) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* trunc_value =
-    irb_.CreateTrunc(src_value, llvm::Type::getIntNTy(context_, N));
-
-  llvm::Value* result_value = irb_.CreateZExt(trunc_value, irb_.GetJIntTy());
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FNeg(unsigned dex_pc, const Instruction* insn,
-                            JType op_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kFloat || op_jty == kDouble) << op_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  llvm::Value* result_value = irb_.CreateFNeg(src_value);
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IntToFP(unsigned dex_pc, const Instruction* insn,
-                               JType src_jty, JType dest_jty) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(src_jty == kInt || src_jty == kLong) << src_jty;
-  DCHECK(dest_jty == kFloat || dest_jty == kDouble) << dest_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, src_jty, kAccurate);
-  llvm::Type* dest_type = irb_.GetJType(dest_jty, kAccurate);
-  llvm::Value* dest_value = irb_.CreateSIToFP(src_value, dest_type);
-  EmitStoreDalvikReg(dec_insn.vA, dest_jty, kAccurate, dest_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FPToInt(unsigned dex_pc, const Instruction* insn,
-                               JType src_jty, JType dest_jty,
-                               IntrinsicHelper::IntrinsicId intr_id) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(src_jty == kFloat || src_jty == kDouble) << src_jty;
-  DCHECK(dest_jty == kInt || dest_jty == kLong) << dest_jty;
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, src_jty, kAccurate);
-  llvm::Value* dest_value = EmitInvokeIntrinsicNoThrow(intr_id, src_value);
-  EmitStoreDalvikReg(dec_insn.vA, dest_jty, kAccurate, dest_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FExt(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kFloat, kAccurate);
-  llvm::Value* result_value = irb_.CreateFPExt(src_value, irb_.GetJDoubleTy());
-  EmitStoreDalvikReg(dec_insn.vA, kDouble, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FTrunc(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kDouble, kAccurate);
-  llvm::Value* result_value = irb_.CreateFPTrunc(src_value, irb_.GetJFloatTy());
-  EmitStoreDalvikReg(dec_insn.vA, kFloat, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IntArithm(unsigned dex_pc, const Instruction* insn,
-                                 IntArithmKind arithm, JType op_jty,
-                                 bool is_2addr) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (is_2addr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vC, op_jty, kAccurate);
-  }
-
-  llvm::Value* result_value =
-    EmitIntArithmResultComputation(dex_pc, src1_value, src2_value,
-                                   arithm, op_jty);
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IntArithmImmediate(unsigned dex_pc,
-                                          const Instruction* insn,
-                                          IntArithmKind arithm) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* imm_value = irb_.getInt32(dec_insn.vC);
-
-  llvm::Value* result_value =
-    EmitIntArithmResultComputation(dex_pc, src_value, imm_value, arithm, kInt);
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IntShiftArithm(unsigned dex_pc, const Instruction* insn,
-                                      IntShiftArithmKind arithm, JType op_jty,
-                                      bool is_2addr) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kInt || op_jty == kLong) << op_jty;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  // NOTE: The 2nd operand of the shift arithmetic instruction is
-  // 32-bit integer regardless of the 1st operand.
-  if (is_2addr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vC, kInt, kAccurate);
-  }
-
-  llvm::Value* result_value = EmitIntShiftArithmResultComputation(dex_pc,
-                                                                  src1_value,
-                                                                  src2_value,
-                                                                  arithm,
-                                                                  op_jty);
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_IntShiftArithmImmediate(unsigned dex_pc,
-                                               const Instruction* insn,
-                                               IntShiftArithmKind arithm) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-
-  llvm::Value* imm_value = irb_.getInt32(dec_insn.vC);
-
-  llvm::Value* result_value = EmitIntShiftArithmResultComputation(dex_pc,
-                                                                  src_value,
-                                                                  imm_value,
-                                                                  arithm, kInt);
-
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_RSubImmediate(unsigned dex_pc, const Instruction* insn) {
-  DecodedInstruction dec_insn(insn);
-
-  llvm::Value* src_value = EmitLoadDalvikReg(dec_insn.vB, kInt, kAccurate);
-  llvm::Value* imm_value = irb_.getInt32(dec_insn.vC);
-  llvm::Value* result_value = irb_.CreateSub(imm_value, src_value);
-  EmitStoreDalvikReg(dec_insn.vA, kInt, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-void DexLang::EmitInsn_FPArithm(unsigned dex_pc, const Instruction* insn,
-                                FPArithmKind arithm, JType op_jty,
-                                bool is_2addr) {
-  DecodedInstruction dec_insn(insn);
-
-  DCHECK(op_jty == kFloat || op_jty == kDouble) << op_jty;
-
-  llvm::Value* src1_value;
-  llvm::Value* src2_value;
-
-  if (is_2addr) {
-    src1_value = EmitLoadDalvikReg(dec_insn.vA, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-  } else {
-    src1_value = EmitLoadDalvikReg(dec_insn.vB, op_jty, kAccurate);
-    src2_value = EmitLoadDalvikReg(dec_insn.vC, op_jty, kAccurate);
-  }
-
-  llvm::Value* result_value;
-  switch (arithm) {
-    case kFPArithm_Add: {
-      result_value = irb_.CreateFAdd(src1_value, src2_value);
-      break;
-    }
-    case kFPArithm_Sub: {
-      result_value = irb_.CreateFSub(src1_value, src2_value);
-      break;
-    }
-    case kFPArithm_Mul: {
-      result_value = irb_.CreateFMul(src1_value, src2_value);
-      break;
-    }
-    case kFPArithm_Div: {
-      result_value = irb_.CreateFDiv(src1_value, src2_value);
-      break;
-    }
-    case kFPArithm_Rem: {
-      result_value = irb_.CreateFRem(src1_value, src2_value);
-      break;
-    }
-    default: {
-      LOG(FATAL) << "Unknown floating-point arithmetic kind: " << arithm;
-      return;
-    }
-  }
-
-  EmitStoreDalvikReg(dec_insn.vA, op_jty, kAccurate, result_value);
-
-  irb_.CreateBr(GetNextBasicBlock(dex_pc));
-  return;
-}
-
-bool DexLang::EmitInstructions() {
-  unsigned dex_pc = 0;
-  while (dex_pc < code_item_->insns_size_in_code_units_) {
-    const Instruction* insn = Instruction::At(code_item_->insns_ + dex_pc);
-    if (!EmitInstruction(dex_pc, insn)) {
-      return false;
-    }
-    dex_pc += insn->SizeInCodeUnits();
-  }
-  return true;
-}
-
-bool DexLang::EmitInstruction(unsigned dex_pc, const Instruction* insn) {
-  // Set the IRBuilder insertion point
-  irb_.SetInsertPoint(GetBasicBlock(dex_pc));
-
-#define ARGS dex_pc, insn
-
-  // Dispatch the instruction
-  switch (insn->Opcode()) {
-    case Instruction::NOP: {
-      EmitInsn_Nop(ARGS);
-      break;
-    }
-    case Instruction::MOVE:
-    case Instruction::MOVE_FROM16:
-    case Instruction::MOVE_16: {
-      EmitInsn_Move(ARGS, kInt);
-      break;
-    }
-    case Instruction::MOVE_WIDE:
-    case Instruction::MOVE_WIDE_FROM16:
-    case Instruction::MOVE_WIDE_16: {
-      EmitInsn_Move(ARGS, kLong);
-      break;
-    }
-    case Instruction::MOVE_OBJECT:
-    case Instruction::MOVE_OBJECT_FROM16:
-    case Instruction::MOVE_OBJECT_16: {
-      EmitInsn_Move(ARGS, kObject);
-      break;
-    }
-    case Instruction::MOVE_RESULT: {
-      EmitInsn_MoveResult(ARGS, kInt);
-      break;
-    }
-    case Instruction::MOVE_RESULT_WIDE: {
-      EmitInsn_MoveResult(ARGS, kLong);
-      break;
-    }
-    case Instruction::MOVE_RESULT_OBJECT: {
-      EmitInsn_MoveResult(ARGS, kObject);
-      break;
-    }
-    case Instruction::MOVE_EXCEPTION: {
-      EmitInsn_MoveException(ARGS);
-      break;
-    }
-    case Instruction::RETURN_VOID: {
-      EmitInsn_ReturnVoid(ARGS);
-      break;
-    }
-    case Instruction::RETURN:
-    case Instruction::RETURN_WIDE:
-    case Instruction::RETURN_OBJECT: {
-      EmitInsn_Return(ARGS);
-      break;
-    }
-    case Instruction::CONST_4:
-    case Instruction::CONST_16:
-    case Instruction::CONST:
-    case Instruction::CONST_HIGH16: {
-      EmitInsn_LoadConstant(ARGS, kInt);
-      break;
-    }
-    case Instruction::CONST_WIDE_16:
-    case Instruction::CONST_WIDE_32:
-    case Instruction::CONST_WIDE:
-    case Instruction::CONST_WIDE_HIGH16: {
-      EmitInsn_LoadConstant(ARGS, kLong);
-      break;
-    }
-    case Instruction::CONST_STRING:
-    case Instruction::CONST_STRING_JUMBO: {
-      EmitInsn_LoadConstantString(ARGS);
-      break;
-    }
-    case Instruction::CONST_CLASS: {
-      EmitInsn_LoadConstantClass(ARGS);
-      break;
-    }
-    case Instruction::MONITOR_ENTER: {
-      EmitInsn_MonitorEnter(ARGS);
-      break;
-    }
-    case Instruction::MONITOR_EXIT: {
-      EmitInsn_MonitorExit(ARGS);
-      break;
-    }
-    case Instruction::CHECK_CAST: {
-      EmitInsn_CheckCast(ARGS);
-      break;
-    }
-    case Instruction::INSTANCE_OF: {
-      EmitInsn_InstanceOf(ARGS);
-      break;
-    }
-    case Instruction::ARRAY_LENGTH: {
-      EmitInsn_ArrayLength(ARGS);
-      break;
-    }
-    case Instruction::NEW_INSTANCE:
-      EmitInsn_NewInstance(ARGS);
-      break;
-
-    case Instruction::NEW_ARRAY: {
-      EmitInsn_NewArray(ARGS);
-      break;
-    }
-    case Instruction::FILLED_NEW_ARRAY:
-      EmitInsn_FilledNewArray(ARGS, /* is_range */false);
-      break;
-
-    case Instruction::FILLED_NEW_ARRAY_RANGE:
-      EmitInsn_FilledNewArray(ARGS, /* is_range */true);
-      break;
-
-    case Instruction::FILL_ARRAY_DATA:
-      EmitInsn_FillArrayData(ARGS);
-      break;
-
-    case Instruction::THROW: {
-      EmitInsn_ThrowException(ARGS);
-      break;
-    }
-    case Instruction::GOTO:
-    case Instruction::GOTO_16:
-    case Instruction::GOTO_32: {
-      EmitInsn_UnconditionalBranch(ARGS);
-      break;
-    }
-    case Instruction::PACKED_SWITCH: {
-      EmitInsn_PackedSwitch(ARGS);
-      break;
-    }
-    case Instruction::SPARSE_SWITCH: {
-      EmitInsn_SparseSwitch(ARGS);
-      break;
-    }
-    case Instruction::CMPL_FLOAT: {
-      EmitInsn_FPCompare(ARGS, kFloat, false);
-      break;
-    }
-    case Instruction::CMPG_FLOAT: {
-      EmitInsn_FPCompare(ARGS, kFloat, true);
-      break;
-    }
-    case Instruction::CMPL_DOUBLE: {
-      EmitInsn_FPCompare(ARGS, kDouble, false);
-      break;
-    }
-    case Instruction::CMPG_DOUBLE: {
-      EmitInsn_FPCompare(ARGS, kDouble, true);
-      break;
-    }
-    case Instruction::CMP_LONG: {
-      EmitInsn_LongCompare(ARGS);
-      break;
-    }
-    case Instruction::IF_EQ: {
-      EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_EQ);
-      break;
-    }
-    case Instruction::IF_NE: {
-      EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_NE);
-      break;
-    }
-    case Instruction::IF_LT: {
-      EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_LT);
-      break;
-    }
-    case Instruction::IF_GE: {
-      EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_GE);
-      break;
-    }
-    case Instruction::IF_GT: {
-      EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_GT);
-      break;
-    }
-    case Instruction::IF_LE: {
-      EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_LE);
-      break;
-    }
-    case Instruction::IF_EQZ: {
-      EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_EQ);
-      break;
-    }
-    case Instruction::IF_NEZ: {
-      EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_NE);
-      break;
-    }
-    case Instruction::IF_LTZ: {
-      EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_LT);
-      break;
-    }
-    case Instruction::IF_GEZ: {
-      EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_GE);
-      break;
-    }
-    case Instruction::IF_GTZ: {
-      EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_GT);
-      break;
-    }
-    case Instruction::IF_LEZ: {
-      EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_LE);
-      break;
-    }
-    case Instruction::AGET: {
-      EmitInsn_AGet(ARGS, kInt);
-      break;
-    }
-    case Instruction::AGET_WIDE: {
-      EmitInsn_AGet(ARGS, kLong);
-      break;
-    }
-    case Instruction::AGET_OBJECT: {
-      EmitInsn_AGet(ARGS, kObject);
-      break;
-    }
-    case Instruction::AGET_BOOLEAN: {
-      EmitInsn_AGet(ARGS, kBoolean);
-      break;
-    }
-    case Instruction::AGET_BYTE: {
-      EmitInsn_AGet(ARGS, kByte);
-      break;
-    }
-    case Instruction::AGET_CHAR: {
-      EmitInsn_AGet(ARGS, kChar);
-      break;
-    }
-    case Instruction::AGET_SHORT: {
-      EmitInsn_AGet(ARGS, kShort);
-      break;
-    }
-    case Instruction::APUT: {
-      EmitInsn_APut(ARGS, kInt);
-      break;
-    }
-    case Instruction::APUT_WIDE: {
-      EmitInsn_APut(ARGS, kLong);
-      break;
-    }
-    case Instruction::APUT_OBJECT: {
-      EmitInsn_APut(ARGS, kObject);
-      break;
-    }
-    case Instruction::APUT_BOOLEAN: {
-      EmitInsn_APut(ARGS, kBoolean);
-      break;
-    }
-    case Instruction::APUT_BYTE: {
-      EmitInsn_APut(ARGS, kByte);
-      break;
-    }
-    case Instruction::APUT_CHAR: {
-      EmitInsn_APut(ARGS, kChar);
-      break;
-    }
-    case Instruction::APUT_SHORT: {
-      EmitInsn_APut(ARGS, kShort);
-      break;
-    }
-    case Instruction::IGET: {
-      EmitInsn_IGet(ARGS, kInt);
-      break;
-    }
-    case Instruction::IGET_WIDE: {
-      EmitInsn_IGet(ARGS, kLong);
-      break;
-    }
-    case Instruction::IGET_OBJECT: {
-      EmitInsn_IGet(ARGS, kObject);
-      break;
-    }
-    case Instruction::IGET_BOOLEAN: {
-      EmitInsn_IGet(ARGS, kBoolean);
-      break;
-    }
-    case Instruction::IGET_BYTE: {
-      EmitInsn_IGet(ARGS, kByte);
-      break;
-    }
-    case Instruction::IGET_CHAR: {
-      EmitInsn_IGet(ARGS, kChar);
-      break;
-    }
-    case Instruction::IGET_SHORT: {
-      EmitInsn_IGet(ARGS, kShort);
-      break;
-    }
-    case Instruction::IPUT: {
-      EmitInsn_IPut(ARGS, kInt);
-      break;
-    }
-    case Instruction::IPUT_WIDE: {
-      EmitInsn_IPut(ARGS, kLong);
-      break;
-    }
-    case Instruction::IPUT_OBJECT: {
-      EmitInsn_IPut(ARGS, kObject);
-      break;
-    }
-    case Instruction::IPUT_BOOLEAN: {
-      EmitInsn_IPut(ARGS, kBoolean);
-      break;
-    }
-    case Instruction::IPUT_BYTE: {
-      EmitInsn_IPut(ARGS, kByte);
-      break;
-    }
-    case Instruction::IPUT_CHAR: {
-      EmitInsn_IPut(ARGS, kChar);
-      break;
-    }
-    case Instruction::IPUT_SHORT: {
-      EmitInsn_IPut(ARGS, kShort);
-      break;
-    }
-    case Instruction::SGET: {
-      EmitInsn_SGet(ARGS, kInt);
-      break;
-    }
-    case Instruction::SGET_WIDE: {
-      EmitInsn_SGet(ARGS, kLong);
-      break;
-    }
-    case Instruction::SGET_OBJECT: {
-      EmitInsn_SGet(ARGS, kObject);
-      break;
-    }
-    case Instruction::SGET_BOOLEAN: {
-      EmitInsn_SGet(ARGS, kBoolean);
-      break;
-    }
-    case Instruction::SGET_BYTE: {
-      EmitInsn_SGet(ARGS, kByte);
-      break;
-    }
-    case Instruction::SGET_CHAR: {
-      EmitInsn_SGet(ARGS, kChar);
-      break;
-    }
-    case Instruction::SGET_SHORT: {
-      EmitInsn_SGet(ARGS, kShort);
-      break;
-    }
-    case Instruction::SPUT: {
-      EmitInsn_SPut(ARGS, kInt);
-      break;
-    }
-    case Instruction::SPUT_WIDE: {
-      EmitInsn_SPut(ARGS, kLong);
-      break;
-    }
-    case Instruction::SPUT_OBJECT: {
-      EmitInsn_SPut(ARGS, kObject);
-      break;
-    }
-    case Instruction::SPUT_BOOLEAN: {
-      EmitInsn_SPut(ARGS, kBoolean);
-      break;
-    }
-    case Instruction::SPUT_BYTE: {
-      EmitInsn_SPut(ARGS, kByte);
-      break;
-    }
-    case Instruction::SPUT_CHAR: {
-      EmitInsn_SPut(ARGS, kChar);
-      break;
-    }
-    case Instruction::SPUT_SHORT: {
-      EmitInsn_SPut(ARGS, kShort);
-      break;
-    }
-    case Instruction::INVOKE_VIRTUAL: {
-      EmitInsn_Invoke(ARGS, kVirtual, kArgReg);
-      break;
-    }
-    case Instruction::INVOKE_SUPER: {
-      EmitInsn_Invoke(ARGS, kSuper, kArgReg);
-      break;
-    }
-    case Instruction::INVOKE_DIRECT: {
-      EmitInsn_Invoke(ARGS, kDirect, kArgReg);
-      break;
-    }
-    case Instruction::INVOKE_STATIC: {
-      EmitInsn_Invoke(ARGS, kStatic, kArgReg);
-      break;
-    }
-    case Instruction::INVOKE_INTERFACE: {
-      EmitInsn_Invoke(ARGS, kInterface, kArgReg);
-      break;
-    }
-    case Instruction::INVOKE_VIRTUAL_RANGE: {
-      EmitInsn_Invoke(ARGS, kVirtual, kArgRange);
-      break;
-    }
-    case Instruction::INVOKE_SUPER_RANGE: {
-      EmitInsn_Invoke(ARGS, kSuper, kArgRange);
-      break;
-    }
-    case Instruction::INVOKE_DIRECT_RANGE: {
-      EmitInsn_Invoke(ARGS, kDirect, kArgRange);
-      break;
-    }
-    case Instruction::INVOKE_STATIC_RANGE: {
-      EmitInsn_Invoke(ARGS, kStatic, kArgRange);
-      break;
-    }
-    case Instruction::INVOKE_INTERFACE_RANGE: {
-      EmitInsn_Invoke(ARGS, kInterface, kArgRange);
-      break;
-    }
-    case Instruction::NEG_INT: {
-      EmitInsn_Neg(ARGS, kInt);
-      break;
-    }
-    case Instruction::NOT_INT: {
-      EmitInsn_Not(ARGS, kInt);
-      break;
-    }
-    case Instruction::NEG_LONG: {
-      EmitInsn_Neg(ARGS, kLong);
-      break;
-    }
-    case Instruction::NOT_LONG: {
-      EmitInsn_Not(ARGS, kLong);
-      break;
-    }
-    case Instruction::NEG_FLOAT: {
-      EmitInsn_FNeg(ARGS, kFloat);
-      break;
-    }
-    case Instruction::NEG_DOUBLE: {
-      EmitInsn_FNeg(ARGS, kDouble);
-      break;
-    }
-    case Instruction::INT_TO_LONG: {
-      EmitInsn_SExt(ARGS);
-      break;
-    }
-    case Instruction::INT_TO_FLOAT: {
-      EmitInsn_IntToFP(ARGS, kInt, kFloat);
-      break;
-    }
-    case Instruction::INT_TO_DOUBLE: {
-      EmitInsn_IntToFP(ARGS, kInt, kDouble);
-      break;
-    }
-    case Instruction::LONG_TO_INT: {
-      EmitInsn_Trunc(ARGS);
-      break;
-    }
-    case Instruction::LONG_TO_FLOAT: {
-      EmitInsn_IntToFP(ARGS, kLong, kFloat);
-      break;
-    }
-    case Instruction::LONG_TO_DOUBLE: {
-      EmitInsn_IntToFP(ARGS, kLong, kDouble);
-      break;
-    }
-    case Instruction::FLOAT_TO_INT: {
-      EmitInsn_FPToInt(ARGS, kFloat, kInt, IntrinsicHelper::F2I);
-      break;
-    }
-    case Instruction::FLOAT_TO_LONG: {
-      EmitInsn_FPToInt(ARGS, kFloat, kLong, IntrinsicHelper::F2L);
-      break;
-    }
-    case Instruction::FLOAT_TO_DOUBLE: {
-      EmitInsn_FExt(ARGS);
-      break;
-    }
-    case Instruction::DOUBLE_TO_INT: {
-      EmitInsn_FPToInt(ARGS, kDouble, kInt, IntrinsicHelper::D2I);
-      break;
-    }
-    case Instruction::DOUBLE_TO_LONG: {
-      EmitInsn_FPToInt(ARGS, kDouble, kLong, IntrinsicHelper::D2L);
-      break;
-    }
-    case Instruction::DOUBLE_TO_FLOAT: {
-      EmitInsn_FTrunc(ARGS);
-      break;
-    }
-    case Instruction::INT_TO_BYTE: {
-      EmitInsn_TruncAndSExt(ARGS, 8);
-      break;
-    }
-    case Instruction::INT_TO_CHAR: {
-      EmitInsn_TruncAndZExt(ARGS, 16);
-      break;
-    }
-    case Instruction::INT_TO_SHORT: {
-      EmitInsn_TruncAndSExt(ARGS, 16);
-      break;
-    }
-    case Instruction::ADD_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Add, kInt, false);
-      break;
-    }
-    case Instruction::SUB_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kInt, false);
-      break;
-    }
-    case Instruction::MUL_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kInt, false);
-      break;
-    }
-    case Instruction::DIV_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Div, kInt, false);
-      break;
-    }
-    case Instruction::REM_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kInt, false);
-      break;
-    }
-    case Instruction::AND_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_And, kInt, false);
-      break;
-    }
-    case Instruction::OR_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Or, kInt, false);
-      break;
-    }
-    case Instruction::XOR_INT: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kInt, false);
-      break;
-    }
-    case Instruction::SHL_INT: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kInt, false);
-      break;
-    }
-    case Instruction::SHR_INT: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kInt, false);
-      break;
-    }
-    case Instruction::USHR_INT: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kInt, false);
-      break;
-    }
-    case Instruction::ADD_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Add, kLong, false);
-      break;
-    }
-    case Instruction::SUB_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kLong, false);
-      break;
-    }
-    case Instruction::MUL_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kLong, false);
-      break;
-    }
-    case Instruction::DIV_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Div, kLong, false);
-      break;
-    }
-    case Instruction::REM_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kLong, false);
-      break;
-    }
-    case Instruction::AND_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_And, kLong, false);
-      break;
-    }
-    case Instruction::OR_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Or, kLong, false);
-      break;
-    }
-    case Instruction::XOR_LONG: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kLong, false);
-      break;
-    }
-    case Instruction::SHL_LONG: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kLong, false);
-      break;
-    }
-    case Instruction::SHR_LONG: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kLong, false);
-      break;
-    }
-    case Instruction::USHR_LONG: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kLong, false);
-      break;
-    }
-    case Instruction::ADD_FLOAT: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Add, kFloat, false);
-      break;
-    }
-    case Instruction::SUB_FLOAT: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kFloat, false);
-      break;
-    }
-    case Instruction::MUL_FLOAT: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kFloat, false);
-      break;
-    }
-    case Instruction::DIV_FLOAT: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Div, kFloat, false);
-      break;
-    }
-    case Instruction::REM_FLOAT: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kFloat, false);
-      break;
-    }
-    case Instruction::ADD_DOUBLE: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Add, kDouble, false);
-      break;
-    }
-    case Instruction::SUB_DOUBLE: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kDouble, false);
-      break;
-    }
-    case Instruction::MUL_DOUBLE: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kDouble, false);
-      break;
-    }
-    case Instruction::DIV_DOUBLE: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Div, kDouble, false);
-      break;
-    }
-    case Instruction::REM_DOUBLE: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kDouble, false);
-      break;
-    }
-    case Instruction::ADD_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Add, kInt, true);
-      break;
-    }
-    case Instruction::SUB_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kInt, true);
-      break;
-    }
-    case Instruction::MUL_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kInt, true);
-      break;
-    }
-    case Instruction::DIV_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Div, kInt, true);
-      break;
-    }
-    case Instruction::REM_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kInt, true);
-      break;
-    }
-    case Instruction::AND_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_And, kInt, true);
-      break;
-    }
-    case Instruction::OR_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Or, kInt, true);
-      break;
-    }
-    case Instruction::XOR_INT_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kInt, true);
-      break;
-    }
-    case Instruction::SHL_INT_2ADDR: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kInt, true);
-      break;
-    }
-    case Instruction::SHR_INT_2ADDR: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kInt, true);
-      break;
-    }
-    case Instruction::USHR_INT_2ADDR: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kInt, true);
-      break;
-    }
-    case Instruction::ADD_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Add, kLong, true);
-      break;
-    }
-    case Instruction::SUB_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kLong, true);
-      break;
-    }
-    case Instruction::MUL_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kLong, true);
-      break;
-    }
-    case Instruction::DIV_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Div, kLong, true);
-      break;
-    }
-    case Instruction::REM_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kLong, true);
-      break;
-    }
-    case Instruction::AND_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_And, kLong, true);
-      break;
-    }
-    case Instruction::OR_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Or, kLong, true);
-      break;
-    }
-    case Instruction::XOR_LONG_2ADDR: {
-      EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kLong, true);
-      break;
-    }
-    case Instruction::SHL_LONG_2ADDR: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shl, kLong, true);
-      break;
-    }
-    case Instruction::SHR_LONG_2ADDR: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_Shr, kLong, true);
-      break;
-    }
-    case Instruction::USHR_LONG_2ADDR: {
-      EmitInsn_IntShiftArithm(ARGS, kIntArithm_UShr, kLong, true);
-      break;
-    }
-    case Instruction::ADD_FLOAT_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Add, kFloat, true);
-      break;
-    }
-    case Instruction::SUB_FLOAT_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kFloat, true);
-      break;
-    }
-    case Instruction::MUL_FLOAT_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kFloat, true);
-      break;
-    }
-    case Instruction::DIV_FLOAT_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Div, kFloat, true);
-      break;
-    }
-    case Instruction::REM_FLOAT_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kFloat, true);
-      break;
-    }
-    case Instruction::ADD_DOUBLE_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Add, kDouble, true);
-      break;
-    }
-    case Instruction::SUB_DOUBLE_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kDouble, true);
-      break;
-    }
-    case Instruction::MUL_DOUBLE_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kDouble, true);
-      break;
-    }
-    case Instruction::DIV_DOUBLE_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Div, kDouble, true);
-      break;
-    }
-    case Instruction::REM_DOUBLE_2ADDR: {
-      EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kDouble, true);
-      break;
-    }
-    case Instruction::ADD_INT_LIT16:
-    case Instruction::ADD_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Add);
-      break;
-    }
-    case Instruction::RSUB_INT:
-    case Instruction::RSUB_INT_LIT8: {
-      EmitInsn_RSubImmediate(ARGS);
-      break;
-    }
-    case Instruction::MUL_INT_LIT16:
-    case Instruction::MUL_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Mul);
-      break;
-    }
-    case Instruction::DIV_INT_LIT16:
-    case Instruction::DIV_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Div);
-      break;
-    }
-    case Instruction::REM_INT_LIT16:
-    case Instruction::REM_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Rem);
-      break;
-    }
-    case Instruction::AND_INT_LIT16:
-    case Instruction::AND_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_And);
-      break;
-    }
-    case Instruction::OR_INT_LIT16:
-    case Instruction::OR_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Or);
-      break;
-    }
-    case Instruction::XOR_INT_LIT16:
-    case Instruction::XOR_INT_LIT8: {
-      EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Xor);
-      break;
-    }
-    case Instruction::SHL_INT_LIT8: {
-      EmitInsn_IntShiftArithmImmediate(ARGS, kIntArithm_Shl);
-      break;
-    }
-    case Instruction::SHR_INT_LIT8: {
-      EmitInsn_IntShiftArithmImmediate(ARGS, kIntArithm_Shr);
-      break;
-    }
-    case Instruction::USHR_INT_LIT8: {
-      EmitInsn_IntShiftArithmImmediate(ARGS, kIntArithm_UShr);
-      break;
-    }
-
-    case Instruction::UNUSED_3E:
-    case Instruction::UNUSED_3F:
-    case Instruction::UNUSED_40:
-    case Instruction::UNUSED_41:
-    case Instruction::UNUSED_42:
-    case Instruction::UNUSED_43:
-    case Instruction::UNUSED_73:
-    case Instruction::UNUSED_79:
-    case Instruction::UNUSED_7A:
-    case Instruction::UNUSED_E3:
-    case Instruction::UNUSED_E4:
-    case Instruction::UNUSED_E5:
-    case Instruction::UNUSED_E6:
-    case Instruction::UNUSED_E7:
-    case Instruction::UNUSED_E8:
-    case Instruction::UNUSED_E9:
-    case Instruction::UNUSED_EA:
-    case Instruction::UNUSED_EB:
-    case Instruction::UNUSED_EC:
-    case Instruction::UNUSED_ED:
-    case Instruction::UNUSED_EE:
-    case Instruction::UNUSED_EF:
-    case Instruction::UNUSED_F0:
-    case Instruction::UNUSED_F1:
-    case Instruction::UNUSED_F2:
-    case Instruction::UNUSED_F3:
-    case Instruction::UNUSED_F4:
-    case Instruction::UNUSED_F5:
-    case Instruction::UNUSED_F6:
-    case Instruction::UNUSED_F7:
-    case Instruction::UNUSED_F8:
-    case Instruction::UNUSED_F9:
-    case Instruction::UNUSED_FA:
-    case Instruction::UNUSED_FB:
-    case Instruction::UNUSED_FC:
-    case Instruction::UNUSED_FD:
-    case Instruction::UNUSED_FE:
-    case Instruction::UNUSED_FF: {
-      LOG(FATAL) << "Dex file contains UNUSED bytecode: " << insn->Opcode();
-    }
-  }
-#undef ARGS
-
-  return true;
-}
-
-
-bool DexLang::IsInstructionDirectToReturn(unsigned dex_pc) {
-  for (int i = 0; i < 8; ++i) {  // Trace at most 8 instructions.
-    if (dex_pc >= code_item_->insns_size_in_code_units_) {
-      return false;
-    }
-
-    Instruction const* insn = Instruction::At(code_item_->insns_ + dex_pc);
-
-    if (insn->IsReturn()) {
-      return true;
-    }
-
-    // Is throw, switch, invoke or conditional branch.
-    if (insn->IsThrow() || insn->IsSwitch() || insn->IsInvoke() ||
-        (insn->IsBranch() && !insn->IsUnconditional())) {
-      return false;
-    }
-
-    switch (insn->Opcode()) {
-    default:
-      dex_pc += insn->SizeInCodeUnits();
-      break;
-
-    // This instruction will remove the exception. Consider as a side effect.
-    case Instruction::MOVE_EXCEPTION:
-      return false;
-      break;
-
-    case Instruction::GOTO:
-    case Instruction::GOTO_16:
-    case Instruction::GOTO_32:
-      {
-        DecodedInstruction dec_insn(insn);
-        int32_t branch_offset = dec_insn.vA;
-        dex_pc += branch_offset;
-      }
-      break;
-    }
-  }
-  return false;
-}
-
-
-// TODO: Use high-level IR to do this
-void DexLang::ComputeMethodInfo() {
-  // If this method is static, we set the "this" register index to -1. So we don't worry about this
-  // method is static or not in the following comparison.
-  int64_t this_reg_idx = (cunit_.IsStatic()) ?
-                         (-1) :
-                         (code_item_->registers_size_ - code_item_->ins_size_);
-  bool has_invoke = false;
-  bool may_have_loop = false;
-  bool may_throw_exception = false;
-  bool assume_this_non_null = false;
-  std::vector<bool>& set_to_another_object = method_info_.set_to_another_object;
-  set_to_another_object.resize(code_item_->registers_size_, false);
-
-  Instruction const* insn;
-  for (uint32_t dex_pc = 0;
-       dex_pc < code_item_->insns_size_in_code_units_;
-       dex_pc += insn->SizeInCodeUnits()) {
-    insn = Instruction::At(code_item_->insns_ + dex_pc);
-    DecodedInstruction dec_insn(insn);
-
-    switch (insn->Opcode()) {
-    case Instruction::NOP:
-      break;
-
-    case Instruction::MOVE:
-    case Instruction::MOVE_FROM16:
-    case Instruction::MOVE_16:
-    case Instruction::MOVE_WIDE:
-    case Instruction::MOVE_WIDE_FROM16:
-    case Instruction::MOVE_WIDE_16:
-    case Instruction::MOVE_RESULT:
-    case Instruction::MOVE_RESULT_WIDE:
-      break;
-
-    case Instruction::MOVE_OBJECT:
-    case Instruction::MOVE_OBJECT_FROM16:
-    case Instruction::MOVE_OBJECT_16:
-    case Instruction::MOVE_RESULT_OBJECT:
-    case Instruction::MOVE_EXCEPTION:
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::RETURN_VOID:
-    case Instruction::RETURN:
-    case Instruction::RETURN_WIDE:
-    case Instruction::RETURN_OBJECT:
-      break;
-
-    case Instruction::CONST_4:
-    case Instruction::CONST_16:
-    case Instruction::CONST:
-    case Instruction::CONST_HIGH16:
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::CONST_WIDE_16:
-    case Instruction::CONST_WIDE_32:
-    case Instruction::CONST_WIDE:
-    case Instruction::CONST_WIDE_HIGH16:
-      break;
-
-    case Instruction::CONST_STRING:
-    case Instruction::CONST_STRING_JUMBO:
-      // TODO: Will the ResolveString throw exception?
-      if (!compiler_.CanAssumeStringIsPresentInDexCache(*dex_file_, dec_insn.vB)) {
-        may_throw_exception = true;
-      }
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::CONST_CLASS:
-      may_throw_exception = true;
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::MONITOR_ENTER:
-    case Instruction::MONITOR_EXIT:
-    case Instruction::CHECK_CAST:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::ARRAY_LENGTH:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::INSTANCE_OF:
-    case Instruction::NEW_INSTANCE:
-    case Instruction::NEW_ARRAY:
-      may_throw_exception = true;
-      set_to_another_object[dec_insn.vA] = true;
-      break;
-
-    case Instruction::FILLED_NEW_ARRAY:
-    case Instruction::FILLED_NEW_ARRAY_RANGE:
-    case Instruction::FILL_ARRAY_DATA:
-    case Instruction::THROW:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::GOTO:
-    case Instruction::GOTO_16:
-    case Instruction::GOTO_32:
-      {
-        int32_t branch_offset = dec_insn.vA;
-        if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-          may_have_loop = true;
-        }
-      }
-      break;
-
-    case Instruction::PACKED_SWITCH:
-    case Instruction::SPARSE_SWITCH:
-    case Instruction::CMPL_FLOAT:
-    case Instruction::CMPG_FLOAT:
-    case Instruction::CMPL_DOUBLE:
-    case Instruction::CMPG_DOUBLE:
-    case Instruction::CMP_LONG:
-      break;
-
-    case Instruction::IF_EQ:
-    case Instruction::IF_NE:
-    case Instruction::IF_LT:
-    case Instruction::IF_GE:
-    case Instruction::IF_GT:
-    case Instruction::IF_LE:
-      {
-        int32_t branch_offset = dec_insn.vC;
-        if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-          may_have_loop = true;
-        }
-      }
-      break;
-
-    case Instruction::IF_EQZ:
-    case Instruction::IF_NEZ:
-    case Instruction::IF_LTZ:
-    case Instruction::IF_GEZ:
-    case Instruction::IF_GTZ:
-    case Instruction::IF_LEZ:
-      {
-        int32_t branch_offset = dec_insn.vB;
-        if (branch_offset <= 0 && !IsInstructionDirectToReturn(dex_pc + branch_offset)) {
-          may_have_loop = true;
-        }
-      }
-      break;
-
-    case Instruction::AGET:
-    case Instruction::AGET_WIDE:
-    case Instruction::AGET_OBJECT:
-    case Instruction::AGET_BOOLEAN:
-    case Instruction::AGET_BYTE:
-    case Instruction::AGET_CHAR:
-    case Instruction::AGET_SHORT:
-      may_throw_exception = true;
-      if (insn->Opcode() == Instruction::AGET_OBJECT) {
-        set_to_another_object[dec_insn.vA] = true;
-      }
-      break;
-
-    case Instruction::APUT:
-    case Instruction::APUT_WIDE:
-    case Instruction::APUT_OBJECT:
-    case Instruction::APUT_BOOLEAN:
-    case Instruction::APUT_BYTE:
-    case Instruction::APUT_CHAR:
-    case Instruction::APUT_SHORT:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::IGET:
-    case Instruction::IGET_WIDE:
-    case Instruction::IGET_OBJECT:
-    case Instruction::IGET_BOOLEAN:
-    case Instruction::IGET_BYTE:
-    case Instruction::IGET_CHAR:
-    case Instruction::IGET_SHORT:
-      {
-        if (insn->Opcode() == Instruction::IGET_OBJECT) {
-          set_to_another_object[dec_insn.vA] = true;
-        }
-        uint32_t reg_idx = dec_insn.vB;
-        uint32_t field_idx = dec_insn.vC;
-        int field_offset;
-        bool is_volatile;
-        bool is_fast_path = compiler_.ComputeInstanceFieldInfo(
-          field_idx, &cunit_, field_offset, is_volatile, false);
-        if (!is_fast_path) {
-          may_throw_exception = true;
-        } else {
-          // Fast-path, may throw NullPointerException
-          if (reg_idx == this_reg_idx) {
-            // We assume "this" will not be null at first.
-            assume_this_non_null = true;
-          } else {
-            may_throw_exception = true;
-          }
-        }
-      }
-      break;
-
-    case Instruction::IPUT:
-    case Instruction::IPUT_WIDE:
-    case Instruction::IPUT_OBJECT:
-    case Instruction::IPUT_BOOLEAN:
-    case Instruction::IPUT_BYTE:
-    case Instruction::IPUT_CHAR:
-    case Instruction::IPUT_SHORT:
-      {
-        uint32_t reg_idx = dec_insn.vB;
-        uint32_t field_idx = dec_insn.vC;
-        int field_offset;
-        bool is_volatile;
-        bool is_fast_path = compiler_.ComputeInstanceFieldInfo(
-          field_idx, &cunit_, field_offset, is_volatile, true);
-        if (!is_fast_path) {
-          may_throw_exception = true;
-        } else {
-          // Fast-path, may throw NullPointerException
-          if (reg_idx == this_reg_idx) {
-            // We assume "this" will not be null at first.
-            assume_this_non_null = true;
-          } else {
-            may_throw_exception = true;
-          }
-        }
-      }
-      break;
-
-    case Instruction::SGET:
-    case Instruction::SGET_WIDE:
-    case Instruction::SGET_OBJECT:
-    case Instruction::SGET_BOOLEAN:
-    case Instruction::SGET_BYTE:
-    case Instruction::SGET_CHAR:
-    case Instruction::SGET_SHORT:
-      {
-        if (insn->Opcode() == Instruction::AGET_OBJECT) {
-          set_to_another_object[dec_insn.vA] = true;
-        }
-        uint32_t field_idx = dec_insn.vB;
-
-        int field_offset;
-        int ssb_index;
-        bool is_referrers_class;
-        bool is_volatile;
-
-        bool is_fast_path = compiler_.ComputeStaticFieldInfo(
-          field_idx, &cunit_, field_offset, ssb_index,
-          is_referrers_class, is_volatile, false);
-        if (!is_fast_path || !is_referrers_class) {
-          may_throw_exception = true;
-        }
-      }
-      break;
-
-    case Instruction::SPUT:
-    case Instruction::SPUT_WIDE:
-    case Instruction::SPUT_OBJECT:
-    case Instruction::SPUT_BOOLEAN:
-    case Instruction::SPUT_BYTE:
-    case Instruction::SPUT_CHAR:
-    case Instruction::SPUT_SHORT:
-      {
-        uint32_t field_idx = dec_insn.vB;
-
-        int field_offset;
-        int ssb_index;
-        bool is_referrers_class;
-        bool is_volatile;
-
-        bool is_fast_path = compiler_.ComputeStaticFieldInfo(
-          field_idx, &cunit_, field_offset, ssb_index,
-          is_referrers_class, is_volatile, true);
-        if (!is_fast_path || !is_referrers_class) {
-          may_throw_exception = true;
-        }
-      }
-      break;
-
-
-    case Instruction::INVOKE_VIRTUAL:
-    case Instruction::INVOKE_SUPER:
-    case Instruction::INVOKE_DIRECT:
-    case Instruction::INVOKE_STATIC:
-    case Instruction::INVOKE_INTERFACE:
-    case Instruction::INVOKE_VIRTUAL_RANGE:
-    case Instruction::INVOKE_SUPER_RANGE:
-    case Instruction::INVOKE_DIRECT_RANGE:
-    case Instruction::INVOKE_STATIC_RANGE:
-    case Instruction::INVOKE_INTERFACE_RANGE:
-      has_invoke = true;
-      may_throw_exception = true;
-      break;
-
-    case Instruction::NEG_INT:
-    case Instruction::NOT_INT:
-    case Instruction::NEG_LONG:
-    case Instruction::NOT_LONG:
-    case Instruction::NEG_FLOAT:
-    case Instruction::NEG_DOUBLE:
-    case Instruction::INT_TO_LONG:
-    case Instruction::INT_TO_FLOAT:
-    case Instruction::INT_TO_DOUBLE:
-    case Instruction::LONG_TO_INT:
-    case Instruction::LONG_TO_FLOAT:
-    case Instruction::LONG_TO_DOUBLE:
-    case Instruction::FLOAT_TO_INT:
-    case Instruction::FLOAT_TO_LONG:
-    case Instruction::FLOAT_TO_DOUBLE:
-    case Instruction::DOUBLE_TO_INT:
-    case Instruction::DOUBLE_TO_LONG:
-    case Instruction::DOUBLE_TO_FLOAT:
-    case Instruction::INT_TO_BYTE:
-    case Instruction::INT_TO_CHAR:
-    case Instruction::INT_TO_SHORT:
-    case Instruction::ADD_INT:
-    case Instruction::SUB_INT:
-    case Instruction::MUL_INT:
-    case Instruction::AND_INT:
-    case Instruction::OR_INT:
-    case Instruction::XOR_INT:
-    case Instruction::SHL_INT:
-    case Instruction::SHR_INT:
-    case Instruction::USHR_INT:
-    case Instruction::ADD_LONG:
-    case Instruction::SUB_LONG:
-    case Instruction::MUL_LONG:
-    case Instruction::AND_LONG:
-    case Instruction::OR_LONG:
-    case Instruction::XOR_LONG:
-    case Instruction::SHL_LONG:
-    case Instruction::SHR_LONG:
-    case Instruction::USHR_LONG:
-    case Instruction::ADD_INT_2ADDR:
-    case Instruction::SUB_INT_2ADDR:
-    case Instruction::MUL_INT_2ADDR:
-    case Instruction::AND_INT_2ADDR:
-    case Instruction::OR_INT_2ADDR:
-    case Instruction::XOR_INT_2ADDR:
-    case Instruction::SHL_INT_2ADDR:
-    case Instruction::SHR_INT_2ADDR:
-    case Instruction::USHR_INT_2ADDR:
-    case Instruction::ADD_LONG_2ADDR:
-    case Instruction::SUB_LONG_2ADDR:
-    case Instruction::MUL_LONG_2ADDR:
-    case Instruction::AND_LONG_2ADDR:
-    case Instruction::OR_LONG_2ADDR:
-    case Instruction::XOR_LONG_2ADDR:
-    case Instruction::SHL_LONG_2ADDR:
-    case Instruction::SHR_LONG_2ADDR:
-    case Instruction::USHR_LONG_2ADDR:
-      break;
-
-    case Instruction::DIV_INT:
-    case Instruction::REM_INT:
-    case Instruction::DIV_LONG:
-    case Instruction::REM_LONG:
-    case Instruction::DIV_INT_2ADDR:
-    case Instruction::REM_INT_2ADDR:
-    case Instruction::DIV_LONG_2ADDR:
-    case Instruction::REM_LONG_2ADDR:
-      may_throw_exception = true;
-      break;
-
-    case Instruction::ADD_FLOAT:
-    case Instruction::SUB_FLOAT:
-    case Instruction::MUL_FLOAT:
-    case Instruction::DIV_FLOAT:
-    case Instruction::REM_FLOAT:
-    case Instruction::ADD_DOUBLE:
-    case Instruction::SUB_DOUBLE:
-    case Instruction::MUL_DOUBLE:
-    case Instruction::DIV_DOUBLE:
-    case Instruction::REM_DOUBLE:
-    case Instruction::ADD_FLOAT_2ADDR:
-    case Instruction::SUB_FLOAT_2ADDR:
-    case Instruction::MUL_FLOAT_2ADDR:
-    case Instruction::DIV_FLOAT_2ADDR:
-    case Instruction::REM_FLOAT_2ADDR:
-    case Instruction::ADD_DOUBLE_2ADDR:
-    case Instruction::SUB_DOUBLE_2ADDR:
-    case Instruction::MUL_DOUBLE_2ADDR:
-    case Instruction::DIV_DOUBLE_2ADDR:
-    case Instruction::REM_DOUBLE_2ADDR:
-      break;
-
-    case Instruction::ADD_INT_LIT16:
-    case Instruction::ADD_INT_LIT8:
-    case Instruction::RSUB_INT:
-    case Instruction::RSUB_INT_LIT8:
-    case Instruction::MUL_INT_LIT16:
-    case Instruction::MUL_INT_LIT8:
-    case Instruction::AND_INT_LIT16:
-    case Instruction::AND_INT_LIT8:
-    case Instruction::OR_INT_LIT16:
-    case Instruction::OR_INT_LIT8:
-    case Instruction::XOR_INT_LIT16:
-    case Instruction::XOR_INT_LIT8:
-    case Instruction::SHL_INT_LIT8:
-    case Instruction::SHR_INT_LIT8:
-    case Instruction::USHR_INT_LIT8:
-      break;
-
-    case Instruction::DIV_INT_LIT16:
-    case Instruction::DIV_INT_LIT8:
-    case Instruction::REM_INT_LIT16:
-    case Instruction::REM_INT_LIT8:
-      if (dec_insn.vC == 0) {
-        may_throw_exception = true;
-      }
-      break;
-
-    case Instruction::UNUSED_3E:
-    case Instruction::UNUSED_3F:
-    case Instruction::UNUSED_40:
-    case Instruction::UNUSED_41:
-    case Instruction::UNUSED_42:
-    case Instruction::UNUSED_43:
-    case Instruction::UNUSED_73:
-    case Instruction::UNUSED_79:
-    case Instruction::UNUSED_7A:
-    case Instruction::UNUSED_E3:
-    case Instruction::UNUSED_E4:
-    case Instruction::UNUSED_E5:
-    case Instruction::UNUSED_E6:
-    case Instruction::UNUSED_E7:
-    case Instruction::UNUSED_E8:
-    case Instruction::UNUSED_E9:
-    case Instruction::UNUSED_EA:
-    case Instruction::UNUSED_EB:
-    case Instruction::UNUSED_EC:
-    case Instruction::UNUSED_ED:
-    case Instruction::UNUSED_EE:
-    case Instruction::UNUSED_EF:
-    case Instruction::UNUSED_F0:
-    case Instruction::UNUSED_F1:
-    case Instruction::UNUSED_F2:
-    case Instruction::UNUSED_F3:
-    case Instruction::UNUSED_F4:
-    case Instruction::UNUSED_F5:
-    case Instruction::UNUSED_F6:
-    case Instruction::UNUSED_F7:
-    case Instruction::UNUSED_F8:
-    case Instruction::UNUSED_F9:
-    case Instruction::UNUSED_FA:
-    case Instruction::UNUSED_FB:
-    case Instruction::UNUSED_FC:
-    case Instruction::UNUSED_FD:
-    case Instruction::UNUSED_FE:
-    case Instruction::UNUSED_FF:
-      LOG(FATAL) << "Dex file contains UNUSED bytecode: " << insn->Opcode();
-      break;
-    }
-  }
-
-  method_info_.this_reg_idx = this_reg_idx;
-  // According to the statistics, there are few methods that modify the "this" pointer. So this is a
-  // simple way to avoid data flow analysis. After we have a high-level IR before IRBuilder, we
-  // should remove this trick.
-  method_info_.this_will_not_be_null =
-      (cunit_.IsStatic()) ? (true) : (!set_to_another_object[this_reg_idx]);
-  method_info_.has_invoke = has_invoke;
-  // If this method has loop or invoke instruction, it may suspend. Thus we need a shadow frame entry
-  // for GC.
-  method_info_.need_shadow_frame_entry = has_invoke || may_have_loop;
-  // If this method may throw an exception, we need a shadow frame for stack trace (dexpc).
-  method_info_.need_shadow_frame = method_info_.need_shadow_frame_entry || may_throw_exception ||
-                                   (assume_this_non_null && !method_info_.this_will_not_be_null);
-  // If can only throw exception, but can't suspend check (no loop, no invoke),
-  // then there is no shadow frame entry. Only Shadow frame is needed.
-  method_info_.lazy_push_shadow_frame =
-      method_info_.need_shadow_frame && !method_info_.need_shadow_frame_entry;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/dex_lang.h b/src/greenland/dex_lang.h
deleted file mode 100644
index 70ad5bf..0000000
--- a/src/greenland/dex_lang.h
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_DEX_LANG_H_
-#define ART_SRC_GREENLAND_DEX_LANG_H_
-
-#include "backend_types.h"
-#include "dalvik_reg.h"
-#include "ir_builder.h"
-
-#include "dex_file.h"
-#include "dex_instruction.h"
-#include "invoke_type.h"
-#include "macros.h"
-
-#include <vector>
-
-#include <llvm/Module.h>
-#include <llvm/ADT/ArrayRef.h>
-
-namespace llvm {
-  class BasicBlock;
-  class Function;
-  class LLVMContext;
-  class Type;
-}
-
-namespace art {
-  class Compiler;
-  class OatCompilationUnit;
-}
-
-namespace art {
-namespace greenland {
-
-class DalvikReg;
-class InferredRegCategoryMap;
-class IntrinsicHelper;
-
-class DexLang {
- public:
-  class Context {
-   private:
-    llvm::Module& module_;
-    IntrinsicHelper* intrinsic_helper_;
-
-   public:
-    Context(llvm::Module& module);
-    ~Context();
-
-    inline llvm::LLVMContext& GetLLVMContext()
-    { return module_.getContext(); }
-
-    inline llvm::Module& GetOutputModule()
-    { return module_; }
-
-    inline IntrinsicHelper& GetIntrinsicHelper()
-    { return *intrinsic_helper_; }
-    inline const IntrinsicHelper& GetIntrinsicHelper() const
-    { return *intrinsic_helper_; }
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(Context);
-  };
-
- public:
-  DexLang(Context& context, Compiler& compiler, OatCompilationUnit& cunit);
-
-  ~DexLang();
-
-  llvm::Function* Build();
-
-  inline IRBuilder& GetIRBuilder() {
-    return irb_;
-  }
-  llvm::Value* AllocateDalvikReg(RegCategory cat, unsigned reg_idx);
-
- private:
-  Context& dex_lang_ctx_;
-  Compiler& compiler_;
-  OatCompilationUnit& cunit_;
-
-  const DexFile* dex_file_;
-  const DexFile::CodeItem* code_item_;
-  uint32_t method_idx_;
-
-  llvm::LLVMContext& context_;
-  llvm::Module& module_;
-  IntrinsicHelper& intrinsic_helper_;
-
-  IRBuilder irb_;
-  llvm::Function* func_;
-
- private:
-  //----------------------------------------------------------------------------
-  // Basic Block Helper Functions
-  //----------------------------------------------------------------------------
-  llvm::BasicBlock* reg_alloc_bb_;
-  llvm::BasicBlock* arg_reg_init_bb_;
-
-  std::vector<llvm::BasicBlock*> basic_blocks_;
-
-  llvm::BasicBlock* GetBasicBlock(unsigned dex_pc);
-  llvm::BasicBlock* CreateBasicBlockWithDexPC(unsigned dex_pc,
-                                              char const* postfix = NULL);
-  llvm::BasicBlock* GetNextBasicBlock(unsigned dex_pc);
-
- private:
-  //----------------------------------------------------------------------------
-  // Register Helper Functions
-  //----------------------------------------------------------------------------
-  std::vector<DalvikReg*> regs_;
-
-  llvm::Value* EmitLoadDalvikReg(unsigned reg_idx, JType jty, JTypeSpace space);
-
-  llvm::Value* EmitLoadDalvikReg(unsigned reg_idx, char shorty, JTypeSpace space);
-
-  void EmitStoreDalvikReg(unsigned reg_idx, JType jty,
-                          JTypeSpace space, llvm::Value* new_value);
-
-  void EmitStoreDalvikReg(unsigned reg_idx, char shorty,
-                          JTypeSpace space, llvm::Value* new_value);
-
- private:
-  //----------------------------------------------------------------------------
-  // Return Value Related
-  //----------------------------------------------------------------------------
-  // Hold the return value returned from the lastest invoke-* instruction
-  DalvikReg* retval_reg_;
-
-  llvm::Value* EmitLoadDalvikRetValReg(JType jty, JTypeSpace space);
-
-  llvm::Value* EmitLoadDalvikRetValReg(char shorty, JTypeSpace space);
-
-  void EmitStoreDalvikRetValReg(JType jty, JTypeSpace space, llvm::Value* new_value);
-
-  void EmitStoreDalvikRetValReg(char shorty, JTypeSpace space, llvm::Value* new_value);
-
- private:
-  //----------------------------------------------------------------------------
-  // Shadow Frame
-  //----------------------------------------------------------------------------
-  unsigned num_shadow_frame_entries_;
-  std::vector<int32_t> reg_to_shadow_frame_index_;
-
-  void EmitUpdateDexPC(unsigned dex_pc);
-
-  void EmitPopShadowFrame();
-
- private:
-  //----------------------------------------------------------------------------
-  // RegCategory
-  //----------------------------------------------------------------------------
-  RegCategory GetInferredRegCategory(unsigned dex_pc, unsigned reg_idx);
-
-  InferredRegCategoryMap const* GetInferredRegCategoryMap();
-
-  bool IsRegCanBeObject(unsigned reg_idx);
-
- private:
-  //----------------------------------------------------------------------------
-  // Exception Handling
-  //----------------------------------------------------------------------------
-  std::vector<llvm::BasicBlock*> landing_pads_bb_;
-  llvm::BasicBlock* exception_unwind_bb_;
-
-  // cur_try_item_offset caches the latest try item offset such that we don't
-  // have to call DexFile::FindCatchHandlerOffset(...) (using binary search) for
-  // every query of the try item for the given dex_pc.
-  int32_t cur_try_item_offset;
-
-  int32_t GetTryItemOffset(unsigned dex_pc);
-
-  llvm::BasicBlock* GetLandingPadBasicBlock(unsigned dex_pc);
-
-  llvm::BasicBlock* GetUnwindBasicBlock();
-
-  void EmitBranchExceptionLandingPad(unsigned dex_pc);
-
-  void EmitGuard_DivZeroException(unsigned dex_pc,
-                                  llvm::Value* denominator,
-                                  JType op_jty);
-
-  void EmitGuard_NullPointerException(unsigned dex_pc, llvm::Value* object);
-
-  void EmitGuard_ArrayIndexOutOfBoundsException(unsigned dex_pc,
-                                                llvm::Value* array,
-                                                llvm::Value* index);
-
-  void EmitGuard_ArrayException(unsigned dex_pc,
-                                llvm::Value* array,
-                                llvm::Value* index);
-
-  void EmitGuard_ExceptionLandingPad(unsigned dex_pc, bool can_skip_unwind);
-
- private:
-  //----------------------------------------------------------------------------
-  // Garbage Collection Safe Point
-  //----------------------------------------------------------------------------
-  void EmitGuard_GarbageCollectionSuspend();
-
- private:
-  //----------------------------------------------------------------------------
-  // Code Generation
-  //----------------------------------------------------------------------------
-  bool CreateFunction();
-  llvm::FunctionType* GetFunctionType();
-
-  bool EmitPrologue();
-  bool EmitPrologueAssignArgRegister();
-  bool EmitPrologueAllcaShadowFrame();
-  bool EmitPrologueLinkBasicBlocks();
-  bool PrettyLayoutExceptionBasicBlocks();
-  bool VerifyFunction();
-  bool OptimizeFunction();
-  // Our optimization passes
-  bool RemoveRedundantPendingExceptionChecks();
-
-  //----------------------------------------------------------------------------
-  // Emit* Helper Functions
-  //----------------------------------------------------------------------------
-  enum CondBranchKind {
-    kCondBranch_EQ,
-    kCondBranch_NE,
-    kCondBranch_LT,
-    kCondBranch_GE,
-    kCondBranch_GT,
-    kCondBranch_LE,
-  };
-
-  enum IntArithmKind {
-    kIntArithm_Add,
-    kIntArithm_Sub,
-    kIntArithm_Mul,
-    kIntArithm_Div,
-    kIntArithm_Rem,
-    kIntArithm_And,
-    kIntArithm_Or,
-    kIntArithm_Xor,
-  };
-
-  enum IntShiftArithmKind {
-    kIntArithm_Shl,
-    kIntArithm_Shr,
-    kIntArithm_UShr,
-  };
-
-  enum FPArithmKind {
-    kFPArithm_Add,
-    kFPArithm_Sub,
-    kFPArithm_Mul,
-    kFPArithm_Div,
-    kFPArithm_Rem,
-  };
-
-  enum InvokeArgFmt {
-    kArgReg,
-    kArgRange,
-  };
-
-  llvm::Value* EmitLoadMethodObjectAddr();
-
-  llvm::Value* EmitGetCurrentThread();
-
-  void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr);
-
-  llvm::Value* EmitInvokeIntrinsicNoThrow(IntrinsicHelper::IntrinsicId intr_id,
-                                          llvm::ArrayRef<llvm::Value*> args
-                                              = llvm::ArrayRef<llvm::Value*>());
-  llvm::Value* EmitInvokeIntrinsic2NoThrow(IntrinsicHelper::IntrinsicId intr_id,
-                                           llvm::Value* arg1,
-                                           llvm::Value* arg2) {
-    llvm::Value* args[] = { arg1, arg2 };
-    return EmitInvokeIntrinsicNoThrow(intr_id, args);
-  }
-  llvm::Value* EmitInvokeIntrinsic3NoThrow(IntrinsicHelper::IntrinsicId intr_id,
-                                           llvm::Value* arg1,
-                                           llvm::Value* arg2,
-                                           llvm::Value* arg3) {
-    llvm::Value* args[] = { arg1, arg2, arg3 };
-    return EmitInvokeIntrinsicNoThrow(intr_id, args);
-  }
-  llvm::Value* EmitInvokeIntrinsic4NoThrow(IntrinsicHelper::IntrinsicId intr_id,
-                                           llvm::Value* arg1,
-                                           llvm::Value* arg2,
-                                           llvm::Value* arg3,
-                                           llvm::Value* arg4) {
-    llvm::Value* args[] = { arg1, arg2, arg3, arg4 };
-    return EmitInvokeIntrinsicNoThrow(intr_id, args);
-  }
-
-  llvm::Value* EmitInvokeIntrinsic(unsigned dex_pc, bool can_skip_unwind,
-                                   IntrinsicHelper::IntrinsicId intr_id,
-                                   llvm::ArrayRef<llvm::Value*> args
-                                        = llvm::ArrayRef<llvm::Value*>());
-  llvm::Value* EmitInvokeIntrinsic2(unsigned dex_pc, bool can_skip_unwind,
-                                    IntrinsicHelper::IntrinsicId intr_id,
-                                    llvm::Value* arg1,
-                                    llvm::Value* arg2) {
-    llvm::Value* args[] = { arg1, arg2 };
-    return EmitInvokeIntrinsic(dex_pc, can_skip_unwind, intr_id, args);
-  }
-  llvm::Value* EmitInvokeIntrinsic3(unsigned dex_pc, bool can_skip_unwind,
-                                    IntrinsicHelper::IntrinsicId intr_id,
-                                    llvm::Value* arg1,
-                                    llvm::Value* arg2,
-                                    llvm::Value* arg3) {
-    llvm::Value* args[] = { arg1, arg2, arg3 };
-    return EmitInvokeIntrinsic(dex_pc, can_skip_unwind, intr_id, args);
-  }
-  llvm::Value* EmitInvokeIntrinsic4(unsigned dex_pc, bool can_skip_unwind,
-                                    IntrinsicHelper::IntrinsicId intr_id,
-                                    llvm::Value* arg1,
-                                    llvm::Value* arg2,
-                                    llvm::Value* arg3,
-                                    llvm::Value* arg4) {
-    llvm::Value* args[] = { arg1, arg2, arg3, arg4 };
-    return EmitInvokeIntrinsic(dex_pc, can_skip_unwind, intr_id, args);
-  }
-  llvm::Value* EmitInvokeIntrinsic5(unsigned dex_pc, bool can_skip_unwind,
-                                    IntrinsicHelper::IntrinsicId intr_id,
-                                    llvm::Value* arg1,
-                                    llvm::Value* arg2,
-                                    llvm::Value* arg3,
-                                    llvm::Value* arg4,
-                                    llvm::Value* arg5) {
-    llvm::Value* args[] = { arg1, arg2, arg3, arg4, arg5 };
-    return EmitInvokeIntrinsic(dex_pc, can_skip_unwind, intr_id, args);
-  }
-
-  llvm::Value* EmitLoadConstantClass(unsigned dex_pc, uint32_t type_idx);
-
-  llvm::Value* EmitLoadArrayLength(llvm::Value* array);
-
-  llvm::Value* EmitAllocNewArray(unsigned dex_pc, int32_t length,
-                                 uint32_t type_idx, bool is_filled_new_array);
-
-  llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq,
-                                          llvm::Value* cmp_lt);
-
-  llvm::Value* EmitLoadStaticStorage(unsigned dex_pc, unsigned type_idx);
-
-  llvm::Value* EmitConditionResult(llvm::Value* lhs, llvm::Value* rhs,
-                                   CondBranchKind cond);
-
-  llvm::Value* EmitIntArithmResultComputation(unsigned dex_pc,
-                                              llvm::Value* lhs,
-                                              llvm::Value* rhs,
-                                              IntArithmKind arithm,
-                                              JType op_jty);
-
-  llvm::Value* EmitIntShiftArithmResultComputation(uint32_t dex_pc,
-                                                   llvm::Value* lhs,
-                                                   llvm::Value* rhs,
-                                                   IntShiftArithmKind arithm,
-                                                   JType op_jty);
-
-  llvm::Value* EmitIntDivRemResultComputation(unsigned dex_pc,
-                                              llvm::Value* dividend,
-                                              llvm::Value* divisor,
-                                              IntArithmKind arithm,
-                                              JType op_jty);
-
-#define GEN_INSN_ARGS unsigned dex_pc, const Instruction* insn
-  // NOP, PAYLOAD (unreachable) instructions
-  void EmitInsn_Nop(GEN_INSN_ARGS);
-
-  // MOVE, MOVE_RESULT instructions
-  void EmitInsn_Move(GEN_INSN_ARGS, JType jty);
-  void EmitInsn_MoveResult(GEN_INSN_ARGS, JType jty);
-
-  // MOVE_EXCEPTION, THROW instructions
-  void EmitInsn_MoveException(GEN_INSN_ARGS);
-  void EmitInsn_ThrowException(GEN_INSN_ARGS);
-
-  // RETURN instructions
-  void EmitInsn_ReturnVoid(GEN_INSN_ARGS);
-  void EmitInsn_Return(GEN_INSN_ARGS);
-
-  // CONST, CONST_CLASS, CONST_STRING instructions
-  void EmitInsn_LoadConstant(GEN_INSN_ARGS, JType imm_jty);
-  void EmitInsn_LoadConstantString(GEN_INSN_ARGS);
-  void EmitInsn_LoadConstantClass(GEN_INSN_ARGS);
-
-  // MONITOR_ENTER, MONITOR_EXIT instructions
-  void EmitInsn_MonitorEnter(GEN_INSN_ARGS);
-  void EmitInsn_MonitorExit(GEN_INSN_ARGS);
-
-  // CHECK_CAST, INSTANCE_OF instructions
-  void EmitInsn_CheckCast(GEN_INSN_ARGS);
-  void EmitInsn_InstanceOf(GEN_INSN_ARGS);
-
-  // NEW_INSTANCE instructions
-  void EmitInsn_NewInstance(GEN_INSN_ARGS);
-
-  // ARRAY_LEN, NEW_ARRAY, FILLED_NEW_ARRAY, FILL_ARRAY_DATA instructions
-  void EmitInsn_ArrayLength(GEN_INSN_ARGS);
-  void EmitInsn_NewArray(GEN_INSN_ARGS);
-  void EmitInsn_FilledNewArray(GEN_INSN_ARGS, bool is_range);
-  void EmitInsn_FillArrayData(GEN_INSN_ARGS);
-
-  // GOTO, IF_TEST, IF_TESTZ instructions
-  void EmitInsn_UnconditionalBranch(GEN_INSN_ARGS);
-  void EmitInsn_UnaryConditionalBranch(GEN_INSN_ARGS, CondBranchKind cond);
-  void EmitInsn_BinaryConditionalBranch(GEN_INSN_ARGS, CondBranchKind cond);
-
-  // PACKED_SWITCH, SPARSE_SWITCH instrutions
-  void EmitInsn_PackedSwitch(GEN_INSN_ARGS);
-  void EmitInsn_SparseSwitch(GEN_INSN_ARGS);
-
-  // CMPX_FLOAT, CMPX_DOUBLE, CMP_LONG instructions
-  void EmitInsn_FPCompare(GEN_INSN_ARGS, JType fp_jty, bool gt_bias);
-  void EmitInsn_LongCompare(GEN_INSN_ARGS);
-
-  // AGET, APUT instrutions
-  void EmitInsn_AGet(GEN_INSN_ARGS, JType elem_jty);
-  void EmitInsn_APut(GEN_INSN_ARGS, JType elem_jty);
-
-  // IGET, IPUT instructions
-  void EmitInsn_IGet(GEN_INSN_ARGS, JType field_jty);
-  void EmitInsn_IPut(GEN_INSN_ARGS, JType field_jty);
-
-  // SGET, SPUT instructions
-  void EmitInsn_SGet(GEN_INSN_ARGS, JType field_jty);
-  void EmitInsn_SPut(GEN_INSN_ARGS, JType field_jty);
-
-  void EmitInsn_Invoke(GEN_INSN_ARGS,
-                       InvokeType invoke_type,
-                       InvokeArgFmt arg_fmt);
-
-  // Unary instructions
-  void EmitInsn_Neg(GEN_INSN_ARGS, JType op_jty);
-  void EmitInsn_Not(GEN_INSN_ARGS, JType op_jty);
-  void EmitInsn_SExt(GEN_INSN_ARGS);
-  void EmitInsn_Trunc(GEN_INSN_ARGS);
-  void EmitInsn_TruncAndSExt(GEN_INSN_ARGS, unsigned N);
-  void EmitInsn_TruncAndZExt(GEN_INSN_ARGS, unsigned N);
-
-  void EmitInsn_FNeg(GEN_INSN_ARGS, JType op_jty);
-  void EmitInsn_IntToFP(GEN_INSN_ARGS, JType src_jty, JType dest_jty);
-  void EmitInsn_FPToInt(GEN_INSN_ARGS, JType src_jty, JType dest_jty,
-                        IntrinsicHelper::IntrinsicId intr_id);
-  void EmitInsn_FExt(GEN_INSN_ARGS);
-  void EmitInsn_FTrunc(GEN_INSN_ARGS);
-
-  // Integer binary arithmetic instructions
-  void EmitInsn_IntArithm(GEN_INSN_ARGS, IntArithmKind arithm,
-                          JType op_jty, bool is_2addr);
-
-  void EmitInsn_IntArithmImmediate(GEN_INSN_ARGS, IntArithmKind arithm);
-
-  void EmitInsn_IntShiftArithm(GEN_INSN_ARGS, IntShiftArithmKind arithm,
-                               JType op_jty, bool is_2addr);
-
-  void EmitInsn_IntShiftArithmImmediate(GEN_INSN_ARGS,
-                                        IntShiftArithmKind arithm);
-
-  void EmitInsn_RSubImmediate(GEN_INSN_ARGS);
-
-  // Floating-point binary arithmetic instructions
-  void EmitInsn_FPArithm(GEN_INSN_ARGS, FPArithmKind arithm,
-                         JType op_jty, bool is_2addr);
-#undef GEN_INSN_ARGS
-
-
-  bool EmitInstructions();
-  bool EmitInstruction(unsigned dex_pc, const Instruction* insn);
-
-
-  // TODO: Use high-level IR to do this
-  bool IsInstructionDirectToReturn(uint32_t dex_pc);
-
-  struct MethodInfo {
-    int64_t this_reg_idx;
-    bool this_will_not_be_null;
-    bool has_invoke;
-    bool need_shadow_frame_entry;
-    bool need_shadow_frame;
-    bool lazy_push_shadow_frame;
-    std::vector<bool> set_to_another_object;
-  };
-  MethodInfo method_info_;
-
-  void ComputeMethodInfo();
-
-  DISALLOW_COPY_AND_ASSIGN(DexLang);
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_DEX_LANG_H_
diff --git a/src/greenland/gbc_context.cc b/src/greenland/gbc_context.cc
deleted file mode 100644
index ec86bfb..0000000
--- a/src/greenland/gbc_context.cc
+++ /dev/null
@@ -1,69 +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 "gbc_context.h"
-
-#include "atomic.h"
-
-namespace art {
-namespace greenland {
-
-GBCContext::GBCContext()
-    : context_(), module_(NULL), ref_count_(1), mem_usage_(0) {
-  module_ = new llvm::Module("art", context_);
-
-  // Initialize the contents of an empty module
-  // Type of "JavaObject"
-  llvm::StructType::create(context_, "JavaObject");
-  // Type of "Method"
-  llvm::StructType::create(context_, "Method");
-  // Type of "Thread"
-  llvm::StructType::create(context_, "Thread");
-
-  dex_lang_ctx_ = new DexLang::Context(*module_);
-  return;
-}
-
-GBCContext::~GBCContext() {
-  delete dex_lang_ctx_;
-  return;
-}
-
-GBCContext& GBCContext::IncRef() {
-  android_atomic_inc(&ref_count_);
-  return *this;
-}
-
-const GBCContext& GBCContext::IncRef() const {
-  android_atomic_inc(&ref_count_);
-  return *this;
-}
-
-void GBCContext::DecRef() const {
-  int32_t old_ref_count = android_atomic_dec(&ref_count_);
-  if (old_ref_count <= 1) {
-    delete this;
-  }
-  return;
-}
-
-void GBCContext::AddMemUsageApproximation(size_t usage) {
-  android_atomic_add(static_cast<int32_t>(usage), &mem_usage_);
-  return;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/gbc_context.h b/src/greenland/gbc_context.h
deleted file mode 100644
index 7c31816..0000000
--- a/src/greenland/gbc_context.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_GBC_CONTEXT_H_
-#define ART_SRC_GREENLAND_GBC_CONTEXT_H_
-
-#include "dex_lang.h"
-
-#include "macros.h"
-
-#include <llvm/LLVMContext.h>
-
-namespace llvm {
-  class Module;
-} // namespace llvm
-
-namespace art {
-namespace greenland {
-
-class IntrinsicHelper;
-
-class GBCContext {
- private:
-  llvm::LLVMContext context_;
-  llvm::Module* module_;
-  DexLang::Context* dex_lang_ctx_;
-
-  mutable volatile int32_t ref_count_;
-  volatile int32_t mem_usage_;
-
-  ~GBCContext();
-
- public:
-  GBCContext();
-
-  inline llvm::LLVMContext& GetLLVMContext()
-  { return context_; }
-  inline llvm::Module& GetOutputModule()
-  { return *module_; }
-
-  inline IntrinsicHelper& GetIntrinsicHelper()
-  { return dex_lang_ctx_->GetIntrinsicHelper(); }
-  inline const IntrinsicHelper& GetIntrinsicHelper() const
-  { return dex_lang_ctx_->GetIntrinsicHelper(); }
-
-  inline DexLang::Context& GetDexLangContext()
-  { return *dex_lang_ctx_; }
-  inline const DexLang::Context& GetDexLangContext() const
-  { return *dex_lang_ctx_; }
-
-  GBCContext& IncRef();
-  const GBCContext& IncRef() const;
-  void DecRef() const;
-
-  void AddMemUsageApproximation(size_t usage);
-  inline bool IsMemUsageThresholdReached() const {
-    return (mem_usage_ > (30 << 20)); // (threshold: 30MiB)
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GBCContext);
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_GBC_CONTEXT_H_
diff --git a/src/greenland/gbc_function.h b/src/greenland/gbc_function.h
deleted file mode 100644
index b7cbea6..0000000
--- a/src/greenland/gbc_function.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_GBC_FUNCTION_H_
-#define ART_SRC_GREENLAND_GBC_FUNCTION_H_
-
-#include "gbc_context.h"
-
-namespace llvm {
-  class Function;
-} // namespace llvm
-
-namespace art {
-  class OatCompilationUnit;
-} // namespace art
-
-namespace art {
-namespace greenland {
-
-class GBCContext;
-
-class GBCFunction {
- private:
-  // The GBCContext associated with this GBCFunction
-  GBCContext& context_;
-
-  // The LLVM Function in Greenland bitcode
-  llvm::Function& func_;
-
-  // The associated OatCompilationUnit
-  const OatCompilationUnit& cunit_;
-
- public:
-  GBCFunction(GBCContext& context, llvm::Function& func,
-              const OatCompilationUnit& cunit)
-    : context_(context.IncRef()), func_(func), cunit_(cunit) { }
-
-  ~GBCFunction() {
-    context_.DecRef();
-    return;
-  }
-
-  IntrinsicHelper& GetIntrinsicHelper() {
-    return context_.GetIntrinsicHelper();
-  }
-  const IntrinsicHelper& GetIntrinsicHelper() const {
-    return context_.GetIntrinsicHelper();
-  }
-
-  llvm::Function& GetBitcode() {
-    return func_;
-  }
-  const llvm::Function& GetBitcode() const {
-    return func_;
-  }
-
-  const OatCompilationUnit& GetOatCompilationUnit() const {
-    return cunit_;
-  }
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_GBC_FUNCTION_H_
diff --git a/src/greenland/greenland.cc b/src/greenland/greenland.cc
deleted file mode 100644
index 469f7d5..0000000
--- a/src/greenland/greenland.cc
+++ /dev/null
@@ -1,217 +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 "greenland.h"
-
-#include "gbc_context.h"
-#include "gbc_function.h"
-#include "target_codegen_machine.h"
-#include "target_registry.h"
-
-#include "class_linker.h"
-#include "compiler.h"
-#include "oat_compilation_unit.h"
-#include "stl_util.h"
-#include "utils.h"
-
-#include <vector>
-
-#include <llvm/InitializePasses.h>
-#include <llvm/Module.h>
-#include <llvm/PassRegistry.h>
-#include <llvm/Support/Threading.h>
-
-namespace art {
-namespace greenland {
-
-// Forward declarations
-#define LLVM_TARGET(TargetName) void Initialize##TargetName##CodeGenMachine();
-#include <llvm/Config/Targets.def>
-
-#define LLVM_TARGET(TargetName) \
-    void Initialize##TargetName##InvokeStubCompiler();
-#include <llvm/Config/Targets.def>
-
-} // namespace greeland
-} // namespace art
-
-namespace {
-
-pthread_once_t greenland_initialized = PTHREAD_ONCE_INIT;
-
-void InitializeAllCodeGenMachines() {
-#define LLVM_TARGET(TargetName) \
-  art::greenland::Initialize##TargetName##CodeGenMachine();
-#include <llvm/Config/Targets.def>
-}
-
-void InitializeAllInvokeStubCompilers() {
-#define LLVM_TARGET(TargetName) \
-    art::greenland::Initialize##TargetName##InvokeStubCompiler();
-#include <llvm/Config/Targets.def>
-}
-
-void InitializeGreenland() {
-  // Initialize LLVM internal data structure for multithreading
-  llvm::llvm_start_multithreaded();
-
-  // Initialize passes
-  llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();
-
-  llvm::initializeCore(registry);
-  llvm::initializeScalarOpts(registry);
-
-  // Run vectorization passes when our backend supports vector type
-  //llvm::initializeVectorization(registry);
-
-  // DexLang operates on an llvm::Function and never runs IPO and IPA
-  //llvm::initializeIPO(registry);
-  //llvm::initializeIPA(registry);
-
-  llvm::initializeAnalysis(registry);
-  llvm::initializeTransformUtils(registry);
-  llvm::initializeInstCombine(registry);
-
-  InitializeAllCodeGenMachines();
-  InitializeAllInvokeStubCompilers();
-
-  return;
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-Greenland::Greenland(art::Compiler& compiler)
-    : compiler_(compiler), codegen_machine_(NULL),
-      lock_("greenland_compiler_lock"), cur_gbc_ctx_(NULL) {
-  // Initialize Greenland
-  pthread_once(&greenland_initialized, InitializeGreenland);
-
-  codegen_machine_ =
-      TargetCodeGenMachine::Create(compiler_.GetInstructionSet());
-  DCHECK(codegen_machine_ != NULL);
-  return;
-}
-
-Greenland::~Greenland() {
-  cur_gbc_ctx_->DecRef();
-  delete codegen_machine_;
-}
-
-CompiledMethod* Greenland::Compile(OatCompilationUnit& cunit) {
-  MutexLock GUARD(lock_);
-
-  // Dex to LLVM IR
-  GBCContext& gbc_ctx = GetGBCContext();
-
-  UniquePtr<DexLang> dex_lang(new DexLang(gbc_ctx.GetDexLangContext(),
-                                          compiler_, cunit));
-
-  llvm::Function* func = dex_lang->Build();
-
-  if (func == NULL) {
-    LOG(FATAL) << "Failed to run dexlang on "
-               << PrettyMethod(cunit.GetDexMethodIndex(), *cunit.GetDexFile());
-    return NULL;
-  }
-
-  func->dump();
-
-  // NOTE: From statistic, the bitcode size is 4.5 times bigger than the
-  // Dex file.  Besides, we have to convert the code unit into bytes.
-  // Thus, we got our magic number 9.
-  gbc_ctx.AddMemUsageApproximation(
-      cunit.GetCodeItem()->insns_size_in_code_units_ * 900);
-
-  GBCFunction gbc_func(gbc_ctx, *func, cunit);
-
-  UniquePtr<CompiledMethod> result(codegen_machine_->Run(compiler_, gbc_func));
-
-  // gbc_ctx was no longer needed
-  gbc_ctx.DecRef();
-
-  return result.release();
-}
-
-GBCContext& Greenland::GetGBCContext() {
-  //MutexLock GUARD(lock_);
-
-  ResetGBCContextIfThresholdReached();
-
-  if (cur_gbc_ctx_ == NULL) {
-    cur_gbc_ctx_ = new GBCContext();
-  }
-  CHECK(cur_gbc_ctx_ != NULL);
-
-  return cur_gbc_ctx_->IncRef();
-}
-
-void Greenland::ResetGBCContextIfThresholdReached() {
-  lock_.AssertHeld();
-
-  if (cur_gbc_ctx_ == NULL) {
-    return;
-  }
-
-  if (cur_gbc_ctx_->IsMemUsageThresholdReached()) {
-    cur_gbc_ctx_->DecRef();
-    cur_gbc_ctx_ = NULL;
-  }
-  return;
-}
-
-} // namespace greenland
-} // namespace art
-
-inline static art::greenland::Greenland* ContextOf(art::Compiler& compiler) {
-  void *compiler_context = compiler.GetCompilerContext();
-  CHECK(compiler_context != NULL);
-  return reinterpret_cast<art::greenland::Greenland*>(compiler_context);
-}
-
-extern "C" void ArtInitCompilerContext(art::Compiler& compiler) {
-  CHECK(compiler.GetCompilerContext() == NULL);
-  compiler.SetCompilerContext(new art::greenland::Greenland(compiler));
-  return;
-}
-
-extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
-                                                 const art::DexFile::CodeItem* code_item,
-                                                 uint32_t access_flags, uint32_t method_idx,
-                                                 const art::ClassLoader* class_loader,
-                                                 const art::DexFile& dex_file)
-{
-  art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
-  art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
-
-  art::OatCompilationUnit cunit(
-    class_loader, class_linker, dex_file, *dex_cache, code_item,
-    method_idx, access_flags);
-
-  return ContextOf(compiler)->Compile(cunit);
-}
-
-extern "C" art::CompiledInvokeStub* ArtCreateInvokeStub(art::Compiler& compiler,
-                                                        bool is_static,
-                                                        const char* shorty,
-                                                        uint32_t shorty_len) {
-  art::greenland::TargetRegistry::CreateInvokeStubFn compiler_fn =
-      art::greenland::TargetRegistry::GetInvokeStubCompiler(compiler.GetInstructionSet());
-  CHECK(compiler_fn != NULL);
-  return (*compiler_fn)(compiler, is_static, shorty, shorty_len);
-}
diff --git a/src/greenland/greenland.h b/src/greenland/greenland.h
deleted file mode 100644
index 1d6f8e5..0000000
--- a/src/greenland/greenland.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_GREENLAND_H_
-#define ART_SRC_GREENLAND_GREENLAND_H_
-
-#include "macros.h"
-#include "object.h"
-
-namespace art {
-  class CompiledMethod;
-  class Compiler;
-  class OatCompilationUnit;
-}
-
-namespace art {
-namespace greenland {
-
-class GBCContext;
-class TargetCodeGenMachine;
-
-class Greenland {
- public:
-  Greenland(art::Compiler& compiler);
-  ~Greenland();
-
-  CompiledMethod* Compile(OatCompilationUnit& cunit);
-
-  const Compiler& GetCompiler() const {
-    return compiler_;
-  }
-  Compiler& GetCompiler() {
-    return compiler_;
-  }
-
- private:
-  Compiler& compiler_;
-
-  TargetCodeGenMachine* codegen_machine_;
-
-  Mutex lock_;
-
-  // NOTE: Ensure that the lock_ is held before altering cur_gbc_ctx
-  GBCContext *cur_gbc_ctx_;
-
-  GBCContext& GetGBCContext();
-  void ResetGBCContextIfThresholdReached();
-
-  DISALLOW_COPY_AND_ASSIGN(Greenland);
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_GREENLAND_H_
diff --git a/src/greenland/mips/mips_codegen_machine.cc b/src/greenland/mips/mips_codegen_machine.cc
deleted file mode 100644
index c63718b..0000000
--- a/src/greenland/mips/mips_codegen_machine.cc
+++ /dev/null
@@ -1,35 +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 "mips_codegen_machine.h"
-
-#include "greenland/target_registry.h"
-
-namespace art {
-namespace greenland {
-
-MipsCodeGenMachine::MipsCodeGenMachine() {
-}
-
-MipsCodeGenMachine::~MipsCodeGenMachine() {
-}
-
-void InitializeMipsCodeGenMachine() {
-  RegisterTargetCodeGenMachine<MipsCodeGenMachine> X(kMips);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/mips/mips_codegen_machine.h b/src/greenland/mips/mips_codegen_machine.h
deleted file mode 100644
index c9f0abf..0000000
--- a/src/greenland/mips/mips_codegen_machine.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_MIPS_CODEGEN_MACHINE_H_
-#define ART_SRC_GREENLAND_MIPS_CODEGEN_MACHINE_H_
-
-#include "greenland/target_codegen_machine.h"
-
-namespace art {
-namespace greenland {
-
-class MipsCodeGenMachine : public TargetCodeGenMachine {
- private:
-
- public:
-  MipsCodeGenMachine();
-  virtual ~MipsCodeGenMachine();
-
-  virtual TargetLIREmitter* CreateLIREmitter() {
-    return NULL;
-  }
-
-  virtual const TargetDataLayout* GetDataLayout() const {
-    return NULL;
-  }
-
-  virtual const TargetLIRInfo* GetLIRInfo() const {
-    return NULL;
-  }
-
-  virtual const TargetRegisterInfo* GetRegisterInfo() const {
-    return NULL;
-  }
-
-  virtual const char* GetConditionCodeName(unsigned cond) const {
-    return NULL;
-  }
-
-  virtual TargetLIRBuilder* CreateLIRBuilder() {
-    return NULL;
-  }
-
-  virtual RegisterAllocator* GetRegisterAllocator() {
-    return NULL;
-  }
-
-  virtual TargetAssembler* GetAssembler() {
-    return NULL;
-  }
-
-  virtual std::string PrettyTargeteLIR(const LIR& lir) const {
-    return "";
-  }
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_MIPS_CODEGEN_MACHINE_H_
diff --git a/src/greenland/mips/mips_invoke_stub_compiler.cc b/src/greenland/mips/mips_invoke_stub_compiler.cc
deleted file mode 100644
index e7aa662..0000000
--- a/src/greenland/mips/mips_invoke_stub_compiler.cc
+++ /dev/null
@@ -1,46 +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 "greenland/target_registry.h"
-
-#include "logging.h"
-
-namespace art {
-  class Compiler;
-  class CompiledInvokeStub;
-}
-
-namespace {
-
-art::CompiledInvokeStub* MipsInvokeStubCompiler(art::Compiler& /*compiler*/,
-                                                bool is_static,
-                                                const char* shorty,
-                                                uint32_t shorty_len) {
-  UNIMPLEMENTED(FATAL);
-  return NULL;
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitializeMipsInvokeStubCompiler() {
-  TargetRegistry::RegisterInvokeStubCompiler(kMips, MipsInvokeStubCompiler);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/mips/mips_lir.def b/src/greenland/mips/mips_lir.def
deleted file mode 100644
index 0741f1b..0000000
--- a/src/greenland/mips/mips_lir.def
+++ /dev/null
@@ -1,18 +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 "greenland/target_lir.def"
-#include "greenland/clear_target_lir.def"
diff --git a/src/greenland/register_allocator.cc b/src/greenland/register_allocator.cc
deleted file mode 100644
index b19f111..0000000
--- a/src/greenland/register_allocator.cc
+++ /dev/null
@@ -1,291 +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 "register_allocator.h"
-#include "lir_function.h"
-#include "lir_frame_info.h"
-#include "lir_reg.h"
-
-#include "target_register_info.h"
-
-#include "logging.h"
-#include "stl_util.h"
-
-namespace art {
-namespace greenland {
-
-void RegisterAllocator::BuildKillInfo(LIRFunction& lir_func) {
-  //TODO: Build Register KillInfo
-}
-
-static LIRBasicBlock::iterator
-GetSourceIterator(LIRBasicBlock& sourceBB, LIRBasicBlock& targetBB) {
-  LIRBasicBlock::iterator it;
-  for (it = sourceBB.back(); it != sourceBB.begin(); --it) {
-    if (it->IsBranch() && (it->GetOperand(0).GetLabelTarget() == &targetBB))
-      break;
-  }
-  return it;
-}
-
-void RegisterAllocator::PHIElimination(LIRFunction& lir_func) {
-  for (LIRFunction::iterator bb = lir_func.begin(); bb != lir_func.end(); ++bb) {
-    if (bb->IsEmpty() || !bb->front().IsPHI())
-      continue;
-
-    LIRBasicBlock::iterator it; // current LIR
-    LIRBasicBlock::iterator next_it; // next LIR
-    for(it = bb->begin(); it != bb->end(); it = next_it) {
-      next_it = it; ++next_it;
-      if (!it->IsPHI())
-        break;
-
-      for (unsigned i = 1; i < it->GetNumOperands(); i+=2) {
-        const LIROperand& dst = it->GetOperand(0);
-        const LIROperand& src = it->GetOperand(i);
-        LIRBasicBlock* sourceBB =
-            const_cast<LIRBasicBlock*> (it->GetOperand(i + 1).GetLabelTarget());
-
-        LIR* lir = reg_info_.CreateCopy(lir_func, dst.GetReg(), src);
-        LOG(INFO) << "PHIElimination: Insert COPY into BB: " << sourceBB->GetName();
-        sourceBB->insert(GetSourceIterator(*sourceBB, *bb), lir);
-      }
-
-      bb->erase(it);
-    }
-  }
-}
-
-RegisterAllocator::Storage
-RegisterAllocator::AllocateStorage(LIRFunction &lir_func, unsigned vreg_idx) {
-  // The virtual register is allocated, return it.
-  if (allocated_map_.find(vreg_idx) != allocated_map_.end()) {
-    return allocated_map_[vreg_idx];
-  }
-
-  Storage s;
-  // Have free register(s).
-  if (!allocatable_list_.empty()) {
-    s.regTag = kPhyRegType;
-    s.index = allocatable_list_.front();
-    allocatable_list_.pop_front();
-  }
-  else {
-    s.regTag = kFrameType;
-    if (stackstorage_list_.empty()) {
-      // FIXME: Get register subword
-      s.index = lir_func.GetFrameInfo().AllocateStackObject(4);
-    }
-    else {
-      s.index = stackstorage_list_.front();
-      stackstorage_list_.pop_front();
-    }
-  }
-  allocated_map_[vreg_idx] = s;
-  return s;
-}
-
-void RegisterAllocator::KeepStorage(const LIR& lir) {
-  unsigned reg_value = lir.GetOperand(0).GetReg();
-  int frame_idx =  lir.GetOperand(1).GetFrameIndex();
-
-  if (!LIRReg::IsVirtualReg(reg_value))
-    return;
-
-  unsigned vreg_idx = LIRReg::GetRegNo(reg_value);
-
-  LOG(INFO) << "VIRTUAL REG " << vreg_idx << " Keep in Stack Frame [" <<  frame_idx << "];";
-
-  Storage s;
-  s.regTag = kInStackType;
-  s.index = frame_idx;
-  allocated_map_[vreg_idx] = s;
-}
-
-void RegisterAllocator::FreeStorage(unsigned vreg_idx) {
-  //TODO: Check vreg_idx must be allocated
-  Storage s = allocated_map_[vreg_idx];
-
-  if (s.regTag == kInStackType)
-    return;
-
-  if (s.regTag == kPhyRegType)
-    allocatable_list_.push_front(s.index);
-  else
-    stackstorage_list_.push_front(s.index);
-
-  allocated_map_.erase(vreg_idx);
-}
-
-void RegisterAllocator::InitializeAllocation(LIRFunction &lir_func) {
-  allocatable_list_ = reg_info_.GetAllocatableList();
-  stackstorage_list_.clear();
-  allocated_map_.clear();
-}
-
-void RegisterAllocator::PreRegisterAllocation(LIRFunction &lir_func) {
-  PHIElimination(lir_func);
-}
-
-void
-RegisterAllocator::HandleInsnCopy(LIRBasicBlock &bb,
-                                  LIRBasicBlock::iterator it,
-                                  LIRBasicBlock::iterator next_it) {
-  unsigned reg_dst = it->GetOperand(0).GetReg();
-  unsigned reg_src = it->GetOperand(1).GetReg();
-
-  Storage stor_dst = {-1, kNoneType};
-  Storage stor_src = {-1, kNoneType};
-  unsigned vidx_dst = 0, vidx_src = 0;
-
-  if (LIRReg::IsVirtualReg(reg_dst)) {
-    vidx_dst = LIRReg::GetRegNo(reg_dst);
-    LOG(INFO) << "VIRTUAL REG " << vidx_dst << " in COPY need allocated !!";
-    stor_dst = AllocateStorage(bb.GetParent(), vidx_dst);
-  }
-
-  if (LIRReg::IsVirtualReg(reg_src)) {
-    vidx_src = LIRReg::GetRegNo(reg_src);
-    LOG(INFO) << "VIRTUAL REG " << vidx_src << " in COPY need allocated !!";
-    stor_src = AllocateStorage(bb.GetParent(), vidx_src);
-  }
-
-  if ((LIRReg::IsPhysicalReg(reg_dst) || (stor_dst.regTag == kPhyRegType))
-      && (LIRReg::IsPhysicalReg(reg_src) || (stor_src.regTag == kPhyRegType))) {
-    // MovRR
-    unsigned idx_dst = (LIRReg::IsPhysicalReg(reg_dst)) ?
-        LIRReg::GetRegNo(reg_dst) : stor_dst.index;
-    unsigned idx_src = (LIRReg::IsPhysicalReg(reg_src)) ?
-        LIRReg::GetRegNo(reg_src) : stor_src.index;
-    LOG(INFO) << "\t [COPY] create MOVE: move " << idx_dst << ", "<< idx_src;
-    LIR* lir = reg_info_.CreateMoveReg(bb.GetParent(), idx_dst, idx_src);
-    bb.insert(next_it, lir);
-    bb.erase(it);
-
-    if(LIRReg::IsVirtualReg(reg_src)) {
-      FreeStorage(vidx_src);
-    }
-    return;
-  }
-
-  if ((stor_dst.regTag == stor_src.regTag) && (stor_dst.index == stor_src.index)) {
-    // Redundant move
-    FreeStorage(vidx_dst);
-    FreeStorage(vidx_src);
-    bb.erase(it);
-    return;
-  }
-
-  if (stor_dst.regTag != kPhyRegType && stor_src.regTag != kPhyRegType) {
-    unsigned idx = reg_info_.GetTempRegsiter(0);
-    LIR* lir = reg_info_.CreateLoadStack(bb.GetParent(), idx, stor_src.index);
-    bb.insert(it, lir);
-    lir = reg_info_.CreateStoreStack(bb.GetParent(), idx, stor_dst.index);
-    bb.insert(next_it, lir);
-    bb.erase(it);
-    return;
-  }
-
-  if (stor_dst.regTag != kPhyRegType) {
-    unsigned idx = (LIRReg::IsPhysicalReg(reg_src)) ?
-        LIRReg::GetRegNo(reg_src) : stor_src.index;
-    LOG(INFO) << "\t [COPY] create StoreStack: move " << idx << ", "<< stor_dst.index;
-    LIR* lir = reg_info_.CreateStoreStack(bb.GetParent(), idx, stor_dst.index);
-    bb.insert(next_it, lir);
-    bb.erase(it);
-    return;
-  }
-
-  if (stor_src.regTag != kPhyRegType) {
-    unsigned idx = (LIRReg::IsPhysicalReg(reg_dst)) ?
-        LIRReg::GetRegNo(reg_dst) : stor_dst.index;
-    LOG(INFO) << "\t [COPY] create LoadStack: move " << idx << ", "<< stor_src.index;
-    LIR* lir = reg_info_.CreateLoadStack(bb.GetParent(), idx, stor_src.index);
-    bb.insert(next_it, lir);
-    bb.erase(it);
-    return;
-  }
-}
-
-void RegisterAllocator::FunctionRegisterAllocation(LIRFunction &lir_func) {
-  for (LIRFunction::iterator bb =  lir_func.begin(); bb != lir_func.end(); ++bb) {
-    LIRBasicBlock::iterator it; // current LIR
-    LIRBasicBlock::iterator next_it; // next LIR
-    for (LIRBasicBlock::iterator it = bb->begin(); it != bb->end(); it = next_it) {
-      next_it = it; ++next_it;
-
-      // Handle Incoming Args
-      if (reg_info_.IsLoadIncomingArgs(it)) {
-        KeepStorage(*it);
-        bb->erase(it);
-        continue;
-      }
-
-      // Handle Copy
-      if (it->GetOpcode() == opcode::kCOPY) {
-        HandleInsnCopy(*bb, *it, *next_it);
-        continue;
-      }
-
-      std::vector<unsigned> free_list;
-      //for (LIR::op_iterator opi = i->operands_begin(); opi != i->operands_end(); ++opi) {
-      for (unsigned i = 0 ; i < it->GetNumOperands(); i++) {
-        LIROperand& lir_opd = it->GetOperand(i);
-        unsigned temp_count = 0;
-
-        if (!lir_opd.IsReg())
-          continue;
-
-        unsigned reg_value = lir_opd.GetReg();
-        if (!LIRReg::IsVirtualReg(reg_value))
-          continue;
-        unsigned vreg_idx = LIRReg::GetRegNo(reg_value);
-        LOG(INFO) << "\t" << "VIRTUAL REG " << vreg_idx << " need allocated !!";
-        Storage s = AllocateStorage(lir_func, vreg_idx);
-        if (!s.regTag) {
-          LOG(INFO) << "\t" << "VIRTUAL REG " << vreg_idx << " is map to REG[" << s.index << "]!!";
-          lir_opd.SetReg(s.index);
-        } else {
-          unsigned temp_idx = reg_info_.GetTempRegsiter(temp_count++);
-          if ( lir_opd.IsDef() ) {
-            LIR* lir = reg_info_.CreateStoreStack(lir_func, temp_idx, s.index);
-            bb->insert(next_it, lir);
-            lir_opd.SetReg(temp_idx);
-          } else {
-            LIR* lir = reg_info_.CreateLoadStack(lir_func, temp_idx, s.index);
-            bb->insert(it, lir);
-            lir_opd.SetReg(temp_idx);
-          }
-
-          LOG(INFO) << "\t" << "VIRTUAL REG " << vreg_idx << " is map to Frame[" << s.index << "]!!";
-        }
-
-        if (lir_opd.IsKill()) {
-          free_list.push_back(vreg_idx);
-          LOG(INFO) << "\t" << "VIRTUAL REG " << vreg_idx << " is mark kill!!";
-        }
-      }
-
-      for (size_t i = 0 ; i < free_list.size(); i++) {
-        LOG(INFO) << "\t" << "VIRTUAL REG " << free_list[i] << " is kill!!";
-        FreeStorage(free_list[i]);
-      }
-    }
-  }
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/register_allocator.h b/src/greenland/register_allocator.h
deleted file mode 100644
index ffe0914..0000000
--- a/src/greenland/register_allocator.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_REGISTER_ALLOCATOR_H_
-#define ART_SRC_GREENLAND_REGISTER_ALLOCATOR_H_
-
-#include "backend_types.h"
-
-#include "lir_basic_block.h"
-
-#include <stdint.h>
-#include <list>
-#include <map>
-
-namespace art {
-namespace greenland {
-
-class LIR;
-class LIRFunction;
-class TargetRegisterInfo;
-
-class RegisterAllocator  {
- private:
-  enum RegTypeTag {
-    kPhyRegType = 0, kFrameType, kInStackType, kNoneType = -1
-  };
-
-  struct Storage {
-    int index;
-    RegTypeTag regTag;
-  };
-
-  // Storage Allocation
-  Storage AllocateStorage(LIRFunction &lir_func, unsigned vreg_idx);
-  void KeepStorage(const LIR& lir);
-  void FreeStorage(unsigned vreg_idx);
-  void HandleInsnCopy(LIRBasicBlock& bb,
-                      LIRBasicBlock::iterator it,
-                      LIRBasicBlock::iterator next_lir);
-
-  // Pre-RA
-  void BuildKillInfo(LIRFunction& lir_func);
-  void PHIElimination(LIRFunction& lir_func);
-
-  void InitializeAllocation(LIRFunction& lir_func);
-  void PreRegisterAllocation(LIRFunction& lir_func);
-  void FunctionRegisterAllocation(LIRFunction& lir_func);
- public:
-  RegisterAllocator(const TargetRegisterInfo& info) : reg_info_(info) { }
-  ~RegisterAllocator() { }
-
-  void AllocateRegisters(LIRFunction& lir_func) {
-    InitializeAllocation(lir_func);
-    PreRegisterAllocation(lir_func);
-    FunctionRegisterAllocation(lir_func);
-  }
-
- private:
-  std::list<unsigned> allocatable_list_;
-  std::list<unsigned> stackstorage_list_;
-  std::map<unsigned, Storage> allocated_map_;
-  const TargetRegisterInfo& reg_info_;
-  DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_REGISTER_ALLOCATOR_H_
diff --git a/src/greenland/runtime/runtime_utils.h b/src/greenland/runtime/runtime_utils.h
deleted file mode 100644
index cbdfcc6..0000000
--- a/src/greenland/runtime/runtime_utils.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_SRC_GREENLAND_RUNTIME_UTILS_H_
-#define ART_SRC_GREENLAND_RUNTIME_UTILS_H_
-
-#include "asm_support.h"
-#include "thread.h"
-
-namespace art {
-namespace greenland {
-
-static inline Thread* art_get_current_thread() {
-#if defined(__i386__)
-  Thread* ptr;
-  __asm__ __volatile__("movl %%fs:(%1), %0"
-      : "=r"(ptr)  // output
-      : "r"(THREAD_SELF_OFFSET)  // input
-      :);  // clobber
-  return ptr;
-#else
-  return Thread::Current();
-#endif
-}
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_RUNTIME_UTILS_H_
diff --git a/src/greenland/runtime/support_alloc.cc b/src/greenland/runtime/support_alloc.cc
deleted file mode 100644
index dd7850d..0000000
--- a/src/greenland/runtime/support_alloc.cc
+++ /dev/null
@@ -1,69 +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 "greenland/runtime_entry_points.h"
-
-#include "runtime_utils.h"
-#include "runtime_support.h"
-
-using namespace art;
-using namespace art::greenland;
-
-namespace {
-
-Object* art_alloc_array_from_code(uint32_t type_idx,
-                                  AbstractMethod* referrer,
-                                  uint32_t length,
-                                  Thread* thread) {
-  return AllocArrayFromCode(type_idx, referrer, length, thread, false);
-}
-
-Object* art_alloc_array_from_code_with_access_check(uint32_t type_idx,
-                                                    AbstractMethod* referrer,
-                                                    uint32_t length,
-                                                    Thread* thread) {
-  return AllocArrayFromCode(type_idx, referrer, length, thread, true);
-}
-
-Object* art_check_and_alloc_array_from_code(uint32_t type_idx,
-                                            AbstractMethod* referrer,
-                                            uint32_t length,
-                                            Thread* thread) {
-  return CheckAndAllocArrayFromCode(type_idx, referrer, length, thread, false);
-}
-
-Object* art_check_and_alloc_array_from_code_with_access_check(uint32_t type_idx,
-                                                              AbstractMethod* referrer,
-                                                              uint32_t length,
-                                                              Thread* thread) {
-  return CheckAndAllocArrayFromCode(type_idx, referrer, length, thread, true);
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitAllocRuntimes(RuntimeEntryPoints* entry_points) {
-  entry_points->AllocArray = art_alloc_array_from_code;
-  entry_points->AllocArrayWithAccessCheck = art_alloc_array_from_code_with_access_check;
-  entry_points->CheckAndAllocArray = art_check_and_alloc_array_from_code;
-  entry_points->CheckAndAllocArrayWithAccessCheck = art_check_and_alloc_array_from_code_with_access_check;
-  return;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/runtime/support_cast.cc b/src/greenland/runtime/support_cast.cc
deleted file mode 100644
index d74dbe7..0000000
--- a/src/greenland/runtime/support_cast.cc
+++ /dev/null
@@ -1,57 +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 "greenland/runtime_entry_points.h"
-
-#include "runtime_utils.h"
-#include "runtime_support.h"
-
-using namespace art;
-using namespace art::greenland;
-
-namespace {
-
-void art_check_put_array_element_from_code(const Object* element,
-                                           const Object* array) {
-  if (element == NULL) {
-    return;
-  }
-  DCHECK(array != NULL);
-  Class* array_class = array->GetClass();
-  DCHECK(array_class != NULL);
-  Class* component_type = array_class->GetComponentType();
-  Class* element_class = element->GetClass();
-  if (UNLIKELY(!component_type->IsAssignableFrom(element_class))) {
-    Thread* thread = art_get_current_thread();
-    thread->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
-                               "%s cannot be stored in an array of type %s",
-                               PrettyDescriptor(element_class).c_str(),
-                               PrettyDescriptor(array_class).c_str());
-  }
-  return;
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitCastRuntimes(RuntimeEntryPoints* entry_points) {
-  entry_points->CheckPutArrayElement = art_check_put_array_element_from_code;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/runtime/support_dexcache.cc b/src/greenland/runtime/support_dexcache.cc
deleted file mode 100644
index 9d36aad..0000000
--- a/src/greenland/runtime/support_dexcache.cc
+++ /dev/null
@@ -1,41 +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 "greenland/runtime_entry_points.h"
-
-#include "runtime_utils.h"
-#include "runtime_support.h"
-
-using namespace art;
-using namespace art::greenland;
-
-namespace {
-
-Object* art_resolve_string(AbstractMethod* referrer, uint32_t string_idx) {
-  return ResolveStringFromCode(referrer, string_idx);
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitDexCacheRuntimes(RuntimeEntryPoints* entry_points) {
-  entry_points->ResolveString = art_resolve_string;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/runtime/support_exception.cc b/src/greenland/runtime/support_exception.cc
deleted file mode 100644
index 4bc910a..0000000
--- a/src/greenland/runtime/support_exception.cc
+++ /dev/null
@@ -1,85 +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 "greenland/runtime_entry_points.h"
-
-#include "nth_caller_visitor.h"
-#include "runtime_utils.h"
-#include "runtime_support.h"
-
-using namespace art;
-using namespace art::greenland;
-
-namespace {
-
-int32_t art_find_catch_block(AbstractMethod* current_method, uint32_t ti_offset) {
-  Thread* thread = art_get_current_thread();
-  Class* exception_type = thread->GetException()->GetClass();
-  MethodHelper mh(current_method);
-  const DexFile::CodeItem* code_item = mh.GetCodeItem();
-  DCHECK_LT(ti_offset, code_item->tries_size_);
-  const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item, ti_offset);
-
-  int iter_index = 0;
-  // Iterate over the catch handlers associated with dex_pc
-  for (CatchHandlerIterator it(*code_item, *try_item); it.HasNext(); it.Next()) {
-    uint16_t iter_type_idx = it.GetHandlerTypeIndex();
-    // Catch all case
-    if (iter_type_idx == DexFile::kDexNoIndex16) {
-      return iter_index;
-    }
-    // Does this catch exception type apply?
-    Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx);
-    if (iter_exception_type == NULL) {
-      // The verifier should take care of resolving all exception classes early
-      LOG(WARNING) << "Unresolved exception class when finding catch block: "
-          << mh.GetTypeDescriptorFromTypeIdx(iter_type_idx);
-    } else if (iter_exception_type->IsAssignableFrom(exception_type)) {
-      return iter_index;
-    }
-    ++iter_index;
-  }
-  // Handler not found
-  return -1;
-}
-
-void art_throw_array_bounds(int32_t length, int32_t index) {
-  Thread* thread = art_get_current_thread();
-  thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
-                             "length=%d; index=%d", length, index);
-}
-
-void art_throw_null_pointer_exception(uint32_t dex_pc) {
-  Thread* thread = art_get_current_thread();
-  NthCallerVisitor visitor(0);
-  thread->WalkStack(&visitor);
-  AbstractMethod* throw_method = visitor.caller;
-  ThrowNullPointerExceptionFromDexPC(thread, throw_method, dex_pc);
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitExceptionRuntimes(RuntimeEntryPoints* entry_points) {
-  entry_points->FindCatchBlock = art_find_catch_block;
-  entry_points->ThrowIndexOutOfBounds = art_throw_array_bounds;
-  entry_points->ThrowNullPointerException = art_throw_null_pointer_exception;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/runtime/support_field.cc b/src/greenland/runtime/support_field.cc
deleted file mode 100644
index e5fa814..0000000
--- a/src/greenland/runtime/support_field.cc
+++ /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.
- */
-
-#include "greenland/runtime_entry_points.h"
-
-#include "runtime_utils.h"
-#include "runtime_support.h"
-
-using namespace art;
-using namespace art::greenland;
-
-namespace {
-
-Object* art_get_obj_static_from_code(uint32_t field_idx, AbstractMethod* referrer) {
-  Field* field = FindFieldFast(field_idx, referrer, false, false, sizeof(Object*));
-  if (LIKELY(field != NULL)) {
-    return field->GetObj(NULL);
-  }
-  field = FindFieldFromCode(field_idx, referrer, art_get_current_thread(),
-                            true, false, false, sizeof(Object*));
-  if (LIKELY(field != NULL)) {
-    return field->GetObj(NULL);
-  }
-  return 0;
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitFieldRuntimes(RuntimeEntryPoints* entry_points) {
-  entry_points->GetObjectStatic = art_get_obj_static_from_code;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/runtime/support_thread.cc b/src/greenland/runtime/support_thread.cc
deleted file mode 100644
index 25fb698..0000000
--- a/src/greenland/runtime/support_thread.cc
+++ /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.
- */
-
-#include "greenland/runtime_entry_points.h"
-
-#include "runtime_utils.h"
-#include "runtime_support.h"
-#include "thread_list.h"
-
-using namespace art;
-using namespace art::greenland;
-
-namespace {
-
-void art_test_suspend(Thread* thread) {
-  Runtime::Current()->GetThreadList()->FullSuspendCheck(thread);
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitThreadRuntimes(RuntimeEntryPoints* entry_points) {
-  entry_points->TestSuspend = art_test_suspend;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/runtime_entry_points.cc b/src/greenland/runtime_entry_points.cc
deleted file mode 100644
index a9b1edc..0000000
--- a/src/greenland/runtime_entry_points.cc
+++ /dev/null
@@ -1,49 +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_entry_points.h"
-
-namespace art {
-
-// Forward Declarations
-namespace greenland {
-
-void InitThreadRuntimes(RuntimeEntryPoints* entry_points);
-void InitExceptionRuntimes(RuntimeEntryPoints* entry_points);
-void InitAllocRuntimes(RuntimeEntryPoints* entry_points);
-void InitDexCacheRuntimes(RuntimeEntryPoints* entry_points);
-void InitFieldRuntimes(RuntimeEntryPoints* entry_points);
-void InitCastRuntimes(RuntimeEntryPoints* entry_points);
-
-} // namespace greenland
-
-void InitRuntimeEntryPoints(RuntimeEntryPoints* entry_points) {
-  // Defined in runtime/support_thread.cc
-  greenland::InitThreadRuntimes(entry_points);
-  // Defined in runtime/support_exception.cc
-  greenland::InitExceptionRuntimes(entry_points);
-  // Defined in runtime/support_alloc.cc
-  greenland::InitAllocRuntimes(entry_points);
-  // Defined in runtime/support_dexcache.cc
-  greenland::InitDexCacheRuntimes(entry_points);
-  // Defined in runtime/support_field.cc
-  greenland::InitFieldRuntimes(entry_points);
-  // Defined in runtime/support_case.cc
-  greenland::InitCastRuntimes(entry_points);
-  return;
-}
-
-} // namespace art
diff --git a/src/greenland/runtime_entry_points.h b/src/greenland/runtime_entry_points.h
deleted file mode 100644
index 9ee053e..0000000
--- a/src/greenland/runtime_entry_points.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_RUNTIME_ENTRY_POINTS_H_
-#define ART_SRC_GREENLAND_RUNTIME_ENTRY_POINTS_H_
-
-#include "macros.h"
-
-#include <stdint.h>
-
-#define RUNTIME_ENTRYPOINT(x) \
-  (static_cast<uintptr_t>(OFFSETOF_MEMBER(Thread, runtime_entry_points_)) + \
-   static_cast<uintptr_t>(OFFSETOF_MEMBER(RuntimeEntryPoints, x)))
-
-namespace art {
-
-class AbstractMethod;
-class Object;
-class Thread;
-
-struct PACKED RuntimeEntryPoints {
-  //----------------------------------------------------------------------------
-  // Thread
-  //----------------------------------------------------------------------------
-  void (*TestSuspend)(Thread* thread);
-
-  //----------------------------------------------------------------------------
-  // Exception
-  //----------------------------------------------------------------------------
-  int32_t (*FindCatchBlock)(AbstractMethod* current_method, uint32_t ti_offset);
-  void (*ThrowIndexOutOfBounds)(int32_t length, int32_t index);
-  void (*ThrowNullPointerException)(unsigned dex_pc);
-
-  //----------------------------------------------------------------------------
-  // Alloc
-  //----------------------------------------------------------------------------
-  Object* (*AllocArray)(uint32_t type_idx, AbstractMethod* referrer,
-                        uint32_t length, Thread* thread);
-
-  Object* (*AllocArrayWithAccessCheck)(uint32_t type_idx, AbstractMethod* referrer,
-                                       uint32_t length, Thread* thread);
-
-  Object* (*CheckAndAllocArray)(uint32_t type_idx, AbstractMethod* referrer,
-                                uint32_t length, Thread* thread);
-
-  Object* (*CheckAndAllocArrayWithAccessCheck)(uint32_t type_idx,
-                                               AbstractMethod* referrer,
-                                               uint32_t length,
-                                               Thread* thread);
-
-  //----------------------------------------------------------------------------
-  // DexCache
-  //----------------------------------------------------------------------------
-  Object* (*ResolveString)(AbstractMethod* referrer, uint32_t string_idx);
-
-  //----------------------------------------------------------------------------
-  // Field
-  //----------------------------------------------------------------------------
-  Object* (*GetObjectStatic)(uint32_t field_idx, AbstractMethod* referrer);
-
-  //----------------------------------------------------------------------------
-  // Cast
-  //----------------------------------------------------------------------------
-  void (*CheckPutArrayElement)(const Object* element, const Object* array);
-
-  //----------------------------------------------------------------------------
-  // JNI
-  //----------------------------------------------------------------------------
-};
-
-// Initialize an entry point data structure.
-void InitRuntimeEntryPoints(RuntimeEntryPoints* entry_points);
-
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_RUNTIME_ENTRY_POINTS_H_
diff --git a/src/greenland/target_codegen_machine.cc b/src/greenland/target_codegen_machine.cc
deleted file mode 100644
index 3c65a68..0000000
--- a/src/greenland/target_codegen_machine.cc
+++ /dev/null
@@ -1,70 +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 "target_codegen_machine.h"
-
-#include "lir_function.h"
-#include "lir_pass_manager.h"
-#include "target_lir_emitter.h"
-#include "target_lir_opcodes.h"
-#include "target_registry.h"
-
-#include "compiled_method.h"
-#include "compiler.h"
-#include "oat_compilation_unit.h"
-#include "utils.h"
-
-#include <UniquePtr.h>
-
-namespace art {
-namespace greenland {
-
-TargetCodeGenMachine* TargetCodeGenMachine::Create(InstructionSet insn_set) {
-  TargetRegistry::TargetCodeGenMachineCtorTy ctor =
-      TargetRegistry::GetTargetCodeGenMachineCtor(insn_set);
-
-  if (ctor == NULL) {
-    return NULL;
-  }
-
-  return (*ctor)();
-}
-
-CompiledMethod* TargetCodeGenMachine::Run(const Compiler& compiler,
-                                          const GBCFunction& gbc_func) {
-  LIRPassManager lir_pm;
-
-  lir_pm.Add(CreateLIREmitter());
-
-  LIRFunction lir_func(*this, gbc_func);
-
-  if (!lir_pm.Run(lir_func)) {
-    return NULL;
-  }
-
-  lir_func.Dump();
-
-  // 0x90 is the NOP in x86
-  std::vector<uint8_t> code(10, 0x90);
-
-  return new CompiledMethod(compiler.GetInstructionSet(), code,
-                            /* frame_size_in_bytes */0,
-                            /* core_spill_mask */0,
-                            /* fp_spill_mask */0);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/target_codegen_machine.h b/src/greenland/target_codegen_machine.h
deleted file mode 100644
index 8cae791..0000000
--- a/src/greenland/target_codegen_machine.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_TARGET_CODEGEN_MACHINE_H_
-#define ART_SRC_GREENLAND_TARGET_CODEGEN_MACHINE_H_
-
-#include "instruction_set.h"
-
-#include <string>
-
-namespace art {
-  class CompiledMethod;
-  class Compiler;
-}
-
-namespace art {
-namespace greenland {
-
-class GBCFunction;
-class LIR;
-class RegisterAllocator;
-class TargetAssembler;
-class TargetDataLayout;
-class TargetLIRBuilder;
-class TargetLIREmitter;
-class TargetLIRInfo;
-class TargetRegisterInfo;
-
-class TargetCodeGenMachine {
- protected:
-  TargetCodeGenMachine() { }
-
- public:
-  virtual ~TargetCodeGenMachine() { }
-
-  virtual TargetLIREmitter* CreateLIREmitter() = 0;
-
-  virtual const TargetDataLayout* GetDataLayout() const = 0;
-
-  virtual const TargetLIRInfo* GetLIRInfo() const = 0;
-
-  virtual const TargetRegisterInfo* GetRegisterInfo() const = 0;
-
-  virtual const char* GetConditionCodeName(unsigned cond) const = 0;
-
-  virtual TargetLIRBuilder* CreateLIRBuilder() = 0;
-
-  virtual RegisterAllocator* GetRegisterAllocator() = 0;
-
-  virtual TargetAssembler* GetAssembler() = 0;
-
-  static TargetCodeGenMachine* Create(InstructionSet insn_set);
-
- public:
-  CompiledMethod* Run(const Compiler& compiler, const GBCFunction& gbc_func);
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_TARGET_CODEGEN_MACHINE_H_
diff --git a/src/greenland/target_data_layout.h b/src/greenland/target_data_layout.h
deleted file mode 100644
index 7b634cf..0000000
--- a/src/greenland/target_data_layout.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_TARGET_DATA_LAYOUT_H_
-#define ART_SRC_GREENLAND_TARGET_DATA_LAYOUT_H_
-
-#include "lir.h"
-
-#include "logging.h"
-
-namespace art {
-namespace greenland {
-
-class TargetDataLayout {
- private:
-  // Size of pointer in bytes
-  unsigned pointer_size_;
-
-  // Stack alignment in bytes
-  unsigned stack_alignment_;
-
- public:
-  TargetDataLayout(unsigned pointer_size, unsigned stack_alignment)
-      : pointer_size_(pointer_size), stack_alignment_(stack_alignment) { }
-
-  unsigned GetPointerSize() const {
-    return pointer_size_;
-  }
-  unsigned GetPointerSizeInBits() const {
-    return (pointer_size_ << 3);
-  }
-
-  unsigned GetStackAlignment() const {
-    return stack_alignment_;
-  }
-
-  unsigned GetOpTypeSize(LIR::OperationType op_type) const {
-    switch (op_type) {
-      case LIR::kUInt8TypeOp:   return 1;   break;
-      case LIR::kSInt8TypeOp:   return 1;   break;
-      case LIR::kUInt16TypeOp:  return 2;   break;
-      case LIR::kSInt16TypeOp:  return 2;   break;
-      case LIR::kInt32TypeOp:   return 4;   break;
-      case LIR::kInt64TypeOp:   return 8;   break;
-      case LIR::kFloatTypeOp:   return 4;   break;
-      case LIR::kDoubleTypeOp:  return 8;   break;
-      case LIR::kPointerTypeOp: return pointer_size_;   break;
-      case LIR::kUnknownTypeOp:
-      default: {
-        LOG(FATAL) << "Unknown operation type: " << op_type;
-        return 0;
-      }
-    }
-    // unreachable
-  }
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_TARGET_DATA_LAYOUT_H_
diff --git a/src/greenland/target_register_info.h b/src/greenland/target_register_info.h
deleted file mode 100644
index 41d69e1..0000000
--- a/src/greenland/target_register_info.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_TARGET_REGISTER_INFO_H_
-#define ART_SRC_GREENLAND_TARGET_REGISTER_INFO_H_
-
-#include "lir_function.h"
-#include "lir_reg.h"
-
-#include "target_lir_builder.h"
-#include "target_lir_info.h"
-
-#include <string>
-
-namespace art {
-namespace greenland {
-
-class TargetRegisterInfo {
- protected:
-  const TargetLIRInfo& lir_info_;
-  TargetRegisterInfo(const TargetLIRInfo& info) :lir_info_(info) { }
-
- public:
-  virtual const char* GetPhyRegName(unsigned reg) const = 0;
-
-  std::string GetRegName(unsigned reg) const {
-    if (LIRReg::IsVirtualReg(reg)) {
-      return LIRReg::GetVirtualRegName(reg);
-    } else {
-      return GetPhyRegName(reg);
-    }
-  }
-
-  virtual LIR*
-  CreateLoadStack(LIRFunction& lir_func,
-                  unsigned reg,
-                  int frame_idx) const = 0;
-
-  virtual LIR*
-  CreateStoreStack(LIRFunction& lir_func,
-                   unsigned reg,
-                   int frame_idx) const = 0;
-
-  virtual LIR*
-  CreateMoveReg(LIRFunction& lir_func,
-                unsigned dst,
-                unsigned src) const = 0;
-
-  virtual bool
-  IsLoadIncomingArgs(const LIR* lir) const = 0;
-
-  virtual LIR*
-  CreateCopy(LIRFunction& lir_func,
-             unsigned dst,
-             const LIROperand& src) const = 0;
-
-  virtual std::list<unsigned> GetAllocatableList() const = 0;
-  virtual unsigned GetTempRegsiter(unsigned idx) const = 0;
-
-  virtual ~TargetRegisterInfo() { }
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_TARGET_REGISTER_INFO_H_
diff --git a/src/greenland/target_registry.cc b/src/greenland/target_registry.cc
deleted file mode 100644
index e4a1840..0000000
--- a/src/greenland/target_registry.cc
+++ /dev/null
@@ -1,80 +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 "target_registry.h"
-
-#include "logging.h"
-
-namespace {
-
-// The following arrays contain the real registry data store by Register*()
-// methods in TargetRegistry. Should keep sync with enum InstructionSet.
-art::greenland::TargetRegistry::TargetCodeGenMachineCtorTy
-RegisteredTargetCodeGenMachineCtor[] = {
-  NULL, /* kNone   */
-  NULL, /* kArm    */
-  NULL, /* kThumb2 */
-  NULL, /* kX86    */
-  NULL, /* kMips   */
-};
-
-art::greenland::TargetRegistry::CreateInvokeStubFn
-RegisteredInvokeStubCompiler[] = {
-  NULL, /* kNone   */
-  NULL, /* kArm    */
-  NULL, /* kThumb2 */
-  NULL, /* kX86    */
-  NULL, /* kMips   */
-};
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void TargetRegistry::RegisterTargetCodeGenMachine(InstructionSet insn_set,
-                                            TargetCodeGenMachineCtorTy ctor) {
-  CHECK(static_cast<unsigned>(insn_set) <
-          (sizeof(RegisteredTargetCodeGenMachineCtor) / sizeof(RegisteredTargetCodeGenMachineCtor[0])));
-  RegisteredTargetCodeGenMachineCtor[static_cast<unsigned>(insn_set)] = ctor;
-  return;
-}
-
-TargetRegistry::TargetCodeGenMachineCtorTy
-TargetRegistry::GetTargetCodeGenMachineCtor(InstructionSet insn_set) {
-  CHECK(static_cast<unsigned>(insn_set) <
-          (sizeof(RegisteredTargetCodeGenMachineCtor) / sizeof(RegisteredTargetCodeGenMachineCtor[0])));
-  return RegisteredTargetCodeGenMachineCtor[static_cast<unsigned>(insn_set)];
-}
-
-void
-TargetRegistry::RegisterInvokeStubCompiler(InstructionSet insn_set,
-                                           CreateInvokeStubFn compiler_fn) {
-  CHECK(static_cast<unsigned>(insn_set) <
-        (sizeof(RegisteredInvokeStubCompiler) / sizeof(RegisteredInvokeStubCompiler[0])));
-  RegisteredInvokeStubCompiler[static_cast<unsigned>(insn_set)] = compiler_fn;
-  return;
-}
-
-TargetRegistry::CreateInvokeStubFn
-TargetRegistry::GetInvokeStubCompiler(InstructionSet insn_set) {
-  CHECK(static_cast<unsigned>(insn_set) <
-        (sizeof(RegisteredInvokeStubCompiler) / sizeof(RegisteredInvokeStubCompiler[0])));
-  return RegisteredInvokeStubCompiler[static_cast<unsigned>(insn_set)];
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/target_registry.h b/src/greenland/target_registry.h
deleted file mode 100644
index 0f490e0..0000000
--- a/src/greenland/target_registry.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_TARGET_REGISTRY_H_
-#define ART_SRC_GREENLAND_TARGET_REGISTRY_H_
-
-#include "instruction_set.h"
-
-#include <stdint.h>
-
-namespace art {
-  class Compiler;
-  class CompiledInvokeStub;
-}
-
-namespace art {
-namespace greenland {
-
-class TargetCodeGenMachine;
-
-class TargetRegistry {
- public:
-  typedef TargetCodeGenMachine* (*TargetCodeGenMachineCtorTy)();
-  typedef CompiledInvokeStub* (*CreateInvokeStubFn)(Compiler& compiler,
-                                                    bool is_static,
-                                                    const char* shorty,
-                                                    uint32_t shorty_len);
-
-  static void RegisterTargetCodeGenMachine(InstructionSet insn_set,
-                                           TargetCodeGenMachineCtorTy ctor);
-  static TargetCodeGenMachineCtorTy GetTargetCodeGenMachineCtor(InstructionSet insn_set);
-
-  static void RegisterInvokeStubCompiler(InstructionSet insn_set,
-                                         CreateInvokeStubFn compiler_fn);
-  static CreateInvokeStubFn GetInvokeStubCompiler(InstructionSet insn_set);
-};
-
-template<class TargetCodeGenMachineImpl>
-class RegisterTargetCodeGenMachine {
- private:
-  static TargetCodeGenMachine* Allocator() {
-    return new TargetCodeGenMachineImpl();
-  }
-
- public:
-  RegisterTargetCodeGenMachine(InstructionSet insn_set) {
-    TargetRegistry::RegisterTargetCodeGenMachine(insn_set, &Allocator);
-  }
-};
-
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_TARGET_REGISTRY_H_
diff --git a/src/greenland/tools/target_lir_builder_generator.cc b/src/greenland/tools/target_lir_builder_generator.cc
deleted file mode 100644
index 2a48136..0000000
--- a/src/greenland/tools/target_lir_builder_generator.cc
+++ /dev/null
@@ -1,574 +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 <cassert>
-#include <cctype>
-#include <cstring>
-#include <iostream>
-#include <string>
-
-// Should be synced with the one in lir_desc.h
-#define MAX_LIR_OPERANDS  6
-
-//----------------------------------------------------------------------------
-// Operand Info
-//----------------------------------------------------------------------------
-class LIROperand {
- public:
-  enum Type {
-    UnknownType,
-    RegisterType,
-    ImmediateType,
-    LabelType,
-    FrameIndexType,
-  };
-};
-
-// Copy from lir_desc.h
-class LIRDescFlag {
- public:
-  enum Flag {
-    kNone,
-    kPseudo,
-    kVariadic,
-
-    kIsLoad,
-    kIsStore,
-    kIsBranch,
-
-    kDefReg0,
-    kDefReg1,
-
-    kUseReg0,
-    kUseReg1,
-    kUseReg2,
-    kUseReg3,
-    kUseReg4,
-    kUseReg5,
-
-    kSetCCodes,
-    kUseCCodes,
-
-    kNeedRelax,
-  };
-};
-
-class LIROperandInfo {
- public:
-  class TypeStrings {
-   public:
-    // Take RegisterType as example:
-    //  type_string_ is "unsigned"
-    //  var_string_ is "reg"
-    //  set_method_ is "SetReg"
-    const char* type_string_;
-    const char* var_string_;
-    const char* set_method_;
-  };
-
-  LIROperand::Type GetOperandType(unsigned i) const {
-    assert((i < num_operands_) && "Invalid operand index!");
-    return info_[i].type_;
-  }
-
-  const TypeStrings& GetOperandTypeStrings(unsigned i) const {
-    return OperandTypeStrings[GetOperandType(i)];
-  }
-
- private:
-  static const TypeStrings OperandTypeStrings[];
-
- public:
-  const char* name_;
-  unsigned num_operands_;
-  struct {
-    enum LIROperand::Type type_;
-  } info_[MAX_LIR_OPERANDS];
-};
-
-const LIROperandInfo::TypeStrings LIROperandInfo::OperandTypeStrings[] = {
-  /* UnknownType    */ { "void",           "",            "",              },
-  /* RegisterType   */ { "unsigned",       "reg",         "SetReg"         },
-  /* ImmediateType  */ { "int32_t" ,       "imm_val",     "SetImm"         },
-  /* LabelType      */ { "LIRBasicBlock*", "target",      "SetLabelTarget" },
-  /* FrameIndexType */ { "int",            "frame_index", "SetFrameIndex"  }
-};
-
-#define DEF_LIR_OPERAND_INFO(INFO_ID, NUM_OPS, INFO_DEF) \
-static const LIROperandInfo OpInfo ## INFO_ID = \
-  { #INFO_ID, NUM_OPS, INFO_DEF };
-#include "greenland/target_lir.def"
-#include "greenland/clear_target_lir.def"
-
-static const LIROperandInfo* const OpInfos[] = {
-#define DEF_LIR_OPERAND_INFO(INFO_ID, NUM_OPS, INFO_DEF) \
-  &OpInfo ## INFO_ID,
-#include "greenland/target_lir.def"
-#include "greenland/clear_target_lir.def"
-};
-
-static const unsigned NumObInfos = sizeof(OpInfos) / sizeof(OpInfos[0]);
-
-//----------------------------------------------------------------------------
-// Data structure of LIRDesc to load {target}_lir.def
-//----------------------------------------------------------------------------
-
-class LIRDesc {
- public:
-  const char* opcode_name_;
-  const char* name_;
-  const char* format_;
-  unsigned flags;
-  const LIROperandInfo& operand_info_;
-
-  bool IsPseudo() const {
-    return (flags & (1 << LIRDescFlag::kPseudo));
-  }
-};
-
-//----------------------------------------------------------------------------
-// Target-independent LIR Enumeration
-//----------------------------------------------------------------------------
-// This is here to get the number of target-independent LIRs
-// (i.e., kNumTargetIndependentLIR)
-enum {
-#define DEF_LIR_DESC(OPCODE, ...) OPCODE,
-#include "greenland/target_lir.def"
-#include "greenland/clear_target_lir.def"
-
-  kNumTargetIndependentLIR
-};
-
-//----------------------------------------------------------------------------
-// ARM
-//----------------------------------------------------------------------------
-static const LIRDesc ARMLIR[] = {
-#define DEF_LIR_DESC(OPCODE, KIND, FLAGS, NAME, FORMAT, OPS_INFO) \
-  { #OPCODE, NAME, FORMAT, FLAGS, OpInfo ## OPS_INFO },
-#include "greenland/arm/arm_lir.def"
-};
-
-//----------------------------------------------------------------------------
-// Mips
-//----------------------------------------------------------------------------
-static const LIRDesc MipsLIR[] = {
-#define DEF_LIR_DESC(OPCODE, KIND, FLAGS, NAME, FORMAT, OPS_INFO) \
-  { #OPCODE, NAME, FORMAT, FLAGS, OpInfo ## OPS_INFO },
-#include "greenland/mips/mips_lir.def"
-};
-
-//----------------------------------------------------------------------------
-// X86
-//----------------------------------------------------------------------------
-static const LIRDesc X86LIR[] = {
-#define DEF_LIR_DESC(OPCODE, KIND, FLAGS, NAME, FORMAT, OPS_INFO) \
-  { #OPCODE, NAME, FORMAT, FLAGS, OpInfo ## OPS_INFO },
-#include "greenland/x86/x86_lir.def"
-};
-
-class Context {
- private:
-  std::ostream& out_;
-  unsigned indent_;
-
- public:
-  Context(std::ostream& out) : out_(out), indent_(0) { }
-
-  void IncIndent() {
-    indent_ += 2;
-    return;
-  }
-
-  void DecIndent() {
-    indent_ -= 2;
-  }
-
-  std::ostream& Indent() {
-    for (unsigned i = 0; i < indent_; i += 2) {
-      out_.write("  ", 2);
-    }
-    return out_;
-  }
-
-  std::ostream& Newline() {
-    return out_ << std::endl;
-  }
-
-  std::ostream& Out() {
-    return out_;
-  }
-
-  const LIRDesc* target_lirs_;
-  unsigned num_target_lirs_;
-
-  std::string lowercase_target_string_;
-  std::string uppercase_target_string_;
-  std::string class_name_;
-};
-
-class GenPrototype {
-  const LIROperandInfo& op_info_;
-  const char* preface_;
- public:
-  GenPrototype(const LIROperandInfo& op_info, const char* preface = NULL)
-      : op_info_(op_info), preface_(preface) { }
-
-  friend std::ostream& operator<<(std::ostream& out, const GenPrototype& obj);
-};
-
-std::ostream& operator<<(std::ostream& out, const GenPrototype& obj) {
-  out << "(";
-
-  unsigned num_ops = obj.op_info_.num_operands_;
-  if (obj.preface_ != NULL) {
-    out << obj.preface_;
-    if (num_ops > 0) {
-      out << ", ";
-    }
-  }
-
-  for (unsigned i = 0; i < num_ops; i++) {
-    const LIROperandInfo::TypeStrings& type_strings =
-        obj.op_info_.GetOperandTypeStrings(i);
-
-    out << type_strings.type_string_ << " " << type_strings.var_string_ << i;
-
-    if (i != (num_ops - 1)) {
-      // Append "," if not the last one
-      out << ", ";
-    }
-  }
-
-  out << ")";
-  return out;
-}
-
-//----------------------------------------------------------------------------
-
-// Forward Declarations
-static void GenBeginNamespace(Context& C);
-static void GenCreateTargetLIR(Context& C, const LIRDesc& lir, bool proto_only);
-static void GenCallSetOperands(Context& C, const LIROperandInfo& operand_info);
-static void GenEndNamespace(Context& C);
-
-static void GenLicenseNote(Context& C) {
-  C.Indent() << "/*" << std::endl;
-  C.Indent() << " * Copyright (C) 2012 The Android Open Source Project" << std::endl;
-  C.Indent() << " *" << std::endl;
-  C.Indent() << " * Licensed under the Apache License, Version 2.0 (the \"License\"" << std::endl;
-  C.Indent() << " * you may not use this file except in compliance with the License." << std::endl;
-  C.Indent() << " * You may obtain a copy of the License at" << std::endl;
-  C.Indent() << " *" << std::endl;
-  C.Indent() << " *      http://www.apache.org/licenses/LICENSE-2.0" << std::endl;
-  C.Indent() << " *" << std::endl;
-  C.Indent() << " * Unless required by applicable law or agreed to in writing, software" << std::endl;
-  C.Indent() << " * distributed under the License is distributed on an \"AS IS\" BASIS," << std::endl;
-  C.Indent() << " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." << std::endl;
-  C.Indent() << " * See the License for the specific language governing permissions and" << std::endl;
-  C.Indent() << " * limitations under the License." << std::endl;
-  C.Indent() << " */" << std::endl;
-  C.Newline();
-  return;
-}
-
-//----------------------------------------------------------------------------
-
-static void GenTargetLIRBuilderHeader(Context& C) {
-  C.Indent() << "#ifdef GET_" << C.uppercase_target_string_ << "_LIR_BUILDER_HEADER";
-  C.Newline();
-
-  //----------------------------------------------------------------------------
-  // Include Files
-  //----------------------------------------------------------------------------
-  C.Indent() << "#include \"greenland/target_lir_builder.h\"" << std::endl;;
-  C.Indent() << "#include \"greenland/target_lir_info.h\"" << std::endl;
-  C.Newline();
-
-  GenBeginNamespace(C);
-
-  //----------------------------------------------------------------------------
-  // Forward Declarations
-  //----------------------------------------------------------------------------
-  C.Indent() << "class TargetLIRInfo;" << std::endl;
-  C.Newline();
-
-  C.Indent() << "class " << C.class_name_ << " : public TargetLIRBuilder {"
-             << std::endl;
-
-  //----------------------------------------------------------------------------
-  // Members
-  //----------------------------------------------------------------------------
-  C.Indent() << " private:" << std::endl;
-  C.IncIndent();
-  C.Indent() << "const TargetLIRInfo& info_;" << std::endl;
-  C.DecIndent();
-  C.Newline();
-
-  //----------------------------------------------------------------------------
-  // APIs
-  //----------------------------------------------------------------------------
-  C.Indent() << " public:" << std::endl;
-
-  C.IncIndent();
-
-  //----------------------------------------------------------------------------
-  // Constructor
-  //----------------------------------------------------------------------------
-  C.Indent() << C.class_name_ << "(const TargetLIRInfo& info) "
-                                 ": TargetLIRBuilder(), info_(info) { }"
-             << std::endl;
-  C.Newline();
-
-  //----------------------------------------------------------------------------
-  // LIR* Create(unsigned opcode)
-  //----------------------------------------------------------------------------
-  C.Indent() << "LIR* Create(unsigned opcode) {" << std::endl;
-  C.IncIndent();
-
-  C.Indent() << "return bb_->GetParent().CreateLIR(*bb_, info_.GetLIRDesc(opcode));" << std::endl;
-
-  C.DecIndent();
-  C.Indent() << "}" << std::endl;
-  C.Newline();
-
-  //----------------------------------------------------------------------------
-  // LIR* Create(LIRDesc& desc)
-  //----------------------------------------------------------------------------
-  C.Indent() << "LIR* Create(const LIRDesc& desc) {" << std::endl;
-  C.IncIndent();
-
-  C.Indent() << "return bb_->GetParent().CreateLIR(*bb_, desc);" << std::endl;
-
-  C.DecIndent();
-  C.Indent() << "}" << std::endl;
-  C.Newline();
-
-  //----------------------------------------------------------------------------
-  // LIR* Create_*([operand...])
-  //----------------------------------------------------------------------------
-  for (unsigned i = 0; i < C.num_target_lirs_; i++) {
-    const LIRDesc& lir = C.target_lirs_[i];
-    if (!lir.IsPseudo() || (i > kNumTargetIndependentLIR)) {
-      GenCreateTargetLIR(C, lir, /* proto_only */true);
-    }
-  }
-
-  C.DecIndent();
-
-  C.Indent() << "};" << std::endl;
-  C.Newline();
-
-  GenEndNamespace(C);
-
-  C.Indent() << "#undef GET_" << C.uppercase_target_string_ << "_LIR_BUILDER_HEADER" << std::endl;
-  C.Indent() << "#endif // GET_" << C.uppercase_target_string_ << "_LIR_BUILDER_HEADER" << std::endl;
-  return;
-}
-
-static void GenTargetLIRBuilderImpl(Context& C) {
-  C.Indent() << "#ifdef GET_" << C.uppercase_target_string_ << "_LIR_BUILDER_IMPL";
-  C.Newline();
-
-  //----------------------------------------------------------------------------
-  // Include Files
-  //----------------------------------------------------------------------------
-  C.Indent() << "#include \"greenland/lir_desc.h\"" << std::endl;
-  C.Indent() << "#include \"greenland/lir_function.h\"" << std::endl;
-  C.Indent() << "#include \"greenland/" << C.lowercase_target_string_
-             << "/" << C.lowercase_target_string_ << "_lir_opcodes.h\""
-             << std::endl;
-  C.Newline();
-
-  GenBeginNamespace(C);
-
-  for (unsigned i = 0; i < C.num_target_lirs_; i++) {
-    const LIRDesc& lir = C.target_lirs_[i];
-    if (!lir.IsPseudo() || (i > kNumTargetIndependentLIR)) {
-      GenCreateTargetLIR(C, lir, /* proto_only */false);
-    }
-  }
-
-  C.Newline();
-
-  GenEndNamespace(C);
-
-  C.Indent() << "#undef GET_" << C.uppercase_target_string_ << "_LIR_BUILDER_IMPL" << std::endl;
-  C.Indent() << "#endif // GET_" << C.uppercase_target_string_ << "_LIR_BUILDER_IMPL" << std::endl;
-  C.Newline();
-  return;
-}
-
-//----------------------------------------------------------------------------
-
-static void GenBeginNamespace(Context& C) {
-  C.Indent() << "namespace art {" << std::endl;
-  C.Indent() << "namespace greenland {" << std::endl;
-  C.Newline();
-  return;
-}
-
-static void GenCreateTargetLIR(Context& C, const LIRDesc& lir, bool proto_only){
-  C.Indent() << "// " << lir.name_ << " " << lir.format_ << std::endl;
-
-  if (proto_only) {
-    C.Indent() << "LIR* Create_" << &lir.opcode_name_[1] /* hack: skip 'k' */
-               << GenPrototype(lir.operand_info_) << ";" << std::endl;
-    return;
-  } else {
-    C.Indent() << "LIR* " << C.class_name_ << "::Create_"
-               << &lir.opcode_name_[1] /* hack: skip 'k' */
-               << GenPrototype(lir.operand_info_) << " {" << std::endl;
-  }
-
-  C.IncIndent();
-  C.Indent() << "LIR* lir = Create("
-             << C.lowercase_target_string_ << "::" << lir.opcode_name_<< ");"
-             << std::endl;
-  GenCallSetOperands(C, lir.operand_info_);
-  C.Indent() << "return lir;" << std::endl;
-  C.DecIndent();
-
-  C.Indent() << "}" << std::endl;
-  C.Newline();
-  return;
-}
-
-static void
-GenCallSetOperands(Context& C, const LIROperandInfo& operand_info) {
-  if (operand_info.num_operands_ > 0) {
-    C.Indent() << "Set" << operand_info.name_ << "Operands(*lir, ";
-
-    for (unsigned i = 0; i < operand_info.num_operands_; i++) {
-      const LIROperandInfo::TypeStrings& type_strings =
-        operand_info.GetOperandTypeStrings(i);
-
-      C.Out() << type_strings.var_string_ << i;
-
-      if (i != (operand_info.num_operands_ - 1)) {
-        // Append "," if not the last one
-        C.Out() << ", ";
-      }
-    }
-
-    C.Out() << ");" << std::endl;
-  }
-  return;
-}
-
-static void GenEndNamespace(Context& C) {
-  C.Newline();
-  C.Indent() << "} // namespace greenland" << std::endl;
-  C.Indent() << "} // namespace art" << std::endl;
-  C.Newline();
-  return;
-}
-
-//----------------------------------------------------------------------------
-// Special functionality to generate Set*Operands in TargetLIRBuilder
-//----------------------------------------------------------------------------
-static void GenSetOperandsImpl(Context& C, const LIROperandInfo& operand_info);
-
-static void GenSetOperands(Context& C) {
-  for (unsigned i = 0; i < NumObInfos; i++) {
-    const LIROperandInfo& op_info = *OpInfos[i];
-    C.Indent() << "static inline void Set" << op_info.name_
-               << "Operands" << GenPrototype(op_info, /* preface */"LIR& lir")
-               << " {" << std::endl;
-    C.IncIndent();
-    GenSetOperandsImpl(C, op_info);
-    C.DecIndent();
-    C.Indent() << "}" << std::endl;
-    C.Newline();
-  }
-
-  return;
-}
-
-static void GenSetOperandsImpl(Context& C, const LIROperandInfo& operand_info) {
-  if (operand_info.num_operands_ <= 0) {
-    return;
-  }
-
-  C.Indent() << "lir";
-  for (unsigned i = 0; i < operand_info.num_operands_; i++) {
-    const LIROperandInfo::TypeStrings& type_strings =
-      operand_info.GetOperandTypeStrings(i);
-
-    if (i != 0) {
-      C.Indent() << "   ";
-    }
-
-    C.Out() << "." << type_strings.set_method_ << "(" << i << ", "
-                                               << type_strings.var_string_ << i
-                                               << ")";
-    if (i == (operand_info.num_operands_ - 1)) {
-      // Append ";" if not the last one
-      C.Out() << ";";
-    }
-    C.Out() << std::endl;
-  }
-
-  C.Indent() << "return;" << std::endl;
-
-  return;
-}
-
-int main(int argc, char** argv) {
-  if (argc < 2) {
-    std::cerr << "usage: " << argv[0] << " [target]" << std::endl;
-    return 1;
-  }
-
-  Context C(std::cout);
-
-  C.lowercase_target_string_ = argv[1];
-  for (size_t i = 0, e = C.lowercase_target_string_.length(); i != e; i++) {
-    C.lowercase_target_string_[i] = ::tolower(C.lowercase_target_string_[i]);
-  }
-
-  // Special function to generate TargetLIRBuilder::Set*Operands(...).
-  if (C.lowercase_target_string_ == "gen_set_operands") {
-    GenSetOperands(C);
-    return 0;
-  }
-
-  // Setup the context according to the target supplied
-  if (C.lowercase_target_string_ == "arm") {
-    C.target_lirs_ = ARMLIR;
-    C.num_target_lirs_ = sizeof(ARMLIR) / sizeof(ARMLIR[0]);
-    C.uppercase_target_string_ = "ARM";
-    C.class_name_ = "ARMLIRBuilderBase";
-  } else if (C.lowercase_target_string_ == "mips") {
-    C.target_lirs_ = MipsLIR;
-    C.num_target_lirs_ = sizeof(MipsLIR) / sizeof(MipsLIR[0]);
-    C.uppercase_target_string_ = "MIPS";
-    C.class_name_ = "MipsLIRBuilderBase";
-  } else if (C.lowercase_target_string_ == "x86") {
-    C.target_lirs_ = X86LIR;
-    C.num_target_lirs_ = sizeof(X86LIR) / sizeof(X86LIR[0]);
-    C.uppercase_target_string_ = "X86";
-    C.class_name_ = "X86LIRBuilderBase";
-  } else {
-    std::cerr << "unknown target `" << argv[1] << "'!" << std::endl;
-    return 1;
-  }
-
-  GenLicenseNote(C);
-  GenTargetLIRBuilderHeader(C);
-  GenTargetLIRBuilderImpl(C);
-
-  return 0;
-}
diff --git a/src/greenland/x86/x86_codegen_machine.cc b/src/greenland/x86/x86_codegen_machine.cc
deleted file mode 100644
index fe4bd83..0000000
--- a/src/greenland/x86/x86_codegen_machine.cc
+++ /dev/null
@@ -1,44 +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 "x86_codegen_machine.h"
-
-#include "x86_lir_emitter.h"
-
-#include "greenland/target_registry.h"
-
-namespace art {
-namespace greenland {
-
-void InitializeX86CodeGenMachine() {
-  RegisterTargetCodeGenMachine<X86CodeGenMachine> X(kX86);
-}
-
-X86CodeGenMachine::X86CodeGenMachine() : lir_info_() {
-}
-
-X86CodeGenMachine::~X86CodeGenMachine() {
-}
-
-TargetLIREmitter*
-X86CodeGenMachine::CreateLIREmitter(const llvm::Function& func,
-                                    const OatCompilationUnit& cunit,
-                                    DexLang::Context& dex_lang_ctx) {
-  return new X86LIREmitter(func, cunit, dex_lang_ctx, lir_info_);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/x86/x86_codegen_machine.h b/src/greenland/x86/x86_codegen_machine.h
deleted file mode 100644
index 1b9ac4d..0000000
--- a/src/greenland/x86/x86_codegen_machine.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_X86_CODEGEN_MACHINE_H_
-#define ART_SRC_GREENLAND_X86_CODEGEN_MACHINE_H_
-
-#include "greenland/target_codegen_machine.h"
-
-#include "x86_lir_info.h"
-
-namespace art {
-namespace greenland {
-
-class X86CodeGenMachine : public TargetCodeGenMachine {
- private:
-  X86LIRInfo lir_info_;
-
- public:
-  X86CodeGenMachine();
-
-  virtual ~X86CodeGenMachine();
-
-  virtual TargetLIREmitter* CreateLIREmitter(const llvm::Function& func,
-                                             const OatCompilationUnit& cunit,
-                                             DexLang::Context& dex_lang_ctx);
-
-  virtual RegisterAllocator* GetRegisterAllocator() {
-    return NULL;
-  }
-
-  virtual TargetAssembler* GetAssembler() {
-    return NULL;
-  }
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_X86_CODEGEN_MACHINE_H_
diff --git a/src/greenland/x86/x86_invoke_stub_compiler.cc b/src/greenland/x86/x86_invoke_stub_compiler.cc
deleted file mode 100644
index 872a9da..0000000
--- a/src/greenland/x86/x86_invoke_stub_compiler.cc
+++ /dev/null
@@ -1,183 +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 "compiled_method.h"
-#include "compiler.h"
-#include "greenland/target_registry.h"
-#include "oat/utils/assembler.h"
-#include "oat/utils/x86/assembler_x86.h"
-#include "object.h"
-
-using namespace art;
-using namespace art::x86;
-
-namespace {
-
-// Creates a function which invokes a managed method with an array of
-// arguments.
-//
-// Immediately after the call on X86, the environment looks like this:
-//
-// [SP+0 ] = Return address
-// [SP+4 ] = method pointer
-// [SP+8 ] = receiver pointer or NULL for static methods
-// [SP+12] = (managed) thread pointer
-// [SP+16] = argument array or NULL for no argument methods
-// [SP+20] = JValue* result or NULL for void returns
-//
-// As the JNI call has already transitioned the thread into the
-// "running" state the remaining responsibilities of this routine are
-// to save the native registers and set up the managed registers. On
-// return, the return value must be store into the result JValue.
-CompiledInvokeStub* CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len) {
-  UniquePtr<X86Assembler> assembler(down_cast<X86Assembler*>(Assembler::Create(kX86)));
-#define __ assembler->
-  size_t num_arg_array_bytes = NumArgArrayBytes(shorty, shorty_len);
-  // Size of frame = return address + saved EBX + Method* + possible receiver + arg array size
-  // Note, space is left in the frame to flush arguments in registers back to out locations.
-  size_t frame_size = 3 * kPointerSize + (is_static ? 0 : kPointerSize) + num_arg_array_bytes;
-  size_t pad_size = RoundUp(frame_size, kStackAlignment) - frame_size;
-
-  Register rMethod = EAX;
-  __ movl(rMethod,   Address(ESP, 4));     // EAX = method
-  Register rReceiver = ECX;
-  if (!is_static) {
-    __ movl(rReceiver, Address(ESP, 8));   // ECX = receiver
-  }
-  // Save EBX
-  __ pushl(EBX);
-  Register rArgArray = EBX;
-  __ movl(rArgArray, Address(ESP, 20));    // EBX = arg array
-
-  // TODO: optimize the frame set up to avoid excessive SP math
-  // Push padding
-  if (pad_size != 0) {
-    __ subl(ESP, Immediate(pad_size));
-  }
-  // Push/copy arguments.
-  size_t arg_count = (shorty_len - 1);
-  size_t dst_offset = num_arg_array_bytes;
-  size_t src_offset = arg_count * sizeof(JValue);
-  for (size_t i = shorty_len - 1; i > 0; --i) {
-    switch (shorty[i]) {
-      case 'D':
-      case 'J':
-        // Move both pointers 64 bits.
-        dst_offset -= kPointerSize;
-        src_offset -= sizeof(JValue) / 2;
-        __ pushl(Address(rArgArray, src_offset));
-        dst_offset -= kPointerSize;
-        src_offset -= sizeof(JValue) / 2;
-        __ pushl(Address(rArgArray, src_offset));
-        break;
-      default:
-        // Move the source pointer sizeof(JValue) and the destination pointer 32 bits.
-        dst_offset -= kPointerSize;
-        src_offset -= sizeof(JValue);
-        __ pushl(Address(rArgArray, src_offset));
-        break;
-    }
-  }
-
-  // Backing space for receiver.
-  if (!is_static) {
-    __ pushl(Immediate(0));
-  }
-  // Push 0 as NULL Method* thereby terminating managed stack crawls.
-  __ pushl(Immediate(0));
-  if (!is_static) {
-    if (shorty_len > 1) {
-      // Receiver already in ECX, pass remaining 2 args in EDX and EBX.
-      __ movl(EDX, Address(rArgArray, 0));
-      if (shorty[1] == 'D' || shorty[1] == 'J') {
-        __ movl(EBX, Address(rArgArray, sizeof(JValue) / 2));
-      } else if (shorty_len > 2) {
-        __ movl(EBX, Address(rArgArray, sizeof(JValue)));
-      }
-    }
-  } else {
-    if (shorty_len > 1) {
-      // Pass remaining 3 args in ECX, EDX and EBX.
-      __ movl(ECX, Address(rArgArray, 0));
-      if (shorty[1] == 'D' || shorty[1] == 'J') {
-        __ movl(EDX, Address(rArgArray, sizeof(JValue) / 2));
-        if (shorty_len > 2) {
-           __ movl(EBX, Address(rArgArray, sizeof(JValue)));
-        }
-      } else if (shorty_len > 2) {
-        __ movl(EDX, Address(rArgArray, sizeof(JValue)));
-        if (shorty[2] == 'D' || shorty[2] == 'J') {
-          __ movl(EBX, Address(rArgArray, sizeof(JValue) + (sizeof(JValue) / 2)));
-        } else {
-          __ movl(EBX, Address(rArgArray, sizeof(JValue) + sizeof(JValue)));
-        }
-      }
-    }
-  }
-
-  __ call(Address(EAX, AbstractMethod::GetCodeOffset()));  // Call code off of method
-
-  // Pop arguments up to EBX and the return address.
-  __ addl(ESP, Immediate(frame_size + pad_size - (2 * kPointerSize)));
-  // Restore EBX.
-  __ popl(EBX);
-  char ch = shorty[0];
-  if (ch != 'V') {
-    // Load the result JValue pointer.
-    __ movl(ECX, Address(ESP, 20));
-    switch (ch) {
-      case 'D':
-        __ movsd(Address(ECX, 0), XMM0);
-        break;
-      case 'F':
-        __ movss(Address(ECX, 0), XMM0);
-        break;
-      case 'J':
-        __ movl(Address(ECX, 0), EAX);
-        __ movl(Address(ECX, 4), EDX);
-        break;
-      default:
-        __ movl(Address(ECX, 0), EAX);
-        break;
-    }
-  }
-  __ ret();
-  // TODO: store native_entry in the stub table
-  std::vector<uint8_t> code(assembler->CodeSize());
-  MemoryRegion region(&code[0], code.size());
-  assembler->FinalizeInstructions(region);
-  return new CompiledInvokeStub(code);
-#undef __
-}
-
-CompiledInvokeStub* X86InvokeStubCompiler(art::Compiler& /*compiler*/,
-                                          bool is_static,
-                                          const char* shorty,
-                                          uint32_t shorty_len) {
-  return CreateInvokeStub(is_static, shorty, shorty_len);
-}
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-void InitializeX86InvokeStubCompiler() {
-  TargetRegistry::RegisterInvokeStubCompiler(kX86, X86InvokeStubCompiler);
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/x86/x86_lir.def b/src/greenland/x86/x86_lir.def
deleted file mode 100644
index bf96b42..0000000
--- a/src/greenland/x86/x86_lir.def
+++ /dev/null
@@ -1,17 +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 "greenland/target_lir.def"
diff --git a/src/greenland/x86/x86_lir_emitter.cc b/src/greenland/x86/x86_lir_emitter.cc
deleted file mode 100644
index 7b56a9f..0000000
--- a/src/greenland/x86/x86_lir_emitter.cc
+++ /dev/null
@@ -1,31 +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 "x86_lir_emitter.h"
-
-namespace art {
-namespace greenland {
-
-X86LIREmitter::X86LIREmitter(const llvm::Function& func,
-                             const OatCompilationUnit& cunit,
-                             DexLang::Context& dex_lang_ctx,
-                             TargetLIRInfo& target_lir_info)
-    : TargetLIREmitter(func, cunit, dex_lang_ctx, target_lir_info) {
-  return;
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/x86/x86_lir_emitter.h b/src/greenland/x86/x86_lir_emitter.h
deleted file mode 100644
index ab2d7c7..0000000
--- a/src/greenland/x86/x86_lir_emitter.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_X86_LIR_EMITTER_H_
-#define ART_SRC_GREENLAND_X86_LIR_EMITTER_H_
-
-#include "greenland/target_lir_emitter.h"
-
-namespace art {
-namespace greenland {
-
-class TargetLIRInfo;
-
-class X86LIREmitter : public TargetLIREmitter {
- private:
-
-
- public:
-  X86LIREmitter(const llvm::Function& func,
-                const OatCompilationUnit& cunit,
-                DexLang::Context& dex_lang_ctx,
-                TargetLIRInfo& target_lir_info);
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_X86_LIR_EMITTER_H_
diff --git a/src/greenland/x86/x86_lir_info.cc b/src/greenland/x86/x86_lir_info.cc
deleted file mode 100644
index 2f29c97..0000000
--- a/src/greenland/x86/x86_lir_info.cc
+++ /dev/null
@@ -1,38 +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 "x86_lir_info.h"
-#include "x86_lir_opcodes.h"
-
-namespace {
-
-const art::greenland::LIRDesc X86LIR[] = {
-#define DEF_LIR_DESC(OPCODE, NUM_OPS) { art::greenland::x86::OPCODE, NUM_OPS },
-#include "x86_lir.def"
-#undef DEF_LIR_DESC
-};
-
-} // anonymous namespace
-
-namespace art {
-namespace greenland {
-
-X86LIRInfo::X86LIRInfo()
-    : TargetLIRInfo(X86LIR, sizeof(X86LIR) / sizeof(X86LIR[0])) {
-}
-
-} // namespace greenland
-} // namespace art
diff --git a/src/greenland/x86/x86_lir_info.h b/src/greenland/x86/x86_lir_info.h
deleted file mode 100644
index 92e4bae..0000000
--- a/src/greenland/x86/x86_lir_info.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_X86_LIR_INFO_H_
-#define ART_SRC_GREENLAND_X86_LIR_INFO_H_
-
-#include "greenland/target_lir_info.h"
-
-namespace art {
-namespace greenland {
-
-class X86LIRInfo : public TargetLIRInfo {
- private:
-
- public:
-  X86LIRInfo();
-};
-
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_X86_LIR_INFO_H_
diff --git a/src/greenland/x86/x86_lir_opcodes.h b/src/greenland/x86/x86_lir_opcodes.h
deleted file mode 100644
index 487b609..0000000
--- a/src/greenland/x86/x86_lir_opcodes.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_GREENLAND_X86_LIR_OPCODES_H_
-#define ART_SRC_GREENLAND_X86_LIR_OPCODES_H_
-
-namespace art {
-namespace greenland {
-namespace x86 {
-
-enum {
-#define DEF_LIR_DESC(OPCODE, ...) OPCODE,
-#include "x86_lir.def"
-#undef DEF_LIR_DESC
-};
-
-} // namespace x86
-} // namespace greenland
-} // namespace art
-
-#endif // ART_SRC_GREENLAND_X86_LIR_OPCODES_H_
