Beginning of LLVM backend for ART.

Change-Id: I03466aed94670ac72d489ebc6e34d7ee1c9c857e
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5973a95
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+USE_LLVM_COMPILER
diff --git a/build/Android.common.mk b/build/Android.common.mk
index a4cdc34..525ca83 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -14,6 +14,18 @@
 # limitations under the License.
 #
 
+# Use llvm as the backend
+ifneq ($(wildcard art/USE_LLVM_COMPILER),)
+ART_USE_LLVM_COMPILER := true
+else
+ART_USE_LLVM_COMPILER := false
+endif
+
+ifeq ($(ART_USE_LLVM_COMPILER),true)
+LLVM_ROOT_PATH := external/llvm
+include $(LLVM_ROOT_PATH)/llvm.mk
+endif
+
 # art-cache
 ART_CACHE_DIR := /data/art-cache
 ART_CACHE_OUT := $(TARGET_OUT_DATA)/art-cache
@@ -53,6 +65,11 @@
 	-fno-align-jumps \
 	-fstrict-aliasing
 
+ifeq ($(ART_USE_LLVM_COMPILER),true)
+art_cflags := \
+	-DART_USE_LLVM_COMPILER=1
+endif
+
 ifeq ($(HOST_OS),linux)
   art_non_debug_cflags := \
 	-Wframe-larger-than=1728
@@ -113,18 +130,6 @@
 	src/class_loader.cc \
 	src/compiled_method.cc \
 	src/compiler.cc \
-	src/compiler/Dataflow.cc \
-	src/compiler/Frontend.cc \
-	src/compiler/IntermediateRep.cc \
-	src/compiler/Ralloc.cc \
-	src/compiler/SSATransformation.cc \
-	src/compiler/Utility.cc \
-	src/compiler/codegen/RallocUtil.cc \
-	src/compiler/codegen/arm/ArchUtility.cc \
-	src/compiler/codegen/arm/ArmRallocUtil.cc \
-	src/compiler/codegen/arm/Assemble.cc \
-	src/compiler/codegen/arm/LocalOptimizations.cc \
-	src/compiler/codegen/arm/armv7-a/Codegen.cc \
 	src/dalvik_system_DexFile.cc \
 	src/dalvik_system_VMDebug.cc \
 	src/dalvik_system_VMRuntime.cc \
@@ -208,6 +213,28 @@
 	src/utils.cc \
 	src/zip_archive.cc
 
+ifeq ($(ART_USE_LLVM_COMPILER),true)
+LIBART_COMMON_SRC_FILES += \
+	src/compiler_llvm/compiler_llvm.cc \
+	src/compiler_llvm/frontend.cc \
+	src/compiler_llvm/ir_builder.cc \
+	src/compiler_llvm/method_compiler.cc
+else
+LIBART_COMMON_SRC_FILES += \
+	src/compiler/Dataflow.cc \
+	src/compiler/Frontend.cc \
+	src/compiler/IntermediateRep.cc \
+	src/compiler/Ralloc.cc \
+	src/compiler/SSATransformation.cc \
+	src/compiler/Utility.cc \
+	src/compiler/codegen/RallocUtil.cc \
+	src/compiler/codegen/arm/ArchUtility.cc \
+	src/compiler/codegen/arm/ArmRallocUtil.cc \
+	src/compiler/codegen/arm/Assemble.cc \
+	src/compiler/codegen/arm/LocalOptimizations.cc \
+	src/compiler/codegen/arm/armv7-a/Codegen.cc
+endif
+
 LIBART_TARGET_SRC_FILES := \
 	$(LIBART_COMMON_SRC_FILES) \
 	src/jdwp/jdwp_adb.cc \
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index 872c6d3..d7ebefe 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -43,6 +43,8 @@
   endif
 
   LOCAL_MODULE_TAGS := optional
+  LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+
   ifeq ($$(art_target_or_host),target)
     LOCAL_SRC_FILES := $(LIBART_TARGET_SRC_FILES)
   else # host
@@ -68,6 +70,9 @@
     endif
   endif
   LOCAL_C_INCLUDES += $(ART_C_INCLUDES)
+  ifeq ($(ART_USE_LLVM_COMPILER),true)
+    LOCAL_STATIC_LIBRARIES += libLLVMBitWriter libLLVMCore libLLVMSupport
+  endif
   LOCAL_SHARED_LIBRARIES := liblog libnativehelper
   ifeq ($$(art_target_or_host),target)
     LOCAL_SHARED_LIBRARIES += libcutils libstlport libz libdl libdynamic_annotations
@@ -81,8 +86,17 @@
   endif
   LOCAL_STATIC_LIBRARIES += libdex
   ifeq ($$(art_target_or_host),target)
+    ifeq ($(ART_USE_LLVM_COMPILER),true)
+      include $(LLVM_GEN_INTRINSICS_MK)
+      include $(LLVM_DEVICE_BUILD_MK)
+    endif
     include $(BUILD_SHARED_LIBRARY)
   else # host
+    LOCAL_IS_HOST_MODULE := true
+    ifeq ($(ART_USE_LLVM_COMPILER),true)
+      include $(LLVM_GEN_INTRINSICS_MK)
+      include $(LLVM_HOST_BUILD_MK)
+    endif
     include $(BUILD_HOST_SHARED_LIBRARY)
   endif
 endef
diff --git a/src/compiled_method.cc b/src/compiled_method.cc
index eb79e0e..7c7460c 100644
--- a/src/compiled_method.cc
+++ b/src/compiled_method.cc
@@ -18,6 +18,13 @@
 
 namespace art {
 
+#if defined(ART_USE_LLVM_COMPILER)
+CompiledMethod::CompiledMethod(art::InstructionSet instruction_set,
+                               llvm::Function *func)
+    : instruction_set_(instruction_set), func_(func), frame_size_in_bytes_(0),
+      core_spill_mask_(0), fp_spill_mask_(0) {
+}
+#else
 CompiledMethod::CompiledMethod(InstructionSet instruction_set,
                                const std::vector<uint16_t>& short_code,
                                const size_t frame_size_in_bytes,
@@ -56,13 +63,16 @@
 
   DCHECK_EQ(vmap_table_[0], static_cast<uint32_t>(__builtin_popcount(core_spill_mask) + __builtin_popcount(fp_spill_mask)));
 }
+#endif
 
 void CompiledMethod::SetGcMap(const std::vector<uint8_t>& gc_map) {
   CHECK_NE(gc_map.size(), 0U);
 
+#if !defined(ART_USE_LLVM_COMPILER)
   // Should only be used with CompiledMethods created with oatCompileMethod
   CHECK_NE(mapping_table_.size(), 0U);
   CHECK_NE(vmap_table_.size(), 0U);
+#endif
 
   gc_map_ = gc_map;
 }
diff --git a/src/compiled_method.h b/src/compiled_method.h
index 15211e7..834ead0 100644
--- a/src/compiled_method.h
+++ b/src/compiled_method.h
@@ -22,10 +22,19 @@
 #include "constants.h"
 #include "utils.h"
 
+namespace llvm {
+  class Function;
+}
+
 namespace art {
 
 class CompiledMethod {
  public:
+#if defined(ART_USE_LLVM_COMPILER)
+  // Create a CompiledMethod from the oatCompileMethod
+  CompiledMethod(InstructionSet instruction_set,
+                 llvm::Function* func);
+#else
   // Create a CompiledMethod from the oatCompileMethod
   CompiledMethod(InstructionSet instruction_set,
                  const std::vector<uint16_t>& code,
@@ -34,6 +43,7 @@
                  const uint32_t fp_spill_mask,
                  const std::vector<uint32_t>& mapping_table,
                  const std::vector<uint16_t>& vmap_table);
+#endif
 
   // Add a GC map to a CompiledMethod created by oatCompileMethod
   void SetGcMap(const std::vector<uint8_t>& gc_map);
@@ -74,6 +84,9 @@
 
  private:
   const InstructionSet instruction_set_;
+#if defined(ART_USE_LLVM_COMPILER)
+  llvm::Function* func_;
+#endif
   std::vector<uint8_t> code_;
   const size_t frame_size_in_bytes_;
   const uint32_t core_spill_mask_;
diff --git a/src/compiler.cc b/src/compiler.cc
index b1a7066..35108bb 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -34,12 +34,18 @@
 #include "stl_util.h"
 #include "timing_logger.h"
 
+#if defined(ART_USE_LLVM_COMPILER)
+#include "compiler_llvm/compiler_llvm.h"
+#endif
+
 namespace art {
 
+#if !defined(ART_USE_LLVM_COMPILER)
 CompiledMethod* oatCompileMethod(Compiler& compiler, const DexFile::CodeItem* code_item,
                                  uint32_t access_flags, uint32_t method_idx,
                                  const ClassLoader* class_loader,
                                  const DexFile& dex_file, InstructionSet);
+#endif
 
 namespace arm {
   ByteArray* CreateAbstractMethodErrorStub();
@@ -172,7 +178,12 @@
       compiled_invoke_stubs_lock_("compiled invoke stubs lock"),
       image_(image),
       thread_count_(thread_count),
-      image_classes_(image_classes) {
+      image_classes_(image_classes)
+#if defined(ART_USE_LLVM_COMPILER)
+      ,
+      compiler_llvm_(new compiler_llvm::CompilerLLVM(this, instruction_set))
+#endif
+      {
   CHECK(!Runtime::Current()->IsStarted());
   if (!image_) {
     CHECK(image_classes_ == NULL);
@@ -293,6 +304,9 @@
 void Compiler::PostCompile(const ClassLoader* class_loader,
                            const std::vector<const DexFile*>& dex_files) {
   SetGcMaps(class_loader, dex_files);
+#if defined(ART_USE_LLVM_COMPILER)
+  compiler_llvm_->MaterializeLLVMModule();
+#endif
   SetCodeAndDirectMethods(dex_files);
 }
 
@@ -914,8 +928,14 @@
     CHECK(compiled_method != NULL);
   } else if ((access_flags & kAccAbstract) != 0) {
   } else {
+#if defined(ART_USE_LLVM_COMPILER)
+    compiled_method =
+      compiler_llvm_->CompileDexMethod(code_item, access_flags, method_idx,
+                                       class_loader, dex_file);
+#else
     compiled_method = oatCompileMethod(*this, code_item, access_flags, method_idx, class_loader,
                                        dex_file, kThumb2);
+#endif
     CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
   }
   uint64_t duration_ns = NanoTime() - start_ns;
diff --git a/src/compiler.h b/src/compiler.h
index 1c71330..186d433 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -31,6 +31,10 @@
 #include "object.h"
 #include "runtime.h"
 
+#if defined(ART_USE_LLVM_COMPILER)
+#include "compiler_llvm/compiler_llvm.h"
+#endif
+
 namespace art {
 
 class Context;
@@ -176,6 +180,12 @@
   bool ComputeInvokeInfo(uint32_t method_idx, CompilationUnit* cUnit, bool is_interface,
                          bool is_super, int& vtable_idx);
 
+#if defined(ART_USE_LLVM_COMPILER)
+  compiler_llvm::CompilerLLVM* GetCompilerLLVM() const {
+    return compiler_llvm_.get();
+  }
+#endif
+
  private:
 
   // Checks if class specified by type_idx is one of the image_classes_
@@ -244,6 +254,11 @@
 
   const std::set<std::string>* image_classes_;
 
+
+#if defined(ART_USE_LLVM_COMPILER)
+  UniquePtr<compiler_llvm::CompilerLLVM> compiler_llvm_;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(Compiler);
 };
 
diff --git a/src/compiler_llvm/backend_types.h b/src/compiler_llvm/backend_types.h
new file mode 100644
index 0000000..86b0ea2
--- /dev/null
+++ b/src/compiler_llvm/backend_types.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_BACKEND_TYPES_H_
+#define ART_SRC_COMPILER_LLVM_BACKEND_TYPES_H_
+
+#include "logging.h"
+
+
+namespace art {
+namespace compiler_llvm {
+
+
+enum JType {
+  kVoid,
+  kBoolean,
+  kByte,
+  kChar,
+  kShort,
+  kInt,
+  kLong,
+  kFloat,
+  kDouble,
+  kObject,
+};
+
+
+enum JTypeSpace {
+  kAccurate,
+  kReg,
+  kField,
+  kArray,
+};
+
+
+enum RegCategory {
+  kRegUnknown,
+  kRegZero,
+  kRegCat1nr,
+  kRegCat2,
+  kRegObject,
+};
+
+
+inline JType GetJTypeFromShorty(char shorty_jty) {
+  switch (shorty_jty) {
+  case 'V':
+    return kVoid;
+
+  case 'Z':
+    return kBoolean;
+
+  case 'B':
+    return kByte;
+
+  case 'C':
+    return kChar;
+
+  case 'S':
+    return kShort;
+
+  case 'I':
+    return kInt;
+
+  case 'J':
+    return kLong;
+
+  case 'F':
+    return kFloat;
+
+  case 'D':
+    return kDouble;
+
+  case 'L':
+    return kObject;
+
+  default:
+    LOG(FATAL) << "Unknown Dalvik shorty descriptor: " << shorty_jty;
+    return kVoid;
+  }
+}
+
+
+inline RegCategory GetRegCategoryFromJType(JType jty) {
+  switch (jty) {
+  case kVoid:
+    return kRegUnknown;
+
+  case kBoolean:
+  case kByte:
+  case kChar:
+  case kShort:
+  case kInt:
+  case kFloat:
+    return kRegCat1nr;
+
+  case kLong:
+  case kDouble:
+    return kRegCat2;
+
+  case kObject:
+    return kRegObject;
+  }
+
+  LOG(FATAL) << "Uknown java type: " << jty;
+  return kRegUnknown;
+}
+
+
+inline RegCategory GetRegCategoryFromShorty(char shorty) {
+  return GetRegCategoryFromJType(GetJTypeFromShorty(shorty));
+}
+
+
+} // namespace compiler_llvm
+} // namespace art
+
+
+#endif // ART_SRC_COMPILER_LLVM_BACKEND_TYPES_H_
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
new file mode 100644
index 0000000..c0f5881
--- /dev/null
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compiler_llvm.h"
+
+#include "compiler.h"
+#include "ir_builder.h"
+#include "method_compiler.h"
+
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/LLVMContext.h>
+#include <llvm/Module.h>
+#include <llvm/Support/ToolOutputFile.h>
+
+using namespace art;
+using namespace art::compiler_llvm;
+
+
+CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
+: compiler_(compiler), compiler_lock_("llvm_compiler_lock"),
+  insn_set_(insn_set), context_(new llvm::LLVMContext()) {
+
+  // Create the module and include the runtime function declaration
+  module_ = new llvm::Module("art", *context_);
+
+  // Create IRBuilder
+  irb_.reset(new IRBuilder(*context_, *module_));
+}
+
+
+CompilerLLVM::~CompilerLLVM() {
+}
+
+
+void CompilerLLVM::MaterializeLLVMModule() {
+#if !defined(NDEBUG)
+  // TODO: For device, need to use another temporary path.
+  WriteBitcodeToFile("/tmp/art_llvm_module.bc");
+#endif
+}
+
+
+void CompilerLLVM::WriteBitcodeToFile(std::string const &filepath) {
+  std::string error_msg;
+
+  // Write the translated bitcode
+  llvm::OwningPtr<llvm::tool_output_file>
+    out(new llvm::tool_output_file(filepath.c_str(), error_msg,
+                                   llvm::raw_fd_ostream::F_Binary));
+
+  if (!error_msg.empty()) {
+    LOG(FATAL) << "Unable to open file: " << error_msg;
+    return;
+  }
+
+  llvm::WriteBitcodeToFile(module_, out->os());
+  out->keep();
+
+  LOG(DEBUG) << "Bitcode Written At: " << filepath;
+}
+
+
+CompiledMethod*
+CompilerLLVM::CompileDexMethod(DexFile::CodeItem const* code_item,
+                               uint32_t access_flags,
+                               uint32_t method_idx,
+                               ClassLoader const* class_loader,
+                               DexFile const& dex_file) {
+
+  MutexLock GUARD(compiler_lock_);
+
+  ClassLinker *class_linker = Runtime::Current()->GetClassLinker();
+  DexCache *dex_cache = class_linker->FindDexCache(dex_file);
+
+  UniquePtr<MethodCompiler> method_compiler(
+    new MethodCompiler(insn_set_, compiler_, class_linker, class_loader,
+                       &dex_file, dex_cache, code_item, method_idx,
+                       access_flags));
+
+  return method_compiler->Compile();
+}
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
new file mode 100644
index 0000000..74f8ba1
--- /dev/null
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_LLVM_COMPILER_H_
+#define ART_SRC_COMPILER_LLVM_LLVM_COMPILER_H_
+
+#include "constants.h"
+#include "dex_file.h"
+#include "macros.h"
+
+#include <UniquePtr.h>
+
+#include <string>
+
+namespace art {
+  class ClassLoader;
+  class CompiledMethod;
+  class Compiler;
+  class Mutex;
+}
+
+
+namespace llvm {
+  class Function;
+  class LLVMContext;
+  class Module;
+  class PointerType;
+  class StructType;
+  class Type;
+}
+
+
+namespace art {
+namespace compiler_llvm {
+
+class IRBuilder;
+
+class CompilerLLVM {
+ public:
+  CompilerLLVM(Compiler* compiler, InstructionSet insn_set);
+
+  ~CompilerLLVM();
+
+  void MaterializeLLVMModule();
+
+  void WriteBitcodeToFile(std::string const &filename);
+
+  Compiler* GetCompiler() const {
+    return compiler_;
+  }
+
+  InstructionSet GetInstructionSet() const {
+    return insn_set_;
+  }
+
+  llvm::Module* GetModule() const {
+    return module_;
+  }
+
+  llvm::LLVMContext* GetLLVMContext() const {
+    return context_.get();
+  }
+
+  IRBuilder* GetIRBuilder() const {
+    return irb_.get();
+  }
+
+  CompiledMethod* CompileDexMethod(DexFile::CodeItem const* code_item,
+                                   uint32_t access_flags,
+                                   uint32_t method_idx,
+                                   ClassLoader const* class_loader,
+                                   DexFile const& dex_file);
+
+ private:
+  Compiler* compiler_;
+
+  Mutex compiler_lock_;
+
+  InstructionSet insn_set_;
+
+  UniquePtr<llvm::LLVMContext> context_;
+
+  UniquePtr<IRBuilder> irb_;
+
+  llvm::Module* module_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompilerLLVM);
+};
+
+
+} // namespace compiler_llvm
+} // namespace art
+
+#endif // ART_SRC_COMPILER_LLVM_LLVM_COMPILER_H_
diff --git a/src/compiler_llvm/frontend.cc b/src/compiler_llvm/frontend.cc
new file mode 100644
index 0000000..d2a4ad4
--- /dev/null
+++ b/src/compiler_llvm/frontend.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "method_compiler.h"
+
+#include "class_linker.h"
+#include "class_loader.h"
+#include "compiler.h"
+#include "constants.h"
+#include "dex_file.h"
+#include "runtime.h"
+
+#include <UniquePtr.h>
+#include <stdint.h>
+
+using namespace art::compiler_llvm;
+
+namespace art {
+
+int oatVRegOffset(const art::DexFile::CodeItem* code_item,
+                  uint32_t core_spills, uint32_t fp_spills,
+                  size_t frame_size, int reg) {
+  UNIMPLEMENTED(FATAL);
+  return 0;
+}
+
+} // namespace art
diff --git a/src/compiler_llvm/ir_builder.cc b/src/compiler_llvm/ir_builder.cc
new file mode 100644
index 0000000..ea773bd
--- /dev/null
+++ b/src/compiler_llvm/ir_builder.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ir_builder.h"
+
+#include <llvm/Module.h>
+
+using namespace art::compiler_llvm;
+
+
+//----------------------------------------------------------------------------
+// General
+//----------------------------------------------------------------------------
+
+IRBuilder::IRBuilder(llvm::LLVMContext& context, llvm::Module& module)
+: LLVMIRBuilder(context) {
+
+  // Get java object type from module
+  llvm::Type* jobject_struct_type =
+    llvm::StructType::create(context, "JavaObject");
+  jobject_type_ = jobject_struct_type->getPointerTo();
+}
+
+
+//----------------------------------------------------------------------------
+// Type Helper Function
+//----------------------------------------------------------------------------
+
+llvm::Type* IRBuilder::getJTypeInAccurateSpace(JType jty) {
+  switch (jty) {
+  case kVoid:
+    return getJVoidTy();
+
+  case kBoolean:
+    return getJBooleanTy();
+
+  case kByte:
+    return getJByteTy();
+
+  case kChar:
+    return getJCharTy();
+
+  case kShort:
+    return getJShortTy();
+
+  case kInt:
+    return getJIntTy();
+
+  case kLong:
+    return getJLongTy();
+
+  case kFloat:
+    return getJFloatTy();
+
+  case kDouble:
+    return getJDoubleTy();
+
+  case kObject:
+    return getJObjectTy();
+  }
+
+  LOG(FATAL) << "Unknown java type: " << jty;
+  return NULL;
+}
+
+
+llvm::Type* IRBuilder::getJTypeInRegSpace(JType jty) {
+  switch (GetRegCategoryFromJType(jty)) {
+  case kRegUnknown:
+  case kRegZero:
+    return NULL;
+
+  case kRegCat1nr:
+    return getInt32Ty();
+
+  case kRegCat2:
+    return getInt64Ty();
+
+  case kRegObject:
+    return getJObjectTy();
+  }
+
+  return NULL;
+}
+
+
+llvm::Type* IRBuilder::getJTypeInArraySpace(JType jty) {
+  switch (jty) {
+  case kVoid:
+    return NULL;
+
+  case kBoolean:
+  case kByte:
+    return getInt8Ty();
+
+  case kChar:
+  case kShort:
+    return getInt16Ty();
+
+  case kInt:
+    return getInt32Ty();
+
+  case kLong:
+    return getInt64Ty();
+
+  case kFloat:
+    return getFloatTy();
+
+  case kDouble:
+    return getDoubleTy();
+
+  case kObject:
+    return getJObjectTy();
+  }
+
+  return NULL;
+}
diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h
new file mode 100644
index 0000000..03ca2d7
--- /dev/null
+++ b/src/compiler_llvm/ir_builder.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_IR_BUILDER_H_
+#define ART_SRC_COMPILER_LLVM_IR_BUILDER_H_
+
+#include "backend_types.h"
+
+#include <llvm/Constants.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Support/IRBuilder.h>
+#include <llvm/Type.h>
+
+#include <stdint.h>
+
+
+namespace art {
+namespace compiler_llvm {
+
+
+typedef llvm::IRBuilder<> LLVMIRBuilder;
+// NOTE: Here we define our own LLVMIRBuilder type alias, so that we can
+// switch "preserveNames" template parameter easily.
+
+
+class IRBuilder : public LLVMIRBuilder {
+ public:
+  //--------------------------------------------------------------------------
+  // General
+  //--------------------------------------------------------------------------
+
+  IRBuilder(llvm::LLVMContext& context, llvm::Module& module);
+
+
+  //--------------------------------------------------------------------------
+  // Type Helper Function
+  //--------------------------------------------------------------------------
+
+  llvm::Type* getJType(char shorty_jty, JTypeSpace space) {
+    return getJType(GetJTypeFromShorty(shorty_jty), space);
+  }
+
+  llvm::Type* getJType(JType jty, JTypeSpace space) {
+    switch (space) {
+    case kAccurate:
+      return getJTypeInAccurateSpace(jty);
+
+    case kReg:
+    case kField: // Currently field space is equivalent to register space.
+      return getJTypeInRegSpace(jty);
+
+    case kArray:
+      return getJTypeInArraySpace(jty);
+    }
+
+    return NULL;
+  }
+
+  llvm::Type* getJVoidTy() {
+    return getVoidTy();
+  }
+
+  llvm::IntegerType* getJBooleanTy() {
+    return getInt1Ty();
+  }
+
+  llvm::IntegerType* getJByteTy() {
+    return getInt8Ty();
+  }
+
+  llvm::IntegerType* getJCharTy() {
+    return getInt16Ty();
+  }
+
+  llvm::IntegerType* getJShortTy() {
+    return getInt16Ty();
+  }
+
+  llvm::IntegerType* getJIntTy() {
+    return getInt32Ty();
+  }
+
+  llvm::IntegerType* getJLongTy() {
+    return getInt64Ty();
+  }
+
+  llvm::Type* getJFloatTy() {
+    return getFloatTy();
+  }
+
+  llvm::Type* getJDoubleTy() {
+    return getDoubleTy();
+  }
+
+  llvm::PointerType* getJObjectTy() {
+    return jobject_type_;
+  }
+
+
+  //--------------------------------------------------------------------------
+  // Constant Value Helper Function
+  //--------------------------------------------------------------------------
+
+  llvm::ConstantInt* getJBoolean(bool is_true) {
+    return (is_true) ? getTrue() : getFalse();
+  }
+
+  llvm::ConstantInt* getJByte(int8_t i) {
+    return llvm::ConstantInt::getSigned(getJByteTy(), i);
+  }
+
+  llvm::ConstantInt* getJChar(int16_t i) {
+    return llvm::ConstantInt::getSigned(getJCharTy(), i);
+  }
+
+  llvm::ConstantInt* getJShort(int16_t i) {
+    return llvm::ConstantInt::getSigned(getJShortTy(), i);
+  }
+
+  llvm::ConstantInt* getJInt(int32_t i) {
+    return llvm::ConstantInt::getSigned(getJIntTy(), i);
+  }
+
+  llvm::ConstantInt* getJLong(int64_t i) {
+    return llvm::ConstantInt::getSigned(getJLongTy(), i);
+  }
+
+  llvm::Constant* getJFloat(float f) {
+    return llvm::ConstantFP::get(getJFloatTy(), f);
+  }
+
+  llvm::Constant* getJDouble(double d) {
+    return llvm::ConstantFP::get(getJDoubleTy(), d);
+  }
+
+  llvm::ConstantPointerNull* getJNull() {
+    return llvm::ConstantPointerNull::get(getJObjectTy());
+  }
+
+  llvm::Constant* getJZero(char shorty_jty) {
+    return getJZero(GetJTypeFromShorty(shorty_jty));
+  }
+
+  llvm::Constant* getJZero(JType jty) {
+    switch (jty) {
+    case kVoid:
+      return NULL;
+
+    case kBoolean:
+      return getJBoolean(false);
+
+    case kByte:
+      return getJByte(0);
+
+    case kChar:
+      return getJChar(0);
+
+    case kShort:
+      return getJShort(0);
+
+    case kInt:
+      return getJInt(0);
+
+    case kLong:
+      return getJLong(0);
+
+    case kFloat:
+      return getJFloat(0.0f);
+
+    case kDouble:
+      return getJDouble(0.0);
+
+    case kObject:
+      return getJNull();
+    }
+
+    LOG(FATAL) << "Unknown java type: " << jty;
+    return NULL;
+  }
+
+
+ private:
+  //--------------------------------------------------------------------------
+  // Type Helper Function (Private)
+  //--------------------------------------------------------------------------
+
+  llvm::Type* getJTypeInAccurateSpace(JType jty);
+  llvm::Type* getJTypeInRegSpace(JType jty);
+  llvm::Type* getJTypeInArraySpace(JType jty);
+
+
+ private:
+  llvm::PointerType* jobject_type_;
+
+};
+
+
+} // namespace compiler_llvm
+} // namespace art
+
+#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_
diff --git a/src/compiler_llvm/libdex.h b/src/compiler_llvm/libdex.h
new file mode 100644
index 0000000..40668fc
--- /dev/null
+++ b/src/compiler_llvm/libdex.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_LIBDEX_H_
+#define ART_SRC_COMPILER_LLVM_LIBDEX_H_
+
+#include <assert.h>
+
+// From Common.h
+// TODO: remove all these and just use the long names
+typedef uint8_t             u1;
+typedef uint16_t            u2;
+typedef uint32_t            u4;
+typedef uint64_t            u8;
+typedef int8_t              s1;
+typedef int16_t             s2;
+typedef int32_t             s4;
+typedef int64_t             s8;
+typedef unsigned long long  u8;
+
+// Skip old DexFile.h
+#define LIBDEX_DEXFILE_H_
+
+// Skip old vm/Common.h
+#define DALVIK_COMMON_H_
+
+// Make inlines inline
+#define DEX_INLINE inline
+#include "DexOpcodes.h"
+#include "InstrUtils.h"
+
+
+#endif // ART_SRC_COMPILER_LLVM_LIBDEX_H_
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
new file mode 100644
index 0000000..4aec8b1
--- /dev/null
+++ b/src/compiler_llvm/method_compiler.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "method_compiler.h"
+
+#include "compiler.h"
+#include "ir_builder.h"
+#include "logging.h"
+#include "object.h"
+#include "object_utils.h"
+#include "stl_util.h"
+
+#include <iomanip>
+
+#include <llvm/Analysis/Verifier.h>
+#include <llvm/Function.h>
+
+using namespace art::compiler_llvm;
+
+
+MethodCompiler::MethodCompiler(art::InstructionSet insn_set,
+                               art::Compiler const* compiler,
+                               art::ClassLinker* class_linker,
+                               art::ClassLoader const* class_loader,
+                               art::DexFile const* dex_file,
+                               art::DexCache* dex_cache,
+                               art::DexFile::CodeItem const* code_item,
+                               uint32_t method_idx,
+                               uint32_t access_flags)
+: insn_set_(insn_set),
+  compiler_(compiler), compiler_llvm_(compiler->GetCompilerLLVM()),
+  class_linker_(class_linker), class_loader_(class_loader),
+  dex_file_(dex_file), dex_cache_(dex_cache), code_item_(code_item),
+  method_(dex_cache->GetResolvedMethod(method_idx)),
+  method_helper_(method_), method_idx_(method_idx),
+  access_flags_(access_flags), module_(compiler_llvm_->GetModule()),
+  context_(compiler_llvm_->GetLLVMContext()),
+  irb_(*compiler_llvm_->GetIRBuilder()), func_(NULL) {
+}
+
+
+MethodCompiler::~MethodCompiler() {
+}
+
+
+void MethodCompiler::EmitPrologue() {
+  // TODO: Not implemented!
+}
+
+
+void MethodCompiler::EmitEpilogue() {
+}
+
+
+void MethodCompiler::EmitInstruction(uint32_t addr,
+                                     art::Instruction const* insn) {
+  // TODO: Not implemented!
+}
+
+
+art::CompiledMethod *MethodCompiler::Compile() {
+  // TODO: Not implemented!
+  return new art::CompiledMethod(insn_set_, NULL);
+}
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
new file mode 100644
index 0000000..2d9f91c
--- /dev/null
+++ b/src/compiler_llvm/method_compiler.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_
+#define ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_
+
+#include "constants.h"
+#include "dex_file.h"
+#include "dex_instruction.h"
+#include "object_utils.h"
+
+#include <llvm/Support/IRBuilder.h>
+
+#include <vector>
+
+#include <stdint.h>
+
+
+namespace art {
+  class ClassLinker;
+  class ClassLoader;
+  class CompiledMethod;
+  class Compiler;
+  class DexCache;
+}
+
+
+namespace llvm {
+  class AllocaInst;
+  class BasicBlock;
+  class Function;
+  class FunctionType;
+  class LLVMContext;
+  class Module;
+  class Type;
+}
+
+
+namespace art {
+namespace compiler_llvm {
+
+class CompilerLLVM;
+class IRBuilder;
+
+class MethodCompiler {
+ private:
+  art::InstructionSet insn_set_;
+  art::Compiler const* compiler_;
+  art::compiler_llvm::CompilerLLVM* compiler_llvm_;
+
+  art::ClassLinker* class_linker_;
+  art::ClassLoader const* class_loader_;
+
+  art::DexFile const* dex_file_;
+  art::DexCache* dex_cache_;
+  art::DexFile::CodeItem const* code_item_;
+
+  art::Method* method_;
+  art::MethodHelper method_helper_;
+
+  uint32_t method_idx_;
+  uint32_t access_flags_;
+
+  llvm::Module* module_;
+  llvm::LLVMContext* context_;
+  IRBuilder& irb_;
+  llvm::Function* func_;
+
+ public:
+  MethodCompiler(art::InstructionSet insn_set,
+                 art::Compiler const* compiler,
+                 art::ClassLinker* class_linker,
+                 art::ClassLoader const* class_loader,
+                 art::DexFile const* dex_file,
+                 art::DexCache* dex_cache,
+                 art::DexFile::CodeItem const* code_item,
+                 uint32_t method_idx,
+                 uint32_t access_flags);
+
+  ~MethodCompiler();
+
+  art::CompiledMethod* Compile();
+
+ private:
+  void CreateFunction();
+
+  void EmitPrologue();
+  void EmitInstructions();
+  void EmitInstruction(uint32_t addr, art::Instruction const* insn);
+  void EmitEpilogue();
+
+};
+
+
+} // namespace compiler_llvm
+} // namespace art
+
+#endif // ART_SRC_COMPILER_LLVM_METHOD_COMPILER_H_