mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Use index based drop loop for slices and arrays
Instead of building two kinds of drop pair loops, of which only one will be eventually used at runtime in a given monomorphization, always use index based loop.
This commit is contained in:
parent
2e7034ebf7
commit
cf0e78bd3b
@ -655,26 +655,20 @@ where
|
|||||||
///
|
///
|
||||||
/// ```text
|
/// ```text
|
||||||
/// loop-block:
|
/// loop-block:
|
||||||
/// can_go = cur == length_or_end
|
/// can_go = cur == len
|
||||||
/// if can_go then succ else drop-block
|
/// if can_go then succ else drop-block
|
||||||
/// drop-block:
|
/// drop-block:
|
||||||
/// if ptr_based {
|
/// ptr = &raw mut P[cur]
|
||||||
/// ptr = cur
|
/// cur = cur + 1
|
||||||
/// cur = cur.offset(1)
|
|
||||||
/// } else {
|
|
||||||
/// ptr = &raw mut P[cur]
|
|
||||||
/// cur = cur + 1
|
|
||||||
/// }
|
|
||||||
/// drop(ptr)
|
/// drop(ptr)
|
||||||
/// ```
|
/// ```
|
||||||
fn drop_loop(
|
fn drop_loop(
|
||||||
&mut self,
|
&mut self,
|
||||||
succ: BasicBlock,
|
succ: BasicBlock,
|
||||||
cur: Local,
|
cur: Local,
|
||||||
length_or_end: Place<'tcx>,
|
len: Local,
|
||||||
ety: Ty<'tcx>,
|
ety: Ty<'tcx>,
|
||||||
unwind: Unwind,
|
unwind: Unwind,
|
||||||
ptr_based: bool,
|
|
||||||
) -> BasicBlock {
|
) -> BasicBlock {
|
||||||
let copy = |place: Place<'tcx>| Operand::Copy(place);
|
let copy = |place: Place<'tcx>| Operand::Copy(place);
|
||||||
let move_ = |place: Place<'tcx>| Operand::Move(place);
|
let move_ = |place: Place<'tcx>| Operand::Move(place);
|
||||||
@ -683,22 +677,19 @@ where
|
|||||||
let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
|
let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
|
||||||
let ptr = Place::from(self.new_temp(ptr_ty));
|
let ptr = Place::from(self.new_temp(ptr_ty));
|
||||||
let can_go = Place::from(self.new_temp(tcx.types.bool));
|
let can_go = Place::from(self.new_temp(tcx.types.bool));
|
||||||
|
|
||||||
let one = self.constant_usize(1);
|
let one = self.constant_usize(1);
|
||||||
let (ptr_next, cur_next) = if ptr_based {
|
|
||||||
(
|
|
||||||
Rvalue::Use(copy(cur.into())),
|
|
||||||
Rvalue::BinaryOp(BinOp::Offset, Box::new((move_(cur.into()), one))),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
|
|
||||||
Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let drop_block = BasicBlockData {
|
let drop_block = BasicBlockData {
|
||||||
statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)],
|
statements: vec![
|
||||||
|
self.assign(
|
||||||
|
ptr,
|
||||||
|
Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
|
||||||
|
),
|
||||||
|
self.assign(
|
||||||
|
cur.into(),
|
||||||
|
Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
|
||||||
|
),
|
||||||
|
],
|
||||||
is_cleanup: unwind.is_cleanup(),
|
is_cleanup: unwind.is_cleanup(),
|
||||||
terminator: Some(Terminator {
|
terminator: Some(Terminator {
|
||||||
source_info: self.source_info,
|
source_info: self.source_info,
|
||||||
@ -711,10 +702,7 @@ where
|
|||||||
let loop_block = BasicBlockData {
|
let loop_block = BasicBlockData {
|
||||||
statements: vec![self.assign(
|
statements: vec![self.assign(
|
||||||
can_go,
|
can_go,
|
||||||
Rvalue::BinaryOp(
|
Rvalue::BinaryOp(BinOp::Eq, Box::new((copy(Place::from(cur)), copy(len.into())))),
|
||||||
BinOp::Eq,
|
|
||||||
Box::new((copy(Place::from(cur)), copy(length_or_end))),
|
|
||||||
),
|
|
||||||
)],
|
)],
|
||||||
is_cleanup: unwind.is_cleanup(),
|
is_cleanup: unwind.is_cleanup(),
|
||||||
terminator: Some(Terminator {
|
terminator: Some(Terminator {
|
||||||
@ -738,13 +726,6 @@ where
|
|||||||
|
|
||||||
fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
|
fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
|
||||||
debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
|
debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
|
||||||
|
|
||||||
// if size_of::<ety>() == 0 {
|
|
||||||
// index_based_loop
|
|
||||||
// } else {
|
|
||||||
// ptr_based_loop
|
|
||||||
// }
|
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
if let Some(size) = opt_size {
|
if let Some(size) = opt_size {
|
||||||
@ -770,86 +751,36 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let move_ = |place: Place<'tcx>| Operand::Move(place);
|
self.drop_loop_pair(ety)
|
||||||
let elem_size = Place::from(self.new_temp(tcx.types.usize));
|
|
||||||
let len = Place::from(self.new_temp(tcx.types.usize));
|
|
||||||
|
|
||||||
let base_block = BasicBlockData {
|
|
||||||
statements: vec![
|
|
||||||
self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
|
|
||||||
self.assign(len, Rvalue::Len(self.place)),
|
|
||||||
],
|
|
||||||
is_cleanup: self.unwind.is_cleanup(),
|
|
||||||
terminator: Some(Terminator {
|
|
||||||
source_info: self.source_info,
|
|
||||||
kind: TerminatorKind::SwitchInt {
|
|
||||||
discr: move_(elem_size),
|
|
||||||
targets: SwitchTargets::static_if(
|
|
||||||
0,
|
|
||||||
self.drop_loop_pair(ety, false, len),
|
|
||||||
self.drop_loop_pair(ety, true, len),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
self.elaborator.patch().new_block(base_block)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a pair of drop-loops of `place`, which drops its contents, even
|
/// Creates a pair of drop-loops of `place`, which drops its contents, even
|
||||||
/// in the case of 1 panic. If `ptr_based`, creates a pointer loop,
|
/// in the case of 1 panic.
|
||||||
/// otherwise create an index loop.
|
fn drop_loop_pair(&mut self, ety: Ty<'tcx>) -> BasicBlock {
|
||||||
fn drop_loop_pair(
|
debug!("drop_loop_pair({:?})", ety);
|
||||||
&mut self,
|
|
||||||
ety: Ty<'tcx>,
|
|
||||||
ptr_based: bool,
|
|
||||||
length: Place<'tcx>,
|
|
||||||
) -> BasicBlock {
|
|
||||||
debug!("drop_loop_pair({:?}, {:?})", ety, ptr_based);
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let iter_ty = if ptr_based { tcx.mk_mut_ptr(ety) } else { tcx.types.usize };
|
let len = self.new_temp(tcx.types.usize);
|
||||||
|
let cur = self.new_temp(tcx.types.usize);
|
||||||
|
|
||||||
let cur = self.new_temp(iter_ty);
|
let unwind =
|
||||||
let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length };
|
self.unwind.map(|unwind| self.drop_loop(unwind, cur, len, ety, Unwind::InCleanup));
|
||||||
|
|
||||||
let unwind = self.unwind.map(|unwind| {
|
let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind);
|
||||||
self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based)
|
|
||||||
});
|
|
||||||
|
|
||||||
let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based);
|
let zero = self.constant_usize(0);
|
||||||
|
let block = BasicBlockData {
|
||||||
let cur = Place::from(cur);
|
statements: vec![
|
||||||
let drop_block_stmts = if ptr_based {
|
self.assign(len.into(), Rvalue::Len(self.place)),
|
||||||
let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place));
|
self.assign(cur.into(), Rvalue::Use(zero)),
|
||||||
let tmp = Place::from(self.new_temp(tmp_ty));
|
],
|
||||||
// tmp = &raw mut P;
|
|
||||||
// cur = tmp as *mut T;
|
|
||||||
// end = Offset(cur, len);
|
|
||||||
let mir_cast_kind = ty::cast::mir_cast_kind(iter_ty, tmp_ty);
|
|
||||||
vec![
|
|
||||||
self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
|
|
||||||
self.assign(cur, Rvalue::Cast(mir_cast_kind, Operand::Move(tmp), iter_ty)),
|
|
||||||
self.assign(
|
|
||||||
length_or_end,
|
|
||||||
Rvalue::BinaryOp(
|
|
||||||
BinOp::Offset,
|
|
||||||
Box::new((Operand::Copy(cur), Operand::Move(length))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
// cur = 0 (length already pushed)
|
|
||||||
let zero = self.constant_usize(0);
|
|
||||||
vec![self.assign(cur, Rvalue::Use(zero))]
|
|
||||||
};
|
|
||||||
let drop_block = self.elaborator.patch().new_block(BasicBlockData {
|
|
||||||
statements: drop_block_stmts,
|
|
||||||
is_cleanup: unwind.is_cleanup(),
|
is_cleanup: unwind.is_cleanup(),
|
||||||
terminator: Some(Terminator {
|
terminator: Some(Terminator {
|
||||||
source_info: self.source_info,
|
source_info: self.source_info,
|
||||||
kind: TerminatorKind::Goto { target: loop_block },
|
kind: TerminatorKind::Goto { target: loop_block },
|
||||||
}),
|
}),
|
||||||
});
|
};
|
||||||
|
|
||||||
|
let drop_block = self.elaborator.patch().new_block(block);
|
||||||
// FIXME(#34708): handle partially-dropped array/slice elements.
|
// FIXME(#34708): handle partially-dropped array/slice elements.
|
||||||
let reset_block = self.drop_flag_reset_block(DropFlagMode::Deep, drop_block, unwind);
|
let reset_block = self.drop_flag_reset_block(DropFlagMode::Deep, drop_block, unwind);
|
||||||
self.drop_flag_test_block(reset_block, self.succ, unwind)
|
self.drop_flag_test_block(reset_block, self.succ, unwind)
|
||||||
|
@ -4,21 +4,13 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
|
|||||||
let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _4: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _5: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _6: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
let mut _7: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
goto -> bb8; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
@ -30,72 +22,34 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bb3 (cleanup): {
|
bb3 (cleanup): {
|
||||||
_5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_4 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
drop((*_4)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4 (cleanup): {
|
bb4 (cleanup): {
|
||||||
_6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_5 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
switchInt(move _6) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
switchInt(move _5) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
_7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_6 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
drop((*_6)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb6: {
|
bb6: {
|
||||||
_8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_7 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
switchInt(move _8) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
switchInt(move _7) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
_4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
_2 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
|
_3 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb8: {
|
bb8: {
|
||||||
goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9 (cleanup): {
|
|
||||||
_11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
|
|
||||||
bb10 (cleanup): {
|
|
||||||
_12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
switchInt(move _12) -> [0: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
|
|
||||||
bb11: {
|
|
||||||
_13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
|
|
||||||
bb12: {
|
|
||||||
_14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
switchInt(move _14) -> [0: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
|
|
||||||
bb13: {
|
|
||||||
_15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
_9 = move _15 as *mut std::string::String (PtrToPtr); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
_10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
|
|
||||||
bb14: {
|
|
||||||
goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
|
|
||||||
bb15: {
|
|
||||||
_2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
_3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
switchInt(move _2) -> [0: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user