mir-opt: Eliminate dead statements even if they are used by debuginfos
This commit is contained in:
@@ -155,6 +155,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
self.debug_poison_to_local(bx, *dest);
|
||||
}
|
||||
}
|
||||
StmtDebugInfo::InvalidAssign(local) => {
|
||||
self.debug_poison_to_local(bx, *local);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -844,6 +844,9 @@ impl Debug for StmtDebugInfo<'_> {
|
||||
StmtDebugInfo::AssignRef(local, place) => {
|
||||
write!(fmt, "{local:?} = &{place:?}")
|
||||
}
|
||||
StmtDebugInfo::InvalidAssign(local) => {
|
||||
write!(fmt, "{local:?} = &?")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,6 +527,20 @@ impl<'tcx> PlaceRef<'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Return the place accessed locals that include the base local.
|
||||
pub fn accessed_locals(self) -> impl Iterator<Item = Local> {
|
||||
std::iter::once(self.local).chain(self.projection.iter().filter_map(|proj| match proj {
|
||||
ProjectionElem::Index(local) => Some(*local),
|
||||
ProjectionElem::Deref
|
||||
| ProjectionElem::Field(_, _)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Downcast(_, _)
|
||||
| ProjectionElem::OpaqueCast(_)
|
||||
| ProjectionElem::UnwrapUnsafeBinder(_) => None,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Generates a new place by appending `more_projections` to the existing ones
|
||||
/// and interning the result.
|
||||
pub fn project_deeper(
|
||||
@@ -1057,4 +1071,5 @@ impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> {
|
||||
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub enum StmtDebugInfo<'tcx> {
|
||||
AssignRef(Local, Place<'tcx>),
|
||||
InvalidAssign(Local),
|
||||
}
|
||||
|
||||
@@ -406,6 +406,13 @@ macro_rules! make_mir_visitor {
|
||||
location
|
||||
);
|
||||
},
|
||||
StmtDebugInfo::InvalidAssign(local) => {
|
||||
self.visit_local(
|
||||
$(& $mutability)? *local,
|
||||
PlaceContext::NonUse(NonUseContext::VarDebugInfo),
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,16 +5,16 @@ use rustc_middle::mir::*;
|
||||
/// Return the set of locals that appear in debuginfo.
|
||||
pub fn debuginfo_locals(body: &Body<'_>) -> DenseBitSet<Local> {
|
||||
let mut visitor = DebuginfoLocals(DenseBitSet::new_empty(body.local_decls.len()));
|
||||
visitor.visit_body(body);
|
||||
for debuginfo in body.var_debug_info.iter() {
|
||||
visitor.visit_var_debug_info(debuginfo);
|
||||
}
|
||||
visitor.0
|
||||
}
|
||||
|
||||
struct DebuginfoLocals(DenseBitSet<Local>);
|
||||
|
||||
impl Visitor<'_> for DebuginfoLocals {
|
||||
fn visit_local(&mut self, local: Local, place_context: PlaceContext, _: Location) {
|
||||
if place_context == PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
|
||||
self.0.insert(local);
|
||||
}
|
||||
fn visit_local(&mut self, local: Local, _: PlaceContext, _: Location) {
|
||||
self.0.insert(local);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +287,6 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
||||
if let Some(destination) =
|
||||
Self::can_be_removed_if_dead(&statement.kind, &self.always_live, &self.debuginfo_locals)
|
||||
&& !state.contains(destination.local)
|
||||
// FIXME: We can eliminate the statement, but we'll need the statements it depends on
|
||||
// for debuginfos. We need a way to handle this.
|
||||
&& !self.debuginfo_locals.contains(destination.local)
|
||||
{
|
||||
// This store is dead
|
||||
return;
|
||||
|
||||
@@ -657,6 +657,22 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_statement_debuginfo(
|
||||
&mut self,
|
||||
stmt_debuginfo: &mut StmtDebugInfo<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
match stmt_debuginfo {
|
||||
StmtDebugInfo::AssignRef(local, place) => {
|
||||
if place.as_ref().accessed_locals().any(|local| self.map[local].is_none()) {
|
||||
*stmt_debuginfo = StmtDebugInfo::InvalidAssign(*local);
|
||||
}
|
||||
}
|
||||
StmtDebugInfo::InvalidAssign(_) => {}
|
||||
}
|
||||
self.super_statement_debuginfo(stmt_debuginfo, location);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
|
||||
*l = self.map[*l].unwrap();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_mir_dataflow::debuginfo::debuginfo_locals;
|
||||
use rustc_session::config::MirStripDebugInfo;
|
||||
|
||||
/// Conditionally remove some of the VarDebugInfo in MIR.
|
||||
@@ -30,6 +31,22 @@ impl<'tcx> crate::MirPass<'tcx> for StripDebugInfo {
|
||||
if place.local.as_usize() <= body.arg_count && place.local != RETURN_PLACE,
|
||||
)
|
||||
});
|
||||
|
||||
let debuginfo_locals = debuginfo_locals(body);
|
||||
for data in body.basic_blocks.as_mut_preserves_cfg() {
|
||||
for stmt in data.statements.iter_mut() {
|
||||
stmt.debuginfos.retain(|debuginfo| match debuginfo {
|
||||
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
|
||||
debuginfo_locals.contains(*local)
|
||||
}
|
||||
});
|
||||
}
|
||||
data.after_last_stmt_debuginfos.retain(|debuginfo| match debuginfo {
|
||||
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
|
||||
debuginfo_locals.contains(*local)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn is_required(&self) -> bool {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//@ compile-flags: -Copt-level=3 -g -Zverify-llvm-ir
|
||||
//@ compile-flags: -Copt-level=3 -g -Zverify-llvm-ir -Zmerge-functions=disabled
|
||||
//@ revisions: CODEGEN OPTIMIZED
|
||||
//@[CODEGEN] compile-flags: -Cno-prepopulate-passes
|
||||
// ignore-tidy-linelength
|
||||
@@ -9,6 +9,13 @@
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Foo(i32, i64, i32);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Bar<'a> {
|
||||
a: i32,
|
||||
b: i64,
|
||||
foo: &'a Foo,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn r#ref(ref_foo: &Foo) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}} i32 @ref
|
||||
@@ -78,11 +85,20 @@ pub fn fragment(fragment_v1: Foo, mut fragment_v2: Foo) -> Foo {
|
||||
fragment_v2
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn deref(bar: Bar) -> i32 {
|
||||
// CHECK-LABEL: define {{.*}} i32 @deref
|
||||
// We are unable to represent dereference within this expression.
|
||||
// CHECK: #dbg_value(ptr poison, [[VAR_deref_dead:![0-9]+]], !DIExpression()
|
||||
let deref_dead = &bar.foo.2;
|
||||
bar.a
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn tuple(foo: (i32, &Foo)) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}} i32 @tuple
|
||||
// CHECK-SAME: (i32 {{.*}}, ptr {{.*}} [[ARG_tuple_foo_1:%.*]])
|
||||
// CHECK: #dbg_value(ptr [[ARG_tuple_foo_1]], [[VAR_tuple_dead:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value)
|
||||
// Although there is no dereference here, there is a dereference in the MIR.
|
||||
// CHECK: #dbg_value(ptr poison, [[VAR_tuple_dead:![0-9]+]], !DIExpression()
|
||||
let tuple_dead = &foo.1.2;
|
||||
foo.1.0
|
||||
}
|
||||
@@ -148,6 +164,7 @@ pub fn non_arg_ref(scalar: i32, foo: Foo, a: &i32) -> i32 {
|
||||
// CHECK-DAG: [[VAR_ptr_v2]] = !DILocalVariable(name: "ptr_v2"
|
||||
// CODEGEN-DAG: [[VAR_val_ref]] = !DILocalVariable(name: "val_ref"
|
||||
// CHECK-DAG: [[VAR_fragment_f]] = !DILocalVariable(name: "fragment_f"
|
||||
// CHECK-DAG: [[VAR_deref_dead]] = !DILocalVariable(name: "deref_dead"
|
||||
// CHECK-DAG: [[VAR_tuple_dead]] = !DILocalVariable(name: "tuple_dead"
|
||||
// CHECK-DAG: [[ARG_dead_first_foo]] = !DILocalVariable(name: "dead_first_foo"
|
||||
// CHECK-DAG: [[VAR_dead_first_v0]] = !DILocalVariable(name: "dead_first_v0"
|
||||
|
||||
@@ -11,9 +11,7 @@ pub fn tuple(v: (i32, &Foo)) -> i32 {
|
||||
// CHECK-LABEL: fn tuple
|
||||
// CHECK: debug _dead => [[dead:_[0-9]+]];
|
||||
// CHECK: bb0:
|
||||
// FIXME: Preserve `tmp` for debuginfo, but we can merge it into the debuginfo.
|
||||
// CHECK: [[tmp:_[0-9]+]] = deref_copy (_1.1: &Foo);
|
||||
// CHECK-NEXT: DBG: [[dead]] = &((*[[tmp]]).2: i32)
|
||||
// CHECK: DBG: [[dead]] = &((*_3).2: i32)
|
||||
let _dead = &v.1.c;
|
||||
v.1.a
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
bb0: {
|
||||
- StorageLive(_2);
|
||||
_3 = deref_copy (_1.1: &Foo);
|
||||
- _3 = deref_copy (_1.1: &Foo);
|
||||
- _2 = &((*_3).2: i32);
|
||||
+ // DBG: _2 = &((*_3).2: i32);
|
||||
_4 = deref_copy (_1.1: &Foo);
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
+ let mut _9: *mut A;
|
||||
+ let mut _10: usize;
|
||||
+ scope 3 (inlined Vec::<A>::as_mut_ptr) {
|
||||
+ let mut _11: &alloc::raw_vec::RawVec<A>;
|
||||
+ scope 4 (inlined alloc::raw_vec::RawVec::<A>::ptr) {
|
||||
+ let mut _12: &alloc::raw_vec::RawVecInner;
|
||||
+ scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<A>) {
|
||||
+ scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<A>) {
|
||||
+ let mut _13: std::ptr::NonNull<u8>;
|
||||
+ let mut _11: std::ptr::NonNull<u8>;
|
||||
+ scope 7 (inlined Unique::<u8>::cast::<A>) {
|
||||
+ scope 8 (inlined NonNull::<u8>::cast::<A>) {
|
||||
+ scope 9 (inlined NonNull::<u8>::as_ptr) {
|
||||
@@ -41,15 +39,15 @@
|
||||
+ }
|
||||
+ }
|
||||
+ scope 14 (inlined drop_in_place::<[A]> - shim(Some([A]))) {
|
||||
+ let mut _14: usize;
|
||||
+ let mut _15: *mut A;
|
||||
+ let mut _16: bool;
|
||||
+ let mut _12: usize;
|
||||
+ let mut _13: *mut A;
|
||||
+ let mut _14: bool;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ scope 15 (inlined drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
|
||||
+ let mut _17: isize;
|
||||
+ let mut _18: isize;
|
||||
+ let mut _15: isize;
|
||||
+ let mut _16: isize;
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
@@ -64,20 +62,16 @@
|
||||
+ StorageLive(_8);
|
||||
+ StorageLive(_9);
|
||||
+ StorageLive(_11);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ _13 = copy (((((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
+ _9 = copy _13 as *mut A (Transmute);
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ _11 = copy (((((*_6).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
+ _9 = copy _11 as *mut A (Transmute);
|
||||
+ StorageDead(_11);
|
||||
+ _10 = copy ((*_6).1: usize);
|
||||
+ _8 = *mut [A] from (copy _9, copy _10);
|
||||
+ StorageDead(_9);
|
||||
+ StorageLive(_12);
|
||||
+ StorageLive(_13);
|
||||
+ StorageLive(_14);
|
||||
+ StorageLive(_15);
|
||||
+ StorageLive(_16);
|
||||
+ _14 = const 0_usize;
|
||||
+ _12 = const 0_usize;
|
||||
+ goto -> bb4;
|
||||
}
|
||||
|
||||
@@ -89,33 +83,33 @@
|
||||
StorageLive(_5);
|
||||
_5 = copy _2;
|
||||
- _0 = drop_in_place::<Option<B>>(move _5) -> [return: bb2, unwind unreachable];
|
||||
+ StorageLive(_17);
|
||||
+ _17 = discriminant((*_5));
|
||||
+ switchInt(move _17) -> [0: bb5, otherwise: bb6];
|
||||
+ StorageLive(_15);
|
||||
+ _15 = discriminant((*_5));
|
||||
+ switchInt(move _15) -> [0: bb5, otherwise: bb6];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
+ StorageDead(_16);
|
||||
+ StorageDead(_15);
|
||||
+ StorageDead(_14);
|
||||
+ StorageDead(_13);
|
||||
+ StorageDead(_12);
|
||||
+ StorageDead(_8);
|
||||
+ StorageDead(_10);
|
||||
+ drop(((*_4).0: alloc::raw_vec::RawVec<A>)) -> [return: bb1, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ _15 = &raw mut (*_8)[_14];
|
||||
+ _14 = Add(move _14, const 1_usize);
|
||||
+ drop((*_15)) -> [return: bb4, unwind unreachable];
|
||||
+ _13 = &raw mut (*_8)[_12];
|
||||
+ _12 = Add(move _12, const 1_usize);
|
||||
+ drop((*_13)) -> [return: bb4, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb4: {
|
||||
+ _16 = Eq(copy _14, copy _10);
|
||||
+ switchInt(move _16) -> [0: bb3, otherwise: bb2];
|
||||
+ _14 = Eq(copy _12, copy _10);
|
||||
+ switchInt(move _14) -> [0: bb3, otherwise: bb2];
|
||||
+ }
|
||||
+
|
||||
+ bb5: {
|
||||
+ StorageDead(_17);
|
||||
+ StorageDead(_15);
|
||||
StorageDead(_5);
|
||||
return;
|
||||
+ }
|
||||
|
||||
@@ -220,16 +220,12 @@
|
||||
+ StorageLive(_49);
|
||||
+ StorageLive(_41);
|
||||
+ StorageLive(_42);
|
||||
+ StorageLive(_43);
|
||||
+ StorageLive(_46);
|
||||
+ _44 = copy (_19.0: &mut std::future::Ready<()>);
|
||||
+ StorageDead(_46);
|
||||
+ StorageLive(_47);
|
||||
+ _47 = Option::<()>::None;
|
||||
+ _42 = copy ((*_44).0: std::option::Option<()>);
|
||||
+ ((*_44).0: std::option::Option<()>) = copy _47;
|
||||
+ StorageDead(_47);
|
||||
+ StorageDead(_43);
|
||||
+ StorageLive(_48);
|
||||
+ _48 = discriminant(_42);
|
||||
+ switchInt(move _48) -> [0: bb11, 1: bb12, otherwise: bb5];
|
||||
|
||||
@@ -237,16 +237,12 @@
|
||||
+ StorageLive(_51);
|
||||
+ StorageLive(_43);
|
||||
+ StorageLive(_44);
|
||||
+ StorageLive(_45);
|
||||
+ StorageLive(_48);
|
||||
+ _46 = copy (_19.0: &mut std::future::Ready<()>);
|
||||
+ StorageDead(_48);
|
||||
+ StorageLive(_49);
|
||||
+ _49 = Option::<()>::None;
|
||||
+ _44 = copy ((*_46).0: std::option::Option<()>);
|
||||
+ ((*_46).0: std::option::Option<()>) = copy _49;
|
||||
+ StorageDead(_49);
|
||||
+ StorageDead(_45);
|
||||
+ StorageLive(_50);
|
||||
+ _50 = discriminant(_44);
|
||||
+ switchInt(move _50) -> [0: bb16, 1: bb17, otherwise: bb7];
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// MIR for `invalid_place` after PreCodegen
|
||||
|
||||
fn invalid_place(_1: bool) -> bool {
|
||||
debug c1_ref => _2;
|
||||
let mut _0: bool;
|
||||
let mut _2: &bool;
|
||||
|
||||
bb0: {
|
||||
// DBG: _2 = &?;
|
||||
_0 = copy _1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
27
tests/mir-opt/pre-codegen/dead_on_invalid_place.rs
Normal file
27
tests/mir-opt/pre-codegen/dead_on_invalid_place.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
#![feature(core_intrinsics, custom_mir)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::intrinsics::mir::*;
|
||||
|
||||
// EMIT_MIR dead_on_invalid_place.invalid_place.PreCodegen.after.mir
|
||||
#[custom_mir(dialect = "runtime")]
|
||||
pub fn invalid_place(c: bool) -> bool {
|
||||
// CHECK-LABEL: fn invalid_place
|
||||
// CHECK: debug c1_ref => [[c1_ref:_[0-9]+]];
|
||||
// CHECK: bb0: {
|
||||
// We cannot read the reference, since `c1` is dead.
|
||||
// CHECK-NEXT: DBG: [[c1_ref]] = &?
|
||||
// CHECK-NEXT: _0 = copy _1;
|
||||
// CHECK-NEXT: return;
|
||||
mir! {
|
||||
let _c1_ref: &bool;
|
||||
let c1: bool;
|
||||
debug c1_ref => _c1_ref;
|
||||
{
|
||||
c1 = c;
|
||||
_c1_ref = &c1;
|
||||
RET = c;
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,11 +56,11 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
|
||||
scope 40 (inlined alloc::raw_vec::RawVec::<impl Sized>::capacity) {
|
||||
debug self => _37;
|
||||
let mut _19: usize;
|
||||
let mut _42: &alloc::raw_vec::RawVecInner;
|
||||
let mut _39: &alloc::raw_vec::RawVecInner;
|
||||
scope 41 (inlined std::mem::size_of::<impl Sized>) {
|
||||
}
|
||||
scope 42 (inlined alloc::raw_vec::RawVecInner::capacity) {
|
||||
debug self => _42;
|
||||
debug self => _39;
|
||||
debug elem_size => _19;
|
||||
let mut _21: core::num::niche_types::UsizeNoHighBit;
|
||||
scope 43 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) {
|
||||
@@ -130,7 +130,6 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
|
||||
}
|
||||
scope 18 (inlined alloc::raw_vec::RawVec::<impl Sized>::non_null) {
|
||||
debug self => _31;
|
||||
let mut _41: &alloc::raw_vec::RawVecInner;
|
||||
scope 19 (inlined alloc::raw_vec::RawVecInner::non_null::<impl Sized>) {
|
||||
let mut _4: std::ptr::NonNull<u8>;
|
||||
scope 20 (inlined Unique::<u8>::cast::<impl Sized>) {
|
||||
@@ -150,9 +149,7 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
|
||||
}
|
||||
scope 12 (inlined Vec::<impl Sized>::allocator) {
|
||||
debug self => _29;
|
||||
let mut _39: &alloc::raw_vec::RawVec<impl Sized>;
|
||||
scope 13 (inlined alloc::raw_vec::RawVec::<impl Sized>::allocator) {
|
||||
let mut _40: &alloc::raw_vec::RawVecInner;
|
||||
scope 14 (inlined alloc::raw_vec::RawVecInner::allocator) {
|
||||
}
|
||||
}
|
||||
@@ -183,13 +180,10 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
|
||||
StorageLive(_3);
|
||||
// DBG: _30 = &_2;
|
||||
// DBG: _29 = &(_2.0: std::vec::Vec<impl Sized>);
|
||||
// DBG: _39 = &((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>);
|
||||
// DBG: _40 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
|
||||
_3 = &raw const ((((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global);
|
||||
StorageDead(_3);
|
||||
// DBG: _32 = &_2;
|
||||
// DBG: _31 = &((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>);
|
||||
// DBG: _41 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
|
||||
_4 = copy (((((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
_5 = copy _4 as *const impl Sized (Transmute);
|
||||
_6 = NonNull::<impl Sized> { pointer: copy _5 };
|
||||
@@ -247,7 +241,7 @@ fn vec_move(_1: Vec<impl Sized>) -> () {
|
||||
bb4: {
|
||||
// DBG: _38 = &_2;
|
||||
// DBG: _37 = &((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>);
|
||||
// DBG: _42 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
|
||||
// DBG: _39 = &(((_2.0: std::vec::Vec<impl Sized>).0: alloc::raw_vec::RawVec<impl Sized>).0: alloc::raw_vec::RawVecInner);
|
||||
StorageLive(_19);
|
||||
_19 = SizeOf(impl Sized);
|
||||
switchInt(move _19) -> [0: bb5, otherwise: bb6];
|
||||
|
||||
@@ -71,21 +71,17 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
|
||||
// DBG: _16 = &((*_3).3: usize);
|
||||
StorageLive(_6);
|
||||
// DBG: _17 = &_13;
|
||||
// DBG: _18 = &_15;
|
||||
// DBG: _18 = &?;
|
||||
_4 = copy ((*_3).0: usize);
|
||||
_5 = copy ((*_3).2: usize);
|
||||
_6 = Le(copy _4, copy _5);
|
||||
switchInt(move _6) -> [0: bb1, otherwise: bb2];
|
||||
switchInt(move _6) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
goto -> bb4;
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_9);
|
||||
// DBG: _19 = &_16;
|
||||
// DBG: _20 = &_14;
|
||||
// DBG: _20 = &?;
|
||||
StorageLive(_7);
|
||||
_7 = copy ((*_3).3: usize);
|
||||
StorageLive(_8);
|
||||
@@ -93,29 +89,25 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
|
||||
_9 = Le(move _7, move _8);
|
||||
StorageDead(_8);
|
||||
StorageDead(_7);
|
||||
switchInt(move _9) -> [0: bb3, otherwise: bb8];
|
||||
switchInt(move _9) -> [0: bb2, otherwise: bb6];
|
||||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_10);
|
||||
// DBG: _21 = &_15;
|
||||
// DBG: _22 = &?;
|
||||
_10 = Le(copy _5, copy _4);
|
||||
switchInt(move _10) -> [0: bb3, otherwise: bb4];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
goto -> bb4;
|
||||
_0 = const false;
|
||||
goto -> bb5;
|
||||
}
|
||||
|
||||
bb4: {
|
||||
StorageLive(_10);
|
||||
// DBG: _21 = &_15;
|
||||
// DBG: _22 = &_13;
|
||||
_10 = Le(copy _5, copy _4);
|
||||
switchInt(move _10) -> [0: bb5, otherwise: bb6];
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_0 = const false;
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
// DBG: _23 = &_14;
|
||||
// DBG: _24 = &_16;
|
||||
// DBG: _24 = &?;
|
||||
StorageLive(_11);
|
||||
_11 = copy ((*_3).1: usize);
|
||||
StorageLive(_12);
|
||||
@@ -123,20 +115,20 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
|
||||
_0 = Le(move _11, move _12);
|
||||
StorageDead(_12);
|
||||
StorageDead(_11);
|
||||
goto -> bb5;
|
||||
}
|
||||
|
||||
bb5: {
|
||||
StorageDead(_10);
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
bb6: {
|
||||
_0 = const true;
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
bb7: {
|
||||
StorageDead(_10);
|
||||
goto -> bb9;
|
||||
}
|
||||
|
||||
bb8: {
|
||||
_0 = const true;
|
||||
goto -> bb9;
|
||||
}
|
||||
|
||||
bb9: {
|
||||
StorageDead(_9);
|
||||
StorageDead(_6);
|
||||
return;
|
||||
|
||||
@@ -11,9 +11,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
||||
let mut _4: usize;
|
||||
scope 3 (inlined Vec::<u8>::as_ptr) {
|
||||
debug self => _1;
|
||||
let mut _6: &alloc::raw_vec::RawVec<u8>;
|
||||
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
|
||||
let mut _7: &alloc::raw_vec::RawVecInner;
|
||||
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
|
||||
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
|
||||
let mut _2: std::ptr::NonNull<u8>;
|
||||
@@ -57,14 +55,8 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_6);
|
||||
// DBG: _6 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
|
||||
StorageLive(_7);
|
||||
// DBG: _7 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
|
||||
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
StorageDead(_7);
|
||||
_3 = copy _2 as *const u8 (Transmute);
|
||||
StorageDead(_6);
|
||||
StorageLive(_4);
|
||||
_4 = copy ((*_1).1: usize);
|
||||
StorageLive(_5);
|
||||
|
||||
@@ -11,9 +11,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
||||
let mut _4: usize;
|
||||
scope 3 (inlined Vec::<u8>::as_ptr) {
|
||||
debug self => _1;
|
||||
let mut _6: &alloc::raw_vec::RawVec<u8>;
|
||||
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
|
||||
let mut _7: &alloc::raw_vec::RawVecInner;
|
||||
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
|
||||
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
|
||||
let mut _2: std::ptr::NonNull<u8>;
|
||||
@@ -57,14 +55,8 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
StorageLive(_6);
|
||||
// DBG: _6 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
|
||||
StorageLive(_7);
|
||||
// DBG: _7 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
|
||||
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
|
||||
StorageDead(_7);
|
||||
_3 = copy _2 as *const u8 (Transmute);
|
||||
StorageDead(_6);
|
||||
StorageLive(_4);
|
||||
_4 = copy ((*_1).1: usize);
|
||||
StorageLive(_5);
|
||||
|
||||
Reference in New Issue
Block a user