From 42c95146294c7773ca03e91e945fd545c6ce1ba2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 5 Feb 2023 11:37:44 +0000 Subject: [PATCH] Simplify construction of replacement map. --- .../rustc_mir_dataflow/src/value_analysis.rs | 2 +- compiler/rustc_mir_transform/src/sroa.rs | 158 ++++++++---------- .../const_debuginfo.main.ConstDebugInfo.diff | 52 +++--- ...ble_variable_aggregate.main.ConstProp.diff | 13 +- ...able_aggregate_mut_ref.main.ConstProp.diff | 10 +- ...variable_unprop_assign.main.ConstProp.diff | 16 +- ...n.ScalarReplacementOfAggregates.64bit.diff | 8 +- ....copies.ScalarReplacementOfAggregates.diff | 69 +++++--- ..._copies.ScalarReplacementOfAggregates.diff | 16 +- tests/mir-opt/sroa.rs | 2 + ...structs.ScalarReplacementOfAggregates.diff | 10 +- 11 files changed, 196 insertions(+), 160 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 6bdbda909d7..90d07c81256 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -790,7 +790,7 @@ impl TryFrom> for TrackElem { } /// Invokes `f` on all direct fields of `ty`. -fn iter_fields<'tcx>( +pub fn iter_fields<'tcx>( ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, mut f: impl FnMut(Option, Field, Ty<'tcx>), diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 462c3b4e918..3cfa0b16499 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -1,11 +1,12 @@ use crate::MirPass; -use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; +use rustc_data_structures::fx::FxIndexMap; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_mir_dataflow::value_analysis::iter_fields; pub struct ScalarReplacementOfAggregates; @@ -125,6 +126,36 @@ fn escaping_locals(body: &Body<'_>) -> BitSet { #[derive(Default, Debug)] struct ReplacementMap<'tcx> { fields: FxIndexMap, Local>, + /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage + /// and deinit statement and debuginfo. + fragments: IndexVec], Local)>>>, +} + +impl<'tcx> ReplacementMap<'tcx> { + fn gather_debug_info_fragments( + &self, + place: PlaceRef<'tcx>, + ) -> Option>> { + let mut fragments = Vec::new(); + let Some(parts) = &self.fragments[place.local] else { return None }; + for (proj, replacement_local) in parts { + if proj.starts_with(place.projection) { + fragments.push(VarDebugInfoFragment { + projection: proj[place.projection.len()..].to_vec(), + contents: Place::from(*replacement_local), + }); + } + } + Some(fragments) + } + + fn place_fragments( + &self, + place: Place<'tcx>, + ) -> Option<&Vec<(&'tcx [PlaceElem<'tcx>], Local)>> { + let local = place.as_local()?; + self.fragments[local].as_ref() + } } /// Compute the replacement of flattened places into locals. @@ -136,53 +167,30 @@ fn compute_flattening<'tcx>( body: &mut Body<'tcx>, escaping: BitSet, ) -> ReplacementMap<'tcx> { - let mut visitor = PreFlattenVisitor { - tcx, - escaping, - local_decls: &mut body.local_decls, - map: Default::default(), - }; - for (block, bbdata) in body.basic_blocks.iter_enumerated() { - visitor.visit_basic_block_data(block, bbdata); - } - return visitor.map; + let mut fields = FxIndexMap::default(); + let mut fragments = IndexVec::from_elem(None::>, &body.local_decls); - struct PreFlattenVisitor<'tcx, 'll> { - tcx: TyCtxt<'tcx>, - local_decls: &'ll mut LocalDecls<'tcx>, - escaping: BitSet, - map: ReplacementMap<'tcx>, - } - - impl<'tcx, 'll> PreFlattenVisitor<'tcx, 'll> { - fn create_place(&mut self, place: PlaceRef<'tcx>) { - if self.escaping.contains(place.local) { + for local in body.local_decls.indices() { + if escaping.contains(local) { + continue; + } + let decl = body.local_decls[local].clone(); + let ty = decl.ty; + iter_fields(ty, tcx, |variant, field, field_ty| { + if variant.is_some() { + // Downcasts are currently not supported. return; - } - - match self.map.fields.entry(place) { - IndexEntry::Occupied(_) => {} - IndexEntry::Vacant(v) => { - let ty = place.ty(&*self.local_decls, self.tcx).ty; - let local = self.local_decls.push(LocalDecl { - ty, - user_ty: None, - ..self.local_decls[place.local].clone() - }); - v.insert(local); - } - } - } - } - - impl<'tcx, 'll> Visitor<'tcx> for PreFlattenVisitor<'tcx, 'll> { - fn visit_place(&mut self, place: &Place<'tcx>, _: PlaceContext, _: Location) { - if let &[PlaceElem::Field(..), ..] = &place.projection[..] { - let pr = PlaceRef { local: place.local, projection: &place.projection[..1] }; - self.create_place(pr) - } - } + }; + let new_local = + body.local_decls.push(LocalDecl { ty: field_ty, user_ty: None, ..decl.clone() }); + let place = Place::from(local) + .project_deeper(&[PlaceElem::Field(field, field_ty)], tcx) + .as_ref(); + fields.insert(place, new_local); + fragments[local].get_or_insert_default().push((place.projection, new_local)); + }); } + ReplacementMap { fields, fragments } } /// Perform the replacement computed by `compute_flattening`. @@ -200,18 +208,11 @@ fn replace_flattened_locals<'tcx>( return; } - let mut fragments = IndexVec::<_, Option>>::from_elem(None, &body.local_decls); - for (k, v) in &replacements.fields { - fragments[k.local].get_or_insert_default().push((k.projection, *v)); - } - debug!(?fragments); - let mut visitor = ReplacementVisitor { tcx, local_decls: &body.local_decls, replacements, all_dead_locals, - fragments: &fragments, patch: MirPatch::new(body), }; for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { @@ -237,30 +238,10 @@ struct ReplacementVisitor<'tcx, 'll> { replacements: ReplacementMap<'tcx>, /// This is used to check that we are not leaving references to replaced locals behind. all_dead_locals: BitSet, - /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage - /// and deinit statement and debuginfo. - fragments: &'ll IndexVec], Local)>>>, patch: MirPatch<'tcx>, } impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> { - fn gather_debug_info_fragments( - &self, - place: PlaceRef<'tcx>, - ) -> Option>> { - let mut fragments = Vec::new(); - let Some(parts) = &self.fragments[place.local] else { return None }; - for (proj, replacement_local) in parts { - if proj.starts_with(place.projection) { - fragments.push(VarDebugInfoFragment { - projection: proj[place.projection.len()..].to_vec(), - contents: Place::from(*replacement_local), - }); - } - } - Some(fragments) - } - fn replace_place(&self, place: PlaceRef<'tcx>) -> Option> { if let &[PlaceElem::Field(..), ref rest @ ..] = place.projection { let pr = PlaceRef { local: place.local, projection: &place.projection[..1] }; @@ -270,14 +251,6 @@ impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> { None } } - - fn place_fragments( - &self, - place: Place<'tcx>, - ) -> Option<&'ll Vec<(&'tcx [PlaceElem<'tcx>], Local)>> { - let local = place.as_local()?; - self.fragments[local].as_ref() - } } impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { @@ -285,10 +258,11 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { self.tcx } + #[instrument(level = "trace", skip(self))] fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { match statement.kind { StatementKind::StorageLive(l) => { - if let Some(final_locals) = &self.fragments[l] { + if let Some(final_locals) = &self.replacements.fragments[l] { for &(_, fl) in final_locals { self.patch.add_statement(location, StatementKind::StorageLive(fl)); } @@ -297,7 +271,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { return; } StatementKind::StorageDead(l) => { - if let Some(final_locals) = &self.fragments[l] { + if let Some(final_locals) = &self.replacements.fragments[l] { for &(_, fl) in final_locals { self.patch.add_statement(location, StatementKind::StorageDead(fl)); } @@ -306,7 +280,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { return; } StatementKind::Deinit(box place) => { - if let Some(final_locals) = self.place_fragments(place) { + if let Some(final_locals) = self.replacements.place_fragments(place) { for &(_, fl) in final_locals { self.patch .add_statement(location, StatementKind::Deinit(Box::new(fl.into()))); @@ -317,7 +291,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { } StatementKind::Assign(box (place, Rvalue::Aggregate(_, ref operands))) => { - if let Some(final_locals) = self.place_fragments(place) { + if let Some(final_locals) = self.replacements.place_fragments(place) { for &(projection, fl) in final_locals { let &[PlaceElem::Field(index, _)] = projection else { bug!() }; let index = index.as_usize(); @@ -333,7 +307,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { } StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => { - if let Some(final_locals) = self.place_fragments(place) { + if let Some(final_locals) = self.replacements.place_fragments(place) { for &(projection, fl) in final_locals { let rvalue = Rvalue::Use(Operand::Move(place.project_deeper(projection, self.tcx))); @@ -353,9 +327,12 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { Operand::Move(rplace) => (rplace, false), Operand::Constant(_) => bug!(), }; - if let Some(final_locals) = self.place_fragments(lhs) { + if let Some(final_locals) = self.replacements.place_fragments(lhs) { for &(projection, fl) in final_locals { let rplace = rplace.project_deeper(projection, self.tcx); + debug!(?rplace); + let rplace = self.replace_place(rplace.as_ref()).unwrap_or(rplace); + debug!(?rplace); let rvalue = if copy { Rvalue::Use(Operand::Copy(rplace)) } else { @@ -389,7 +366,9 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { VarDebugInfoContents::Place(ref mut place) => { if let Some(repl) = self.replace_place(place.as_ref()) { *place = repl; - } else if let Some(fragments) = self.gather_debug_info_fragments(place.as_ref()) { + } else if let Some(fragments) = + self.replacements.gather_debug_info_fragments(place.as_ref()) + { let ty = place.ty(self.local_decls, self.tcx).ty; var_debug_info.value = VarDebugInfoContents::Composite { ty, fragments }; } @@ -401,8 +380,9 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> { if let Some(repl) = self.replace_place(fragment.contents.as_ref()) { fragment.contents = repl; true - } else if let Some(frg) = - self.gather_debug_info_fragments(fragment.contents.as_ref()) + } else if let Some(frg) = self + .replacements + .gather_debug_info_fragments(fragment.contents.as_ref()) { new_fragments.extend(frg.into_iter().map(|mut f| { f.projection.splice(0..0, fragment.projection.iter().copied()); diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff index e14e586f34b..f1f53a48165 100644 --- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -8,8 +8,8 @@ let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16 let mut _7: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:19: +4:20 let mut _8: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:23: +4:24 - let mut _13: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 - let mut _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 + let mut _12: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 + let mut _13: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 scope 1 { - debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 + debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 @@ -29,19 +29,21 @@ scope 5 { - debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 + debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 - let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _14: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _15: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _16: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 scope 6 { - debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 - let _11: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + debug f => (bool, bool, u32){ .0 => _14, .1 => _15, .2 => _16, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _10: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 scope 7 { - debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 - let _15: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 - let _16: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + debug o => _10; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 + let _17: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 scope 8 { - debug p => Point{ .0 => _15, .1 => _16, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 - let _12: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + debug p => Point{ .0 => _17, .1 => _18, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 scope 9 { -- debug a => _12; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 +- debug a => _11; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 + debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 } } @@ -67,17 +69,23 @@ // mir::Constant // + span: $DIR/const_debuginfo.rs:14:13: 14:28 // + literal: Const { ty: &str, val: Value(Slice(..)) } - StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - _10 = (const true, const false, const 123_u32); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 - _11 = Option::::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 - _15 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - _16 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - StorageLive(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 - _12 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 - StorageDead(_12); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageLive(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + _14 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _15 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _16 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + StorageLive(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + _10 = Option::::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + _17 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + _18 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + StorageLive(_11); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + _11 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 + StorageDead(_11); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_10); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_14); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_15); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_16); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2 return; // scope 0 at $DIR/const_debuginfo.rs:+14:2: +14:2 diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index 0eb47087c9c..37fbcf9dd49 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -6,9 +6,10 @@ let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 scope 1 { debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 - let _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + let _2: i32; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + let _3: i32; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 + debug y => (i32, i32){ .0 => _2, .1 => _3, }; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 } } @@ -18,9 +19,13 @@ + _1 = const (42_i32, 43_i32); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25 (_1.1: i32) = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+2:5: +2:13 StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 -- _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 -+ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 + StorageLive(_3); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 +- _2 = (_1.0: i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 +- _3 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 ++ _2 = const 42_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 ++ _3 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 + StorageDead(_3); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2 } diff --git a/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff index 26a1c3c1aa9..134f0c080bf 100644 --- a/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff @@ -9,9 +9,10 @@ let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 scope 2 { debug z => _2; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 - let _3: (i32, i32); // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + let _3: i32; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + let _4: i32; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 scope 3 { - debug y => _3; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + debug y => (i32, i32){ .0 => _3, .1 => _4, }; // in scope 3 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 } } } @@ -23,8 +24,11 @@ _2 = &mut _1; // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:13: +2:19 ((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13 StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 - _3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 + StorageLive(_4); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 + _3 = (_1.0: i32); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 + _4 = (_1.1: i32); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 StorageDead(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 + StorageDead(_4); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 return; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2 diff --git a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff index 8bd589fb2c8..4010dd6c6d0 100644 --- a/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff +++ b/tests/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff @@ -10,13 +10,13 @@ let mut _5: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 scope 2 { - debug x => (i32, i32){ .1 => _5, .0 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + debug x => (i32, i32){ .0 => _5, .1 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 let _3: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 scope 3 { debug y => _3; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 let _4: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 scope 4 { - debug z => _6; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 } } } @@ -31,17 +31,17 @@ } bb1: { - StorageLive(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 - _5 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 - _6 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + StorageLive(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + _5 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + _6 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 StorageLive(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 _2 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - _5 = move _2; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 + _6 = move _2; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 StorageDead(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 - _3 = _5; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 + _3 = _6; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 - StorageDead(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2 } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff index 87271f24fc4..98cd020dade 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff @@ -11,6 +11,7 @@ let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -51,11 +52,14 @@ - _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 -+ _10 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 ++ _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 -+ _8 = _10; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 ++ _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 ++ StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + nop; // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff index 72610de8eaf..b76e2d6d0f2 100644 --- a/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff @@ -5,44 +5,65 @@ debug x => _1; // in scope 0 at $DIR/sroa.rs:+0:11: +0:12 let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:19: +0:19 let _2: Foo; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 -+ let _5: u8; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 -+ let _6: &str; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 scope 1 { -- debug y => _2; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 -+ debug y => Foo{ .0 => _5, .2 => _6, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 + debug y => _2; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 let _3: u8; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 scope 2 { debug t => _3; // in scope 2 at $DIR/sroa.rs:+2:9: +2:10 let _4: &str; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10 scope 3 { debug u => _4; // in scope 3 at $DIR/sroa.rs:+3:9: +3:10 + let _5: Foo; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _7: u8; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _8: (); // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _9: &str; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ let _10: std::option::Option; // in scope 3 at $DIR/sroa.rs:+4:9: +4:10 + scope 4 { +- debug z => _5; // in scope 4 at $DIR/sroa.rs:+4:9: +4:10 ++ debug z => Foo{ .0 => _7, .1 => _8, .2 => _9, .3 => _10, }; // in scope 4 at $DIR/sroa.rs:+4:9: +4:10 + let _6: (); // in scope 4 at $DIR/sroa.rs:+5:9: +5:10 + scope 5 { + debug a => _6; // in scope 5 at $DIR/sroa.rs:+5:9: +5:10 + } + } } } } bb0: { -- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 -- _2 = _1; // scope 0 at $DIR/sroa.rs:+1:13: +1:14 -+ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 -+ StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 -+ nop; // scope 0 at $DIR/sroa.rs:+1:9: +1:10 -+ _5 = (_1.0: u8); // scope 0 at $DIR/sroa.rs:+1:13: +1:14 -+ _6 = (_1.2: &str); // scope 0 at $DIR/sroa.rs:+1:13: +1:14 -+ nop; // scope 0 at $DIR/sroa.rs:+1:13: +1:14 + StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 + _2 = _1; // scope 0 at $DIR/sroa.rs:+1:13: +1:14 StorageLive(_3); // scope 1 at $DIR/sroa.rs:+2:9: +2:10 -- _3 = (_2.0: u8); // scope 1 at $DIR/sroa.rs:+2:13: +2:16 -+ _3 = _5; // scope 1 at $DIR/sroa.rs:+2:13: +2:16 + _3 = (_2.0: u8); // scope 1 at $DIR/sroa.rs:+2:13: +2:16 StorageLive(_4); // scope 2 at $DIR/sroa.rs:+3:9: +3:10 -- _4 = (_2.2: &str); // scope 2 at $DIR/sroa.rs:+3:13: +3:16 -+ _4 = _6; // scope 2 at $DIR/sroa.rs:+3:13: +3:16 - _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +4:2 - StorageDead(_4); // scope 2 at $DIR/sroa.rs:+4:1: +4:2 - StorageDead(_3); // scope 1 at $DIR/sroa.rs:+4:1: +4:2 -- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 -+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 -+ StorageDead(_6); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 -+ nop; // scope 0 at $DIR/sroa.rs:+4:1: +4:2 - return; // scope 0 at $DIR/sroa.rs:+4:2: +4:2 + _4 = (_2.2: &str); // scope 2 at $DIR/sroa.rs:+3:13: +3:16 +- StorageLive(_5); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 +- _5 = _2; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ StorageLive(_7); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ StorageLive(_8); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ StorageLive(_9); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ StorageLive(_10); // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ nop; // scope 3 at $DIR/sroa.rs:+4:9: +4:10 ++ _7 = (_2.0: u8); // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _8 = (_2.1: ()); // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _9 = (_2.2: &str); // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ _10 = (_2.3: std::option::Option); // scope 3 at $DIR/sroa.rs:+4:13: +4:14 ++ nop; // scope 3 at $DIR/sroa.rs:+4:13: +4:14 + StorageLive(_6); // scope 4 at $DIR/sroa.rs:+5:9: +5:10 +- _6 = (_5.1: ()); // scope 4 at $DIR/sroa.rs:+5:13: +5:16 ++ _6 = _8; // scope 4 at $DIR/sroa.rs:+5:13: +5:16 + _0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +6:2 + StorageDead(_6); // scope 4 at $DIR/sroa.rs:+6:1: +6:2 +- StorageDead(_5); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_7); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_8); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_9); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ StorageDead(_10); // scope 3 at $DIR/sroa.rs:+6:1: +6:2 ++ nop; // scope 3 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_4); // scope 2 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_3); // scope 1 at $DIR/sroa.rs:+6:1: +6:2 + StorageDead(_2); // scope 0 at $DIR/sroa.rs:+6:1: +6:2 + return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2 } } diff --git a/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff index 1a561a9edde..f0d62220dd6 100644 --- a/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.ref_copies.ScalarReplacementOfAggregates.diff @@ -6,10 +6,12 @@ let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:24: +0:24 let _2: Foo; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 + let _5: u8; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 -+ let _6: &str; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _6: (); // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _7: &str; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ let _8: std::option::Option; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10 scope 1 { - debug y => _2; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 -+ debug y => Foo{ .0 => _5, .2 => _6, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 ++ debug y => Foo{ .0 => _5, .1 => _6, .2 => _7, .3 => _8, }; // in scope 1 at $DIR/sroa.rs:+1:9: +1:10 let _3: u8; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10 scope 2 { debug t => _3; // in scope 2 at $DIR/sroa.rs:+2:9: +2:10 @@ -25,22 +27,28 @@ - _2 = (*_1); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 + StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 + StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 ++ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 + nop; // scope 0 at $DIR/sroa.rs:+1:9: +1:10 + _5 = ((*_1).0: u8); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 -+ _6 = ((*_1).2: &str); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ _6 = ((*_1).1: ()); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ _7 = ((*_1).2: &str); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 ++ _8 = ((*_1).3: std::option::Option); // scope 0 at $DIR/sroa.rs:+1:13: +1:15 + nop; // scope 0 at $DIR/sroa.rs:+1:13: +1:15 StorageLive(_3); // scope 1 at $DIR/sroa.rs:+2:9: +2:10 - _3 = (_2.0: u8); // scope 1 at $DIR/sroa.rs:+2:13: +2:16 + _3 = _5; // scope 1 at $DIR/sroa.rs:+2:13: +2:16 StorageLive(_4); // scope 2 at $DIR/sroa.rs:+3:9: +3:10 - _4 = (_2.2: &str); // scope 2 at $DIR/sroa.rs:+3:13: +3:16 -+ _4 = _6; // scope 2 at $DIR/sroa.rs:+3:13: +3:16 ++ _4 = _7; // scope 2 at $DIR/sroa.rs:+3:13: +3:16 _0 = const (); // scope 0 at $DIR/sroa.rs:+0:24: +4:2 StorageDead(_4); // scope 2 at $DIR/sroa.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/sroa.rs:+4:1: +4:2 - StorageDead(_2); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + StorageDead(_5); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + StorageDead(_6); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ StorageDead(_7); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 ++ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + nop; // scope 0 at $DIR/sroa.rs:+4:1: +4:2 return; // scope 0 at $DIR/sroa.rs:+4:2: +4:2 } diff --git a/tests/mir-opt/sroa.rs b/tests/mir-opt/sroa.rs index b80f61600c2..471aac9f9d8 100644 --- a/tests/mir-opt/sroa.rs +++ b/tests/mir-opt/sroa.rs @@ -77,6 +77,8 @@ fn copies(x: Foo) { let y = x; let t = y.a; let u = y.c; + let z = y; + let a = z.b; } fn ref_copies(x: &Foo) { diff --git a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff index ca3cb3d8ed1..2c63d8b266d 100644 --- a/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa.structs.ScalarReplacementOfAggregates.diff @@ -6,22 +6,26 @@ let mut _0: f32; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30 let mut _2: structs::U; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 let mut _3: f32; // in scope 0 at $DIR/sroa.rs:+6:18: +6:19 -+ let mut _4: f32; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ let mut _4: usize; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ let mut _5: f32; // in scope 0 at $DIR/sroa.rs:+6:5: +6:21 bb0: { - StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 + StorageLive(_4); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ StorageLive(_5); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 + nop; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19 _3 = _1; // scope 0 at $DIR/sroa.rs:+6:18: +6:19 - _2 = U { _foo: const 0_usize, a: move _3 }; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 -+ _4 = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ _4 = const 0_usize; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 ++ _5 = move _3; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 + nop; // scope 0 at $DIR/sroa.rs:+6:5: +6:21 StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:20: +6:21 - _0 = (_2.1: f32); // scope 0 at $DIR/sroa.rs:+6:5: +6:23 - StorageDead(_2); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 -+ _0 = _4; // scope 0 at $DIR/sroa.rs:+6:5: +6:23 ++ _0 = _5; // scope 0 at $DIR/sroa.rs:+6:5: +6:23 + StorageDead(_4); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 ++ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+7:1: +7:2 + nop; // scope 0 at $DIR/sroa.rs:+7:1: +7:2 return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2 }