From d91ff7cd3b08cfe30b731799da8358dd9f90558c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 18 Apr 2005 01:44:27 +0000 Subject: [PATCH] Add support for targets that require stubs for external functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21313 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/JIT/JITEmitter.cpp | 29 ++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index cb12642367f..8b5071b31d5 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -138,6 +138,9 @@ namespace { // to. std::map StubToFunctionMap; + /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for + /// external functions. + std::map 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());