MCJIT.cpp revision 53608a34ce3f0969e9fb01eaa983422761011e03
1bb498ca5c2acb7567d8d4d84b00229bed6f501b1Eric Christopher//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===// 26aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// 36aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// The LLVM Compiler Infrastructure 46aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// 56aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// This file is distributed under the University of Illinois Open Source 66aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// License. See LICENSE.TXT for details. 76aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// 86aec29848676494867e26307698155bc2c5a4033Daniel Dunbar//===----------------------------------------------------------------------===// 96aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 106aec29848676494867e26307698155bc2c5a4033Daniel Dunbar#include "MCJIT.h" 1134714a06096f854c76371295d8c20b017fbba50bJim Grosbach#include "llvm/DerivedTypes.h" 1231649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach#include "llvm/Function.h" 136aec29848676494867e26307698155bc2c5a4033Daniel Dunbar#include "llvm/ExecutionEngine/GenericValue.h" 14776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor#include "llvm/ExecutionEngine/JITEventListener.h" 15f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/ExecutionEngine/JITMemoryManager.h" 163f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/MCJIT.h" 173f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/ObjectBuffer.h" 183f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/ObjectImage.h" 19f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/MC/MCAsmInfo.h" 206aec29848676494867e26307698155bc2c5a4033Daniel Dunbar#include "llvm/Support/ErrorHandling.h" 211f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DynamicLibrary.h" 22f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/Support/MemoryBuffer.h" 23ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor#include "llvm/Support/MutexGuard.h" 243574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow#include "llvm/DataLayout.h" 256aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 266aec29848676494867e26307698155bc2c5a4033Daniel Dunbarusing namespace llvm; 276aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 286aec29848676494867e26307698155bc2c5a4033Daniel Dunbarnamespace { 296aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 306aec29848676494867e26307698155bc2c5a4033Daniel Dunbarstatic struct RegisterJIT { 316aec29848676494867e26307698155bc2c5a4033Daniel Dunbar RegisterJIT() { MCJIT::Register(); } 326aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} JITRegistrator; 336aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 346aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 356aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 366aec29848676494867e26307698155bc2c5a4033Daniel Dunbarextern "C" void LLVMLinkInMCJIT() { 376aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 386aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 396aec29848676494867e26307698155bc2c5a4033Daniel DunbarExecutionEngine *MCJIT::createJIT(Module *M, 406aec29848676494867e26307698155bc2c5a4033Daniel Dunbar std::string *ErrorStr, 416aec29848676494867e26307698155bc2c5a4033Daniel Dunbar JITMemoryManager *JMM, 426aec29848676494867e26307698155bc2c5a4033Daniel Dunbar bool GVsWithCode, 43c5b28580a94e247300e5d3ccf532e153f2ae6f12Dylan Noblesmith TargetMachine *TM) { 446aec29848676494867e26307698155bc2c5a4033Daniel Dunbar // Try to register the program as a source of symbols to resolve against. 456aec29848676494867e26307698155bc2c5a4033Daniel Dunbar // 466aec29848676494867e26307698155bc2c5a4033Daniel Dunbar // FIXME: Don't do this here. 476aec29848676494867e26307698155bc2c5a4033Daniel Dunbar sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); 486aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 49647d6d7d3b6bfc8d99b8425cff50f979dbbd2ab6Andrew Kaylor return new MCJIT(M, TM, JMM, GVsWithCode); 506aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 516aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 528005bcd5e0c923881d82afcb813a7e537cd1b241Jim GrosbachMCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM, 538005bcd5e0c923881d82afcb813a7e537cd1b241Jim Grosbach bool AllocateGVsWithCode) 548005bcd5e0c923881d82afcb813a7e537cd1b241Jim Grosbach : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM), 553f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor isCompiled(false), M(m) { 5631649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach 573574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow setDataLayout(TM->getDataLayout()); 58ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor} 59ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 60ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew KaylorMCJIT::~MCJIT() { 61776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (LoadedObject) 62a082892fb734f4738f5e687778997706fa0dd65aAndrew Kaylor NotifyFreeingObject(*LoadedObject.get()); 63ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor delete MemMgr; 64ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor delete TM; 65ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor} 66ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 67ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylorvoid MCJIT::emitObject(Module *m) { 68ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor /// Currently, MCJIT only supports a single module and the module passed to 69ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor /// this function call is expected to be the contained module. The module 703f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor /// is passed as a parameter here to prepare for multiple module support in 71ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor /// the future. 72ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor assert(M == m); 73ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 74ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // Get a thread lock to make sure we aren't trying to compile multiple times 75ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor MutexGuard locked(lock); 76ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 77ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Track compilation state on a per-module basis when multiple modules 78ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // are supported. 79ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // Re-compilation is not supported 80ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor if (isCompiled) 81ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor return; 82ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 83ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor PassManager PM; 84ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 853574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow PM.add(new DataLayout(*TM->getDataLayout())); 8631649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach 873f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // The RuntimeDyld will take ownership of this shortly 883f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor OwningPtr<ObjectBufferStream> Buffer(new ObjectBufferStream()); 893f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor 9031649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach // Turn the machine code intermediate representation into bytes in memory 9131649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach // that may be executed. 923f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (TM->addPassesToEmitMC(PM, Ctx, Buffer->getOStream(), false)) { 9331649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach report_fatal_error("Target does not support MC emission!"); 9431649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach } 9531649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach 9631649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach // Initialize passes. 97ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor PM.run(*m); 983f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // Flush the output buffer to get the generated code into memory 993f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor Buffer->flush(); 100f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach 101f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach // Load the object into the dynamic linker. 1023f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // handing off ownership of the buffer 1033f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor LoadedObject.reset(Dyld.loadObject(Buffer.take())); 1043f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (!LoadedObject) 1058086f3b49429e02603270c8e09e2aabac9215a21Jim Grosbach report_fatal_error(Dyld.getErrorString()); 106ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 10769e813282d4aa078102ce058f8269d0c13260061Jim Grosbach // Resolve any relocations. 10869e813282d4aa078102ce058f8269d0c13260061Jim Grosbach Dyld.resolveRelocations(); 1096aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1103f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // FIXME: Make this optional, maybe even move it to a JIT event listener 1113f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor LoadedObject->registerWithDebugger(); 1123f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor 113776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor NotifyObjectEmitted(*LoadedObject); 114776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 115ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Add support for per-module compilation state 116ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor isCompiled = true; 1176aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1186aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 11928989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor// FIXME: Add a parameter to identify which object is being finalized when 12028989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor// MCJIT supports multiple modules. 12153608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor// FIXME: Provide a way to separate code emission, relocations and page 12253608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor// protection in the interface. 12328989889bf3aa3314562d438aece245b71176ec4Andrew Kaylorvoid MCJIT::finalizeObject() { 12428989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // If the module hasn't been compiled, just do that. 12528989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor if (!isCompiled) { 12628989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // If the call to Dyld.resolveRelocations() is removed from emitObject() 12728989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // we'll need to do that here. 12828989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor emitObject(M); 12953608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor 13053608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // Set page permissions. 13153608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor MemMgr->applyPermissions(); 13253608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor 13328989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor return; 13428989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor } 13528989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor 13628989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // Resolve any relocations. 13728989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor Dyld.resolveRelocations(); 13853608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor 13953608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // Set page permissions. 14053608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor MemMgr->applyPermissions(); 14128989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor} 14228989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor 1436aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { 1446aec29848676494867e26307698155bc2c5a4033Daniel Dunbar report_fatal_error("not yet implemented"); 1456aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1466aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1476aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid *MCJIT::getPointerToFunction(Function *F) { 14835ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // FIXME: This should really return a uint64_t since it's a pointer in the 14935ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // target address space, not our local address space. That's part of the 15035ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // ExecutionEngine interface, though. Fix that when the old JIT finally 15135ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // dies. 15235ed842773da41779d57d3ed23f440202d0be198Jim Grosbach 153ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Add support for per-module compilation state 154ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor if (!isCompiled) 155ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor emitObject(M); 156ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 15734714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { 15834714a06096f854c76371295d8c20b017fbba50bJim Grosbach bool AbortOnFailure = !F->hasExternalWeakLinkage(); 15934714a06096f854c76371295d8c20b017fbba50bJim Grosbach void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); 16034714a06096f854c76371295d8c20b017fbba50bJim Grosbach addGlobalMapping(F, Addr); 16134714a06096f854c76371295d8c20b017fbba50bJim Grosbach return Addr; 16234714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 16334714a06096f854c76371295d8c20b017fbba50bJim Grosbach 164ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Should the Dyld be retaining module information? Probably not. 1653ec2c7c3e48f1fbab749870c51a74920f91c82c1Jim Grosbach // FIXME: Should we be using the mangler for this? Probably. 16635ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // 16735ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // This is the accessor for the target address, so make sure to check the 16835ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // load address of the symbol, not the local address. 1693ec2c7c3e48f1fbab749870c51a74920f91c82c1Jim Grosbach StringRef BaseName = F->getName(); 1703ec2c7c3e48f1fbab749870c51a74920f91c82c1Jim Grosbach if (BaseName[0] == '\1') 17135ed842773da41779d57d3ed23f440202d0be198Jim Grosbach return (void*)Dyld.getSymbolLoadAddress(BaseName.substr(1)); 17235ed842773da41779d57d3ed23f440202d0be198Jim Grosbach return (void*)Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() 173c0ceedb6f885b1cbd3d3cea02f695afe393dfd2cJim Grosbach + BaseName).str()); 1746aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1756aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1766aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid *MCJIT::recompileAndRelinkFunction(Function *F) { 1776aec29848676494867e26307698155bc2c5a4033Daniel Dunbar report_fatal_error("not yet implemented"); 1786aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1796aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1806aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid MCJIT::freeMachineCodeForFunction(Function *F) { 1816aec29848676494867e26307698155bc2c5a4033Daniel Dunbar report_fatal_error("not yet implemented"); 1826aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1836aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1846aec29848676494867e26307698155bc2c5a4033Daniel DunbarGenericValue MCJIT::runFunction(Function *F, 1856aec29848676494867e26307698155bc2c5a4033Daniel Dunbar const std::vector<GenericValue> &ArgValues) { 18634714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert(F && "Function *F was null at entry to run()"); 18734714a06096f854c76371295d8c20b017fbba50bJim Grosbach 18831649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach void *FPtr = getPointerToFunction(F); 18934714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); 190db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = F->getFunctionType(); 191db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = FTy->getReturnType(); 19234714a06096f854c76371295d8c20b017fbba50bJim Grosbach 19334714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert((FTy->getNumParams() == ArgValues.size() || 19434714a06096f854c76371295d8c20b017fbba50bJim Grosbach (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && 19534714a06096f854c76371295d8c20b017fbba50bJim Grosbach "Wrong number of arguments passed into function!"); 19634714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert(FTy->getNumParams() == ArgValues.size() && 19734714a06096f854c76371295d8c20b017fbba50bJim Grosbach "This doesn't support passing arguments through varargs (yet)!"); 19834714a06096f854c76371295d8c20b017fbba50bJim Grosbach 19934714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Handle some common cases first. These cases correspond to common `main' 20034714a06096f854c76371295d8c20b017fbba50bJim Grosbach // prototypes. 20134714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { 20234714a06096f854c76371295d8c20b017fbba50bJim Grosbach switch (ArgValues.size()) { 20334714a06096f854c76371295d8c20b017fbba50bJim Grosbach case 3: 20434714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (FTy->getParamType(0)->isIntegerTy(32) && 20534714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(1)->isPointerTy() && 20634714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(2)->isPointerTy()) { 20734714a06096f854c76371295d8c20b017fbba50bJim Grosbach int (*PF)(int, char **, const char **) = 20834714a06096f854c76371295d8c20b017fbba50bJim Grosbach (int(*)(int, char **, const char **))(intptr_t)FPtr; 20934714a06096f854c76371295d8c20b017fbba50bJim Grosbach 21034714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Call the function. 21134714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 21234714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 21334714a06096f854c76371295d8c20b017fbba50bJim Grosbach (char **)GVTOP(ArgValues[1]), 21434714a06096f854c76371295d8c20b017fbba50bJim Grosbach (const char **)GVTOP(ArgValues[2]))); 21534714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 21634714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 21734714a06096f854c76371295d8c20b017fbba50bJim Grosbach break; 21834714a06096f854c76371295d8c20b017fbba50bJim Grosbach case 2: 21934714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (FTy->getParamType(0)->isIntegerTy(32) && 22034714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(1)->isPointerTy()) { 22134714a06096f854c76371295d8c20b017fbba50bJim Grosbach int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr; 22234714a06096f854c76371295d8c20b017fbba50bJim Grosbach 22334714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Call the function. 22434714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 22534714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 22634714a06096f854c76371295d8c20b017fbba50bJim Grosbach (char **)GVTOP(ArgValues[1]))); 22734714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 22834714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 22934714a06096f854c76371295d8c20b017fbba50bJim Grosbach break; 23034714a06096f854c76371295d8c20b017fbba50bJim Grosbach case 1: 23134714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (FTy->getNumParams() == 1 && 23234714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(0)->isIntegerTy(32)) { 23334714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 23434714a06096f854c76371295d8c20b017fbba50bJim Grosbach int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; 23534714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); 23634714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 23734714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 23834714a06096f854c76371295d8c20b017fbba50bJim Grosbach break; 23934714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 24034714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 24134714a06096f854c76371295d8c20b017fbba50bJim Grosbach 24234714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Handle cases where no arguments are passed first. 24334714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (ArgValues.empty()) { 24434714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 24534714a06096f854c76371295d8c20b017fbba50bJim Grosbach switch (RetTy->getTypeID()) { 24634714a06096f854c76371295d8c20b017fbba50bJim Grosbach default: llvm_unreachable("Unknown return type for function call!"); 24734714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::IntegerTyID: { 24834714a06096f854c76371295d8c20b017fbba50bJim Grosbach unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); 24934714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (BitWidth == 1) 25034714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)()); 25134714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 8) 25234714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)()); 25334714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 16) 25434714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)()); 25534714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 32) 25634714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); 25734714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 64) 25834714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); 25934714a06096f854c76371295d8c20b017fbba50bJim Grosbach else 26034714a06096f854c76371295d8c20b017fbba50bJim Grosbach llvm_unreachable("Integer types > 64 bits not supported"); 26134714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 26234714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 26334714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::VoidTyID: 26434714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); 26534714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 26634714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::FloatTyID: 26734714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.FloatVal = ((float(*)())(intptr_t)FPtr)(); 26834714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 26934714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::DoubleTyID: 27034714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.DoubleVal = ((double(*)())(intptr_t)FPtr)(); 27134714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 27234714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::X86_FP80TyID: 27334714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::FP128TyID: 27434714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::PPC_FP128TyID: 27534714a06096f854c76371295d8c20b017fbba50bJim Grosbach llvm_unreachable("long double not supported yet"); 27634714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::PointerTyID: 27734714a06096f854c76371295d8c20b017fbba50bJim Grosbach return PTOGV(((void*(*)())(intptr_t)FPtr)()); 27834714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 27934714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 28034714a06096f854c76371295d8c20b017fbba50bJim Grosbach 281858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper llvm_unreachable("Full-featured argument passing not supported yet!"); 2826aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 28330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 28430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshevvoid *MCJIT::getPointerToNamedFunction(const std::string &Name, 2855fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky bool AbortOnFailure) { 286ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Add support for per-module compilation state 287ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor if (!isCompiled) 288ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor emitObject(M); 289ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 29030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (!isSymbolSearchingDisabled() && MemMgr) { 29130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev void *ptr = MemMgr->getPointerToNamedFunction(Name, false); 29230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (ptr) 29330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return ptr; 29430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 29530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 29630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev /// If a LazyFunctionCreator is installed, use it to get/create the function. 29730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (LazyFunctionCreator) 29830b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (void *RP = LazyFunctionCreator(Name)) 29930b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return RP; 30030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 30130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (AbortOnFailure) { 30230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev report_fatal_error("Program used external function '"+Name+ 3035fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky "' which could not be resolved!"); 30430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 30530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return 0; 30630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev} 307776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 308776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::RegisterJITEventListener(JITEventListener *L) { 309776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (L == NULL) 310776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor return; 311776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 312776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners.push_back(L); 313776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 314776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::UnregisterJITEventListener(JITEventListener *L) { 315776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (L == NULL) 316776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor return; 317776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 318776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor SmallVector<JITEventListener*, 2>::reverse_iterator I= 319776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor std::find(EventListeners.rbegin(), EventListeners.rend(), L); 320776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (I != EventListeners.rend()) { 321776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor std::swap(*I, EventListeners.back()); 322776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners.pop_back(); 323776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor } 324776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 325776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { 326776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 327776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 328776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners[I]->NotifyObjectEmitted(Obj); 329776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor } 330776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 331776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { 332776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 333776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 334776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners[I]->NotifyFreeingObject(Obj); 335776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor } 336776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 337