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

MIR opt: Expand aggregates into multiple locals #85796

Closed
wants to merge 1 commit into from

Conversation

cjgillot
Copy link
Contributor

The MIR deaggregator expands aggregate assignments into field accesses, downcasts and discriminant assignments. However, this creates needlessly complicated place projections that may limit later optimization passes.

This PR attempts to replace those accesses by new locals that can be optimized more easily, for instance by DestProp.

@rust-highfive
Copy link
Collaborator

r? @varkor

(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 May 28, 2021
@rust-log-analyzer

This comment has been minimized.

@tmiasko

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@erikdesjardins
Copy link
Contributor

Related: #48300 was a previous attempt at this

}

fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
if place.projection.is_empty()
Copy link
Member

Choose a reason for hiding this comment

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

I think we should play safe and reject all locals that have their address taken. Whether only for a part of as a whole. At least until we have better support for handling references in mir opts.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented May 30, 2021

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

@rust-log-analyzer

This comment has been minimized.

@varkor
Copy link
Member

varkor commented Jun 6, 2021

I don't have time to review this at the moment. Going to reassign to r? @bjorn3 who's more familiar with this code.

@rust-highfive rust-highfive assigned bjorn3 and unassigned varkor Jun 6, 2021
@bjorn3
Copy link
Member

bjorn3 commented Jun 6, 2021

r? @RalfJung This optimization depends on the exact semantics of MIR and we have had miscompilations due to incorrect MIR optimizations before. As such I don't feel comfortable signing off on a MIR optimization.

@rust-highfive rust-highfive assigned RalfJung and unassigned bjorn3 Jun 6, 2021
@RalfJung
Copy link
Member

RalfJung commented Jun 6, 2021

I can help with advice on MIR semantics, but I won't have time to review a PR of this size any time soon I am afraid.

@bjorn3
Copy link
Member

bjorn3 commented Jun 6, 2021

No problem. I will try to taken review on myself then, but I would like it to either land behind either -Zmir-opt-level=3/4 or -Zunsound-mir-opts.

r? @bjorn3

@rust-highfive rust-highfive assigned bjorn3 and unassigned RalfJung Jun 6, 2021
@bors
Copy link
Contributor

bors commented Jun 7, 2021

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

@rust-log-analyzer

This comment has been minimized.

@crlf0710
Copy link
Member

Triage: Seems CI is still red.

@crlf0710 crlf0710 removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 26, 2021
@rust-timer
Copy link
Collaborator

Queued 2a09f2c20f1895c61a8f6f6a3a484627b2327ce4 with parent d9aa287, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (2a09f2c20f1895c61a8f6f6a3a484627b2327ce4): comparison url.

Summary: This change led to significant mixed results 🤷 in compiler performance.

  • Moderate improvement in instruction counts (up to -4.2% on incr-unchanged builds of deeply-nested-async-check)
  • Moderate regression in instruction counts (up to 1.4% on incr-patched: b9b3e592dd cherry picked builds of style-servo-opt)

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

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 led to changes in compiler perf.

Next Steps: If you can justify the regressions found in this 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-review -S-waiting-on-perf +perf-regression

@rustbot rustbot added the perf-regression Performance regression. label Jul 25, 2021
return;
}

match self.map.fields.entry(place.clone()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

PlaceRef implements copy, so clone should be unnecessary.

Comment on lines 497 to 502
&flatten_locals::FlattenLocals,
&remove_storage_markers::RemoveStorageMarkers,
Copy link
Contributor

Choose a reason for hiding this comment

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

RemoveStorageMarkers removes the storage markers at opt-level=0. Reordering those two passes would avoid needles expansion of storage markers during flattening.

return None;
}
let mut expanded = Vec::new();
for (k, &v) in &replacements.fields {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be quadratic in the MIR size in the worst case. Could we avoid that?

Some(expanded.into_iter())
});
}
super::simplify::simplify_locals(body, tcx);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does running simplify locals immediately after flattening have additional benefits compared to leaving this clean-up for later?

@tmiasko
Copy link
Contributor

tmiasko commented Jul 25, 2021

Benchmarks that slightly regressed include check and doc builds. I would suspect that this is mostly a side effect of different partitioning while building rustc. It could be interesting to run perf comparison while keeping partitioning fixed, e.g., by always returning 1 from MonoItem::size_estimate (though, this would require quite a bit of extra work to prepare to builds for comparison).

@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 15, 2021
@inquisitivecrystal inquisitivecrystal added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 24, 2021
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Sep 9, 2021

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

StatementKind::StorageDead(l) => (false, *l),
_ => return None,
};
replaced_locals.get(origin_local).map(move |final_locals| {
Copy link
Contributor

Choose a reason for hiding this comment

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

This removes storage markers for locals without any replacements (replaced_locals is an IndexVec now, so get doesn't have desired effect).

@tmiasko
Copy link
Contributor

tmiasko commented Sep 9, 2021

Other than the issue with storage markers, the implementation looks good to me. The perf results are mostly a regression, though?

@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 27, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 19, 2021
@cjgillot cjgillot closed this Oct 27, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 15, 2022
Perform simple scalar replacement of aggregates (SROA) MIR opt

This is a re-open of rust-lang#85796

I copied the debuginfo implementation (first commit) from `@eddyb's` own SROA PR.

This pass replaces plain field accesses by simple locals when possible.
To be eligible, the replaced locals:
- must not be enums or unions;
- must not be used whole;
- must not have their address taken.

The storage and deinit statements are duplicated on each created local.

cc `@tmiasko` who reviewed the former version of this PR.
RalfJung pushed a commit to RalfJung/miri that referenced this pull request Nov 16, 2022
Perform simple scalar replacement of aggregates (SROA) MIR opt

This is a re-open of rust-lang/rust#85796

I copied the debuginfo implementation (first commit) from `@eddyb's` own SROA PR.

This pass replaces plain field accesses by simple locals when possible.
To be eligible, the replaced locals:
- must not be enums or unions;
- must not be used whole;
- must not have their address taken.

The storage and deinit statements are duplicated on each created local.

cc `@tmiasko` who reviewed the former version of this PR.
@cjgillot cjgillot deleted the deagg branch February 13, 2023 12:17
antoyo pushed a commit to rust-lang/rustc_codegen_gcc that referenced this pull request Jun 3, 2023
Perform simple scalar replacement of aggregates (SROA) MIR opt

This is a re-open of rust-lang/rust#85796

I copied the debuginfo implementation (first commit) from `@eddyb's` own SROA PR.

This pass replaces plain field accesses by simple locals when possible.
To be eligible, the replaced locals:
- must not be enums or unions;
- must not be used whole;
- must not have their address taken.

The storage and deinit statements are duplicated on each created local.

cc `@tmiasko` who reviewed the former version of this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.