-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
LLVM doesn't know about jemalloc #22159
Comments
I feel like we must have opened an issue for this at some point, but a cursory search doesn't show one. |
I believe that past discussions of this behavior have involved making jemalloc pretend to be malloc in order to trigger the optimization, but here are we proposing to change LLVM itself? |
Apparently Rust already uses a few patches on LLVM; adding another one is probably not that bad. I think the best way for this to be handled is for there to be some way to indicate "malloc-y stuff" to LLVM; currently, LLVM is just hardcoded. The easiest change would just be replacing "malloc" with "je_mallocx", and "free" with "je_sdallocx", but removing the hardcoding entirely (and contributing that back to LLVM upstream) is probably ideal. It's arguable that this is actually LLVM's issue, but because we are already not using "stock" LLVM, it may be worth it to diverge a little further from LLVM master. I'm not sure how jemalloc could pretend to be malloc, because the APIs are different; from what I saw of LLVM's code, it checks both the function name and the signature. Any wins from better optimization here are unlikely to be worth giving up sized deallocation and alignment, for example. |
Most (maybe all?) of them are performance related these days, and we try to move them upstream. Building with standard LLVM will be important for things like packaging Rust. |
This is significant, since for a basic hello world program, fn main() {
let _ = Box::new(42i32);
} jemalloc consumes approximately 70% of the resulting executable (on x86_64 OS X). |
@steveklabnik This is also a performance-related change, and should be backwards- and forwards- compatible (can only tell it's there by examining performance or jemalloc instrumentation; otherwise you can remove it or add it and nobody's the wiser.). |
This would fix many of the issues caused by #13996 , as allocation functions are automatically marked noalias. |
The "quick and dirty" fix for this: https://gist.github.com/XMPPwocky/4bdb29e142d235899867 |
@XMPPwocky Please put this in a PR! The fix is so simple, we can safely apply it to our branch. It solves the here-and-now problem, it doesn't require us to address custom allocators first, and it doesn't fundamentally change the language—just the optimization capabilities of our implementation. It can even be applied to a future stable release like LLVM 3.6, should that happen before Rust 1.0. True, the librustc available from rust-lang.org wouldn't be statically linked against an unmodified, stable release of LLVM, but the gains speak for themselves. |
rust-lang/llvm#37 has been merged. |
JFYI, I'll make a PR to update LLVM to 3.6 RC4 once it's tagged (probably tomorrow). That will include the patch from rust-lang/llvm#37, no need for a dedicated PR to update LLVM just for this. |
Fixes rust-lang#22159 Fixes rust-lang#21721 Conflicts: src/llvm
LLVM can remove "dead" calls to malloc() (where the return value is ignored, or immediately free()-d (possibly after being compared with NULL)). However, this is basically hardcoded to the "malloc" symbol (and "free", etc.); it is not aware of jemalloc (specifically je_mallocx and je_sdallocx), which Rust uses.
LLVM is very good at removing temporary allocations, as it turns out:
will not call malloc or free (at -O2).
On the other hand, even the most trivial allocation using liballoc...
will invoke je_mallocx and je_sdallocx, even at -O3.
/cc @dotdash
The text was updated successfully, but these errors were encountered: