all() causing LLVM bloat #491

Closed
opened 2026-06-30 12:08:06 -05:00 by bolshoytoster · 3 comments
bolshoytoster commented 2026-06-30 12:08:06 -05:00 (Migrated from github.com)

Currently, bitflags::all() outputs 6 + 20n lines of LLVM IR in debug builds, and 8 + 14n on release builds, where n is the number of flags. I first noticed this with wgpu's FeaturesWGPU, which has 58 flags (1166 lines debug, 820 release).

The implementation is here:
github.com/bitflags/bitflags@9253889ee9/src/public.rs (L150-L168)

If I wrap the function in const {} then the function emits only 1 line of IR in debug, and seems to be fully optimized away in release.

This bloat slows down builds (sllightly) and probably makes it less likely for some optimizations to occur (don't quote me on that, I'm not a compiler developer).

There are probably some other generated functions that suffer from this. I can investigate and open a PR if that's wanted.

Currently, bitflags::all() outputs `6 + 20n` lines of LLVM IR in debug builds, and `8 + 14n` on release builds, where `n` is the number of flags. I first noticed this with wgpu's [FeaturesWGPU](https://docs.rs/wgpu-types/latest/wgpu_types/struct.FeaturesWGPU.html), which has 58 flags (1166 lines debug, 820 release). The implementation is here: https://github.com/bitflags/bitflags/blob/9253889ee93921055309908c46272bd6c5c6ad99/src/public.rs#L150-L168 If I wrap the function in `const {}` then the function emits only 1 line of IR in debug, and seems to be fully optimized away in release. This bloat slows down builds (sllightly) and probably makes it less likely for some optimizations to occur (don't quote me on that, I'm not a compiler developer). There are probably some other generated functions that suffer from this. I can investigate and open a PR if that's wanted.
bolshoytoster commented 2026-06-30 12:46:49 -05:00 (Migrated from github.com)

from_name is also fairly big 13 + 7n debug, 12 + 14n release (not a typo, it's way bigger in release). I can get it down to 13 + 6n and 13 + 12n release by changing $PublicBitFlags::$Flag.bits() to $value (only affected debug), and changing the list of if statements to a match (only affected release).

`from_name` is also fairly big `13 + 7n` debug, `12 + 14n` release (not a typo, it's way bigger in release). I can get it down to `13 + 6n` and `13 + 12n` release by changing `$PublicBitFlags::$Flag.bits()` to `$value` (only affected debug), and changing the list of if statements to a match (only affected release).
KodrAus commented 2026-06-30 17:11:54 -05:00 (Migrated from github.com)

Thanks for investigating this @bolshoytoster! Would you be happy to open a PR with your improvements and we can take a look? We should be aiming for as small a footprint as possible.

Thanks for investigating this @bolshoytoster! Would you be happy to open a PR with your improvements and we can take a look? We should be aiming for as small a footprint as possible.
bolshoytoster commented 2026-07-01 04:26:56 -05:00 (Migrated from github.com)

I've opened a PR (#492)

I've opened a PR (#492)
Sign in to join this conversation.
No labels
bug
good first issue
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-bitflags/bitflags#491
No description provided.