rui314 / mold

Mold: A Modern Linker 🦠
MIT License
14.33k stars 470 forks source link

Partial linking (-r) with LTO #509

Open marxin opened 2 years ago

marxin commented 2 years ago

I noticed that LTO is not run for partial linking:

$ cat partial.C
class Container
{
public:
  virtual ~Container ();
};

class List : public Container
{
};

static List cache[256];

int main (void)
{
  return 0;
}

$ g++-11 partial.C -c -O2 -flto -Wsuggest-final-methods && g++-11 -O2 -flto -Wsuggest-final-methods partial.o -r -nostdlib -flinker-output=nolto-rel
partial.C:7:7: warning: Declaring virtual destructor of ‘struct List’ final would enable devirtualization of 1 call [-Wsuggest-final-methods]
    7 | class List : public Container
      |       ^

while using mold:

$ g++ partial.C -c -O2 -flto -Wsuggest-final-methods && g++ -O2 -flto -Wsuggest-final-methods partial.o -r -nostdlib -flinker-output=nolto-rel

I verified that mold does not call GCC's WPA.

rui314 commented 2 years ago

Partial linking is tricky, and partial linking with LTO is trickier. Maybe we should just concatenate given LTO object files if -r is given and handle a file created such way as a bundle of object files? As long as mold creates such files and can consume them, it should work as a whole.

marxin commented 2 years ago

@janhubicka Can help us I guess.

janhubicka commented 2 years ago

There are three ways one can meaningfully partial link with LTO (all implemented in GCC) 1) one can just use ld -r and concatenate object files This is used for building kernel. 2) one can do partial LTO producing final binary. invoke lto plugin that will read the LTO bytecode and produce combined .o file containing final binary. This is commonly done in GCC testuite. I am not sure how much other practical uses we have 3) one can do partial LTO producing LTO data. Here you invoke lto plugin, read LTO bytecode and stream combined one. This should be useful to optimize link times when a common static library (such as libbackend.a in GCC) is linked into multiple binaries. At LTO stream-in the type mergin and declaration merging is done so produced combined object files works faster.

I do 1 by simply invoking ld and not using wrapper. LTO section has seeds added to it so just merging them work. This was implemented by Andi Kleen so I would need to look up the details

2/2 i do by invoking linker via plugin as Martin does. Partcular mode is done via -flinker-output=rel and -flinker-output=nolto-rel

So I assume that mold differs from gold/bfs that with -r it does not attempt to do the plugin path? Honza

On Thu, May 12, 2022 at 10:34 AM Martin Liška @.***> wrote:

@janhubicka https://github.com/janhubicka Can help us I guess.

— Reply to this email directly, view it on GitHub https://github.com/rui314/mold/issues/509#issuecomment-1124690392, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK7OQW3D3RQNWGYLJ3JJHVLVJS67VANCNFSM5VXMHPIA . You are receiving this because you were mentioned.Message ID: @.***>

marxin commented 2 years ago

It's documented here https://github.com/rui314/mold/blob/main/docs/design.md under Incremental linking bullet point.