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