Add support for targets that require stubs for external functions.
authorChris Lattner <sabre@nondot.org>
Mon, 18 Apr 2005 01:44:27 +0000 (01:44 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 18 Apr 2005 01:44:27 +0000 (01:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21313 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/JIT/JITEmitter.cpp

index cb12642367f1b0096ca090dc8d3ed5684a28fa0a..8b5071b31d503c6c0160da84507da82d26a62a9f 100644 (file)
@@ -138,6 +138,9 @@ namespace {
     // to.
     std::map<void*, Function*> StubToFunctionMap;
 
+    /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for
+    /// external functions.
+    std::map<void*, void*> ExternalFnToStubMap;
   public:
     JITResolver(MachineCodeEmitter &mce) : MCE(mce) {
       LazyResolverFn =
@@ -148,6 +151,10 @@ namespace {
     /// one on demand as needed.
     void *getFunctionStub(Function *F);
 
+    /// getExternalFunctionStub - Return a stub for the function at the
+    /// specified address, created lazily on demand.
+    void *getExternalFunctionStub(void *FnAddr);
+
     /// AddCallbackAtLocation - If the target is capable of rewriting an
     /// instruction without the use of a stub, record the location of the use so
     /// we know which function is being used at the location.
@@ -204,6 +211,20 @@ void *JITResolver::getFunctionStub(Function *F) {
   return Stub;
 }
 
+/// getExternalFunctionStub - Return a stub for the function at the
+/// specified address, created lazily on demand.
+void *JITResolver::getExternalFunctionStub(void *FnAddr) {
+  // If we already have a stub for this function, recycle it.
+  void *&Stub = ExternalFnToStubMap[FnAddr];
+  if (Stub) return Stub;
+
+  Stub = TheJIT->getJITInfo().emitFunctionStub(FnAddr, MCE);
+  DEBUG(std::cerr << "JIT: Stub emitted at [" << Stub
+        << "] for external function at '" << FnAddr << "'\n");
+  return Stub;
+}
+
+
 /// JITCompilerFn - This function is called when a lazy compilation stub has
 /// been entered.  It looks up which function this stub corresponds to, compiles
 /// it if necessary, then returns the resultant function pointer.
@@ -350,9 +371,13 @@ void JITEmitter::finishFunction(MachineFunction &F) {
     for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
       MachineRelocation &MR = Relocations[i];
       void *ResultPtr;
-      if (MR.isString())
+      if (MR.isString()) {
         ResultPtr = TheJIT->getPointerToNamedFunction(MR.getString());
-      else
+        
+        // If the target REALLY wants a stub for this function, emit it now.
+        if (!MR.doesntNeedFunctionStub())
+          ResultPtr = getJITResolver(this).getExternalFunctionStub(ResultPtr);
+      } else
         ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
                                        CurBlock+MR.getMachineCodeOffset(),
                                        MR.doesntNeedFunctionStub());