aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/JIT/JITEmitter.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-01-04 10:46:51 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-01-04 10:46:51 +0000
commitbe8c03fc66b75fa775e1f47d62a1b0d803fced1c (patch)
treef7d4aff605c112d72392dd096356c1b12e72ce62 /lib/ExecutionEngine/JIT/JITEmitter.cpp
parent2674d71df02f562cf8c3bc011be92d6dcb9cd9aa (diff)
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
Diffstat (limited to 'lib/ExecutionEngine/JIT/JITEmitter.cpp')
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index beeca3b0f6..aa572a408f 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -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()) {