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