I have a Module/LLVMContext that I'd like to clone and manipulate in different threads (each thread may perform different translation / optimization, so they need unique copies). Currently this process has to be locked, since each clone of the Module still refers to the same LLVMContext. Is there a way to clone both the Module and LLVMContext so that the copies can be manipulated independently in different threads?
You could probably round trip it through bitcode in memory. I think all of the IR cloning functionality assumes that only one context is being used. Even if the serialization isn’t efficient as a clone could be, it should give you very high confidence that everything Just Works.
Sorry to resurrect an old thread, but I finally got around to testing this approach (round tripping through bitcode in memory) and it works beautifully - and isn’t that much slower than cloning.
I have noticed however that the copy process isn’t thread-safe. The problem is that in Function, there is lazy initialization code for arguments:
I’ve worked around this by calling Function::getArgumentList() outside the threaded code to harden it before the threaded copies. Are there other lazy data structures that need to be solidified before threading? Should I be playing it safe and put a thread lock around the entire copy procedure?
In case you are interested, here is the algorithm I’m using to copy a Module to a same (or different) LLVMContext:
if (&context == &other.myContext)
{
// If the context is shared, we can use cloning
ValueToValueMapTy map;
myModule = CloneModule(other.myModule, map);
}
else
{
// Otherwise, round trip the module to a stream and then back
// into the new context. This approach allows for duplication
// and optimization to proceed in parallel for different
// modules.
std::string str;
raw_string_ostream stream(str);
WriteBitcodeToFile(other.myModule, stream);
Sorry to resurrect an old thread, but I finally got around to testing
this approach (round tripping through bitcode in memory) and it works
beautifully - and isn't that much slower than cloning.
I have noticed however that the copy process isn't thread-safe. The
problem is that in Function, there is lazy initialization code for
arguments:
If you're interested, I think we shouldn't make this lazy at all, I don't
think it buys us anything. I once filed llvm.org/PR16536 with what I think
we should do, though it's a fundamental change that is may be more work
than you want to take on.
Nick
I've worked around this by calling Function::getArgumentList() outside the