diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-01-04 10:46:51 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-01-04 10:46:51 +0000 |
commit | be8c03fc66b75fa775e1f47d62a1b0d803fced1c (patch) | |
tree | f7d4aff605c112d72392dd096356c1b12e72ce62 /lib/ExecutionEngine/JIT/JITEmitter.cpp | |
parent | 2674d71df02f562cf8c3bc011be92d6dcb9cd9aa (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.cpp | 49 |
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()) { |