add a mechanism for the JIT to invoke a function to lazily create functions as they...
authorChris Lattner <sabre@nondot.org>
Mon, 22 Oct 2007 02:50:12 +0000 (02:50 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 22 Oct 2007 02:50:12 +0000 (02:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43210 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/ExecutionEngine.h
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/JIT/Intercept.cpp

index da034a7cc2f945698c436a1af7f8e3aebd805f29..3ec2641cada9867f7d1ed31a70f7879ea6dc573b 100644 (file)
@@ -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();
index 2129dd5019d92d5d7d7206a4bab9eede07fe7d57..d89a9bb4ac7e15122bc29ceeb66d6032e1cf4f6a 100644 (file)
@@ -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));
index 61035c25359670eac21abe6bfc583035fb5c7274..318d6067d6c01351bf1273f1e9e8e08b87e19028 100644 (file)
@@ -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";