-
Notifications
You must be signed in to change notification settings - Fork 13k
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
regression: dead heap allocations aren't optimized out anymore #24194
Comments
hmmm, I'm not so sure if it's a regression. It still works for vectors: http://is.gd/yNAFF6 . Maybe it never worked for boxes? |
So, where do we go with this ticket? Was/is this a regression? is it worth tracking? |
@steveklabnik Probably a regression from when we moved from actual zeroing-drop to using the non-zero drop pattern. The check for that pattern basically says "leak this if the adress matches the drop pattern", so LLVM cannot remove the allocation because that would change semantics. Dynamic drop will fix this, and I think we should keep this open to track that, just to make sure. |
This appears to be fixed: https://is.gd/kT0Gs9 Is this worth creating some kind of regression test for? |
We could test it by adding a run pass test that uses a custom allocator (which doesn't allocate, but panics). |
tentatively needstest, then. Maybe a src/test/codegen test? |
Seems to not work again on nightly. |
I've used @Mark-Simulacrum 's bisection tool to find out the regressing commit. It was the LLVM 4.0 upgrade, commit 0777c75 . |
Assigning myself just so it stays on my to-do list. Not immediately working on it, though. Feel free to take over if you want. |
Historically this optimization was done by rust-lang/llvm@4daef48 but this commit was not carried forward to our current branch when the 4.0 upgrade was done because it no longer applies cleanly (IIRC) |
Sadly, I couldn’t make the patch above to work. In fact, some testing seems to indicate that the responsibility for eliding allocations has been moved out of LLVM into clang. Namely, code like this
when compiled with
whereas if the special handling of the built-ins is not disabled (i.e. without This seems to suggest to me that, unless we do some serious patchwork on LLVM (pretty sure we don’t want to do that), it falls onto rustc to optimise out heap allocations now. This could also very well be a bug. I have a test case on hand that does optimise out on 3.9 but not on 4.0. I might do a bisection. |
Okay, never mind. I got it to work. |
The LLVM upgrade reintroduces optimisation for _rust_allocate, but the optimisation for __rust_allocate_zeroed was backed out due to weird UB-like behaviour with bitvec iterators in rustc_data_structures. Should investigate eventually. Assigning myself. |
cc @arielb1 you were interested in this yesterday. |
I believe this is no longer a regression, so untagging as a regression. |
It's not very clear to me whether this is still actionable. The original snippet doesn't seem to be misoptimised anymore. Can someone produce a new snippet that demonstrates the continued existence of the issue? Should the issue be closed? Cc @rust-lang/wg-codegen |
This should stay open as only a handful of alllocating functions are
currently handled (i.e. malloc equivalent but not realloc IIRC).
…On Mon, Apr 2, 2018, 14:37 Anthony Ramine ***@***.***> wrote:
It's not very clear to me whether this is still actionable. The original
snippet doesn't seem to be misoptimised anymore. Can someone produce a new
snippet that demonstrates the continued existence of the issue? Should the
issue be closed?
Cc @rust-lang/wg-codegen
<https://github.com/orgs/rust-lang/teams/wg-codegen>
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
<#24194 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AApc0mikNK6SdwDWKu-Gccdw9qaNIrHUks5tkg2RgaJpZM4D8f_0>
.
|
Or was it calloc-equivalent.
…On Tue, Apr 3, 2018, 12:13 Simonas Kazlauskas ***@***.***> wrote:
This should stay open as only a handful of alllocating functions are
currently handled (i.e. malloc equivalent but not realloc IIRC).
On Mon, Apr 2, 2018, 14:37 Anthony Ramine ***@***.***>
wrote:
> It's not very clear to me whether this is still actionable. The original
> snippet doesn't seem to be misoptimised anymore. Can someone produce a new
> snippet that demonstrates the continued existence of the issue? Should the
> issue be closed?
>
> Cc @rust-lang/wg-codegen
> <https://github.com/orgs/rust-lang/teams/wg-codegen>
>
> —
> You are receiving this because you modified the open/close state.
> Reply to this email directly, view it on GitHub
> <#24194 (comment)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AApc0mikNK6SdwDWKu-Gccdw9qaNIrHUks5tkg2RgaJpZM4D8f_0>
> .
>
|
@nagisa Any snippet demonstrating the issue? |
#![feature(allocator_api)]
use std::heap::{Heap, Layout, Alloc};
pub unsafe fn alloc_zeroed_doesnt_optimise() {
let _ = Heap.alloc_zeroed(Layout::from_size_align_unchecked(4, 8));
}
extern "C" {
fn foo(x: *mut u8);
}
pub unsafe fn alloc_zeroed_should_optimise_rezeroing() {
let a = Heap.alloc_zeroed(Layout::from_size_align_unchecked(16, 8)).unwrap();
let slc = ::std::slice::from_raw_parts_mut(a, 16);
for i in slc.iter_mut() {
*i = 0;
}
foo(slc.as_mut_ptr());
} |
For searchability purposes, the functions are now called |
This was noticed in the wild on Stack Overflow. |
It would be nice if we didn't have to patch LLVM to support custom allocation functions. Unfortunately the last discussion on that topic didn't really end up anywhere: http://lists.llvm.org/pipermail/llvm-dev/2016-January/093625.html |
The only way around that is to guarantee this optimization via MIR optimizations. But our MIR optimization story is nowhere near the level required for that. |
Couldn't this be generalized by having a "pure, no side-effects" unsafe attribute? |
This obviates the patch that teaches LLVM internals about _rust_{re,de}alloc functions by putting annotations directly in the IR for the optimizer. The sole test change is required to anchor FileCheck to the body of the `box_uninitialized` method, so it doesn't see the `allocalign` on `__rust_alloc` and get mad about the string `alloca` showing up. Since I was there anyway, I added some checks on the attributes to prove the right attributes got set. While we're here, we also emit allocator attributes on __rust_alloc_zeroed. This should allow LLVM to perform more optimizations for zeroed blocks, and probably fixes rust-lang#90032. [This comment](rust-lang#24194 (comment)) mentions "weird UB-like behaviour with bitvec iterators in rustc_data_structures" so we may need to back this change out if things go wrong. The new test cases require LLVM 15, so we copy them into LLVM 14-supporting versions, which we can delete when we drop LLVM 14.
This obviates the patch that teaches LLVM internals about _rust_{re,de}alloc functions by putting annotations directly in the IR for the optimizer. The sole test change is required to anchor FileCheck to the body of the `box_uninitialized` method, so it doesn't see the `allocalign` on `__rust_alloc` and get mad about the string `alloca` showing up. Since I was there anyway, I added some checks on the attributes to prove the right attributes got set. While we're here, we also emit allocator attributes on __rust_alloc_zeroed. This should allow LLVM to perform more optimizations for zeroed blocks, and probably fixes #90032. [This comment](rust-lang/rust#24194 (comment)) mentions "weird UB-like behaviour with bitvec iterators in rustc_data_structures" so we may need to back this change out if things go wrong. The new test cases require LLVM 15, so we copy them into LLVM 14-supporting versions, which we can delete when we drop LLVM 14.
#22159 was closed after a llvm update (#22526). It used to work (I remember I tried it out). Now it doesn't work anymore.
http://is.gd/Wekr7w
LLVM-IR:
The text was updated successfully, but these errors were encountered: