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§

source

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.

source

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§

source

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§

source§

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;
}
source§

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;
}