about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-14 09:23:22 +0000
committerbors <bors@rust-lang.org>2020-08-14 09:23:22 +0000
commit6b2ca8457a0f6450896c669caf880090a18d1541 (patch)
treee57c6a74533ce74bdbff555de0259d6290b09681
parent43bec40138bab10c08ac916bff2f2f81b2b70669 (diff)
parentfd63bf7262d616e8fb5d3465a736434ddc81ff99 (diff)
downloadrust-6b2ca8457a0f6450896c669caf880090a18d1541.tar.gz
rust-6b2ca8457a0f6450896c669caf880090a18d1541.zip
Auto merge of #75503 - JulianKnodt:opt_opt, r=oli-obk
Clean up some mir transform passes

I noticed a few places where there were intermediates being created
in MIR optimization passes, so I removed them.

I also changed some `Some(..)` into just `..` and wrap `Some(..)` at the function end, doing early returns for `None`.

I was generally looking for some easy optimizations in theses passes, and hopefully these should improve the runtime of these passes by a tinnnyyyyy bit.

r? @oli-obk
-rw-r--r--src/librustc_mir/transform/add_retag.rs38
-rw-r--r--src/librustc_mir/transform/deaggregator.rs24
-rw-r--r--src/librustc_mir/transform/simplify_try.rs43
-rw-r--r--src/librustc_mir/transform/uninhabited_enum_branching.rs32
-rw-r--r--src/librustc_mir/transform/unreachable_prop.rs28
5 files changed, 72 insertions, 93 deletions
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index baa3e5e1581..324289166b9 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -86,12 +86,11 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
                 .skip(1)
                 .take(arg_count)
                 .map(|(local, _)| Place::from(local))
-                .filter(needs_retag)
-                .collect::<Vec<_>>();
+                .filter(needs_retag);
             // Emit their retags.
             basic_blocks[START_BLOCK].statements.splice(
                 0..0,
-                places.into_iter().map(|place| Statement {
+                places.map(|place| Statement {
                     source_info,
                     kind: StatementKind::Retag(RetagKind::FnEntry, box (place)),
                 }),
@@ -101,29 +100,24 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
         // PART 2
         // Retag return values of functions.  Also escape-to-raw the argument of `drop`.
         // We collect the return destinations because we cannot mutate while iterating.
-        let mut returns: Vec<(SourceInfo, Place<'tcx>, BasicBlock)> = Vec::new();
-        for block_data in basic_blocks.iter_mut() {
-            match block_data.terminator().kind {
-                TerminatorKind::Call { ref destination, .. } => {
-                    // Remember the return destination for later
-                    if let Some(ref destination) = destination {
-                        if needs_retag(&destination.0) {
-                            returns.push((
-                                block_data.terminator().source_info,
-                                destination.0,
-                                destination.1,
-                            ));
-                        }
+        let returns = basic_blocks
+            .iter_mut()
+            .filter_map(|block_data| {
+                match block_data.terminator().kind {
+                    TerminatorKind::Call { destination: Some(ref destination), .. }
+                        if needs_retag(&destination.0) =>
+                    {
+                        // Remember the return destination for later
+                        Some((block_data.terminator().source_info, destination.0, destination.1))
                     }
-                }
-                TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => {
+
                     // `Drop` is also a call, but it doesn't return anything so we are good.
-                }
-                _ => {
+                    TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => None,
                     // Not a block ending in a Call -> ignore.
+                    _ => None,
                 }
-            }
-        }
+            })
+            .collect::<Vec<_>>();
         // Now we go over the returns we collected to retag the return values.
         for (source_info, dest_place, dest_block) in returns {
             basic_blocks[dest_block].statements.insert(
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 2de701284e3..66989a90244 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -12,26 +12,24 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
         for bb in basic_blocks {
             bb.expand_statements(|stmt| {
                 // FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
-                if let StatementKind::Assign(box (_, ref rhs)) = stmt.kind {
-                    if let Rvalue::Aggregate(ref kind, _) = *rhs {
-                        // FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
-                        if let AggregateKind::Array(_) = **kind {
-                            return None;
-                        }
-                    } else {
+                match stmt.kind {
+                    // FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
+                    StatementKind::Assign(box (
+                        _,
+                        Rvalue::Aggregate(box AggregateKind::Array(_), _),
+                    )) => {
                         return None;
                     }
-                } else {
-                    return None;
+                    StatementKind::Assign(box (_, Rvalue::Aggregate(_, _))) => {}
+                    _ => return None,
                 }
 
                 let stmt = stmt.replace_nop();
                 let source_info = stmt.source_info;
                 let (lhs, kind, operands) = match stmt.kind {
-                    StatementKind::Assign(box (lhs, rvalue)) => match rvalue {
-                        Rvalue::Aggregate(kind, operands) => (lhs, kind, operands),
-                        _ => bug!(),
-                    },
+                    StatementKind::Assign(box (lhs, Rvalue::Aggregate(kind, operands))) => {
+                        (lhs, kind, operands)
+                    }
                     _ => bug!(),
                 };
 
diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs
index 02896d7de35..84082edd193 100644
--- a/src/librustc_mir/transform/simplify_try.rs
+++ b/src/librustc_mir/transform/simplify_try.rs
@@ -246,12 +246,14 @@ fn get_arm_identity_info<'a, 'tcx>(
         tmp_assigned_vars.insert(*r);
     }
 
-    let mut dbg_info_to_adjust = Vec::new();
-    for (i, var_info) in debug_info.iter().enumerate() {
-        if tmp_assigned_vars.contains(var_info.place.local) {
-            dbg_info_to_adjust.push(i);
-        }
-    }
+    let dbg_info_to_adjust: Vec<_> =
+        debug_info
+            .iter()
+            .enumerate()
+            .filter_map(|(i, var_info)| {
+                if tmp_assigned_vars.contains(var_info.place.local) { Some(i) } else { None }
+            })
+            .collect();
 
     Some(ArmIdentityInfo {
         local_temp_0: local_tmp_s0,
@@ -461,14 +463,14 @@ fn match_get_variant_field<'tcx>(
     stmt: &Statement<'tcx>,
 ) -> Option<(Local, Local, VarField<'tcx>, &'tcx List<PlaceElem<'tcx>>)> {
     match &stmt.kind {
-        StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from {
-            Rvalue::Use(Operand::Copy(pf) | Operand::Move(pf)) => {
-                let local_into = place_into.as_local()?;
-                let (local_from, vf) = match_variant_field_place(*pf)?;
-                Some((local_into, local_from, vf, pf.projection))
-            }
-            _ => None,
-        },
+        StatementKind::Assign(box (
+            place_into,
+            Rvalue::Use(Operand::Copy(pf) | Operand::Move(pf)),
+        )) => {
+            let local_into = place_into.as_local()?;
+            let (local_from, vf) = match_variant_field_place(*pf)?;
+            Some((local_into, local_from, vf, pf.projection))
+        }
         _ => None,
     }
 }
@@ -479,14 +481,11 @@ fn match_get_variant_field<'tcx>(
 /// ```
 fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local, VarField<'tcx>)> {
     match &stmt.kind {
-        StatementKind::Assign(box (place_from, rvalue_into)) => match rvalue_into {
-            Rvalue::Use(Operand::Move(place_into)) => {
-                let local_into = place_into.as_local()?;
-                let (local_from, vf) = match_variant_field_place(*place_from)?;
-                Some((local_into, local_from, vf))
-            }
-            _ => None,
-        },
+        StatementKind::Assign(box (place_from, Rvalue::Use(Operand::Move(place_into)))) => {
+            let local_into = place_into.as_local()?;
+            let (local_from, vf) = match_variant_field_place(*place_from)?;
+            Some((local_into, local_from, vf))
+        }
         _ => None,
     }
 }
diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/src/librustc_mir/transform/uninhabited_enum_branching.rs
index e3b182b8849..4cca4d223c0 100644
--- a/src/librustc_mir/transform/uninhabited_enum_branching.rs
+++ b/src/librustc_mir/transform/uninhabited_enum_branching.rs
@@ -99,26 +99,18 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
             if let TerminatorKind::SwitchInt { values, targets, .. } =
                 &mut body.basic_blocks_mut()[bb].terminator_mut().kind
             {
-                let vals = &*values;
-                let zipped = vals.iter().zip(targets.iter());
-
-                let mut matched_values = Vec::with_capacity(allowed_variants.len());
-                let mut matched_targets = Vec::with_capacity(allowed_variants.len() + 1);
-
-                for (val, target) in zipped {
-                    if allowed_variants.contains(val) {
-                        matched_values.push(*val);
-                        matched_targets.push(*target);
-                    } else {
-                        trace!("eliminating {:?} -> {:?}", val, target);
-                    }
-                }
-
-                // handle the "otherwise" branch
-                matched_targets.push(targets.pop().unwrap());
-
-                *values = matched_values.into();
-                *targets = matched_targets;
+                // take otherwise out early
+                let otherwise = targets.pop().unwrap();
+                assert_eq!(targets.len(), values.len());
+                let mut i = 0;
+                targets.retain(|_| {
+                    let keep = allowed_variants.contains(&values[i]);
+                    i += 1;
+                    keep
+                });
+                targets.push(otherwise);
+
+                values.to_mut().retain(|var| allowed_variants.contains(var));
             } else {
                 unreachable!()
             }
diff --git a/src/librustc_mir/transform/unreachable_prop.rs b/src/librustc_mir/transform/unreachable_prop.rs
index d9f2259030f..fa362c66fb2 100644
--- a/src/librustc_mir/transform/unreachable_prop.rs
+++ b/src/librustc_mir/transform/unreachable_prop.rs
@@ -67,18 +67,13 @@ fn remove_successors<F>(
 where
     F: Fn(BasicBlock) -> bool,
 {
-    match *terminator_kind {
-        TerminatorKind::Goto { target } if predicate(target) => Some(TerminatorKind::Unreachable),
+    let terminator = match *terminator_kind {
+        TerminatorKind::Goto { target } if predicate(target) => TerminatorKind::Unreachable,
         TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
             let original_targets_len = targets.len();
             let (otherwise, targets) = targets.split_last().unwrap();
-            let retained = values
-                .iter()
-                .zip(targets.iter())
-                .filter(|(_, &t)| !predicate(t))
-                .collect::<Vec<_>>();
-            let mut values = retained.iter().map(|&(v, _)| *v).collect::<Vec<_>>();
-            let mut targets = retained.iter().map(|&(_, d)| *d).collect::<Vec<_>>();
+            let (mut values, mut targets): (Vec<_>, Vec<_>) =
+                values.iter().zip(targets.iter()).filter(|(_, &t)| !predicate(t)).unzip();
 
             if !predicate(*otherwise) {
                 targets.push(*otherwise);
@@ -89,20 +84,21 @@ where
             let retained_targets_len = targets.len();
 
             if targets.is_empty() {
-                Some(TerminatorKind::Unreachable)
+                TerminatorKind::Unreachable
             } else if targets.len() == 1 {
-                Some(TerminatorKind::Goto { target: targets[0] })
+                TerminatorKind::Goto { target: targets[0] }
             } else if original_targets_len != retained_targets_len {
-                Some(TerminatorKind::SwitchInt {
+                TerminatorKind::SwitchInt {
                     discr: discr.clone(),
                     switch_ty,
                     values: Cow::from(values),
                     targets,
-                })
+                }
             } else {
-                None
+                return None;
             }
         }
-        _ => None,
-    }
+        _ => return None,
+    };
+    Some(terminator)
 }