COMDAT resolution for LLVM Dialect linker #79
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The general idea is that the COMDAT group conflicts have to be resolved before the module is being linked (because COMDAT groups are used/thrown away as a whole), for that I added a hook to the linker that allows "presummary" of a module (
moduleOpSummary()). After that, the COMDAT conflict resolution is fairly simple, after I finally understood how it's supposed to be done (resources bellow).The "tricky" part about it is that it has to modify the already summarized operations.
The whole process is basically like this:
isLinkNeededfor LLVM Dialect linking uses the COMDAT resolution to see if it was selected by a COMDAT. If yes, it says the symbol has to be linked. Note: if a COMDAT is replacing another COMDAT, the symbols form the replaced COMDAT are dropped to declarations, so the conflict resolution is usually simple. The declarations are stripped of COMDAT and do not participate in COMDAT resolution anymore (this is necessary to keep the IR valid; llvm-link does the same). The exception areNoDeduplicateCOMDATs which should be handled in the conflict resolution.The missing stuff:
llvm-linkfor reference)llvm-linkgetConflictResolution(); seellvm-linkfor reference)The main references in llvm-link are in the file
llvm/lib/Linker/LinkModules.cpp:getComdatResult()(and the functions used by it)run()(precomputing the COMDAT resolution and handling dropping of the operations)linkIfNeeded()(for nodeduplicate comdat conflict handling)Some resources I found useful for understanding COMDAT and linking of COMDAT (althoug they are a bit sparse… Unfortunately reading the code of
llvm-linkwas a must):https://github.com/incc-project/inccblog/blob/main/linking/comdat.md
https://maskray.me/blog/2021-07-25-comdat-and-section-group
https://habr.com/en/articles/458442/ (not that helpful, but might help draw the whole picture)