Remove unneeded field from SwitchTargets

This commit is contained in:
Jakob Degen 2022-12-03 16:03:27 -08:00
parent 14ca83a04b
commit 9fb8da8f8f
131 changed files with 304 additions and 388 deletions

View file

@ -82,8 +82,9 @@ impl<'tcx> Visitor<'tcx> for ConstGotoOptimizationFinder<'_, 'tcx> {
}
let target_bb_terminator = target_bb.terminator();
let (discr, switch_ty, targets) = target_bb_terminator.kind.as_switch()?;
let (discr, targets) = target_bb_terminator.kind.as_switch()?;
if discr.place() == Some(*place) {
let switch_ty = place.ty(self.body.local_decls(), self.tcx).ty;
// We now know that the Switch matches on the const place, and it is statementless
// Now find which value in the Switch matches the const value.
let const_value =

View file

@ -37,7 +37,7 @@ use rustc_data_structures::graph::WithSuccessors;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::coverage::CoverageKind;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty;
use rustc_span::{self, BytePos, Pos, Span, DUMMY_SP};
// All `TEMP_BLOCK` targets should be replaced before calling `to_body() -> mir::Body`.
@ -47,7 +47,6 @@ struct MockBlocks<'tcx> {
blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
dummy_place: Place<'tcx>,
next_local: usize,
bool_ty: Ty<'tcx>,
}
impl<'tcx> MockBlocks<'tcx> {
@ -56,7 +55,6 @@ impl<'tcx> MockBlocks<'tcx> {
blocks: IndexVec::new(),
dummy_place: Place { local: RETURN_PLACE, projection: ty::List::empty() },
next_local: 0,
bool_ty: TyCtxt::BOOL_TY_FOR_UNIT_TESTING,
}
}
@ -157,7 +155,6 @@ impl<'tcx> MockBlocks<'tcx> {
fn switchint(&mut self, some_from_block: Option<BasicBlock>) -> BasicBlock {
let switchint_kind = TerminatorKind::SwitchInt {
discr: Operand::Move(Place::from(self.new_temp())),
switch_ty: self.bool_ty, // just a dummy value
targets: SwitchTargets::static_if(0, TEMP_BLOCK, TEMP_BLOCK),
};
self.add_block_from(some_from_block, switchint_kind)

View file

@ -121,7 +121,6 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
let TerminatorKind::SwitchInt {
discr: parent_op,
switch_ty: parent_ty,
targets: parent_targets
} = &bbs[parent].terminator().kind else {
unreachable!()
@ -132,6 +131,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
Operand::Copy(x) => Operand::Copy(*x),
Operand::Constant(x) => Operand::Constant(x.clone()),
};
let parent_ty = parent_op.ty(body.local_decls(), tcx);
let statements_before = bbs[parent].statements.len();
let parent_end = Location { block: parent, statement_index: statements_before };
@ -153,7 +153,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
// create temp to store inequality comparison between the two discriminants, `_t` in
// example above
let nequal = BinOp::Ne;
let comp_res_type = nequal.ty(tcx, *parent_ty, opt_data.child_ty);
let comp_res_type = nequal.ty(tcx, parent_ty, opt_data.child_ty);
let comp_temp = patch.new_temp(comp_res_type, opt_data.child_source.span);
patch.add_statement(parent_end, StatementKind::StorageLive(comp_temp));
@ -181,7 +181,6 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
kind: TerminatorKind::SwitchInt {
// switch on the first discriminant, so we can mark the second one as dead
discr: parent_op,
switch_ty: opt_data.child_ty,
targets: eq_targets,
},
}));
@ -193,12 +192,7 @@ impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
let false_case = eq_bb;
patch.patch_terminator(
parent,
TerminatorKind::if_(
tcx,
Operand::Move(Place::from(comp_temp)),
true_case,
false_case,
),
TerminatorKind::if_(Operand::Move(Place::from(comp_temp)), true_case, false_case),
);
// generate StorageDead for the second_discriminant_temp not in use anymore
@ -319,11 +313,11 @@ fn evaluate_candidate<'tcx>(
let bbs = &body.basic_blocks;
let TerminatorKind::SwitchInt {
targets,
switch_ty: parent_ty,
..
discr: parent_discr,
} = &bbs[parent].terminator().kind else {
return None
};
let parent_ty = parent_discr.ty(body.local_decls(), tcx);
let parent_dest = {
let poss = targets.otherwise();
// If the fallthrough on the parent is trivially unreachable, we can let the
@ -339,12 +333,12 @@ fn evaluate_candidate<'tcx>(
let (_, child) = targets.iter().next()?;
let child_terminator = &bbs[child].terminator();
let TerminatorKind::SwitchInt {
switch_ty: child_ty,
targets: child_targets,
..
discr: child_discr,
} = &child_terminator.kind else {
return None
};
let child_ty = child_discr.ty(body.local_decls(), tcx);
if child_ty != parent_ty {
return None;
}
@ -372,7 +366,7 @@ fn evaluate_candidate<'tcx>(
Some(OptimizationData {
destination,
child_place: *child_place,
child_ty: *child_ty,
child_ty,
child_source: child_terminator.source_info,
})
}

View file

@ -877,11 +877,7 @@ fn insert_switch<'tcx>(
let (assign, discr) = transform.get_discr(body);
let switch_targets =
SwitchTargets::new(cases.iter().map(|(i, bb)| ((*i) as u128, *bb)), default_block);
let switch = TerminatorKind::SwitchInt {
discr: Operand::Move(discr),
switch_ty: transform.discr_ty,
targets: switch_targets,
};
let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), targets: switch_targets };
let source_info = SourceInfo::outermost(body.span);
body.basic_blocks_mut().raw.insert(

View file

@ -55,10 +55,9 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
continue;
}
let (discr, val, switch_ty, first, second) = match bbs[bb_idx].terminator().kind {
let (discr, val, first, second) = match bbs[bb_idx].terminator().kind {
TerminatorKind::SwitchInt {
discr: ref discr @ (Operand::Copy(_) | Operand::Move(_)),
switch_ty,
ref targets,
..
} if targets.iter().len() == 1 => {
@ -66,7 +65,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
if target == targets.otherwise() {
continue;
}
(discr, value, switch_ty, target, targets.otherwise())
(discr, value, target, targets.otherwise())
}
// Only optimize switch int statements
_ => continue,
@ -105,10 +104,11 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
}
// Take ownership of items now that we know we can optimize.
let discr = discr.clone();
let discr_ty = discr.ty(&body.local_decls, tcx);
// Introduce a temporary for the discriminant value.
let source_info = bbs[bb_idx].terminator().source_info;
let discr_local = body.local_decls.push(LocalDecl::new(switch_ty, source_info.span));
let discr_local = body.local_decls.push(LocalDecl::new(discr_ty, source_info.span));
// We already checked that first and second are different blocks,
// and bb_idx has a different terminator from both of them.
@ -130,10 +130,10 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
(*f).clone()
} else {
// Different value between blocks. Make value conditional on switch condition.
let size = tcx.layout_of(param_env.and(switch_ty)).unwrap().size;
let size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size;
let const_cmp = Operand::const_from_scalar(
tcx,
switch_ty,
discr_ty,
rustc_const_eval::interpret::Scalar::from_uint(val, size),
rustc_span::DUMMY_SP,
);

View file

@ -548,7 +548,6 @@ impl<'tcx> CloneShimBuilder<'tcx> {
statements.push(statement);
*kind = TerminatorKind::SwitchInt {
discr: Operand::Move(temp),
switch_ty: discr_ty,
targets: SwitchTargets::new(cases.into_iter(), unreachable),
};
}

View file

@ -24,12 +24,9 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
let terminator = block.terminator_mut();
terminator.kind = match terminator.kind {
TerminatorKind::SwitchInt {
discr: Operand::Constant(ref c),
switch_ty,
ref targets,
..
discr: Operand::Constant(ref c), ref targets, ..
} => {
let constant = c.literal.try_eval_bits(tcx, param_env, switch_ty);
let constant = c.literal.try_eval_bits(tcx, param_env, c.ty());
if let Some(constant) = constant {
let target = targets.target_for_value(constant);
TerminatorKind::Goto { target }

View file

@ -127,11 +127,8 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
let targets = SwitchTargets::new(iter::once((new_value, bb_cond)), bb_otherwise);
let terminator = bb.terminator_mut();
terminator.kind = TerminatorKind::SwitchInt {
discr: Operand::Move(opt.to_switch_on),
switch_ty: opt.branch_value_ty,
targets,
};
terminator.kind =
TerminatorKind::SwitchInt { discr: Operand::Move(opt.to_switch_on), targets };
}
for (idx, bb_idx) in storage_deads_to_remove {

View file

@ -76,7 +76,7 @@ where
let terminator = match terminator_kind {
// This will unconditionally run into an unreachable and is therefore unreachable as well.
TerminatorKind::Goto { target } if is_unreachable(*target) => TerminatorKind::Unreachable,
TerminatorKind::SwitchInt { targets, discr, switch_ty } => {
TerminatorKind::SwitchInt { targets, discr } => {
let otherwise = targets.otherwise();
// If all targets are unreachable, we can be unreachable as well.
@ -110,11 +110,7 @@ where
return None;
}
TerminatorKind::SwitchInt {
discr: discr.clone(),
switch_ty: *switch_ty,
targets: new_targets,
}
TerminatorKind::SwitchInt { discr: discr.clone(), targets: new_targets }
} else {
// If the otherwise branch is reachable, we don't want to delete any unreachable branches.
return None;