Currently we do not represent runtime preemption in the IR, which has several drawbacks:
- The semantics of GlobalValues differ depending on the object file format you are targeting (as well as the relocation-model and -fPIE value).
- We have no way of disabling inlining of run time interposable functions, since in the IR we only know if a function is link-time interposable. Because of this llvm cannot support elf-interposition semantics.
- In LTO builds of executables we will have extra knowledge that a symbol resolved to a local definition and can't be preemptable, but have no way to propagate that knowledge through the compiler.
This patch adds preemptability specifiers to the IR with the following meaning:
dso_local means the compiler may assume the symbol will resolve to a definition within the current linkage unit and the symbol may be accessed directly even if the definition is not within this compilation unit.
dso_preemptable means that the compiler must assume the GlobalValue may be replaced with a definition from outside the current linkage unit at runtime.
There is a question with the implementation though: should these be optional, or do we eventually want these to be required on every GlobalValue? My motivation for picking up this patch is to resolve the lto limitation, and that can be done equally well either way. I believe the original motivation though was issues 1 and 2. To support an option like '-fsemantic-interposition' then clang will need to properly mark the global values with dso_local/dso_preemptable, and we can support older bitcode files simply by treating global values as preemptable when not marked as explicitly dso_local. That will be pessimistic with old bitcode but at least have the correct semantics and not require breaking compatibility. I would appreciate some feedback in this area, how do people want to proceed?