/*
 * Copyright 2010, 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.h"

#include "Config.h"

#if USE_OLD_JIT
#include "OldJIT/ContextManager.h"
#endif

#if USE_DISASSEMBLER
#include "Disassembler/Disassembler.h"
#endif

#include "DebugHelper.h"
#include "FileHandle.h"
#include "Runtime.h"
#include "ScriptCompiled.h"
#include "Sha1Helper.h"

#if USE_MCJIT
#include "librsloader.h"
#endif

#include "llvm/ADT/StringRef.h"

#include "llvm/Analysis/Passes.h"

#include "llvm/Bitcode/ReaderWriter.h"

#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"

#include "llvm/MC/SubtargetFeature.h"

#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"

#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetSelect.h"

#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"

#include "llvm/Type.h"
#include "llvm/GlobalValue.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Value.h"

#include <errno.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string.h>

#include <algorithm>
#include <iterator>
#include <string>
#include <vector>

namespace bcc {

//////////////////////////////////////////////////////////////////////////////
// BCC Compiler Static Variables
//////////////////////////////////////////////////////////////////////////////

bool Compiler::GlobalInitialized = false;

// Code generation optimization level for the compiler
llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;

std::string Compiler::Triple;

std::string Compiler::CPU;

std::vector<std::string> Compiler::Features;

// Name of metadata node where pragma info resides (should be synced with
// slang.cpp)
const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";

// Name of metadata node where exported variable names reside (should be
// synced with slang_rs_metadata.h)
const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";

// Name of metadata node where exported function names reside (should be
// synced with slang_rs_metadata.h)
const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";

// Name of metadata node where RS object slot info resides (should be
// synced with slang_rs_metadata.h)
const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";

//////////////////////////////////////////////////////////////////////////////
// Compiler
//////////////////////////////////////////////////////////////////////////////

void Compiler::GlobalInitialization() {
  if (GlobalInitialized)
    return;
  // if (!llvm::llvm_is_multithreaded())
  //   llvm::llvm_start_multithreaded();

  // Set Triple, CPU and Features here
  Triple = TARGET_TRIPLE_STRING;

  Features.push_back("+vfp3");

  // NOTE: Currently, we have to turn off the support for NEON explicitly.
  // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
  // instructions.
#if ARCH_ARM_HAVE_NEON
  Features.push_back("+d32");
  Features.push_back("+neon");
  Features.push_back("+neonfp");
#else
  Features.push_back("+d16");
  Features.push_back("-neon");
  Features.push_back("-neonfp");
#endif

  Features.push_back("-vmlx");

#if defined(DEFAULT_ARM_CODEGEN) || defined(PROVIDE_ARM_CODEGEN)
  LLVMInitializeARMMCAsmInfo();
  LLVMInitializeARMMCCodeGenInfo();
  LLVMInitializeARMMCSubtargetInfo();
  LLVMInitializeARMAsmPrinter();
  LLVMInitializeARMTargetInfo();
  LLVMInitializeARMTarget();
#endif

#if defined(DEFAULT_X86_CODEGEN) || defined(PROVIDE_X86_CODEGEN) || \
    defined(DEFAULT_X64_CODEGEN) || defined(PROVIDE_X64_CODEGEN)
  LLVMInitializeX86MCAsmInfo();
  LLVMInitializeX86MCCodeGenInfo();
  LLVMInitializeX86MCSubtargetInfo();
  LLVMInitializeX86AsmPrinter();
  LLVMInitializeX86TargetInfo();
  LLVMInitializeX86Target();
#endif

#if USE_DISASSEMBLER
  InitializeDisassembler();
#endif

  // -O0: llvm::CodeGenOpt::None
  // -O1: llvm::CodeGenOpt::Less
  // -O2: llvm::CodeGenOpt::Default
  // -O3: llvm::CodeGenOpt::Aggressive
  CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;

  // Below are the global settings to LLVM

  // Disable frame pointer elimination optimization
  llvm::NoFramePointerElim = false;

  // Use hardfloat ABI
  //
  // TODO(all): Need to detect the CPU capability and decide whether to use
  // softfp. To use softfp, change following 2 lines to
  //
  // llvm::FloatABIType = llvm::FloatABI::Soft;
  // llvm::UseSoftFloat = true;
  //
  llvm::FloatABIType = llvm::FloatABI::Soft;
  llvm::UseSoftFloat = false;

#if defined(DEFAULT_X64_CODEGEN)
  // Data address in X86_64 architecture may reside in a far-away place
  llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium);
#else
  // This is set for the linker (specify how large of the virtual addresses
  // we can access for all unknown symbols.)
  llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small);
#endif

  // Register the scheduler
  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);

  // Register allocation policy:
  //  createFastRegisterAllocator: fast but bad quality
  //  createLinearScanRegisterAllocator: not so fast but good quality
  llvm::RegisterRegAlloc::setDefault
    ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
     llvm::createFastRegisterAllocator :
     llvm::createLinearScanRegisterAllocator);

#if USE_CACHE
  // Read in SHA1 checksum of libbcc and libRS.
  readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);

  calcFileSHA1(sha1LibRS, pathLibRS);
#endif

  GlobalInitialized = true;
}


void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
  std::string *Error = static_cast<std::string*>(UserData);
  Error->assign(Message);
  LOGE("%s", Message.c_str());
  exit(1);
}


#if USE_OLD_JIT
CodeMemoryManager *Compiler::createCodeMemoryManager() {
  mCodeMemMgr.reset(new CodeMemoryManager());
  return mCodeMemMgr.get();
}
#endif


#if USE_OLD_JIT
CodeEmitter *Compiler::createCodeEmitter() {
  mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
  return mCodeEmitter.get();
}
#endif


Compiler::Compiler(ScriptCompiled *result)
  : mpResult(result),
#if USE_MCJIT
    mRSExecutable(NULL),
#endif
    mpSymbolLookupFn(NULL),
    mpSymbolLookupContext(NULL),
    mContext(NULL),
    mModule(NULL),
    mHasLinked(false) /* Turn off linker */ {
  llvm::remove_fatal_error_handler();
  llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
  mContext = new llvm::LLVMContext();
  return;
}


llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
  llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);

  if (!result) {
    LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
    return NULL;
  }

  return result;
}


int Compiler::linkModule(llvm::Module *moduleWith) {
  if (llvm::Linker::LinkModules(mModule, moduleWith, &mError) != 0) {
    return hasError();
  }

  // Everything for linking should be settled down here with no error occurs
  mHasLinked = true;
  return hasError();
}


int Compiler::compile(bool compileOnly) {
  llvm::Target const *Target = NULL;
  llvm::TargetData *TD = NULL;
  llvm::TargetMachine *TM = NULL;

  std::string FeaturesStr;

  llvm::NamedMDNode const *PragmaMetadata;
  llvm::NamedMDNode const *ExportVarMetadata;
  llvm::NamedMDNode const *ExportFuncMetadata;
  llvm::NamedMDNode const *ObjectSlotMetadata;

  if (mModule == NULL)  // No module was loaded
    return 0;

  // Create TargetMachine
  Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
  if (hasError())
    goto on_bcc_compile_error;

  if (!CPU.empty() || !Features.empty()) {
    llvm::SubtargetFeatures F;

    for (std::vector<std::string>::const_iterator
         I = Features.begin(), E = Features.end(); I != E; I++) {
      F.AddFeature(*I);
    }

    FeaturesStr = F.getString();
  }

  TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
                                   llvm::Reloc::Static);
  if (TM == NULL) {
    setError("Failed to create target machine implementation for the"
             " specified triple '" + Triple + "'");
    goto on_bcc_compile_error;
  }

  // Get target data from Module
  TD = new llvm::TargetData(mModule);

  // Load named metadata
  ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
  ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
  PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
  ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);

  // Perform link-time optimization if we have multiple modules
  if (mHasLinked) {
    runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
  }

  // Perform code generation
#if USE_OLD_JIT
  if (runCodeGen(new llvm::TargetData(*TD), TM,
                 ExportVarMetadata, ExportFuncMetadata) != 0) {
    goto on_bcc_compile_error;
  }
#endif

#if USE_MCJIT
  if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
    goto on_bcc_compile_error;
  }

  if (compileOnly)
    return 0;

  // Load the ELF Object
  mRSExecutable =
    rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
                       mEmittedELFExecutable.size(),
                       &resolveSymbolAdapter, this);

  if (!mRSExecutable) {
    setError("Fail to load emitted ELF relocatable file");
    goto on_bcc_compile_error;
  }

  if (ExportVarMetadata) {
    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
    std::vector<std::string> &varNameList = mpResult->mExportVarsName;

    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef ExportVarName =
            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();

          varList.push_back(
            rsloaderGetSymbolAddress(mRSExecutable,
                                     ExportVarName.str().c_str()));
          varNameList.push_back(ExportVarName.str());
#if DEBUG_MCJIT_REFLECT
          LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
               varList.back());
#endif
          continue;
        }
      }

      varList.push_back(NULL);
    }
  }

  if (ExportFuncMetadata) {
    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
    std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;

    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef ExportFuncName =
            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();

          funcList.push_back(
            rsloaderGetSymbolAddress(mRSExecutable,
                                     ExportFuncName.str().c_str()));
          funcNameList.push_back(ExportFuncName.str());
#if DEBUG_MCJIT_RELECT
          LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
               funcList.back());
#endif
        }
      }
    }
  }

#if DEBUG_MCJIT_DISASSEMBLER
  {
    // Get MC codegen emitted function name list
    size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
    std::vector<char const *> func_list(func_list_size, NULL);
    rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());

    // Disassemble each function
    for (size_t i = 0; i < func_list_size; ++i) {
      void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
      if (func) {
        size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
        Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
                    Target, TM, func_list[i], (unsigned char const *)func, size);
      }
    }
  }
#endif
#endif

  // Read pragma information from the metadata node of the module.
  if (PragmaMetadata) {
    ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;

    for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
      if (Pragma != NULL &&
          Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
        llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
        llvm::Value *PragmaValueMDS = Pragma->getOperand(1);

        if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
            (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
          llvm::StringRef PragmaName =
            static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
          llvm::StringRef PragmaValue =
            static_cast<llvm::MDString*>(PragmaValueMDS)->getString();

          pragmaList.push_back(
            std::make_pair(std::string(PragmaName.data(),
                                       PragmaName.size()),
                           std::string(PragmaValue.data(),
                                       PragmaValue.size())));
#if DEBUG_BCC_REFLECT
          LOGD("compile(): Pragma: %s -> %s\n",
               pragmaList.back().first.c_str(),
               pragmaList.back().second.c_str());
#endif
        }
      }
    }
  }

  if (ObjectSlotMetadata) {
    ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;

    for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
      if (ObjectSlot != NULL &&
          ObjectSlot->getNumOperands() == 1) {
        llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
        if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef Slot =
              static_cast<llvm::MDString*>(SlotMDS)->getString();
          uint32_t USlot = 0;
          if (Slot.getAsInteger(10, USlot)) {
            setError("Non-integer object slot value '" + Slot.str() + "'");
            goto on_bcc_compile_error;
          }
          objectSlotList.push_back(USlot);
#if DEBUG_BCC_REFLECT
          LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
#endif
        }
      }
    }
  }

on_bcc_compile_error:
  // LOGE("on_bcc_compiler_error");
  if (TD) {
    delete TD;
  }

  if (TM) {
    delete TM;
  }

  if (mError.empty()) {
    return 0;
  }

  // LOGE(getErrorMessage());
  return 1;
}


#if USE_OLD_JIT
int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
                         llvm::NamedMDNode const *ExportVarMetadata,
                         llvm::NamedMDNode const *ExportFuncMetadata) {
  // Create memory manager for creation of code emitter later.
  if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
    setError("Failed to startup memory management for further compilation");
    return 1;
  }

  mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());

  // Create code emitter
  if (!mCodeEmitter.get()) {
    if (!createCodeEmitter()) {
      setError("Failed to create machine code emitter for compilation");
      return 1;
    }
  } else {
    // Reuse the code emitter
    mCodeEmitter->reset();
  }

  mCodeEmitter->setTargetMachine(*TM);
  mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
                                       mpSymbolLookupContext);

  // Create code-gen pass to run the code emitter
  llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
    new llvm::FunctionPassManager(mModule));

  // Add TargetData to code generation pass manager
  CodeGenPasses->add(TD);

  // Add code emit passes
  if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
                                     *mCodeEmitter,
                                     CodeGenOptLevel)) {
    setError("The machine code emission is not supported on '" + Triple + "'");
    return 1;
  }

  // Run the code emitter on every non-declaration function in the module
  CodeGenPasses->doInitialization();
  for (llvm::Module::iterator
       I = mModule->begin(), E = mModule->end(); I != E; I++) {
    if (!I->isDeclaration()) {
      CodeGenPasses->run(*I);
    }
  }

  CodeGenPasses->doFinalization();

  // Copy the global address mapping from code emitter and remapping
  if (ExportVarMetadata) {
    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;

    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef ExportVarName =
            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();

          CodeEmitter::global_addresses_const_iterator I, E;
          for (I = mCodeEmitter->global_address_begin(),
               E = mCodeEmitter->global_address_end();
               I != E; I++) {
            if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
              continue;
            if (ExportVarName == I->first->getName()) {
              varList.push_back(I->second);
#if DEBUG_BCC_REFLECT
              LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
#endif
              break;
            }
          }
          if (I != mCodeEmitter->global_address_end())
            continue;  // found

#if DEBUG_BCC_REFLECT
          LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
               ExportVarName.str().c_str(), (void *)0);
#endif
        }
      }
      // if reaching here, we know the global variable record in metadata is
      // not found. So we make an empty slot
      varList.push_back(NULL);
    }

    bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
              "Number of slots doesn't match the number of export variables!");
  }

  if (ExportFuncMetadata) {
    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;

    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef ExportFuncName =
            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
          funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
#if DEBUG_BCC_REFLECT
          LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
               funcList.back());
#endif
        }
      }
    }
  }

  // Tell code emitter now can release the memory using during the JIT since
  // we have done the code emission
  mCodeEmitter->releaseUnnecessary();

  return 0;
}
#endif // USE_OLD_JIT


#if USE_MCJIT
int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
  // Decorate mEmittedELFExecutable with formatted ostream
  llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);

  // Relax all machine instructions
  TM->setMCRelaxAll(/* RelaxAll= */ true);

  // Create MC code generation pass manager
  llvm::PassManager MCCodeGenPasses;

  // Add TargetData to MC code generation pass manager
  MCCodeGenPasses.add(TD);

  // Add MC code generation passes to pass manager
  llvm::MCContext *Ctx;
  if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
                            CodeGenOptLevel, false)) {
    setError("Fail to add passes to emit file");
    return 1;
  }

  MCCodeGenPasses.run(*mModule);
  OutSVOS.flush();
  return 0;
}
#endif // USE_MCJIT


int Compiler::runLTO(llvm::TargetData *TD,
                     llvm::NamedMDNode const *ExportVarMetadata,
                     llvm::NamedMDNode const *ExportFuncMetadata) {
  llvm::PassManager LTOPasses;

  // Add TargetData to LTO passes
  LTOPasses.add(TD);

  // Collect All Exported Symbols
  std::vector<const char*> ExportSymbols;

  // Note: This is a workaround for getting export variable and function name.
  // We should refine it soon.
  if (ExportVarMetadata) {
    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef ExportVarName =
            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
          ExportSymbols.push_back(ExportVarName.data());
        }
      }
    }
  }

  if (ExportFuncMetadata) {
    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
          llvm::StringRef ExportFuncName =
            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
          ExportSymbols.push_back(ExportFuncName.data());
        }
      }
    }
  }

  // TODO(logan): Remove this after we have finished the
  // bccMarkExternalSymbol API.

  // root(), init(), and .rs.dtor() are born to be exported
  ExportSymbols.push_back("root");
  ExportSymbols.push_back("init");
  ExportSymbols.push_back(".rs.dtor");

  // User-defined exporting symbols
  std::vector<char const *> const &UserDefinedExternalSymbols =
    mpResult->getUserDefinedExternalSymbols();

  std::copy(UserDefinedExternalSymbols.begin(),
            UserDefinedExternalSymbols.end(),
            std::back_inserter(ExportSymbols));

  // We now create passes list performing LTO. These are copied from
  // (including comments) llvm::createStandardLTOPasses().

  // Internalize all other symbols not listed in ExportSymbols
  LTOPasses.add(llvm::createInternalizePass(ExportSymbols));

  // Propagate constants at call sites into the functions they call. This
  // opens opportunities for globalopt (and inlining) by substituting
  // function pointers passed as arguments to direct uses of functions.
  LTOPasses.add(llvm::createIPSCCPPass());

  // Now that we internalized some globals, see if we can hack on them!
  LTOPasses.add(llvm::createGlobalOptimizerPass());

  // Linking modules together can lead to duplicated global constants, only
  // keep one copy of each constant...
  LTOPasses.add(llvm::createConstantMergePass());

  // Remove unused arguments from functions...
  LTOPasses.add(llvm::createDeadArgEliminationPass());

  // Reduce the code after globalopt and ipsccp. Both can open up
  // significant simplification opportunities, and both can propagate
  // functions through function pointers. When this happens, we often have
  // to resolve varargs calls, etc, so let instcombine do this.
  LTOPasses.add(llvm::createInstructionCombiningPass());

  // Inline small functions
  LTOPasses.add(llvm::createFunctionInliningPass());

  // Remove dead EH info.
  LTOPasses.add(llvm::createPruneEHPass());

  // Internalize the globals again after inlining
  LTOPasses.add(llvm::createGlobalOptimizerPass());

  // Remove dead functions.
  LTOPasses.add(llvm::createGlobalDCEPass());

  // If we didn't decide to inline a function, check to see if we can
  // transform it to pass arguments by value instead of by reference.
  LTOPasses.add(llvm::createArgumentPromotionPass());

  // The IPO passes may leave cruft around.  Clean up after them.
  LTOPasses.add(llvm::createInstructionCombiningPass());
  LTOPasses.add(llvm::createJumpThreadingPass());

  // Break up allocas
  LTOPasses.add(llvm::createScalarReplAggregatesPass());

  // Run a few AA driven optimizations here and now, to cleanup the code.
  LTOPasses.add(llvm::createFunctionAttrsPass());  // Add nocapture.
  LTOPasses.add(llvm::createGlobalsModRefPass());  // IP alias analysis.

  // Hoist loop invariants.
  LTOPasses.add(llvm::createLICMPass());

  // Remove redundancies.
  LTOPasses.add(llvm::createGVNPass());

  // Remove dead memcpys.
  LTOPasses.add(llvm::createMemCpyOptPass());

  // Nuke dead stores.
  LTOPasses.add(llvm::createDeadStoreEliminationPass());

  // Cleanup and simplify the code after the scalar optimizations.
  LTOPasses.add(llvm::createInstructionCombiningPass());

  LTOPasses.add(llvm::createJumpThreadingPass());

  // Delete basic blocks, which optimization passes may have killed.
  LTOPasses.add(llvm::createCFGSimplificationPass());

  // Now that we have optimized the program, discard unreachable functions.
  LTOPasses.add(llvm::createGlobalDCEPass());

  LTOPasses.run(*mModule);

  return 0;
}


#if USE_MCJIT
void *Compiler::getSymbolAddress(char const *name) {
  return rsloaderGetSymbolAddress(mRSExecutable, name);
}
#endif


#if USE_MCJIT
void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
  Compiler *self = reinterpret_cast<Compiler *>(context);

  if (void *Addr = FindRuntimeFunction(name)) {
    return Addr;
  }

  if (self->mpSymbolLookupFn) {
    if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
      return Addr;
    }
  }

  LOGE("Unable to resolve symbol: %s\n", name);
  return NULL;
}
#endif


Compiler::~Compiler() {
  delete mModule;
  delete mContext;

#if USE_MCJIT
  rsloaderDisposeExec(mRSExecutable);
#endif

  // llvm::llvm_shutdown();
}


}  // namespace bcc
