X86 PIC JIT support fixes: encoding bugs, add lazy pointer stubs support.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45575 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2008-01-04 10:46:51 +00:00
parent 2674d71df0
commit be8c03fc66
6 changed files with 154 additions and 32 deletions

View File

@@ -52,6 +52,10 @@ namespace {
/// corresponds to.
std::map<void*, Function*> StubToFunctionMap;
/// GlobalToLazyPtrMap - Keep track of the lazy pointer created for a
/// particular GlobalVariable so that we can reuse them if necessary.
std::map<GlobalValue*, void*> GlobalToLazyPtrMap;
public:
std::map<Function*, void*>& getFunctionToStubMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock));
@@ -62,6 +66,12 @@ namespace {
assert(locked.holds(TheJIT->lock));
return StubToFunctionMap;
}
std::map<GlobalValue*, void*>&
getGlobalToLazyPtrMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock));
return GlobalToLazyPtrMap;
}
};
/// JITResolver - Keep track of, and resolve, call sites for functions that
@@ -103,6 +113,10 @@ namespace {
/// specified address, created lazily on demand.
void *getExternalFunctionStub(void *FnAddr);
/// getGlobalValueLazyPtr - Return a lazy pointer containing the specified
/// GV address.
void *getGlobalValueLazyPtr(GlobalValue *V, void *GVAddress);
/// 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.
@@ -181,6 +195,25 @@ void *JITResolver::getFunctionStub(Function *F) {
return Stub;
}
/// getGlobalValueLazyPtr - Return a lazy pointer containing the specified
/// GV address.
void *JITResolver::getGlobalValueLazyPtr(GlobalValue *GV, void *GVAddress) {
MutexGuard locked(TheJIT->lock);
// If we already have a stub for this global variable, recycle it.
void *&LazyPtr = state.getGlobalToLazyPtrMap(locked)[GV];
if (LazyPtr) return LazyPtr;
// Otherwise, codegen a new lazy pointer.
LazyPtr = TheJIT->getJITInfo().emitGlobalValueLazyPtr(GVAddress,
*TheJIT->getCodeEmitter());
DOUT << "JIT: Stub emitted at [" << LazyPtr << "] for GV '"
<< GV->getName() << "'\n";
return LazyPtr;
}
/// getExternalFunctionStub - Return a stub for the function at the
/// specified address, created lazily on demand.
void *JITResolver::getExternalFunctionStub(void *FnAddr) {
@@ -361,6 +394,8 @@ namespace {
}
private:
void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
bool NoNeedStub);
};
}
@@ -396,6 +431,16 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
return Resolver.getFunctionStub(F);
}
void *JITEmitter::getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
bool DoesntNeedStub) {
// Make sure GV is emitted first.
// FIXME: For now, if the GV is an external function we force the JIT to
// compile it so the lazy pointer will contain the fully resolved address.
void *GVAddress = getPointerToGlobal(V, Reference, true);
return Resolver.getGlobalValueLazyPtr(V, GVAddress);
}
void JITEmitter::startFunction(MachineFunction &F) {
uintptr_t ActualSize;
BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
@@ -450,6 +495,10 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
BufferBegin+MR.getMachineCodeOffset(),
MR.doesntNeedStub());
} else if (MR.isGlobalValueLazyPtr()) {
ResultPtr = getPointerToGVLazyPtr(MR.getGlobalValue(),
BufferBegin+MR.getMachineCodeOffset(),
MR.doesntNeedStub());
} else if (MR.isBasicBlock()) {
ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock());
} else if (MR.isConstantPoolIndex()) {