Auto merge of #106285 - cjgillot:refprop-ssa, r=JakobDegen

Implement SSA-based reference propagation

Rust has a tendency to create a lot of short-lived borrows, in particular for method calls. This PR aims to remove those short-lived borrows with a const-propagation dedicated to pointers to local places.

This pass aims to transform the following pattern:
```
  _1 = &raw? mut? PLACE;
  _3 = *_1;
  _4 = &raw? mut? *_1;
```

Into
```
  _1 = &raw? mut? PLACE;
  _3 = PLACE;
  _4 = &raw? mut? PLACE;
```

where `PLACE` is a direct or an indirect place expression.

By removing indirection, this pass should help both dest-prop and const-prop to handle more cases.
This optimization is distinct from const-prop and dataflow const-prop since the borrow-reborrow patterns needs to preserve borrowck invariants, especially the uniqueness property of mutable references.

The pointed-to places are computed using a SSA analysis. We suppose that removable borrows are typically temporaries from autoref, so they are by construction assigned only once, and a SSA analysis is enough to catch them. For each local, we store both where and how it is used, in order to efficiently compute the all-or-nothing property. Thanks to `Derefer`, we only have to track locals, not places in general.

---

There are 3 properties that need to be upheld for this transformation to be legal:
- place constness: `PLACE` must refer to the same memory wherever it appears;
- pointer liveness: we must not introduce dereferences of dangling pointers;
- `&mut` borrow uniqueness.

## Constness

If `PLACE` is an indirect projection, if its of the form `(*LOCAL).PROJECTIONS` where:
- `LOCAL` is SSA;
- all projections in `PROJECTIONS` are constant (no dereference and no indexing).

If `PLACE` is a direct projection of a local, we consider it as constant if:
- the local is always live, or it has a single `StorageLive` that dominates all uses;
- all projections are constant.

# Liveness

When performing a substitution, we must take care not to introduce uses of dangling locals.

Using a dangling borrow is UB. Therefore, we assume that for any use of `*x`, where `x` is a borrow, the pointed-to memory is live.

Limitations:
- occurrences of `*x` in an `&raw mut? *x` are accepted;
- raw pointers are allowed to be dangling.

In those 2 case, we do not substitute anything, to be on the safe side.

**Open question:** we do not differentiate borrows of ZST and non-ZST. The UB rules may be
different depending on the layout. Having a different treatment would effectively prevent this
pass from running on polymorphic MIR, which defeats the purpose of MIR opts.

## Uniqueness

For `&mut` borrows, we also need to preserve the uniqueness property:
we must avoid creating a state where we interleave uses of `*_1` and `_2`.
To do it, we only perform full substitution of mutable borrows:
we replace either all or none of the occurrences of `*_1`.

Some care has to be taken when `_1` is copied in other locals.
```
   _1 = &raw? mut? _2;
   _3 = *_1;
   _4 = _1
   _5 = *_4
```
In such cases, fully substituting `_1` means fully substituting all of the copies.

For immutable borrows, we do not need to preserve such uniqueness property,
so we perform all the possible substitutions without removing the `_1 = &_2` statement.
This commit is contained in:
bors 2023-05-09 21:54:34 +00:00
commit 50dff955a9
23 changed files with 3143 additions and 117 deletions

View file

@ -1524,6 +1524,19 @@ impl<V, T> ProjectionElem<V, T> {
}
}
/// Returns `true` if the target of this projection always refers to the same memory region
/// whatever the state of the program.
pub fn is_stable_offset(&self) -> bool {
match self {
Self::Deref | Self::Index(_) => false,
Self::Field(_, _)
| Self::OpaqueCast(_)
| Self::ConstantIndex { .. }
| Self::Subslice { .. }
| Self::Downcast(_, _) => true,
}
}
/// Returns `true` if this is a `Downcast` projection with the given `VariantIdx`.
pub fn is_downcast_to(&self, v: VariantIdx) -> bool {
matches!(*self, Self::Downcast(_, x) if x == v)

View file

@ -26,7 +26,7 @@ pub use self::borrowed_locals::borrowed_locals;
pub use self::borrowed_locals::MaybeBorrowedLocals;
pub use self::liveness::MaybeLiveLocals;
pub use self::liveness::MaybeTransitiveLiveLocals;
pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageLive};
pub use self::storage_liveness::{MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive};
/// `MaybeInitializedPlaces` tracks all places that might be
/// initialized upon reaching a particular point in the control flow

View file

@ -74,6 +74,73 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> {
}
}
#[derive(Clone)]
pub struct MaybeStorageDead {
always_live_locals: BitSet<Local>,
}
impl MaybeStorageDead {
pub fn new(always_live_locals: BitSet<Local>) -> Self {
MaybeStorageDead { always_live_locals }
}
}
impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageDead {
type Domain = BitSet<Local>;
const NAME: &'static str = "maybe_storage_dead";
fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
// bottom = live
BitSet::new_empty(body.local_decls.len())
}
fn initialize_start_block(&self, body: &mir::Body<'tcx>, on_entry: &mut Self::Domain) {
assert_eq!(body.local_decls.len(), self.always_live_locals.domain_size());
// Do not iterate on return place and args, as they are trivially always live.
for local in body.vars_and_temps_iter() {
if !self.always_live_locals.contains(local) {
on_entry.insert(local);
}
}
}
}
impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead {
type Idx = Local;
fn statement_effect(
&self,
trans: &mut impl GenKill<Self::Idx>,
stmt: &mir::Statement<'tcx>,
_: Location,
) {
match stmt.kind {
StatementKind::StorageLive(l) => trans.kill(l),
StatementKind::StorageDead(l) => trans.gen(l),
_ => (),
}
}
fn terminator_effect(
&self,
_trans: &mut impl GenKill<Self::Idx>,
_: &mir::Terminator<'tcx>,
_: Location,
) {
// Terminators have no effect
}
fn call_return_effect(
&self,
_trans: &mut impl GenKill<Self::Idx>,
_block: BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {
// Nothing to do when a call returns successfully
}
}
type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorrowedLocals>;
/// Dataflow analysis that determines whether each local requires storage at a

View file

@ -33,9 +33,8 @@ impl<'tcx> MirPass<'tcx> for CopyProp {
}
fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
let borrowed_locals = borrowed_locals(body);
let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals);
let ssa = SsaLocals::new(body);
let fully_moved = fully_moved_locals(&ssa, body);
debug!(?fully_moved);
@ -76,7 +75,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> {
let mut fully_moved = BitSet::new_filled(body.local_decls.len());
for (_, rvalue) in ssa.assignments(body) {
for (_, rvalue, _) in ssa.assignments(body) {
let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place))
= rvalue
else { continue };

View file

@ -84,6 +84,7 @@ mod match_branches;
mod multiple_return_terminators;
mod normalize_array_len;
mod nrvo;
mod ref_prop;
mod remove_noop_landing_pads;
mod remove_storage_markers;
mod remove_uninit_drops;
@ -559,6 +560,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&separate_const_switch::SeparateConstSwitch,
&simplify::SimplifyLocals::BeforeConstProp,
&copy_prop::CopyProp,
&ref_prop::ReferencePropagation,
&const_prop::ConstProp,
&dataflow_const_prop::DataflowConstProp,
//

View file

@ -7,7 +7,6 @@ use rustc_index::IndexVec;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
use rustc_mir_dataflow::impls::borrowed_locals;
pub struct NormalizeArrayLen;
@ -24,9 +23,7 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
}
fn normalize_array_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
let borrowed_locals = borrowed_locals(body);
let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals);
let ssa = SsaLocals::new(body);
let slice_lengths = compute_slice_length(tcx, &ssa, body);
debug!(?slice_lengths);
@ -41,7 +38,7 @@ fn compute_slice_length<'tcx>(
) -> IndexVec<Local, Option<ty::Const<'tcx>>> {
let mut slice_lengths = IndexVec::from_elem(None, &body.local_decls);
for (local, rvalue) in ssa.assignments(body) {
for (local, rvalue, _) in ssa.assignments(body) {
match rvalue {
Rvalue::Cast(
CastKind::Pointer(ty::adjustment::PointerCast::Unsize),

View file

@ -0,0 +1,355 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::impls::MaybeStorageDead;
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::Analysis;
use crate::ssa::{SsaLocals, StorageLiveLocals};
use crate::MirPass;
/// Propagate references using SSA analysis.
///
/// MIR building may produce a lot of borrow-dereference patterns.
///
/// This pass aims to transform the following pattern:
/// _1 = &raw? mut? PLACE;
/// _3 = *_1;
/// _4 = &raw? mut? *_1;
///
/// Into
/// _1 = &raw? mut? PLACE;
/// _3 = PLACE;
/// _4 = &raw? mut? PLACE;
///
/// where `PLACE` is a direct or an indirect place expression.
///
/// There are 3 properties that need to be upheld for this transformation to be legal:
/// - place stability: `PLACE` must refer to the same memory wherever it appears;
/// - pointer liveness: we must not introduce dereferences of dangling pointers;
/// - `&mut` borrow uniqueness.
///
/// # Stability
///
/// If `PLACE` is an indirect projection, if its of the form `(*LOCAL).PROJECTIONS` where:
/// - `LOCAL` is SSA;
/// - all projections in `PROJECTIONS` have a stable offset (no dereference and no indexing).
///
/// If `PLACE` is a direct projection of a local, we consider it as constant if:
/// - the local is always live, or it has a single `StorageLive`;
/// - all projections have a stable offset.
///
/// # Liveness
///
/// When performing a substitution, we must take care not to introduce uses of dangling locals.
/// To ensure this, we walk the body with the `MaybeStorageDead` dataflow analysis:
/// - if we want to replace `*x` by reborrow `*y` and `y` may be dead, we allow replacement and
/// mark storage statements on `y` for removal;
/// - if we want to replace `*x` by non-reborrow `y` and `y` must be live, we allow replacement;
/// - if we want to replace `*x` by non-reborrow `y` and `y` may be dead, we do not replace.
///
/// # Uniqueness
///
/// For `&mut` borrows, we also need to preserve the uniqueness property:
/// we must avoid creating a state where we interleave uses of `*_1` and `_2`.
/// To do it, we only perform full substitution of mutable borrows:
/// we replace either all or none of the occurrences of `*_1`.
///
/// Some care has to be taken when `_1` is copied in other locals.
/// _1 = &raw? mut? _2;
/// _3 = *_1;
/// _4 = _1
/// _5 = *_4
/// In such cases, fully substituting `_1` means fully substituting all of the copies.
///
/// For immutable borrows, we do not need to preserve such uniqueness property,
/// so we perform all the possible substitutions without removing the `_1 = &_2` statement.
pub struct ReferencePropagation;
impl<'tcx> MirPass<'tcx> for ReferencePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 4
}
#[instrument(level = "trace", skip(self, tcx, body))]
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!(def_id = ?body.source.def_id());
propagate_ssa(tcx, body);
}
}
fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let ssa = SsaLocals::new(body);
let mut replacer = compute_replacement(tcx, body, &ssa);
debug!(?replacer.targets, ?replacer.allowed_replacements, ?replacer.storage_to_remove);
replacer.visit_body_preserves_cfg(body);
if replacer.any_replacement {
crate::simplify::remove_unused_definitions(body);
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Value<'tcx> {
/// Not a pointer, or we can't know.
Unknown,
/// We know the value to be a pointer to this place.
/// The boolean indicates whether the reference is mutable, subject the uniqueness rule.
Pointer(Place<'tcx>, bool),
}
/// For each local, save the place corresponding to `*local`.
#[instrument(level = "trace", skip(tcx, body))]
fn compute_replacement<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
ssa: &SsaLocals,
) -> Replacer<'tcx> {
let always_live_locals = always_storage_live_locals(body);
// Compute which locals have a single `StorageLive` statement ever.
let storage_live = StorageLiveLocals::new(body, &always_live_locals);
// Compute `MaybeStorageDead` dataflow to check that we only replace when the pointee is
// definitely live.
let mut maybe_dead = MaybeStorageDead::new(always_live_locals)
.into_engine(tcx, body)
.iterate_to_fixpoint()
.into_results_cursor(body);
// Map for each local to the pointee.
let mut targets = IndexVec::from_elem(Value::Unknown, &body.local_decls);
// Set of locals for which we will remove their storage statement. This is useful for
// reborrowed references.
let mut storage_to_remove = BitSet::new_empty(body.local_decls.len());
let fully_replacable_locals = fully_replacable_locals(ssa);
// Returns true iff we can use `place` as a pointee.
//
// Note that we only need to verify that there is a single `StorageLive` statement, and we do
// not need to verify that it dominates all uses of that local.
//
// Consider the three statements:
// SL : StorageLive(a)
// DEF: b = &raw? mut? a
// USE: stuff that uses *b
//
// First, we recall that DEF is checked to dominate USE. Now imagine for the sake of
// contradiction there is a DEF -> SL -> USE path. Consider two cases:
//
// - DEF dominates SL. We always have UB the first time control flow reaches DEF,
// because the storage of `a` is dead. Since DEF dominates USE, that means we cannot
// reach USE and so our optimization is ok.
//
// - DEF does not dominate SL. Then there is a `START_BLOCK -> SL` path not including DEF.
// But we can extend this path to USE, meaning there is also a `START_BLOCK -> USE` path not
// including DEF. This violates the DEF dominates USE condition, and so is impossible.
let is_constant_place = |place: Place<'_>| {
// We only allow `Deref` as the first projection, to avoid surprises.
if place.projection.first() == Some(&PlaceElem::Deref) {
// `place == (*some_local).xxx`, it is constant only if `some_local` is constant.
// We approximate constness using SSAness.
ssa.is_ssa(place.local) && place.projection[1..].iter().all(PlaceElem::is_stable_offset)
} else {
storage_live.has_single_storage(place.local)
&& place.projection[..].iter().all(PlaceElem::is_stable_offset)
}
};
let mut can_perform_opt = |target: Place<'tcx>, loc: Location| {
if target.projection.first() == Some(&PlaceElem::Deref) {
// We are creating a reborrow. As `place.local` is a reference, removing the storage
// statements should not make it much harder for LLVM to optimize.
storage_to_remove.insert(target.local);
true
} else {
// This is a proper dereference. We can only allow it if `target` is live.
maybe_dead.seek_after_primary_effect(loc);
let maybe_dead = maybe_dead.contains(target.local);
!maybe_dead
}
};
for (local, rvalue, location) in ssa.assignments(body) {
debug!(?local);
// Only visit if we have something to do.
let Value::Unknown = targets[local] else { bug!() };
let ty = body.local_decls[local].ty;
// If this is not a reference or pointer, do nothing.
if !ty.is_any_ptr() {
debug!("not a reference or pointer");
continue;
}
// If this a mutable reference that we cannot fully replace, mark it as unknown.
if ty.is_mutable_ptr() && !fully_replacable_locals.contains(local) {
debug!("not fully replaceable");
continue;
}
debug!(?rvalue);
match rvalue {
// This is a copy, just use the value we have in store for the previous one.
// As we are visiting in `assignment_order`, ie. reverse postorder, `rhs` should
// have been visited before.
Rvalue::Use(Operand::Copy(place) | Operand::Move(place))
| Rvalue::CopyForDeref(place) => {
if let Some(rhs) = place.as_local() {
let target = targets[rhs];
if matches!(target, Value::Pointer(..)) {
targets[local] = target;
} else if ssa.is_ssa(rhs) {
let refmut = body.local_decls[rhs].ty.is_mutable_ptr();
targets[local] = Value::Pointer(tcx.mk_place_deref(rhs.into()), refmut);
}
}
}
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
let mut place = *place;
// Try to see through `place` in order to collapse reborrow chains.
if place.projection.first() == Some(&PlaceElem::Deref)
&& let Value::Pointer(target, refmut) = targets[place.local]
// Only see through immutable reference and pointers, as we do not know yet if
// mutable references are fully replaced.
&& !refmut
// Only collapse chain if the pointee is definitely live.
&& can_perform_opt(target, location)
{
place = target.project_deeper(&place.projection[1..], tcx);
}
assert_ne!(place.local, local);
if is_constant_place(place) {
targets[local] = Value::Pointer(place, ty.is_mutable_ptr());
}
}
// We do not know what to do, so keep as not-a-pointer.
_ => {}
}
}
debug!(?targets);
let mut finder = ReplacementFinder {
targets: &mut targets,
can_perform_opt,
allowed_replacements: FxHashSet::default(),
};
let reachable_blocks = traversal::reachable_as_bitset(body);
for (bb, bbdata) in body.basic_blocks.iter_enumerated() {
// Only visit reachable blocks as we rely on dataflow.
if reachable_blocks.contains(bb) {
finder.visit_basic_block_data(bb, bbdata);
}
}
let allowed_replacements = finder.allowed_replacements;
return Replacer {
tcx,
targets,
storage_to_remove,
allowed_replacements,
any_replacement: false,
};
struct ReplacementFinder<'a, 'tcx, F> {
targets: &'a mut IndexVec<Local, Value<'tcx>>,
can_perform_opt: F,
allowed_replacements: FxHashSet<(Local, Location)>,
}
impl<'tcx, F> Visitor<'tcx> for ReplacementFinder<'_, 'tcx, F>
where
F: FnMut(Place<'tcx>, Location) -> bool,
{
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) {
if matches!(ctxt, PlaceContext::NonUse(_)) {
// There is no need to check liveness for non-uses.
return;
}
if let Value::Pointer(target, refmut) = self.targets[place.local]
&& place.projection.first() == Some(&PlaceElem::Deref)
{
let perform_opt = (self.can_perform_opt)(target, loc);
if perform_opt {
self.allowed_replacements.insert((target.local, loc));
} else if refmut {
// This mutable reference is not fully replacable, so drop it.
self.targets[place.local] = Value::Unknown;
}
}
}
}
}
/// Compute the set of locals that can be fully replaced.
///
/// We consider a local to be replacable iff it's only used in a `Deref` projection `*_local` or
/// non-use position (like storage statements and debuginfo).
fn fully_replacable_locals(ssa: &SsaLocals) -> BitSet<Local> {
let mut replacable = BitSet::new_empty(ssa.num_locals());
// First pass: for each local, whether its uses can be fully replaced.
for local in ssa.locals() {
if ssa.num_direct_uses(local) == 0 {
replacable.insert(local);
}
}
// Second pass: a local can only be fully replaced if all its copies can.
ssa.meet_copy_equivalence(&mut replacable);
replacable
}
/// Utility to help performing subtitution of `*pattern` by `target`.
struct Replacer<'tcx> {
tcx: TyCtxt<'tcx>,
targets: IndexVec<Local, Value<'tcx>>,
storage_to_remove: BitSet<Local>,
allowed_replacements: FxHashSet<(Local, Location)>,
any_replacement: bool,
}
impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) {
if let Value::Pointer(target, _) = self.targets[place.local]
&& place.projection.first() == Some(&PlaceElem::Deref)
{
let perform_opt = matches!(ctxt, PlaceContext::NonUse(_))
|| self.allowed_replacements.contains(&(target.local, loc));
if perform_opt {
*place = target.project_deeper(&place.projection[1..], self.tcx);
self.any_replacement = true;
}
} else {
self.super_place(place, ctxt, loc);
}
}
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
match stmt.kind {
StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
if self.storage_to_remove.contains(l) =>
{
stmt.make_nop();
}
// Do not remove assignments as they may still be useful for debuginfo.
_ => self.super_statement(stmt, loc),
}
}
}

View file

@ -1,3 +1,10 @@
//! We denote as "SSA" the set of locals that verify the following properties:
//! 1/ They are only assigned-to once, either as a function parameter, or in an assign statement;
//! 2/ This single assignment dominates all uses;
//!
//! As a consequence of rule 2, we consider that borrowed locals are not SSA, even if they are
//! `Freeze`, as we do not track that the assignment dominates all uses of the borrow.
use either::Either;
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet;
@ -5,7 +12,6 @@ use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::middle::resolve_bound_vars::Set1;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::{ParamEnv, TyCtxt};
#[derive(Debug)]
pub struct SsaLocals {
@ -17,6 +23,9 @@ pub struct SsaLocals {
assignment_order: Vec<Local>,
/// Copy equivalence classes between locals. See `copy_classes` for documentation.
copy_classes: IndexVec<Local, Local>,
/// Number of "direct" uses of each local, ie. uses that are not dereferences.
/// We ignore non-uses (Storage statements, debuginfo).
direct_uses: IndexVec<Local, u32>,
}
/// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
@ -26,48 +35,48 @@ struct SmallDominators {
inner: Option<Dominators<BasicBlock>>,
}
trait DomExt {
fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool;
}
impl DomExt for Location {
fn dominates(self, other: Location, dominators: &SmallDominators) -> bool {
if self.block == other.block {
self.statement_index <= other.statement_index
impl SmallDominators {
fn dominates(&self, first: Location, second: Location) -> bool {
if first.block == second.block {
first.statement_index <= second.statement_index
} else if let Some(inner) = &self.inner {
inner.dominates(first.block, second.block)
} else {
dominators.dominates(self.block, other.block)
first.block < second.block
}
}
fn check_dominates(&mut self, set: &mut Set1<LocationExtended>, loc: Location) {
let assign_dominates = match *set {
Set1::Empty | Set1::Many => false,
Set1::One(LocationExtended::Arg) => true,
Set1::One(LocationExtended::Plain(assign)) => {
self.dominates(assign.successor_within_block(), loc)
}
};
// We are visiting a use that is not dominated by an assignment.
// Either there is a cycle involved, or we are reading for uninitialized local.
// Bail out.
if !assign_dominates {
*set = Set1::Many;
}
}
}
impl SmallDominators {
fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool {
if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node }
}
}
impl SsaLocals {
pub fn new<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
body: &Body<'tcx>,
borrowed_locals: &BitSet<Local>,
) -> SsaLocals {
pub fn new<'tcx>(body: &Body<'tcx>) -> SsaLocals {
let assignment_order = Vec::with_capacity(body.local_decls.len());
let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
let dominators =
if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None };
let dominators = SmallDominators { inner: dominators };
let mut visitor = SsaVisitor { assignments, assignment_order, dominators };
for (local, decl) in body.local_decls.iter_enumerated() {
if matches!(body.local_kind(local), LocalKind::Arg) {
visitor.assignments[local] = Set1::One(LocationExtended::Arg);
}
if borrowed_locals.contains(local) && !decl.ty.is_freeze(tcx, param_env) {
visitor.assignments[local] = Set1::Many;
}
let direct_uses = IndexVec::from_elem(0, &body.local_decls);
let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses };
for local in body.args_iter() {
visitor.assignments[local] = Set1::One(LocationExtended::Arg);
}
if body.basic_blocks.len() > 2 {
@ -85,36 +94,51 @@ impl SsaLocals {
}
debug!(?visitor.assignments);
debug!(?visitor.direct_uses);
visitor
.assignment_order
.retain(|&local| matches!(visitor.assignments[local], Set1::One(_)));
debug!(?visitor.assignment_order);
let copy_classes = compute_copy_classes(&visitor, body);
let copy_classes = compute_copy_classes(&mut visitor, body);
SsaLocals {
assignments: visitor.assignments,
assignment_order: visitor.assignment_order,
direct_uses: visitor.direct_uses,
copy_classes,
}
}
pub fn num_locals(&self) -> usize {
self.assignments.len()
}
pub fn locals(&self) -> impl Iterator<Item = Local> {
self.assignments.indices()
}
pub fn is_ssa(&self, local: Local) -> bool {
matches!(self.assignments[local], Set1::One(_))
}
/// Return the number of uses if a local that are not "Deref".
pub fn num_direct_uses(&self, local: Local) -> u32 {
self.direct_uses[local]
}
pub fn assignments<'a, 'tcx>(
&'a self,
body: &'a Body<'tcx>,
) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>)> + 'a {
) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a {
self.assignment_order.iter().filter_map(|&local| {
if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] {
// `loc` must point to a direct assignment to `local`.
let Either::Left(stmt) = body.stmt_at(loc) else { bug!() };
let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() };
assert_eq!(target.as_local(), Some(local));
Some((local, rvalue))
Some((local, rvalue, loc))
} else {
None
}
@ -177,30 +201,14 @@ struct SsaVisitor {
dominators: SmallDominators,
assignments: IndexVec<Local, Set1<LocationExtended>>,
assignment_order: Vec<Local>,
}
impl SsaVisitor {
fn check_assignment_dominates(&mut self, local: Local, loc: Location) {
let set = &mut self.assignments[local];
let assign_dominates = match *set {
Set1::Empty | Set1::Many => false,
Set1::One(LocationExtended::Arg) => true,
Set1::One(LocationExtended::Plain(assign)) => {
assign.successor_within_block().dominates(loc, &self.dominators)
}
};
// We are visiting a use that is not dominated by an assignment.
// Either there is a cycle involved, or we are reading for uninitialized local.
// Bail out.
if !assign_dominates {
*set = Set1::Many;
}
}
direct_uses: IndexVec<Local, u32>,
}
impl<'tcx> Visitor<'tcx> for SsaVisitor {
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
match ctxt {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
| PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(),
PlaceContext::MutatingUse(MutatingUseContext::Store) => {
self.assignments[local].insert(LocationExtended::Plain(loc));
if let Set1::One(_) = self.assignments[local] {
@ -209,12 +217,20 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor {
}
}
// Anything can happen with raw pointers, so remove them.
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
| PlaceContext::MutatingUse(_) => self.assignments[local] = Set1::Many,
// Immutable borrows are taken into account in `SsaLocals::new` by
// removing non-freeze locals.
// We do not verify that all uses of the borrow dominate the assignment to `local`,
// so we have to remove them too.
PlaceContext::NonMutatingUse(
NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::ShallowBorrow
| NonMutatingUseContext::UniqueBorrow
| NonMutatingUseContext::AddressOf,
)
| PlaceContext::MutatingUse(_) => {
self.assignments[local] = Set1::Many;
}
PlaceContext::NonMutatingUse(_) => {
self.check_assignment_dominates(local, loc);
self.dominators.check_dominates(&mut self.assignments[local], loc);
self.direct_uses[local] += 1;
}
PlaceContext::NonUse(_) => {}
}
@ -224,20 +240,22 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor {
if place.projection.first() == Some(&PlaceElem::Deref) {
// Do not do anything for storage statements and debuginfo.
if ctxt.is_use() {
// A use through a `deref` only reads from the local, and cannot write to it.
let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection);
// Only change the context if it is a real use, not a "use" in debuginfo.
let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy);
self.visit_projection(place.as_ref(), new_ctxt, loc);
self.check_assignment_dominates(place.local, loc);
self.dominators.check_dominates(&mut self.assignments[place.local], loc);
}
return;
} else {
self.visit_projection(place.as_ref(), ctxt, loc);
self.visit_local(place.local, ctxt, loc);
}
self.super_place(place, ctxt, loc);
}
}
#[instrument(level = "trace", skip(ssa, body))]
fn compute_copy_classes(ssa: &SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Local> {
fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Local> {
let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len());
for &local in &ssa.assignment_order {
@ -267,9 +285,11 @@ fn compute_copy_classes(ssa: &SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Lo
// We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been
// visited before `local`, and we just have to copy the representing local.
copies[local] = copies[rhs];
ssa.direct_uses[rhs] -= 1;
}
debug!(?copies);
debug!(?ssa.direct_uses);
// Invariant: `copies` must point to the head of an equivalence class.
#[cfg(debug_assertions)]
@ -279,3 +299,36 @@ fn compute_copy_classes(ssa: &SsaVisitor, body: &Body<'_>) -> IndexVec<Local, Lo
copies
}
#[derive(Debug)]
pub(crate) struct StorageLiveLocals {
/// Set of "StorageLive" statements for each local.
storage_live: IndexVec<Local, Set1<LocationExtended>>,
}
impl StorageLiveLocals {
pub(crate) fn new(
body: &Body<'_>,
always_storage_live_locals: &BitSet<Local>,
) -> StorageLiveLocals {
let mut storage_live = IndexVec::from_elem(Set1::Empty, &body.local_decls);
for local in always_storage_live_locals.iter() {
storage_live[local] = Set1::One(LocationExtended::Arg);
}
for (block, bbdata) in body.basic_blocks.iter_enumerated() {
for (statement_index, statement) in bbdata.statements.iter().enumerate() {
if let StatementKind::StorageLive(local) = statement.kind {
storage_live[local]
.insert(LocationExtended::Plain(Location { block, statement_index }));
}
}
}
debug!(?storage_live);
StorageLiveLocals { storage_live }
}
#[inline]
pub(crate) fn has_single_storage(&self, local: Local) -> bool {
matches!(self.storage_live[local], Set1::One(_))
}
}

View file

@ -20,8 +20,7 @@
}
bb1: {
- _0 = opaque::<u8>(_3) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
+ _0 = opaque::<u8>(_1) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
_0 = opaque::<u8>(_3) -> bb2; // scope 0 at $DIR/borrowed_local.rs:+12:13: +12:38
// mir::Constant
// + span: $DIR/borrowed_local.rs:28:28: 28:34
// + literal: Const { ty: fn(u8) -> bool {opaque::<u8>}, val: Value(<ZST>) }

View file

@ -0,0 +1,38 @@
- // MIR for `dominate_storage` before ReferencePropagation
+ // MIR for `dominate_storage` after ReferencePropagation
fn dominate_storage() -> () {
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23
let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _4: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _5: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
bb0: {
goto -> bb1; // scope 0 at $DIR/reference_prop.rs:+8:11: +8:20
}
bb1: {
_1 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18
_2 = &_1; // scope 0 at $DIR/reference_prop.rs:+11:13: +11:19
goto -> bb2; // scope 0 at $DIR/reference_prop.rs:+12:13: +12:22
}
bb2: {
_5 = (*_2); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
_0 = opaque::<i32>(_5) -> bb3; // scope 0 at $DIR/reference_prop.rs:+16:13: +16:38
// mir::Constant
// + span: $DIR/reference_prop.rs:383:28: 383:34
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb3: {
StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+19:13: +19:27
StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27
_6 = const true; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
switchInt(_6) -> [0: bb3, otherwise: bb1]; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:47
}
}

View file

@ -0,0 +1,56 @@
- // MIR for `maybe_dead` before ReferencePropagation
+ // MIR for `maybe_dead` after ReferencePropagation
fn maybe_dead(_1: bool) -> () {
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:24: +0:24
let mut _2: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _4: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _5: &mut i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _6: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _7: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _8: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
bb0: {
StorageLive(_2); // scope 0 at $DIR/reference_prop.rs:+7:13: +7:27
StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+8:13: +8:27
_2 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+9:13: +9:18
_3 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+10:13: +10:18
_4 = &_2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
_5 = &mut _3; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
(*_5) = const 7_i32; // scope 0 at $DIR/reference_prop.rs:+14:13: +14:19
- _6 = (*_4); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
+ _6 = _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
switchInt(_1) -> [1: bb1, otherwise: bb2]; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:46
}
bb1: {
StorageDead(_2); // scope 0 at $DIR/reference_prop.rs:+20:13: +20:27
StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+21:13: +21:27
_0 = opaque::<i32>(_6) -> bb2; // scope 0 at $DIR/reference_prop.rs:+22:13: +22:38
// mir::Constant
// + span: $DIR/reference_prop.rs:417:28: 417:34
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb2: {
_7 = (*_4); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
_0 = opaque::<i32>(_7) -> bb3; // scope 0 at $DIR/reference_prop.rs:+27:13: +27:38
// mir::Constant
// + span: $DIR/reference_prop.rs:422:28: 422:34
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb3: {
_8 = (*_5); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
_0 = opaque::<i32>(_8) -> bb4; // scope 0 at $DIR/reference_prop.rs:+33:13: +33:43
// mir::Constant
// + span: $DIR/reference_prop.rs:428:33: 428:39
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb4: {
return; // scope 0 at $DIR/reference_prop.rs:+36:13: +36:21
}
}

View file

@ -0,0 +1,27 @@
- // MIR for `multiple_storage` before ReferencePropagation
+ // MIR for `multiple_storage` after ReferencePropagation
fn multiple_storage() -> () {
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:23: +0:23
let mut _1: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _2: &i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _3: i32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
bb0: {
StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+6:13: +6:27
_1 = const 5_i32; // scope 0 at $DIR/reference_prop.rs:+7:13: +7:18
_2 = &_1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
StorageDead(_1); // scope 0 at $DIR/reference_prop.rs:+9:13: +9:27
StorageLive(_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:27
_3 = (*_2); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
_0 = opaque::<i32>(_3) -> bb1; // scope 0 at $DIR/reference_prop.rs:+14:13: +14:43
// mir::Constant
// + span: $DIR/reference_prop.rs:357:33: 357:39
// + literal: Const { ty: fn(i32) {opaque::<i32>}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/reference_prop.rs:+18:13: +18:21
}
}

View file

@ -0,0 +1,24 @@
- // MIR for `read_through_raw` before ReferencePropagation
+ // MIR for `read_through_raw` after ReferencePropagation
fn read_through_raw(_1: &mut usize) -> usize {
let mut _0: usize; // return place in scope 0 at $DIR/reference_prop.rs:+0:39: +0:44
let mut _2: &mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _3: &mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _4: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
let mut _5: *mut usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
bb0: {
_2 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+10:13: +10:25
- _3 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
- _4 = &raw mut (*_2); // scope 0 at $DIR/reference_prop.rs:+12:13: +12:30
- _5 = &raw mut (*_3); // scope 0 at $DIR/reference_prop.rs:+13:13: +13:30
- _0 = (*_4); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
- _0 = (*_5); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
+ _3 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:26
+ _0 = (*_2); // scope 0 at $DIR/reference_prop.rs:+15:13: +15:22
+ _0 = (*_3); // scope 0 at $DIR/reference_prop.rs:+16:13: +16:22
return; // scope 0 at $DIR/reference_prop.rs:+17:13: +17:21
}
}

View file

@ -0,0 +1,375 @@
- // MIR for `reference_propagation` before ReferencePropagation
+ // MIR for `reference_propagation` after ReferencePropagation
fn reference_propagation(_1: &T, _2: &T) -> () {
debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:39: +0:45
debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:54: +0:66
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:75: +0:75
let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
let _4: usize; // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:14
let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
let _10: usize; // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:14
let mut _13: &usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16
let _14: &usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:16
let _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
let mut _17: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
let _18: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
let _19: usize; // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:14
let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
let mut _24: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
let _25: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
let _26: usize; // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:14
let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
let mut _31: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
let _32: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
let _33: usize; // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:14
let _36: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
let mut _37: &usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
let _38: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
let _39: usize; // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:14
let _45: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
let mut _46: &usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
let _47: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
let _48: &T; // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
let _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
let mut _51: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
let _52: &T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
let mut _53: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28
let _54: &T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:28
let _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
let mut _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
scope 1 {
debug a => _4; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
let _5: &usize; // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
scope 2 {
debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
let _6: usize; // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
scope 3 {
debug c => _6; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
}
}
}
scope 4 {
debug a => _10; // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:14
let _11: usize; // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:15
scope 5 {
debug a2 => _11; // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:15
let mut _12: &usize; // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
scope 6 {
debug b => _12; // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18
let _15: usize; // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
scope 7 {
debug c => _15; // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14
}
}
}
}
scope 8 {
debug a => _19; // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:14
let _20: &usize; // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
scope 9 {
debug b => _20; // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14
let _21: &&usize; // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
scope 10 {
debug d => _21; // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14
let _22: usize; // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
scope 11 {
debug c => _22; // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14
}
}
}
}
scope 12 {
debug a => _26; // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:14
let mut _27: &usize; // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
scope 13 {
debug b => _27; // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18
let _28: &mut &usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
scope 14 {
debug d => _28; // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14
let _29: usize; // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
scope 15 {
debug c => _29; // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14
}
}
}
}
scope 16 {
debug a => _33; // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:14
let _34: &usize; // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
scope 17 {
debug b => _34; // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14
let _35: usize; // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
scope 18 {
debug c => _35; // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14
}
}
}
scope 19 {
debug a => _39; // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:14
let _40: &usize; // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
scope 20 {
debug b1 => _40; // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15
let _41: usize; // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
scope 21 {
debug c => _41; // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14
let _42: &usize; // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
scope 22 {
debug b2 => _42; // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15
let _43: usize; // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
scope 23 {
debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15
let _44: &usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
scope 24 {
debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15
}
}
}
}
}
}
scope 25 {
debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
let _49: T; // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
scope 26 {
debug b => _49; // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14
}
}
scope 27 {
debug a => _52; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14
let _55: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
scope 28 {
debug b => _55; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
StorageLive(_4); // scope 0 at $DIR/reference_prop.rs:+3:13: +3:14
_4 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+3:17: +3:24
StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
_5 = &_4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:19
StorageLive(_6); // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
- _6 = (*_5); // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
+ _6 = _4; // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
StorageLive(_8); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
_8 = (); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
_7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
// mir::Constant
// + span: $DIR/reference_prop.rs:16:9: 16:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_8); // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19
StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20
- _3 = const (); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
StorageDead(_6); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_4); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
StorageLive(_10); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:14
_10 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+11:17: +11:24
StorageLive(_11); // scope 4 at $DIR/reference_prop.rs:+12:13: +12:15
_11 = const 7_usize; // scope 4 at $DIR/reference_prop.rs:+12:18: +12:25
StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
_12 = &_10; // scope 5 at $DIR/reference_prop.rs:+13:21: +13:23
StorageLive(_13); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
- StorageLive(_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
- _14 = &_11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
- _13 = &(*_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
+ _13 = &_11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:16
_12 = move _13; // scope 6 at $DIR/reference_prop.rs:+14:9: +14:16
StorageDead(_13); // scope 6 at $DIR/reference_prop.rs:+14:15: +14:16
- StorageDead(_14); // scope 6 at $DIR/reference_prop.rs:+14:16: +14:17
StorageLive(_15); // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
_15 = (*_12); // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19
StorageLive(_16); // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
StorageLive(_17); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
_17 = (); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
_16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
// mir::Constant
// + span: $DIR/reference_prop.rs:27:9: 27:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb2: {
StorageDead(_17); // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19
StorageDead(_16); // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20
- _9 = const (); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
StorageDead(_15); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_12); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_11); // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_10); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageLive(_18); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
StorageLive(_19); // scope 0 at $DIR/reference_prop.rs:+22:13: +22:14
_19 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+22:17: +22:24
StorageLive(_20); // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
_20 = &_19; // scope 8 at $DIR/reference_prop.rs:+23:17: +23:19
StorageLive(_21); // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
_21 = &_20; // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19
StorageLive(_22); // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
_22 = (*_20); // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19
StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
_24 = (); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
_23 = opaque::<()>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
// mir::Constant
// + span: $DIR/reference_prop.rs:36:9: 36:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb3: {
StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19
StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:19: +26:20
- _18 = const (); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
StorageDead(_22); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_21); // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_20); // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_19); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageDead(_18); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageLive(_25); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
StorageLive(_26); // scope 0 at $DIR/reference_prop.rs:+31:13: +31:14
_26 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+31:17: +31:24
StorageLive(_27); // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
_27 = &_26; // scope 12 at $DIR/reference_prop.rs:+32:21: +32:23
StorageLive(_28); // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
_28 = &mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:23
StorageLive(_29); // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
_29 = (*_27); // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19
StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
_31 = (); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
_30 = opaque::<()>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
// mir::Constant
// + span: $DIR/reference_prop.rs:45:9: 45:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb4: {
StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19
StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:19: +35:20
- _25 = const (); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
StorageDead(_29); // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_28); // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_27); // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_26); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageDead(_25); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageLive(_32); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
StorageLive(_33); // scope 0 at $DIR/reference_prop.rs:+40:13: +40:14
_33 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+40:17: +40:24
StorageLive(_34); // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
_34 = &_33; // scope 16 at $DIR/reference_prop.rs:+41:17: +41:19
StorageLive(_35); // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
- _35 = (*_34); // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
+ _35 = _33; // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
StorageLive(_36); // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
StorageLive(_37); // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
_37 = _34; // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
_36 = opaque::<&usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
// mir::Constant
// + span: $DIR/reference_prop.rs:53:9: 53:15
// + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) }
}
bb5: {
StorageDead(_37); // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18
StorageDead(_36); // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19
- _32 = const (); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
StorageDead(_35); // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_34); // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_33); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageDead(_32); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageLive(_38); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
StorageLive(_39); // scope 0 at $DIR/reference_prop.rs:+48:13: +48:14
_39 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+48:17: +48:24
StorageLive(_40); // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
_40 = &_39; // scope 19 at $DIR/reference_prop.rs:+49:18: +49:20
StorageLive(_41); // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
- _41 = (*_40); // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
+ _41 = _39; // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
StorageLive(_42); // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
_42 = _40; // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20
StorageLive(_43); // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
- _43 = (*_42); // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
+ _43 = _39; // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
StorageLive(_44); // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
_44 = _42; // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20
StorageLive(_45); // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
StorageLive(_46); // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
_46 = _44; // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
_45 = opaque::<&usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
// mir::Constant
// + span: $DIR/reference_prop.rs:66:9: 66:15
// + literal: Const { ty: fn(&usize) {opaque::<&usize>}, val: Value(<ZST>) }
}
bb6: {
StorageDead(_46); // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19
StorageDead(_45); // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20
- _38 = const (); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
StorageDead(_44); // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_43); // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_42); // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_41); // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_40); // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_39); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageDead(_38); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageLive(_47); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
_48 = &(*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:25
StorageLive(_49); // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
- _49 = (*_48); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
+ _49 = (*_1); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
StorageLive(_50); // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
StorageLive(_51); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
_51 = (); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
_50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
// mir::Constant
// + span: $DIR/reference_prop.rs:73:9: 73:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb7: {
StorageDead(_51); // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19
StorageDead(_50); // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20
- _47 = const (); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
StorageDead(_49); // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6
StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
- StorageDead(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
_52 = &(*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:27
StorageLive(_53); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
- StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
- _54 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
- _53 = &(*_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
+ _53 = &(*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:28
_2 = move _53; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:28
StorageDead(_53); // scope 27 at $DIR/reference_prop.rs:+69:27: +69:28
- StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:28: +69:29
StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
_55 = (*_52); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19
StorageLive(_56); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
_57 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
_56 = opaque::<()>(move _57) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
// mir::Constant
// + span: $DIR/reference_prop.rs:81:9: 81:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb8: {
StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19
StorageDead(_56); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20
_0 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6
StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
return; // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2
}
}

View file

@ -0,0 +1,431 @@
- // MIR for `reference_propagation_const_ptr` before ReferencePropagation
+ // MIR for `reference_propagation_const_ptr` after ReferencePropagation
fn reference_propagation_const_ptr(_1: *const T, _2: *const T) -> () {
debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:45: +0:51
debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:63: +0:75
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87
let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
let mut _13: *const usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:26
let _15: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
let mut _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
let _17: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
let mut _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
let _24: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
let mut _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
let _31: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
let _35: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
let mut _36: *const usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
let _37: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
let _44: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
let mut _45: *const usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
let _46: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
let _49: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
let mut _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
let _51: (); // in scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
let mut _53: *const T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:38
let _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
let mut _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
let _61: (); // in scope 0 at $DIR/reference_prop.rs:+80:9: +80:19
let mut _62: (); // in scope 0 at $DIR/reference_prop.rs:+80:16: +80:18
scope 1 {
let _4: usize; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
scope 2 {
debug a => _4; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:14
let _5: *const usize; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
scope 3 {
debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
let _6: usize; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
scope 4 {
debug c => _6; // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14
}
}
}
}
scope 5 {
let _10: usize; // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:14
scope 6 {
debug a => _10; // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:14
let _11: usize; // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:15
scope 7 {
debug a2 => _11; // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:15
let mut _12: *const usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
scope 8 {
debug b => _12; // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18
let _14: usize; // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
scope 9 {
debug c => _14; // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14
}
}
}
}
}
scope 10 {
let _18: usize; // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:14
scope 11 {
debug a => _18; // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:14
let _19: *const usize; // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
scope 12 {
debug b => _19; // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14
let _20: &*const usize; // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
scope 13 {
debug d => _20; // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14
let _21: usize; // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
scope 14 {
debug c => _21; // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14
}
}
}
}
}
scope 15 {
let _25: usize; // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:14
scope 16 {
debug a => _25; // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:14
let mut _26: *const usize; // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
scope 17 {
debug b => _26; // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18
let _27: &mut *const usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
scope 18 {
debug d => _27; // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14
let _28: usize; // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
scope 19 {
debug c => _28; // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14
}
}
}
}
}
scope 20 {
let _32: usize; // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:14
scope 21 {
debug a => _32; // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:14
let _33: *const usize; // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
scope 22 {
debug b => _33; // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14
let _34: usize; // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
scope 23 {
debug c => _34; // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14
}
}
}
}
scope 24 {
let _38: usize; // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:14
scope 25 {
debug a => _38; // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:14
let _39: *const usize; // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
scope 26 {
debug b1 => _39; // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15
let _40: usize; // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
scope 27 {
debug c => _40; // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14
let _41: *const usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
scope 28 {
debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15
let _42: usize; // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
scope 29 {
debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15
let _43: *const usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
scope 30 {
debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15
}
}
}
}
}
}
}
scope 31 {
let _47: *const T; // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
scope 32 {
debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
let _48: T; // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
scope 33 {
debug b => _48; // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14
}
}
}
scope 34 {
let _52: *const T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
scope 35 {
debug a => _52; // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14
let _54: T; // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
scope 36 {
debug b => _54; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14
}
}
}
scope 37 {
let _57: usize; // in scope 37 at $DIR/reference_prop.rs:+76:13: +76:14
scope 38 {
debug a => _57; // in scope 38 at $DIR/reference_prop.rs:+76:13: +76:14
let _58: *const usize; // in scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
scope 39 {
debug b => _58; // in scope 39 at $DIR/reference_prop.rs:+77:13: +77:14
let _59: *const usize; // in scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
scope 40 {
debug c => _59; // in scope 40 at $DIR/reference_prop.rs:+78:13: +78:14
let _60: usize; // in scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
scope 41 {
debug e => _60; // in scope 41 at $DIR/reference_prop.rs:+79:13: +79:14
}
}
}
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
StorageLive(_4); // scope 1 at $DIR/reference_prop.rs:+3:13: +3:14
_4 = const 5_usize; // scope 1 at $DIR/reference_prop.rs:+3:17: +3:24
StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
_5 = &raw const _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:29
StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
- _6 = (*_5); // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
+ _6 = _4; // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
StorageLive(_8); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
_8 = (); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
_7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
// mir::Constant
// + span: $DIR/reference_prop.rs:166:9: 166:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_8); // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19
StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20
- _3 = const (); // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6
StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_4); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+11:13: +11:14
_10 = const 5_usize; // scope 5 at $DIR/reference_prop.rs:+11:17: +11:24
StorageLive(_11); // scope 6 at $DIR/reference_prop.rs:+12:13: +12:15
_11 = const 7_usize; // scope 6 at $DIR/reference_prop.rs:+12:18: +12:25
StorageLive(_12); // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
_12 = &raw const _10; // scope 7 at $DIR/reference_prop.rs:+13:21: +13:33
StorageLive(_13); // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26
_13 = &raw const _11; // scope 8 at $DIR/reference_prop.rs:+14:13: +14:26
_12 = move _13; // scope 8 at $DIR/reference_prop.rs:+14:9: +14:26
StorageDead(_13); // scope 8 at $DIR/reference_prop.rs:+14:25: +14:26
StorageLive(_14); // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
_14 = (*_12); // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19
StorageLive(_15); // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
StorageLive(_16); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
_16 = (); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
_15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
// mir::Constant
// + span: $DIR/reference_prop.rs:177:9: 177:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb2: {
StorageDead(_16); // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19
StorageDead(_15); // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20
- _9 = const (); // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6
StorageDead(_14); // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_12); // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_11); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageLive(_17); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
StorageLive(_18); // scope 10 at $DIR/reference_prop.rs:+22:13: +22:14
_18 = const 5_usize; // scope 10 at $DIR/reference_prop.rs:+22:17: +22:24
StorageLive(_19); // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
_19 = &raw const _18; // scope 11 at $DIR/reference_prop.rs:+23:17: +23:29
StorageLive(_20); // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
_20 = &_19; // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19
StorageLive(_21); // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
_21 = (*_19); // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19
StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
_23 = (); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
_22 = opaque::<()>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
// mir::Constant
// + span: $DIR/reference_prop.rs:186:9: 186:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb3: {
StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19
StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:19: +26:20
- _17 = const (); // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6
StorageDead(_21); // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_20); // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_19); // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_18); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageDead(_17); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageLive(_24); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
StorageLive(_25); // scope 15 at $DIR/reference_prop.rs:+31:13: +31:14
_25 = const 5_usize; // scope 15 at $DIR/reference_prop.rs:+31:17: +31:24
StorageLive(_26); // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
_26 = &raw const _25; // scope 16 at $DIR/reference_prop.rs:+32:21: +32:33
StorageLive(_27); // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
_27 = &mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:23
StorageLive(_28); // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
_28 = (*_26); // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19
StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
_30 = (); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
_29 = opaque::<()>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
// mir::Constant
// + span: $DIR/reference_prop.rs:195:9: 195:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb4: {
StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19
StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:19: +35:20
- _24 = const (); // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6
StorageDead(_28); // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_27); // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_26); // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_25); // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageDead(_24); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageLive(_31); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
StorageLive(_32); // scope 20 at $DIR/reference_prop.rs:+40:13: +40:14
_32 = const 7_usize; // scope 20 at $DIR/reference_prop.rs:+40:17: +40:24
StorageLive(_33); // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
_33 = &raw const _32; // scope 21 at $DIR/reference_prop.rs:+41:17: +41:29
StorageLive(_34); // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
- _34 = (*_33); // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
+ _34 = _32; // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
StorageLive(_35); // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
StorageLive(_36); // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
_36 = _33; // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
_35 = opaque::<*const usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
// mir::Constant
// + span: $DIR/reference_prop.rs:203:9: 203:15
// + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) }
}
bb5: {
StorageDead(_36); // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18
StorageDead(_35); // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19
- _31 = const (); // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6
StorageDead(_34); // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_33); // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_32); // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageDead(_31); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageLive(_37); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
StorageLive(_38); // scope 24 at $DIR/reference_prop.rs:+48:13: +48:14
_38 = const 7_usize; // scope 24 at $DIR/reference_prop.rs:+48:17: +48:24
StorageLive(_39); // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
_39 = &raw const _38; // scope 25 at $DIR/reference_prop.rs:+49:18: +49:30
StorageLive(_40); // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
- _40 = (*_39); // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
+ _40 = _38; // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
StorageLive(_41); // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
_41 = _39; // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20
StorageLive(_42); // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
- _42 = (*_41); // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
+ _42 = _38; // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
StorageLive(_43); // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
_43 = _41; // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20
StorageLive(_44); // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
StorageLive(_45); // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
_45 = _43; // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
_44 = opaque::<*const usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
// mir::Constant
// + span: $DIR/reference_prop.rs:216:9: 216:15
// + literal: Const { ty: fn(*const usize) {opaque::<*const usize>}, val: Value(<ZST>) }
}
bb6: {
StorageDead(_45); // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19
StorageDead(_44); // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20
- _37 = const (); // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6
StorageDead(_43); // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_42); // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_41); // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_40); // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_39); // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_38); // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageDead(_37); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageLive(_46); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
_47 = &raw const (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:35
StorageLive(_48); // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
- _48 = (*_47); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
+ _48 = (*_1); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
StorageLive(_49); // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
StorageLive(_50); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
_50 = (); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
_49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
// mir::Constant
// + span: $DIR/reference_prop.rs:223:9: 223:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb7: {
StorageDead(_50); // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19
StorageDead(_49); // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20
- _46 = const (); // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6
StorageDead(_48); // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6
StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6
- StorageDead(_46); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
- StorageLive(_51); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
StorageLive(_52); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
_52 = &raw const (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:37
StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38
_53 = &raw const (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:38
_2 = move _53; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:38
StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+69:37: +69:38
StorageLive(_54); // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
_54 = (*_52); // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19
StorageLive(_55); // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
StorageLive(_56); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
_56 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
_55 = opaque::<()>(move _56) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
// mir::Constant
// + span: $DIR/reference_prop.rs:231:9: 231:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb8: {
StorageDead(_56); // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19
StorageDead(_55); // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20
- _51 = const (); // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6
StorageDead(_54); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6
StorageDead(_52); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6
- StorageDead(_51); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
StorageLive(_57); // scope 37 at $DIR/reference_prop.rs:+76:13: +76:14
_57 = const 13_usize; // scope 37 at $DIR/reference_prop.rs:+76:17: +76:25
StorageLive(_58); // scope 38 at $DIR/reference_prop.rs:+77:13: +77:14
_58 = &raw const _57; // scope 38 at $DIR/reference_prop.rs:+77:17: +77:29
StorageLive(_59); // scope 39 at $DIR/reference_prop.rs:+78:13: +78:14
- _59 = &raw const (*_58); // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30
+ _59 = &raw const _57; // scope 39 at $DIR/reference_prop.rs:+78:17: +78:30
StorageLive(_60); // scope 40 at $DIR/reference_prop.rs:+79:13: +79:14
- _60 = (*_59); // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
+ _60 = _57; // scope 40 at $DIR/reference_prop.rs:+79:17: +79:19
StorageLive(_61); // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
StorageLive(_62); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
_62 = (); // scope 41 at $DIR/reference_prop.rs:+80:16: +80:18
_61 = opaque::<()>(move _62) -> bb9; // scope 41 at $DIR/reference_prop.rs:+80:9: +80:19
// mir::Constant
// + span: $DIR/reference_prop.rs:240:9: 240:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb9: {
StorageDead(_62); // scope 41 at $DIR/reference_prop.rs:+80:18: +80:19
StorageDead(_61); // scope 41 at $DIR/reference_prop.rs:+80:19: +80:20
_0 = const (); // scope 37 at $DIR/reference_prop.rs:+75:5: +81:6
StorageDead(_60); // scope 40 at $DIR/reference_prop.rs:+81:5: +81:6
StorageDead(_59); // scope 39 at $DIR/reference_prop.rs:+81:5: +81:6
StorageDead(_58); // scope 38 at $DIR/reference_prop.rs:+81:5: +81:6
StorageDead(_57); // scope 37 at $DIR/reference_prop.rs:+81:5: +81:6
return; // scope 0 at $DIR/reference_prop.rs:+82:2: +82:2
}
}

View file

@ -0,0 +1,372 @@
- // MIR for `reference_propagation_mut` before ReferencePropagation
+ // MIR for `reference_propagation_mut` after ReferencePropagation
fn reference_propagation_mut(_1: &mut T, _2: &mut T) -> () {
debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49
debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:62: +0:74
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:87: +0:87
let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
let mut _4: usize; // in scope 0 at $DIR/reference_prop.rs:+3:13: +3:18
let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
let mut _10: usize; // in scope 0 at $DIR/reference_prop.rs:+11:13: +11:18
let mut _13: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20
let mut _14: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:20
let _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
let mut _17: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
let _18: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
let mut _19: usize; // in scope 0 at $DIR/reference_prop.rs:+22:13: +22:18
let _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
let mut _24: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
let _25: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
let mut _26: usize; // in scope 0 at $DIR/reference_prop.rs:+31:13: +31:18
let _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
let mut _31: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
let _32: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
let mut _33: usize; // in scope 0 at $DIR/reference_prop.rs:+40:13: +40:18
let _36: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
let mut _37: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
let _38: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
let mut _39: usize; // in scope 0 at $DIR/reference_prop.rs:+48:13: +48:18
let _45: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
let mut _46: &mut usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
let _47: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
let _48: &mut T; // in scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
let _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
let mut _51: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
let _52: &mut T; // in scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
let mut _53: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32
let mut _54: &mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:32
let _56: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
let mut _57: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
scope 1 {
debug a => _4; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
let _5: &mut usize; // in scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
scope 2 {
debug b => _5; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
let _6: usize; // in scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
scope 3 {
debug c => _6; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
}
}
}
scope 4 {
debug a => _10; // in scope 4 at $DIR/reference_prop.rs:+11:13: +11:18
let mut _11: usize; // in scope 4 at $DIR/reference_prop.rs:+12:13: +12:19
scope 5 {
debug a2 => _11; // in scope 5 at $DIR/reference_prop.rs:+12:13: +12:19
let mut _12: &mut usize; // in scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
scope 6 {
debug b => _12; // in scope 6 at $DIR/reference_prop.rs:+13:13: +13:18
let _15: usize; // in scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
scope 7 {
debug c => _15; // in scope 7 at $DIR/reference_prop.rs:+16:13: +16:14
}
}
}
}
scope 8 {
debug a => _19; // in scope 8 at $DIR/reference_prop.rs:+22:13: +22:18
let _20: &mut usize; // in scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
scope 9 {
debug b => _20; // in scope 9 at $DIR/reference_prop.rs:+23:13: +23:14
let _21: &&mut usize; // in scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
scope 10 {
debug d => _21; // in scope 10 at $DIR/reference_prop.rs:+24:13: +24:14
let _22: usize; // in scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
scope 11 {
debug c => _22; // in scope 11 at $DIR/reference_prop.rs:+25:13: +25:14
}
}
}
}
scope 12 {
debug a => _26; // in scope 12 at $DIR/reference_prop.rs:+31:13: +31:18
let mut _27: &mut usize; // in scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
scope 13 {
debug b => _27; // in scope 13 at $DIR/reference_prop.rs:+32:13: +32:18
let _28: &mut &mut usize; // in scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
scope 14 {
debug d => _28; // in scope 14 at $DIR/reference_prop.rs:+33:13: +33:14
let _29: usize; // in scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
scope 15 {
debug c => _29; // in scope 15 at $DIR/reference_prop.rs:+34:13: +34:14
}
}
}
}
scope 16 {
debug a => _33; // in scope 16 at $DIR/reference_prop.rs:+40:13: +40:18
let _34: &mut usize; // in scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
scope 17 {
debug b => _34; // in scope 17 at $DIR/reference_prop.rs:+41:13: +41:14
let _35: usize; // in scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
scope 18 {
debug c => _35; // in scope 18 at $DIR/reference_prop.rs:+42:13: +42:14
}
}
}
scope 19 {
debug a => _39; // in scope 19 at $DIR/reference_prop.rs:+48:13: +48:18
let _40: &mut usize; // in scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
scope 20 {
debug b1 => _40; // in scope 20 at $DIR/reference_prop.rs:+49:13: +49:15
let _41: usize; // in scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
scope 21 {
debug c => _41; // in scope 21 at $DIR/reference_prop.rs:+50:13: +50:14
let _42: &mut usize; // in scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
scope 22 {
debug b2 => _42; // in scope 22 at $DIR/reference_prop.rs:+51:13: +51:15
let _43: usize; // in scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
scope 23 {
debug c2 => _43; // in scope 23 at $DIR/reference_prop.rs:+52:13: +52:15
let _44: &mut usize; // in scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
scope 24 {
debug b3 => _44; // in scope 24 at $DIR/reference_prop.rs:+53:13: +53:15
}
}
}
}
}
}
scope 25 {
debug a => _48; // in scope 25 at $DIR/reference_prop.rs:+61:13: +61:14
let _49: T; // in scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
scope 26 {
debug b => _49; // in scope 26 at $DIR/reference_prop.rs:+62:13: +62:14
}
}
scope 27 {
debug a => _52; // in scope 27 at $DIR/reference_prop.rs:+68:13: +68:14
let _55: T; // in scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
scope 28 {
debug b => _55; // in scope 28 at $DIR/reference_prop.rs:+70:13: +70:14
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
StorageLive(_4); // scope 0 at $DIR/reference_prop.rs:+3:13: +3:18
_4 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+3:21: +3:28
StorageLive(_5); // scope 1 at $DIR/reference_prop.rs:+4:13: +4:14
_5 = &mut _4; // scope 1 at $DIR/reference_prop.rs:+4:17: +4:23
StorageLive(_6); // scope 2 at $DIR/reference_prop.rs:+5:13: +5:14
- _6 = (*_5); // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
+ _6 = _4; // scope 2 at $DIR/reference_prop.rs:+5:17: +5:19
StorageLive(_7); // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
StorageLive(_8); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
_8 = (); // scope 3 at $DIR/reference_prop.rs:+6:16: +6:18
_7 = opaque::<()>(move _8) -> bb1; // scope 3 at $DIR/reference_prop.rs:+6:9: +6:19
// mir::Constant
// + span: $DIR/reference_prop.rs:91:9: 91:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_8); // scope 3 at $DIR/reference_prop.rs:+6:18: +6:19
StorageDead(_7); // scope 3 at $DIR/reference_prop.rs:+6:19: +6:20
- _3 = const (); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
StorageDead(_6); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_5); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_4); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
StorageLive(_10); // scope 0 at $DIR/reference_prop.rs:+11:13: +11:18
_10 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+11:21: +11:28
StorageLive(_11); // scope 4 at $DIR/reference_prop.rs:+12:13: +12:19
_11 = const 7_usize; // scope 4 at $DIR/reference_prop.rs:+12:22: +12:29
StorageLive(_12); // scope 5 at $DIR/reference_prop.rs:+13:13: +13:18
_12 = &mut _10; // scope 5 at $DIR/reference_prop.rs:+13:21: +13:27
StorageLive(_13); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
- StorageLive(_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
- _14 = &mut _11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
- _13 = &mut (*_14); // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
+ _13 = &mut _11; // scope 6 at $DIR/reference_prop.rs:+14:13: +14:20
_12 = move _13; // scope 6 at $DIR/reference_prop.rs:+14:9: +14:20
StorageDead(_13); // scope 6 at $DIR/reference_prop.rs:+14:19: +14:20
- StorageDead(_14); // scope 6 at $DIR/reference_prop.rs:+14:20: +14:21
StorageLive(_15); // scope 6 at $DIR/reference_prop.rs:+16:13: +16:14
_15 = (*_12); // scope 6 at $DIR/reference_prop.rs:+16:17: +16:19
StorageLive(_16); // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
StorageLive(_17); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
_17 = (); // scope 7 at $DIR/reference_prop.rs:+17:16: +17:18
_16 = opaque::<()>(move _17) -> bb2; // scope 7 at $DIR/reference_prop.rs:+17:9: +17:19
// mir::Constant
// + span: $DIR/reference_prop.rs:102:9: 102:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb2: {
StorageDead(_17); // scope 7 at $DIR/reference_prop.rs:+17:18: +17:19
StorageDead(_16); // scope 7 at $DIR/reference_prop.rs:+17:19: +17:20
- _9 = const (); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
StorageDead(_15); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_12); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_11); // scope 4 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_10); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageLive(_18); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
StorageLive(_19); // scope 0 at $DIR/reference_prop.rs:+22:13: +22:18
_19 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+22:21: +22:28
StorageLive(_20); // scope 8 at $DIR/reference_prop.rs:+23:13: +23:14
_20 = &mut _19; // scope 8 at $DIR/reference_prop.rs:+23:17: +23:23
StorageLive(_21); // scope 9 at $DIR/reference_prop.rs:+24:13: +24:14
_21 = &_20; // scope 9 at $DIR/reference_prop.rs:+24:17: +24:19
StorageLive(_22); // scope 10 at $DIR/reference_prop.rs:+25:13: +25:14
_22 = (*_20); // scope 10 at $DIR/reference_prop.rs:+25:17: +25:19
StorageLive(_23); // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
StorageLive(_24); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
_24 = (); // scope 11 at $DIR/reference_prop.rs:+26:16: +26:18
_23 = opaque::<()>(move _24) -> bb3; // scope 11 at $DIR/reference_prop.rs:+26:9: +26:19
// mir::Constant
// + span: $DIR/reference_prop.rs:111:9: 111:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb3: {
StorageDead(_24); // scope 11 at $DIR/reference_prop.rs:+26:18: +26:19
StorageDead(_23); // scope 11 at $DIR/reference_prop.rs:+26:19: +26:20
- _18 = const (); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
StorageDead(_22); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_21); // scope 9 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_20); // scope 8 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_19); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageDead(_18); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageLive(_25); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
StorageLive(_26); // scope 0 at $DIR/reference_prop.rs:+31:13: +31:18
_26 = const 5_usize; // scope 0 at $DIR/reference_prop.rs:+31:21: +31:28
StorageLive(_27); // scope 12 at $DIR/reference_prop.rs:+32:13: +32:18
_27 = &mut _26; // scope 12 at $DIR/reference_prop.rs:+32:21: +32:27
StorageLive(_28); // scope 13 at $DIR/reference_prop.rs:+33:13: +33:14
_28 = &mut _27; // scope 13 at $DIR/reference_prop.rs:+33:17: +33:23
StorageLive(_29); // scope 14 at $DIR/reference_prop.rs:+34:13: +34:14
_29 = (*_27); // scope 14 at $DIR/reference_prop.rs:+34:17: +34:19
StorageLive(_30); // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
StorageLive(_31); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
_31 = (); // scope 15 at $DIR/reference_prop.rs:+35:16: +35:18
_30 = opaque::<()>(move _31) -> bb4; // scope 15 at $DIR/reference_prop.rs:+35:9: +35:19
// mir::Constant
// + span: $DIR/reference_prop.rs:120:9: 120:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb4: {
StorageDead(_31); // scope 15 at $DIR/reference_prop.rs:+35:18: +35:19
StorageDead(_30); // scope 15 at $DIR/reference_prop.rs:+35:19: +35:20
- _25 = const (); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
StorageDead(_29); // scope 14 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_28); // scope 13 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_27); // scope 12 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_26); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageDead(_25); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageLive(_32); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
StorageLive(_33); // scope 0 at $DIR/reference_prop.rs:+40:13: +40:18
_33 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+40:21: +40:28
StorageLive(_34); // scope 16 at $DIR/reference_prop.rs:+41:13: +41:14
_34 = &mut _33; // scope 16 at $DIR/reference_prop.rs:+41:17: +41:23
StorageLive(_35); // scope 17 at $DIR/reference_prop.rs:+42:13: +42:14
_35 = (*_34); // scope 17 at $DIR/reference_prop.rs:+42:17: +42:19
StorageLive(_36); // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
StorageLive(_37); // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
_37 = move _34; // scope 18 at $DIR/reference_prop.rs:+43:16: +43:17
_36 = opaque::<&mut usize>(move _37) -> bb5; // scope 18 at $DIR/reference_prop.rs:+43:9: +43:18
// mir::Constant
// + span: $DIR/reference_prop.rs:128:9: 128:15
// + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) }
}
bb5: {
StorageDead(_37); // scope 18 at $DIR/reference_prop.rs:+43:17: +43:18
StorageDead(_36); // scope 18 at $DIR/reference_prop.rs:+43:18: +43:19
- _32 = const (); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
StorageDead(_35); // scope 17 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_34); // scope 16 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_33); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageDead(_32); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageLive(_38); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
StorageLive(_39); // scope 0 at $DIR/reference_prop.rs:+48:13: +48:18
_39 = const 7_usize; // scope 0 at $DIR/reference_prop.rs:+48:21: +48:28
StorageLive(_40); // scope 19 at $DIR/reference_prop.rs:+49:13: +49:15
_40 = &mut _39; // scope 19 at $DIR/reference_prop.rs:+49:18: +49:24
StorageLive(_41); // scope 20 at $DIR/reference_prop.rs:+50:13: +50:14
_41 = (*_40); // scope 20 at $DIR/reference_prop.rs:+50:17: +50:20
StorageLive(_42); // scope 21 at $DIR/reference_prop.rs:+51:13: +51:15
_42 = move _40; // scope 21 at $DIR/reference_prop.rs:+51:18: +51:20
StorageLive(_43); // scope 22 at $DIR/reference_prop.rs:+52:13: +52:15
_43 = (*_42); // scope 22 at $DIR/reference_prop.rs:+52:18: +52:21
StorageLive(_44); // scope 23 at $DIR/reference_prop.rs:+53:13: +53:15
_44 = move _42; // scope 23 at $DIR/reference_prop.rs:+53:18: +53:20
StorageLive(_45); // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
StorageLive(_46); // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
_46 = move _44; // scope 24 at $DIR/reference_prop.rs:+56:16: +56:18
_45 = opaque::<&mut usize>(move _46) -> bb6; // scope 24 at $DIR/reference_prop.rs:+56:9: +56:19
// mir::Constant
// + span: $DIR/reference_prop.rs:141:9: 141:15
// + literal: Const { ty: fn(&mut usize) {opaque::<&mut usize>}, val: Value(<ZST>) }
}
bb6: {
StorageDead(_46); // scope 24 at $DIR/reference_prop.rs:+56:18: +56:19
StorageDead(_45); // scope 24 at $DIR/reference_prop.rs:+56:19: +56:20
- _38 = const (); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
StorageDead(_44); // scope 23 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_43); // scope 22 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_42); // scope 21 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_41); // scope 20 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_40); // scope 19 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_39); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageDead(_38); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageLive(_47); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
StorageLive(_48); // scope 0 at $DIR/reference_prop.rs:+61:13: +61:14
_48 = &mut (*_1); // scope 0 at $DIR/reference_prop.rs:+61:17: +61:29
StorageLive(_49); // scope 25 at $DIR/reference_prop.rs:+62:13: +62:14
- _49 = (*_48); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
+ _49 = (*_1); // scope 25 at $DIR/reference_prop.rs:+62:17: +62:19
StorageLive(_50); // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
StorageLive(_51); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
_51 = (); // scope 26 at $DIR/reference_prop.rs:+63:16: +63:18
_50 = opaque::<()>(move _51) -> bb7; // scope 26 at $DIR/reference_prop.rs:+63:9: +63:19
// mir::Constant
// + span: $DIR/reference_prop.rs:148:9: 148:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb7: {
StorageDead(_51); // scope 26 at $DIR/reference_prop.rs:+63:18: +63:19
StorageDead(_50); // scope 26 at $DIR/reference_prop.rs:+63:19: +63:20
- _47 = const (); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
StorageDead(_49); // scope 25 at $DIR/reference_prop.rs:+64:5: +64:6
StorageDead(_48); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
- StorageDead(_47); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
StorageLive(_52); // scope 0 at $DIR/reference_prop.rs:+68:13: +68:14
_52 = &mut (*_2); // scope 0 at $DIR/reference_prop.rs:+68:17: +68:31
StorageLive(_53); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
- StorageLive(_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
- _54 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
- _53 = &mut (*_54); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
+ _53 = &mut (*_1); // scope 27 at $DIR/reference_prop.rs:+69:20: +69:32
_2 = move _53; // scope 27 at $DIR/reference_prop.rs:+69:9: +69:32
StorageDead(_53); // scope 27 at $DIR/reference_prop.rs:+69:31: +69:32
- StorageDead(_54); // scope 27 at $DIR/reference_prop.rs:+69:32: +69:33
StorageLive(_55); // scope 27 at $DIR/reference_prop.rs:+70:13: +70:14
_55 = (*_52); // scope 27 at $DIR/reference_prop.rs:+70:17: +70:19
StorageLive(_56); // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
StorageLive(_57); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
_57 = (); // scope 28 at $DIR/reference_prop.rs:+71:16: +71:18
_56 = opaque::<()>(move _57) -> bb8; // scope 28 at $DIR/reference_prop.rs:+71:9: +71:19
// mir::Constant
// + span: $DIR/reference_prop.rs:156:9: 156:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb8: {
StorageDead(_57); // scope 28 at $DIR/reference_prop.rs:+71:18: +71:19
StorageDead(_56); // scope 28 at $DIR/reference_prop.rs:+71:19: +71:20
_0 = const (); // scope 0 at $DIR/reference_prop.rs:+67:5: +72:6
StorageDead(_55); // scope 27 at $DIR/reference_prop.rs:+72:5: +72:6
StorageDead(_52); // scope 0 at $DIR/reference_prop.rs:+72:5: +72:6
return; // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2
}
}

View file

@ -0,0 +1,378 @@
- // MIR for `reference_propagation_mut_ptr` before ReferencePropagation
+ // MIR for `reference_propagation_mut_ptr` after ReferencePropagation
fn reference_propagation_mut_ptr(_1: *mut T, _2: *mut T) -> () {
debug single => _1; // in scope 0 at $DIR/reference_prop.rs:+0:43: +0:49
debug multiple => _2; // in scope 0 at $DIR/reference_prop.rs:+0:59: +0:71
let mut _0: (); // return place in scope 0 at $DIR/reference_prop.rs:+0:81: +0:81
let _3: (); // in scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
let _7: (); // in scope 0 at $DIR/reference_prop.rs:+6:9: +6:19
let mut _8: (); // in scope 0 at $DIR/reference_prop.rs:+6:16: +6:18
let _9: (); // in scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
let mut _13: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+14:13: +14:24
let _15: (); // in scope 0 at $DIR/reference_prop.rs:+17:9: +17:19
let mut _16: (); // in scope 0 at $DIR/reference_prop.rs:+17:16: +17:18
let _17: (); // in scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
let _22: (); // in scope 0 at $DIR/reference_prop.rs:+26:9: +26:19
let mut _23: (); // in scope 0 at $DIR/reference_prop.rs:+26:16: +26:18
let _24: (); // in scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
let _29: (); // in scope 0 at $DIR/reference_prop.rs:+35:9: +35:19
let mut _30: (); // in scope 0 at $DIR/reference_prop.rs:+35:16: +35:18
let _31: (); // in scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
let _35: (); // in scope 0 at $DIR/reference_prop.rs:+43:9: +43:18
let mut _36: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+43:16: +43:17
let _37: (); // in scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
let _44: (); // in scope 0 at $DIR/reference_prop.rs:+56:9: +56:19
let mut _45: *mut usize; // in scope 0 at $DIR/reference_prop.rs:+56:16: +56:18
let _46: (); // in scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
let _49: (); // in scope 0 at $DIR/reference_prop.rs:+63:9: +63:19
let mut _50: (); // in scope 0 at $DIR/reference_prop.rs:+63:16: +63:18
let mut _52: *mut T; // in scope 0 at $DIR/reference_prop.rs:+69:20: +69:36
let _54: (); // in scope 0 at $DIR/reference_prop.rs:+71:9: +71:19
let mut _55: (); // in scope 0 at $DIR/reference_prop.rs:+71:16: +71:18
scope 1 {
let mut _4: usize; // in scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
scope 2 {
debug a => _4; // in scope 2 at $DIR/reference_prop.rs:+3:13: +3:18
let _5: *mut usize; // in scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
scope 3 {
debug b => _5; // in scope 3 at $DIR/reference_prop.rs:+4:13: +4:14
let _6: usize; // in scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
scope 4 {
debug c => _6; // in scope 4 at $DIR/reference_prop.rs:+5:13: +5:14
}
}
}
}
scope 5 {
let mut _10: usize; // in scope 5 at $DIR/reference_prop.rs:+11:13: +11:18
scope 6 {
debug a => _10; // in scope 6 at $DIR/reference_prop.rs:+11:13: +11:18
let mut _11: usize; // in scope 6 at $DIR/reference_prop.rs:+12:13: +12:19
scope 7 {
debug a2 => _11; // in scope 7 at $DIR/reference_prop.rs:+12:13: +12:19
let mut _12: *mut usize; // in scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
scope 8 {
debug b => _12; // in scope 8 at $DIR/reference_prop.rs:+13:13: +13:18
let _14: usize; // in scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
scope 9 {
debug c => _14; // in scope 9 at $DIR/reference_prop.rs:+16:13: +16:14
}
}
}
}
}
scope 10 {
let mut _18: usize; // in scope 10 at $DIR/reference_prop.rs:+22:13: +22:18
scope 11 {
debug a => _18; // in scope 11 at $DIR/reference_prop.rs:+22:13: +22:18
let _19: *mut usize; // in scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
scope 12 {
debug b => _19; // in scope 12 at $DIR/reference_prop.rs:+23:13: +23:14
let _20: &*mut usize; // in scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
scope 13 {
debug d => _20; // in scope 13 at $DIR/reference_prop.rs:+24:13: +24:14
let _21: usize; // in scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
scope 14 {
debug c => _21; // in scope 14 at $DIR/reference_prop.rs:+25:13: +25:14
}
}
}
}
}
scope 15 {
let mut _25: usize; // in scope 15 at $DIR/reference_prop.rs:+31:13: +31:18
scope 16 {
debug a => _25; // in scope 16 at $DIR/reference_prop.rs:+31:13: +31:18
let mut _26: *mut usize; // in scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
scope 17 {
debug b => _26; // in scope 17 at $DIR/reference_prop.rs:+32:13: +32:18
let _27: &mut *mut usize; // in scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
scope 18 {
debug d => _27; // in scope 18 at $DIR/reference_prop.rs:+33:13: +33:14
let _28: usize; // in scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
scope 19 {
debug c => _28; // in scope 19 at $DIR/reference_prop.rs:+34:13: +34:14
}
}
}
}
}
scope 20 {
let mut _32: usize; // in scope 20 at $DIR/reference_prop.rs:+40:13: +40:18
scope 21 {
debug a => _32; // in scope 21 at $DIR/reference_prop.rs:+40:13: +40:18
let _33: *mut usize; // in scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
scope 22 {
debug b => _33; // in scope 22 at $DIR/reference_prop.rs:+41:13: +41:14
let _34: usize; // in scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
scope 23 {
debug c => _34; // in scope 23 at $DIR/reference_prop.rs:+42:13: +42:14
}
}
}
}
scope 24 {
let mut _38: usize; // in scope 24 at $DIR/reference_prop.rs:+48:13: +48:18
scope 25 {
debug a => _38; // in scope 25 at $DIR/reference_prop.rs:+48:13: +48:18
let _39: *mut usize; // in scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
scope 26 {
debug b1 => _39; // in scope 26 at $DIR/reference_prop.rs:+49:13: +49:15
let _40: usize; // in scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
scope 27 {
debug c => _40; // in scope 27 at $DIR/reference_prop.rs:+50:13: +50:14
let _41: *mut usize; // in scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
scope 28 {
debug b2 => _41; // in scope 28 at $DIR/reference_prop.rs:+51:13: +51:15
let _42: usize; // in scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
scope 29 {
debug c2 => _42; // in scope 29 at $DIR/reference_prop.rs:+52:13: +52:15
let _43: *mut usize; // in scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
scope 30 {
debug b3 => _43; // in scope 30 at $DIR/reference_prop.rs:+53:13: +53:15
}
}
}
}
}
}
}
scope 31 {
let _47: *mut T; // in scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
scope 32 {
debug a => _47; // in scope 32 at $DIR/reference_prop.rs:+61:13: +61:14
let _48: T; // in scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
scope 33 {
debug b => _48; // in scope 33 at $DIR/reference_prop.rs:+62:13: +62:14
}
}
}
scope 34 {
let _51: *mut T; // in scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
scope 35 {
debug a => _51; // in scope 35 at $DIR/reference_prop.rs:+68:13: +68:14
let _53: T; // in scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
scope 36 {
debug b => _53; // in scope 36 at $DIR/reference_prop.rs:+70:13: +70:14
}
}
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/reference_prop.rs:+2:5: +7:6
StorageLive(_4); // scope 1 at $DIR/reference_prop.rs:+3:13: +3:18
_4 = const 5_usize; // scope 1 at $DIR/reference_prop.rs:+3:21: +3:28
StorageLive(_5); // scope 2 at $DIR/reference_prop.rs:+4:13: +4:14
_5 = &raw mut _4; // scope 2 at $DIR/reference_prop.rs:+4:17: +4:27
StorageLive(_6); // scope 3 at $DIR/reference_prop.rs:+5:13: +5:14
- _6 = (*_5); // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
+ _6 = _4; // scope 3 at $DIR/reference_prop.rs:+5:17: +5:19
StorageLive(_7); // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
StorageLive(_8); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
_8 = (); // scope 4 at $DIR/reference_prop.rs:+6:16: +6:18
_7 = opaque::<()>(move _8) -> bb1; // scope 4 at $DIR/reference_prop.rs:+6:9: +6:19
// mir::Constant
// + span: $DIR/reference_prop.rs:250:9: 250:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_8); // scope 4 at $DIR/reference_prop.rs:+6:18: +6:19
StorageDead(_7); // scope 4 at $DIR/reference_prop.rs:+6:19: +6:20
- _3 = const (); // scope 1 at $DIR/reference_prop.rs:+2:5: +7:6
StorageDead(_6); // scope 3 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_5); // scope 2 at $DIR/reference_prop.rs:+7:5: +7:6
StorageDead(_4); // scope 1 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageDead(_3); // scope 0 at $DIR/reference_prop.rs:+7:5: +7:6
- StorageLive(_9); // scope 0 at $DIR/reference_prop.rs:+10:5: +18:6
StorageLive(_10); // scope 5 at $DIR/reference_prop.rs:+11:13: +11:18
_10 = const 5_usize; // scope 5 at $DIR/reference_prop.rs:+11:21: +11:28
StorageLive(_11); // scope 6 at $DIR/reference_prop.rs:+12:13: +12:19
_11 = const 7_usize; // scope 6 at $DIR/reference_prop.rs:+12:22: +12:29
StorageLive(_12); // scope 7 at $DIR/reference_prop.rs:+13:13: +13:18
_12 = &raw mut _10; // scope 7 at $DIR/reference_prop.rs:+13:21: +13:31
StorageLive(_13); // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24
_13 = &raw mut _11; // scope 8 at $DIR/reference_prop.rs:+14:13: +14:24
_12 = move _13; // scope 8 at $DIR/reference_prop.rs:+14:9: +14:24
StorageDead(_13); // scope 8 at $DIR/reference_prop.rs:+14:23: +14:24
StorageLive(_14); // scope 8 at $DIR/reference_prop.rs:+16:13: +16:14
_14 = (*_12); // scope 8 at $DIR/reference_prop.rs:+16:17: +16:19
StorageLive(_15); // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
StorageLive(_16); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
_16 = (); // scope 9 at $DIR/reference_prop.rs:+17:16: +17:18
_15 = opaque::<()>(move _16) -> bb2; // scope 9 at $DIR/reference_prop.rs:+17:9: +17:19
// mir::Constant
// + span: $DIR/reference_prop.rs:261:9: 261:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb2: {
StorageDead(_16); // scope 9 at $DIR/reference_prop.rs:+17:18: +17:19
StorageDead(_15); // scope 9 at $DIR/reference_prop.rs:+17:19: +17:20
- _9 = const (); // scope 5 at $DIR/reference_prop.rs:+10:5: +18:6
StorageDead(_14); // scope 8 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_12); // scope 7 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_11); // scope 6 at $DIR/reference_prop.rs:+18:5: +18:6
StorageDead(_10); // scope 5 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageDead(_9); // scope 0 at $DIR/reference_prop.rs:+18:5: +18:6
- StorageLive(_17); // scope 0 at $DIR/reference_prop.rs:+21:5: +27:6
StorageLive(_18); // scope 10 at $DIR/reference_prop.rs:+22:13: +22:18
_18 = const 5_usize; // scope 10 at $DIR/reference_prop.rs:+22:21: +22:28
StorageLive(_19); // scope 11 at $DIR/reference_prop.rs:+23:13: +23:14
_19 = &raw mut _18; // scope 11 at $DIR/reference_prop.rs:+23:17: +23:27
StorageLive(_20); // scope 12 at $DIR/reference_prop.rs:+24:13: +24:14
_20 = &_19; // scope 12 at $DIR/reference_prop.rs:+24:17: +24:19
StorageLive(_21); // scope 13 at $DIR/reference_prop.rs:+25:13: +25:14
_21 = (*_19); // scope 13 at $DIR/reference_prop.rs:+25:17: +25:19
StorageLive(_22); // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
StorageLive(_23); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
_23 = (); // scope 14 at $DIR/reference_prop.rs:+26:16: +26:18
_22 = opaque::<()>(move _23) -> bb3; // scope 14 at $DIR/reference_prop.rs:+26:9: +26:19
// mir::Constant
// + span: $DIR/reference_prop.rs:270:9: 270:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb3: {
StorageDead(_23); // scope 14 at $DIR/reference_prop.rs:+26:18: +26:19
StorageDead(_22); // scope 14 at $DIR/reference_prop.rs:+26:19: +26:20
- _17 = const (); // scope 10 at $DIR/reference_prop.rs:+21:5: +27:6
StorageDead(_21); // scope 13 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_20); // scope 12 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_19); // scope 11 at $DIR/reference_prop.rs:+27:5: +27:6
StorageDead(_18); // scope 10 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageDead(_17); // scope 0 at $DIR/reference_prop.rs:+27:5: +27:6
- StorageLive(_24); // scope 0 at $DIR/reference_prop.rs:+30:5: +36:6
StorageLive(_25); // scope 15 at $DIR/reference_prop.rs:+31:13: +31:18
_25 = const 5_usize; // scope 15 at $DIR/reference_prop.rs:+31:21: +31:28
StorageLive(_26); // scope 16 at $DIR/reference_prop.rs:+32:13: +32:18
_26 = &raw mut _25; // scope 16 at $DIR/reference_prop.rs:+32:21: +32:31
StorageLive(_27); // scope 17 at $DIR/reference_prop.rs:+33:13: +33:14
_27 = &mut _26; // scope 17 at $DIR/reference_prop.rs:+33:17: +33:23
StorageLive(_28); // scope 18 at $DIR/reference_prop.rs:+34:13: +34:14
_28 = (*_26); // scope 18 at $DIR/reference_prop.rs:+34:17: +34:19
StorageLive(_29); // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
StorageLive(_30); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
_30 = (); // scope 19 at $DIR/reference_prop.rs:+35:16: +35:18
_29 = opaque::<()>(move _30) -> bb4; // scope 19 at $DIR/reference_prop.rs:+35:9: +35:19
// mir::Constant
// + span: $DIR/reference_prop.rs:279:9: 279:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb4: {
StorageDead(_30); // scope 19 at $DIR/reference_prop.rs:+35:18: +35:19
StorageDead(_29); // scope 19 at $DIR/reference_prop.rs:+35:19: +35:20
- _24 = const (); // scope 15 at $DIR/reference_prop.rs:+30:5: +36:6
StorageDead(_28); // scope 18 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_27); // scope 17 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_26); // scope 16 at $DIR/reference_prop.rs:+36:5: +36:6
StorageDead(_25); // scope 15 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageDead(_24); // scope 0 at $DIR/reference_prop.rs:+36:5: +36:6
- StorageLive(_31); // scope 0 at $DIR/reference_prop.rs:+39:5: +44:6
StorageLive(_32); // scope 20 at $DIR/reference_prop.rs:+40:13: +40:18
_32 = const 7_usize; // scope 20 at $DIR/reference_prop.rs:+40:21: +40:28
StorageLive(_33); // scope 21 at $DIR/reference_prop.rs:+41:13: +41:14
_33 = &raw mut _32; // scope 21 at $DIR/reference_prop.rs:+41:17: +41:27
StorageLive(_34); // scope 22 at $DIR/reference_prop.rs:+42:13: +42:14
_34 = (*_33); // scope 22 at $DIR/reference_prop.rs:+42:17: +42:19
StorageLive(_35); // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
StorageLive(_36); // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
_36 = _33; // scope 23 at $DIR/reference_prop.rs:+43:16: +43:17
_35 = opaque::<*mut usize>(move _36) -> bb5; // scope 23 at $DIR/reference_prop.rs:+43:9: +43:18
// mir::Constant
// + span: $DIR/reference_prop.rs:287:9: 287:15
// + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) }
}
bb5: {
StorageDead(_36); // scope 23 at $DIR/reference_prop.rs:+43:17: +43:18
StorageDead(_35); // scope 23 at $DIR/reference_prop.rs:+43:18: +43:19
- _31 = const (); // scope 20 at $DIR/reference_prop.rs:+39:5: +44:6
StorageDead(_34); // scope 22 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_33); // scope 21 at $DIR/reference_prop.rs:+44:5: +44:6
StorageDead(_32); // scope 20 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageDead(_31); // scope 0 at $DIR/reference_prop.rs:+44:5: +44:6
- StorageLive(_37); // scope 0 at $DIR/reference_prop.rs:+47:5: +57:6
StorageLive(_38); // scope 24 at $DIR/reference_prop.rs:+48:13: +48:18
_38 = const 7_usize; // scope 24 at $DIR/reference_prop.rs:+48:21: +48:28
StorageLive(_39); // scope 25 at $DIR/reference_prop.rs:+49:13: +49:15
_39 = &raw mut _38; // scope 25 at $DIR/reference_prop.rs:+49:18: +49:28
StorageLive(_40); // scope 26 at $DIR/reference_prop.rs:+50:13: +50:14
_40 = (*_39); // scope 26 at $DIR/reference_prop.rs:+50:17: +50:20
StorageLive(_41); // scope 27 at $DIR/reference_prop.rs:+51:13: +51:15
_41 = _39; // scope 27 at $DIR/reference_prop.rs:+51:18: +51:20
StorageLive(_42); // scope 28 at $DIR/reference_prop.rs:+52:13: +52:15
_42 = (*_41); // scope 28 at $DIR/reference_prop.rs:+52:18: +52:21
StorageLive(_43); // scope 29 at $DIR/reference_prop.rs:+53:13: +53:15
_43 = _41; // scope 29 at $DIR/reference_prop.rs:+53:18: +53:20
StorageLive(_44); // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
StorageLive(_45); // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
_45 = _43; // scope 30 at $DIR/reference_prop.rs:+56:16: +56:18
_44 = opaque::<*mut usize>(move _45) -> bb6; // scope 30 at $DIR/reference_prop.rs:+56:9: +56:19
// mir::Constant
// + span: $DIR/reference_prop.rs:300:9: 300:15
// + literal: Const { ty: fn(*mut usize) {opaque::<*mut usize>}, val: Value(<ZST>) }
}
bb6: {
StorageDead(_45); // scope 30 at $DIR/reference_prop.rs:+56:18: +56:19
StorageDead(_44); // scope 30 at $DIR/reference_prop.rs:+56:19: +56:20
- _37 = const (); // scope 24 at $DIR/reference_prop.rs:+47:5: +57:6
StorageDead(_43); // scope 29 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_42); // scope 28 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_41); // scope 27 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_40); // scope 26 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_39); // scope 25 at $DIR/reference_prop.rs:+57:5: +57:6
StorageDead(_38); // scope 24 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageDead(_37); // scope 0 at $DIR/reference_prop.rs:+57:5: +57:6
- StorageLive(_46); // scope 0 at $DIR/reference_prop.rs:+60:5: +64:6
StorageLive(_47); // scope 31 at $DIR/reference_prop.rs:+61:13: +61:14
_47 = &raw mut (*_1); // scope 31 at $DIR/reference_prop.rs:+61:17: +61:33
StorageLive(_48); // scope 32 at $DIR/reference_prop.rs:+62:13: +62:14
- _48 = (*_47); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
+ _48 = (*_1); // scope 32 at $DIR/reference_prop.rs:+62:17: +62:19
StorageLive(_49); // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
StorageLive(_50); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
_50 = (); // scope 33 at $DIR/reference_prop.rs:+63:16: +63:18
_49 = opaque::<()>(move _50) -> bb7; // scope 33 at $DIR/reference_prop.rs:+63:9: +63:19
// mir::Constant
// + span: $DIR/reference_prop.rs:307:9: 307:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb7: {
StorageDead(_50); // scope 33 at $DIR/reference_prop.rs:+63:18: +63:19
StorageDead(_49); // scope 33 at $DIR/reference_prop.rs:+63:19: +63:20
- _46 = const (); // scope 31 at $DIR/reference_prop.rs:+60:5: +64:6
StorageDead(_48); // scope 32 at $DIR/reference_prop.rs:+64:5: +64:6
StorageDead(_47); // scope 31 at $DIR/reference_prop.rs:+64:5: +64:6
- StorageDead(_46); // scope 0 at $DIR/reference_prop.rs:+64:5: +64:6
StorageLive(_51); // scope 34 at $DIR/reference_prop.rs:+68:13: +68:14
_51 = &raw mut (*_2); // scope 34 at $DIR/reference_prop.rs:+68:17: +68:35
StorageLive(_52); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36
_52 = &raw mut (*_1); // scope 35 at $DIR/reference_prop.rs:+69:20: +69:36
_2 = move _52; // scope 35 at $DIR/reference_prop.rs:+69:9: +69:36
StorageDead(_52); // scope 35 at $DIR/reference_prop.rs:+69:35: +69:36
StorageLive(_53); // scope 35 at $DIR/reference_prop.rs:+70:13: +70:14
_53 = (*_51); // scope 35 at $DIR/reference_prop.rs:+70:17: +70:19
StorageLive(_54); // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
StorageLive(_55); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
_55 = (); // scope 36 at $DIR/reference_prop.rs:+71:16: +71:18
_54 = opaque::<()>(move _55) -> bb8; // scope 36 at $DIR/reference_prop.rs:+71:9: +71:19
// mir::Constant
// + span: $DIR/reference_prop.rs:315:9: 315:15
// + literal: Const { ty: fn(()) {opaque::<()>}, val: Value(<ZST>) }
}
bb8: {
StorageDead(_55); // scope 36 at $DIR/reference_prop.rs:+71:18: +71:19
StorageDead(_54); // scope 36 at $DIR/reference_prop.rs:+71:19: +71:20
_0 = const (); // scope 34 at $DIR/reference_prop.rs:+67:5: +72:6
StorageDead(_53); // scope 35 at $DIR/reference_prop.rs:+72:5: +72:6
StorageDead(_51); // scope 34 at $DIR/reference_prop.rs:+72:5: +72:6
return; // scope 0 at $DIR/reference_prop.rs:+73:2: +73:2
}
}

View file

@ -0,0 +1,456 @@
// unit-test: ReferencePropagation
// needs-unwind
#![feature(raw_ref_op)]
#![feature(core_intrinsics, custom_mir)]
#[inline(never)]
fn opaque(_: impl Sized) {}
fn reference_propagation<'a, T: Copy>(single: &'a T, mut multiple: &'a T) {
// Propagation through a reference.
{
let a = 5_usize;
let b = &a; // This borrow is only used once.
let c = *b; // This should be optimized.
opaque(()); // We use opaque to separate cases into basic blocks in the MIR.
}
// Propagation through a two references.
{
let a = 5_usize;
let a2 = 7_usize;
let mut b = &a;
b = &a2;
// `b` is assigned twice, so we cannot propagate it.
let c = *b;
opaque(());
}
// Propagation through a borrowed reference.
{
let a = 5_usize;
let b = &a;
let d = &b;
let c = *b; // `b` is immutably borrowed, we know its value, but do not propagate it
opaque(());
}
// Propagation through a borrowed reference.
{
let a = 5_usize;
let mut b = &a;
let d = &mut b;
let c = *b; // `b` is mutably borrowed, we cannot know its value.
opaque(());
}
// Propagation through an escaping borrow.
{
let a = 7_usize;
let b = &a;
let c = *b;
opaque(b); // `b` escapes here, but we can still replace immutable borrow
}
// Propagation through a transitively escaping borrow.
{
let a = 7_usize;
let b1 = &a;
let c = *b1;
let b2 = b1;
let c2 = *b2;
let b3 = b2;
// `b3` escapes here, so we can only replace immutable borrow,
// for either `b`, `b2` or `b3`.
opaque(b3);
}
// Propagation a reborrow of an argument.
{
let a = &*single;
let b = *a; // This should be optimized as `*single`.
opaque(());
}
// Propagation a reborrow of a mutated argument.
{
let a = &*multiple;
multiple = &*single;
let b = *a; // This should not be optimized.
opaque(());
}
}
fn reference_propagation_mut<'a, T: Copy>(single: &'a mut T, mut multiple: &'a mut T) {
// Propagation through a reference.
{
let mut a = 5_usize;
let b = &mut a; // This borrow is only used once.
let c = *b; // This should be optimized.
opaque(());
}
// Propagation through a two references.
{
let mut a = 5_usize;
let mut a2 = 7_usize;
let mut b = &mut a;
b = &mut a2;
// `b` is assigned twice, so we cannot propagate it.
let c = *b;
opaque(());
}
// Propagation through a borrowed reference.
{
let mut a = 5_usize;
let b = &mut a;
let d = &b;
let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
opaque(());
}
// Propagation through a borrowed reference.
{
let mut a = 5_usize;
let mut b = &mut a;
let d = &mut b;
let c = *b; // `b` is mutably borrowed, we cannot know its value.
opaque(());
}
// Propagation through an escaping borrow.
{
let mut a = 7_usize;
let b = &mut a;
let c = *b;
opaque(b); // `b` escapes here, so we can only replace immutable borrow
}
// Propagation through a transitively escaping borrow.
{
let mut a = 7_usize;
let b1 = &mut a;
let c = *b1;
let b2 = b1;
let c2 = *b2;
let b3 = b2;
// `b3` escapes here, so we can only replace immutable borrow,
// for either `b`, `b2` or `b3`.
opaque(b3);
}
// Propagation a reborrow of an argument.
{
let a = &mut *single;
let b = *a; // This should be optimized as `*single`.
opaque(());
}
// Propagation a reborrow of a mutated argument.
{
let a = &mut *multiple;
multiple = &mut *single;
let b = *a; // This should not be optimized.
opaque(());
}
}
fn reference_propagation_const_ptr<T: Copy>(single: *const T, mut multiple: *const T) {
// Propagation through a reference.
unsafe {
let a = 5_usize;
let b = &raw const a; // This borrow is only used once.
let c = *b; // This should be optimized.
opaque(());
}
// Propagation through a two references.
unsafe {
let a = 5_usize;
let a2 = 7_usize;
let mut b = &raw const a;
b = &raw const a2;
// `b` is assigned twice, so we cannot propagate it.
let c = *b;
opaque(());
}
// Propagation through a borrowed reference.
unsafe {
let a = 5_usize;
let b = &raw const a;
let d = &b;
let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
opaque(());
}
// Propagation through a borrowed reference.
unsafe {
let a = 5_usize;
let mut b = &raw const a;
let d = &mut b;
let c = *b; // `b` is mutably borrowed, we cannot know its value.
opaque(());
}
// Propagation through an escaping borrow.
unsafe {
let a = 7_usize;
let b = &raw const a;
let c = *b;
opaque(b); // `b` escapes here, so we can only replace immutable borrow
}
// Propagation through a transitively escaping borrow.
unsafe {
let a = 7_usize;
let b1 = &raw const a;
let c = *b1;
let b2 = b1;
let c2 = *b2;
let b3 = b2;
// `b3` escapes here, so we can only replace immutable borrow,
// for either `b`, `b2` or `b3`.
opaque(b3);
}
// Propagation a reborrow of an argument.
unsafe {
let a = &raw const *single;
let b = *a; // This should be optimized as `*single`.
opaque(());
}
// Propagation a reborrow of a mutated argument.
unsafe {
let a = &raw const *multiple;
multiple = &raw const *single;
let b = *a; // This should not be optimized.
opaque(());
}
// Propagation through a reborrow.
unsafe {
let a = 13_usize;
let b = &raw const a;
let c = &raw const *b;
let e = *c;
opaque(());
}
}
fn reference_propagation_mut_ptr<T: Copy>(single: *mut T, mut multiple: *mut T) {
// Propagation through a reference.
unsafe {
let mut a = 5_usize;
let b = &raw mut a; // This borrow is only used once.
let c = *b; // This should be optimized.
opaque(());
}
// Propagation through a two references.
unsafe {
let mut a = 5_usize;
let mut a2 = 7_usize;
let mut b = &raw mut a;
b = &raw mut a2;
// `b` is assigned twice, so we cannot propagate it.
let c = *b;
opaque(());
}
// Propagation through a borrowed reference.
unsafe {
let mut a = 5_usize;
let b = &raw mut a;
let d = &b;
let c = *b; // `b` is immutably borrowed, we know its value, but cannot be removed.
opaque(());
}
// Propagation through a borrowed reference.
unsafe {
let mut a = 5_usize;
let mut b = &raw mut a;
let d = &mut b;
let c = *b; // `b` is mutably borrowed, we cannot know its value.
opaque(());
}
// Propagation through an escaping borrow.
unsafe {
let mut a = 7_usize;
let b = &raw mut a;
let c = *b;
opaque(b); // `b` escapes here, so we can only replace immutable borrow
}
// Propagation through a transitively escaping borrow.
unsafe {
let mut a = 7_usize;
let b1 = &raw mut a;
let c = *b1;
let b2 = b1;
let c2 = *b2;
let b3 = b2;
// `b3` escapes here, so we can only replace immutable borrow,
// for either `b`, `b2` or `b3`.
opaque(b3);
}
// Propagation a reborrow of an argument.
unsafe {
let a = &raw mut *single;
let b = *a; // This should be optimized as `*single`.
opaque(());
}
// Propagation a reborrow of a mutated argument.
unsafe {
let a = &raw mut *multiple;
multiple = &raw mut *single;
let b = *a; // This should not be optimized.
opaque(());
}
}
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
fn read_through_raw(x: &mut usize) -> usize {
use std::intrinsics::mir::*;
mir!(
let r1: &mut usize;
let r2: &mut usize;
let p1: *mut usize;
let p2: *mut usize;
{
r1 = &mut *x;
r2 = &mut *r1;
p1 = &raw mut *r1;
p2 = &raw mut *r2;
RET = *p1;
RET = *p2;
Return()
}
)
}
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
fn multiple_storage() {
use std::intrinsics::mir::*;
mir!(
let x: i32;
{
StorageLive(x);
x = 5;
let z = &x;
StorageDead(x);
StorageLive(x);
// As there are multiple `StorageLive` statements for `x`, we cannot know if this `z`'s
// pointer address is the address of `x`, so do nothing.
let y = *z;
Call(RET, retblock, opaque(y))
}
retblock = {
Return()
}
)
}
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
fn dominate_storage() {
use std::intrinsics::mir::*;
mir!(
let x: i32;
let r: &i32;
let c: i32;
let d: bool;
{ Goto(bb0) }
bb0 = {
x = 5;
r = &x;
Goto(bb1)
}
bb1 = {
let c = *r;
Call(RET, bb2, opaque(c))
}
bb2 = {
StorageDead(x);
StorageLive(x);
let d = true;
match d { false => bb2, _ => bb0 }
}
)
}
#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
fn maybe_dead(m: bool) {
use std::intrinsics::mir::*;
mir!(
let x: i32;
let y: i32;
{
StorageLive(x);
StorageLive(y);
x = 5;
y = 5;
let a = &x;
let b = &mut y;
// As we don't replace `b` in `bb2`, we cannot replace it here either.
*b = 7;
// But this can still be replaced.
let u = *a;
match m { true => bb1, _ => bb2 }
}
bb1 = {
StorageDead(x);
StorageDead(y);
Call(RET, bb2, opaque(u))
}
bb2 = {
// As `x` may be `StorageDead`, `a` may be dangling, so we do nothing.
let z = *a;
Call(RET, bb3, opaque(z))
}
bb3 = {
// As `y` may be `StorageDead`, `b` may be dangling, so we do nothing.
// This implies that we also do not substitute `b` in `bb0`.
let t = *b;
Call(RET, retblock, opaque(t))
}
retblock = {
Return()
}
)
}
fn main() {
let mut x = 5_usize;
let mut y = 7_usize;
reference_propagation(&x, &y);
reference_propagation_mut(&mut x, &mut y);
reference_propagation_const_ptr(&raw const x, &raw const y);
reference_propagation_mut_ptr(&raw mut x, &raw mut y);
read_through_raw(&mut x);
multiple_storage();
dominate_storage();
maybe_dead(true);
}
// EMIT_MIR reference_prop.reference_propagation.ReferencePropagation.diff
// EMIT_MIR reference_prop.reference_propagation_mut.ReferencePropagation.diff
// EMIT_MIR reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
// EMIT_MIR reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
// EMIT_MIR reference_prop.read_through_raw.ReferencePropagation.diff
// EMIT_MIR reference_prop.multiple_storage.ReferencePropagation.diff
// EMIT_MIR reference_prop.dominate_storage.ReferencePropagation.diff
// EMIT_MIR reference_prop.maybe_dead.ReferencePropagation.diff

View file

@ -12,7 +12,9 @@ pub fn variant_b(input: &[(usize, usize, usize, usize)]) -> usize {
input.iter().filter(|&&(a, b, c, d)| a <= c && d <= b || c <= a && b <= d).count()
}
// EMIT_MIR slice_filter.variant_a-{closure#0}.ReferencePropagation.diff
// EMIT_MIR slice_filter.variant_a-{closure#0}.CopyProp.diff
// EMIT_MIR slice_filter.variant_a-{closure#0}.DestinationPropagation.diff
// EMIT_MIR slice_filter.variant_b-{closure#0}.CopyProp.diff
// EMIT_MIR slice_filter.variant_b-{closure#0}.ReferencePropagation.diff
// EMIT_MIR slice_filter.variant_b-{closure#0}.DestinationPropagation.diff

View file

@ -101,16 +101,16 @@
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
- StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
- StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
- StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
@ -184,10 +184,10 @@
bb3: {
StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
}

View file

@ -30,10 +30,14 @@
let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
scope 1 {
debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
- debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
- debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
- debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
- debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
+ debug a => _20; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
+ debug b => _15; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
+ debug c => _11; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
+ debug d => _24; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46
debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
@ -85,25 +89,38 @@
}
bb0: {
- StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
- _3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
- StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+ _20 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
- _4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
- StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+ _15 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
- _5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
- StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+ _11 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
- _6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
- StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
+ _24 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
_9 = &_3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
_11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
_10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
_29 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
_30 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- _11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- _29 = deref_copy _3; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+ _29 = deref_copy _20; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
_30 = deref_copy _11; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
_31 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
@ -111,7 +128,8 @@
_8 = Le(move _31, move _32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_32); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_31); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
@ -127,13 +145,14 @@
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
StorageLive(_17); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
_18 = &_5; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
_20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
_19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
_33 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
_34 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- _20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- _33 = deref_copy _5; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+ _33 = deref_copy _11; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
_34 = deref_copy _20; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
_35 = (*_33); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
@ -141,7 +160,8 @@
_17 = Le(move _35, move _36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
@ -150,8 +170,16 @@
bb3: {
- StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
}
@ -166,13 +194,14 @@
- StorageLive(_12); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
_13 = &_6; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
_15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
_14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
_37 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
_38 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _37 = deref_copy _6; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ _37 = deref_copy _24; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
_38 = deref_copy _15; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_39); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
_39 = (*_37); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
@ -180,7 +209,8 @@
_12 = Le(move _39, move _40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_40); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_39); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _7 = move _12; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
@ -202,13 +232,14 @@
- StorageLive(_21); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
_22 = &_4; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_41 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
_42 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _41 = deref_copy _4; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ _41 = deref_copy _15; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
_42 = deref_copy _24; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_43); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
_43 = (*_41); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
@ -217,7 +248,8 @@
+ _0 = Le(move _43, move _44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_44); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_43); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
+ nop; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _16 = move _21; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76

View file

@ -0,0 +1,247 @@
- // MIR for `variant_a::{closure#0}` before ReferencePropagation
+ // MIR for `variant_a::{closure#0}` after ReferencePropagation
fn variant_a::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:8:25: 8:39], _2: &&(usize, usize, usize, usize)) -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:40: +0:40
let _3: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
let _4: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
let _5: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
let _6: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:56
let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:46
let mut _9: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:40: +0:41
let mut _10: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
let _11: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:45: +0:46
let mut _12: bool; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:56
let mut _13: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:50: +0:51
let mut _14: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
let _15: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:55: +0:56
let mut _16: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:76
let mut _17: bool; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:66
let mut _18: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:60: +0:61
let mut _19: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
let _20: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:65: +0:66
let mut _21: bool; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:76
let mut _22: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:70: +0:71
let mut _23: &&usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
let _24: &usize; // in scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
let mut _25: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
let mut _26: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
let mut _27: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
let mut _28: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:38
let mut _31: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _32: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _37: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _38: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _43: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _44: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _49: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _50: &usize; // in scope 0 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 1 {
debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:27: +0:28
debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:30: +0:31
debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:33: +0:34
debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:36: +0:37
scope 2 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:40: 8:46
debug self => _9; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _10; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _29: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _30: &usize; // in scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 3 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
debug self => _29; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _30; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _33: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _34: usize; // in scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
scope 4 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:60: 8:66
debug self => _18; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _19; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _35: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _36: &usize; // in scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 5 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
debug self => _35; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _36; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _39: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _40: usize; // in scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
scope 6 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:50: 8:56
debug self => _13; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _14; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _41: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _42: &usize; // in scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 7 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
debug self => _41; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _42; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _45: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _46: usize; // in scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
scope 8 (inlined cmp::impls::<impl PartialOrd for &usize>::le) { // at $DIR/slice_filter.rs:8:70: 8:76
debug self => _22; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _23; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _47: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _48: &usize; // in scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
scope 9 (inlined cmp::impls::<impl PartialOrd for usize>::le) { // at $SRC_DIR/core/src/cmp.rs:LL:COL
debug self => _47; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
debug other => _48; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _51: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
let mut _52: usize; // in scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
}
}
}
bb0: {
StorageLive(_3); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_25 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
_3 = &((*_25).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:27: +0:28
StorageLive(_4); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_26 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
_4 = &((*_26).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:30: +0:31
StorageLive(_5); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_27 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
_5 = &((*_27).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:33: +0:34
StorageLive(_6); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_28 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
_6 = &((*_28).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:36: +0:37
StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:46
StorageLive(_9); // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
_9 = &_3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:41
StorageLive(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
_11 = _5; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
_10 = &_11; // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
- _29 = deref_copy (*_9); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _30 = deref_copy (*_10); // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _29 = deref_copy _3; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _30 = deref_copy _11; // scope 2 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
_33 = (*_29); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
_34 = (*_30); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
_8 = Le(move _33, move _34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_34); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_33); // scope 3 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
StorageDead(_10); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
StorageDead(_9); // scope 1 at $DIR/slice_filter.rs:+0:45: +0:46
switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
}
bb1: {
_0 = const true; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
}
bb2: {
StorageLive(_16); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
StorageLive(_17); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:66
StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
_18 = &_5; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:61
StorageLive(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
StorageLive(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
_20 = _3; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
_19 = &_20; // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
- _35 = deref_copy (*_18); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _36 = deref_copy (*_19); // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _35 = deref_copy _5; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _36 = deref_copy _20; // scope 4 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
_39 = (*_35); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
_40 = (*_36); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
_17 = Le(move _39, move _40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_40); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_39); // scope 5 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_20); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
StorageDead(_19); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:65: +0:66
switchInt(move _17) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
}
bb3: {
StorageDead(_16); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_6); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_5); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_4); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_3); // scope 0 at $DIR/slice_filter.rs:+0:75: +0:76
return; // scope 0 at $DIR/slice_filter.rs:+0:76: +0:76
}
bb4: {
_7 = const false; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
}
bb5: {
StorageLive(_12); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:56
StorageLive(_13); // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
_13 = &_6; // scope 1 at $DIR/slice_filter.rs:+0:50: +0:51
StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
_15 = _4; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
_14 = &_15; // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
- _41 = deref_copy (*_13); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _42 = deref_copy (*_14); // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _41 = deref_copy _6; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _42 = deref_copy _15; // scope 6 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
_45 = (*_41); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
_46 = (*_42); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
_12 = Le(move _45, move _46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_46); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_45); // scope 7 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageDead(_13); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
_7 = move _12; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:56
StorageDead(_12); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:55: +0:56
switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
}
bb6: {
_16 = const false; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
}
bb7: {
StorageLive(_21); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:76
StorageLive(_22); // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
_22 = &_4; // scope 1 at $DIR/slice_filter.rs:+0:70: +0:71
StorageLive(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageLive(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_24 = _6; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_23 = &_24; // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
- _47 = deref_copy (*_22); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
- _48 = deref_copy (*_23); // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _47 = deref_copy _4; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
+ _48 = deref_copy _24; // scope 8 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
_51 = (*_47); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageLive(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
_52 = (*_48); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
_21 = Le(move _51, move _52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_52); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_51); // scope 9 at $SRC_DIR/core/src/cmp.rs:LL:COL
StorageDead(_24); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_23); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_22); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_16 = move _21; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:60: +0:76
}
bb8: {
StorageDead(_21); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
StorageDead(_17); // scope 1 at $DIR/slice_filter.rs:+0:75: +0:76
_0 = move _16; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:40: +0:76
}
}

View file

@ -0,0 +1,103 @@
- // MIR for `variant_b::{closure#0}` before ReferencePropagation
+ // MIR for `variant_b::{closure#0}` after ReferencePropagation
fn variant_b::{closure#0}(_1: &mut [closure@$DIR/slice_filter.rs:12:25: 12:41], _2: &&(usize, usize, usize, usize)) -> bool {
let mut _0: bool; // return place in scope 0 at $DIR/slice_filter.rs:+0:42: +0:42
let _3: usize; // in scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
let _4: usize; // in scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
let _5: usize; // in scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
let _6: usize; // in scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
let mut _7: bool; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:58
let mut _8: bool; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:48
let mut _9: usize; // in scope 0 at $DIR/slice_filter.rs:+0:42: +0:43
let mut _10: usize; // in scope 0 at $DIR/slice_filter.rs:+0:47: +0:48
let mut _11: bool; // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:58
let mut _12: usize; // in scope 0 at $DIR/slice_filter.rs:+0:52: +0:53
let mut _13: usize; // in scope 0 at $DIR/slice_filter.rs:+0:57: +0:58
let mut _14: bool; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:78
let mut _15: bool; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:68
let mut _16: usize; // in scope 0 at $DIR/slice_filter.rs:+0:62: +0:63
let mut _17: usize; // in scope 0 at $DIR/slice_filter.rs:+0:67: +0:68
let mut _18: bool; // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:78
let mut _19: usize; // in scope 0 at $DIR/slice_filter.rs:+0:72: +0:73
let mut _20: usize; // in scope 0 at $DIR/slice_filter.rs:+0:77: +0:78
let mut _21: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
let mut _22: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
let mut _23: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
let mut _24: &(usize, usize, usize, usize); // in scope 0 at $DIR/slice_filter.rs:+0:26: +0:40
scope 1 {
debug a => _3; // in scope 1 at $DIR/slice_filter.rs:+0:29: +0:30
debug b => _4; // in scope 1 at $DIR/slice_filter.rs:+0:32: +0:33
debug c => _5; // in scope 1 at $DIR/slice_filter.rs:+0:35: +0:36
debug d => _6; // in scope 1 at $DIR/slice_filter.rs:+0:38: +0:39
}
bb0: {
_21 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
_3 = ((*_21).0: usize); // scope 0 at $DIR/slice_filter.rs:+0:29: +0:30
_22 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
_4 = ((*_22).1: usize); // scope 0 at $DIR/slice_filter.rs:+0:32: +0:33
_23 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
_5 = ((*_23).2: usize); // scope 0 at $DIR/slice_filter.rs:+0:35: +0:36
_24 = deref_copy (*_2); // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
_6 = ((*_24).3: usize); // scope 0 at $DIR/slice_filter.rs:+0:38: +0:39
StorageLive(_7); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
StorageLive(_8); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
_8 = Le(_3, _5); // scope 1 at $DIR/slice_filter.rs:+0:42: +0:48
switchInt(move _8) -> [0: bb4, otherwise: bb5]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
}
bb1: {
_0 = const true; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
}
bb2: {
StorageLive(_14); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
StorageLive(_15); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
_15 = Le(_5, _3); // scope 1 at $DIR/slice_filter.rs:+0:62: +0:68
switchInt(move _15) -> [0: bb6, otherwise: bb7]; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
}
bb3: {
StorageDead(_14); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
StorageDead(_7); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
return; // scope 0 at $DIR/slice_filter.rs:+0:78: +0:78
}
bb4: {
_7 = const false; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
goto -> bb2; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
}
bb5: {
StorageLive(_11); // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
_11 = Le(_6, _4); // scope 1 at $DIR/slice_filter.rs:+0:52: +0:58
_7 = move _11; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:58
StorageDead(_11); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
StorageDead(_8); // scope 1 at $DIR/slice_filter.rs:+0:57: +0:58
switchInt(move _7) -> [0: bb2, otherwise: bb1]; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
}
bb6: {
_14 = const false; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
}
bb7: {
StorageLive(_18); // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
_18 = Le(_4, _6); // scope 1 at $DIR/slice_filter.rs:+0:72: +0:78
_14 = move _18; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
goto -> bb8; // scope 1 at $DIR/slice_filter.rs:+0:62: +0:78
}
bb8: {
StorageDead(_18); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
StorageDead(_15); // scope 1 at $DIR/slice_filter.rs:+0:77: +0:78
_0 = move _14; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
goto -> bb3; // scope 1 at $DIR/slice_filter.rs:+0:42: +0:78
}
}