Skip to content

Commit ec7e4f9

Browse files
committed
MIR SRoA: Update escaping_locals to only be about escaping
1 parent fe08ba0 commit ec7e4f9

File tree

1 file changed

+24
-13
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+24
-13
lines changed

compiler/rustc_mir_transform/src/sroa.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
3131
let mut excluded = excluded_locals(body);
3232
let typing_env = body.typing_env(tcx);
3333
loop {
34+
add_type_based_exclusions(tcx, &mut excluded, body);
3435
debug!(?excluded);
35-
let escaping = escaping_locals(tcx, &excluded, body);
36+
let escaping = escaping_locals(&excluded, body);
3637
debug!(?escaping);
3738
let replacements = compute_flattening(tcx, typing_env, body, escaping);
3839
debug!(?replacements);
@@ -55,18 +56,13 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
5556
}
5657
}
5758

58-
/// Identify all locals that are not eligible for SROA.
59-
///
60-
/// There are 3 cases:
61-
/// - the aggregated local is used or passed to other code (function parameters and arguments);
62-
/// - the locals is a union or an enum;
63-
/// - the local's address is taken, and thus the relative addresses of the fields are observable to
64-
/// client code.
65-
fn escaping_locals<'tcx>(
59+
/// Also exclude locals whose types are ineligible for SRoA because of
60+
/// implementation restrictions (whether here or in codegen later).
61+
fn add_type_based_exclusions<'tcx>(
6662
tcx: TyCtxt<'tcx>,
67-
excluded: &DenseBitSet<Local>,
63+
excluded: &mut DenseBitSet<Local>,
6864
body: &Body<'tcx>,
69-
) -> DenseBitSet<Local> {
65+
) {
7066
let is_excluded_ty = |ty: Ty<'tcx>| {
7167
if ty.is_union() || ty.is_enum() {
7268
return true;
@@ -86,10 +82,25 @@ fn escaping_locals<'tcx>(
8682
false
8783
};
8884

85+
for (local, decl) in body.local_decls().iter_enumerated() {
86+
if is_excluded_ty(decl.ty) {
87+
excluded.insert(local);
88+
}
89+
}
90+
}
91+
92+
/// Identify all locals that are not eligible for SROA.
93+
///
94+
/// There are 3 cases:
95+
/// - the aggregated local is used or passed to other code (function parameters and arguments);
96+
/// - the locals is a union or an enum;
97+
/// - the local's address is taken, and thus the relative addresses of the fields are observable to
98+
/// client code.
99+
fn escaping_locals<'tcx>(excluded: &DenseBitSet<Local>, body: &Body<'tcx>) -> DenseBitSet<Local> {
89100
let mut set = DenseBitSet::new_empty(body.local_decls.len());
90101
set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count));
91-
for (local, decl) in body.local_decls().iter_enumerated() {
92-
if excluded.contains(local) || is_excluded_ty(decl.ty) {
102+
for local in body.local_decls().indices() {
103+
if excluded.contains(local) {
93104
set.insert(local);
94105
}
95106
}

0 commit comments

Comments
 (0)