From d958a5a9feea7239a73c2068f43f237db550f46e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 22 Oct 2007 02:50:12 +0000 Subject: [PATCH] add a mechanism for the JIT to invoke a function to lazily create functions as they are referenced. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43210 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ExecutionEngine/ExecutionEngine.h | 15 ++++++++++++++- lib/ExecutionEngine/ExecutionEngine.cpp | 4 ++-- lib/ExecutionEngine/JIT/Intercept.cpp | 5 +++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index da034a7cc2f..3ec2641cada 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -64,6 +64,7 @@ class ExecutionEngine { const TargetData *TD; ExecutionEngineState state; bool LazyCompilationDisabled; + protected: /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We /// use a smallvector to optimize for the case where there is only one module. @@ -78,7 +79,11 @@ protected: // at startup time if they are linked in. typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*, std::string*); static EECtorFn JITCtor, InterpCtor; - + + /// LazyFunctionCreator - If an unknown function is needed, this function + /// pointer is invoked to create it. If this returns null, the JIT will abort. + void* (*LazyFunctionCreator)(const std::string &); + public: /// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and /// JITEmitter classes. It must be held while changing the internal state of @@ -218,6 +223,14 @@ public: bool isLazyCompilationDisabled() const { return LazyCompilationDisabled; } + + + /// InstallLazyFunctionCreator - If an unknown function is needed, the + /// specified function pointer is invoked to create it. If it returns null, + /// the JIT will abort. + void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { + LazyFunctionCreator = P; + } protected: void emitGlobals(); diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 2129dd5019d..d89a9bb4ac7 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -33,13 +33,13 @@ STATISTIC(NumGlobals , "Number of global vars initialized"); ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0; ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0; -ExecutionEngine::ExecutionEngine(ModuleProvider *P) { +ExecutionEngine::ExecutionEngine(ModuleProvider *P) : LazyFunctionCreator(0) { LazyCompilationDisabled = false; Modules.push_back(P); assert(P && "ModuleProvider is null?"); } -ExecutionEngine::ExecutionEngine(Module *M) { +ExecutionEngine::ExecutionEngine(Module *M) : LazyFunctionCreator(0) { LazyCompilationDisabled = false; assert(M && "Module is null?"); Modules.push_back(new ExistingModuleProvider(M)); diff --git a/lib/ExecutionEngine/JIT/Intercept.cpp b/lib/ExecutionEngine/JIT/Intercept.cpp index 61035c25359..318d6067d6c 100644 --- a/lib/ExecutionEngine/JIT/Intercept.cpp +++ b/lib/ExecutionEngine/JIT/Intercept.cpp @@ -101,6 +101,11 @@ void *JIT::getPointerToNamedFunction(const std::string &Name) { Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); if (Ptr) return Ptr; } + + /// If a LazyFunctionCreator is installed, use it to get/create the function. + if (LazyFunctionCreator) + if (void *RP = LazyFunctionCreator(Name)) + return RP; cerr << "ERROR: Program used external function '" << Name << "' which could not be resolved!\n"; -- 2.34.1