mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-05 02:07:16 +00:00
Allow targets to avoid emitting a stub for EVERY lazily resolved call. In
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
This commit is contained in:
parent
79fe833411
commit
5e22558853
@ -96,9 +96,13 @@ namespace {
|
||||
/// 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.
|
||||
MachineCodeEmitter &MCE;
|
||||
|
||||
/// 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;
|
||||
@ -108,12 +112,24 @@ namespace {
|
||||
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);
|
||||
|
||||
/// 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.
|
||||
@ -131,10 +147,6 @@ static JITResolver &getJITResolver(MachineCodeEmitter *MCE = 0) {
|
||||
/// 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;
|
||||
@ -234,7 +246,7 @@ namespace {
|
||||
virtual uint64_t forceCompilationOf(Function *F);
|
||||
|
||||
private:
|
||||
void *getPointerToGlobal(GlobalValue *GV);
|
||||
void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
|
||||
};
|
||||
}
|
||||
|
||||
@ -242,7 +254,8 @@ MachineCodeEmitter *JIT::createEmitter(JIT &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!
|
||||
@ -261,6 +274,12 @@ void *Emitter::getPointerToGlobal(GlobalValue *V) {
|
||||
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);
|
||||
}
|
||||
@ -283,7 +302,9 @@ void Emitter::finishFunction(MachineFunction &F) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user