Stream: t-compiler

Topic: Garbage collecting debug info


Nikhil Benesch (Apr 18 2020 at 18:18, on Zulip):

Is there anyone informed about rustc's debug info generation who could chime in on an LLVM diff? https://reviews.llvm.org/D74169#1990625

The tl;dr is that Rust currently generates a massive amount of unnecessary debug info (https://github.com/rust-lang/rust/issues/56068) because its codegen units are _huge_. This isn't a problem for the actual text segment because the linker garbage collects unused sections, but no linker presently garbage collects the DWARF associated with those unused sections. The diff linked above adds a --gc-debuginfo flag to lld that seems exactly like what we need, but there is presently a massive link-time penalty. One of the LLVM devs upstream is asking whether there is existing work to optimize this on Rust's end, and I don't know the answer!

Jonas Schievink (Apr 18 2020 at 18:22, on Zulip):

No active work from what I know, but maybe @eddyb has something in the pipeline. Seems like that issue went under the radar.

eddyb (Apr 18 2020 at 18:23, on Zulip):

nope but I would love to be able to dedup debuginfo between CGUs

eddyb (Apr 18 2020 at 18:24, on Zulip):

lld growing functionality like this is awesome!

Nikhil Benesch (Apr 18 2020 at 18:26, on Zulip):

Agreed! Unfortunately it is sloooooooow. The lld patch is still pretty WIP, so unclear if there's just missing optimizations or if there's something fundamentally polynomial about the approach. --gc-sections increased link time from 10s to 240s (!) on the binary I was testing.

Nikhil Benesch (Apr 18 2020 at 18:28, on Zulip):

@eddyb would you expect to see a decrease in debug info size with codegen-units = 1? That's interesting.

eddyb (Apr 18 2020 at 18:29, on Zulip):

well, it can't be less than that

eddyb (Apr 18 2020 at 18:29, on Zulip):

but I was also thinking cross-crate

eddyb (Apr 18 2020 at 18:30, on Zulip):

which I guess we could measure

eddyb (Apr 18 2020 at 18:31, on Zulip):

you compile all the dependency crates with that flag to only serialize MIR and do no codegen, then compile the final crate with 1 CGU

eddyb (Apr 18 2020 at 18:32, on Zulip):

that should be the minimal size both in terms of LLVM IR and debuginfo (but LLVM passes may increase the total machine code)

Nikhil Benesch (Apr 18 2020 at 18:34, on Zulip):

Is that the -Zmir-only-rlibs flag?

Nikhil Benesch (Apr 18 2020 at 18:49, on Zulip):

Hmm, that flag doesn't seem to exist. Anyway, just compiling everything with codegen-units = 1 cut the size of .debug_info by 40% (!). Unfortunately it makes compile times on this project untenable, but still intriguing.

eddyb (Apr 18 2020 at 20:45, on Zulip):

right, it removes parallelism

eddyb (Apr 18 2020 at 20:46, on Zulip):

@Nikhil Benesch hmm, -Z always-encode-mir but what you mention makes more sense

eddyb (Apr 18 2020 at 20:46, on Zulip):

I wonder when that went away

Nikhil Benesch (Apr 18 2020 at 20:50, on Zulip):

Yeah, sorry, compile time increase with 1 CGU is totally expected. I'm just musing that even in our CI release pipeline we are unlikely to want to take the 4x increase in compile time for a 40% reduction in debug info.

Nikhil Benesch (Apr 18 2020 at 20:50, on Zulip):

I would, however, be interested in poking at doing some DWARF deduplication in rustc! But I'd probably need a pointer or two.

eddyb (Apr 18 2020 at 20:50, on Zulip):

you could try to compare it to full LTO

eddyb (Apr 18 2020 at 20:51, on Zulip):

@Nikhil Benesch we can't do it in rustc. or rather, this is a linker thing

eddyb (Apr 18 2020 at 20:51, on Zulip):

you'd have to parse DWARF, deduplicate, then re-encode it

eddyb (Apr 18 2020 at 20:52, on Zulip):

(full LTO should have a similar effect to doing codegen only in the final crate)

Nikhil Benesch (Apr 18 2020 at 20:52, on Zulip):

I'm wondering if rustc could be smarter about creating codegen units, though?

Nikhil Benesch (Apr 18 2020 at 20:53, on Zulip):

Smarter specifically wrt trying to group bunches of symbols together that can all be dropped on the floor when linking debug info. Maybe that's an impossible ask though.

eddyb (Apr 18 2020 at 20:54, on Zulip):

doesn't sound easy, while what I was thinking is stuff like type descriptions that are replicated across CGUs/libraries

Nikhil Benesch (Apr 18 2020 at 20:56, on Zulip):

Gotcha. I'll try to get some full LTO stats.

Nikhil Benesch (Apr 18 2020 at 20:57, on Zulip):

Btw, while I have you, https://github.com/rust-lang/rust/issues/46034 looks pretty easy to address. The tl;dr is that the debug_pubnames and debug_pubtypes sections are pretty useless. Removed in DWARF 5, and no longer generated by default by gcc/clang. There's even a working patch for Rust that unconditionally omits them.

eddyb (Apr 18 2020 at 20:57, on Zulip):

alright

Nikhil Benesch (Apr 18 2020 at 20:58, on Zulip):

I think the only hold up is deciding if it's acceptable to change rustc to unconditionally omit those on Linux, or if it needs to be behind some codegen flag that gets stabilized.

Nikhil Benesch (Apr 18 2020 at 20:58, on Zulip):

Happy to pick that patch up and submit for review if you (or anyone) can advise. I'm not familiar with what sort of stability promises rustc makes on the debug info front.

eddyb (Apr 18 2020 at 20:58, on Zulip):

me neither tbh

Nikhil Benesch (Apr 18 2020 at 20:59, on Zulip):

Hah, ok! Do you know who would know?

eddyb (Apr 18 2020 at 20:59, on Zulip):

mw is away from Rust for a while

Jonas Schievink (Apr 18 2020 at 20:59, on Zulip):

How does it change user-visible behavior?

eddyb (Apr 18 2020 at 21:00, on Zulip):

@bjorn3 did a bunch of work on debuginfo for the cranelift backend

eddyb (Apr 18 2020 at 21:00, on Zulip):

and @Hanna Kruppe, @nagisa and @Nikita Popov are the go-to people for LLVM things, that I know of

Nikhil Benesch (Apr 18 2020 at 21:03, on Zulip):

@Jonas Schievink AIUI you can tell the linker to build debug_pubnames and debug_pubtypes into a GDB index that speeds up the initial boot of gdb/lldb. But doesn't seem like anyone regularly uses them.

Nikhil Benesch (Apr 18 2020 at 21:03, on Zulip):

And thanks, eddyb, that's super helpful!

Jonas Schievink (Apr 18 2020 at 21:06, on Zulip):

So users would have to customize the linker invocation to benefit from this? Seems fine to remove this then

Nikhil Benesch (Apr 18 2020 at 21:06, on Zulip):

Here's some additional context on debug_pubnames and debug_pubtypes from Fedora: https://fedoraproject.org/wiki/Features/GdbIndex#Detailed_Description

To the best of my knowledge no program in the distro (and probably no program anywhere) uses these sections. They are just wasted space.

Nikhil Benesch (Apr 18 2020 at 21:07, on Zulip):

Yeah exactly. In order to make use of it you're already going to need to edit the linker args. Unfortunately there is no LLVM arg that controls their generation, so right now you have no choice but to accept them, and with the existing patch you have no choice but to not have them.

nagisa (Apr 19 2020 at 00:51, on Zulip):

Our collector is already fairly good about grouping related stuff together into codegen units, to facilitate incremental compilation. If there’s a possibility to improve it, it would be primarily driven by incremental compilation needs I feel.

nagisa (Apr 19 2020 at 00:53, on Zulip):

I’d be cool with disabling pubnames/types by default, especially because, I believe, we generate fairly recent version (4) of dwarf in the first place

Last update: May 29 2020 at 18:00UTC