-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Unnecessary alloca Without Optimization Flags #129282
Comments
@saethlin informed me that this is an issue with his mono-reachable traversal implementation. |
I know that when I initially worked on this I searched the generated LLVM IR for the special "No predecessors!" comment that LLVM leaves on such orphaned basic blocks. There are a lot and I think I concluded they were all not actionable. Clearly this case is. There are actually two bugs here:
|
Don't alloca for unused locals This fixes the second problem in rust-lang#129282 r? `@ghost`
Don't alloca for unused locals This fixes the second problem in rust-lang#129282 r? `@ghost`
Let MonoReachable traversal evaluate BinOps This fixes the first bug in rust-lang#129282 I don't know what the right organization is for the code here, but something probably has to get rearranged because this traversal now depends on `rustc_const_eval` so that it can use an `InterpCx` internally, so it can't live in `rustc_middle`. r? `@ghost`
I think that if you want this you should write fn test<const SIZE: usize>() {
- if SIZE < 4096 {
+ if const { SIZE < 4096 } { so that rust will know it's a constant, and be more likely to give you the behaviour you want in unoptimized builds. (Or make your own trait so it can be Anything else will just mean exactly the same bug comes back if you write it as |
@scottmcm That doesn't work, either. See version 1.80.0 or version 1.82.0-nightly on Compiler Explorer. |
Let MonoReachable traversal evaluate BinOps This fixes the first bug in rust-lang#129282 I don't know what the right organization is for the code here, but something probably has to get rearranged because this traversal now depends on `rustc_const_eval` so that it can use an `InterpCx` internally, so it can't live in `rustc_middle`. r? `@ghost`
Don't alloca for unused locals We already have a concept of mono-unreachable basic blocks; this is primarily useful for ensuring that we do not compile code under an `if false`. But since we never gave locals the same analysis, a large local only used under an `if false` will still have stack space allocated for it. There are 3 places we traverse MIR during monomorphization: Inside the collector, `non_ssa_locals`, and the walk to generate code. Unfortunately, rust-lang#129283 (comment) indicates that we cannot afford the expense of tracking reachable locals during the collector's traversal, so we do need at least two mono-reachable traversals. And of course caching is of no help here because the benchmarks that regress are incr-unchanged; they don't do any codegen. This fixes the second problem in rust-lang#129282, and brings us anther step toward `const if` at home.
…tmcm Don't alloca for unused locals We already have a concept of mono-unreachable basic blocks; this is primarily useful for ensuring that we do not compile code under an `if false`. But since we never gave locals the same analysis, a large local only used under an `if false` will still have stack space allocated for it. There are 3 places we traverse MIR during monomorphization: Inside the collector, `non_ssa_locals`, and the walk to generate code. Unfortunately, rust-lang#129283 (comment) indicates that we cannot afford the expense of tracking reachable locals during the collector's traversal, so we do need at least two mono-reachable traversals. And of course caching is of no help here because the benchmarks that regress are incr-unchanged; they don't do any codegen. This fixes the second problem in rust-lang#129282, and brings us anther step toward `const if` at home.
Don't alloca for unused locals We already have a concept of mono-unreachable basic blocks; this is primarily useful for ensuring that we do not compile code under an `if false`. But since we never gave locals the same analysis, a large local only used under an `if false` will still have stack space allocated for it. There are 3 places we traverse MIR during monomorphization: Inside the collector, `non_ssa_locals`, and the walk to generate code. Unfortunately, rust-lang#129283 (comment) indicates that we cannot afford the expense of tracking reachable locals during the collector's traversal, so we do need at least two mono-reachable traversals. And of course caching is of no help here because the benchmarks that regress are incr-unchanged; they don't do any codegen. This fixes the second problem in rust-lang#129282, and brings us anther step toward `const if` at home. try-job: test-various
Don't alloca for unused locals We already have a concept of mono-unreachable basic blocks; this is primarily useful for ensuring that we do not compile code under an `if false`. But since we never gave locals the same analysis, a large local only used under an `if false` will still have stack space allocated for it. There are 3 places we traverse MIR during monomorphization: Inside the collector, `non_ssa_locals`, and the walk to generate code. Unfortunately, rust-lang#129283 (comment) indicates that we cannot afford the expense of tracking reachable locals during the collector's traversal, so we do need at least two mono-reachable traversals. And of course caching is of no help here because the benchmarks that regress are incr-unchanged; they don't do any codegen. This fixes the second problem in rust-lang#129282, and brings us anther step toward `const if` at home. try-job: test-various
…tmcm Don't alloca for unused locals We already have a concept of mono-unreachable basic blocks; this is primarily useful for ensuring that we do not compile code under an `if false`. But since we never gave locals the same analysis, a large local only used under an `if false` will still have stack space allocated for it. There are 3 places we traverse MIR during monomorphization: Inside the collector, `non_ssa_locals`, and the walk to generate code. Unfortunately, rust-lang#129283 (comment) indicates that we cannot afford the expense of tracking reachable locals during the collector's traversal, so we do need at least two mono-reachable traversals. And of course caching is of no help here because the benchmarks that regress are incr-unchanged; they don't do any codegen. This fixes the second problem in rust-lang#129282, and brings us anther step toward `const if` at home.
The following code, when compiled without optimization flags (or with
-Copt-level=0
) emits LLVM IR for an 8192-bytealloca
, which can easily cause 100% unnecessary stack overflow errors in a running executable.The following is the relevant LLVM IR:
%arr
only ends up being used bybb1
below, butbb1
has no predecessors:Here's a Godbolt Compiler Explorer link with all of the IR.
The text was updated successfully, but these errors were encountered: