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