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" 116aec29848676494867e26307698155bc2c5a4033Daniel Dunbar#include "llvm/ExecutionEngine/GenericValue.h" 12776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor#include "llvm/ExecutionEngine/JITEventListener.h" 13f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/ExecutionEngine/JITMemoryManager.h" 143f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/MCJIT.h" 153f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/ObjectBuffer.h" 163f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/ObjectImage.h" 17d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm/ExecutionEngine/SectionMemoryManager.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 200b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 21f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/MC/MCAsmInfo.h" 221f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DynamicLibrary.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h" 24f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/Support/MemoryBuffer.h" 25ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor#include "llvm/Support/MutexGuard.h" 266aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 276aec29848676494867e26307698155bc2c5a4033Daniel Dunbarusing namespace llvm; 286aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 296aec29848676494867e26307698155bc2c5a4033Daniel Dunbarnamespace { 306aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 316aec29848676494867e26307698155bc2c5a4033Daniel Dunbarstatic struct RegisterJIT { 326aec29848676494867e26307698155bc2c5a4033Daniel Dunbar RegisterJIT() { MCJIT::Register(); } 336aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} JITRegistrator; 346aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 356aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 366aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 376aec29848676494867e26307698155bc2c5a4033Daniel Dunbarextern "C" void LLVMLinkInMCJIT() { 386aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 396aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 406aec29848676494867e26307698155bc2c5a4033Daniel DunbarExecutionEngine *MCJIT::createJIT(Module *M, 416aec29848676494867e26307698155bc2c5a4033Daniel Dunbar std::string *ErrorStr, 4213a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo RTDyldMemoryManager *MemMgr, 436aec29848676494867e26307698155bc2c5a4033Daniel Dunbar bool GVsWithCode, 44c5b28580a94e247300e5d3ccf532e153f2ae6f12Dylan Noblesmith TargetMachine *TM) { 456aec29848676494867e26307698155bc2c5a4033Daniel Dunbar // Try to register the program as a source of symbols to resolve against. 466aec29848676494867e26307698155bc2c5a4033Daniel Dunbar // 476aec29848676494867e26307698155bc2c5a4033Daniel Dunbar // FIXME: Don't do this here. 486aec29848676494867e26307698155bc2c5a4033Daniel Dunbar sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); 496aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 5013a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(), 5113a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo GVsWithCode); 526aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 536aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 548005bcd5e0c923881d82afcb813a7e537cd1b241Jim GrosbachMCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM, 558005bcd5e0c923881d82afcb813a7e537cd1b241Jim Grosbach bool AllocateGVsWithCode) 5613a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM), 5713a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo IsLoaded(false), M(m), ObjCache(0) { 5831649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach 593574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow setDataLayout(TM->getDataLayout()); 60ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor} 61ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 62ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew KaylorMCJIT::~MCJIT() { 63776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (LoadedObject) 64a082892fb734f4738f5e687778997706fa0dd65aAndrew Kaylor NotifyFreeingObject(*LoadedObject.get()); 65ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor delete MemMgr; 66ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor delete TM; 67ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor} 68ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 691c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorvoid MCJIT::setObjectCache(ObjectCache* NewCache) { 701c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjCache = NewCache; 711c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} 721c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 731c489455ea5fac43a5f20911dfb5486630eb0160Andrew KaylorObjectBufferStream* MCJIT::emitObject(Module *m) { 74ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor /// Currently, MCJIT only supports a single module and the module passed to 75ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor /// this function call is expected to be the contained module. The module 763f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor /// is passed as a parameter here to prepare for multiple module support in 77ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor /// the future. 78ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor assert(M == m); 79ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 80ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // Get a thread lock to make sure we aren't trying to compile multiple times 81ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor MutexGuard locked(lock); 82ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 83ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Track compilation state on a per-module basis when multiple modules 84ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // are supported. 85ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // Re-compilation is not supported 861c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor assert(!IsLoaded); 87ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 88ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor PassManager PM; 89ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 903574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow PM.add(new DataLayout(*TM->getDataLayout())); 9131649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach 923f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // The RuntimeDyld will take ownership of this shortly 931c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor OwningPtr<ObjectBufferStream> CompiledObject(new ObjectBufferStream()); 943f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor 9531649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach // Turn the machine code intermediate representation into bytes in memory 9631649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach // that may be executed. 971c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), false)) { 9831649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach report_fatal_error("Target does not support MC emission!"); 9931649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach } 10031649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach 10131649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach // Initialize passes. 102ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor PM.run(*m); 1033f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // Flush the output buffer to get the generated code into memory 1041c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor CompiledObject->flush(); 1051c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1061c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // If we have an object cache, tell it about the new object. 1071c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Note that we're using the compiled image, not the loaded image (as below). 1081c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (ObjCache) { 1091c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // MemoryBuffer is a thin wrapper around the actual memory, so it's OK 1101c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // to create a temporary object here and delete it after the call. 1111c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor OwningPtr<MemoryBuffer> MB(CompiledObject->getMemBuffer()); 1121c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjCache->notifyObjectCompiled(m, MB.get()); 1131c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 1141c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1151c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor return CompiledObject.take(); 1161c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor} 1171c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1181c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorvoid MCJIT::loadObject(Module *M) { 1191c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1201c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Get a thread lock to make sure we aren't trying to load multiple times 1211c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor MutexGuard locked(lock); 1221c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1231c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // FIXME: Track compilation state on a per-module basis when multiple modules 1241c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // are supported. 1251c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Re-compilation is not supported 1261c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (IsLoaded) 1271c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor return; 1281c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1291c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor OwningPtr<ObjectBuffer> ObjectToLoad; 1301c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // Try to load the pre-compiled object from cache if possible 1311c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (0 != ObjCache) { 13240d8171e3e74f4786d89a8f1fb370653f81c7941Andrew Kaylor OwningPtr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M)); 1331c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (0 != PreCompiledObject.get()) 1341c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.take())); 1351c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 1361c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor 1371c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // If the cache did not contain a suitable object, compile the object 1381c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (!ObjectToLoad) { 1391c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor ObjectToLoad.reset(emitObject(M)); 1401c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor assert(ObjectToLoad.get() && "Compilation did not produce an object."); 1411c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor } 142f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach 143f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach // Load the object into the dynamic linker. 1443f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // handing off ownership of the buffer 1451c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor LoadedObject.reset(Dyld.loadObject(ObjectToLoad.take())); 1463f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor if (!LoadedObject) 1478086f3b49429e02603270c8e09e2aabac9215a21Jim Grosbach report_fatal_error(Dyld.getErrorString()); 148ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 14969e813282d4aa078102ce058f8269d0c13260061Jim Grosbach // Resolve any relocations. 15069e813282d4aa078102ce058f8269d0c13260061Jim Grosbach Dyld.resolveRelocations(); 1516aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1523f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor // FIXME: Make this optional, maybe even move it to a JIT event listener 1533f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor LoadedObject->registerWithDebugger(); 1543f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor 155776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor NotifyObjectEmitted(*LoadedObject); 156776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 157ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Add support for per-module compilation state 1581c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor IsLoaded = true; 1596aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1606aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 16128989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor// FIXME: Add a parameter to identify which object is being finalized when 16228989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor// MCJIT supports multiple modules. 16353608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor// FIXME: Provide a way to separate code emission, relocations and page 16453608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor// protection in the interface. 16528989889bf3aa3314562d438aece245b71176ec4Andrew Kaylorvoid MCJIT::finalizeObject() { 16628989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // If the module hasn't been compiled, just do that. 1671c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (!IsLoaded) { 1681c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor // If the call to Dyld.resolveRelocations() is removed from loadObject() 16928989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // we'll need to do that here. 1701c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor loadObject(M); 171a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola } else { 172a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola // Resolve any relocations. 173a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Dyld.resolveRelocations(); 17428989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor } 17528989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor 176a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola StringRef EHData = Dyld.getEHFrameSection(); 177a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola if (!EHData.empty()) 178a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola MemMgr->registerEHFrames(EHData); 17953608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor 18053608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // Set page permissions. 181abb38fe8dec11b1ea7535f84fac8ad0f0af70addDavid Tweed MemMgr->finalizeMemory(); 18228989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor} 18328989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor 1846aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { 1856aec29848676494867e26307698155bc2c5a4033Daniel Dunbar report_fatal_error("not yet implemented"); 1866aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 1876aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 1886aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid *MCJIT::getPointerToFunction(Function *F) { 18935ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // FIXME: This should really return a uint64_t since it's a pointer in the 19035ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // target address space, not our local address space. That's part of the 19135ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // ExecutionEngine interface, though. Fix that when the old JIT finally 19235ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // dies. 19335ed842773da41779d57d3ed23f440202d0be198Jim Grosbach 194ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Add support for per-module compilation state 1951c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (!IsLoaded) 1961c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor loadObject(M); 197ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 19834714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { 19934714a06096f854c76371295d8c20b017fbba50bJim Grosbach bool AbortOnFailure = !F->hasExternalWeakLinkage(); 20034714a06096f854c76371295d8c20b017fbba50bJim Grosbach void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); 20134714a06096f854c76371295d8c20b017fbba50bJim Grosbach addGlobalMapping(F, Addr); 20234714a06096f854c76371295d8c20b017fbba50bJim Grosbach return Addr; 20334714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 20434714a06096f854c76371295d8c20b017fbba50bJim Grosbach 205ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Should the Dyld be retaining module information? Probably not. 2063ec2c7c3e48f1fbab749870c51a74920f91c82c1Jim Grosbach // FIXME: Should we be using the mangler for this? Probably. 20735ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // 20835ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // This is the accessor for the target address, so make sure to check the 20935ed842773da41779d57d3ed23f440202d0be198Jim Grosbach // load address of the symbol, not the local address. 2103ec2c7c3e48f1fbab749870c51a74920f91c82c1Jim Grosbach StringRef BaseName = F->getName(); 2113ec2c7c3e48f1fbab749870c51a74920f91c82c1Jim Grosbach if (BaseName[0] == '\1') 21235ed842773da41779d57d3ed23f440202d0be198Jim Grosbach return (void*)Dyld.getSymbolLoadAddress(BaseName.substr(1)); 21335ed842773da41779d57d3ed23f440202d0be198Jim Grosbach return (void*)Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() 214c0ceedb6f885b1cbd3d3cea02f695afe393dfd2cJim Grosbach + BaseName).str()); 2156aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 2166aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 2176aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid *MCJIT::recompileAndRelinkFunction(Function *F) { 2186aec29848676494867e26307698155bc2c5a4033Daniel Dunbar report_fatal_error("not yet implemented"); 2196aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 2206aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 2216aec29848676494867e26307698155bc2c5a4033Daniel Dunbarvoid MCJIT::freeMachineCodeForFunction(Function *F) { 2226aec29848676494867e26307698155bc2c5a4033Daniel Dunbar report_fatal_error("not yet implemented"); 2236aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 2246aec29848676494867e26307698155bc2c5a4033Daniel Dunbar 2256aec29848676494867e26307698155bc2c5a4033Daniel DunbarGenericValue MCJIT::runFunction(Function *F, 2266aec29848676494867e26307698155bc2c5a4033Daniel Dunbar const std::vector<GenericValue> &ArgValues) { 22734714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert(F && "Function *F was null at entry to run()"); 22834714a06096f854c76371295d8c20b017fbba50bJim Grosbach 22931649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach void *FPtr = getPointerToFunction(F); 23034714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); 231db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = F->getFunctionType(); 232db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = FTy->getReturnType(); 23334714a06096f854c76371295d8c20b017fbba50bJim Grosbach 23434714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert((FTy->getNumParams() == ArgValues.size() || 23534714a06096f854c76371295d8c20b017fbba50bJim Grosbach (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && 23634714a06096f854c76371295d8c20b017fbba50bJim Grosbach "Wrong number of arguments passed into function!"); 23734714a06096f854c76371295d8c20b017fbba50bJim Grosbach assert(FTy->getNumParams() == ArgValues.size() && 23834714a06096f854c76371295d8c20b017fbba50bJim Grosbach "This doesn't support passing arguments through varargs (yet)!"); 23934714a06096f854c76371295d8c20b017fbba50bJim Grosbach 24034714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Handle some common cases first. These cases correspond to common `main' 24134714a06096f854c76371295d8c20b017fbba50bJim Grosbach // prototypes. 24234714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { 24334714a06096f854c76371295d8c20b017fbba50bJim Grosbach switch (ArgValues.size()) { 24434714a06096f854c76371295d8c20b017fbba50bJim Grosbach case 3: 24534714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (FTy->getParamType(0)->isIntegerTy(32) && 24634714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(1)->isPointerTy() && 24734714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(2)->isPointerTy()) { 24834714a06096f854c76371295d8c20b017fbba50bJim Grosbach int (*PF)(int, char **, const char **) = 24934714a06096f854c76371295d8c20b017fbba50bJim Grosbach (int(*)(int, char **, const char **))(intptr_t)FPtr; 25034714a06096f854c76371295d8c20b017fbba50bJim Grosbach 25134714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Call the function. 25234714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 25334714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 25434714a06096f854c76371295d8c20b017fbba50bJim Grosbach (char **)GVTOP(ArgValues[1]), 25534714a06096f854c76371295d8c20b017fbba50bJim Grosbach (const char **)GVTOP(ArgValues[2]))); 25634714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 25734714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 25834714a06096f854c76371295d8c20b017fbba50bJim Grosbach break; 25934714a06096f854c76371295d8c20b017fbba50bJim Grosbach case 2: 26034714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (FTy->getParamType(0)->isIntegerTy(32) && 26134714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(1)->isPointerTy()) { 26234714a06096f854c76371295d8c20b017fbba50bJim Grosbach int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr; 26334714a06096f854c76371295d8c20b017fbba50bJim Grosbach 26434714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Call the function. 26534714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 26634714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 26734714a06096f854c76371295d8c20b017fbba50bJim Grosbach (char **)GVTOP(ArgValues[1]))); 26834714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 26934714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 27034714a06096f854c76371295d8c20b017fbba50bJim Grosbach break; 27134714a06096f854c76371295d8c20b017fbba50bJim Grosbach case 1: 27234714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (FTy->getNumParams() == 1 && 27334714a06096f854c76371295d8c20b017fbba50bJim Grosbach FTy->getParamType(0)->isIntegerTy(32)) { 27434714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 27534714a06096f854c76371295d8c20b017fbba50bJim Grosbach int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; 27634714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); 27734714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 27834714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 27934714a06096f854c76371295d8c20b017fbba50bJim Grosbach break; 28034714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 28134714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 28234714a06096f854c76371295d8c20b017fbba50bJim Grosbach 28334714a06096f854c76371295d8c20b017fbba50bJim Grosbach // Handle cases where no arguments are passed first. 28434714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (ArgValues.empty()) { 28534714a06096f854c76371295d8c20b017fbba50bJim Grosbach GenericValue rv; 28634714a06096f854c76371295d8c20b017fbba50bJim Grosbach switch (RetTy->getTypeID()) { 28734714a06096f854c76371295d8c20b017fbba50bJim Grosbach default: llvm_unreachable("Unknown return type for function call!"); 28834714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::IntegerTyID: { 28934714a06096f854c76371295d8c20b017fbba50bJim Grosbach unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); 29034714a06096f854c76371295d8c20b017fbba50bJim Grosbach if (BitWidth == 1) 29134714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)()); 29234714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 8) 29334714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)()); 29434714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 16) 29534714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)()); 29634714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 32) 29734714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); 29834714a06096f854c76371295d8c20b017fbba50bJim Grosbach else if (BitWidth <= 64) 29934714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); 30034714a06096f854c76371295d8c20b017fbba50bJim Grosbach else 30134714a06096f854c76371295d8c20b017fbba50bJim Grosbach llvm_unreachable("Integer types > 64 bits not supported"); 30234714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 30334714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 30434714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::VoidTyID: 30534714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); 30634714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 30734714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::FloatTyID: 30834714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.FloatVal = ((float(*)())(intptr_t)FPtr)(); 30934714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 31034714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::DoubleTyID: 31134714a06096f854c76371295d8c20b017fbba50bJim Grosbach rv.DoubleVal = ((double(*)())(intptr_t)FPtr)(); 31234714a06096f854c76371295d8c20b017fbba50bJim Grosbach return rv; 31334714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::X86_FP80TyID: 31434714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::FP128TyID: 31534714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::PPC_FP128TyID: 31634714a06096f854c76371295d8c20b017fbba50bJim Grosbach llvm_unreachable("long double not supported yet"); 31734714a06096f854c76371295d8c20b017fbba50bJim Grosbach case Type::PointerTyID: 31834714a06096f854c76371295d8c20b017fbba50bJim Grosbach return PTOGV(((void*(*)())(intptr_t)FPtr)()); 31934714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 32034714a06096f854c76371295d8c20b017fbba50bJim Grosbach } 32134714a06096f854c76371295d8c20b017fbba50bJim Grosbach 322858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper llvm_unreachable("Full-featured argument passing not supported yet!"); 3236aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} 32430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 32530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshevvoid *MCJIT::getPointerToNamedFunction(const std::string &Name, 3265fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky bool AbortOnFailure) { 327ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor // FIXME: Add support for per-module compilation state 3281c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor if (!IsLoaded) 3291c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor loadObject(M); 330ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor 33130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (!isSymbolSearchingDisabled() && MemMgr) { 33230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev void *ptr = MemMgr->getPointerToNamedFunction(Name, false); 33330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (ptr) 33430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return ptr; 33530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 33630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 33730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev /// If a LazyFunctionCreator is installed, use it to get/create the function. 33830b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (LazyFunctionCreator) 33930b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (void *RP = LazyFunctionCreator(Name)) 34030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return RP; 34130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 34230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (AbortOnFailure) { 34330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev report_fatal_error("Program used external function '"+Name+ 3445fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky "' which could not be resolved!"); 34530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 34630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return 0; 34730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev} 348776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor 349776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::RegisterJITEventListener(JITEventListener *L) { 350776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (L == NULL) 351776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor return; 352776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 353776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners.push_back(L); 354776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 355776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::UnregisterJITEventListener(JITEventListener *L) { 356776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (L == NULL) 357776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor return; 358776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 359776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor SmallVector<JITEventListener*, 2>::reverse_iterator I= 360776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor std::find(EventListeners.rbegin(), EventListeners.rend(), L); 361776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor if (I != EventListeners.rend()) { 362776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor std::swap(*I, EventListeners.back()); 363776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners.pop_back(); 364776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor } 365776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 366776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { 367776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 368776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 369776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners[I]->NotifyObjectEmitted(Obj); 370776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor } 371776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 372776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { 373776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor MutexGuard locked(lock); 374776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 375776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor EventListeners[I]->NotifyFreeingObject(Obj); 376776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor } 377776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor} 378