Skip to content

Clean up some mir transform passes #75503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 16 additions & 22 deletions src/librustc_mir/transform/add_retag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
}),
Expand All @@ -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(
Expand Down
24 changes: 11 additions & 13 deletions src/librustc_mir/transform/deaggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
};

Expand Down
43 changes: 21 additions & 22 deletions src/librustc_mir/transform/simplify_try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
}
}
Expand All @@ -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,
}
}
Expand Down
32 changes: 12 additions & 20 deletions src/librustc_mir/transform/uninhabited_enum_branching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
}
Expand Down
28 changes: 12 additions & 16 deletions src/librustc_mir/transform/unreachable_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
}