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

Lift a few limitations on ConstProp optimization pass #107856

Closed
wants to merge 9 commits into from

Conversation

cjgillot
Copy link
Contributor

@cjgillot cjgillot commented Feb 9, 2023

ConstProp does not emit lints any more. Therefore, we can extend and simplify it.

This PR starts by fortifying the current implementation of ConstProp and of the interpreter.

In a second part, we enable propagation even if overflow checks are disabled. It's now codegen's responsibility to skip emitting overflow checks.

In a third part, we remove limitation on propagation.

Finally, we only disable the pass for mir-opt-level=1, since it's now purely an optimization pass.

@cjgillot cjgillot added the A-mir-opt Area: MIR optimizations label Feb 9, 2023
@rustbot
Copy link
Collaborator

rustbot commented Feb 9, 2023

r? @lcnr

(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 Feb 9, 2023
@rustbot
Copy link
Collaborator

rustbot commented Feb 9, 2023

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred to the CTFE / Miri engine

cc @rust-lang/miri

Some changes occurred to the CTFE / Miri engine

cc @rust-lang/miri

@cjgillot
Copy link
Contributor Author

cjgillot commented Feb 9, 2023

@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 Feb 9, 2023
@bors
Copy link
Contributor

bors commented Feb 9, 2023

⌛ Trying commit b27fb59b1c018d8223f4ef35d5ae3eb687a8bbf3 with merge 85e382751271dbc84dc43390b8ce9624f3b96753...

@@ -601,7 +601,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// that the `RevealAll` pass has happened and that the body's consts
// are normalized, so any call to resolve before that needs to be
// manually normalized.
let val = self.tcx.normalize_erasing_regions(self.param_env, *val);
let Ok(val) = self.tcx.try_normalize_erasing_regions(self.param_env, *val) else {
throw_unsup!(Normalization)
Copy link
Member

@RalfJung RalfJung Feb 9, 2023

Choose a reason for hiding this comment

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

This is more invalid than unsupported I think, just like all the other const-prop-hacks we carry in the interpreter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

throw_inval!(TooGeneric) may be better suited then.

Copy link
Member

Choose a reason for hiding this comment

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

Ah right, we already have that variant. Agreed.

@@ -356,7 +356,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

_ => {
span_bug!(self.cur_span(), "invalid unsizing {:?} -> {:?}", src.layout.ty, cast_ty)
throw_inval!(Unsize(src.layout.ty, cast_ty))
Copy link
Member

Choose a reason for hiding this comment

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

Even more const-prop induced technical debt in the interpreter. :(

How can this one even happen...?

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 can have a generic context

fn foo<T: ?Sized, V: std::marker::Unsize<T>>(value: &V) -> &T { value }

Copy link
Member

Choose a reason for hiding this comment

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

Please add a comment explaining that (and that this is only needed for ConstProp).

Why does that not affect the similar bug! in unsize_into?

@oli-obk
Copy link
Contributor

oli-obk commented Feb 9, 2023

I don't think we should make const prop smarter. We should get the dataflow const prop to cover most of the const prop optimizations and then just remove const prop.

@saethlin
Copy link
Member

saethlin commented Feb 9, 2023

Do we have a solution to DataFlowConstProp's runtime?

@cjgillot
Copy link
Contributor Author

cjgillot commented Feb 9, 2023

I don't think we should make const prop smarter. We should get the dataflow const prop to cover most of the const prop optimizations and then just remove const prop.

I don't agree with this vision. My suggestion is to have:

  1. this ConstProp pass do the "easy" cases: locals assigned once, and intra-bb propagation;
  2. some intermediary cleanup pass to shrink MIR and reduce state space (SimplifyConstSwitch and SimplifyLocals in particular);
  3. let DataflowConstProp do the harder work of inter-bb propagation for what remains.

Whatever the decision on that discussion, there are 2 changes that I'd like to propose:

  1. gate ConstProp on mir-opt-level >= 2, since it doesn't have a reason to run on mir-opt-level=1 any more;
  2. make codegen alone handle the decisions on overflow checks, and always propagate checked operations (in both ConstProp and DataflowConstProp).

I can move them in separate PRs if needed.

@bors
Copy link
Contributor

bors commented Feb 9, 2023

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

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (85e382751271dbc84dc43390b8ce9624f3b96753): 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.7% [0.4%, 1.1%] 7
Regressions ❌
(secondary)
7.3% [1.0%, 21.6%] 10
Improvements ✅
(primary)
-0.9% [-1.9%, -0.3%] 12
Improvements ✅
(secondary)
-1.1% [-2.0%, -0.2%] 16
All ❌✅ (primary) -0.3% [-1.9%, 1.1%] 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)
2.9% [0.1%, 5.7%] 2
Regressions ❌
(secondary)
29.0% [3.9%, 53.1%] 4
Improvements ✅
(primary)
-3.4% [-4.4%, -2.4%] 10
Improvements ✅
(secondary)
-2.4% [-4.1%, -0.7%] 50
All ❌✅ (primary) -2.3% [-4.4%, 5.7%] 12

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)
13.0% [2.8%, 23.3%] 7
Improvements ✅
(primary)
-1.5% [-1.9%, -1.1%] 4
Improvements ✅
(secondary)
-1.9% [-1.9%, -1.9%] 1
All ❌✅ (primary) -1.5% [-1.9%, -1.1%] 4

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Feb 9, 2023
@rust-log-analyzer

This comment has been minimized.

@lcnr
Copy link
Contributor

lcnr commented Feb 10, 2023

r? @oli-obk @RalfJung

though re 7bbc67468dae49930263f44eb9fedd275acb912e, is there a test which actually ICEs without this change? While I can imagine cases where this ICEs with generic_const_exprs, that's a bug with that feature and in my ideal impl of CTFE this is actually infallible

@rustbot rustbot assigned oli-obk and unassigned lcnr Feb 10, 2023
@RalfJung
Copy link
Member

I don't think we should make const prop smarter. We should get the dataflow const prop to cover most of the const prop optimizations and then just remove const prop.

I think that would be great, if it can be done in our perf budget. It means less code to maintain, and fewer issues with ConstProp using the interpreter in ways it was not intended to be used.

@oli-obk
Copy link
Contributor

oli-obk commented Feb 10, 2023

I'll benchmark removing the old pass and enabling the new one so we can make a decision here.

Even if we can't split it, we can still change const prop to stop using mir interpreter rvalue processing and instead make it only use the math APIs like the dataflow const prop does

@cjgillot
Copy link
Contributor Author

On the perf report:

  • check builds: mostly non-relevant red and green, nothing obvious;
  • debug builds: mostly green, effect of not running ConstProp any more. An exception: keccak (20% regression), as generated MIR is 40% larger.
  • opt builds: mostly red. Largest (diesel) may be due to evaluation of ty unevaluated constants (to be confirmed).

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

bors commented Feb 10, 2023

⌛ Trying commit 2131dae17d267c3c4cb53690cf00cdbc7a2e9de0 with merge 47d13e87e7c1c86fba1429c13a990657fa7a3561...

@bors
Copy link
Contributor

bors commented Feb 10, 2023

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

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (47d13e87e7c1c86fba1429c13a990657fa7a3561): 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.8% [0.3%, 1.6%] 19
Regressions ❌
(secondary)
1.2% [0.9%, 1.6%] 6
Improvements ✅
(primary)
-0.6% [-1.1%, -0.3%] 8
Improvements ✅
(secondary)
-1.0% [-1.2%, -0.8%] 2
All ❌✅ (primary) 0.4% [-1.1%, 1.6%] 27

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.8% [0.1%, 9.2%] 5
Regressions ❌
(secondary)
2.9% [2.7%, 3.1%] 2
Improvements ✅
(primary)
-3.6% [-3.9%, -3.4%] 2
Improvements ✅
(secondary)
-2.2% [-2.2%, -2.2%] 1
All ❌✅ (primary) 1.7% [-3.9%, 9.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)
- - 0
Regressions ❌
(secondary)
6.7% [5.4%, 7.7%] 6
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-1.3% [-1.3%, -1.3%] 1
All ❌✅ (primary) - - 0

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 10, 2023
@rust-log-analyzer

This comment has been minimized.

@cjgillot
Copy link
Contributor 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 Feb 11, 2023
@bors
Copy link
Contributor

bors commented Feb 11, 2023

⌛ Trying commit 9a58168 with merge 1cff2133ab3b7724841c768a38ec63160562386a...

@bors
Copy link
Contributor

bors commented Feb 11, 2023

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

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (1cff2133ab3b7724841c768a38ec63160562386a): 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.6% [0.4%, 0.7%] 5
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.6% [-0.6%, -0.6%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.4% [-0.6%, 0.7%] 6

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.4% [2.4%, 4.1%] 6
Regressions ❌
(secondary)
2.7% [0.7%, 4.2%] 49
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 3.4% [2.4%, 4.1%] 6

Cycles

This benchmark run did not return any relevant results for this metric.

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 11, 2023
@cjgillot
Copy link
Contributor Author

The last perf result confirm there is nothing to gain by extending this pass.
I'll close this PR, and propose the cleanups in another PR based on #107921.

@cjgillot cjgillot closed this Feb 11, 2023
@cjgillot cjgillot deleted the unleash-const-prop branch February 11, 2023 15:10
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. 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants