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 "llvm/ExecutionEngine/GenericValue.h" 12 #include "llvm/ExecutionEngine/JITEventListener.h" 13 #include "llvm/ExecutionEngine/JITMemoryManager.h" 14 #include "llvm/ExecutionEngine/MCJIT.h" 15 #include "llvm/ExecutionEngine/ObjectBuffer.h" 16 #include "llvm/ExecutionEngine/ObjectImage.h" 17 #include "llvm/IR/DataLayout.h" 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/Function.h" 20 #include "llvm/MC/MCAsmInfo.h" 21 #include "llvm/Support/DynamicLibrary.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Support/MutexGuard.h" 25 26 using namespace llvm; 27 28 namespace { 29 30 static struct RegisterJIT { 31 RegisterJIT() { MCJIT::Register(); } 32 } JITRegistrator; 33 34 } 35 36 extern "C" void LLVMLinkInMCJIT() { 37 } 38 39 ExecutionEngine *MCJIT::createJIT(Module *M, 40 std::string *ErrorStr, 41 JITMemoryManager *JMM, 42 bool GVsWithCode, 43 TargetMachine *TM) { 44 // Try to register the program as a source of symbols to resolve against. 45 // 46 // FIXME: Don't do this here. 47 sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); 48 49 return new MCJIT(M, TM, JMM, GVsWithCode); 50 } 51 52 MCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM, 53 bool AllocateGVsWithCode) 54 : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM), 55 isCompiled(false), M(m) { 56 57 setDataLayout(TM->getDataLayout()); 58 } 59 60 MCJIT::~MCJIT() { 61 if (LoadedObject) 62 NotifyFreeingObject(*LoadedObject.get()); 63 delete MemMgr; 64 delete TM; 65 } 66 67 void MCJIT::emitObject(Module *m) { 68 /// Currently, MCJIT only supports a single module and the module passed to 69 /// this function call is expected to be the contained module. The module 70 /// is passed as a parameter here to prepare for multiple module support in 71 /// the future. 72 assert(M == m); 73 74 // Get a thread lock to make sure we aren't trying to compile multiple times 75 MutexGuard locked(lock); 76 77 // FIXME: Track compilation state on a per-module basis when multiple modules 78 // are supported. 79 // Re-compilation is not supported 80 if (isCompiled) 81 return; 82 83 PassManager PM; 84 85 PM.add(new DataLayout(*TM->getDataLayout())); 86 87 // The RuntimeDyld will take ownership of this shortly 88 OwningPtr<ObjectBufferStream> Buffer(new ObjectBufferStream()); 89 90 // Turn the machine code intermediate representation into bytes in memory 91 // that may be executed. 92 if (TM->addPassesToEmitMC(PM, Ctx, Buffer->getOStream(), false)) { 93 report_fatal_error("Target does not support MC emission!"); 94 } 95 96 // Initialize passes. 97 PM.run(*m); 98 // Flush the output buffer to get the generated code into memory 99 Buffer->flush(); 100 101 // Load the object into the dynamic linker. 102 // handing off ownership of the buffer 103 LoadedObject.reset(Dyld.loadObject(Buffer.take())); 104 if (!LoadedObject) 105 report_fatal_error(Dyld.getErrorString()); 106 107 // Resolve any relocations. 108 Dyld.resolveRelocations(); 109 110 // FIXME: Make this optional, maybe even move it to a JIT event listener 111 LoadedObject->registerWithDebugger(); 112 113 NotifyObjectEmitted(*LoadedObject); 114 115 // FIXME: Add support for per-module compilation state 116 isCompiled = true; 117 } 118 119 // FIXME: Add a parameter to identify which object is being finalized when 120 // MCJIT supports multiple modules. 121 // FIXME: Provide a way to separate code emission, relocations and page 122 // protection in the interface. 123 void MCJIT::finalizeObject() { 124 // If the module hasn't been compiled, just do that. 125 if (!isCompiled) { 126 // If the call to Dyld.resolveRelocations() is removed from emitObject() 127 // we'll need to do that here. 128 emitObject(M); 129 130 // Set page permissions. 131 MemMgr->applyPermissions(); 132 133 return; 134 } 135 136 // Resolve any relocations. 137 Dyld.resolveRelocations(); 138 139 // Set page permissions. 140 MemMgr->applyPermissions(); 141 } 142 143 void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { 144 report_fatal_error("not yet implemented"); 145 } 146 147 void *MCJIT::getPointerToFunction(Function *F) { 148 // FIXME: This should really return a uint64_t since it's a pointer in the 149 // target address space, not our local address space. That's part of the 150 // ExecutionEngine interface, though. Fix that when the old JIT finally 151 // dies. 152 153 // FIXME: Add support for per-module compilation state 154 if (!isCompiled) 155 emitObject(M); 156 157 if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { 158 bool AbortOnFailure = !F->hasExternalWeakLinkage(); 159 void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); 160 addGlobalMapping(F, Addr); 161 return Addr; 162 } 163 164 // FIXME: Should the Dyld be retaining module information? Probably not. 165 // FIXME: Should we be using the mangler for this? Probably. 166 // 167 // This is the accessor for the target address, so make sure to check the 168 // load address of the symbol, not the local address. 169 StringRef BaseName = F->getName(); 170 if (BaseName[0] == '\1') 171 return (void*)Dyld.getSymbolLoadAddress(BaseName.substr(1)); 172 return (void*)Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() 173 + BaseName).str()); 174 } 175 176 void *MCJIT::recompileAndRelinkFunction(Function *F) { 177 report_fatal_error("not yet implemented"); 178 } 179 180 void MCJIT::freeMachineCodeForFunction(Function *F) { 181 report_fatal_error("not yet implemented"); 182 } 183 184 GenericValue MCJIT::runFunction(Function *F, 185 const std::vector<GenericValue> &ArgValues) { 186 assert(F && "Function *F was null at entry to run()"); 187 188 void *FPtr = getPointerToFunction(F); 189 assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); 190 FunctionType *FTy = F->getFunctionType(); 191 Type *RetTy = FTy->getReturnType(); 192 193 assert((FTy->getNumParams() == ArgValues.size() || 194 (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && 195 "Wrong number of arguments passed into function!"); 196 assert(FTy->getNumParams() == ArgValues.size() && 197 "This doesn't support passing arguments through varargs (yet)!"); 198 199 // Handle some common cases first. These cases correspond to common `main' 200 // prototypes. 201 if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { 202 switch (ArgValues.size()) { 203 case 3: 204 if (FTy->getParamType(0)->isIntegerTy(32) && 205 FTy->getParamType(1)->isPointerTy() && 206 FTy->getParamType(2)->isPointerTy()) { 207 int (*PF)(int, char **, const char **) = 208 (int(*)(int, char **, const char **))(intptr_t)FPtr; 209 210 // Call the function. 211 GenericValue rv; 212 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 213 (char **)GVTOP(ArgValues[1]), 214 (const char **)GVTOP(ArgValues[2]))); 215 return rv; 216 } 217 break; 218 case 2: 219 if (FTy->getParamType(0)->isIntegerTy(32) && 220 FTy->getParamType(1)->isPointerTy()) { 221 int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr; 222 223 // Call the function. 224 GenericValue rv; 225 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 226 (char **)GVTOP(ArgValues[1]))); 227 return rv; 228 } 229 break; 230 case 1: 231 if (FTy->getNumParams() == 1 && 232 FTy->getParamType(0)->isIntegerTy(32)) { 233 GenericValue rv; 234 int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; 235 rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); 236 return rv; 237 } 238 break; 239 } 240 } 241 242 // Handle cases where no arguments are passed first. 243 if (ArgValues.empty()) { 244 GenericValue rv; 245 switch (RetTy->getTypeID()) { 246 default: llvm_unreachable("Unknown return type for function call!"); 247 case Type::IntegerTyID: { 248 unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); 249 if (BitWidth == 1) 250 rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)()); 251 else if (BitWidth <= 8) 252 rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)()); 253 else if (BitWidth <= 16) 254 rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)()); 255 else if (BitWidth <= 32) 256 rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); 257 else if (BitWidth <= 64) 258 rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); 259 else 260 llvm_unreachable("Integer types > 64 bits not supported"); 261 return rv; 262 } 263 case Type::VoidTyID: 264 rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); 265 return rv; 266 case Type::FloatTyID: 267 rv.FloatVal = ((float(*)())(intptr_t)FPtr)(); 268 return rv; 269 case Type::DoubleTyID: 270 rv.DoubleVal = ((double(*)())(intptr_t)FPtr)(); 271 return rv; 272 case Type::X86_FP80TyID: 273 case Type::FP128TyID: 274 case Type::PPC_FP128TyID: 275 llvm_unreachable("long double not supported yet"); 276 case Type::PointerTyID: 277 return PTOGV(((void*(*)())(intptr_t)FPtr)()); 278 } 279 } 280 281 llvm_unreachable("Full-featured argument passing not supported yet!"); 282 } 283 284 void *MCJIT::getPointerToNamedFunction(const std::string &Name, 285 bool AbortOnFailure) { 286 // FIXME: Add support for per-module compilation state 287 if (!isCompiled) 288 emitObject(M); 289 290 if (!isSymbolSearchingDisabled() && MemMgr) { 291 void *ptr = MemMgr->getPointerToNamedFunction(Name, false); 292 if (ptr) 293 return ptr; 294 } 295 296 /// If a LazyFunctionCreator is installed, use it to get/create the function. 297 if (LazyFunctionCreator) 298 if (void *RP = LazyFunctionCreator(Name)) 299 return RP; 300 301 if (AbortOnFailure) { 302 report_fatal_error("Program used external function '"+Name+ 303 "' which could not be resolved!"); 304 } 305 return 0; 306 } 307 308 void MCJIT::RegisterJITEventListener(JITEventListener *L) { 309 if (L == NULL) 310 return; 311 MutexGuard locked(lock); 312 EventListeners.push_back(L); 313 } 314 void MCJIT::UnregisterJITEventListener(JITEventListener *L) { 315 if (L == NULL) 316 return; 317 MutexGuard locked(lock); 318 SmallVector<JITEventListener*, 2>::reverse_iterator I= 319 std::find(EventListeners.rbegin(), EventListeners.rend(), L); 320 if (I != EventListeners.rend()) { 321 std::swap(*I, EventListeners.back()); 322 EventListeners.pop_back(); 323 } 324 } 325 void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { 326 MutexGuard locked(lock); 327 for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 328 EventListeners[I]->NotifyObjectEmitted(Obj); 329 } 330 } 331 void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { 332 MutexGuard locked(lock); 333 for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 334 EventListeners[I]->NotifyFreeingObject(Obj); 335 } 336 } 337