Rollup merge of #107687 - cjgillot:sroa-2, r=oli-obk
Adapt SROA MIR opt for aggregated MIR The pass was broken by https://github.com/rust-lang/rust/pull/107267. This PR extends it to replace: ``` x = Struct { 0: a, 1: b } y = move? x ``` by assignment between locals ``` x_0 = a x_1 = b y_0 = move? x_0 y_1 = move? x_1 ``` The improved pass runs to fixpoint, so we can flatten nested field accesses.
This commit is contained in:
commit
e385ca25be
21 changed files with 589 additions and 313 deletions
|
@ -790,7 +790,7 @@ impl<V, T> TryFrom<ProjectionElem<V, T>> 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<VariantIdx>, Field, Ty<'tcx>),
|
||||
|
@ -824,7 +824,7 @@ fn iter_fields<'tcx>(
|
|||
}
|
||||
|
||||
/// Returns all locals with projections that have their reference or address taken.
|
||||
fn excluded_locals(body: &Body<'_>) -> IndexVec<Local, bool> {
|
||||
pub fn excluded_locals(body: &Body<'_>) -> IndexVec<Local, bool> {
|
||||
struct Collector {
|
||||
result: IndexVec<Local, bool>,
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use crate::MirPass;
|
||||
use rustc_data_structures::fx::{FxIndexMap, IndexEntry};
|
||||
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_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields};
|
||||
|
||||
pub struct ScalarReplacementOfAggregates;
|
||||
|
||||
|
@ -13,27 +14,41 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
|
|||
sess.mir_opt_level() >= 3
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, tcx, body))]
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let escaping = escaping_locals(&*body);
|
||||
debug!(?escaping);
|
||||
let replacements = compute_flattening(tcx, body, escaping);
|
||||
debug!(?replacements);
|
||||
replace_flattened_locals(tcx, body, replacements);
|
||||
debug!(def_id = ?body.source.def_id());
|
||||
let mut excluded = excluded_locals(body);
|
||||
loop {
|
||||
debug!(?excluded);
|
||||
let escaping = escaping_locals(&excluded, body);
|
||||
debug!(?escaping);
|
||||
let replacements = compute_flattening(tcx, body, escaping);
|
||||
debug!(?replacements);
|
||||
let all_dead_locals = replace_flattened_locals(tcx, body, replacements);
|
||||
if !all_dead_locals.is_empty() {
|
||||
for local in excluded.indices() {
|
||||
excluded[local] |= all_dead_locals.contains(local);
|
||||
}
|
||||
excluded.raw.resize(body.local_decls.len(), false);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Identify all locals that are not eligible for SROA.
|
||||
///
|
||||
/// There are 3 cases:
|
||||
/// - the aggegated local is used or passed to other code (function parameters and arguments);
|
||||
/// - the aggregated local is used or passed to other code (function parameters and arguments);
|
||||
/// - the locals is a union or an enum;
|
||||
/// - the local's address is taken, and thus the relative addresses of the fields are observable to
|
||||
/// client code.
|
||||
fn escaping_locals(body: &Body<'_>) -> BitSet<Local> {
|
||||
fn escaping_locals(excluded: &IndexVec<Local, bool>, body: &Body<'_>) -> BitSet<Local> {
|
||||
let mut set = BitSet::new_empty(body.local_decls.len());
|
||||
set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count));
|
||||
for (local, decl) in body.local_decls().iter_enumerated() {
|
||||
if decl.ty.is_union() || decl.ty.is_enum() {
|
||||
if decl.ty.is_union() || decl.ty.is_enum() || excluded[local] {
|
||||
set.insert(local);
|
||||
}
|
||||
}
|
||||
|
@ -58,41 +73,33 @@ fn escaping_locals(body: &Body<'_>) -> BitSet<Local> {
|
|||
self.super_place(place, context, location);
|
||||
}
|
||||
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
if let Rvalue::AddressOf(.., place) | Rvalue::Ref(.., place) = rvalue {
|
||||
if !place.is_indirect() {
|
||||
// Raw pointers may be used to access anything inside the enclosing place.
|
||||
self.set.insert(place.local);
|
||||
return;
|
||||
fn visit_assign(
|
||||
&mut self,
|
||||
lvalue: &Place<'tcx>,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
if lvalue.as_local().is_some() {
|
||||
match rvalue {
|
||||
// Aggregate assignments are expanded in run_pass.
|
||||
Rvalue::Aggregate(..) | Rvalue::Use(..) => {
|
||||
self.visit_rvalue(rvalue, location);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.super_rvalue(rvalue, location)
|
||||
self.super_assign(lvalue, rvalue, location)
|
||||
}
|
||||
|
||||
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
|
||||
if let StatementKind::StorageLive(..)
|
||||
| StatementKind::StorageDead(..)
|
||||
| StatementKind::Deinit(..) = statement.kind
|
||||
{
|
||||
match statement.kind {
|
||||
// Storage statements are expanded in run_pass.
|
||||
return;
|
||||
StatementKind::StorageLive(..)
|
||||
| StatementKind::StorageDead(..)
|
||||
| StatementKind::Deinit(..) => return,
|
||||
_ => self.super_statement(statement, location),
|
||||
}
|
||||
self.super_statement(statement, location)
|
||||
}
|
||||
|
||||
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
|
||||
// Drop implicitly calls `drop_in_place`, which takes a `&mut`.
|
||||
// This implies that `Drop` implicitly takes the address of the place.
|
||||
if let TerminatorKind::Drop { place, .. }
|
||||
| TerminatorKind::DropAndReplace { place, .. } = terminator.kind
|
||||
{
|
||||
if !place.is_indirect() {
|
||||
// Raw pointers may be used to access anything inside the enclosing place.
|
||||
self.set.insert(place.local);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.super_terminator(terminator, location);
|
||||
}
|
||||
|
||||
// We ignore anything that happens in debuginfo, since we expand it using
|
||||
|
@ -103,7 +110,30 @@ fn escaping_locals(body: &Body<'_>) -> BitSet<Local> {
|
|||
|
||||
#[derive(Default, Debug)]
|
||||
struct ReplacementMap<'tcx> {
|
||||
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<IndexVec<Field, Option<(Ty<'tcx>, Local)>>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> ReplacementMap<'tcx> {
|
||||
fn replace_place(&self, tcx: TyCtxt<'tcx>, place: PlaceRef<'tcx>) -> Option<Place<'tcx>> {
|
||||
let &[PlaceElem::Field(f, _), ref rest @ ..] = place.projection else { return None; };
|
||||
let fields = self.fragments[place.local].as_ref()?;
|
||||
let (_, new_local) = fields[f]?;
|
||||
Some(Place { local: new_local, projection: tcx.intern_place_elems(&rest) })
|
||||
}
|
||||
|
||||
fn place_fragments(
|
||||
&self,
|
||||
place: Place<'tcx>,
|
||||
) -> Option<impl Iterator<Item = (Field, Ty<'tcx>, Local)> + '_> {
|
||||
let local = place.as_local()?;
|
||||
let fields = self.fragments[local].as_ref()?;
|
||||
Some(fields.iter_enumerated().filter_map(|(field, &opt_ty_local)| {
|
||||
let (ty, local) = opt_ty_local?;
|
||||
Some((field, ty, local))
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the replacement of flattened places into locals.
|
||||
|
@ -115,53 +145,25 @@ fn compute_flattening<'tcx>(
|
|||
body: &mut Body<'tcx>,
|
||||
escaping: BitSet<Local>,
|
||||
) -> 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 fragments = IndexVec::from_elem(None, &body.local_decls);
|
||||
|
||||
struct PreFlattenVisitor<'tcx, 'll> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
local_decls: &'ll mut LocalDecls<'tcx>,
|
||||
escaping: BitSet<Local>,
|
||||
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() });
|
||||
fragments.get_or_insert_with(local, IndexVec::new).insert(field, (field_ty, new_local));
|
||||
});
|
||||
}
|
||||
ReplacementMap { fragments }
|
||||
}
|
||||
|
||||
/// Perform the replacement computed by `compute_flattening`.
|
||||
|
@ -169,29 +171,24 @@ fn replace_flattened_locals<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
replacements: ReplacementMap<'tcx>,
|
||||
) {
|
||||
) -> BitSet<Local> {
|
||||
let mut all_dead_locals = BitSet::new_empty(body.local_decls.len());
|
||||
for p in replacements.fields.keys() {
|
||||
all_dead_locals.insert(p.local);
|
||||
for (local, replacements) in replacements.fragments.iter_enumerated() {
|
||||
if replacements.is_some() {
|
||||
all_dead_locals.insert(local);
|
||||
}
|
||||
}
|
||||
debug!(?all_dead_locals);
|
||||
if all_dead_locals.is_empty() {
|
||||
return;
|
||||
return all_dead_locals;
|
||||
}
|
||||
|
||||
let mut fragments = IndexVec::new();
|
||||
for (k, v) in &replacements.fields {
|
||||
fragments.ensure_contains_elem(k.local, || Vec::new());
|
||||
fragments[k.local].push((k.projection, *v));
|
||||
}
|
||||
debug!(?fragments);
|
||||
|
||||
let mut visitor = ReplacementVisitor {
|
||||
tcx,
|
||||
local_decls: &body.local_decls,
|
||||
replacements,
|
||||
replacements: &replacements,
|
||||
all_dead_locals,
|
||||
fragments,
|
||||
patch: MirPatch::new(body),
|
||||
};
|
||||
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
|
||||
visitor.visit_basic_block_data(bb, data);
|
||||
|
@ -205,6 +202,9 @@ fn replace_flattened_locals<'tcx>(
|
|||
for var_debug_info in &mut body.var_debug_info {
|
||||
visitor.visit_var_debug_info(var_debug_info);
|
||||
}
|
||||
let ReplacementVisitor { patch, all_dead_locals, .. } = visitor;
|
||||
patch.apply(body);
|
||||
all_dead_locals
|
||||
}
|
||||
|
||||
struct ReplacementVisitor<'tcx, 'll> {
|
||||
|
@ -212,40 +212,23 @@ struct ReplacementVisitor<'tcx, 'll> {
|
|||
/// This is only used to compute the type for `VarDebugInfoContents::Composite`.
|
||||
local_decls: &'ll LocalDecls<'tcx>,
|
||||
/// Work to do.
|
||||
replacements: ReplacementMap<'tcx>,
|
||||
replacements: &'ll ReplacementMap<'tcx>,
|
||||
/// This is used to check that we are not leaving references to replaced locals behind.
|
||||
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: IndexVec<Local, Vec<(&'tcx [PlaceElem<'tcx>], Local)>>,
|
||||
patch: MirPatch<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> {
|
||||
fn gather_debug_info_fragments(
|
||||
&self,
|
||||
place: PlaceRef<'tcx>,
|
||||
) -> Vec<VarDebugInfoFragment<'tcx>> {
|
||||
impl<'tcx> ReplacementVisitor<'tcx, '_> {
|
||||
fn gather_debug_info_fragments(&self, local: Local) -> Option<Vec<VarDebugInfoFragment<'tcx>>> {
|
||||
let mut fragments = Vec::new();
|
||||
let parts = &self.fragments[place.local];
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
fragments
|
||||
}
|
||||
|
||||
fn replace_place(&self, place: PlaceRef<'tcx>) -> Option<Place<'tcx>> {
|
||||
if let &[PlaceElem::Field(..), ref rest @ ..] = place.projection {
|
||||
let pr = PlaceRef { local: place.local, projection: &place.projection[..1] };
|
||||
let local = self.replacements.fields.get(&pr)?;
|
||||
Some(Place { local: *local, projection: self.tcx.intern_place_elems(&rest) })
|
||||
} else {
|
||||
None
|
||||
let parts = self.replacements.place_fragments(local.into())?;
|
||||
for (field, ty, replacement_local) in parts {
|
||||
fragments.push(VarDebugInfoFragment {
|
||||
projection: vec![PlaceElem::Field(field, ty)],
|
||||
contents: Place::from(replacement_local),
|
||||
});
|
||||
}
|
||||
Some(fragments)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,94 +237,186 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
|
||||
if let StatementKind::StorageLive(..)
|
||||
| StatementKind::StorageDead(..)
|
||||
| StatementKind::Deinit(..) = statement.kind
|
||||
{
|
||||
// Storage statements are expanded in run_pass.
|
||||
return;
|
||||
}
|
||||
self.super_statement(statement, location)
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
|
||||
if let Some(repl) = self.replace_place(place.as_ref()) {
|
||||
if let Some(repl) = self.replacements.replace_place(self.tcx, place.as_ref()) {
|
||||
*place = repl
|
||||
} else {
|
||||
self.super_place(place, context, location)
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
|
||||
match statement.kind {
|
||||
// Duplicate storage and deinit statements, as they pretty much apply to all fields.
|
||||
StatementKind::StorageLive(l) => {
|
||||
if let Some(final_locals) = self.replacements.place_fragments(l.into()) {
|
||||
for (_, _, fl) in final_locals {
|
||||
self.patch.add_statement(location, StatementKind::StorageLive(fl));
|
||||
}
|
||||
statement.make_nop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
StatementKind::StorageDead(l) => {
|
||||
if let Some(final_locals) = self.replacements.place_fragments(l.into()) {
|
||||
for (_, _, fl) in final_locals {
|
||||
self.patch.add_statement(location, StatementKind::StorageDead(fl));
|
||||
}
|
||||
statement.make_nop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
StatementKind::Deinit(box 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())));
|
||||
}
|
||||
statement.make_nop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We have `a = Struct { 0: x, 1: y, .. }`.
|
||||
// We replace it by
|
||||
// ```
|
||||
// a_0 = x
|
||||
// a_1 = y
|
||||
// ...
|
||||
// ```
|
||||
StatementKind::Assign(box (place, Rvalue::Aggregate(_, ref mut operands))) => {
|
||||
if let Some(local) = place.as_local()
|
||||
&& let Some(final_locals) = &self.replacements.fragments[local]
|
||||
{
|
||||
// This is ok as we delete the statement later.
|
||||
let operands = std::mem::take(operands);
|
||||
for (&opt_ty_local, mut operand) in final_locals.iter().zip(operands) {
|
||||
if let Some((_, new_local)) = opt_ty_local {
|
||||
// Replace mentions of SROA'd locals that appear in the operand.
|
||||
self.visit_operand(&mut operand, location);
|
||||
|
||||
let rvalue = Rvalue::Use(operand);
|
||||
self.patch.add_statement(
|
||||
location,
|
||||
StatementKind::Assign(Box::new((new_local.into(), rvalue))),
|
||||
);
|
||||
}
|
||||
}
|
||||
statement.make_nop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We have `a = some constant`
|
||||
// We add the projections.
|
||||
// ```
|
||||
// a_0 = a.0
|
||||
// a_1 = a.1
|
||||
// ...
|
||||
// ```
|
||||
// ConstProp will pick up the pieces and replace them by actual constants.
|
||||
StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => {
|
||||
if let Some(final_locals) = self.replacements.place_fragments(place) {
|
||||
for (field, ty, new_local) in final_locals {
|
||||
let rplace = self.tcx.mk_place_field(place, field, ty);
|
||||
let rvalue = Rvalue::Use(Operand::Move(rplace));
|
||||
self.patch.add_statement(
|
||||
location,
|
||||
StatementKind::Assign(Box::new((new_local.into(), rvalue))),
|
||||
);
|
||||
}
|
||||
// We still need `place.local` to exist, so don't make it nop.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We have `a = move? place`
|
||||
// We replace it by
|
||||
// ```
|
||||
// a_0 = move? place.0
|
||||
// a_1 = move? place.1
|
||||
// ...
|
||||
// ```
|
||||
StatementKind::Assign(box (lhs, Rvalue::Use(ref op))) => {
|
||||
let (rplace, copy) = match *op {
|
||||
Operand::Copy(rplace) => (rplace, true),
|
||||
Operand::Move(rplace) => (rplace, false),
|
||||
Operand::Constant(_) => bug!(),
|
||||
};
|
||||
if let Some(final_locals) = self.replacements.place_fragments(lhs) {
|
||||
for (field, ty, new_local) in final_locals {
|
||||
let rplace = self.tcx.mk_place_field(rplace, field, ty);
|
||||
debug!(?rplace);
|
||||
let rplace = self
|
||||
.replacements
|
||||
.replace_place(self.tcx, rplace.as_ref())
|
||||
.unwrap_or(rplace);
|
||||
debug!(?rplace);
|
||||
let rvalue = if copy {
|
||||
Rvalue::Use(Operand::Copy(rplace))
|
||||
} else {
|
||||
Rvalue::Use(Operand::Move(rplace))
|
||||
};
|
||||
self.patch.add_statement(
|
||||
location,
|
||||
StatementKind::Assign(Box::new((new_local.into(), rvalue))),
|
||||
);
|
||||
}
|
||||
statement.make_nop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
self.super_statement(statement, location)
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) {
|
||||
match &mut var_debug_info.value {
|
||||
VarDebugInfoContents::Place(ref mut place) => {
|
||||
if let Some(repl) = self.replace_place(place.as_ref()) {
|
||||
if let Some(repl) = self.replacements.replace_place(self.tcx, place.as_ref()) {
|
||||
*place = repl;
|
||||
} else if self.all_dead_locals.contains(place.local) {
|
||||
} else if let Some(local) = place.as_local()
|
||||
&& let Some(fragments) = self.gather_debug_info_fragments(local)
|
||||
{
|
||||
let ty = place.ty(self.local_decls, self.tcx).ty;
|
||||
let fragments = self.gather_debug_info_fragments(place.as_ref());
|
||||
var_debug_info.value = VarDebugInfoContents::Composite { ty, fragments };
|
||||
}
|
||||
}
|
||||
VarDebugInfoContents::Composite { ty: _, ref mut fragments } => {
|
||||
let mut new_fragments = Vec::new();
|
||||
debug!(?fragments);
|
||||
fragments
|
||||
.drain_filter(|fragment| {
|
||||
if let Some(repl) = self.replace_place(fragment.contents.as_ref()) {
|
||||
if let Some(repl) =
|
||||
self.replacements.replace_place(self.tcx, fragment.contents.as_ref())
|
||||
{
|
||||
fragment.contents = repl;
|
||||
true
|
||||
} else if self.all_dead_locals.contains(fragment.contents.local) {
|
||||
let frg = self.gather_debug_info_fragments(fragment.contents.as_ref());
|
||||
false
|
||||
} else if let Some(local) = fragment.contents.as_local()
|
||||
&& let Some(frg) = self.gather_debug_info_fragments(local)
|
||||
{
|
||||
new_fragments.extend(frg.into_iter().map(|mut f| {
|
||||
f.projection.splice(0..0, fragment.projection.iter().copied());
|
||||
f
|
||||
}));
|
||||
false
|
||||
} else {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.for_each(drop);
|
||||
debug!(?fragments);
|
||||
debug!(?new_fragments);
|
||||
fragments.extend(new_fragments);
|
||||
}
|
||||
VarDebugInfoContents::Const(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_basic_block_data(&mut self, bb: BasicBlock, bbdata: &mut BasicBlockData<'tcx>) {
|
||||
self.super_basic_block_data(bb, bbdata);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Stmt {
|
||||
StorageLive,
|
||||
StorageDead,
|
||||
Deinit,
|
||||
}
|
||||
|
||||
bbdata.expand_statements(|stmt| {
|
||||
let source_info = stmt.source_info;
|
||||
let (stmt, origin_local) = match &stmt.kind {
|
||||
StatementKind::StorageLive(l) => (Stmt::StorageLive, *l),
|
||||
StatementKind::StorageDead(l) => (Stmt::StorageDead, *l),
|
||||
StatementKind::Deinit(p) if let Some(l) = p.as_local() => (Stmt::Deinit, l),
|
||||
_ => return None,
|
||||
};
|
||||
if !self.all_dead_locals.contains(origin_local) {
|
||||
return None;
|
||||
}
|
||||
let final_locals = self.fragments.get(origin_local)?;
|
||||
Some(final_locals.iter().map(move |&(_, l)| {
|
||||
let kind = match stmt {
|
||||
Stmt::StorageLive => StatementKind::StorageLive(l),
|
||||
Stmt::StorageDead => StatementKind::StorageDead(l),
|
||||
Stmt::Deinit => StatementKind::Deinit(Box::new(l.into())),
|
||||
};
|
||||
Statement { source_info, kind }
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
|
||||
assert!(!self.all_dead_locals.contains(*local));
|
||||
}
|
||||
|
|
|
@ -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 _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16
|
||||
let mut _15: 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,18 +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<u16>; // 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<u16>; // 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 _12: Point; // 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 => _12; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10
|
||||
let _13: 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 => _13; // 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
|
||||
}
|
||||
}
|
||||
|
@ -66,24 +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::<u16>::Some(const 99_u16); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24
|
||||
StorageLive(_12); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10
|
||||
_12 = Point { x: const 32_u32, y: const 32_u32 }; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35
|
||||
StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10
|
||||
StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
|
||||
_14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16
|
||||
StorageLive(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22
|
||||
_15 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22
|
||||
_13 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22
|
||||
StorageDead(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
|
||||
StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22
|
||||
StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2
|
||||
StorageDead(_12); // scope 7 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::<u16>::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
|
||||
|
|
|
@ -3,25 +3,27 @@
|
|||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +0:11
|
||||
let mut _1: (i32, i32); // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
|
||||
let mut _3: i32; // in scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
|
||||
let mut _4: 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
|
||||
debug x => (i32, i32){ .0 => _3, .1 => _4, }; // in scope 1 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
|
||||
let _1: 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
|
||||
scope 2 {
|
||||
debug y => _2; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
|
||||
debug y => (i32, i32){ .0 => _3, .1 => _2, }; // in scope 2 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
|
||||
- _1 = (const 42_i32, const 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
|
||||
StorageLive(_4); // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:9: +1:14
|
||||
_3 = const 42_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
|
||||
_4 = const 43_i32; // scope 0 at $DIR/mutable_variable_aggregate.rs:+1:17: +1:25
|
||||
_4 = 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
|
||||
- _2 = _4; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14
|
||||
+ _2 = 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(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2
|
||||
StorageDead(_4); // 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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
|
||||
let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
|
||||
let mut _2: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10
|
||||
let mut _2: (i32, 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
|
||||
scope 2 {
|
||||
debug x => _2; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
|
||||
let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
|
||||
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 => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
|
||||
let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5: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
|
||||
scope 4 {
|
||||
debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
|
||||
}
|
||||
|
@ -30,21 +31,17 @@
|
|||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14
|
||||
- _2 = (const 1_i32, const 2_i32); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
|
||||
+ _2 = const (1_i32, 2_i32); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35
|
||||
StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
|
||||
_3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
|
||||
(_2.1: i32) = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12
|
||||
StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12
|
||||
StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10
|
||||
_4 = (_2.1: i32); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16
|
||||
StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10
|
||||
- _5 = (_2.0: i32); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
|
||||
+ _5 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16
|
||||
StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
|
||||
StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
|
||||
StorageDead(_2); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2
|
||||
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
|
||||
_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 = _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(_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
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
|
||||
let mut _6: usize; // 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: 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
|
||||
|
@ -17,7 +17,7 @@
|
|||
debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
debug z => _9; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,13 +50,7 @@
|
|||
+ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
|
||||
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
_9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
|
||||
+ _8 = const 42_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(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
_9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33
|
||||
let mut _6: usize; // 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: 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
|
||||
|
@ -17,7 +17,7 @@
|
|||
debug y => _3; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
let _8: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug z => _8; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
debug z => _9; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,13 +50,7 @@
|
|||
+ _3 = const 3_i32; // scope 1 at $DIR/optimizes_into_variable.rs:+2:13: +2:34
|
||||
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
_9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
- _8 = (_9.1: u32); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38
|
||||
+ _8 = const 42_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(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
_9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
let mut _3: 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 _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ fn main() -> () {
|
|||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
let mut _3: 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 _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ fn main() -> () {
|
|||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
let mut _6: usize; // 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 _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
|
||||
|
@ -45,10 +47,20 @@
|
|||
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
_9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
_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(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
- _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
- _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 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 = _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
|
||||
StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
let mut _6: usize; // 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 _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
|
||||
|
@ -45,10 +47,20 @@
|
|||
StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35
|
||||
StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
_9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
_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(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
- _9 = Point { x: const 12_u32, y: const 42_u32 }; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36
|
||||
- _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 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 = _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
|
||||
StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
let mut _3: 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 _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ fn main() -> () {
|
|||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11
|
||||
let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
let mut _3: 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 _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
scope 2 {
|
||||
debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
scope 3 {
|
||||
debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ fn main() -> () {
|
|||
bb0: {
|
||||
StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10
|
||||
StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10
|
||||
StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10
|
||||
StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2
|
||||
return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2
|
||||
|
|
|
@ -4,25 +4,22 @@ fn ezmap(_1: Option<i32>) -> Option<i32> {
|
|||
debug x => _1; // in scope 0 at $DIR/simple_option_map_e2e.rs:+0:14: +0:15
|
||||
let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map_e2e.rs:+0:33: +0:44
|
||||
let mut _2: [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]; // in scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21
|
||||
let mut _7: i32; // in scope 0 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]>) { // at $DIR/simple_option_map_e2e.rs:14:5: 14:22
|
||||
debug slf => _1; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:17: 2:20
|
||||
debug f => _2; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:33: 2:34
|
||||
let mut _3: isize; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:9: 7:16
|
||||
let _4: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
|
||||
let mut _5: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
let mut _6: (i32,); // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
scope 2 {
|
||||
debug x => _4; // in scope 2 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
|
||||
scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
debug n => _7; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14
|
||||
debug n => _4; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:12: +1:21
|
||||
StorageLive(_4); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:5: +1:22
|
||||
_3 = discriminant(_1); // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14
|
||||
switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map_e2e.rs:6:5: 6:14
|
||||
}
|
||||
|
@ -39,20 +36,13 @@ fn ezmap(_1: Option<i32>) -> Option<i32> {
|
|||
bb3: {
|
||||
_4 = move ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
|
||||
StorageLive(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
StorageLive(_6); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
_6 = (move _4,); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
StorageLive(_7); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
_7 = move (_6.0: i32); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
_5 = Add(_7, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
|
||||
StorageDead(_7); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
|
||||
StorageDead(_6); // scope 2 at $DIR/simple_option_map_e2e.rs:7:28: 7:29
|
||||
_5 = Add(_4, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
|
||||
_0 = Option::<i32>::Some(move _5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
|
||||
StorageDead(_5); // scope 2 at $DIR/simple_option_map_e2e.rs:7:29: 7:30
|
||||
goto -> bb4; // scope 1 at $DIR/simple_option_map_e2e.rs:10:1: 10:2
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageDead(_4); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:5: +1:22
|
||||
StorageDead(_2); // scope 0 at $DIR/simple_option_map_e2e.rs:+1:21: +1:22
|
||||
return; // scope 0 at $DIR/simple_option_map_e2e.rs:+2:2: +2:2
|
||||
}
|
||||
|
|
91
tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff
Normal file
91
tests/mir-opt/sroa.copies.ScalarReplacementOfAggregates.diff
Normal file
|
@ -0,0 +1,91 @@
|
|||
- // MIR for `copies` before ScalarReplacementOfAggregates
|
||||
+ // MIR for `copies` after ScalarReplacementOfAggregates
|
||||
|
||||
fn copies(_1: Foo) -> () {
|
||||
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 _11: u8; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ let _12: (); // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ let _13: &str; // in scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ let _14: std::option::Option<isize>; // 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 => _11, .1 => _12, .2 => _13, .3 => _14, }; // 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<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: {
|
||||
- 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(_11); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ StorageLive(_12); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ StorageLive(_13); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ StorageLive(_14); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ nop; // scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
+ _11 = (_1.0: u8); // scope 0 at $DIR/sroa.rs:+1:13: +1:14
|
||||
+ _12 = (_1.1: ()); // scope 0 at $DIR/sroa.rs:+1:13: +1:14
|
||||
+ _13 = (_1.2: &str); // scope 0 at $DIR/sroa.rs:+1:13: +1:14
|
||||
+ _14 = (_1.3: std::option::Option<isize>); // 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
|
||||
- _3 = (_2.0: u8); // scope 1 at $DIR/sroa.rs:+2:13: +2:16
|
||||
+ _3 = _11; // 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
|
||||
- StorageLive(_5); // scope 3 at $DIR/sroa.rs:+4:9: +4:10
|
||||
- _5 = _2; // scope 3 at $DIR/sroa.rs:+4:13: +4:14
|
||||
+ _4 = _13; // scope 2 at $DIR/sroa.rs:+3:13: +3:16
|
||||
+ 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 = _11; // scope 3 at $DIR/sroa.rs:+4:13: +4:14
|
||||
+ _8 = _12; // scope 3 at $DIR/sroa.rs:+4:13: +4:14
|
||||
+ _9 = _13; // scope 3 at $DIR/sroa.rs:+4:13: +4:14
|
||||
+ _10 = _14; // 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
|
||||
+ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
+ StorageDead(_12); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
+ StorageDead(_13); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
+ StorageDead(_14); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
+ nop; // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
return; // scope 0 at $DIR/sroa.rs:+6:2: +6:2
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
StorageLive(_5); // scope 0 at $DIR/sroa.rs:+2:34: +2:37
|
||||
_5 = g() -> bb1; // scope 0 at $DIR/sroa.rs:+2:34: +2:37
|
||||
// mir::Constant
|
||||
// + span: $DIR/sroa.rs:78:34: 78:35
|
||||
// + span: $DIR/sroa.rs:73:34: 73:35
|
||||
// + literal: Const { ty: fn() -> u32 {g}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
|||
_2 = &raw const (*_3); // scope 0 at $DIR/sroa.rs:+2:7: +2:41
|
||||
_1 = f(move _2) -> bb2; // scope 0 at $DIR/sroa.rs:+2:5: +2:42
|
||||
// mir::Constant
|
||||
// + span: $DIR/sroa.rs:78:5: 78:6
|
||||
// + span: $DIR/sroa.rs:73:5: 73:6
|
||||
// + literal: Const { ty: fn(*const u32) {f}, val: Value(<ZST>) }
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
let mut _5: Foo; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
let mut _6: (); // in scope 0 at $DIR/sroa.rs:+1:45: +1:47
|
||||
let mut _7: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:60: +1:68
|
||||
+ let mut _8: u8; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ let mut _9: (); // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ let mut _10: &str; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ let mut _11: std::option::Option<isize>; // in scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
scope 1 {
|
||||
debug a => _1; // in scope 1 at $DIR/sroa.rs:+1:15: +1:16
|
||||
debug b => _2; // in scope 1 at $DIR/sroa.rs:+1:18: +1:19
|
||||
|
@ -26,26 +30,45 @@
|
|||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
- StorageLive(_5); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ StorageLive(_8); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ StorageLive(_9); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ StorageLive(_10); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ StorageLive(_11); // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ nop; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
StorageLive(_6); // scope 0 at $DIR/sroa.rs:+1:45: +1:47
|
||||
_6 = (); // scope 0 at $DIR/sroa.rs:+1:45: +1:47
|
||||
StorageLive(_7); // scope 0 at $DIR/sroa.rs:+1:60: +1:68
|
||||
_7 = Option::<isize>::Some(const -4_isize); // scope 0 at $DIR/sroa.rs:+1:60: +1:68
|
||||
_5 = Foo { a: const 5_u8, b: move _6, c: const "a", d: move _7 }; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
- _5 = Foo { a: const 5_u8, b: move _6, c: const "a", d: move _7 }; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ _8 = const 5_u8; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ _9 = move _6; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ _10 = const "a"; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
// mir::Constant
|
||||
// + span: $DIR/sroa.rs:57:52: 57:55
|
||||
// + span: $DIR/sroa.rs:53:52: 53:55
|
||||
// + literal: Const { ty: &str, val: Value(Slice(..)) }
|
||||
+ _11 = move _7; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
+ nop; // scope 0 at $DIR/sroa.rs:+1:30: +1:70
|
||||
StorageDead(_7); // scope 0 at $DIR/sroa.rs:+1:69: +1:70
|
||||
StorageDead(_6); // scope 0 at $DIR/sroa.rs:+1:69: +1:70
|
||||
StorageLive(_1); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
|
||||
_1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
|
||||
- _1 = (_5.0: u8); // scope 0 at $DIR/sroa.rs:+1:15: +1:16
|
||||
+ _1 = _8; // scope 0 at $DIR/sroa.rs:+1:15: +1:16
|
||||
StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
|
||||
_2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
|
||||
- _2 = (_5.1: ()); // scope 0 at $DIR/sroa.rs:+1:18: +1:19
|
||||
+ _2 = _9; // scope 0 at $DIR/sroa.rs:+1:18: +1:19
|
||||
StorageLive(_3); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
|
||||
_3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
|
||||
- _3 = (_5.2: &str); // scope 0 at $DIR/sroa.rs:+1:21: +1:22
|
||||
+ _3 = _10; // scope 0 at $DIR/sroa.rs:+1:21: +1:22
|
||||
StorageLive(_4); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
|
||||
_4 = (_5.3: std::option::Option<isize>); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
|
||||
StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
- _4 = (_5.3: std::option::Option<isize>); // scope 0 at $DIR/sroa.rs:+1:24: +1:25
|
||||
- StorageDead(_5); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
+ _4 = _11; // scope 0 at $DIR/sroa.rs:+1:24: +1:25
|
||||
+ StorageDead(_8); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
+ StorageDead(_9); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
+ StorageDead(_10); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
+ StorageDead(_11); // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
+ nop; // scope 0 at $DIR/sroa.rs:+1:70: +1:71
|
||||
_0 = const (); // scope 0 at $DIR/sroa.rs:+0:15: +6:2
|
||||
StorageDead(_4); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
StorageDead(_3); // scope 0 at $DIR/sroa.rs:+6:1: +6:2
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
- // MIR for `ref_copies` before ScalarReplacementOfAggregates
|
||||
+ // MIR for `ref_copies` after ScalarReplacementOfAggregates
|
||||
|
||||
fn ref_copies(_1: &Foo) -> () {
|
||||
debug x => _1; // in scope 0 at $DIR/sroa.rs:+0:15: +0:16
|
||||
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: (); // 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 {
|
||||
- debug y => _2; // 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
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2); // scope 0 at $DIR/sroa.rs:+1:9: +1:10
|
||||
- _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).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
|
||||
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 = _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
|
||||
}
|
||||
}
|
||||
|
|
@ -12,17 +12,14 @@ impl Drop for Tag {
|
|||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff
|
||||
pub fn dropping() {
|
||||
S(Tag(0), Tag(1), Tag(2)).1;
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff
|
||||
pub fn enums(a: usize) -> usize {
|
||||
if let Some(a) = Some(a) { a } else { 0 }
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff
|
||||
pub fn structs(a: f32) -> f32 {
|
||||
struct U {
|
||||
_foo: usize,
|
||||
|
@ -32,7 +29,6 @@ pub fn structs(a: f32) -> f32 {
|
|||
U { _foo: 0, a }.a
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff
|
||||
pub fn unions(a: f32) -> u32 {
|
||||
union Repr {
|
||||
f: f32,
|
||||
|
@ -41,6 +37,7 @@ pub fn unions(a: f32) -> u32 {
|
|||
unsafe { Repr { f: a }.u }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Foo {
|
||||
a: u8,
|
||||
b: (),
|
||||
|
@ -52,7 +49,6 @@ fn g() -> u32 {
|
|||
3
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff
|
||||
pub fn flat() {
|
||||
let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) };
|
||||
let _ = a;
|
||||
|
@ -72,12 +68,25 @@ fn f(a: *const u32) {
|
|||
println!("{}", unsafe { *a.add(2) });
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff
|
||||
pub fn escaping() {
|
||||
// Verify this struct is not flattened.
|
||||
f(&Escaping { a: 1, b: 2, c: g() }.a);
|
||||
}
|
||||
|
||||
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) {
|
||||
let y = *x;
|
||||
let t = y.a;
|
||||
let u = y.c;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dropping();
|
||||
enums(5);
|
||||
|
@ -85,4 +94,15 @@ fn main() {
|
|||
unions(5.);
|
||||
flat();
|
||||
escaping();
|
||||
copies(Foo { a: 5, b: (), c: "a", d: Some(-4) });
|
||||
ref_copies(&Foo { a: 5, b: (), c: "a", d: Some(-4) });
|
||||
}
|
||||
|
||||
// EMIT_MIR sroa.dropping.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.enums.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.structs.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.unions.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.flat.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.escaping.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.copies.ScalarReplacementOfAggregates.diff
|
||||
// EMIT_MIR sroa.ref_copies.ScalarReplacementOfAggregates.diff
|
||||
|
|
|
@ -6,15 +6,27 @@
|
|||
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: 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(_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
|
||||
- _2 = U { _foo: const 0_usize, a: 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 = (_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 = _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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue