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 23using namespace llvm; 24 25namespace { 26 27static struct RegisterJIT { 28 RegisterJIT() { MCJIT::Register(); } 29} JITRegistrator; 30 31} 32 33extern "C" void LLVMLinkInMCJIT() { 34} 35 36ExecutionEngine *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 55MCJIT::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 86MCJIT::~MCJIT() { 87 delete MemMgr; 88 delete TM; 89} 90 91void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { 92 report_fatal_error("not yet implemented"); 93} 94 95void *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 111void *MCJIT::recompileAndRelinkFunction(Function *F) { 112 report_fatal_error("not yet implemented"); 113} 114 115void MCJIT::freeMachineCodeForFunction(Function *F) { 116 report_fatal_error("not yet implemented"); 117} 118 119GenericValue 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 219void *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