COFF requires that every comdat contain a symbol with the same name as
the comdat. ThinLTOBitcodeWriter renames symbols, which may cause this
requirement to be violated. This change avoids such violations by
renaming comdats if their leaders are renamed. It also keeps comdats
together when splitting modules.
Details
Diff Detail
- Build Status
Buildable 5475 Build 5475: arc lint + arc unit
Event Timeline
This is an alternative to D31735. Instead of deleting comdats that are invalidated, it keeps comdats valid by keeping their members in the same module and renaming the comdat if its leader is renamed. I think this is a cleaner solution.
lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | ||
---|---|---|
306 | I don't think you need to extract this lambda. The appropriate test is just whether the GlobalValue is a GlobalVariable with type metadata. The canonical definitions of any virtual functions identified by this lambda live in the thin LTO module, and the copies in the merged module are used for optimization only and are not comdat members (see line 347 below). So your code for identifying comdats could be added to the loop above. | |
351 | The code above should guarantee that if a module contains one member of a comdat it will also contain all other members. So I think you can now apply comdat renaming in promoteInternals. | |
test/Transforms/ThinLTOBitcodeWriter/comdat.ll | ||
6–27 | Please move these checks next to the corresponding input IR (where possible). |
lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | ||
---|---|---|
306 | Yes. The way I wrote this actually introduces a bug where we can end up with functions available_externally in MergedM, and no definition in M. I'm working on a fix. |
test/Transforms/ThinLTOBitcodeWriter/comdat.ll | ||
---|---|---|
6–27 | What is a good way to do that? When I wrote the checks next to the IR, I got errors, because the IR was emitted in a different order from how I wrote it. Specifically, all the comdat declarations come first, then all the globals, then all the functions. So I could reorder my code to be in that same order, but that would mix things from different comdats together, which, as you pointed out elsewhere, made the test harder to read. I thought this was a reasonable compromise - putting all the same comdats together in the IR, and putting the same modules together in the checks. But if you have a better suggestion, I'm all ears. |
test/Transforms/ThinLTOBitcodeWriter/comdat.ll | ||
---|---|---|
6–27 | The main thing that made your previous test hard to read was the fact that the global variables from different comdats were not grouped, combined with the choice of names. It's fine if you separate comdats from global variables from aliases from functions, as long as the global variables are grouped and all names are prefixed. | |
42 | I think you need to add a comdat($lwt) here if you intend this to be a member of lwt. It also doesn't look like you have any tests for this function. | |
60 | Same here. | |
75 | Same here. |
Implemented more of @pcc's suggestions:
- Use Comdat* instead of StringRef in MergedMComdats.
- Populate MergedMComdats in existing loop instead of creating a new one.
- Remove regexes when matching unpromoted names.
I think that's all your comments, @pcc. The functions are just there to make sure the globals are used. I've added a comment to that effect. The functions are purposely not part of the comdats, so that they can be externally visible without causing the comdats to have externally visible members.
I don't think you need to extract this lambda. The appropriate test is just whether the GlobalValue is a GlobalVariable with type metadata. The canonical definitions of any virtual functions identified by this lambda live in the thin LTO module, and the copies in the merged module are used for optimization only and are not comdat members (see line 347 below). So your code for identifying comdats could be added to the loop above.