llvm / llvm/llvm-project

LLVM cl::opt global variables create state conflicts for multi-threaded compilation

Open
#182,385 28 comments 3 reactions 0 assignees View on GitHub
llvm
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

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](https://discourse.llvm.org/t/meta-rfc-long-term-vision-for-improving-build-times/89828), 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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.