Reland "Compute GUIDs once and store in metadata" (#184065) #201849
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
ad94f68 to
a1a789e
Compare
🐧 Linux x64 Test Results
✅ The build succeeded and all tests passed. |
8cd8eb5 to
f053482
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
f053482 to
9926393
Compare
🪟 Windows x64 Test Results
✅ The build succeeded and all tests passed. |
13d3ad0 to
f8a1ec9
Compare
854a6f9 to
6dc97cf
Compare
|
✅ With the latest revision this PR passed the LLVM ABI annotation checker. |
6f02138 to
c7ff207
Compare
c7ff207 to
525046e
Compare
Note that some compile time performance effect in thinlto builds should be expected: we serialize/deserialize more. I think the main concern was "is there something else". re. stage1 - yes, see my earlier response ("for the single-TU compilations, the regression was attributable to modules with lots of global values but not so much IR, where the bitcode serialization of the extra GUID table would start showing up.") Re. clang-build, there's little change in the overall build timing (I don't think it's a geomean) because the individual compilation outliers like ModuleLinker were few and their negative contribution likely lost, before, in the overall parallel compilation part of the build. The rest is very likely for the same reason (more serialization) seen in the benchmarks builds, as at most we see compilation regressions within the same relative ranges for individual modules. |
|
To clarify, the regression I was concerned about is the one on bin/clang-23, i.e. the one during thin linking, not the one on individual files (pre-link). |
|
Ah, ok. About that one: Looking at the profile itself, ( Before: After: This lines up with the "we serialize more" (and so we deserialize during linking). Not sure what to make of the |
1cbfe8b to
55df97c
Compare
55df97c to
e432443
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/196/builds/20771 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/232/builds/3124 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/174/builds/37887 Here is the relevant piece of the build log for the reference |
This reverts #201194, thus relanding @orodley's PR #184065 (and #200323): > This allows us to keep GUIDs consistent across compilation phases which may change the name or linkage type. > See https://discourse.llvm.org/t/rfc-keep-globalvalue-guids-stable/84801 The CFI issues that triggered the original revert are fixed by #201370, together with the addressing of the TODOs in `LowerTypeTests.cpp` left in the latter. The [graphite diff](https://app.graphite.com/github/pr/llvm/llvm-project/201849/Reland-%23184065) between this change's V1 and V2 shows what's been added: - the `TODO`s from #201370 are done - in LowerTypeTests.cpp, passing `!guid` when creating a new declaration and when converting a definition to a declaration. - `llvm/test/Transforms/LowerTypeTests/export-icall.ll` tests also the above def->decl conversion - removed `test/Analysis/CtxProfAnalysis/flatten-prethinlink-requires-guid-metadata.ll` introduced in #194383 (this was between the revert and this PR), as now the general expectation is that GUID assignment happens appropriately and all passes use `getGUID`, so there's no reason for `CtxProfAnalysis` to do something different. Currently, we reassign GUIDs when CFI promotes internal linkage symbols, which is counter to the goal of the RFC. This is addressed in PR #203171. The reason for this split fix can be explained on `compiler-rt/test/cfi/icall/wrong-signature-mixed-lto.c`. Here, a module with the exact same source path is compiled twice, under different conditional compilation, to produce 2 objects. Each object defines an internal linkage symbol with the same name (this is `install_trap_loop_detection` from `compiler-rt/test/cfi/trap_loop_signal_handler.inc` which is `-include`\-d by both - see how `%clang_cfi` is defined). The ThinLTO GUID of this symbol will be the same. Its name won't be - because CFI promotes it and renames it using a hash that is based on the IR Module content (rather than the source path). During thinlink, `LTO::addThinLTO`will mark each of the 2 exported symbols as prevailing in their corresponding modules. But that is done by associating their GUID to the module. So whichever comes last wins. The other symbol will be marked available externally and its body DCEd later in backend. But each module will refer to its copy of `install_trap_loop_detection`, and so we end up with a linker error. As mentioned, the fix is in PR #203171, and this relanding PR just maintains the existing ThinLTO behavior by rewriting the GUIDs. Since we haven't yet leveraged the GUID mechanics for e.g. simplifying PGO, this aspect of this change is essentially NFC. Co-authored-by: Owen Rodley <[email protected]>
Prior to [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "#184065") (relanded in [#201849](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "#201849")), the code introduced in https://reviews.llvm.org/D42922 was using the GUID of an internal linkage GlobalValue to create a module id, which would then be used in a few cuda-specific places (including creating a symbol name suffix). [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "#184065") assumed the linkage of that symbol is external - which it isn't - and, thus, all module IDs computed for this would be identical. The fix is to not rely on GlobalValue GUIDs in the first place. What is needed here is a hash that's specific to this module. So we're creating that and explicitly decoupling that calculation from GlobalValue's notion of GUIDs. The change should be safe wrt uniqueness / hash collisions: the old behavior was computing a hash where the only distinguishing component was the module's `getSourceFileName`. FWIW, there's a stronger module ID we could compute, with `llvm::getUniqueModuleId` (or with a trivial refactoring of it, because it prepends a ".").
Prior to [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#184065") (relanded in [#201849](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#201849")), the code introduced in https://reviews.llvm.org/D42922 was using the GUID of an internal linkage GlobalValue to create a module id, which would then be used in a few cuda-specific places (including creating a symbol name suffix). [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#184065") assumed the linkage of that symbol is external - which it isn't - and, thus, all module IDs computed for this would be identical. The fix is to not rely on GlobalValue GUIDs in the first place. What is needed here is a hash that's specific to this module. So we're creating that and explicitly decoupling that calculation from GlobalValue's notion of GUIDs. The change should be safe wrt uniqueness / hash collisions: the old behavior was computing a hash where the only distinguishing component was the module's `getSourceFileName`. FWIW, there's a stronger module ID we could compute, with `llvm::getUniqueModuleId` (or with a trivial refactoring of it, because it prepends a ".").
Prior to [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#184065") (relanded in [#201849](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#201849")), the code introduced in https://reviews.llvm.org/D42922 was using the GUID of an internal linkage GlobalValue to create a module id, which would then be used in a few cuda-specific places (including creating a symbol name suffix). [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#184065") assumed the linkage of that symbol is external - which it isn't - and, thus, all module IDs computed for this would be identical. The fix is to not rely on GlobalValue GUIDs in the first place. What is needed here is a hash that's specific to this module. So we're creating that and explicitly decoupling that calculation from GlobalValue's notion of GUIDs. The change should be safe wrt uniqueness / hash collisions: the old behavior was computing a hash where the only distinguishing component was the module's `getSourceFileName`. FWIW, there's a stronger module ID we could compute, with `llvm::getUniqueModuleId` (or with a trivial refactoring of it, because it prepends a ".").
Prior to [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#184065") (relanded in [#201849](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#201849")), the code introduced in https://reviews.llvm.org/D42922 was using the GUID of an internal linkage GlobalValue to create a module id, which would then be used in a few cuda-specific places (including creating a symbol name suffix). [#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm/llvm-project#184065") assumed the linkage of that symbol is external - which it isn't - and, thus, all module IDs computed for this would be identical. The fix is to not rely on GlobalValue GUIDs in the first place. What is needed here is a hash that's specific to this module. So we're creating that and explicitly decoupling that calculation from GlobalValue's notion of GUIDs. The change should be safe wrt uniqueness / hash collisions: the old behavior was computing a hash where the only distinguishing component was the module's `getSourceFileName`. FWIW, there's a stronger module ID we could compute, with `llvm::getUniqueModuleId` (or with a trivial refactoring of it, because it prepends a ".").
Prior to [llvm#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm#184065") (relanded in [llvm#201849](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm#201849")), the code introduced in https://reviews.llvm.org/D42922 was using the GUID of an internal linkage GlobalValue to create a module id, which would then be used in a few cuda-specific places (including creating a symbol name suffix). [llvm#184065](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html "llvm#184065") assumed the linkage of that symbol is external - which it isn't - and, thus, all module IDs computed for this would be identical. The fix is to not rely on GlobalValue GUIDs in the first place. What is needed here is a hash that's specific to this module. So we're creating that and explicitly decoupling that calculation from GlobalValue's notion of GUIDs. The change should be safe wrt uniqueness / hash collisions: the old behavior was computing a hash where the only distinguishing component was the module's `getSourceFileName`. FWIW, there's a stronger module ID we could compute, with `llvm::getUniqueModuleId` (or with a trivial refactoring of it, because it prepends a ".").
|
IIUC, this doesn't work with Do we now require If |
Do you have a repro? The guids get assigned early so a LTO pass should find them. |
I'm not sure how to provide a repro, assuming you don't want to build ROCm components yourself.
That's the problem. We probably want to run it later. So for example, I have a bitcode library that is compiled w/o using LTO pipeline. Then this bitcode library will not have GUID. Next, when I compile another file using LTO pipeline, and then link the bitcode library via |
|
Oh, under |
|
The following can fix the issue. This is not just for ThinLTO though, since full LTO also emits module summary, and I think the assertion I've seen is in the module summary pass. That's why I added it there instead of further down. |
|
why would you need it for thinlto though - for thinlto, we perform it as part of the regular LLVM PassBuilderPipeline.cpp pipelines. |
I suppose even for ThinLTO, a bitcode library without GUID can also be linked via Are you suggesting something like: |
|
Normal ThinLTO (in proc or distributed) doesn't need it in clang because it is handled fine in the PassBuilderPipeline.cpp side of things. This feature - I'd add it right above LinKInModulesPass(BC) |

This reverts #201194, thus relanding @orodley's PR #184065 (and #200323):
The CFI issues that triggered the original revert are fixed by #201370, together with the addressing of the TODOs in
LowerTypeTests.cppleft in the latter. The graphite diff between this change's V1 and V2 shows what's been added:TODOs from [CFI][ThinLTO] Remove the need for CFI calculating ThinLTO GUIDs #201370 are done!guidwhen creating a new declaration and when converting a definition to a declaration.llvm/test/Transforms/LowerTypeTests/export-icall.lltests also the above def->decl conversiontest/Analysis/CtxProfAnalysis/flatten-prethinlink-requires-guid-metadata.llintroduced in [CtxProf] emit fatal usage error when flatten-prethinlink runs without guid metadata #194383 (this was between the revert and this PR), as now the general expectation is that GUID assignment happens appropriately and all passes usegetGUID, so there's no reason forCtxProfAnalysisto do something different.Currently, we reassign GUIDs when CFI promotes internal linkage symbols, which is counter to the goal of the RFC. This is addressed in PR #203171. The reason for this split fix can be explained on
compiler-rt/test/cfi/icall/wrong-signature-mixed-lto.c. Here, a module with the exact same source path is compiled twice, under different conditional compilation, to produce 2 objects. Each object defines an internal linkage symbol with the same name (this isinstall_trap_loop_detectionfromcompiler-rt/test/cfi/trap_loop_signal_handler.incwhich is-include-d by both - see how%clang_cfiis defined). The ThinLTO GUID of this symbol will be the same. Its name won't be - because CFI promotes it and renames it using a hash that is based on the IR Module content (rather than the source path). During thinlink,LTO::addThinLTOwill mark each of the 2 exported symbols as prevailing in their corresponding modules. But that is done by associating their GUID to the module. So whichever comes last wins. The other symbol will be marked available externally and its body DCEd later in backend. But each module will refer to its copy ofinstall_trap_loop_detection, and so we end up with a linker error.As mentioned, the fix is in PR #203171, and this relanding PR just maintains the existing ThinLTO behavior by rewriting the GUIDs. Since we haven't yet leveraged the GUID mechanics for e.g. simplifying PGO, this aspect of this change is essentially NFC.
Co-authored-by: Owen Rodley [email protected]