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

Sink unused const assignments #106613

Closed
wants to merge 1 commit into from

Conversation

saethlin
Copy link
Member

@saethlin saethlin commented Jan 9, 2023

Waiting for #107009 to land before re-evaluating the impact of this pass


This MIR optimization is designed to optimize away the drop flags in Option::map. It is based on the observation that there are actually two distinct code paths through Option::map, one for Option::None and the other for Option::Some, and along each of those code paths the drop flag is a constant assigned once to a local then branched on, but ConstGoto doesn't eliminate the branches because the assignments to the drop flag local don't occur in the branch immediately before the branch.

So this optimization pushes the assignments later so that when possible they appear immediately before they are branched on, and ConstGoto is able to eliminate them.

A totally viable alternative approach would be making ConstGoto smarter. But I personally find viewing this whole situation from the perspective of the SwitchInt looking backwards complicated. Worded this way, a poor version of this implementation can be implemented in a single pass over the Body which should mitigate any runaway runtime.

cc @JakobDegen I think this is the 2 funclets ICE ICE has been fixed

@rustbot
Copy link
Collaborator

rustbot commented Jan 9, 2023

r? @oli-obk

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

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 9, 2023
@rust-log-analyzer

This comment has been minimized.

@@ -28,7 +28,7 @@ pub struct ConstGoto;

impl<'tcx> MirPass<'tcx> for ConstGoto {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 4
sess.mir_opt_level() >= 2
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like DelayConstAssignments + ConstProp + SimplifyCfg ought to be able to handle everything that ConstGoto used to. (Which would be good, because those optimizations are more general than ConstGoto.)

e.g. for the simple example in ConstGoto's header:

bb2: {
    _2 = const true;
    goto -> bb3;
}
bb3: {
    switchInt(_2) -> [false: bb4, otherwise: bb5];
}

I'd expect DelayConstAssignments to change it to

bb2: {
    goto -> bb3;
}
bb3: {
    _2 = const true;
    switchInt(_2) -> [false: bb4, otherwise: bb5];
}

which ConstProp/SimplifyCfg should be able to handle.

Do you know of any situations where this doesn't work?

Copy link
Member Author

Choose a reason for hiding this comment

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

In case it's not obvious I have no formal training or education of any kind in compilers or optimizations. I'm just looking through the MIR that comes out of the compiler today for things that look derpy and trying to fix them.

I think before ConstProp we can have code like this:

bb0: {
    _8 = const 1;
    _9 = const 2;
    _10 = Add(move _8, _move 9);
    switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2];
}

And here I am not sure the amount of analysis we'd need to figure out if _10 is being assigned a const is simpler than just doing ConstProp.

Copy link
Contributor

Choose a reason for hiding this comment

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

Aside from the naming, it wasn't obvious. This pass is sensible :)

I may not have been clear--I think we should be able to remove ConstGoto (not ConstProp) after this change, because SinkConstAssignments should move the const assignment right into the block with the switchInt, which ConstProp/SimplifyCfg can handle without ConstGoto. Can you try your motivating Option::map example without ConstGoto, and see if it still gets optimized? Ah, I thought ConstGoto was more limited than it is--it allows multiple predecessors, so it can't be replaced like that. This is fine as-is then. (FWIW, the optimization that ConstGoto performs is referred to elsewhere as jump threading.)

It's a bit unfortunate that DataflowConstProp doesn't help here. It would know the value of the constant in the predecessor block, but there aren't any usages in the predecessor, so it doesn't do anything that would help ConstGoto. Maybe if it was available to other passes as an analysis...

@oli-obk

This comment was marked as resolved.

@rustbot

This comment was marked as resolved.

let block_data = &body.basic_blocks[block];
let Some(terminator) = &block_data.terminator else { continue; };

let mut successors = Vec::new();
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this should bail out when there are too many successors. It's probably not worth creating 100 new assign statements for a 100-arm match

@saethlin saethlin changed the title Delay const assignments when unused Sink unused const assignments Jan 17, 2023
@cjgillot cjgillot added the A-mir-opt Area: MIR optimizations label Jan 21, 2023
@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Jan 26, 2023

☔ The latest upstream changes (presumably #107309) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-log-analyzer

This comment has been minimized.

@saethlin saethlin force-pushed the delay-const-assignments branch 2 times, most recently from 80a7213 to 118865f Compare January 26, 2023 14:52
@saethlin
Copy link
Member Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 26, 2023
@bors
Copy link
Contributor

bors commented Jan 26, 2023

⌛ Trying commit 118865fb355b6535d79d52d806c3ccfb396b7ee9 with merge 90673fadd0ffde09dfdff3444aeaea5eb51b2281...

@bors
Copy link
Contributor

bors commented Jan 27, 2023

☀️ Try build successful - checks-actions
Build commit: 90673fadd0ffde09dfdff3444aeaea5eb51b2281 (90673fadd0ffde09dfdff3444aeaea5eb51b2281)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (90673fadd0ffde09dfdff3444aeaea5eb51b2281): comparison URL.

Overall result: ❌✅ regressions and improvements - ACTION NEEDED

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
1.0% [0.3%, 2.1%] 19
Regressions ❌
(secondary)
3.0% [0.3%, 17.6%] 19
Improvements ✅
(primary)
-0.4% [-0.9%, -0.2%] 10
Improvements ✅
(secondary)
-0.7% [-1.1%, -0.3%] 11
All ❌✅ (primary) 0.5% [-0.9%, 2.1%] 29

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
2.2% [1.0%, 3.2%] 3
Regressions ❌
(secondary)
3.9% [1.1%, 8.3%] 10
Improvements ✅
(primary)
-4.0% [-7.7%, -0.2%] 4
Improvements ✅
(secondary)
-2.5% [-2.5%, -2.5%] 1
All ❌✅ (primary) -1.4% [-7.7%, 3.2%] 7

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
1.9% [1.2%, 2.8%] 8
Regressions ❌
(secondary)
6.8% [2.0%, 17.3%] 7
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.9% [1.2%, 2.8%] 8

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Jan 27, 2023
@bors
Copy link
Contributor

bors commented Jan 28, 2023

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

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (f1f15ac48700d773dd71238c8f152c29dffc8b82): comparison URL.

Overall result: ❌✅ regressions and improvements - ACTION NEEDED

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.4% [0.3%, 0.5%] 6
Regressions ❌
(secondary)
0.6% [0.4%, 1.2%] 13
Improvements ✅
(primary)
-0.6% [-1.0%, -0.2%] 13
Improvements ✅
(secondary)
-0.6% [-0.7%, -0.4%] 3
All ❌✅ (primary) -0.3% [-1.0%, 0.5%] 19

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
3.1% [3.1%, 3.1%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-4.5% [-7.0%, -0.2%] 4
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -3.0% [-7.0%, 3.1%] 5

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.3% [2.3%, 4.2%] 2
Improvements ✅
(primary)
-1.1% [-1.1%, -1.1%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -1.1% [-1.1%, -1.1%] 1

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 28, 2023
@saethlin
Copy link
Member Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 28, 2023
@bors
Copy link
Contributor

bors commented Jan 28, 2023

⌛ Trying commit ac7531b7435eb8fe6b5adc29590de1b3d43a7f52 with merge 90c99bf540820d70bcb15c5c75996422aaa3ec35...

@bors
Copy link
Contributor

bors commented Jan 28, 2023

☀️ Try build successful - checks-actions
Build commit: 90c99bf540820d70bcb15c5c75996422aaa3ec35 (90c99bf540820d70bcb15c5c75996422aaa3ec35)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (90c99bf540820d70bcb15c5c75996422aaa3ec35): comparison URL.

Overall result: ❌ regressions - ACTION NEEDED

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.5% [0.2%, 1.1%] 41
Regressions ❌
(secondary)
0.6% [0.2%, 1.2%] 14
Improvements ✅
(primary)
-0.5% [-0.7%, -0.3%] 4
Improvements ✅
(secondary)
-0.5% [-0.5%, -0.5%] 1
All ❌✅ (primary) 0.4% [-0.7%, 1.1%] 45

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
2.8% [2.8%, 2.8%] 1
Regressions ❌
(secondary)
2.1% [2.1%, 2.1%] 1
Improvements ✅
(primary)
-3.6% [-6.7%, -0.4%] 7
Improvements ✅
(secondary)
-2.3% [-2.3%, -2.3%] 1
All ❌✅ (primary) -2.8% [-6.7%, 2.8%] 8

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.9% [-0.9%, -0.9%] 1
Improvements ✅
(secondary)
-3.5% [-3.5%, -3.5%] 1
All ❌✅ (primary) -0.9% [-0.9%, -0.9%] 1

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 28, 2023
@bors
Copy link
Contributor

bors commented Jan 29, 2023

☔ The latest upstream changes (presumably #106908) made this pull request unmergeable. Please resolve the merge conflicts.

@WaffleLapkin
Copy link
Member

@rustbot author
(since this is a draft + has a merge conflict)

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 24, 2023
@saethlin
Copy link
Member Author

I'm planning on waiting for #107009 to land before evaluating the value of landing this

@rust-log-analyzer
Copy link
Collaborator

The job mingw-check-tidy failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
Prepare all required actions
Getting action download info
Download action repository 'actions/checkout@v3' (SHA:24cb9080177205b6e8c946b17badbe402adc938f)
Download action repository 'rust-lang/simpleinfra@master' (SHA:3fb2b44a4eaebb9ed8086446bde46c27199ef5ed)
Complete job name: PR (mingw-check-tidy, true, ubuntu-20.04-xl)
git config --global core.autocrlf false
shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
env:
  CI_JOB_NAME: mingw-check-tidy
---
Building wheels for collected packages: reuse
  Building wheel for reuse (pyproject.toml): started
  Building wheel for reuse (pyproject.toml): finished with status 'done'
  Created wheel for reuse: filename=reuse-1.1.0-cp310-cp310-manylinux_2_35_x86_64.whl size=180119 sha256=9fa76c45f3193f307e02ea67d1a48cfe7ef2b854a074b766938a88e046bc7887
  Stored in directory: /tmp/pip-ephem-wheel-cache-nfxvsvb9/wheels/c2/3c/b9/1120c2ab4bd82694f7e6f0537dc5b9a085c13e2c69a8d0c76d
Installing collected packages: boolean-py, binaryornot, setuptools, reuse, python-debian, markupsafe, license-expression, jinja2, chardet
  Attempting uninstall: setuptools
    Found existing installation: setuptools 59.6.0
    Not uninstalling setuptools at /usr/lib/python3/dist-packages, outside environment /usr
---
Successfully built a2f0d85908fc
Successfully tagged rust-ci:latest
Built container sha256:a2f0d85908fc5ec8e8f6beb64f73ca48684e2b44602e97b013dd0d647e13e7c9
Uploading finished image to https://ci-caches.rust-lang.org/docker/38eba79578bd6d379f830cfbe873c54dad8d10db1dfcf4fbac8af27e25e93a7ecaa2a7c62028c216d50741db91fde3d04f83489b4d576287b0239d35dee6e197
upload failed: - to s3://rust-lang-ci-sccache2/docker/38eba79578bd6d379f830cfbe873c54dad8d10db1dfcf4fbac8af27e25e93a7ecaa2a7c62028c216d50741db91fde3d04f83489b4d576287b0239d35dee6e197 Unable to locate credentials
[CI_JOB_NAME=mingw-check-tidy]
[CI_JOB_NAME=mingw-check-tidy]
---
    Finished release [optimized] target(s) in 16.86s
fmt check
tidy check
tidy: Skipping binary file check, read-only filesystem
tidy error: the following output file is not associated with any mir-opt test, you can remove it: /checkout/tests/mir-opt/lower_array_len_e2e.array_bound_mut.PreCodegen.after.mir
some tidy checks failed

@bors
Copy link
Contributor

bors commented Apr 7, 2023

☔ The latest upstream changes (presumably #102906) made this pull request unmergeable. Please resolve the merge conflicts.

@Dylan-DPC Dylan-DPC added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 18, 2023
@saethlin
Copy link
Member Author

Per the PR description, the jump threading pass has landed and since it produces the optimizations I was looking for with this pass, I'm closing this.

@saethlin saethlin closed this Oct 28, 2023
@saethlin saethlin deleted the delay-const-assignments branch October 28, 2023 05:32
@saethlin saethlin removed the S-blocked Status: Blocked on something else such as an RFC or other implementation work. label Oct 28, 2023
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 perf-regression Performance regression. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants