diff options
| -rw-r--r-- | src/librustc_mir/transform/add_retag.rs | 38 | ||||
| -rw-r--r-- | src/librustc_mir/transform/deaggregator.rs | 24 | ||||
| -rw-r--r-- | src/librustc_mir/transform/unreachable_prop.rs | 39 |
3 files changed, 50 insertions, 51 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/unreachable_prop.rs b/src/librustc_mir/transform/unreachable_prop.rs index d9f2259030f..e2f8917156b 100644 --- a/src/librustc_mir/transform/unreachable_prop.rs +++ b/src/librustc_mir/transform/unreachable_prop.rs @@ -67,18 +67,24 @@ 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::FalseEdge { real_target, imaginary_target } + if predicate(real_target) && predicate(imaginary_target) => + { + TerminatorKind::Unreachable + } + TerminatorKind::FalseUnwind { real_target, unwind } + if predicate(real_target) && unwind.map_or(true, &predicate) => + { + TerminatorKind::Unreachable + } + + 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 +95,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) } |
