most cases (e.g. direct calls) no stub is needed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18080
91177308-0d34-0410-b5e6-
96231b3b80d8
/// JITResolver - Keep track of, and resolve, call sites for functions that
/// have not yet been compiled.
class JITResolver {
/// JITResolver - Keep track of, and resolve, call sites for functions that
/// have not yet been compiled.
class JITResolver {
- /// The MCE to use to emit stubs with.
+ /// MCE - The MachineCodeEmitter to use to emit stubs with.
+ /// LazyResolverFn - The target lazy resolver function that we actually
+ /// rewrite instructions to use.
+ TargetJITInfo::LazyResolverFn LazyResolverFn;
+
// FunctionToStubMap - Keep track of the stub created for a particular
// function so that we can reuse them if necessary.
std::map<Function*, void*> FunctionToStubMap;
// FunctionToStubMap - Keep track of the stub created for a particular
// function so that we can reuse them if necessary.
std::map<Function*, void*> FunctionToStubMap;
std::map<void*, Function*> StubToFunctionMap;
public:
std::map<void*, Function*> StubToFunctionMap;
public:
- JITResolver(MachineCodeEmitter &mce) : MCE(mce) {}
+ JITResolver(MachineCodeEmitter &mce) : MCE(mce) {
+ LazyResolverFn =
+ TheJIT->getJITInfo().getLazyResolverFunction(JITCompilerFn);
+ }
/// getFunctionStub - This returns a pointer to a function stub, creating
/// one on demand as needed.
void *getFunctionStub(Function *F);
/// getFunctionStub - This returns a pointer to a function stub, creating
/// one on demand as needed.
void *getFunctionStub(Function *F);
+ /// 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.
+ void *AddCallbackAtLocation(Function *F, void *Location) {
+ /// Get the target-specific JIT resolver function.
+ StubToFunctionMap[Location] = F;
+ return (void*)LazyResolverFn;
+ }
+
/// JITCompilerFn - This function is called to resolve a stub to a compiled
/// address. If the LLVM Function corresponding to the stub has not yet
/// been compiled, this function compiles it first.
/// JITCompilerFn - This function is called to resolve a stub to a compiled
/// address. If the LLVM Function corresponding to the stub has not yet
/// been compiled, this function compiles it first.
/// getFunctionStub - This returns a pointer to a function stub, creating
/// one on demand as needed.
void *JITResolver::getFunctionStub(Function *F) {
/// getFunctionStub - This returns a pointer to a function stub, creating
/// one on demand as needed.
void *JITResolver::getFunctionStub(Function *F) {
- /// Get the target-specific JIT resolver function.
- static TargetJITInfo::LazyResolverFn LazyResolverFn =
- TheJIT->getJITInfo().getLazyResolverFunction(JITResolver::JITCompilerFn);
-
// If we already have a stub for this function, recycle it.
void *&Stub = FunctionToStubMap[F];
if (Stub) return Stub;
// If we already have a stub for this function, recycle it.
void *&Stub = FunctionToStubMap[F];
if (Stub) return Stub;
virtual uint64_t forceCompilationOf(Function *F);
private:
virtual uint64_t forceCompilationOf(Function *F);
private:
- void *getPointerToGlobal(GlobalValue *GV);
+ void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
return new Emitter(jit);
}
return new Emitter(jit);
}
-void *Emitter::getPointerToGlobal(GlobalValue *V) {
+void *Emitter::getPointerToGlobal(GlobalValue *V, void *Reference,
+ bool DoesntNeedStub) {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
/// FIXME: If we straightened things out, this could actually emit the
/// global immediately instead of queuing it for codegen later!
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
/// FIXME: If we straightened things out, this could actually emit the
/// global immediately instead of queuing it for codegen later!
return TheJIT->getPointerToFunction(F);
}
return TheJIT->getPointerToFunction(F);
}
+ // Okay, the function has not been compiled yet, if the target callback
+ // mechanism is capable of rewriting the instruction directly, prefer to do
+ // that instead of emitting a stub.
+ if (DoesntNeedStub)
+ return getJITResolver(this).AddCallbackAtLocation(F, Reference);
+
// Otherwise, we have to emit a lazy resolving stub.
return getJITResolver(this).getFunctionStub(F);
}
// Otherwise, we have to emit a lazy resolving stub.
return getJITResolver(this).getFunctionStub(F);
}
if (MR.isString())
ResultPtr = TheJIT->getPointerToNamedFunction(MR.getString());
else
if (MR.isString())
ResultPtr = TheJIT->getPointerToNamedFunction(MR.getString());
else
- ResultPtr = getPointerToGlobal(MR.getGlobalValue());
+ ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
+ CurBlock+MR.getMachineCodeOffset(),
+ MR.doesntNeedFunctionStub());
MR.setResultPointer(ResultPtr);
}
MR.setResultPointer(ResultPtr);
}