[lto] proper way to handle COMDAT

Cary Coutant ccoutant@google.com
Thu Dec 11 00:03:00 GMT 2008


> Since the linker plugin directly instructs the compiler which symbols
> to generate, it should never be necessary for lto1 to emit a COMDAT.
> In fact, using COMDAT can confuse the linker if the plugin is used.
> This was the case in the resent problem with a nop plugin that Cary
> just fixed on gold.
>
> Never emitting a COMDAT should be no problem if the linker gets all
> the files at once. But consider the case where we do two partial
> links, each with a subset of the input files. The first partial link
> produces A.o and the second one B.o. A template instantiation (for
> example) that would normally be in a COMDAT will be outside and will
> exist in both A.o and B.o.

It's not actually clear to me what a partial link should actually do
-- should it just combine the IR files, deferring optimization for the
final link, or should it actually run the WPA phase and produce a
fully-compiled relocatable object? I can see arguments on both sides
and I think we could justify providing both options. If, however, the
partial link includes a mixture of IR files and regular object files,
we don't really have a good way of deferring the compilation -- we
can't put the code from the regular objects into the same output file
as the combined IR, as the next link step would then just ignore
everything that's not IR.

If we do run WPA during a partial link, where we don't have complete
visibility over the entire program, we will have to put template
instantiations and out-of-line inlines in COMDAT sections. Now that
the linker can handle this correctly, that shouldn't be a problem.

(One other note about running WPA during a partial link: If you have a
global symbol defined in IR, and the linker returns a resolution of
"IR only", you can't assume it's visible only from within the IR you
have. Perhaps I should change the linker so that it never returns the
"IR only" resolution during a -r link?)

The idea of not putting anything in COMDAT during a full link was kind
of idealistic, and I originally thought it would keep the linker
implementation simple. As it turned out, it wasn't that big a deal to
handle in the linker, and it seems that it's not really worth trying
to do in lto1.

> Nick Kledzik (kledzik@apple.com) noted that the apple solution was to
> use the garbage collector in the linker. In the above example, if the
> linker selects the template instantiation from A.o, any data used by
> the instantiation in B.o is now dead and is removed.
>
> Cary, do you think we can do the same? That would make things very
> simple for lto1 :-)

Using COMDAT/linkonce achieves the same effect. It's cheaper too,
since we can toss the duplicate sections without even reading them,
rather than wait for a GC pass to eliminate them.

-cary



More information about the Gcc-patches mailing list