diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index b5ac6db0fd9c..a1ce4fca1847 100644 --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -21,6 +21,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/System/DynamicLibrary.h" #include "llvm/Target/TargetData.h" #include @@ -47,6 +48,73 @@ ExecutionEngine::~ExecutionEngine() { delete MP; } +/// addGlobalMapping - Tell the execution engine that the specified global is +/// at the specified location. This is used internally as functions are JIT'd +/// and as global variables are laid out in memory. It can and should also be +/// used by clients of the EE that want to have an LLVM global overlay +/// existing data in memory. +void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) { + MutexGuard locked(lock); + + void *&CurVal = state.getGlobalAddressMap(locked)[GV]; + assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!"); + CurVal = Addr; + + // If we are using the reverse mapping, add it too + if (!state.getGlobalAddressReverseMap(locked).empty()) { + const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; + assert((V == 0 || GV == 0) && "GlobalMapping already established!"); + V = GV; + } +} + +/// clearAllGlobalMappings - Clear all global mappings and start over again +/// use in dynamic compilation scenarios when you want to move globals +void ExecutionEngine::clearAllGlobalMappings() { + MutexGuard locked(lock); + + state.getGlobalAddressMap(locked).clear(); + state.getGlobalAddressReverseMap(locked).clear(); +} + +/// updateGlobalMapping - Replace an existing mapping for GV with a new +/// address. This updates both maps as required. If "Addr" is null, the +/// entry for the global is removed from the mappings. +void ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) { + MutexGuard locked(lock); + + // Deleting from the mapping? + if (Addr == 0) { + state.getGlobalAddressMap(locked).erase(GV); + if (!state.getGlobalAddressReverseMap(locked).empty()) + state.getGlobalAddressReverseMap(locked).erase(Addr); + return; + } + + void *&CurVal = state.getGlobalAddressMap(locked)[GV]; + if (CurVal && !state.getGlobalAddressReverseMap(locked).empty()) + state.getGlobalAddressReverseMap(locked).erase(CurVal); + CurVal = Addr; + + // If we are using the reverse mapping, add it too + if (!state.getGlobalAddressReverseMap(locked).empty()) { + const GlobalValue *&V = state.getGlobalAddressReverseMap(locked)[Addr]; + assert((V == 0 || GV == 0) && "GlobalMapping already established!"); + V = GV; + } +} + +/// getPointerToGlobalIfAvailable - This returns the address of the specified +/// global value if it is has already been codegen'd, otherwise it returns null. +/// +void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) { + MutexGuard locked(lock); + + std::map::iterator I = + state.getGlobalAddressMap(locked).find(GV); + return I != state.getGlobalAddressMap(locked).end() ? I->second : 0; +} + /// getGlobalValueAtAddress - Return the LLVM global value object that starts /// at the specified address. /// @@ -55,9 +123,11 @@ const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) { // If we haven't computed the reverse mapping yet, do so first. if (state.getGlobalAddressReverseMap(locked).empty()) { - for (std::map::iterator I = - state.getGlobalAddressMap(locked).begin(), E = state.getGlobalAddressMap(locked).end(); I != E; ++I) - state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second, I->first)); + for (std::map::iterator + I = state.getGlobalAddressMap(locked).begin(), + E = state.getGlobalAddressMap(locked).end(); I != E; ++I) + state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second, + I->first)); } std::map::iterator I = diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/llvm/lib/ExecutionEngine/JIT/JIT.cpp index 7262739e9266..022bd658c211 100644 --- a/llvm/lib/ExecutionEngine/JIT/JIT.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -22,6 +22,7 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/System/DynamicLibrary.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetJITInfo.h" @@ -349,8 +350,3 @@ void *JIT::recompileAndRelinkFunction(Function *F) { return Addr; } -/// freeMachineCodeForFunction - release machine code memory for given Function -/// -void JIT::freeMachineCodeForFunction(Function *F) { - // currently a no-op -} diff --git a/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp b/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp index 966b154da1f5..704fa803f81b 100644 --- a/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -26,6 +26,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetJITInfo.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/ADT/Statistic.h" #include "llvm/System/Memory.h" #include @@ -336,7 +337,14 @@ void *JIT::getPointerToFunctionOrStub(Function *F) { return getJITResolver(MCE).getFunctionStub(F); } - +/// freeMachineCodeForFunction - release machine code memory for given Function. +/// +void JIT::freeMachineCodeForFunction(Function *F) { + // Delete translation for this from the ExecutionEngine, so it will get + // retranslated next time it is used. + updateGlobalMapping(F, 0); + +} //===----------------------------------------------------------------------===// // JITEmitter code.