diff options
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp')
| -rw-r--r-- | contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp | 830 | 
1 files changed, 830 insertions, 0 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp new file mode 100644 index 000000000000..63125b79c8e2 --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -0,0 +1,830 @@ +//===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tool implements a just-in-time compiler for LLVM, allowing direct +// execution of LLVM bitcode in an efficient manner. +// +//===----------------------------------------------------------------------===// + +#include "JIT.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Instructions.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/CodeGen/JITCodeEmitter.h" +#include "llvm/CodeGen/MachineCodeInfo.h" +#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/ExecutionEngine/JITEventListener.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetJITInfo.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MutexGuard.h" +#include "llvm/System/DynamicLibrary.h" +#include "llvm/Config/config.h" + +using namespace llvm; + +#ifdef __APPLE__  +// Apple gcc defaults to -fuse-cxa-atexit (i.e. calls __cxa_atexit instead +// of atexit). It passes the address of linker generated symbol __dso_handle +// to the function. +// This configuration change happened at version 5330. +# include <AvailabilityMacros.h> +# if defined(MAC_OS_X_VERSION_10_4) && \ +     ((MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4) || \ +      (MAC_OS_X_VERSION_MIN_REQUIRED == MAC_OS_X_VERSION_10_4 && \ +       __APPLE_CC__ >= 5330)) +#  ifndef HAVE___DSO_HANDLE +#   define HAVE___DSO_HANDLE 1 +#  endif +# endif +#endif + +#if HAVE___DSO_HANDLE +extern void *__dso_handle __attribute__ ((__visibility__ ("hidden"))); +#endif + +namespace { + +static struct RegisterJIT { +  RegisterJIT() { JIT::Register(); } +} JITRegistrator; + +} + +extern "C" void LLVMLinkInJIT() { +} + + +#if defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__USING_SJLJ_EXCEPTIONS__) +  +// libgcc defines the __register_frame function to dynamically register new +// dwarf frames for exception handling. This functionality is not portable +// across compilers and is only provided by GCC. We use the __register_frame +// function here so that code generated by the JIT cooperates with the unwinding +// runtime of libgcc. When JITting with exception handling enable, LLVM +// generates dwarf frames and registers it to libgcc with __register_frame. +// +// The __register_frame function works with Linux. +// +// Unfortunately, this functionality seems to be in libgcc after the unwinding +// library of libgcc for darwin was written. The code for darwin overwrites the +// value updated by __register_frame with a value fetched with "keymgr". +// "keymgr" is an obsolete functionality, which should be rewritten some day. +// In the meantime, since "keymgr" is on all libgccs shipped with apple-gcc, we +// need a workaround in LLVM which uses the "keymgr" to dynamically modify the +// values of an opaque key, used by libgcc to find dwarf tables. + +extern "C" void __register_frame(void*); + +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050 +# define USE_KEYMGR 1 +#else +# define USE_KEYMGR 0 +#endif + +#if USE_KEYMGR + +namespace { + +// LibgccObject - This is the structure defined in libgcc. There is no #include +// provided for this structure, so we also define it here. libgcc calls it +// "struct object". The structure is undocumented in libgcc. +struct LibgccObject { +  void *unused1; +  void *unused2; +  void *unused3; +   +  /// frame - Pointer to the exception table. +  void *frame; +   +  /// encoding -  The encoding of the object? +  union { +    struct { +      unsigned long sorted : 1; +      unsigned long from_array : 1; +      unsigned long mixed_encoding : 1; +      unsigned long encoding : 8; +      unsigned long count : 21;  +    } b; +    size_t i; +  } encoding; +   +  /// fde_end - libgcc defines this field only if some macro is defined. We +  /// include this field even if it may not there, to make libgcc happy. +  char *fde_end; +   +  /// next - At least we know it's a chained list! +  struct LibgccObject *next; +}; + +// "kemgr" stuff. Apparently, all frame tables are stored there. +extern "C" void _keymgr_set_and_unlock_processwide_ptr(int, void *); +extern "C" void *_keymgr_get_and_lock_processwide_ptr(int); +#define KEYMGR_GCC3_DW2_OBJ_LIST        302     /* Dwarf2 object list  */ + +/// LibgccObjectInfo - libgcc defines this struct as km_object_info. It +/// probably contains all dwarf tables that are loaded. +struct LibgccObjectInfo { + +  /// seenObjects - LibgccObjects already parsed by the unwinding runtime. +  /// +  struct LibgccObject* seenObjects; + +  /// unseenObjects - LibgccObjects not parsed yet by the unwinding runtime. +  /// +  struct LibgccObject* unseenObjects; +   +  unsigned unused[2]; +}; + +/// darwin_register_frame - Since __register_frame does not work with darwin's +/// libgcc,we provide our own function, which "tricks" libgcc by modifying the +/// "Dwarf2 object list" key. +void DarwinRegisterFrame(void* FrameBegin) { +  // Get the key. +  LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) +    _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); +  assert(LOI && "This should be preallocated by the runtime"); +   +  // Allocate a new LibgccObject to represent this frame. Deallocation of this +  // object may be impossible: since darwin code in libgcc was written after +  // the ability to dynamically register frames, things may crash if we +  // deallocate it. +  struct LibgccObject* ob = (struct LibgccObject*) +    malloc(sizeof(struct LibgccObject)); +   +  // Do like libgcc for the values of the field. +  ob->unused1 = (void *)-1; +  ob->unused2 = 0; +  ob->unused3 = 0; +  ob->frame = FrameBegin; +  ob->encoding.i = 0;  +  ob->encoding.b.encoding = llvm::dwarf::DW_EH_PE_omit; +   +  // Put the info on both places, as libgcc uses the first or the second +  // field. Note that we rely on having two pointers here. If fde_end was a +  // char, things would get complicated. +  ob->fde_end = (char*)LOI->unseenObjects; +  ob->next = LOI->unseenObjects; +   +  // Update the key's unseenObjects list. +  LOI->unseenObjects = ob; +   +  // Finally update the "key". Apparently, libgcc requires it.  +  _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, +                                         LOI); + +} + +} +#endif // __APPLE__ +#endif // __GNUC__ + +/// createJIT - This is the factory method for creating a JIT for the current +/// machine, it does not fall back to the interpreter.  This takes ownership +/// of the module. +ExecutionEngine *ExecutionEngine::createJIT(Module *M, +                                            std::string *ErrorStr, +                                            JITMemoryManager *JMM, +                                            CodeGenOpt::Level OptLevel, +                                            bool GVsWithCode, +                                            CodeModel::Model CMM) { +  // Use the defaults for extra parameters.  Users can use EngineBuilder to +  // set them. +  StringRef MArch = ""; +  StringRef MCPU = ""; +  SmallVector<std::string, 1> MAttrs; +  return JIT::createJIT(M, ErrorStr, JMM, OptLevel, GVsWithCode, CMM, +                        MArch, MCPU, MAttrs); +} + +ExecutionEngine *JIT::createJIT(Module *M, +                                std::string *ErrorStr, +                                JITMemoryManager *JMM, +                                CodeGenOpt::Level OptLevel, +                                bool GVsWithCode, +                                CodeModel::Model CMM, +                                StringRef MArch, +                                StringRef MCPU, +                                const SmallVectorImpl<std::string>& MAttrs) { +  // Try to register the program as a source of symbols to resolve against. +  sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); + +  // Pick a target either via -march or by guessing the native arch. +  TargetMachine *TM = JIT::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr); +  if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0; +  TM->setCodeModel(CMM); + +  // If the target supports JIT code generation, create a the JIT. +  if (TargetJITInfo *TJ = TM->getJITInfo()) { +    return new JIT(M, *TM, *TJ, JMM, OptLevel, GVsWithCode); +  } else { +    if (ErrorStr) +      *ErrorStr = "target does not support JIT code generation"; +    return 0; +  } +} + +namespace { +/// This class supports the global getPointerToNamedFunction(), which allows +/// bugpoint or gdb users to search for a function by name without any context. +class JitPool { +  SmallPtrSet<JIT*, 1> JITs;  // Optimize for process containing just 1 JIT. +  mutable sys::Mutex Lock; +public: +  void Add(JIT *jit) { +    MutexGuard guard(Lock); +    JITs.insert(jit); +  } +  void Remove(JIT *jit) { +    MutexGuard guard(Lock); +    JITs.erase(jit); +  } +  void *getPointerToNamedFunction(const char *Name) const { +    MutexGuard guard(Lock); +    assert(JITs.size() != 0 && "No Jit registered"); +    //search function in every instance of JIT +    for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(), +           end = JITs.end(); +         Jit != end; ++Jit) { +      if (Function *F = (*Jit)->FindFunctionNamed(Name)) +        return (*Jit)->getPointerToFunction(F); +    } +    // The function is not available : fallback on the first created (will +    // search in symbol of the current program/library) +    return (*JITs.begin())->getPointerToNamedFunction(Name); +  } +}; +ManagedStatic<JitPool> AllJits; +} +extern "C" { +  // getPointerToNamedFunction - This function is used as a global wrapper to +  // JIT::getPointerToNamedFunction for the purpose of resolving symbols when +  // bugpoint is debugging the JIT. In that scenario, we are loading an .so and +  // need to resolve function(s) that are being mis-codegenerated, so we need to +  // resolve their addresses at runtime, and this is the way to do it. +  void *getPointerToNamedFunction(const char *Name) { +    return AllJits->getPointerToNamedFunction(Name); +  } +} + +JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, +         JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode) +  : ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode), +    isAlreadyCodeGenerating(false) { +  setTargetData(TM.getTargetData()); + +  jitstate = new JITState(M); + +  // Initialize JCE +  JCE = createEmitter(*this, JMM, TM); + +  // Register in global list of all JITs. +  AllJits->Add(this); + +  // Add target data +  MutexGuard locked(lock); +  FunctionPassManager &PM = jitstate->getPM(locked); +  PM.add(new TargetData(*TM.getTargetData())); + +  // Turn the machine code intermediate representation into bytes in memory that +  // may be executed. +  if (TM.addPassesToEmitMachineCode(PM, *JCE, OptLevel)) { +    report_fatal_error("Target does not support machine code emission!"); +  } +   +  // Register routine for informing unwinding runtime about new EH frames +#if defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__USING_SJLJ_EXCEPTIONS__) +#if USE_KEYMGR +  struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) +    _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); +   +  // The key is created on demand, and libgcc creates it the first time an +  // exception occurs. Since we need the key to register frames, we create +  // it now. +  if (!LOI) +    LOI = (LibgccObjectInfo*)calloc(sizeof(struct LibgccObjectInfo), 1);  +  _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, LOI); +  InstallExceptionTableRegister(DarwinRegisterFrame); +#else +  InstallExceptionTableRegister(__register_frame); +#endif // __APPLE__ +#endif // __GNUC__ +   +  // Initialize passes. +  PM.doInitialization(); +} + +JIT::~JIT() { +  AllJits->Remove(this); +  delete jitstate; +  delete JCE; +  delete &TM; +} + +/// addModule - Add a new Module to the JIT.  If we previously removed the last +/// Module, we need re-initialize jitstate with a valid Module. +void JIT::addModule(Module *M) { +  MutexGuard locked(lock); + +  if (Modules.empty()) { +    assert(!jitstate && "jitstate should be NULL if Modules vector is empty!"); + +    jitstate = new JITState(M); + +    FunctionPassManager &PM = jitstate->getPM(locked); +    PM.add(new TargetData(*TM.getTargetData())); + +    // Turn the machine code intermediate representation into bytes in memory +    // that may be executed. +    if (TM.addPassesToEmitMachineCode(PM, *JCE, CodeGenOpt::Default)) { +      report_fatal_error("Target does not support machine code emission!"); +    } +     +    // Initialize passes. +    PM.doInitialization(); +  } +   +  ExecutionEngine::addModule(M); +} + +/// removeModule - If we are removing the last Module, invalidate the jitstate +/// since the PassManager it contains references a released Module. +bool JIT::removeModule(Module *M) { +  bool result = ExecutionEngine::removeModule(M); +   +  MutexGuard locked(lock); +   +  if (jitstate->getModule() == M) { +    delete jitstate; +    jitstate = 0; +  } +   +  if (!jitstate && !Modules.empty()) { +    jitstate = new JITState(Modules[0]); + +    FunctionPassManager &PM = jitstate->getPM(locked); +    PM.add(new TargetData(*TM.getTargetData())); +     +    // Turn the machine code intermediate representation into bytes in memory +    // that may be executed. +    if (TM.addPassesToEmitMachineCode(PM, *JCE, CodeGenOpt::Default)) { +      report_fatal_error("Target does not support machine code emission!"); +    } +     +    // Initialize passes. +    PM.doInitialization(); +  }     +  return result; +} + +/// run - Start execution with the specified function and arguments. +/// +GenericValue JIT::runFunction(Function *F, +                              const std::vector<GenericValue> &ArgValues) { +  assert(F && "Function *F was null at entry to run()"); + +  void *FPtr = getPointerToFunction(F); +  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); +  const FunctionType *FTy = F->getFunctionType(); +  const Type *RetTy = FTy->getReturnType(); + +  assert((FTy->getNumParams() == ArgValues.size() || +          (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && +         "Wrong number of arguments passed into function!"); +  assert(FTy->getNumParams() == ArgValues.size() && +         "This doesn't support passing arguments through varargs (yet)!"); + +  // Handle some common cases first.  These cases correspond to common `main' +  // prototypes. +  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { +    switch (ArgValues.size()) { +    case 3: +      if (FTy->getParamType(0)->isIntegerTy(32) && +          FTy->getParamType(1)->isPointerTy() && +          FTy->getParamType(2)->isPointerTy()) { +        int (*PF)(int, char **, const char **) = +          (int(*)(int, char **, const char **))(intptr_t)FPtr; + +        // Call the function. +        GenericValue rv; +        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),  +                                 (char **)GVTOP(ArgValues[1]), +                                 (const char **)GVTOP(ArgValues[2]))); +        return rv; +      } +      break; +    case 2: +      if (FTy->getParamType(0)->isIntegerTy(32) && +          FTy->getParamType(1)->isPointerTy()) { +        int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr; + +        // Call the function. +        GenericValue rv; +        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),  +                                 (char **)GVTOP(ArgValues[1]))); +        return rv; +      } +      break; +    case 1: +      if (FTy->getNumParams() == 1 && +          FTy->getParamType(0)->isIntegerTy(32)) { +        GenericValue rv; +        int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; +        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); +        return rv; +      } +      break; +    } +  } + +  // Handle cases where no arguments are passed first. +  if (ArgValues.empty()) { +    GenericValue rv; +    switch (RetTy->getTypeID()) { +    default: llvm_unreachable("Unknown return type for function call!"); +    case Type::IntegerTyID: { +      unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); +      if (BitWidth == 1) +        rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)()); +      else if (BitWidth <= 8) +        rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)()); +      else if (BitWidth <= 16) +        rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)()); +      else if (BitWidth <= 32) +        rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); +      else if (BitWidth <= 64) +        rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); +      else  +        llvm_unreachable("Integer types > 64 bits not supported"); +      return rv; +    } +    case Type::VoidTyID: +      rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); +      return rv; +    case Type::FloatTyID: +      rv.FloatVal = ((float(*)())(intptr_t)FPtr)(); +      return rv; +    case Type::DoubleTyID: +      rv.DoubleVal = ((double(*)())(intptr_t)FPtr)(); +      return rv; +    case Type::X86_FP80TyID: +    case Type::FP128TyID: +    case Type::PPC_FP128TyID: +      llvm_unreachable("long double not supported yet"); +      return rv; +    case Type::PointerTyID: +      return PTOGV(((void*(*)())(intptr_t)FPtr)()); +    } +  } + +  // Okay, this is not one of our quick and easy cases.  Because we don't have a +  // full FFI, we have to codegen a nullary stub function that just calls the +  // function we are interested in, passing in constants for all of the +  // arguments.  Make this function and return. + +  // First, create the function. +  FunctionType *STy=FunctionType::get(RetTy, false); +  Function *Stub = Function::Create(STy, Function::InternalLinkage, "", +                                    F->getParent()); + +  // Insert a basic block. +  BasicBlock *StubBB = BasicBlock::Create(F->getContext(), "", Stub); + +  // Convert all of the GenericValue arguments over to constants.  Note that we +  // currently don't support varargs. +  SmallVector<Value*, 8> Args; +  for (unsigned i = 0, e = ArgValues.size(); i != e; ++i) { +    Constant *C = 0; +    const Type *ArgTy = FTy->getParamType(i); +    const GenericValue &AV = ArgValues[i]; +    switch (ArgTy->getTypeID()) { +    default: llvm_unreachable("Unknown argument type for function call!"); +    case Type::IntegerTyID: +        C = ConstantInt::get(F->getContext(), AV.IntVal); +        break; +    case Type::FloatTyID: +        C = ConstantFP::get(F->getContext(), APFloat(AV.FloatVal)); +        break; +    case Type::DoubleTyID: +        C = ConstantFP::get(F->getContext(), APFloat(AV.DoubleVal)); +        break; +    case Type::PPC_FP128TyID: +    case Type::X86_FP80TyID: +    case Type::FP128TyID: +        C = ConstantFP::get(F->getContext(), APFloat(AV.IntVal)); +        break; +    case Type::PointerTyID: +      void *ArgPtr = GVTOP(AV); +      if (sizeof(void*) == 4) +        C = ConstantInt::get(Type::getInt32Ty(F->getContext()),  +                             (int)(intptr_t)ArgPtr); +      else +        C = ConstantInt::get(Type::getInt64Ty(F->getContext()), +                             (intptr_t)ArgPtr); +      // Cast the integer to pointer +      C = ConstantExpr::getIntToPtr(C, ArgTy); +      break; +    } +    Args.push_back(C); +  } + +  CallInst *TheCall = CallInst::Create(F, Args.begin(), Args.end(), +                                       "", StubBB); +  TheCall->setCallingConv(F->getCallingConv()); +  TheCall->setTailCall(); +  if (!TheCall->getType()->isVoidTy()) +    // Return result of the call. +    ReturnInst::Create(F->getContext(), TheCall, StubBB); +  else +    ReturnInst::Create(F->getContext(), StubBB);           // Just return void. + +  // Finally, call our nullary stub function. +  GenericValue Result = runFunction(Stub, std::vector<GenericValue>()); +  // Erase it, since no other function can have a reference to it. +  Stub->eraseFromParent(); +  // And return the result. +  return Result; +} + +void JIT::RegisterJITEventListener(JITEventListener *L) { +  if (L == NULL) +    return; +  MutexGuard locked(lock); +  EventListeners.push_back(L); +} +void JIT::UnregisterJITEventListener(JITEventListener *L) { +  if (L == NULL) +    return; +  MutexGuard locked(lock); +  std::vector<JITEventListener*>::reverse_iterator I= +      std::find(EventListeners.rbegin(), EventListeners.rend(), L); +  if (I != EventListeners.rend()) { +    std::swap(*I, EventListeners.back()); +    EventListeners.pop_back(); +  } +} +void JIT::NotifyFunctionEmitted( +    const Function &F, +    void *Code, size_t Size, +    const JITEvent_EmittedFunctionDetails &Details) { +  MutexGuard locked(lock); +  for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { +    EventListeners[I]->NotifyFunctionEmitted(F, Code, Size, Details); +  } +} + +void JIT::NotifyFreeingMachineCode(void *OldPtr) { +  MutexGuard locked(lock); +  for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { +    EventListeners[I]->NotifyFreeingMachineCode(OldPtr); +  } +} + +/// runJITOnFunction - Run the FunctionPassManager full of +/// just-in-time compilation passes on F, hopefully filling in +/// GlobalAddress[F] with the address of F's machine code. +/// +void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) { +  MutexGuard locked(lock); + +  class MCIListener : public JITEventListener { +    MachineCodeInfo *const MCI; +   public: +    MCIListener(MachineCodeInfo *mci) : MCI(mci) {} +    virtual void NotifyFunctionEmitted(const Function &, +                                       void *Code, size_t Size, +                                       const EmittedFunctionDetails &) { +      MCI->setAddress(Code); +      MCI->setSize(Size); +    } +  }; +  MCIListener MCIL(MCI); +  if (MCI) +    RegisterJITEventListener(&MCIL); + +  runJITOnFunctionUnlocked(F, locked); + +  if (MCI) +    UnregisterJITEventListener(&MCIL); +} + +void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { +  assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!"); + +  jitTheFunction(F, locked); + +  // If the function referred to another function that had not yet been +  // read from bitcode, and we are jitting non-lazily, emit it now. +  while (!jitstate->getPendingFunctions(locked).empty()) { +    Function *PF = jitstate->getPendingFunctions(locked).back(); +    jitstate->getPendingFunctions(locked).pop_back(); + +    assert(!PF->hasAvailableExternallyLinkage() && +           "Externally-defined function should not be in pending list."); + +    jitTheFunction(PF, locked); +     +    // Now that the function has been jitted, ask the JITEmitter to rewrite +    // the stub with real address of the function. +    updateFunctionStub(PF); +  } +} + +void JIT::jitTheFunction(Function *F, const MutexGuard &locked) { +  isAlreadyCodeGenerating = true; +  jitstate->getPM(locked).run(*F); +  isAlreadyCodeGenerating = false; + +  // clear basic block addresses after this function is done +  getBasicBlockAddressMap(locked).clear(); +} + +/// getPointerToFunction - This method is used to get the address of the +/// specified function, compiling it if neccesary. +/// +void *JIT::getPointerToFunction(Function *F) { + +  if (void *Addr = getPointerToGlobalIfAvailable(F)) +    return Addr;   // Check if function already code gen'd + +  MutexGuard locked(lock); + +  // Now that this thread owns the lock, make sure we read in the function if it +  // exists in this Module. +  std::string ErrorMsg; +  if (F->Materialize(&ErrorMsg)) { +    report_fatal_error("Error reading function '" + F->getName()+ +                      "' from bitcode file: " + ErrorMsg); +  } + +  // ... and check if another thread has already code gen'd the function. +  if (void *Addr = getPointerToGlobalIfAvailable(F)) +    return Addr; + +  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { +    bool AbortOnFailure = !F->hasExternalWeakLinkage(); +    void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); +    addGlobalMapping(F, Addr); +    return Addr; +  } + +  runJITOnFunctionUnlocked(F, locked); + +  void *Addr = getPointerToGlobalIfAvailable(F); +  assert(Addr && "Code generation didn't add function to GlobalAddress table!"); +  return Addr; +} + +void JIT::addPointerToBasicBlock(const BasicBlock *BB, void *Addr) { +  MutexGuard locked(lock); +   +  BasicBlockAddressMapTy::iterator I = +    getBasicBlockAddressMap(locked).find(BB); +  if (I == getBasicBlockAddressMap(locked).end()) { +    getBasicBlockAddressMap(locked)[BB] = Addr; +  } else { +    // ignore repeats: some BBs can be split into few MBBs? +  } +} + +void JIT::clearPointerToBasicBlock(const BasicBlock *BB) { +  MutexGuard locked(lock); +  getBasicBlockAddressMap(locked).erase(BB); +} + +void *JIT::getPointerToBasicBlock(BasicBlock *BB) { +  // make sure it's function is compiled by JIT +  (void)getPointerToFunction(BB->getParent()); + +  // resolve basic block address +  MutexGuard locked(lock); +   +  BasicBlockAddressMapTy::iterator I = +    getBasicBlockAddressMap(locked).find(BB); +  if (I != getBasicBlockAddressMap(locked).end()) { +    return I->second; +  } else { +    assert(0 && "JIT does not have BB address for address-of-label, was" +           " it eliminated by optimizer?"); +    return 0; +  } +} + +/// getOrEmitGlobalVariable - Return the address of the specified global +/// variable, possibly emitting it to memory if needed.  This is used by the +/// Emitter. +void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) { +  MutexGuard locked(lock); + +  void *Ptr = getPointerToGlobalIfAvailable(GV); +  if (Ptr) return Ptr; + +  // If the global is external, just remember the address. +  if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { +#if HAVE___DSO_HANDLE +    if (GV->getName() == "__dso_handle") +      return (void*)&__dso_handle; +#endif +    Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(GV->getName()); +    if (Ptr == 0) { +      report_fatal_error("Could not resolve external global address: " +                        +GV->getName()); +    } +    addGlobalMapping(GV, Ptr); +  } else { +    // If the global hasn't been emitted to memory yet, allocate space and +    // emit it into memory. +    Ptr = getMemoryForGV(GV); +    addGlobalMapping(GV, Ptr); +    EmitGlobalVariable(GV);  // Initialize the variable. +  } +  return Ptr; +} + +/// recompileAndRelinkFunction - This method is used to force a function +/// which has already been compiled, to be compiled again, possibly +/// after it has been modified. Then the entry to the old copy is overwritten +/// with a branch to the new copy. If there was no old copy, this acts +/// just like JIT::getPointerToFunction(). +/// +void *JIT::recompileAndRelinkFunction(Function *F) { +  void *OldAddr = getPointerToGlobalIfAvailable(F); + +  // If it's not already compiled there is no reason to patch it up. +  if (OldAddr == 0) { return getPointerToFunction(F); } + +  // Delete the old function mapping. +  addGlobalMapping(F, 0); + +  // Recodegen the function +  runJITOnFunction(F); + +  // Update state, forward the old function to the new function. +  void *Addr = getPointerToGlobalIfAvailable(F); +  assert(Addr && "Code generation didn't add function to GlobalAddress table!"); +  TJI.replaceMachineCodeForFunction(OldAddr, Addr); +  return Addr; +} + +/// getMemoryForGV - This method abstracts memory allocation of global +/// variable so that the JIT can allocate thread local variables depending +/// on the target. +/// +char* JIT::getMemoryForGV(const GlobalVariable* GV) { +  char *Ptr; + +  // GlobalVariable's which are not "constant" will cause trouble in a server +  // situation. It's returned in the same block of memory as code which may +  // not be writable. +  if (isGVCompilationDisabled() && !GV->isConstant()) { +    report_fatal_error("Compilation of non-internal GlobalValue is disabled!"); +  } + +  // Some applications require globals and code to live together, so they may +  // be allocated into the same buffer, but in general globals are allocated +  // through the memory manager which puts them near the code but not in the +  // same buffer. +  const Type *GlobalType = GV->getType()->getElementType(); +  size_t S = getTargetData()->getTypeAllocSize(GlobalType); +  size_t A = getTargetData()->getPreferredAlignment(GV); +  if (GV->isThreadLocal()) { +    MutexGuard locked(lock); +    Ptr = TJI.allocateThreadLocalMemory(S); +  } else if (TJI.allocateSeparateGVMemory()) { +    if (A <= 8) { +      Ptr = (char*)malloc(S); +    } else { +      // Allocate S+A bytes of memory, then use an aligned pointer within that +      // space. +      Ptr = (char*)malloc(S+A); +      unsigned MisAligned = ((intptr_t)Ptr & (A-1)); +      Ptr = Ptr + (MisAligned ? (A-MisAligned) : 0); +    } +  } else if (AllocateGVsWithCode) { +    Ptr = (char*)JCE->allocateSpace(S, A); +  } else { +    Ptr = (char*)JCE->allocateGlobal(S, A); +  } +  return Ptr; +} + +void JIT::addPendingFunction(Function *F) { +  MutexGuard locked(lock); +  jitstate->getPendingFunctions(locked).push_back(F); +} + + +JITEventListener::~JITEventListener() {}  | 
