]> git.lizzy.rs Git - rust.git/commitdiff
Slightly simplify the MIR for slice drop shims
authorMatthew Jasper <mjjasper1@gmail.com>
Mon, 29 Apr 2019 19:38:08 +0000 (20:38 +0100)
committerMatthew Jasper <mjjasper1@gmail.com>
Wed, 1 May 2019 18:01:57 +0000 (19:01 +0100)
src/librustc_mir/util/elaborate_drops.rs
src/test/mir-opt/slice-drop-shim.rs

index 856783bcbaa469dee234d4cf139cf826ab737ce1..98ca7c32675c8b09e1ea0e1083090df7b9c326f7 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_data_structures::indexed_vec::Idx;
 use crate::util::patch::MirPatch;
 
-use std::u32;
+use std::convert::TryInto;
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
 pub enum DropFlagState {
@@ -545,10 +545,9 @@ fn destructor_call_block<'a>(&mut self, (succ, unwind): (BasicBlock, Unwind))
         self.elaborator.patch().new_block(result)
     }
 
-    /// create a loop that drops an array:
-    ///
-
+    /// Create a loop that drops an array:
     ///
+    /// ```text
     /// loop-block:
     ///    can_go = cur == length_or_end
     ///    if can_go then succ else drop-block
@@ -561,15 +560,16 @@ fn destructor_call_block<'a>(&mut self, (succ, unwind): (BasicBlock, Unwind))
     ///        cur = cur + 1
     ///    }
     ///    drop(ptr)
-    fn drop_loop(&mut self,
-                 succ: BasicBlock,
-                 cur: Local,
-                 length_or_end: &Place<'tcx>,
-                 ety: Ty<'tcx>,
-                 unwind: Unwind,
-                 ptr_based: bool)
-                 -> BasicBlock
-    {
+    /// ```
+    fn drop_loop(
+        &mut self,
+        succ: BasicBlock,
+        cur: Local,
+        length_or_end: &Place<'tcx>,
+        ety: Ty<'tcx>,
+        unwind: Unwind,
+        ptr_based: bool,
+    ) -> BasicBlock {
         let copy = |place: &Place<'tcx>| Operand::Copy(place.clone());
         let move_ = |place: &Place<'tcx>| Operand::Move(place.clone());
         let tcx = self.tcx();
@@ -591,13 +591,13 @@ fn drop_loop(&mut self,
                     elem: ProjectionElem::Deref,
                 }))
              ),
-             Rvalue::BinaryOp(BinOp::Offset, copy(&Place::Base(PlaceBase::Local(cur))), one))
+             Rvalue::BinaryOp(BinOp::Offset, move_(&Place::Base(PlaceBase::Local(cur))), one))
         } else {
             (Rvalue::Ref(
                  tcx.lifetimes.re_erased,
                  BorrowKind::Mut { allow_two_phase_borrow: false },
                  self.place.clone().index(cur)),
-             Rvalue::BinaryOp(BinOp::Add, copy(&Place::Base(PlaceBase::Local(cur))), one))
+             Rvalue::BinaryOp(BinOp::Add, move_(&Place::Base(PlaceBase::Local(cur))), one))
         };
 
         let drop_block = BasicBlockData {
@@ -647,9 +647,9 @@ fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> Basic
         // }
 
         if let Some(size) = opt_size {
-            assert!(size <= (u32::MAX as u64),
-                    "move out check doesn't implemented for array bigger then u32");
-            let size = size as u32;
+            let size: u32 = size.try_into().unwrap_or_else(|_| {
+                bug!("move out check isn't implemented for array sizes bigger than u32::MAX");
+            });
             let fields: Vec<(Place<'tcx>, Option<D::Path>)> = (0..size).map(|i| {
                 (self.place.clone().elem(ProjectionElem::ConstantIndex{
                     offset: i,
@@ -667,33 +667,42 @@ fn open_drop_for_array(&mut self, ety: Ty<'tcx>, opt_size: Option<u64>) -> Basic
 
         let move_ = |place: &Place<'tcx>| Operand::Move(place.clone());
         let tcx = self.tcx();
-        let size = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.usize)));
-        let size_is_zero = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.bool)));
+        let elem_size = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.usize)));
+        let len = &Place::Base(PlaceBase::Local(self.new_temp(tcx.types.usize)));
+
+        static USIZE_SWITCH_ZERO: &[u128] = &[0];
+
         let base_block = BasicBlockData {
             statements: vec![
-                self.assign(size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
-                self.assign(size_is_zero, Rvalue::BinaryOp(BinOp::Eq,
-                                                           move_(size),
-                                                           self.constant_usize(0)))
+                self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
+                self.assign(len, Rvalue::Len(self.place.clone())),
             ],
             is_cleanup: self.unwind.is_cleanup(),
             terminator: Some(Terminator {
                 source_info: self.source_info,
-                kind: TerminatorKind::if_(
-                    tcx,
-                    move_(size_is_zero),
-                    self.drop_loop_pair(ety, false),
-                    self.drop_loop_pair(ety, true)
-                )
+                kind: TerminatorKind::SwitchInt {
+                    discr: move_(elem_size),
+                    switch_ty: tcx.types.usize,
+                    values: From::from(USIZE_SWITCH_ZERO),
+                    targets: vec![
+                        self.drop_loop_pair(ety, false, len.clone()),
+                        self.drop_loop_pair(ety, true, len.clone()),
+                    ],
+                },
             })
         };
         self.elaborator.patch().new_block(base_block)
     }
 
-    // create a pair of drop-loops of `place`, which drops its contents
-    // even in the case of 1 panic. If `ptr_based`, create a pointer loop,
-    // otherwise create an index loop.
-    fn drop_loop_pair(&mut self, ety: Ty<'tcx>, ptr_based: bool) -> BasicBlock {
+    /// Ceates 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,
+    /// otherwise create an index loop.
+    fn drop_loop_pair(
+        &mut self,
+        ety: Ty<'tcx>,
+        ptr_based: bool,
+        length: Place<'tcx>,
+    ) -> BasicBlock {
         debug!("drop_loop_pair({:?}, {:?})", ety, ptr_based);
         let tcx = self.tcx();
         let iter_ty = if ptr_based {
@@ -703,7 +712,6 @@ fn drop_loop_pair(&mut self, ety: Ty<'tcx>, ptr_based: bool) -> BasicBlock {
         };
 
         let cur = self.new_temp(iter_ty);
-        let length = Place::Base(PlaceBase::Local(self.new_temp(tcx.types.usize)));
         let length_or_end = if ptr_based {
             // FIXME check if we want to make it return a `Place` directly
             // if all use sites want a `Place::Base` anyway.
@@ -722,9 +730,8 @@ fn drop_loop_pair(&mut self, ety: Ty<'tcx>, ptr_based: bool) -> BasicBlock {
                            ptr_based)
         });
 
-        let succ = self.succ; // FIXME(#43234)
         let loop_block = self.drop_loop(
-            succ,
+            self.succ,
             cur,
             &length_or_end,
             ety,
@@ -732,31 +739,32 @@ fn drop_loop_pair(&mut self, ety: Ty<'tcx>, ptr_based: bool) -> BasicBlock {
             ptr_based);
 
         let cur = Place::Base(PlaceBase::Local(cur));
-        let zero = self.constant_usize(0);
-        let mut drop_block_stmts = vec![];
-        drop_block_stmts.push(self.assign(&length, Rvalue::Len(self.place.clone())));
-        if ptr_based {
+        let drop_block_stmts = if ptr_based {
             let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place));
             let tmp = Place::Base(PlaceBase::Local(self.new_temp(tmp_ty)));
             // tmp = &mut P;
             // cur = tmp as *mut T;
             // end = Offset(cur, len);
-            drop_block_stmts.push(self.assign(&tmp, Rvalue::Ref(
-                tcx.lifetimes.re_erased,
-                BorrowKind::Mut { allow_two_phase_borrow: false },
-                self.place.clone()
-            )));
-            drop_block_stmts.push(self.assign(&cur, Rvalue::Cast(
-                CastKind::Misc, Operand::Move(tmp), iter_ty
-            )));
-            drop_block_stmts.push(self.assign(&length_or_end,
-                Rvalue::BinaryOp(BinOp::Offset,
-                     Operand::Copy(cur), Operand::Move(length)
-            )));
+            vec![
+                self.assign(&tmp, Rvalue::Ref(
+                    tcx.lifetimes.re_erased,
+                    BorrowKind::Mut { allow_two_phase_borrow: false },
+                    self.place.clone()
+                )),
+                self.assign(
+                    &cur,
+                    Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty),
+                ),
+                self.assign(
+                    &length_or_end,
+                    Rvalue::BinaryOp(BinOp::Offset, Operand::Copy(cur), Operand::Move(length)
+                )),
+            ]
         } else {
-            // index = 0 (length already pushed)
-            drop_block_stmts.push(self.assign(&cur, Rvalue::Use(zero)));
-        }
+            // 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(),
@@ -768,7 +776,7 @@ fn drop_loop_pair(&mut self, ety: Ty<'tcx>, ptr_based: bool) -> BasicBlock {
 
         // FIXME(#34708): handle partially-dropped array/slice elements.
         let reset_block = self.drop_flag_reset_block(DropFlagMode::Deep, drop_block, unwind);
-        self.drop_flag_test_block(reset_block, succ, unwind)
+        self.drop_flag_test_block(reset_block, self.succ, unwind)
     }
 
     /// The slow-path - create an "open", elaborated drop for a type
index f558ec18ba9f232eb9cf8914c960945c52f4d92b..754fad51b21e78faf35ffbdb57e6326efad9e46f 100644 (file)
@@ -6,21 +6,19 @@ fn main() {
 
 // START rustc.ptr-real_drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir
 // let mut _2: usize;
-// let mut _3: bool;
+// let mut _3: usize;
 // let mut _4: usize;
-// let mut _5: usize;
-// let mut _6: &mut std::string::String;
-// let mut _7: bool;
-// let mut _8: &mut std::string::String;
-// let mut _9: bool;
+// let mut _5: &mut std::string::String;
+// let mut _6: bool;
+// let mut _7: &mut std::string::String;
+// let mut _8: bool;
+// let mut _9: *mut std::string::String;
 // let mut _10: *mut std::string::String;
-// let mut _11: usize;
-// let mut _12: *mut std::string::String;
+// let mut _11: &mut std::string::String;
+// let mut _12: bool;
 // let mut _13: &mut std::string::String;
 // let mut _14: bool;
-// let mut _15: &mut std::string::String;
-// let mut _16: bool;
-// let mut _17: *mut [std::string::String];
+// let mut _15: *mut [std::string::String];
 // bb0: {
 //     goto -> bb15;
 // }
@@ -31,25 +29,24 @@ fn main() {
 //     resume;
 // }
 // bb3 (cleanup): {
-//     _6 = &mut (*_1)[_4];
-//     _4 = Add(_4, const 1usize);
-//     drop((*_6)) -> bb4;
+//     _5 = &mut (*_1)[_4];
+//     _4 = Add(move _4, const 1usize);
+//     drop((*_5)) -> bb4;
 // }
 // bb4 (cleanup): {
-//     _7 = Eq(_4, _5);
-//     switchInt(move _7) -> [false: bb3, otherwise: bb2];
+//     _6 = Eq(_4, _3);
+//     switchInt(move _6) -> [false: bb3, otherwise: bb2];
 // }
 // bb5: {
-//     _8 = &mut (*_1)[_4];
-//     _4 = Add(_4, const 1usize);
-//     drop((*_8)) -> [return: bb6, unwind: bb4];
+//     _7 = &mut (*_1)[_4];
+//     _4 = Add(move _4, const 1usize);
+//     drop((*_7)) -> [return: bb6, unwind: bb4];
 // }
 // bb6: {
-//     _9 = Eq(_4, _5);
-//     switchInt(move _9) -> [false: bb5, otherwise: bb1];
+//     _8 = Eq(_4, _3);
+//     switchInt(move _8) -> [false: bb5, otherwise: bb1];
 // }
 // bb7: {
-//     _5 = Len((*_1));
 //     _4 = const 0usize;
 //     goto -> bb6;
 // }
@@ -57,28 +54,27 @@ fn main() {
 //     goto -> bb7;
 // }
 // bb9 (cleanup): {
-//     _13 = &mut (*_10);
-//     _10 = Offset(_10, const 1usize);
-//     drop((*_13)) -> bb10;
+//     _11 = &mut (*_9);
+//     _9 = Offset(move _9, const 1usize);
+//     drop((*_11)) -> bb10;
 // }
 // bb10 (cleanup): {
-//     _14 = Eq(_10, _12);
-//     switchInt(move _14) -> [false: bb9, otherwise: bb2];
+//     _12 = Eq(_9, _10);
+//     switchInt(move _12) -> [false: bb9, otherwise: bb2];
 // }
 // bb11: {
-//     _15 = &mut (*_10);
-//     _10 = Offset(_10, const 1usize);
-//     drop((*_15)) -> [return: bb12, unwind: bb10];
+//     _13 = &mut (*_9);
+//     _9 = Offset(move _9, const 1usize);
+//     drop((*_13)) -> [return: bb12, unwind: bb10];
 // }
 // bb12: {
-//     _16 = Eq(_10, _12);
-//     switchInt(move _16) -> [false: bb11, otherwise: bb1];
+//     _14 = Eq(_9, _10);
+//     switchInt(move _14) -> [false: bb11, otherwise: bb1];
 // }
 // bb13: {
-//     _11 = Len((*_1));
-//     _17 = &mut (*_1);
-//     _10 = move _17 as *mut std::string::String (Misc);
-//     _12 = Offset(_10, move _11);
+//     _15 = &mut (*_1);
+//     _9 = move _15 as *mut std::string::String (Misc);
+//     _10 = Offset(_9, move _3);
 //     goto -> bb12;
 // }
 // bb14: {
@@ -86,7 +82,7 @@ fn main() {
 // }
 // bb15: {
 //     _2 = SizeOf(std::string::String);
-//     _3 = Eq(move _2, const 0usize);
-//     switchInt(move _3) -> [false: bb14, otherwise: bb8];
+//     _3 = Len((*_1));
+//     switchInt(move _2) -> [0usize: bb8, otherwise: bb14];
 // }
 // END rustc.ptr-real_drop_in_place.[std__string__String].AddMovesForPackedDrops.before.mir