-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Does inlining work through the __rust_alloc symbol? #45831
Comments
I have noticed that while the following C code gets optimized away completely: #include <stdio.h>
#include <stdlib.h>
void foo() {
int *x = (int*)malloc(4);
if (!x) return;
*x = 0;
int *y = (int*)malloc(4);
if (!y) {
free(x);
return;
}
*y = 0;
if (x == y) {
printf("Equal!\n");
}
free(x);
free(y);
} the matching Rust code does not get the matching optimization: fn main() {
let x = &*Box::new(0);
let y = &*Box::new(0);
if x as *const _ == y as *const _ {
println!("Equal!");
}
} Looking at the LLVM IR, the calls to
But that doesn't seem enough, and anyway, I was going to report a separate issue, but this actually looks like it is the same problem? Cc @eddyb EDIT: Updated C code to actually match Rust code. |
The __rust_alloc symbols are inherently non-inlineable (without LTO at least) since their implementations aren't known until the final link. |
So this means Rust is losing all the optimizations that are based on the return value of |
It looks like these optimizations might be incompatible with the indirection that enables |
I think we just need to teach LLVM that |
There’s already an |
Glancing at 695dee0, that might be a copy/paste leftover. |
Something really funny is going on somewhere, see #45955. Even if I explicitly call |
@RalfJung I can’t find that second indirection in the code. On Unix |
Doesn't jemalloc, when linked into the program, replace those symbols? Doing The reason I think it is not using the system allocator is that the addresses look very different than they do in a C program calling malloc; and furthermore, two subsequent calls to allocate 8 bytes with alignment 8 actually result in adjacent addresses, while I have not yet observed system malloc ever giving out adjacent addresses. |
Oh, that’s a good point. jemalloc is configured for std here: https://github.com/rust-lang/rust/blob/master/src/liballoc_jemalloc/build.rs I think It’s a bug that |
I assume that would be #45955 -- probably, the misalignment occurs because while |
I’ve filed #45966 about This issue remains that this part of the comment is not accurate anymore and should be removed:
|
Thanks.
Agreed, that's the least that should happen. Furthermore, it would be nice to be able to tell LLVM that |
#46117 removes the obsolete part of the comment. |
https://github.com/rust-lang/rust/blob/1.21.0/src/liballoc_system/lib.rs#L24-L26 defines a
MIN_ALLOC
constant with this comment:However,
System.alloc()
and friends are typically not used directly but fromstd::heap::Heap.alloc()
and through symbols like:This indirection allows
#[global_allocator]
to change which allocatorHeap
uses. Doesn’t it also prevent inlining, constant-propagation of the alignment value, and elimination of the branch on comparing withMIN_ALIGN
? Or can (Thin)LTO “see through” that indirection?If the branch is not eliminated that’s probably OK, its cost is probably small compared to the total cost of performing allocation. But if the second sentence of that comment is wrong we might want to remove it.
The text was updated successfully, but these errors were encountered: