Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-crate global constants aren't being inlined #9036

Closed
alexcrichton opened this issue Sep 7, 2013 · 3 comments
Closed

Cross-crate global constants aren't being inlined #9036

alexcrichton opened this issue Sep 7, 2013 · 3 comments
Labels
A-codegen Area: Code generation I-slow Issue: Problems and improvements with respect to performance of generated code.

Comments

@alexcrichton
Copy link
Member

I've got a project which uses extra::bitv::Bitv heavily, and I was looking at some time profiles of it recently. Currently the hottest function is bitv::Bitv::get, but if you look at the actual assembly heat map, there are two "hot" instructions, both of which are div operations.

Now this is very odd, because the only division/remainder done in bitv::Bitv::get is by uint::bits, a power-of-two constant. Hence, I would expect that these operations get optimized to shifts and ands.

I tried to reproduce this with a smaller test case, but LLVM's optimizations ended up thwarting me. I ended up generating the ll file for my project (282k lines of assembly), and found the definition of the get function. It appears that because it's marked #[inline], we inline it into the current crate. Because the division is done by the path uint::bits, this is translated to the load of a global constant before then passed to the udiv instruction for llvm.

Apparently, even though we inlined the entire function into another crate, we did not inline the constant. This global (uint::generated::bits) is then reflected in the LLVM module as:

@"...uint::generated::bits..." = external global i64

Which means that LLVM can no longer optimize based on the values of globals.

So my question is, is this something that we intend to support for optimizations? In a specific case like bitv perhaps we could remove the #[inline] annotation, but that's a bit of a shame. I'm not entirely sure that we can inline the values of global constants because that's only possible if the addresses are insignificant (which they're not by default right now).

In theory the values of constants could be inlined, but not much beyond immediates (constants with addresses to other constants may get tricky).

I'm not entirely sure what the best course of action to take here, but I wanted to see what others thought about this. The answer may just be removing #[inline] from bitv with a comment explaining why it can't be marked as such. This may have repercussions elsewhere though...

@alexcrichton
Copy link
Member Author

cc @thestinger

@thestinger
Copy link
Contributor

You can always expose the values of globals with the original symbol and use available_externally to avoid emitting a new symbol for them and hitting a conflict. It's only an ABI issue, never a correctness one related to addresses.

@alexcrichton
Copy link
Member Author

Hmm, with that in mind I think that #8185 may have caused this regression.

bors added a commit that referenced this issue Sep 17, 2013
In #8185 cross-crate condition handlers were fixed by ensuring that globals
didn't start appearing in different crates with different addressed. An
unfortunate side effect of that pull request is that constants weren't inlined
across crates (uint::bits is unknown to everything but libstd).

This commit fixes this inlining by using the `available_eternally` linkage
provided by LLVM. It partially reverts #8185, and then adds support for this
linkage type. The main caveat is that not all statics could be inlined into
other crates. Before this patch, all statics were considered "inlineable items",
but an unfortunate side effect of how we deal with `&static` and `&[static]`
means that these two cases cannot be inlined across crates. The translation of
constants was modified to propogate this condition of whether a constant
should be considered inlineable into other crates.

Closes #9036
flip1995 pushed a commit to flip1995/rust that referenced this issue Jun 30, 2022
…dswij

Check for `--force-warn` in Clippy's driver run condition

Just a thing I've noticed while tinkering on the driver. Currently, the driver only checks for `--cap-lints=allow` to determine if Clippy should run on the code, but ignores possible `--force-warn` arguments

---

changelog: Others: Allowing all lints and only `--force-warn`ing some will now work with Clippy's driver
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation I-slow Issue: Problems and improvements with respect to performance of generated code.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants