trait SimplifyMatch<'tcx> {
// Required methods
fn can_simplify(
&mut self,
tcx: TyCtxt<'tcx>,
targets: &SwitchTargets,
param_env: ParamEnv<'tcx>,
bbs: &IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
discr_ty: Ty<'tcx>,
) -> Option<()>;
fn new_stmts(
&self,
tcx: TyCtxt<'tcx>,
targets: &SwitchTargets,
param_env: ParamEnv<'tcx>,
patch: &mut MirPatch<'tcx>,
parent_end: Location,
bbs: &IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
discr_local: Local,
discr_ty: Ty<'tcx>,
);
// Provided method
fn simplify(
&mut self,
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
switch_bb_idx: BasicBlock,
param_env: ParamEnv<'tcx>,
) -> Option<()> { ... }
}
Required Methods§
sourcefn can_simplify(
&mut self,
tcx: TyCtxt<'tcx>,
targets: &SwitchTargets,
param_env: ParamEnv<'tcx>,
bbs: &IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
discr_ty: Ty<'tcx>,
) -> Option<()>
fn can_simplify( &mut self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, param_env: ParamEnv<'tcx>, bbs: &IndexSlice<BasicBlock, BasicBlockData<'tcx>>, discr_ty: Ty<'tcx>, ) -> Option<()>
Check that the BBs to be simplified satisfies all distinct and that the terminator are the same. There are also conditions for different ways of simplification.
fn new_stmts( &self, tcx: TyCtxt<'tcx>, targets: &SwitchTargets, param_env: ParamEnv<'tcx>, patch: &mut MirPatch<'tcx>, parent_end: Location, bbs: &IndexSlice<BasicBlock, BasicBlockData<'tcx>>, discr_local: Local, discr_ty: Ty<'tcx>, )
Provided Methods§
sourcefn simplify(
&mut self,
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
switch_bb_idx: BasicBlock,
param_env: ParamEnv<'tcx>,
) -> Option<()>
fn simplify( &mut self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, switch_bb_idx: BasicBlock, param_env: ParamEnv<'tcx>, ) -> Option<()>
Simplifies a match statement, returning true if the simplification succeeds, false otherwise. Generic code is written here, and we generally don’t need a custom implementation.
Implementors§
impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp
If we find that the value of match is the same as the assignment, merge a target block statements into the source block, using cast to transform different integer types.
For example:
bb0: {
switchInt(_1) -> [1: bb2, 2: bb3, 3: bb4, otherwise: bb1];
}
bb1: {
unreachable;
}
bb2: {
_0 = const 1_i16;
goto -> bb5;
}
bb3: {
_0 = const 2_i16;
goto -> bb5;
}
bb4: {
_0 = const 3_i16;
goto -> bb5;
}
into:
bb0: {
_0 = _3 as i16 (IntToInt);
goto -> bb5;
}
impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf
If a source block is found that switches between two blocks that are exactly the same modulo const bool assignments (e.g., one assigns true another false to the same place), merge a target block statements into the source block, using Eq / Ne comparison with switch value where const bools value differ.
For example:
bb0: {
switchInt(move _3) -> [42_isize: bb1, otherwise: bb2];
}
bb1: {
_2 = const true;
goto -> bb3;
}
bb2: {
_2 = const false;
goto -> bb3;
}
into:
bb0: {
_2 = Eq(move _3, const 42_isize);
goto -> bb3;
}