Skip to content

Commit 2d64f22

Browse files
committed
Auto merge of #109085 - tmiasko:index-based, r=WaffleLapkin
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.
2 parents 511364e + cf0e78b commit 2d64f22

File tree

2 files changed

+49
-164
lines changed

2 files changed

+49
-164
lines changed

compiler/rustc_mir_dataflow/src/elaborate_drops.rs

+32-101
Original file line numberDiff line numberDiff line change
@@ -655,26 +655,20 @@ where
655655
///
656656
/// ```text
657657
/// loop-block:
658-
/// can_go = cur == length_or_end
658+
/// can_go = cur == len
659659
/// if can_go then succ else drop-block
660660
/// drop-block:
661-
/// if ptr_based {
662-
/// ptr = cur
663-
/// cur = cur.offset(1)
664-
/// } else {
665-
/// ptr = &raw mut P[cur]
666-
/// cur = cur + 1
667-
/// }
661+
/// ptr = &raw mut P[cur]
662+
/// cur = cur + 1
668663
/// drop(ptr)
669664
/// ```
670665
fn drop_loop(
671666
&mut self,
672667
succ: BasicBlock,
673668
cur: Local,
674-
length_or_end: Place<'tcx>,
669+
len: Local,
675670
ety: Ty<'tcx>,
676671
unwind: Unwind,
677-
ptr_based: bool,
678672
) -> BasicBlock {
679673
let copy = |place: Place<'tcx>| Operand::Copy(place);
680674
let move_ = |place: Place<'tcx>| Operand::Move(place);
@@ -683,22 +677,19 @@ where
683677
let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
684678
let ptr = Place::from(self.new_temp(ptr_ty));
685679
let can_go = Place::from(self.new_temp(tcx.types.bool));
686-
687680
let one = self.constant_usize(1);
688-
let (ptr_next, cur_next) = if ptr_based {
689-
(
690-
Rvalue::Use(copy(cur.into())),
691-
Rvalue::BinaryOp(BinOp::Offset, Box::new((move_(cur.into()), one))),
692-
)
693-
} else {
694-
(
695-
Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
696-
Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
697-
)
698-
};
699681

700682
let drop_block = BasicBlockData {
701-
statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)],
683+
statements: vec![
684+
self.assign(
685+
ptr,
686+
Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
687+
),
688+
self.assign(
689+
cur.into(),
690+
Rvalue::BinaryOp(BinOp::Add, Box::new((move_(cur.into()), one))),
691+
),
692+
],
702693
is_cleanup: unwind.is_cleanup(),
703694
terminator: Some(Terminator {
704695
source_info: self.source_info,
@@ -711,10 +702,7 @@ where
711702
let loop_block = BasicBlockData {
712703
statements: vec![self.assign(
713704
can_go,
714-
Rvalue::BinaryOp(
715-
BinOp::Eq,
716-
Box::new((copy(Place::from(cur)), copy(length_or_end))),
717-
),
705+
Rvalue::BinaryOp(BinOp::Eq, Box::new((copy(Place::from(cur)), copy(len.into())))),
718706
)],
719707
is_cleanup: unwind.is_cleanup(),
720708
terminator: Some(Terminator {
@@ -738,13 +726,6 @@ where
738726

739727
fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> BasicBlock {
740728
debug!("open_drop_for_array({:?}, {:?})", ety, opt_size);
741-
742-
// if size_of::<ety>() == 0 {
743-
// index_based_loop
744-
// } else {
745-
// ptr_based_loop
746-
// }
747-
748729
let tcx = self.tcx();
749730

750731
if let Some(size) = opt_size {
@@ -770,86 +751,36 @@ where
770751
}
771752
}
772753

773-
let move_ = |place: Place<'tcx>| Operand::Move(place);
774-
let elem_size = Place::from(self.new_temp(tcx.types.usize));
775-
let len = Place::from(self.new_temp(tcx.types.usize));
776-
777-
let base_block = BasicBlockData {
778-
statements: vec![
779-
self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
780-
self.assign(len, Rvalue::Len(self.place)),
781-
],
782-
is_cleanup: self.unwind.is_cleanup(),
783-
terminator: Some(Terminator {
784-
source_info: self.source_info,
785-
kind: TerminatorKind::SwitchInt {
786-
discr: move_(elem_size),
787-
targets: SwitchTargets::static_if(
788-
0,
789-
self.drop_loop_pair(ety, false, len),
790-
self.drop_loop_pair(ety, true, len),
791-
),
792-
},
793-
}),
794-
};
795-
self.elaborator.patch().new_block(base_block)
754+
self.drop_loop_pair(ety)
796755
}
797756

798757
/// Creates a pair of drop-loops of `place`, which drops its contents, even
799-
/// in the case of 1 panic. If `ptr_based`, creates a pointer loop,
800-
/// otherwise create an index loop.
801-
fn drop_loop_pair(
802-
&mut self,
803-
ety: Ty<'tcx>,
804-
ptr_based: bool,
805-
length: Place<'tcx>,
806-
) -> BasicBlock {
807-
debug!("drop_loop_pair({:?}, {:?})", ety, ptr_based);
758+
/// in the case of 1 panic.
759+
fn drop_loop_pair(&mut self, ety: Ty<'tcx>) -> BasicBlock {
760+
debug!("drop_loop_pair({:?})", ety);
808761
let tcx = self.tcx();
809-
let iter_ty = if ptr_based { tcx.mk_mut_ptr(ety) } else { tcx.types.usize };
762+
let len = self.new_temp(tcx.types.usize);
763+
let cur = self.new_temp(tcx.types.usize);
810764

811-
let cur = self.new_temp(iter_ty);
812-
let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length };
765+
let unwind =
766+
self.unwind.map(|unwind| self.drop_loop(unwind, cur, len, ety, Unwind::InCleanup));
813767

814-
let unwind = self.unwind.map(|unwind| {
815-
self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based)
816-
});
768+
let loop_block = self.drop_loop(self.succ, cur, len, ety, unwind);
817769

818-
let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based);
819-
820-
let cur = Place::from(cur);
821-
let drop_block_stmts = if ptr_based {
822-
let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place));
823-
let tmp = Place::from(self.new_temp(tmp_ty));
824-
// tmp = &raw mut P;
825-
// cur = tmp as *mut T;
826-
// end = Offset(cur, len);
827-
let mir_cast_kind = ty::cast::mir_cast_kind(iter_ty, tmp_ty);
828-
vec![
829-
self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
830-
self.assign(cur, Rvalue::Cast(mir_cast_kind, Operand::Move(tmp), iter_ty)),
831-
self.assign(
832-
length_or_end,
833-
Rvalue::BinaryOp(
834-
BinOp::Offset,
835-
Box::new((Operand::Copy(cur), Operand::Move(length))),
836-
),
837-
),
838-
]
839-
} else {
840-
// cur = 0 (length already pushed)
841-
let zero = self.constant_usize(0);
842-
vec![self.assign(cur, Rvalue::Use(zero))]
843-
};
844-
let drop_block = self.elaborator.patch().new_block(BasicBlockData {
845-
statements: drop_block_stmts,
770+
let zero = self.constant_usize(0);
771+
let block = BasicBlockData {
772+
statements: vec![
773+
self.assign(len.into(), Rvalue::Len(self.place)),
774+
self.assign(cur.into(), Rvalue::Use(zero)),
775+
],
846776
is_cleanup: unwind.is_cleanup(),
847777
terminator: Some(Terminator {
848778
source_info: self.source_info,
849779
kind: TerminatorKind::Goto { target: loop_block },
850780
}),
851-
});
781+
};
852782

783+
let drop_block = self.elaborator.patch().new_block(block);
853784
// FIXME(#34708): handle partially-dropped array/slice elements.
854785
let reset_block = self.drop_flag_reset_block(DropFlagMode::Deep, drop_block, unwind);
855786
self.drop_flag_test_block(reset_block, self.succ, unwind)

tests/mir-opt/slice_drop_shim.core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir

+17-63
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,13 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
44
let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
55
let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
66
let mut _3: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
7-
let mut _4: usize; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
8-
let mut _5: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
9-
let mut _6: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
10-
let mut _7: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
11-
let mut _8: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
12-
let mut _9: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
13-
let mut _10: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
14-
let mut _11: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
15-
let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
16-
let mut _13: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
17-
let mut _14: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
18-
let mut _15: *mut [std::string::String]; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
7+
let mut _4: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
8+
let mut _5: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
9+
let mut _6: *mut std::string::String; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
10+
let mut _7: bool; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
1911

2012
bb0: {
21-
goto -> bb15; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
13+
goto -> bb8; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
2214
}
2315

2416
bb1: {
@@ -30,72 +22,34 @@ fn std::ptr::drop_in_place(_1: *mut [String]) -> () {
3022
}
3123

3224
bb3 (cleanup): {
33-
_5 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
34-
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
35-
drop((*_5)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
25+
_4 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
26+
_3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
27+
drop((*_4)) -> bb4; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
3628
}
3729

3830
bb4 (cleanup): {
39-
_6 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
40-
switchInt(move _6) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
31+
_5 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
32+
switchInt(move _5) -> [0: bb3, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
4133
}
4234

4335
bb5: {
44-
_7 = &raw mut (*_1)[_4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
45-
_4 = Add(move _4, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
46-
drop((*_7)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
36+
_6 = &raw mut (*_1)[_3]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
37+
_3 = Add(move _3, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
38+
drop((*_6)) -> [return: bb6, unwind: bb4]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
4739
}
4840

4941
bb6: {
50-
_8 = Eq(_4, _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
51-
switchInt(move _8) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
42+
_7 = Eq(_3, _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
43+
switchInt(move _7) -> [0: bb5, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
5244
}
5345

5446
bb7: {
55-
_4 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
47+
_2 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
48+
_3 = const 0_usize; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
5649
goto -> bb6; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
5750
}
5851

5952
bb8: {
6053
goto -> bb7; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
6154
}
62-
63-
bb9 (cleanup): {
64-
_11 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
65-
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
66-
drop((*_11)) -> bb10; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
67-
}
68-
69-
bb10 (cleanup): {
70-
_12 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
71-
switchInt(move _12) -> [0: bb9, otherwise: bb2]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
72-
}
73-
74-
bb11: {
75-
_13 = _9; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
76-
_9 = Offset(move _9, const 1_usize); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
77-
drop((*_13)) -> [return: bb12, unwind: bb10]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
78-
}
79-
80-
bb12: {
81-
_14 = Eq(_9, _10); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
82-
switchInt(move _14) -> [0: bb11, otherwise: bb1]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
83-
}
84-
85-
bb13: {
86-
_15 = &raw mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
87-
_9 = move _15 as *mut std::string::String (PtrToPtr); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
88-
_10 = Offset(_9, move _3); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
89-
goto -> bb12; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
90-
}
91-
92-
bb14: {
93-
goto -> bb13; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
94-
}
95-
96-
bb15: {
97-
_2 = SizeOf(std::string::String); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
98-
_3 = Len((*_1)); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
99-
switchInt(move _2) -> [0: bb8, otherwise: bb14]; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56
100-
}
10155
}

0 commit comments

Comments
 (0)