Simplify construction of replacement map.

This commit is contained in:
Camille GILLOT 2023-02-05 11:37:44 +00:00
parent e465d647b1
commit 42c9514629
11 changed files with 196 additions and 160 deletions

View file

@ -790,7 +790,7 @@ impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
} }
/// Invokes `f` on all direct fields of `ty`. /// Invokes `f` on all direct fields of `ty`.
fn iter_fields<'tcx>( pub fn iter_fields<'tcx>(
ty: Ty<'tcx>, ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
mut f: impl FnMut(Option<VariantIdx>, Field, Ty<'tcx>), mut f: impl FnMut(Option<VariantIdx>, Field, Ty<'tcx>),

View file

@ -1,11 +1,12 @@
use crate::MirPass; 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::bit_set::BitSet;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::visit::*; use rustc_middle::mir::visit::*;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::value_analysis::iter_fields;
pub struct ScalarReplacementOfAggregates; pub struct ScalarReplacementOfAggregates;
@ -125,6 +126,36 @@ fn escaping_locals(body: &Body<'_>) -> BitSet<Local> {
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct ReplacementMap<'tcx> { struct ReplacementMap<'tcx> {
fields: FxIndexMap<PlaceRef<'tcx>, Local>, fields: FxIndexMap<PlaceRef<'tcx>, 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, Option<Vec<(&'tcx [PlaceElem<'tcx>], Local)>>>,
}
impl<'tcx> ReplacementMap<'tcx> {
fn gather_debug_info_fragments(
&self,
place: PlaceRef<'tcx>,
) -> Option<Vec<VarDebugInfoFragment<'tcx>>> {
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. /// Compute the replacement of flattened places into locals.
@ -136,53 +167,30 @@ fn compute_flattening<'tcx>(
body: &mut Body<'tcx>, body: &mut Body<'tcx>,
escaping: BitSet<Local>, escaping: BitSet<Local>,
) -> ReplacementMap<'tcx> { ) -> ReplacementMap<'tcx> {
let mut visitor = PreFlattenVisitor { let mut fields = FxIndexMap::default();
tcx, let mut fragments = IndexVec::from_elem(None::<Vec<_>>, &body.local_decls);
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;
struct PreFlattenVisitor<'tcx, 'll> { for local in body.local_decls.indices() {
tcx: TyCtxt<'tcx>, if escaping.contains(local) {
local_decls: &'ll mut LocalDecls<'tcx>, continue;
escaping: BitSet<Local>, }
map: ReplacementMap<'tcx>, let decl = body.local_decls[local].clone();
} let ty = decl.ty;
iter_fields(ty, tcx, |variant, field, field_ty| {
impl<'tcx, 'll> PreFlattenVisitor<'tcx, 'll> { if variant.is_some() {
fn create_place(&mut self, place: PlaceRef<'tcx>) { // Downcasts are currently not supported.
if self.escaping.contains(place.local) {
return; return;
} };
let new_local =
match self.map.fields.entry(place) { body.local_decls.push(LocalDecl { ty: field_ty, user_ty: None, ..decl.clone() });
IndexEntry::Occupied(_) => {} let place = Place::from(local)
IndexEntry::Vacant(v) => { .project_deeper(&[PlaceElem::Field(field, field_ty)], tcx)
let ty = place.ty(&*self.local_decls, self.tcx).ty; .as_ref();
let local = self.local_decls.push(LocalDecl { fields.insert(place, new_local);
ty, fragments[local].get_or_insert_default().push((place.projection, new_local));
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)
}
}
} }
ReplacementMap { fields, fragments }
} }
/// Perform the replacement computed by `compute_flattening`. /// Perform the replacement computed by `compute_flattening`.
@ -200,18 +208,11 @@ fn replace_flattened_locals<'tcx>(
return; return;
} }
let mut fragments = IndexVec::<_, Option<Vec<_>>>::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 { let mut visitor = ReplacementVisitor {
tcx, tcx,
local_decls: &body.local_decls, local_decls: &body.local_decls,
replacements, replacements,
all_dead_locals, all_dead_locals,
fragments: &fragments,
patch: MirPatch::new(body), patch: MirPatch::new(body),
}; };
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() { 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>, replacements: ReplacementMap<'tcx>,
/// This is used to check that we are not leaving references to replaced locals behind. /// This is used to check that we are not leaving references to replaced locals behind.
all_dead_locals: BitSet<Local>, all_dead_locals: BitSet<Local>,
/// 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, Option<Vec<(&'tcx [PlaceElem<'tcx>], Local)>>>,
patch: MirPatch<'tcx>, patch: MirPatch<'tcx>,
} }
impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> { impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> {
fn gather_debug_info_fragments(
&self,
place: PlaceRef<'tcx>,
) -> Option<Vec<VarDebugInfoFragment<'tcx>>> {
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<Place<'tcx>> { fn replace_place(&self, place: PlaceRef<'tcx>) -> Option<Place<'tcx>> {
if let &[PlaceElem::Field(..), ref rest @ ..] = place.projection { if let &[PlaceElem::Field(..), ref rest @ ..] = place.projection {
let pr = PlaceRef { local: place.local, projection: &place.projection[..1] }; let pr = PlaceRef { local: place.local, projection: &place.projection[..1] };
@ -270,14 +251,6 @@ impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> {
None 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> { impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
@ -285,10 +258,11 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
self.tcx self.tcx
} }
#[instrument(level = "trace", skip(self))]
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
match statement.kind { match statement.kind {
StatementKind::StorageLive(l) => { 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 { for &(_, fl) in final_locals {
self.patch.add_statement(location, StatementKind::StorageLive(fl)); self.patch.add_statement(location, StatementKind::StorageLive(fl));
} }
@ -297,7 +271,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
return; return;
} }
StatementKind::StorageDead(l) => { 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 { for &(_, fl) in final_locals {
self.patch.add_statement(location, StatementKind::StorageDead(fl)); self.patch.add_statement(location, StatementKind::StorageDead(fl));
} }
@ -306,7 +280,7 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
return; return;
} }
StatementKind::Deinit(box place) => { 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 { for &(_, fl) in final_locals {
self.patch self.patch
.add_statement(location, StatementKind::Deinit(Box::new(fl.into()))); .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))) => { 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 { for &(projection, fl) in final_locals {
let &[PlaceElem::Field(index, _)] = projection else { bug!() }; let &[PlaceElem::Field(index, _)] = projection else { bug!() };
let index = index.as_usize(); 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(_)))) => { 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 { for &(projection, fl) in final_locals {
let rvalue = let rvalue =
Rvalue::Use(Operand::Move(place.project_deeper(projection, self.tcx))); 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::Move(rplace) => (rplace, false),
Operand::Constant(_) => bug!(), 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 { for &(projection, fl) in final_locals {
let rplace = rplace.project_deeper(projection, self.tcx); 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 { let rvalue = if copy {
Rvalue::Use(Operand::Copy(rplace)) Rvalue::Use(Operand::Copy(rplace))
} else { } else {
@ -389,7 +366,9 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
VarDebugInfoContents::Place(ref mut place) => { VarDebugInfoContents::Place(ref mut place) => {
if let Some(repl) = self.replace_place(place.as_ref()) { if let Some(repl) = self.replace_place(place.as_ref()) {
*place = repl; *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; let ty = place.ty(self.local_decls, self.tcx).ty;
var_debug_info.value = VarDebugInfoContents::Composite { ty, fragments }; 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()) { if let Some(repl) = self.replace_place(fragment.contents.as_ref()) {
fragment.contents = repl; fragment.contents = repl;
true true
} else if let Some(frg) = } else if let Some(frg) = self
self.gather_debug_info_fragments(fragment.contents.as_ref()) .replacements
.gather_debug_info_fragments(fragment.contents.as_ref())
{ {
new_fragments.extend(frg.into_iter().map(|mut f| { new_fragments.extend(frg.into_iter().map(|mut f| {
f.projection.splice(0..0, fragment.projection.iter().copied()); f.projection.splice(0..0, fragment.projection.iter().copied());

View file

@ -8,8 +8,8 @@
let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16 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 _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 _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 _12: 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 _13: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22
scope 1 { scope 1 {
- debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 - 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 + debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10
@ -29,19 +29,21 @@
scope 5 { scope 5 {
- debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 - 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 + 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 { scope 6 {
debug f => _10; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8: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 _11: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 let _10: std::option::Option<u16>; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
scope 7 { scope 7 {
debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 debug o => _10; // 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 _17: 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 let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
scope 8 { scope 8 {
debug p => Point{ .0 => _15, .1 => _16, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 debug p => Point{ .0 => _17, .1 => _18, }; // 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 let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
scope 9 { 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 + debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10
} }
} }
@ -67,17 +69,23 @@
// mir::Constant // mir::Constant
// + span: $DIR/const_debuginfo.rs:14:13: 14:28 // + span: $DIR/const_debuginfo.rs:14:13: 14:28
// + literal: Const { ty: &str, val: Value(Slice(..)) } // + literal: Const { ty: &str, val: Value(Slice(..)) }
StorageLive(_10); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 StorageLive(_14); // 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(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10
_11 = Option::<u16>::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 _14 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
_15 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 _15 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
_16 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 _16 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34
StorageLive(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 StorageLive(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10
_12 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 _10 = Option::<u16>::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
StorageDead(_12); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 _17 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 _18 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
StorageDead(_10); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 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(_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 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 return; // scope 0 at $DIR/const_debuginfo.rs:+14:2: +14:2

View file

@ -6,9 +6,10 @@
let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
scope 1 { scope 1 {
debug x => _1; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14 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 { 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 = 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 (_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 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 StorageLive(_3); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
+ _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 - _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(_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 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 return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2
} }

View file

@ -9,9 +9,10 @@
let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 let _2: &mut (i32, i32); // in scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10
scope 2 { scope 2 {
debug z => _2; // in scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+2:9: +2:10 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 { 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 = &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 ((*_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 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(_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(_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 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 return; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:2: +5:2

View file

@ -10,13 +10,13 @@
let mut _5: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 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 let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
scope 2 { 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 let _3: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
scope 3 { scope 3 {
debug y => _3; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 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 let _4: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
scope 4 { 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: { bb1: {
StorageLive(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 StorageLive(_6); // 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 _5 = const 1_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 _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 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 _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 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 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(_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 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 return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2
} }

View file

@ -11,6 +11,7 @@
let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 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 _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 _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 { scope 1 {
debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 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 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 - _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 - 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(_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 + 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 + 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(_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 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39
nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 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 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2

View file

@ -5,44 +5,65 @@
debug x => _1; // in scope 0 at $DIR/sroa.rs:+0:11: +0:12 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 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 _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 { scope 1 {
- debug y => _2; // 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
+ debug y => Foo{ .0 => _5, .2 => _6, }; // 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 let _3: u8; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10
scope 2 { scope 2 {
debug t => _3; // in scope 2 at $DIR/sroa.rs:+2:9: +2:10 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 let _4: &str; // in scope 2 at $DIR/sroa.rs:+3:9: +3:10
scope 3 { scope 3 {
debug u => _4; // in scope 3 at $DIR/sroa.rs:+3:9: +3:10 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<isize>; // 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: { bb0: {
- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
- _2 = _1; // scope 0 at $DIR/sroa.rs:+1:13: +1:14 _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(_3); // scope 1 at $DIR/sroa.rs:+2:9: +2:10 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 = (_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 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 = (_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 - StorageLive(_5); // scope 3 at $DIR/sroa.rs:+4:9: +4:10
_0 = const (); // scope 0 at $DIR/sroa.rs:+0:19: +4:2 - _5 = _2; // scope 3 at $DIR/sroa.rs:+4:13: +4:14
StorageDead(_4); // scope 2 at $DIR/sroa.rs:+4:1: +4:2 + StorageLive(_7); // scope 3 at $DIR/sroa.rs:+4:9: +4:10
StorageDead(_3); // scope 1 at $DIR/sroa.rs:+4:1: +4:2 + StorageLive(_8); // scope 3 at $DIR/sroa.rs:+4:9: +4:10
- StorageDead(_2); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + StorageLive(_9); // scope 3 at $DIR/sroa.rs:+4:9: +4:10
+ StorageDead(_5); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + StorageLive(_10); // scope 3 at $DIR/sroa.rs:+4:9: +4:10
+ StorageDead(_6); // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + nop; // scope 3 at $DIR/sroa.rs:+4:9: +4:10
+ nop; // scope 0 at $DIR/sroa.rs:+4:1: +4:2 + _7 = (_2.0: u8); // scope 3 at $DIR/sroa.rs:+4:13: +4:14
return; // scope 0 at $DIR/sroa.rs:+4:2: +4:2 + _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<isize>); // 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
} }
} }

View file

@ -6,10 +6,12 @@
let mut _0: (); // return place in scope 0 at $DIR/sroa.rs:+0:24: +0:24 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 _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 _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<isize>; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
scope 1 { scope 1 {
- debug y => _2; // 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
+ 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 let _3: u8; // in scope 1 at $DIR/sroa.rs:+2:9: +2:10
scope 2 { scope 2 {
debug t => _3; // in scope 2 at $DIR/sroa.rs:+2:9: +2:10 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 - _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(_5); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
+ StorageLive(_6); // 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 + 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 + _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<isize>); // scope 0 at $DIR/sroa.rs:+1:13: +1:15
+ nop; // 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 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 = (_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 = _5; // scope 1 at $DIR/sroa.rs:+2:13: +2:16
StorageLive(_4); // scope 2 at $DIR/sroa.rs:+3:9: +3:10 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 = (_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 _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(_4); // scope 2 at $DIR/sroa.rs:+4:1: +4:2
StorageDead(_3); // scope 1 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(_2); // scope 0 at $DIR/sroa.rs:+4:1: +4:2
+ StorageDead(_5); // 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(_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 + nop; // scope 0 at $DIR/sroa.rs:+4:1: +4:2
return; // scope 0 at $DIR/sroa.rs:+4:2: +4:2 return; // scope 0 at $DIR/sroa.rs:+4:2: +4:2
} }

View file

@ -77,6 +77,8 @@ fn copies(x: Foo) {
let y = x; let y = x;
let t = y.a; let t = y.a;
let u = y.c; let u = y.c;
let z = y;
let a = z.b;
} }
fn ref_copies(x: &Foo) { fn ref_copies(x: &Foo) {

View file

@ -6,22 +6,26 @@
let mut _0: f32; // return place in scope 0 at $DIR/sroa.rs:+0:27: +0:30 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 _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 _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: { bb0: {
- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+6:5: +6:21 - 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(_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 + nop; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19 StorageLive(_3); // scope 0 at $DIR/sroa.rs:+6:18: +6:19
_3 = _1; // 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 - _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 + nop; // scope 0 at $DIR/sroa.rs:+6:5: +6:21
StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:20: +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 - _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 - 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(_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 + nop; // scope 0 at $DIR/sroa.rs:+7:1: +7:2
return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2 return; // scope 0 at $DIR/sroa.rs:+7:2: +7:2
} }