diff --git a/src/compiler/llvm/llvm_compilation_unit.cc b/src/compiler/llvm/llvm_compilation_unit.cc
new file mode 100644
index 0000000..aad18fb
--- /dev/null
+++ b/src/compiler/llvm/llvm_compilation_unit.cc
@@ -0,0 +1,420 @@
+/*
+ * 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 "llvm_compilation_unit.h"
+
+#include "base/logging.h"
+#include "compiled_method.h"
+#include "compiler_llvm.h"
+#include "instruction_set.h"
+#include "ir_builder.h"
+#include "os.h"
+
+#include "runtime_support_builder_arm.h"
+#include "runtime_support_builder_thumb2.h"
+#include "runtime_support_builder_x86.h"
+
+#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/StringSet.h>
+#include <llvm/ADT/Triple.h>
+#include <llvm/Analysis/CallGraph.h>
+#include <llvm/Analysis/DebugInfo.h>
+#include <llvm/Analysis/Dominators.h>
+#include <llvm/Analysis/LoopInfo.h>
+#include <llvm/Analysis/LoopPass.h>
+#include <llvm/Analysis/RegionPass.h>
+#include <llvm/Analysis/ScalarEvolution.h>
+#include <llvm/Analysis/Verifier.h>
+#include <llvm/Assembly/PrintModulePass.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/CallGraphSCCPass.h>
+#include <llvm/CodeGen/MachineFrameInfo.h>
+#include <llvm/CodeGen/MachineFunction.h>
+#include <llvm/CodeGen/MachineFunctionPass.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/LLVMContext.h>
+#include <llvm/Module.h>
+#include <llvm/Object/ObjectFile.h>
+#include <llvm/PassManager.h>
+#include <llvm/Support/Debug.h>
+#include <llvm/Support/ELF.h>
+#include <llvm/Support/FormattedStream.h>
+#include <llvm/Support/ManagedStatic.h>
+#include <llvm/Support/MemoryBuffer.h>
+#include <llvm/Support/PassNameParser.h>
+#include <llvm/Support/PluginLoader.h>
+#include <llvm/Support/PrettyStackTrace.h>
+#include <llvm/Support/Signals.h>
+#include <llvm/Support/SystemUtils.h>
+#include <llvm/Support/TargetRegistry.h>
+#include <llvm/Support/TargetSelect.h>
+#include <llvm/Support/ToolOutputFile.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/system_error.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Target/TargetLibraryInfo.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/Transforms/IPO.h>
+#include <llvm/Transforms/IPO/PassManagerBuilder.h>
+#include <llvm/Transforms/Scalar.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <string>
+
+namespace art {
+namespace llvm {
+
+::llvm::FunctionPass*
+CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
+                      CompilerDriver* compiler, DexCompilationUnit* dex_compilation_unit);
+
+::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
+
+
+LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_idx)
+    : compiler_llvm_(compiler_llvm), cunit_idx_(cunit_idx) {
+  driver_ = NULL;
+  dex_compilation_unit_ = NULL;
+  llvm_info_.reset(new LLVMInfo());
+  context_.reset(llvm_info_->GetLLVMContext());
+  module_ = llvm_info_->GetLLVMModule();
+
+  // Include the runtime function declaration
+  makeLLVMModuleContents(module_);
+
+
+  intrinsic_helper_.reset(new IntrinsicHelper(*context_, *module_));
+
+  // Create IRBuilder
+  irb_.reset(new IRBuilder(*context_, *module_, *intrinsic_helper_));
+
+  // We always need a switch case, so just use a normal function.
+  switch(GetInstructionSet()) {
+  default:
+    runtime_support_.reset(new RuntimeSupportBuilder(*context_, *module_, *irb_));
+    break;
+  case kArm:
+    runtime_support_.reset(new RuntimeSupportBuilderARM(*context_, *module_, *irb_));
+    break;
+  case kThumb2:
+    runtime_support_.reset(new RuntimeSupportBuilderThumb2(*context_, *module_, *irb_));
+    break;
+  case kX86:
+    runtime_support_.reset(new RuntimeSupportBuilderX86(*context_, *module_, *irb_));
+    break;
+  }
+
+  irb_->SetRuntimeSupport(runtime_support_.get());
+}
+
+
+LlvmCompilationUnit::~LlvmCompilationUnit() {
+  ::llvm::LLVMContext* llvm_context = context_.release(); // Managed by llvm_info_
+  CHECK(llvm_context != NULL);
+}
+
+
+InstructionSet LlvmCompilationUnit::GetInstructionSet() const {
+  return compiler_llvm_->GetInstructionSet();
+}
+
+
+bool LlvmCompilationUnit::Materialize() {
+  std::string elf_image;
+
+  // Compile and prelink ::llvm::Module
+  if (!MaterializeToString(elf_image)) {
+    LOG(ERROR) << "Failed to materialize compilation unit " << cunit_idx_;
+    return false;
+  }
+
+#if 0
+  // Dump the ELF image for debugging
+  std::string filename(StringPrintf("%s/Art%zu.elf",
+                                    GetArtCacheOrDie(GetAndroidData()).c_str(),
+                                    cunit_idx_));
+  UniquePtr<File> output(OS::OpenFile(filename.c_str(), true));
+  output->WriteFully(elf_image.data(), elf_image.size());
+#endif
+
+  // Extract the .text section and prelink the code
+  if (!ExtractCodeAndPrelink(elf_image)) {
+    LOG(ERROR) << "Failed to extract code from compilation unit " << cunit_idx_;
+    return false;
+  }
+
+  return true;
+}
+
+
+bool LlvmCompilationUnit::MaterializeToString(std::string& str_buffer) {
+  ::llvm::raw_string_ostream str_os(str_buffer);
+  return MaterializeToRawOStream(str_os);
+}
+
+
+bool LlvmCompilationUnit::MaterializeToRawOStream(::llvm::raw_ostream& out_stream) {
+  // Lookup the LLVM target
+  std::string target_triple;
+  std::string target_cpu;
+  std::string target_attr;
+  CompilerDriver::InstructionSetToLLVMTarget(GetInstructionSet(), target_triple, target_cpu, target_attr);
+
+  std::string errmsg;
+  const ::llvm::Target* target =
+    ::llvm::TargetRegistry::lookupTarget(target_triple, errmsg);
+
+  CHECK(target != NULL) << errmsg;
+
+  // Target options
+  ::llvm::TargetOptions target_options;
+  target_options.FloatABIType = ::llvm::FloatABI::Soft;
+  target_options.NoFramePointerElim = true;
+  target_options.NoFramePointerElimNonLeaf = true;
+  target_options.UseSoftFloat = false;
+  target_options.EnableFastISel = false;
+
+  // Create the ::llvm::TargetMachine
+  ::llvm::OwningPtr< ::llvm::TargetMachine> target_machine(
+    target->createTargetMachine(target_triple, target_cpu, target_attr, target_options,
+                                ::llvm::Reloc::Static, ::llvm::CodeModel::Small,
+                                ::llvm::CodeGenOpt::Aggressive));
+
+  CHECK(target_machine.get() != NULL) << "Failed to create target machine";
+
+  // Add target data
+  const ::llvm::TargetData* target_data = target_machine->getTargetData();
+
+  // PassManager for code generation passes
+  ::llvm::PassManager pm;
+  pm.add(new ::llvm::TargetData(*target_data));
+
+  // FunctionPassManager for optimization pass
+  ::llvm::FunctionPassManager fpm(module_);
+  fpm.add(new ::llvm::TargetData(*target_data));
+
+  if (bitcode_filename_.empty()) {
+    // If we don't need write the bitcode to file, add the AddSuspendCheckToLoopLatchPass to the
+    // regular FunctionPass.
+    fpm.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
+                                  driver_, dex_compilation_unit_));
+  } else {
+    ::llvm::FunctionPassManager fpm2(module_);
+    fpm2.add(CreateGBCExpanderPass(*llvm_info_->GetIntrinsicHelper(), *irb_.get(),
+                                   driver_, dex_compilation_unit_));
+    fpm2.doInitialization();
+    for (::llvm::Module::iterator F = module_->begin(), E = module_->end();
+         F != E; ++F) {
+      fpm2.run(*F);
+    }
+    fpm2.doFinalization();
+
+    // Write bitcode to file
+    std::string errmsg;
+
+    ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
+      new ::llvm::tool_output_file(bitcode_filename_.c_str(), errmsg,
+                                 ::llvm::raw_fd_ostream::F_Binary));
+
+
+    if (!errmsg.empty()) {
+      LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
+      return false;
+    }
+
+    ::llvm::WriteBitcodeToFile(module_, out_file->os());
+    out_file->keep();
+  }
+
+  // Add optimization pass
+  ::llvm::PassManagerBuilder pm_builder;
+  // TODO: Use inliner after we can do IPO.
+  pm_builder.Inliner = NULL;
+  //pm_builder.Inliner = ::llvm::createFunctionInliningPass();
+  //pm_builder.Inliner = ::llvm::createAlwaysInlinerPass();
+  //pm_builder.Inliner = ::llvm::createPartialInliningPass();
+  pm_builder.OptLevel = 3;
+  pm_builder.DisableSimplifyLibCalls = 1;
+  pm_builder.DisableUnitAtATime = 1;
+  pm_builder.populateFunctionPassManager(fpm);
+  pm_builder.populateModulePassManager(pm);
+  pm.add(::llvm::createStripDeadPrototypesPass());
+
+  // Add passes to emit ELF image
+  {
+    ::llvm::formatted_raw_ostream formatted_os(out_stream, false);
+
+    // Ask the target to add backend passes as necessary.
+    if (target_machine->addPassesToEmitFile(pm,
+                                            formatted_os,
+                                            ::llvm::TargetMachine::CGFT_ObjectFile,
+                                            true)) {
+      LOG(FATAL) << "Unable to generate ELF for this target";
+      return false;
+    }
+
+    // Run the per-function optimization
+    fpm.doInitialization();
+    for (::llvm::Module::iterator F = module_->begin(), E = module_->end();
+         F != E; ++F) {
+      fpm.run(*F);
+    }
+    fpm.doFinalization();
+
+    // Run the code generation passes
+    pm.run(*module_);
+  }
+
+  return true;
+}
+
+bool LlvmCompilationUnit::ExtractCodeAndPrelink(const std::string& elf_image) {
+  if (GetInstructionSet() == kX86) {
+    compiled_code_.push_back(0xccU);
+    compiled_code_.push_back(0xccU);
+    compiled_code_.push_back(0xccU);
+    compiled_code_.push_back(0xccU);
+    return true;
+  }
+
+  ::llvm::OwningPtr< ::llvm::MemoryBuffer> elf_image_buff(
+    ::llvm::MemoryBuffer::getMemBuffer(::llvm::StringRef(elf_image.data(),
+                                                     elf_image.size())));
+
+  ::llvm::OwningPtr< ::llvm::object::ObjectFile> elf_file(
+    ::llvm::object::ObjectFile::createELFObjectFile(elf_image_buff.take()));
+
+  ::llvm::error_code ec;
+
+  const ProcedureLinkageTable& plt = compiler_llvm_->GetProcedureLinkageTable();
+
+  for (::llvm::object::section_iterator
+       sec_iter = elf_file->begin_sections(),
+       sec_end = elf_file->end_sections();
+       sec_iter != sec_end; sec_iter.increment(ec)) {
+
+    CHECK(ec == 0) << "Failed to read section because " << ec.message();
+
+    // Read the section information
+    ::llvm::StringRef name;
+    uint64_t alignment = 0u;
+    uint64_t size = 0u;
+
+    CHECK(sec_iter->getName(name) == 0);
+    CHECK(sec_iter->getSize(size) == 0);
+    CHECK(sec_iter->getAlignment(alignment) == 0);
+
+    if (name == ".data" || name == ".bss" || name == ".rodata") {
+      if (size > 0) {
+        LOG(FATAL) << "Compilation unit " << cunit_idx_ << " has non-empty "
+                   << name.str() << " section";
+      }
+
+    } else if (name == "" || name == ".rel.text" ||
+               name == ".ARM.attributes" || name == ".symtab" ||
+               name == ".strtab" || name == ".shstrtab") {
+      // We can ignore these sections.  We don't have to copy them into
+      // the result Oat file.
+
+    } else if (name == ".text") {
+      // Ensure the alignment requirement is less than or equal to
+      // kArchAlignment
+      CheckCodeAlign(alignment);
+
+      // Copy the compiled code
+      ::llvm::StringRef contents;
+      CHECK(sec_iter->getContents(contents) == 0);
+
+      copy(contents.data(),
+           contents.data() + contents.size(),
+           back_inserter(compiled_code_));
+
+      // Prelink the compiled code
+      for (::llvm::object::relocation_iterator
+           rel_iter = sec_iter->begin_relocations(),
+           rel_end = sec_iter->end_relocations(); rel_iter != rel_end;
+           rel_iter.increment(ec)) {
+
+        CHECK(ec == 0) << "Failed to read relocation because " << ec.message();
+
+        // Read the relocation information
+        ::llvm::object::SymbolRef sym_ref;
+        uint64_t rel_offset = 0;
+        uint64_t rel_type = 0;
+        int64_t rel_addend = 0;
+
+        CHECK(rel_iter->getSymbol(sym_ref) == 0);
+        CHECK(rel_iter->getOffset(rel_offset) == 0);
+        CHECK(rel_iter->getType(rel_type) == 0);
+        CHECK(rel_iter->getAdditionalInfo(rel_addend) == 0);
+
+        // Read the symbol related to this relocation fixup
+        ::llvm::StringRef sym_name;
+        CHECK(sym_ref.getName(sym_name) == 0);
+
+        // Relocate the fixup.
+        // TODO: Support more relocation type.
+        CHECK(rel_type == ::llvm::ELF::R_ARM_ABS32);
+        CHECK_LE(rel_offset + 4, compiled_code_.size());
+
+        uintptr_t dest_addr = plt.GetEntryAddress(sym_name.str().c_str());
+        uintptr_t final_addr = dest_addr + rel_addend;
+        compiled_code_[rel_offset] = final_addr & 0xff;
+        compiled_code_[rel_offset + 1] = (final_addr >> 8) & 0xff;
+        compiled_code_[rel_offset + 2] = (final_addr >> 16) & 0xff;
+        compiled_code_[rel_offset + 3] = (final_addr >> 24) & 0xff;
+      }
+
+    } else {
+      LOG(WARNING) << "Unexpected section: " << name.str();
+    }
+  }
+
+  return true;
+}
+
+
+// Check whether the align is less than or equal to the code alignment of
+// that architecture.  Since the Oat writer only guarantee that the compiled
+// method being aligned to kArchAlignment, we have no way to align the ELf
+// section if the section alignment is greater than kArchAlignment.
+void LlvmCompilationUnit::CheckCodeAlign(uint32_t align) const {
+  InstructionSet insn_set = GetInstructionSet();
+  switch (insn_set) {
+  case kThumb2:
+  case kArm:
+    CHECK_LE(align, static_cast<uint32_t>(kArmAlignment));
+    break;
+
+  case kX86:
+    CHECK_LE(align, static_cast<uint32_t>(kX86Alignment));
+    break;
+
+  case kMips:
+    CHECK_LE(align, static_cast<uint32_t>(kMipsAlignment));
+    break;
+
+  default:
+    LOG(FATAL) << "Unknown instruction set: " << insn_set;
+  }
+}
+
+
+} // namespace llvm
+} // namespace art
