diff options
author | Chris Lattner <sabre@nondot.org> | 2010-07-11 23:07:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-07-11 23:07:28 +0000 |
commit | 68feb22ad8e7e3b5cd97312ef105505b3c554d40 (patch) | |
tree | 9024316ad8e470ebc8d4c05116c59789a32915a6 /lib/ExecutionEngine/JIT | |
parent | b162290e39afd49d4c7d342333b331bc96232720 (diff) | |
download | external_llvm-68feb22ad8e7e3b5cd97312ef105505b3c554d40.zip external_llvm-68feb22ad8e7e3b5cd97312ef105505b3c554d40.tar.gz external_llvm-68feb22ad8e7e3b5cd97312ef105505b3c554d40.tar.bz2 |
first part of JIT support for address of labels, part of PR7264,
patch by Yuri!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108107 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/JIT')
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.cpp | 54 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.h | 30 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 10 |
3 files changed, 81 insertions, 13 deletions
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 546d2b2..67bd3ed 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -626,10 +626,7 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) { void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!"); - // JIT the function - isAlreadyCodeGenerating = true; - jitstate->getPM(locked).run(*F); - isAlreadyCodeGenerating = false; + jitTheFunction(F, locked); // If the function referred to another function that had not yet been // read from bitcode, and we are jitting non-lazily, emit it now. @@ -640,10 +637,7 @@ void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { assert(!PF->hasAvailableExternallyLinkage() && "Externally-defined function should not be in pending list."); - // JIT the function - isAlreadyCodeGenerating = true; - jitstate->getPM(locked).run(*PF); - isAlreadyCodeGenerating = false; + jitTheFunction(PF, locked); // Now that the function has been jitted, ask the JITEmitter to rewrite // the stub with real address of the function. @@ -651,6 +645,15 @@ void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { } } +void JIT::jitTheFunction(Function *F, const MutexGuard &locked) { + isAlreadyCodeGenerating = true; + jitstate->getPM(locked).run(*F); + isAlreadyCodeGenerating = false; + + // clear basic block addresses after this function is done + getBasicBlockAddressMap(locked).clear(); +} + /// getPointerToFunction - This method is used to get the address of the /// specified function, compiling it if neccesary. /// @@ -687,6 +690,41 @@ void *JIT::getPointerToFunction(Function *F) { return Addr; } +void JIT::addPointerToBasicBlock(const BasicBlock *BB, void *Addr) { + MutexGuard locked(lock); + + BasicBlockAddressMapTy::iterator I = + getBasicBlockAddressMap(locked).find(BB); + if (I == getBasicBlockAddressMap(locked).end()) { + getBasicBlockAddressMap(locked)[BB] = Addr; + } else { + // ignore repeats: some BBs can be split into few MBBs? + } +} + +void JIT::clearPointerToBasicBlock(const BasicBlock *BB) { + MutexGuard locked(lock); + getBasicBlockAddressMap(locked).erase(BB); +} + +void *JIT::getPointerToBasicBlock(BasicBlock *BB) { + // make sure it's function is compiled by JIT + (void)getPointerToFunction(BB->getParent()); + + // resolve basic block address + MutexGuard locked(lock); + + BasicBlockAddressMapTy::iterator I = + getBasicBlockAddressMap(locked).find(BB); + if (I != getBasicBlockAddressMap(locked).end()) { + return I->second; + } else { + assert(0 && "JIT does not have BB address for address-of-label, was" + " it eliminated by optimizer?"); + return 0; + } +} + /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the /// Emitter. diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index edae719..831f528 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -51,6 +51,10 @@ public: class JIT : public ExecutionEngine { + /// types + typedef ValueMap<const BasicBlock *, void *> + BasicBlockAddressMapTy; + /// data TargetMachine &TM; // The current target we are compiling to TargetJITInfo &TJI; // The JITInfo for the target we are compiling to JITCodeEmitter *JCE; // JCE object @@ -67,6 +71,12 @@ class JIT : public ExecutionEngine { JITState *jitstate; + /// BasicBlockAddressMap - A mapping between LLVM basic blocks and their + /// actualized version, only filled for basic blocks that have their address + /// taken. + BasicBlockAddressMapTy BasicBlockAddressMap; + + JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool AllocateGVsWithCode); @@ -127,10 +137,15 @@ public: /// void *getPointerToFunction(Function *F); - void *getPointerToBasicBlock(BasicBlock *BB) { - assert(0 && "JIT does not support address-of-label yet!"); - return 0; - } + /// addPointerToBasicBlock - Adds address of the specific basic block. + void addPointerToBasicBlock(const BasicBlock *BB, void *Addr); + + /// clearPointerToBasicBlock - Removes address of specific basic block. + void clearPointerToBasicBlock(const BasicBlock *BB); + + /// getPointerToBasicBlock - This returns the address of the specified basic + /// block, assuming function is compiled. + void *getPointerToBasicBlock(BasicBlock *BB); /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the @@ -197,11 +212,18 @@ public: const JITEvent_EmittedFunctionDetails &Details); void NotifyFreeingMachineCode(void *OldPtr); + BasicBlockAddressMapTy & + getBasicBlockAddressMap(const MutexGuard &) { + return BasicBlockAddressMap; + } + + private: static JITCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM, TargetMachine &tm); void runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked); void updateFunctionStub(Function *F); + void jitTheFunction(Function *F, const MutexGuard &locked); protected: diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index e3855b2..28d79da 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -435,6 +435,9 @@ namespace { if (MBBLocations.size() <= (unsigned)MBB->getNumber()) MBBLocations.resize((MBB->getNumber()+1)*2); MBBLocations[MBB->getNumber()] = getCurrentPCValue(); + if (MBB->hasAddressTaken()) + TheJIT->addPointerToBasicBlock(MBB->getBasicBlock(), + (void*)getCurrentPCValue()); DEBUG(dbgs() << "JIT: Emitting BB" << MBB->getNumber() << " at [" << (void*) getCurrentPCValue() << "]\n"); } @@ -442,7 +445,7 @@ namespace { virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; - virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { + virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const{ assert(MBBLocations.size() > (unsigned)MBB->getNumber() && MBBLocations[MBB->getNumber()] && "MBB not emitted!"); return MBBLocations[MBB->getNumber()]; @@ -1310,6 +1313,11 @@ void JITEmitter::retryWithMoreMemory(MachineFunction &F) { deallocateMemForFunction(F.getFunction()); // Try again with at least twice as much free space. SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin)); + + for (MachineFunction::iterator MBB = F.begin(), E = F.end(); MBB != E; ++MBB){ + if (MBB->hasAddressTaken()) + TheJIT->clearPointerToBasicBlock(MBB->getBasicBlock()); + } } /// deallocateMemForFunction - Deallocate all memory for the specified |