From 196777074e44136414191ade69da671d6ed0c659 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Tue, 22 Jun 2021 13:44:59 +0200 Subject: [PATCH 1/2] squash_0 --- .../src/transform/trivial_copy_elimination.rs | 514 ++++++++++++++++++ .../inline_any_operand.bar.Inline.after.mir | 10 +- ...e_closure_borrows_arg.foo.Inline.after.mir | 2 +- .../issue_73223.main.PreCodegen.32bit.diff | 104 ++-- .../issue_73223.main.PreCodegen.64bit.diff | 104 ++-- .../simplify_locals.c.SimplifyLocals.diff | 2 +- ..._locals_fixedpoint.foo.SimplifyLocals.diff | 10 +- 7 files changed, 618 insertions(+), 128 deletions(-) create mode 100644 compiler/rustc_mir/src/transform/trivial_copy_elimination.rs diff --git a/compiler/rustc_mir/src/transform/trivial_copy_elimination.rs b/compiler/rustc_mir/src/transform/trivial_copy_elimination.rs new file mode 100644 index 0000000000000..6539fa1d4f3c1 --- /dev/null +++ b/compiler/rustc_mir/src/transform/trivial_copy_elimination.rs @@ -0,0 +1,514 @@ +//! A simple intra-block copy propagation pass. +//! +//! This pass performs simple forwards-propagation of locals that were assigned within the same MIR +//! block. This is a common pattern introduced by MIR building. + +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_index::bit_set::BitSet; +use rustc_middle::mir::visit::{ + MutVisitor, MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor, +}; +use rustc_middle::mir::{ + Body, Local, Location, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, +}; +use rustc_middle::ty::TyCtxt; +use smallvec::SmallVec; + +use super::MirPass; + +const MAX_LOCALS_FOR_PASS: usize = 400; +const MAX_STATEMENTS_PERE_BLOCK: usize = 400; +const AVERAGE_NUM_PATCHES: usize = 2; + +pub struct TrivialCopyElimination; + +impl<'tcx> MirPass<'tcx> for TrivialCopyElimination { + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + // if tcx.sess.mir_opt_level() < 2 { + // return; + // } + + let num_locals = body.local_decls.len(); + if num_locals > MAX_LOCALS_FOR_PASS { + return; + } + let mut locals = FxIndexMap::with_capacity_and_hasher(num_locals, Default::default()); + let mut sources = FxIndexMap::with_capacity_and_hasher(num_locals, Default::default()); + let mut patches = FxIndexMap::with_capacity_and_hasher(num_locals, Default::default()); + let mut selected_patches = + FxIndexMap::with_capacity_and_hasher(num_locals, Default::default()); + let mut patchable_locals = BitSet::new_empty(num_locals); + + for (block, block_data) in body.basic_blocks_mut().iter_enumerated_mut() { + if block_data.statements.len() > MAX_STATEMENTS_PERE_BLOCK { + continue; + } + let mut visitor = LocalStateCollector { + locals: &mut locals, + sources: &mut sources, + statement_idx: 0, + place_idx: 0, + patches: &mut patches, + }; + visitor.visit_basic_block_data(block, block_data); + + let LocalStateCollector { locals, sources, patches, .. } = visitor; + // now we need to identify interesting locals and place them into the patches + for (local, state) in locals.drain(..) { + let mut patches = + if let Some(patches) = patches.remove(&local) { patches } else { continue }; + if patches.is_empty() { + continue; + } + + let skip_last; + match state { + LocalState::Dead => { + skip_last = false; + } + LocalState::CopyIntoLive(.., gen) | LocalState::CopyUsed(.., gen) => { + if gen == 0 { + continue; + } + skip_last = true; + } + LocalState::MovedOut(gen) => { + if gen == 0 { + continue; + } + skip_last = false; + } + _ => continue, + } + if skip_last { + let _ = patches.pop(); + } + if patches.is_empty() { + continue; + } + patchable_locals.insert(local); + for (src, statement_idx, place_idx) in patches { + if selected_patches.contains_key(&(statement_idx, place_idx)) { + bug!( + "Already contains a patch for statement {} place {}", + statement_idx, + place_idx + ); + } + selected_patches.insert((statement_idx, place_idx), (local, src)); + } + } + assert!(locals.is_empty()); + assert!(patches.is_empty()); + sources.clear(); + + let mut visitor = Patcher { + tcx, + statement_idx: 0, + place_idx: 0, + patches: &mut selected_patches, + patchable_locals: &patchable_locals, + patched_move_just_yet: false, + }; + visitor.visit_basic_block_data(block, block_data); + + assert!(visitor.patches.is_empty()); + patchable_locals.clear(); + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] +enum LocalState<'tcx> { + NotInteresting, + Live, + CopyIntoLive(Option>, u16), + CopyUsed(Option>, u16), + MovedOut(u16), + Dead, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum Action<'tcx> { + CopyFrom(Option>), + CopyUse, + MoveUse, + Invalidate, + Dead, +} + +impl<'tcx> LocalState<'tcx> { + fn update(self, action: Action<'tcx>) -> Self { + match (self, action) { + // trivial case + (LocalState::Live, Action::Dead) => LocalState::Dead, + // we copy something in here + (LocalState::Live, Action::CopyFrom(src)) => LocalState::CopyIntoLive(src, 0), + // trivial replacement + (LocalState::CopyIntoLive(.., gen), Action::CopyFrom(src)) => { + LocalState::CopyIntoLive(src, gen + 1) + } + // actual use a freshly copied value + (LocalState::CopyIntoLive(src, gen), Action::CopyUse) => LocalState::CopyUsed(src, gen), + (LocalState::CopyIntoLive(.., gen), Action::MoveUse) => LocalState::MovedOut(gen), + // use already used value + (LocalState::CopyUsed(src, gen), Action::CopyUse) => LocalState::CopyUsed(src, gen), + // copy over + (LocalState::CopyUsed(.., gen) | LocalState::MovedOut(gen), Action::CopyFrom(src)) => { + LocalState::CopyIntoLive(src, gen + 1) + } + // dead when source was invalidated + ( + LocalState::CopyUsed(..) | LocalState::MovedOut(..) | LocalState::CopyIntoLive(..), + Action::Dead, + ) => LocalState::Dead, + // invalidations of invalid source + ( + LocalState::CopyIntoLive(.., gen) + | LocalState::CopyUsed(.., gen) + | LocalState::MovedOut(.., gen), + Action::Invalidate, + ) => LocalState::CopyIntoLive(None, gen), + _ => LocalState::NotInteresting, + } + } +} + +/// Determines whether `place` is an assignment source that may later be used instead of the local +/// it is assigned to. +/// +/// This is the case only for places that don't dereference pointers (since the dereference +/// operation may not be valid anymore after this point), and don't index a slice (since that uses +/// another local besides the base local, which would need additional tracking). +fn place_eligible(place: &Place<'_>) -> bool { + place.projection.iter().all(|elem| match elem { + ProjectionElem::Deref | ProjectionElem::Index(_) => false, + + ProjectionElem::Field(..) + | ProjectionElem::ConstantIndex { .. } + | ProjectionElem::Subslice { .. } + | ProjectionElem::Downcast(..) => true, + }) +} + +/// FSM on per-block locals and quasi-locals +/// that allows us to determinee if we want to patch it or not +struct LocalStateCollector<'a, 'tcx> { + locals: &'a mut FxIndexMap>, + sources: &'a mut FxIndexMap>, + statement_idx: u16, + place_idx: u16, + patches: &'a mut FxIndexMap, u16, u16); AVERAGE_NUM_PATCHES]>>, +} + +impl<'a, 'tcx> LocalStateCollector<'a, 'tcx> { + fn log_patch(&mut self, place: &Place<'tcx>) { + let local = if let Some(local) = place.local_or_deref_local() { local } else { return }; + if let Some(local_state) = self.locals.get(&local) { + match local_state { + LocalState::CopyIntoLive(Some(src), ..) | LocalState::CopyUsed(Some(src), ..) => { + let entry = self.patches.entry(local).or_default(); + entry.push((*src, self.statement_idx, self.place_idx)); + } + _ => {} + } + } + } + + fn progress(&mut self, local: Local, action: Action<'tcx>) { + if let Some(t) = self.locals.remove(&local) { + let new = t.update(action); + self.locals.insert(local, new); + } + + // if action is a copy into then keep track of sources + match action { + Action::CopyFrom(Some(src)) => { + // peek back into the locals. The generation here is already a new generation + if let Some(LocalState::CopyIntoLive(..)) = self.locals.get(&local) { + // get raw local from the src. If it's eligible it's Some in Action + let src_local = src.local; + let entries = self.sources.entry(src_local).or_insert(Default::default()); + entries.insert(local); + } + } + _ => {} + } + } + + fn make_live(&mut self, local: Local) { + if self.locals.contains_key(&local) { + bug!("We already considered this local as live or quasi-live in our context"); + } + let new = LocalState::Live; + self.locals.insert(local, new); + } + + fn invalidate_source_information(&mut self, local: Local) { + // if this local is some tracked source + if let Some(dests) = self.sources.remove(&local) { + // walk over destinations of this source ordered by generation + for dest in dests { + if let Some(state) = self.locals.get(&dest).copied() { + // only invalidate if it's for the last generation! + match state { + LocalState::CopyIntoLive(Some(src), ..) if src.local == local => { + self.progress(dest, Action::Invalidate); + } + LocalState::CopyUsed(Some(src), ..) if src.local == local => { + self.progress(dest, Action::Invalidate); + } + _ => {} + } + } + } + } + } + + fn make_dead(&mut self, local: Local) { + if let Some(t) = self.locals.remove(&local) { + let new = t.update(Action::Dead); + self.locals.insert(local, new); + } + + // we may need to update the source information too + // if source is dead we have to check if we currently track this source as a source for one of our + // locals of interest + self.invalidate_source_information(local); + } + + fn invalidate(&mut self, local: Local) { + if let Some(t) = self.locals.remove(&local) { + let new = t.update(Action::Invalidate); + self.locals.insert(local, new); + } + } +} + +impl<'a, 'tcx: 'a> Visitor<'tcx> for LocalStateCollector<'a, 'tcx> { + fn visit_local(&mut self, local: &Local, context: PlaceContext, _location: Location) { + // only edge case of storage live and dead that do not show up in "visit_place" + match context { + PlaceContext::NonUse(NonUseContext::StorageLive) => { + self.make_live(*local); + } + PlaceContext::NonUse(NonUseContext::StorageDead) => { + self.make_dead(*local); + } + _ => {} + } + } + + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { + self.super_place(place, context, location); + + let local = place.local; + let local_is_in_tracked_locals = self.locals.contains_key(&local); + let local_is_source = self.sources.contains_key(&local); + // otherwise we need auxilaty information, that will update a generation + // of disallow patches in a current generation + + match context { + PlaceContext::NonUse(NonUseContext::StorageLive) => { + // captured in visit local + unreachable!("Not visited as `place`"); + } + PlaceContext::NonUse(NonUseContext::StorageDead) => { + unreachable!("Not visited as `place`"); + } + PlaceContext::NonUse(..) => { + // should be ok + } + PlaceContext::MutatingUse(MutatingUseContext::Store) => { + // we know that is is not a copy into the local, + // so if it's copy into the source we invalidate + if local_is_source { + self.invalidate_source_information(local); + } + if local_is_in_tracked_locals { + // do nothing, we have captured this information already + } + } + PlaceContext::MutatingUse(..) => { + if local_is_source { + self.invalidate_source_information(local); + } + if local_is_in_tracked_locals { + self.invalidate(local); + } + } + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) => { + if local_is_source { + // ok + } + if local_is_in_tracked_locals { + // log first, as we need a current state + self.log_patch(place); + self.progress(local, Action::CopyUse); + } + } + PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => { + if local_is_source { + self.invalidate_source_information(local); + if local_is_in_tracked_locals { + self.invalidate(local); + } + } else if local_is_in_tracked_locals { + // log first, as we need a current state + self.log_patch(place); + self.progress(local, Action::MoveUse); + } + } + // PlaceContext::NonMutatingUse(..) => { + // if local_is_source { + // // ok + // } + // if local_is_in_tracked_locals { + // progress(self, local, Action::CopyUse); + // } + // }, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) => { + if local_is_source { + // ok + } + if local_is_in_tracked_locals { + // log first, as we need a current state + self.log_patch(place); + self.progress(local, Action::CopyUse); + } + } + PlaceContext::NonMutatingUse(..) => { + if local_is_source { + self.invalidate_source_information(local); + } + if local_is_in_tracked_locals { + self.invalidate(local); + } + } + } + + self.place_idx += 1; + } + + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + match &statement.kind { + StatementKind::Assign(box (place, rvalue)) => { + if let Some(local) = place.as_local() { + match rvalue { + Rvalue::Use(Operand::Copy(src)) => { + // we can NOT copy whatever we want into the local + let src = if place_eligible(src) { Some(*src) } else { None }; + if self.locals.get(&local).is_none() { + // even if our local is not yet seen due to not + // marker "live" in other places, + // we can still insert it here is quasi-live state + self.make_live(local); + } + self.progress(local, Action::CopyFrom(src)); + } + _ => { + // something else assigned to our local of interest, so + // we mark it as copy from non-source, so we bump a generation + if self.locals.contains_key(&local) { + self.progress(local, Action::CopyFrom(None)); + } + } + } + } + } + _ => {} + } + + // we visit super after we did capture some information + self.super_statement(statement, location); + + self.statement_idx += 1; + } +} + +struct Patcher<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + statement_idx: u16, + place_idx: u16, + patches: &'a mut FxIndexMap<(u16, u16), (Local, Place<'tcx>)>, + patchable_locals: &'a BitSet, + patched_move_just_yet: bool, +} + +impl<'a, 'tcx> Patcher<'a, 'tcx> { + fn apply_patch(&mut self, place: &mut Place<'tcx>) -> bool { + if self.patches.is_empty() { + return false; + } + let (local, add_deref) = if let Some(local) = place.as_local() { + (local, false) + } else if let Some(local) = place.local_or_deref_local() { + (local, true) + } else { + return false; + }; + if let Some((local_to_patch, patch_into_place)) = + self.patches.remove(&(self.statement_idx, self.place_idx)) + { + assert_eq!(local, local_to_patch); + + let source = if add_deref { + self.tcx.mk_place_deref(patch_into_place) + } else { + patch_into_place + }; + *place = source; + + return true; + } + + false + } +} + +impl<'a, 'tcx> MutVisitor<'tcx> for Patcher<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { + self.super_statement(statement, location); + self.statement_idx += 1; + } + + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { + self.super_operand(operand, location); + match operand { + Operand::Move(place) => { + if self.patched_move_just_yet { + *operand = Operand::Copy(*place); + self.patched_move_just_yet = false; + } + } + _ => {} + } + } + + fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, _location: Location) { + if !self.patchable_locals.contains(place.local) { + self.place_idx += 1; + return; + } + match context { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) => { + let _ = self.apply_patch(place); + } + PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => { + if self.apply_patch(place) { + self.patched_move_just_yet = true; + } + } + PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) => { + let _ = self.apply_patch(place); + } + _ => {} + } + + self.place_idx += 1; + } +} diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir index 815d02c73d1e2..da977c395c6dc 100644 --- a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir @@ -11,8 +11,6 @@ fn bar() -> bool { scope 2 (inlined foo) { // at $DIR/inline-any-operand.rs:12:5: 12:13 debug x => _3; // in scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 debug y => _4; // in scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - let mut _5: i32; // in scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - let mut _6: i32; // in scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 } } @@ -28,13 +26,7 @@ fn bar() -> bool { _3 = const 1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 StorageLive(_4); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 _4 = const -1_i32; // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageLive(_5); // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - _5 = _3; // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageLive(_6); // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - _6 = _4; // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - _0 = Eq(move _5, move _6); // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageDead(_6); // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 - StorageDead(_5); // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 + _0 = Eq(_3, _4); // scope 2 at $DIR/inline-any-operand.rs:12:5: 12:13 StorageDead(_4); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 StorageDead(_3); // scope 1 at $DIR/inline-any-operand.rs:12:5: 12:13 StorageDead(_2); // scope 1 at $DIR/inline-any-operand.rs:12:12: 12:13 diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir index 4bda9ae383c22..db504b416fe1d 100644 --- a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir @@ -40,7 +40,7 @@ fn foo(_1: T, _2: &i32) -> i32 { _9 = move (_5.1: &i32); // scope 1 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageLive(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 _10 = _8; // scope 2 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 - _0 = (*_10); // scope 3 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 + _0 = (*_8); // scope 3 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageDead(_10); // scope 2 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageDead(_9); // scope 1 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 StorageDead(_8); // scope 1 at $DIR/inline-closure-borrows-arg.rs:16:5: 16:12 diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff index 95a8ef997fa49..c45643b8a489b 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.32bit.diff @@ -6,32 +6,30 @@ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:2:9: 2:14 let mut _2: std::option::Option; // in scope 0 at $DIR/issue-73223.rs:2:23: 2:30 let _3: i32; // in scope 0 at $DIR/issue-73223.rs:3:14: 3:15 - let mut _5: i32; // in scope 0 at $DIR/issue-73223.rs:7:22: 7:27 - let mut _6: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _8: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _13: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _9: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _14: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _19: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _4: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 scope 3 { debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:7:9: 7:14 - let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _10: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _7: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _18: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 4 { - debug left_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug right_val => _10; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _14: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug left_val => _7; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _12: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 5 { - debug kind => _14; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug kind => _12; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } } } @@ -47,60 +45,54 @@ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30 StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 - _1 = _3; // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 + _1 = ((_2 as Some).0: i32); // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:5:6: 5:7 StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:7:9: 7:14 - StorageLive(_5); // scope 1 at $DIR/issue-73223.rs:7:22: 7:27 - _5 = _1; // scope 1 at $DIR/issue-73223.rs:7:22: 7:27 - ((_4 as Some).0: i32) = move _5; // scope 1 at $DIR/issue-73223.rs:7:17: 7:28 + ((_4 as Some).0: i32) = _1; // scope 1 at $DIR/issue-73223.rs:7:17: 7:28 discriminant(_4) = 1; // scope 1 at $DIR/issue-73223.rs:7:17: 7:28 - StorageDead(_5); // scope 1 at $DIR/issue-73223.rs:7:27: 7:28 + StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _7 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } - _8 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_6.0: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_6.1: &i32) = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _9 = (_6.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _10 = (_6.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.1: &i32) = _18; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _7 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _13 = (*_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _12 = Eq(move _13, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _11 = Not(move _12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _11) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = (*_7); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = Eq(move _11, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = Not(move _10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _9) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb1: { - StorageLive(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_14) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_12) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = _7; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _16 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _18 = _10; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_17) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _13, move _15, move _17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, std::option::Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } @@ -113,10 +105,10 @@ } bb2: { - StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:9:1: 9:2 StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:9:1: 9:2 return; // scope 0 at $DIR/issue-73223.rs:9:2: 9:2 diff --git a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff index 95a8ef997fa49..c45643b8a489b 100644 --- a/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff +++ b/src/test/mir-opt/issue_73223.main.PreCodegen.64bit.diff @@ -6,32 +6,30 @@ let _1: i32; // in scope 0 at $DIR/issue-73223.rs:2:9: 2:14 let mut _2: std::option::Option; // in scope 0 at $DIR/issue-73223.rs:2:23: 2:30 let _3: i32; // in scope 0 at $DIR/issue-73223.rs:3:14: 3:15 - let mut _5: i32; // in scope 0 at $DIR/issue-73223.rs:7:22: 7:27 - let mut _6: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _8: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _13: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _5: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _6: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _9: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _10: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _14: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _15: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let _16: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _17: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _19: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: std::option::Option; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue-73223.rs:2:9: 2:14 let _4: std::option::Option; // in scope 1 at $DIR/issue-73223.rs:7:9: 7:14 scope 3 { debug _prev => _4; // in scope 3 at $DIR/issue-73223.rs:7:9: 7:14 - let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _10: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _20: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _7: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _8: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _18: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 4 { - debug left_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug right_val => _10; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _14: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug left_val => _7; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _8; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _12: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 5 { - debug kind => _14; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug kind => _12; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } } } @@ -47,60 +45,54 @@ discriminant(_2) = 1; // scope 0 at $DIR/issue-73223.rs:2:23: 2:30 StorageLive(_3); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 _3 = ((_2 as Some).0: i32); // scope 0 at $DIR/issue-73223.rs:3:14: 3:15 - _1 = _3; // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 + _1 = ((_2 as Some).0: i32); // scope 2 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_3); // scope 0 at $DIR/issue-73223.rs:3:20: 3:21 StorageDead(_2); // scope 0 at $DIR/issue-73223.rs:5:6: 5:7 StorageLive(_4); // scope 1 at $DIR/issue-73223.rs:7:9: 7:14 - StorageLive(_5); // scope 1 at $DIR/issue-73223.rs:7:22: 7:27 - _5 = _1; // scope 1 at $DIR/issue-73223.rs:7:22: 7:27 - ((_4 as Some).0: i32) = move _5; // scope 1 at $DIR/issue-73223.rs:7:17: 7:28 + ((_4 as Some).0: i32) = _1; // scope 1 at $DIR/issue-73223.rs:7:17: 7:28 discriminant(_4) = 1; // scope 1 at $DIR/issue-73223.rs:7:17: 7:28 - StorageDead(_5); // scope 1 at $DIR/issue-73223.rs:7:27: 7:28 + StorageLive(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _7 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _20 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _6 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = const main::promoted[0]; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // ty::Const // + ty: &i32 // + val: Unevaluated(main, [], Some(promoted[0])) // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(Unevaluated { def: WithOptConstParam { did: DefId(0:3 ~ issue_73223[317d]::main), const_param_did: None }, substs: [], promoted: Some(promoted[0]) }) } - _8 = _20; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_6.0: &i32) = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - (_6.1: &i32) = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _9 = (_6.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _10 = (_6.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.0: &i32) = move _6; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + (_5.1: &i32) = _18; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _7 = (_5.0: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = (_5.1: &i32); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _13 = (*_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _12 = Eq(move _13, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _11 = Not(move _12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _11) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = (*_7); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = Eq(move _11, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = Not(move _10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_10); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _9) -> [false: bb2, otherwise: bb1]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb1: { - StorageLive(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_14) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_12) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = _7; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_15); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _16 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = _8; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _15 = _16; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _18 = _10; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _17 = _18; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_19) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _15, move _17, move _19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_17) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _13, move _15, move _17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'r, 's, 't0> fn(core::panicking::AssertKind, &'r i32, &'s i32, std::option::Option>) -> ! {core::panicking::assert_failed::}, val: Value(Scalar()) } @@ -113,10 +105,10 @@ } bb2: { - StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_6); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_5); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_4); // scope 1 at $DIR/issue-73223.rs:9:1: 9:2 StorageDead(_1); // scope 0 at $DIR/issue-73223.rs:9:1: 9:2 return; // scope 0 at $DIR/issue-73223.rs:9:2: 9:2 diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff index 2995d1e86e3bf..4806e2de24b6b 100644 --- a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff @@ -21,7 +21,7 @@ - StorageLive(_4); // scope 1 at $DIR/simplify-locals.rs:16:20: 16:26 - _4 = &_1; // scope 1 at $DIR/simplify-locals.rs:16:20: 16:26 - _3 = _4; // scope 1 at $DIR/simplify-locals.rs:16:20: 16:26 -- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify-locals.rs:16:20: 16:26 +- _2 = _4 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify-locals.rs:16:20: 16:26 - StorageDead(_3); // scope 1 at $DIR/simplify-locals.rs:16:25: 16:26 - StorageDead(_4); // scope 1 at $DIR/simplify-locals.rs:16:26: 16:27 - StorageDead(_2); // scope 1 at $DIR/simplify-locals.rs:16:26: 16:27 diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff index 70725e5f14f7d..a7cf36c2d2469 100644 --- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff @@ -10,7 +10,7 @@ let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:13: 4:20 let _6: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 - let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 +- let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 scope 1 { debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 } @@ -43,10 +43,10 @@ StorageLive(_6); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 StorageLive(_7); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 - StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 - _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 - _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 - StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20 +- StorageLive(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 +- _8 = _6; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 + _7 = Gt(_6, const 42_u8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 +- StorageDead(_8); // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20 switchInt(move _7) -> [false: bb5, otherwise: bb4]; // scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 } From f9c6cc95c5613dc4fddbae8bd1c913270149334f Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Tue, 22 Jun 2021 14:13:25 +0200 Subject: [PATCH 2/2] end squash/rebase --- compiler/rustc_mir/src/transform/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 5c201594ddd89..a933702c4a6a3 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -52,6 +52,7 @@ pub mod simplify; pub mod simplify_branches; pub mod simplify_comparison_integral; pub mod simplify_try; +pub mod trivial_copy_elimination; pub mod uninhabited_enum_branching; pub mod unreachable_prop; pub mod validate; @@ -513,6 +514,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &simplify::SimplifyCfg::new("final"), &nrvo::RenameReturnPlace, &const_debuginfo::ConstDebugInfo, + &trivial_copy_elimination::TrivialCopyElimination, &simplify::SimplifyLocals, &multiple_return_terminators::MultipleReturnTerminators, &deduplicate_blocks::DeduplicateBlocks,