summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/JIT/JIT.cpp
diff options
context:
space:
mode:
authorJeffrey Yasskin <jyasskin@google.com>2010-02-11 01:07:39 +0000
committerJeffrey Yasskin <jyasskin@google.com>2010-02-11 01:07:39 +0000
commit40966a7c6847c102fbf466da3e8726c59c3dbb1e (patch)
treeea8915adc7d6f5938961424cbb6c5b0b96749dbe /lib/ExecutionEngine/JIT/JIT.cpp
parent09eeac9f5f8c21621f82f9b6598eb7e34593357e (diff)
downloadllvm-40966a7c6847c102fbf466da3e8726c59c3dbb1e.tar.gz
llvm-40966a7c6847c102fbf466da3e8726c59c3dbb1e.tar.bz2
llvm-40966a7c6847c102fbf466da3e8726c59c3dbb1e.tar.xz
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
Diffstat (limited to 'lib/ExecutionEngine/JIT/JIT.cpp')
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp53
1 files changed, 51 insertions, 2 deletions
diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp
index 616a66e18a..59a9a3dfe0 100644
--- a/lib/ExecutionEngine/JIT/JIT.cpp
+++ b/lib/ExecutionEngine/JIT/JIT.cpp
@@ -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