Home | History | Annotate | Download | only in MCJIT
      1 //===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "MCJIT.h"
     11 #include "MCJITMemoryManager.h"
     12 #include "llvm/DerivedTypes.h"
     13 #include "llvm/Function.h"
     14 #include "llvm/ExecutionEngine/GenericValue.h"
     15 #include "llvm/ExecutionEngine/MCJIT.h"
     16 #include "llvm/ExecutionEngine/JITMemoryManager.h"
     17 #include "llvm/MC/MCAsmInfo.h"
     18 #include "llvm/Support/ErrorHandling.h"
     19 #include "llvm/Support/DynamicLibrary.h"
     20 #include "llvm/Support/MemoryBuffer.h"
     21 #include "llvm/Target/TargetData.h"
     22 
     23 using namespace llvm;
     24 
     25 namespace {
     26 
     27 static struct RegisterJIT {
     28   RegisterJIT() { MCJIT::Register(); }
     29 } JITRegistrator;
     30 
     31 }
     32 
     33 extern "C" void LLVMLinkInMCJIT() {
     34 }
     35 
     36 ExecutionEngine *MCJIT::createJIT(Module *M,
     37                                   std::string *ErrorStr,
     38                                   JITMemoryManager *JMM,
     39                                   bool GVsWithCode,
     40                                   TargetMachine *TM) {
     41   // Try to register the program as a source of symbols to resolve against.
     42   //
     43   // FIXME: Don't do this here.
     44   sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
     45 
     46   // If the target supports JIT code generation, create the JIT.
     47   if (TargetJITInfo *TJ = TM->getJITInfo())
     48     return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM, M), GVsWithCode);
     49 
     50   if (ErrorStr)
     51     *ErrorStr = "target does not support JIT code generation";
     52   return 0;
     53 }
     54 
     55 MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
     56              RTDyldMemoryManager *MM, bool AllocateGVsWithCode)
     57   : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) {
     58 
     59   setTargetData(TM->getTargetData());
     60   PM.add(new TargetData(*TM->getTargetData()));
     61 
     62   // Turn the machine code intermediate representation into bytes in memory
     63   // that may be executed.
     64   if (TM->addPassesToEmitMC(PM, Ctx, OS, false)) {
     65     report_fatal_error("Target does not support MC emission!");
     66   }
     67 
     68   // Initialize passes.
     69   // FIXME: When we support multiple modules, we'll want to move the code
     70   // gen and finalization out of the constructor here and do it more
     71   // on-demand as part of getPointerToFunction().
     72   PM.run(*M);
     73   // Flush the output buffer so the SmallVector gets its data.
     74   OS.flush();
     75 
     76   // Load the object into the dynamic linker.
     77   MemoryBuffer *MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(),
     78                                                           Buffer.size()),
     79                                                 "", false);
     80   if (Dyld.loadObject(MB))
     81     report_fatal_error(Dyld.getErrorString());
     82   // Resolve any relocations.
     83   Dyld.resolveRelocations();
     84 }
     85 
     86 MCJIT::~MCJIT() {
     87   delete MemMgr;
     88   delete TM;
     89 }
     90 
     91 void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
     92   report_fatal_error("not yet implemented");
     93 }
     94 
     95 void *MCJIT::getPointerToFunction(Function *F) {
     96   if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
     97     bool AbortOnFailure = !F->hasExternalWeakLinkage();
     98     void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
     99     addGlobalMapping(F, Addr);
    100     return Addr;
    101   }
    102 
    103   // FIXME: Should we be using the mangler for this? Probably.
    104   StringRef BaseName = F->getName();
    105   if (BaseName[0] == '\1')
    106     return (void*)Dyld.getSymbolAddress(BaseName.substr(1));
    107   return (void*)Dyld.getSymbolAddress((TM->getMCAsmInfo()->getGlobalPrefix()
    108                                        + BaseName).str());
    109 }
    110 
    111 void *MCJIT::recompileAndRelinkFunction(Function *F) {
    112   report_fatal_error("not yet implemented");
    113 }
    114 
    115 void MCJIT::freeMachineCodeForFunction(Function *F) {
    116   report_fatal_error("not yet implemented");
    117 }
    118 
    119 GenericValue MCJIT::runFunction(Function *F,
    120                                 const std::vector<GenericValue> &ArgValues) {
    121   assert(F && "Function *F was null at entry to run()");
    122 
    123   void *FPtr = getPointerToFunction(F);
    124   assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
    125   FunctionType *FTy = F->getFunctionType();
    126   Type *RetTy = FTy->getReturnType();
    127 
    128   assert((FTy->getNumParams() == ArgValues.size() ||
    129           (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
    130          "Wrong number of arguments passed into function!");
    131   assert(FTy->getNumParams() == ArgValues.size() &&
    132          "This doesn't support passing arguments through varargs (yet)!");
    133 
    134   // Handle some common cases first.  These cases correspond to common `main'
    135   // prototypes.
    136   if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
    137     switch (ArgValues.size()) {
    138     case 3:
    139       if (FTy->getParamType(0)->isIntegerTy(32) &&
    140           FTy->getParamType(1)->isPointerTy() &&
    141           FTy->getParamType(2)->isPointerTy()) {
    142         int (*PF)(int, char **, const char **) =
    143           (int(*)(int, char **, const char **))(intptr_t)FPtr;
    144 
    145         // Call the function.
    146         GenericValue rv;
    147         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
    148                                  (char **)GVTOP(ArgValues[1]),
    149                                  (const char **)GVTOP(ArgValues[2])));
    150         return rv;
    151       }
    152       break;
    153     case 2:
    154       if (FTy->getParamType(0)->isIntegerTy(32) &&
    155           FTy->getParamType(1)->isPointerTy()) {
    156         int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
    157 
    158         // Call the function.
    159         GenericValue rv;
    160         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
    161                                  (char **)GVTOP(ArgValues[1])));
    162         return rv;
    163       }
    164       break;
    165     case 1:
    166       if (FTy->getNumParams() == 1 &&
    167           FTy->getParamType(0)->isIntegerTy(32)) {
    168         GenericValue rv;
    169         int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
    170         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
    171         return rv;
    172       }
    173       break;
    174     }
    175   }
    176 
    177   // Handle cases where no arguments are passed first.
    178   if (ArgValues.empty()) {
    179     GenericValue rv;
    180     switch (RetTy->getTypeID()) {
    181     default: llvm_unreachable("Unknown return type for function call!");
    182     case Type::IntegerTyID: {
    183       unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
    184       if (BitWidth == 1)
    185         rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
    186       else if (BitWidth <= 8)
    187         rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
    188       else if (BitWidth <= 16)
    189         rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
    190       else if (BitWidth <= 32)
    191         rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
    192       else if (BitWidth <= 64)
    193         rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
    194       else
    195         llvm_unreachable("Integer types > 64 bits not supported");
    196       return rv;
    197     }
    198     case Type::VoidTyID:
    199       rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
    200       return rv;
    201     case Type::FloatTyID:
    202       rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
    203       return rv;
    204     case Type::DoubleTyID:
    205       rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
    206       return rv;
    207     case Type::X86_FP80TyID:
    208     case Type::FP128TyID:
    209     case Type::PPC_FP128TyID:
    210       llvm_unreachable("long double not supported yet");
    211     case Type::PointerTyID:
    212       return PTOGV(((void*(*)())(intptr_t)FPtr)());
    213     }
    214   }
    215 
    216   llvm_unreachable("Full-featured argument passing not supported yet!");
    217 }
    218 
    219 void *MCJIT::getPointerToNamedFunction(const std::string &Name,
    220                                        bool AbortOnFailure){
    221   if (!isSymbolSearchingDisabled() && MemMgr) {
    222     void *ptr = MemMgr->getPointerToNamedFunction(Name, false);
    223     if (ptr)
    224       return ptr;
    225   }
    226 
    227   /// If a LazyFunctionCreator is installed, use it to get/create the function.
    228   if (LazyFunctionCreator)
    229     if (void *RP = LazyFunctionCreator(Name))
    230       return RP;
    231 
    232   if (AbortOnFailure) {
    233     report_fatal_error("Program used external function '"+Name+
    234                       "' which could not be resolved!");
    235   }
    236   return 0;
    237 }
    238