Skip to content
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

Lower intrinsics calls: forget, size_of, unreachable, wrapping_* #79049

Merged
merged 1 commit into from
Nov 15, 2020

Conversation

tmiasko
Copy link
Contributor

@tmiasko tmiasko commented Nov 14, 2020

This allows constant propagation to evaluate size_of and wrapping_*,
and unreachable propagation to propagate a call to unreachable.

The lowering is performed as a MIR optimization, rather than during MIR
building to preserve the special status of intrinsics with respect to
unsafety checks and promotion.

Currently enabled by default to determine the performance impact (no
significant impact expected). In practice only useful when combined with
inlining since intrinsics are rarely used directly (with exception of
unreachable and discriminant_value used by built-in derive macros).

Closes #32716.

This allows constant propagation to evaluate `size_of` and `wrapping_*`,
and unreachable propagation to propagate a call to `unreachable`.

The lowering is performed as a MIR optimization, rather than during MIR
building to preserve the special status of intrinsics with respect to
unsafety checks and promotion.
@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 14, 2020
@jonas-schievink
Copy link
Contributor

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion

@bors
Copy link
Contributor

bors commented Nov 14, 2020

⌛ Trying commit 7188f55140098182d6378946b518683eed3c6937 with merge 702dc8081c7c9f77501bbdb6bad0af62a43dc781...

Copy link
Contributor

@jonas-schievink jonas-schievink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM, let's see if this impacts perf at all

@bors
Copy link
Contributor

bors commented Nov 14, 2020

☀️ Try build successful - checks-actions
Build commit: 702dc8081c7c9f77501bbdb6bad0af62a43dc781 (702dc8081c7c9f77501bbdb6bad0af62a43dc781)

@rust-timer
Copy link
Collaborator

Queued 702dc8081c7c9f77501bbdb6bad0af62a43dc781 with parent 30e49a9, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (702dc8081c7c9f77501bbdb6bad0af62a43dc781): comparison url.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying rollup- to bors.

Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up.

@bors rollup=never
@rustbot modify labels: +S-waiting-on-review -S-waiting-on-perf

@jonas-schievink
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Nov 14, 2020

📌 Commit 7188f55140098182d6378946b518683eed3c6937 has been approved by jonas-schievink

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 14, 2020
source_info: terminator.source_info,
kind: StatementKind::Assign(box (
destination,
Rvalue::NullaryOp(NullOp::SizeOf, tp_ty),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... we could also remove this nullary op and replace it with Rvalue::Use(Operand::Constant(...)). This applies to all nullary const fn.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also teach constant propagation to evalaute rust intrinsics more generally?

Copy link
Member

@RalfJung RalfJung Dec 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This applies to all nullary const fn.

Not anymore, now that CTFE can allocate memory (which landed after this was written)... it only applies to most nullary intrinsics.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 14, 2020

cc @rust-lang/wg-mir-opt

@bors
Copy link
Contributor

bors commented Nov 14, 2020

⌛ Testing commit 7188f55140098182d6378946b518683eed3c6937 with merge e8db247bb5311146388688d8e52c896305c4f9f1...

@oli-obk oli-obk added the A-mir-opt Area: MIR optimizations label Nov 14, 2020
@bors
Copy link
Contributor

bors commented Nov 14, 2020

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Nov 14, 2020
@jonas-schievink
Copy link
Contributor

Ah, the test output changes on panic=abort targets. Maybe try using -C panic=abort for that test?

@jonas-schievink
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Nov 14, 2020

📌 Commit 6903273 has been approved by jonas-schievink

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 14, 2020
@bors
Copy link
Contributor

bors commented Nov 14, 2020

⌛ Testing commit 6903273 with merge 361c4ea...

@petrochenkov
Copy link
Contributor

r? @jonas-schievink

@bors
Copy link
Contributor

bors commented Nov 15, 2020

☀️ Test successful - checks-actions
Approved by: jonas-schievink
Pushing 361c4ea to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 15, 2020
@bors bors merged commit 361c4ea into rust-lang:master Nov 15, 2020
@rustbot rustbot added this to the 1.50.0 milestone Nov 15, 2020
@tmiasko tmiasko deleted the lower-intrinsics branch November 15, 2020 00:48
@RalfJung
Copy link
Member

Interesting PR, thanks! Would be nice to Cc @rust-lang/miri for things involving intrinsics as this made some code in Miri (and the CTFE core engine) dead that used to implement those intrinsics.

Also, I expected to see code being removed from the LLVM backend now that it does not have to handle these intrinsics any more; is there any reason this code is kept around?

@@ -390,6 +391,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

// The main optimizations that we do on MIR.
let optimizations: &[&dyn MirPass<'tcx>] = &[
&lower_intrinsics::LowerIntrinsics,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the optimization is run even with mir-opt-level=0. This means codegen and CTFE can rely on these intrinsics not existing any more. Is that deliberate? For something called "lowering", it makes sense to be able to rely on it, but then it should be moved to run_post_borrowck_cleanup_passes IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't run at mir-opt-level=0. The default situation might also change if CTFE is to be run on unoptimized MIR. Always lowering them seems fine to me, modulo concerns already mentioned in the PR description.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure? In #79989 I tried -Zmir-opt-level=0 and it did not make a difference...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that the pass is only added in optimizations, but then CTFE should fail when the forget intrinsic is called in #79989, and yet I still see this trace:

│ │└┐rustc_mir::interpret::eval_context::frame std::mem::forget::<Vec<i32>>
│ │ ├─0ms  INFO rustc_mir::interpret::step // executing bb0
│ │ ├─0ms  INFO rustc_mir::interpret::step _0 = const ()
│ │ ├─0ms  INFO rustc_mir::interpret::step return
│ │ ├─0ms  INFO rustc_mir::interpret::eval_context popping stack frame (returning from function)
│ │┌┘rustc_mir::interpret::eval_context::frame std::mem::forget::<Vec<i32>>

Note the lack of anything happening in mem::forget. This was with RUSTC_LOG=rustc_mir::interpret=info rustc +196ca161be8363503d2d2445bab9840f0ce2bba4 /tmp/forget.rs -Zmir-opt-level=0, on this code:

fn main() {
    const fn forget_arg_and_return_4(x: Vec<i32>) -> i32 {
        std::mem::forget(x);
        4
    }

    const FOUR_THE_HARD_WAY: i32 = forget_arg_and_return_4(Vec::new());

    assert_eq!(FOUR_THE_HARD_WAY, 4);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you are building std with -Zmir-opt-level=0 it is already too late for it to have an effect for non-local MIR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right... so we now have a barely tested code path here, namely the intrinsic implementations in CTFE and codegen, which is only hit when std is compiled with mit-opr-level=0. That seems potentially problematic.

bors added a commit to rust-lang/miri that referenced this pull request Dec 22, 2020
remove intrinsic that is now implemented in the rustc side

Since rust-lang/rust#80040, we can rely on the pass introduced in rust-lang/rust#79049 to lower away `forget`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-mir-opt Area: MIR optimizations merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[MIR] Consider lowering some intrinsic functions to MIR
9 participants