//===---------------- JIT.cc - Initialize the JIT -------------------------===//
//
//                     The Micro Virtual Machine
//
// This file is distributed under the University of Illinois Open Source 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <llvm/CallingConv.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Instructions.h>
#include <llvm/LinkAllPasses.h>
#include <llvm/Linker.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/PassManager.h>
#include <llvm/Type.h>
#include <llvm/Analysis/DebugInfo.h>
#include <llvm/Analysis/LoopPass.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/Parser.h>
#include <llvm/CodeGen/GCStrategy.h>
#include <llvm/Config/config.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/Support/CommandLine.h"
#include <llvm/Support/Debug.h>
#include <llvm/Support/IRReader.h>
#include <llvm/Support/MutexGuard.h>
#include <llvm/Support/PassNameParser.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Target/TargetOptions.h>
#include <llvm/Target/TargetSelect.h>

#include "mvm/JIT.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
#include "mvm/VirtualMachine.h"
#include "mvm/GC/GC.h"
#include "MutatorThread.h"
#include "MvmGC.h"

#include <sys/mman.h>

using namespace mvm;
using namespace llvm;


static cl::list<std::string> 
LoadBytecodeFiles("load-bc", cl::desc("Load bytecode file"), cl::ZeroOrMore,
                  cl::CommaSeparated);

namespace mvm {
  namespace llvm_runtime {
    #include "LLVMRuntime.inc"
  }
  
  namespace mmtk_runtime {
    #include "MMTkInline.inc"
  }
  void linkVmkitGC();
}

const char* MvmModule::getHostTriple() {
  return LLVM_HOSTTRIPLE;
}

class MvmJITMethodInfo : public JITMethodInfo {
  const llvm::Function* Func;
public:
  virtual void print(void* ip, void* addr);
  MvmJITMethodInfo(llvm::GCFunctionInfo* GFI, const llvm::Function* F) :
    JITMethodInfo(GFI) {
      Func = F;
      MethodType = 0;
  }
};

void MvmJITMethodInfo::print(void* ip, void* addr) {
  fprintf(stderr, "; %p in %s LLVM method\n", ip, Func->getName().data());
}

class MvmJITListener : public llvm::JITEventListener {
public:
  virtual void NotifyFunctionEmitted(const Function &F,
                                     void *Code, size_t Size,
                                     const EmittedFunctionDetails &Details) {
    // Functions compiled in the global module are MMTk functions and the
    // interfaces with VMKit.
    if (F.getParent() == MvmModule::globalModule) {
      llvm::GCFunctionInfo* GFI = 0;
      // We know the last GC info is for this method.
      if (F.hasGC()) {
        // Only the interface functions have GC informations.
        GCStrategy::iterator I = mvm::MvmModule::TheGCStrategy->end();
        I--;
        DEBUG(errs() << (*I)->getFunction().getName() << '\n');
        DEBUG(errs() << F.getName() << '\n');
        assert(&(*I)->getFunction() == &F &&
           "GC Info and method do not correspond");
        GFI = *I;
      }
      MethodInfo* MI =
        new(*MvmModule::Allocator, "MvmJITMethodInfo") MvmJITMethodInfo(GFI, &F);
      VirtualMachine::SharedRuntimeFunctions.addMethodInfo(MI, Code,
                                              (void*)((uintptr_t)Code + Size));
    }
  }
};

static MvmJITListener JITListener;

void MvmModule::loadBytecodeFile(const std::string& str) {
  SMDiagnostic Err;
  Module* M = ParseIRFile(str, Err, globalModule->getContext());
  if (M) {
    M->setTargetTriple(getHostTriple());
    Linker::LinkModules(globalModule, M, 0);
    delete M;
  } else {
    Err.Print("load bytecode", errs());
  }
}

typedef void (*BootType)(uintptr_t Plan);
typedef void (*BootHeapType)(intptr_t initial, intptr_t max);

void MvmModule::initialise(CodeGenOpt::Level level, Module* M,
                           TargetMachine* T) {
  mvm::linkVmkitGC();
  
  llvm_start_multithreaded();
  
  llvm::NoFramePointerElim = true;
  llvm::DisablePrettyStackTrace = true;
  llvm::JITEmitDebugInfo = false;
#if DWARF_EXCEPTIONS
  llvm::DwarfExceptionHandling = true;
#else
  llvm::DwarfExceptionHandling = false;
#endif
  
  // Disable branch fold for accurate line numbers.
  char* commands[2] = { (char*)"vmkit", (char*)"-disable-branch-fold" };
  llvm::cl::ParseCommandLineOptions(2, commands);

  if (!M) {
    globalModule = new Module("bootstrap module", getGlobalContext());

    InitializeNativeTarget();

    executionEngine = ExecutionEngine::createJIT(globalModule, 0,
                                                 0, level, false);

    Allocator = new BumpPtrAllocator();
    executionEngine->RegisterJITEventListener(&JITListener);    
    std::string str = 
      executionEngine->getTargetData()->getStringRepresentation();
    globalModule->setDataLayout(str);
    globalModule->setTargetTriple(getHostTriple());
  
    TheTargetData = executionEngine->getTargetData();
  } else {
    globalModule = M;
    TheTargetData = T->getTargetData();
  }

  globalFunctionPasses = new FunctionPassManager(globalModule);

  
  //LLVMContext& Context = globalModule->getContext();
  //MetadataTypeKind = Context.getMDKindID("HighLevelType");
 
  for (std::vector<std::string>::iterator i = LoadBytecodeFiles.begin(),
       e = LoadBytecodeFiles.end(); i != e; ++i) {
    loadBytecodeFile(*i); 
  }

#ifdef WITH_MMTK
  llvm::GlobalVariable* GV = globalModule->getGlobalVariable("MMTkCollectorSize", false);
  if (GV && executionEngine) {
    // Allocate the memory for MMTk right now, to avoid conflicts with
    // other allocators.
#if defined (__MACH__)
    uint32 flags = MAP_PRIVATE | MAP_ANON | MAP_FIXED;
#else
    uint32 flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
#endif
    void* baseAddr = mmap((void*)0x30000000, 0x50000000, PROT_READ | PROT_WRITE,
                          flags, -1, 0);
    if (baseAddr == MAP_FAILED) {
      perror("mmap");
      abort();
    }

    ConstantInt* C = dyn_cast<ConstantInt>(GV->getInitializer());
    uint64_t val = C->getZExtValue();
    MutatorThread::MMTkCollectorSize = val;
  
    GV = globalModule->getGlobalVariable("MMTkMutatorSize", false);
    assert(GV && "Could not find MMTkMutatorSize");
    C = dyn_cast<ConstantInt>(GV->getInitializer());
    val = C->getZExtValue();
    MutatorThread::MMTkMutatorSize = val;

    Function* F = globalModule->getFunction("JnJVM_org_j3_config_Selected_00024Mutator__0003Cinit_0003E__");
    assert(F && "Could not find <init> from Mutator");
    MutatorThread::MutatorInit = (MutatorThread::MMTkInitType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_MutatorContext_initMutator__I");
    assert(F && "Could not find init from Mutator");
    MutatorThread::MutatorCallInit = (MutatorThread::MMTkInitIntType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_MutatorContext_deinitMutator__");
    assert(F && "Could not find deinit from Mutator");
    MutatorThread::MutatorCallDeinit = (MutatorThread::MMTkInitType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    
    GV = globalModule->getGlobalVariable("org_j3_config_Selected_4Mutator_VT", false);
    assert(GV && "Could not find VT from Mutator");
    MutatorThread::MutatorVT = (VirtualTable*)executionEngine->getPointerToGlobal(GV);
  
    F = globalModule->getFunction("JnJVM_org_j3_config_Selected_00024Collector__0003Cinit_0003E__");
    assert(F && "Could not find <init> from Collector");
    MutatorThread::CollectorInit = (MutatorThread::MMTkInitType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    GV = globalModule->getGlobalVariable("org_j3_config_Selected_4Collector_VT", false);
    assert(GV && "Could not find VT from Collector");
    MutatorThread::CollectorVT = (VirtualTable*)executionEngine->getPointerToGlobal(GV);

    GlobalAlias* GA = dyn_cast<GlobalAlias>(globalModule->getNamedValue("MMTkAlloc"));
    assert(GA && "Could not find MMTkAlloc alias");
    F = dyn_cast<Function>(GA->getAliasee());
    gc::MMTkGCAllocator = (gc::MMTkAllocType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
  
    GA = dyn_cast<GlobalAlias>(globalModule->getNamedValue("MMTkPostAlloc"));
    assert(GA && "Could not find MMTkPostAlloc alias");
    F = dyn_cast<Function>(GA->getAliasee());
    gc::MMTkGCPostAllocator = (gc::MMTkPostAllocType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    GA = dyn_cast<GlobalAlias>(globalModule->getNamedValue("MMTkCheckAllocator"));
    assert(GA && "Could not find MMTkCheckAllocator alias");
    F = dyn_cast<Function>(GA->getAliasee());
    gc::MMTkCheckAllocator = (gc::MMTkCheckAllocatorType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
     
    F = globalModule->getFunction("JnJVM_org_mmtk_utility_heap_HeapGrowthManager_boot__Lorg_vmmagic_unboxed_Extent_2Lorg_vmmagic_unboxed_Extent_2");
    assert(F && "Could not find boot from HeapGrowthManager");
    BootHeapType BootHeap = (BootHeapType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    BootHeap(128 * 1024 * 1024, 1024 * 1024 * 1024);
    
    GV = globalModule->getGlobalVariable("org_j3_config_Selected_4Plan_static", false);
    assert(GV && "No global plan.");
    uintptr_t Plan = *((uintptr_t*)executionEngine->getPointerToGlobal(GV));
    
    GA = dyn_cast<GlobalAlias>(globalModule->getNamedValue("MMTkPlanBoot"));
    assert(GA && "Could not find MMTkPlanBoot alias");
    F = dyn_cast<Function>(GA->getAliasee());
    BootType Boot = (BootType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    Boot(Plan);
    
    GA = dyn_cast<GlobalAlias>(globalModule->getNamedValue("MMTkPlanPostBoot"));
    assert(GA && "Could not find MMTkPlanPostBoot alias");
    F = dyn_cast<Function>(GA->getAliasee());
    Boot = (BootType)(uintptr_t)executionEngine->getPointerToFunction(F);
    Boot(Plan);
    
    GA = dyn_cast<GlobalAlias>(globalModule->getNamedValue("MMTkPlanFullBoot"));
    assert(GA && "Could not find MMTkPlanFullBoot alias");
    F = dyn_cast<Function>(GA->getAliasee());
    Boot = (BootType)(uintptr_t)executionEngine->getPointerToFunction(F);
    Boot(Plan);
    
    F = globalModule->getFunction("Java_org_j3_mmtk_Collection_triggerCollection__I");
    assert(F && "Could not find external collect");
    gc::MMTkTriggerCollection = (gc::MMTkCollectType)
      (uintptr_t)executionEngine->getPointerToFunction(F);

    //===-------------------- TODO: make those virtual. -------------------===//
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_reportDelayedRootEdge__Lorg_vmmagic_unboxed_Address_2");
    assert(F && "Could not find reportDelayedRootEdge from TraceLocal");
    gc::MMTkDelayedRoot = (gc::MMTkDelayedRootType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_processEdge__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Address_2");
    assert(F && "Could not find processEdge from TraceLocal");
    gc::MMTkProcessEdge = (gc::MMTkProcessEdgeType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_processRootEdge__Lorg_vmmagic_unboxed_Address_2Z");
    assert(F && "Could not find processEdge from TraceLocal");
    gc::MMTkProcessRootEdge = (gc::MMTkProcessRootEdgeType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_marksweep_MSTraceLocal_isLive__Lorg_vmmagic_unboxed_ObjectReference_2");
    assert(F && "Could not find isLive from TraceLocal");
    gc::MMTkIsLive = (gc::MMTkIsLiveType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
   
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_retainForFinalize__Lorg_vmmagic_unboxed_ObjectReference_2");
    assert(F && "Could not find isLive from TraceLocal");
    gc::MMTkRetainForFinalize = (gc::MMTkRetainForFinalizeType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_retainReferent__Lorg_vmmagic_unboxed_ObjectReference_2");
    assert(F && "Could not find isLive from TraceLocal");
    gc::MMTkRetainReferent = (gc::MMTkRetainReferentType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_getForwardedReference__Lorg_vmmagic_unboxed_ObjectReference_2");
    assert(F && "Could not find isLive from TraceLocal");
    gc::MMTkGetForwardedReference = (gc::MMTkGetForwardedReferenceType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_getForwardedReferent__Lorg_vmmagic_unboxed_ObjectReference_2");
    assert(F && "Could not find isLive from TraceLocal");
    gc::MMTkGetForwardedReferent = (gc::MMTkGetForwardedReferentType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
    F = globalModule->getFunction("JnJVM_org_mmtk_plan_TraceLocal_getForwardedFinalizable__Lorg_vmmagic_unboxed_ObjectReference_2");
    assert(F && "Could not find isLive from TraceLocal");
    gc::MMTkGetForwardedFinalizable = (gc::MMTkGetForwardedFinalizableType)
      (uintptr_t)executionEngine->getPointerToFunction(F);
    
  }
#endif
}


BaseIntrinsics::BaseIntrinsics(llvm::Module* module) {

  module->setDataLayout(MvmModule::globalModule->getDataLayout());
  module->setTargetTriple(MvmModule::globalModule->getTargetTriple());
  LLVMContext& Context = module->getContext();
  
#ifdef WITH_MMTK
  if (MutatorThread::MMTkCollectorSize) {
    // If we have found MMTk, read the gcmalloc function and set the address of
    // global variables and functions used by gcmalloc.
    mvm::mmtk_runtime::makeLLVMFunction(module);
    if (MvmModule::executionEngine) {
      for (Module::global_iterator i = module->global_begin(),
           e = module->global_end(); i != e; ++i) {
        if (i->isDeclaration()) {
          GlobalVariable* GV =
            MvmModule::globalModule->getGlobalVariable(i->getName(), true);
          assert(GV && "GV can not be found");
          void* ptr = MvmModule::executionEngine->getPointerToGlobal(GV);
          MvmModule::executionEngine->updateGlobalMapping(i, ptr);
        }
      }
      for (Module::iterator i = module->begin(), e = module->end();
           i != e; ++i) {
        if (i->isDeclaration() && !i->isIntrinsic()) {
          Function* F =
            MvmModule::globalModule->getFunction(i->getName());
          assert(F && "Function can not be found");
          void* ptr = MvmModule::executionEngine->getPointerToFunction(F);
          MvmModule::executionEngine->updateGlobalMapping(i, ptr);
        }
      }
    }
  }
#endif
  mvm::llvm_runtime::makeLLVMModuleContents(module);
  
  
  // Type declaration
  ptrType = PointerType::getUnqual(Type::getInt8Ty(Context));
  ptr32Type = PointerType::getUnqual(Type::getInt32Ty(Context));
  ptrPtrType = PointerType::getUnqual(ptrType);
  pointerSizeType = module->getPointerSize() == Module::Pointer32 ?
    Type::getInt32Ty(Context) : Type::getInt64Ty(Context);
  
  // Constant declaration
  constantLongMinusOne = ConstantInt::get(Type::getInt64Ty(Context), (uint64_t)-1);
  constantLongZero = ConstantInt::get(Type::getInt64Ty(Context), 0);
  constantLongOne = ConstantInt::get(Type::getInt64Ty(Context), 1);
  constantZero = ConstantInt::get(Type::getInt32Ty(Context), 0);
  constantInt8Zero = ConstantInt::get(Type::getInt8Ty(Context), 0);
  constantOne = ConstantInt::get(Type::getInt32Ty(Context), 1);
  constantTwo = ConstantInt::get(Type::getInt32Ty(Context), 2);
  constantThree = ConstantInt::get(Type::getInt32Ty(Context), 3);
  constantFour = ConstantInt::get(Type::getInt32Ty(Context), 4);
  constantFive = ConstantInt::get(Type::getInt32Ty(Context), 5);
  constantSix = ConstantInt::get(Type::getInt32Ty(Context), 6);
  constantSeven = ConstantInt::get(Type::getInt32Ty(Context), 7);
  constantEight = ConstantInt::get(Type::getInt32Ty(Context), 8);
  constantMinusOne = ConstantInt::get(Type::getInt32Ty(Context), (uint64_t)-1);
  constantMinInt = ConstantInt::get(Type::getInt32Ty(Context), MinInt);
  constantMaxInt = ConstantInt::get(Type::getInt32Ty(Context), MaxInt);
  constantMinLong = ConstantInt::get(Type::getInt64Ty(Context), MinLong);
  constantMaxLong = ConstantInt::get(Type::getInt64Ty(Context), MaxLong);
  constantFloatZero = ConstantFP::get(Type::getFloatTy(Context), 0.0f);
  constantFloatOne = ConstantFP::get(Type::getFloatTy(Context), 1.0f);
  constantFloatTwo = ConstantFP::get(Type::getFloatTy(Context), 2.0f);
  constantDoubleZero = ConstantFP::get(Type::getDoubleTy(Context), 0.0);
  constantDoubleOne = ConstantFP::get(Type::getDoubleTy(Context), 1.0);
  constantMaxIntFloat = ConstantFP::get(Type::getFloatTy(Context), MaxIntFloat);
  constantMinIntFloat = ConstantFP::get(Type::getFloatTy(Context), MinIntFloat);
  constantMinLongFloat = ConstantFP::get(Type::getFloatTy(Context), MinLongFloat);
  constantMinLongDouble = ConstantFP::get(Type::getDoubleTy(Context), MinLongDouble);
  constantMaxLongFloat = ConstantFP::get(Type::getFloatTy(Context), MaxLongFloat);
  constantMaxIntDouble = ConstantFP::get(Type::getDoubleTy(Context), MaxIntDouble);
  constantMinIntDouble = ConstantFP::get(Type::getDoubleTy(Context), MinIntDouble);
  constantMaxLongDouble = ConstantFP::get(Type::getDoubleTy(Context), MaxLongDouble);
  constantMaxLongDouble = ConstantFP::get(Type::getDoubleTy(Context), MaxLongDouble);
  constantFloatInfinity = ConstantFP::get(Type::getFloatTy(Context), MaxFloat);
  constantFloatMinusInfinity = ConstantFP::get(Type::getFloatTy(Context), MinFloat);
  constantDoubleInfinity = ConstantFP::get(Type::getDoubleTy(Context), MaxDouble);
  constantDoubleMinusInfinity = ConstantFP::get(Type::getDoubleTy(Context), MinDouble);
  constantDoubleMinusZero = ConstantFP::get(Type::getDoubleTy(Context), -0.0);
  constantFloatMinusZero = ConstantFP::get(Type::getFloatTy(Context), -0.0f);
  constantThreadIDMask = ConstantInt::get(pointerSizeType, mvm::Thread::IDMask);
  constantStackOverflowMask = 
    ConstantInt::get(pointerSizeType, mvm::Thread::StackOverflowMask);
  constantFatMask = ConstantInt::get(pointerSizeType, 
      pointerSizeType == Type::getInt32Ty(Context) ? 0x80000000 : 0x8000000000000000LL);
  constantPtrOne = ConstantInt::get(pointerSizeType, 1);
  constantPtrZero = ConstantInt::get(pointerSizeType, 0);

  constantPtrNull = Constant::getNullValue(ptrType); 
  constantPtrLogSize = 
    ConstantInt::get(Type::getInt32Ty(Context), sizeof(void*) == 8 ? 3 : 2);
  arrayPtrType = PointerType::getUnqual(ArrayType::get(Type::getInt8Ty(Context), 0));


    
  printFloatLLVM = module->getFunction("printFloat");
  printDoubleLLVM = module->getFunction("printDouble");
  printLongLLVM = module->getFunction("printLong");
  printIntLLVM = module->getFunction("printInt");
  printObjectLLVM = module->getFunction("printObject");

  unwindResume = module->getFunction("_Unwind_Resume_or_Rethrow");
  
  llvmGetException = module->getFunction("llvm.eh.exception");
  exceptionSelector = module->getFunction("llvm.eh.selector"); 
  
  personality = module->getFunction("__gxx_personality_v0");
  exceptionEndCatch = module->getFunction("__cxa_end_catch");
  exceptionBeginCatch = module->getFunction("__cxa_begin_catch");

  func_llvm_sqrt_f64 = module->getFunction("llvm.sqrt.f64");
  func_llvm_sin_f64 = module->getFunction("llvm.sin.f64");
  func_llvm_cos_f64 = module->getFunction("llvm.cos.f64");
  
  func_llvm_tan_f64 = module->getFunction("tan");
  func_llvm_asin_f64 = module->getFunction("asin");
  func_llvm_acos_f64 = module->getFunction("acos");
  func_llvm_atan_f64 = module->getFunction("atan");
  func_llvm_exp_f64 = module->getFunction("exp");
  func_llvm_log_f64 = module->getFunction("log");
  func_llvm_ceil_f64 = module->getFunction("ceil");
  func_llvm_floor_f64 = module->getFunction("floor");
  func_llvm_cbrt_f64 = module->getFunction("cbrt");
  func_llvm_cosh_f64 = module->getFunction("cosh");
  func_llvm_expm1_f64 = module->getFunction("expm1");
  func_llvm_log10_f64 = module->getFunction("log10");
  func_llvm_log1p_f64 = module->getFunction("log1p");
  func_llvm_sinh_f64 = module->getFunction("sinh");
  func_llvm_tanh_f64 = module->getFunction("tanh");
  func_llvm_fabs_f64 = module->getFunction("fabs");
  func_llvm_rint_f64 = module->getFunction("rint");
    
  func_llvm_hypot_f64 = module->getFunction("hypot");
  func_llvm_pow_f64 = module->getFunction("pow");
  func_llvm_atan2_f64 = module->getFunction("atan2");
    
  func_llvm_fabs_f32 = module->getFunction("fabsf");

  setjmpLLVM = module->getFunction("setjmp");
  
  llvm_memcpy_i32 = module->getFunction("llvm.memcpy.i32");
  llvm_memset_i32 = module->getFunction("llvm.memset.i32");
  llvm_frameaddress = module->getFunction("llvm.frameaddress");
  llvm_gc_gcroot = module->getFunction("llvm.gcroot");

  llvm_atomic_lcs_i8 = module->getFunction("llvm.atomic.cmp.swap.i8.p0i8");
  llvm_atomic_lcs_i16 = module->getFunction("llvm.atomic.cmp.swap.i16.p0i16");
  llvm_atomic_lcs_i32 = module->getFunction("llvm.atomic.cmp.swap.i32.p0i32");
  llvm_atomic_lcs_i64 = module->getFunction("llvm.atomic.cmp.swap.i64.p0i64");

  llvm_atomic_lcs_ptr = pointerSizeType == Type::getInt32Ty(Context) ? llvm_atomic_lcs_i32 :
                                                           llvm_atomic_lcs_i64;

  unconditionalSafePoint = module->getFunction("unconditionalSafePoint");
  conditionalSafePoint = module->getFunction("conditionalSafePoint");
  AllocateFunction = module->getFunction("gcmalloc");
  assert(AllocateFunction && "No allocate function");
  AllocateUnresolvedFunction = module->getFunction("gcmallocUnresolved");
  assert(AllocateUnresolvedFunction && "No allocateUnresolved function");
  AddFinalizationCandidate = module->getFunction("addFinalizationCandidate");
  assert(AddFinalizationCandidate && "No addFinalizationCandidate function");
  
  MvmModule::copyDefinitions(module, MvmModule::globalModule); 
}

const llvm::TargetData* MvmModule::TheTargetData;
llvm::GCStrategy* MvmModule::TheGCStrategy;
llvm::Module *MvmModule::globalModule;
llvm::FunctionPassManager* MvmModule::globalFunctionPasses;
llvm::ExecutionEngine* MvmModule::executionEngine;
mvm::LockRecursive MvmModule::protectEngine;
mvm::BumpPtrAllocator* MvmModule::Allocator;
//unsigned MvmModule::MetadataTypeKind;

uint64 MvmModule::getTypeSize(const llvm::Type* type) {
  return TheTargetData->getTypeAllocSize(type);
}

void MvmModule::runPasses(llvm::Function* func,
                          llvm::FunctionPassManager* pm) {
  // Take the lock because the pass manager will call materializeFunction.
  // Our implementation of materializeFunction requires that the lock is held
  // by the caller. This is due to LLVM's JIT subsystem where the call to
  // materializeFunction is guarded.
  if (executionEngine) executionEngine->lock.acquire();
  pm->run(*func);
  if (executionEngine) executionEngine->lock.release();
}

static void addPass(FunctionPassManager *PM, Pass *P) {
  // Add the pass to the pass manager...
  PM->add(P);
}

// This is equivalent to:
// opt -simplifycfg -mem2reg -instcombine -jump-threading -simplifycfg
//     -scalarrepl -instcombine -condprop -simplifycfg -predsimplify 
//     -reassociate -licm -loop-unswitch -indvars -loop-deletion -loop-unroll 
//     -instcombine -gvn -sccp -simplifycfg -instcombine -condprop -dse -adce 
//     -simplifycfg
//
static void AddStandardCompilePasses(FunctionPassManager* PM) { 
   
  addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code
  addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas
  
  addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
  addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
  addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl.
  addPass(PM, createJumpThreadingPass());        // Thread jumps.
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createReassociatePass());          // Reassociate expressions
  addPass(PM, createLoopRotatePass());           // Rotate loops.
  addPass(PM, createLICMPass());                 // Hoist loop invariants
  addPass(PM, createLoopUnswitchPass());         // Unswitch loops.
  addPass(PM, createInstructionCombiningPass()); 
  addPass(PM, createIndVarSimplifyPass());       // Canonicalize indvars
  addPass(PM, createLoopDeletionPass());         // Delete dead loops
  addPass(PM, createLoopUnrollPass());           // Unroll small loops*/
  addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller
  addPass(PM, createGVNPass());                  // Remove redundancies
  addPass(PM, createMemCpyOptPass());             // Remove memcpy / form memset  
  addPass(PM, createSCCPPass());                 // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  addPass(PM, createInstructionCombiningPass());
  addPass(PM, createJumpThreadingPass());         // Thread jumps
  addPass(PM, createDeadStoreEliminationPass());  // Delete dead stores
  addPass(PM, createAggressiveDCEPass());         // Delete dead instructions
  addPass(PM, createCFGSimplificationPass());     // Merge & remove BBs
}

static cl::opt<bool> 
DisableOptimizations("disable-opt", 
                     cl::desc("Do not run any optimization passes"));

cl::opt<bool>
StandardCompileOpts("std-compile-opts", 
                   cl::desc("Include the standard compile time optimizations"));

// The OptimizationList is automatically populated with registered Passes by the
// PassNameParser.
//
static llvm::cl::list<const llvm::PassInfo*, bool, llvm::PassNameParser>
PassList(llvm::cl::desc("Optimizations available:"));

namespace mvm {
  llvm::FunctionPass* createInlineMallocPass();
}

void MvmModule::addCommandLinePasses(FunctionPassManager* PM) {
  addPass(PM, new TargetData(*MvmModule::TheTargetData));

  addPass(PM, createVerifierPass());        // Verify that input is correct

#ifdef WITH_MMTK
  addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code
  addPass(PM, createInlineMallocPass());
#endif
  
  // Create a new optimization pass for each one specified on the command line
  for (unsigned i = 0; i < PassList.size(); ++i) {
    // Check to see if -std-compile-opts was specified before this option.  If
    // so, handle it.
    if (StandardCompileOpts && 
        StandardCompileOpts.getPosition() < PassList.getPosition(i)) {
      if (!DisableOptimizations) AddStandardCompilePasses(PM);
      StandardCompileOpts = false;
    }
      
    const PassInfo *PassInf = PassList[i];
    Pass *P = 0;
    if (PassInf->getNormalCtor())
      P = PassInf->getNormalCtor()();
    else
      errs() << "cannot create pass: "
           << PassInf->getPassName() << "\n";
    if (P) {
        bool isModulePass = (P->getPassKind() == PT_Module);
        if (isModulePass) 
          errs() << "vmkit does not support module pass: "
             << PassInf->getPassName() << "\n";
        else addPass(PM, P);

    }
  }
    
  // If -std-compile-opts was specified at the end of the pass list, add them.
  if (StandardCompileOpts) {
    AddStandardCompilePasses(PM);
  }
  PM->doInitialization();
}

// We protect the creation of IR with the executionEngine lock because
// codegen'ing a function may also create IR objects.
void MvmModule::protectIR() {
  if (executionEngine) {
    protectEngine.lock();
  }
}

void MvmModule::unprotectIR() {
  if (executionEngine) {
    protectEngine.unlock();
  }
}


void MvmModule::copyDefinitions(Module* Dst, Module* Src) {
  Function* SF = Src->getFunction("gcmalloc");
  Function* DF = Dst->getFunction("gcmalloc");
  if (SF && DF && executionEngine && !SF->isDeclaration()) {
    void* ptr = executionEngine->getPointerToFunction(SF);
    executionEngine->updateGlobalMapping(DF, ptr);
  }
  
  SF = Src->getFunction("gcmallocUnresolved");
  DF = Dst->getFunction("gcmallocUnresolved");
  if (SF && DF && executionEngine && !SF->isDeclaration()) {
    void* ptr = executionEngine->getPointerToFunction(SF);
    executionEngine->updateGlobalMapping(DF, ptr);
  }
  
  SF = Src->getFunction("addFinalizationCandidate");
  DF = Dst->getFunction("addFinalizationCandidate");
  if (SF && DF && executionEngine && !SF->isDeclaration()) {
    void* ptr = executionEngine->getPointerToFunction(SF);
    executionEngine->updateGlobalMapping(DF, ptr);
  }
}

void JITMethodInfo::scan(void* TL, void* ip, void* addr) {
  if (GCInfo) {
    DEBUG(llvm::errs() << GCInfo->getFunction().getName() << '\n');
    // All safe points have the same informations currently in LLVM.
    llvm::GCFunctionInfo::iterator J = GCInfo->begin();
    //uintptr_t spaddr = (uintptr_t)addr + GFI->getFrameSize() + sizeof(void*);
    uintptr_t spaddr = ((uintptr_t*)addr)[0];
    for (llvm::GCFunctionInfo::live_iterator K = GCInfo->live_begin(J),
         KE = GCInfo->live_end(J); K != KE; ++K) {
      intptr_t obj = *(intptr_t*)(spaddr + K->StackOffset);
      // Verify that obj does not come from a JSR bytecode.
      if (!(obj & 1)) Collector::scanObject((void**)(spaddr + K->StackOffset));
    }
  }
}

