Make it possible to create multiple JIT instances at the same time, by removing

the global TheJIT and TheJITResolver variables.  Lazy compilation is supported
by a global map from a stub address to the JITResolver that knows how to
compile it.

Patch by Olivier Meurant!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95837 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jeffrey Yasskin
2010-02-11 01:07:39 +00:00
parent 09eeac9f5f
commit 40966a7c68
5 changed files with 297 additions and 43 deletions
+51 -2
View File
@@ -18,6 +18,7 @@
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/JITCodeEmitter.h"
#include "llvm/CodeGen/MachineCodeInfo.h"
#include "llvm/ExecutionEngine/GenericValue.h"
@@ -27,6 +28,7 @@
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Config/config.h"
@@ -237,9 +239,53 @@ ExecutionEngine *JIT::createJIT(Module *M,
}
}
namespace {
/// This class supports the global getPointerToNamedFunction(), which allows
/// bugpoint or gdb users to search for a function by name without any context.
class JitPool {
SmallPtrSet<JIT*, 1> JITs; // Optimize for process containing just 1 JIT.
mutable sys::Mutex Lock;
public:
void Add(JIT *jit) {
MutexGuard guard(Lock);
JITs.insert(jit);
}
void Remove(JIT *jit) {
MutexGuard guard(Lock);
JITs.erase(jit);
}
void *getPointerToNamedFunction(const char *Name) const {
MutexGuard guard(Lock);
assert(JITs.size() != 0 && "No Jit registered");
//search function in every instance of JIT
for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(),
end = JITs.end();
Jit != end; ++Jit) {
if (Function *F = (*Jit)->FindFunctionNamed(Name))
return (*Jit)->getPointerToFunction(F);
}
// The function is not available : fallback on the first created (will
// search in symbol of the current program/library)
return (*JITs.begin())->getPointerToNamedFunction(Name);
}
};
ManagedStatic<JitPool> AllJits;
}
extern "C" {
// getPointerToNamedFunction - This function is used as a global wrapper to
// JIT::getPointerToNamedFunction for the purpose of resolving symbols when
// bugpoint is debugging the JIT. In that scenario, we are loading an .so and
// need to resolve function(s) that are being mis-codegenerated, so we need to
// resolve their addresses at runtime, and this is the way to do it.
void *getPointerToNamedFunction(const char *Name) {
return AllJits->getPointerToNamedFunction(Name);
}
}
JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode)
: ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode) {
: ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode),
isAlreadyCodeGenerating(false) {
setTargetData(TM.getTargetData());
jitstate = new JITState(M);
@@ -247,6 +293,9 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
// Initialize JCE
JCE = createEmitter(*this, JMM, TM);
// Register in global list of all JITs.
AllJits->Add(this);
// Add target data
MutexGuard locked(lock);
FunctionPassManager &PM = jitstate->getPM(locked);
@@ -281,6 +330,7 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
}
JIT::~JIT() {
AllJits->Remove(this);
delete jitstate;
delete JCE;
delete &TM;
@@ -570,7 +620,6 @@ void JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) {
}
void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) {
static bool isAlreadyCodeGenerating = false;
assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!");
// JIT the function