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                                   CodeGenOpt::Level OptLevel,
     40                                   bool GVsWithCode,
     41                                   TargetMachine *TM) {
     42   // Try to register the program as a source of symbols to resolve against.
     43   //
     44   // FIXME: Don't do this here.
     45   sys::DynamicLibrary::LoadLibraryPermanently(0, NULL);
     46 
     47   // If the target supports JIT code generation, create the JIT.
     48   if (TargetJITInfo *TJ = TM->getJITInfo())
     49     return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM, M), OptLevel,
     50                      GVsWithCode);
     51 
     52   if (ErrorStr)
     53     *ErrorStr = "target does not support JIT code generation";
     54   return 0;
     55 }
     56 
     57 MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
     58              RTDyldMemoryManager *MM, CodeGenOpt::Level OptLevel,
     59              bool AllocateGVsWithCode)
     60   : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) {
     61 
     62   setTargetData(TM->getTargetData());
     63   PM.add(new TargetData(*TM->getTargetData()));
     64 
     65   // Turn the machine code intermediate representation into bytes in memory
     66   // that may be executed.
     67   if (TM->addPassesToEmitMC(PM, Ctx, OS, CodeGenOpt::Default, false)) {
     68     report_fatal_error("Target does not support MC emission!");
     69   }
     70 
     71   // Initialize passes.
     72   // FIXME: When we support multiple modules, we'll want to move the code
     73   // gen and finalization out of the constructor here and do it more
     74   // on-demand as part of getPointerToFunction().
     75   PM.run(*M);
     76   // Flush the output buffer so the SmallVector gets its data.
     77   OS.flush();
     78 
     79   // Load the object into the dynamic linker.
     80   // FIXME: It would be nice to avoid making yet another copy.
     81   MemoryBuffer *MB = MemoryBuffer::getMemBufferCopy(StringRef(Buffer.data(),
     82                                                               Buffer.size()));
     83   if (Dyld.loadObject(MB))
     84     report_fatal_error(Dyld.getErrorString());
     85   // Resolve any relocations.
     86   Dyld.resolveRelocations();
     87 }
     88 
     89 MCJIT::~MCJIT() {
     90   delete MemMgr;
     91 }
     92 
     93 void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
     94   report_fatal_error("not yet implemented");
     95   return 0;
     96 }
     97 
     98 void *MCJIT::getPointerToFunction(Function *F) {
     99   if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
    100     bool AbortOnFailure = !F->hasExternalWeakLinkage();
    101     void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
    102     addGlobalMapping(F, Addr);
    103     return Addr;
    104   }
    105 
    106   // FIXME: Should we be using the mangler for this? Probably.
    107   StringRef BaseName = F->getName();
    108   if (BaseName[0] == '\1')
    109     return (void*)Dyld.getSymbolAddress(BaseName.substr(1));
    110   return (void*)Dyld.getSymbolAddress((TM->getMCAsmInfo()->getGlobalPrefix()
    111                                        + BaseName).str());
    112 }
    113 
    114 void *MCJIT::recompileAndRelinkFunction(Function *F) {
    115   report_fatal_error("not yet implemented");
    116 }
    117 
    118 void MCJIT::freeMachineCodeForFunction(Function *F) {
    119   report_fatal_error("not yet implemented");
    120 }
    121 
    122 GenericValue MCJIT::runFunction(Function *F,
    123                                 const std::vector<GenericValue> &ArgValues) {
    124   assert(F && "Function *F was null at entry to run()");
    125 
    126   void *FPtr = getPointerToFunction(F);
    127   assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
    128   FunctionType *FTy = F->getFunctionType();
    129   Type *RetTy = FTy->getReturnType();
    130 
    131   assert((FTy->getNumParams() == ArgValues.size() ||
    132           (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
    133          "Wrong number of arguments passed into function!");
    134   assert(FTy->getNumParams() == ArgValues.size() &&
    135          "This doesn't support passing arguments through varargs (yet)!");
    136 
    137   // Handle some common cases first.  These cases correspond to common `main'
    138   // prototypes.
    139   if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
    140     switch (ArgValues.size()) {
    141     case 3:
    142       if (FTy->getParamType(0)->isIntegerTy(32) &&
    143           FTy->getParamType(1)->isPointerTy() &&
    144           FTy->getParamType(2)->isPointerTy()) {
    145         int (*PF)(int, char **, const char **) =
    146           (int(*)(int, char **, const char **))(intptr_t)FPtr;
    147 
    148         // Call the function.
    149         GenericValue rv;
    150         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
    151                                  (char **)GVTOP(ArgValues[1]),
    152                                  (const char **)GVTOP(ArgValues[2])));
    153         return rv;
    154       }
    155       break;
    156     case 2:
    157       if (FTy->getParamType(0)->isIntegerTy(32) &&
    158           FTy->getParamType(1)->isPointerTy()) {
    159         int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
    160 
    161         // Call the function.
    162         GenericValue rv;
    163         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
    164                                  (char **)GVTOP(ArgValues[1])));
    165         return rv;
    166       }
    167       break;
    168     case 1:
    169       if (FTy->getNumParams() == 1 &&
    170           FTy->getParamType(0)->isIntegerTy(32)) {
    171         GenericValue rv;
    172         int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
    173         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
    174         return rv;
    175       }
    176       break;
    177     }
    178   }
    179 
    180   // Handle cases where no arguments are passed first.
    181   if (ArgValues.empty()) {
    182     GenericValue rv;
    183     switch (RetTy->getTypeID()) {
    184     default: llvm_unreachable("Unknown return type for function call!");
    185     case Type::IntegerTyID: {
    186       unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
    187       if (BitWidth == 1)
    188         rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
    189       else if (BitWidth <= 8)
    190         rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
    191       else if (BitWidth <= 16)
    192         rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
    193       else if (BitWidth <= 32)
    194         rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
    195       else if (BitWidth <= 64)
    196         rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
    197       else
    198         llvm_unreachable("Integer types > 64 bits not supported");
    199       return rv;
    200     }
    201     case Type::VoidTyID:
    202       rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
    203       return rv;
    204     case Type::FloatTyID:
    205       rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
    206       return rv;
    207     case Type::DoubleTyID:
    208       rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
    209       return rv;
    210     case Type::X86_FP80TyID:
    211     case Type::FP128TyID:
    212     case Type::PPC_FP128TyID:
    213       llvm_unreachable("long double not supported yet");
    214       return rv;
    215     case Type::PointerTyID:
    216       return PTOGV(((void*(*)())(intptr_t)FPtr)());
    217     }
    218   }
    219 
    220   assert(0 && "Full-featured argument passing not supported yet!");
    221   return GenericValue();
    222 }
    223