Attempt #1: JIT Thread Safety

This is what I was trying to do when I ran into the HowToUseJIT problem. I've made a first attempt at adding locking to the JIT. Unfortunately, since I do not really understand the structure of LLVM, I could have very easily screwed something up. I touched two classes, the JIT and the ExecutionEngine. I need some help from someone who is more familiar with the code to make sure that I have protected the correct data structures. I'm also looking for suggestion about how to test this for correctness.

To make sure that I added locks where required, I moved "dangerous" members of the classes into a new class, called JITState and ExecutionEngineState, respectively. These classes only allow access to the variables if a lock is held. This allows the compiler to verify that locks are held in the correct places, although there could still easily be bugs if the locks are released too early. The data structures that are protected are:

ExecutionEngine:
std::map<const GlobalValue*, void *> GlobalAddressMap; // R/W data structure
std::map<void *, const GlobalValue*> GlobalAddressReverseMap; // R/W data structure

JIT:
std::vector<const GlobalVariable*> PendingGlobals; // R/W data structure
FunctionPassManager PM; // Could call passes which are not thread safe

Both of these classes have additional members which I have not protected. It looked to my brief analysis that they were used in a read-only fashion. Can anyone tell me if I am wrong:

ExecutionEngine:
Module &CurMod;
const TargetData *TD;

JIT:
TargetMachine &TM;
TargetJITInfo &TJI;
MachineCodeEmitter *MCE;

I specifically did not protect the ExecutionEngine::CurMod member because a reference is returned via ExecutionEngine::getModule(). If access to it must be serialized, it must be done very carefully. I tried to make getModule return a constant reference, but that quickly led me into deep trouble in the world of const correctness.

I've attached my patch against the latest CVS. There is one "trivial" fix which should be committed, even if this patch is incorrect. In ThreadSupport.h, the include guard macro needs to have "LLVM_" prefixed to it. The ThreadSupport-PThread.h and ThreadSupport-NoSupport.h files look for the macro with this prefix.

Thank you,

Evan Jones

llvm-threadsafe.patch (12.9 KB)