Relation between MSVC Compiler & linker option for COMDAT folding
Asked Answered
D

2

7

This question has some answers on SO but mine is slightly different. Before marking as duplicate, please give it a shot.

MSVC has always provided the /Gy compiler option to enable identical functions to be folded into COMDAT sections. At the same time, the linker also provides the /OPT:ICF option. Is my understanding right that these two options must be used in conjunction? That is, while the former packages functions into COMDAT, the latter eliminates redundant COMDATs. Is that correct?

If yes, then either we use both or turn off both?

Dishonor answered 11/11, 2016 at 19:29 Comment(1)
Yeah, that's a bit overkill to have to do this both in the compiler and the linker. /OPT:ICF is however pretty expensive and you do have the option to provide the iterations argument to keep link time somewhat reasonable. The probable reason it was done like this.Gorski
D
4

Answer from someone who communicated with me off-line. Helped me understand these options a lot better.

===================================

That is essentially true. Suppose we talk just C, or C++ but with no member functions. Without /Gy, the compiler creates object files that are in some sense irreducible. If the linker wants just one function from the object, it gets them all. This is specially a consideration in programming for libraries, such that if you mean to be kind to the library's users, you should write your library as lots of small object files, typically one non-static function per object, so that the user of the library doesn't bloat from having to carry code that actually never executes.

With /Gy, the compiler creates object files that have COMDATs. Each function is in its own COMDAT, which is to some extent a mini-object. If the linker wants just one function from the object, it can pick out just that one. The linker's /OPT switch gives you some control over what the linker does with this selectivity - but without /Gy there's nothing to select.

Or very little. It's at least conceivable that the linker could, for instance, fold functions that are each the whole of the code in an object file and happen to have identical code. It's certainly conceivable that the linker could eliminate a whole object file that contains nothing that's referenced. After all, it does this with object files in libraries. The rule in practice, however, used to be that if you add a non-COMDAT object file to the linker's command line, then you're saying you want that in the binary even if unreferenced. The difference between what's conceivable and what's done is typically huge.

Best, then, to stick with the quick answer. The linker options benefit from being able to separate functions (and variables) from inside each object file, but the separation depends on the code and data to have been organised into COMDATs, which is the compiler's work.

===================================

Dishonor answered 14/11, 2016 at 20:29 Comment(0)
A
1

As answered by Raymond Chen in Jan 2013

As explained in the documentation for /Gy, function-level linking allows functions to be discardable during the "unused function" pass, if you ask for it via /OPT:REF. It does not alter the actual classical model for linking. The flag name is misleading. It's not "perform function-level linking". It merely enables it by telling the linker where functions begin and end. And it's not so much function-level linking as it is function-level unlinking. -Raymond

(This snippet might make more sense with some further context:here are the posts about classical linking model:1, 2

So in a nutshell - yes. If you activate one switch without the other, there would be no observable impact.

Actinoid answered 14/11, 2016 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.