-
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
Future::and_then and other adapters are not always zero cost #37930
Comments
Hilariously this is not an issue at |
Opened #37933 |
Whoa wow I totally thought this was in the futures-rs repo, not the rust-lang/rust repo! Ok, inlining #37933 into here: Originally reported at #37930, minimized at https://gist.github.com/alexcrichton/86db63138ef979422d8fa10538dc6dcb, the code optimizes better at opt-level=2 than opt-level=3. For example:
That is, with opt-level=2 we can prove the code doesn't panic, but at opt-level=3 something goes awry and we don't prove that it doesn't panic. Do we need to tweak our opt-level=3 pipeline? Has it diverged from clang? Is it inappropriate to run by default? |
I should also note that the |
I am investigating @alexcrichton's issue. Some code generated ends up looking like
through way too many passes, ends up with a conditional of the form
Which it is then unable to optimize. |
Minimal example (if both icmps have the same bitwise value, this optimizes to a switch of true/false. If they don't, it doesn't):
The double nested loop seems to be essential to getting the optimization to trigger. I wonder whether this is the case in the more complicated example too. |
Sure, looks like this issue is encountered on @japaric's posted |
Awesome, thanks for the minimization @arielb1! |
I had the minimization correct, but I got confused on finding the pass to blame. |
I'm confused. I can now grep Cc @rust-lang/wg-codegen |
Triage: |
I expected these two code snippets to produce the same (or very similar) code
when fully optimized (release+LTO) but they don't:
The first is
panic!
-free but the second is not; it still contains calls topanic!("cannot poll a chained future twice")
even though it never polls eitherfuture after it has yielded its value.
STR
If the program is changed to the no-
and_then
variant, the disassembly lookslike this:
There are no
panic_fmt
calls in it.Meta
I don't think this is a problem with the implementation of
AndThen
/Chain
inthe futures crate because I have tried to re-implement
Future
in a fewdifferent ways e.g. without error-handling, sprinkling #[inline] everywhere but
none of that helps.
Code like this:
optimizes the same as the "split" version and in that case LLVM evaluates the
expression at compile time and replaces it with
42
. So LLVM can actually lowerand_then
topanic!
free code; it just doesn't optimize well this particularcase (perhaps, because of the volatile memory operations?)
join
is another adapter that has the same issue.cc @alexcrichton @eddyb
The text was updated successfully, but these errors were encountered: