Lower the LLVM IR output of the generated output #492
Loading…
Reference in a new issue
No description provided.
Delete branch "main"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR lowers the LLVM IR (and MIR) sizes of the generated
allandfrom_namefunctions. (#491)I have wrapped
allinconst {}, which causes it to be evaluated early on. I also decided to simplify the function to reduce what it's evaluating (before:after:
)
I have measured the bloat by adding this file (emulating wgpu's 58-flag
FeaturesWGPU) asexamples/all_bloat.rs:and running
cargo llvm-lines --example all_bloat/cargo llvm-lines --example all_bloat --release.I got the MIR output with
cargo asm --example all_bloat --mir "fn _::<impl at src/lib.rs:658:9: 658:29>::all() -> InternalBitFlags" 0While doing something completely unrelated, I found that changing
$PublicBitFlags::$Flag.bits()to$valuebreaks if any of your flags useSelf(i.e.const RGBA = Self::RGB.bits() | Self::ALPHAPIXELS.bits();). This is becauseall's implementation is forInternalBitFlags, soSelfis not what you expect it to be.I can change them back, which will result in the compiler having to evaluate more at compile time.
Is there any reason
all's implementation can't be just on the public type? I haven't found much documentation on why there needs to be an internal and a public type at all.Thanks for looking at this @bolshoytoster! The internal/public type split is so that if you add
#[derive]s to your generated flags type it can use a flags-aware implementation instead of just treating the value as an integer. ReferencingSelfin flags consts is pretty common, so we need that to keep working. Do we still get an improvement in codegen with just theconst-wrapping?Thanks for the explaination. There's still an improvement from just the
constwrapping, and there's still an MIR benefit in using$PublicBitFlags::$Flag.bits()instead of$crate::Flags>::FLAGS[i].value().bits(). The only difference between this and the previous commit is that now the compiler has to inline/evaluatebits(), which is probably cheap.I'm not really sure what to do about the MSRV test failure.
const {}blocks aren't supported in the MSRV. I think there are 3 options:allinto the public type, so at least it can get the benefit of changing<$PublicBitFlags as $crate::Flags>::FLAGS[i]to$value#[cfg()]to pick either the const or old oneIt looks like I could also use an inner const:
But that seems a little ugly.
Thanks for working on this @bolshoytoster. I think using an inner const might be the best approach here. We are pretty conservative with our MSRV in
bitflags.The last issue is the compile-fail tests are giving different error messages. It looks like the difference is just semantic (
s/constant function/constants/):Can I bless it?
Looks good! Yeh the compile fail tests regularly change anyways just from changes in
rustcdiagnostics.It should be all good now.
Thanks @bolshoytoster!