-
Notifications
You must be signed in to change notification settings - Fork 16.2k
Description
A longstanding issue in LLVM is that it lots of internal global state, primarily in the form of cl::opt settings and ManagedStatic globals. This creates problems when users of LLVM as a library try to compile two modules at once with conflicting cl::opt settings. A library might naively call cl::ParseCommandLineOptions to set LLVM's internal options and assume that is safe to call from multiple threads, but it is not. This came up recently in @aganea 's Meta-RFC, but truly this is a longstanding issue.
I propose that we do the following:
- each cl::opt is assigned a unique option id on construction
- The LLVMContext allocates a table indexed by option id. This could naturally be a vector, but it could be a map, just to naturally accommodate options registered after context creation.
- The table contains an owning reference to storage for the option value
- Call sites that read cl::opt values should be updated to query the LLVMContext instead (one could call
MyOpt.get(Ctxt), just to keep it simple)
If we want to ease the migration path here, we could create cl::opt_ctx with the new behavior and migrate one option at a time, so that we don't break downstream users of cl::opt.
A possible alternative would be to take advantage of TLS, but LLVMContext is our usual "global compilation context" object, and I think it makes more sense to use that.