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
This commit is contained in:
Chris Lattner
2007-10-22 02:50:12 +00:00
parent ec2fcafbea
commit d958a5a9fe
3 changed files with 21 additions and 3 deletions

View File

@ -64,6 +64,7 @@ class ExecutionEngine {
const TargetData *TD; const TargetData *TD;
ExecutionEngineState state; ExecutionEngineState state;
bool LazyCompilationDisabled; bool LazyCompilationDisabled;
protected: protected:
/// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We /// 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. /// use a smallvector to optimize for the case where there is only one module.
@ -79,6 +80,10 @@ protected:
typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*, std::string*); typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*, std::string*);
static EECtorFn JITCtor, InterpCtor; 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: public:
/// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and /// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and
/// JITEmitter classes. It must be held while changing the internal state of /// JITEmitter classes. It must be held while changing the internal state of
@ -219,6 +224,14 @@ public:
return LazyCompilationDisabled; 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: protected:
void emitGlobals(); void emitGlobals();

View File

@ -33,13 +33,13 @@ STATISTIC(NumGlobals , "Number of global vars initialized");
ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0; ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0;
ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0; ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0;
ExecutionEngine::ExecutionEngine(ModuleProvider *P) { ExecutionEngine::ExecutionEngine(ModuleProvider *P) : LazyFunctionCreator(0) {
LazyCompilationDisabled = false; LazyCompilationDisabled = false;
Modules.push_back(P); Modules.push_back(P);
assert(P && "ModuleProvider is null?"); assert(P && "ModuleProvider is null?");
} }
ExecutionEngine::ExecutionEngine(Module *M) { ExecutionEngine::ExecutionEngine(Module *M) : LazyFunctionCreator(0) {
LazyCompilationDisabled = false; LazyCompilationDisabled = false;
assert(M && "Module is null?"); assert(M && "Module is null?");
Modules.push_back(new ExistingModuleProvider(M)); Modules.push_back(new ExistingModuleProvider(M));

View File

@ -102,6 +102,11 @@ void *JIT::getPointerToNamedFunction(const std::string &Name) {
if (Ptr) return Ptr; 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 cerr << "ERROR: Program used external function '" << Name
<< "' which could not be resolved!\n"; << "' which could not be resolved!\n";
abort(); abort();