[−][src]Trait rustc_mir::dataflow::framework::BottomValue

pub trait BottomValue {
    const BOTTOM_VALUE: bool;
    fn join<T: Idx>(
        &self,
        inout_set: &mut BitSet<T>,
        in_set: &BitSet<T>
    ) -> bool { ... } }

Parameterization for the precise form of data flow that is used.

BottomValue determines whether the initial entry set for each basic block is empty or full. This also determines the semantics of the lattice join operator used to merge dataflow results, since dataflow works by starting at the bottom and moving monotonically to a fixed point.

This means, for propagation across the graph, that you either want to start at all-zeroes and then use Union as your merge when propagating, or you start at all-ones and then use Intersect as your merge when propagating.

Associated Constants

const BOTTOM_VALUE: bool

Specifies the initial value for each bit in the entry set for each basic block.

Loading content...

Provided methods

fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool

Merges in_set into inout_set, returning true if inout_set changed.

It is almost certainly wrong to override this, since it automatically applies

  • inout_set & in_set if BOTTOM_VALUE == true
  • inout_set | in_set if BOTTOM_VALUE == false

This means that if a bit is not BOTTOM_VALUE, it is propagated into all target blocks. For clarity, the above statement again from a different perspective: A bit in the block's entry set is !BOTTOM_VALUE if any predecessor block's bit value is !BOTTOM_VALUE.

There are situations where you want the opposite behaviour: propagate only if all predecessor blocks's value is !BOTTOM_VALUE. E.g. if you want to know whether a bit is definitely set at a specific location. This means that all code paths leading to the location must have set the bit, instead of any code path leading there.

If you want this kind of "definitely set" analysis, you need to

  1. Invert BOTTOM_VALUE
  2. Reset the entry_set in start_block_effect to !BOTTOM_VALUE
  3. Override join to do the opposite from what it's doing now.
Loading content...

Implementors

impl BottomValue for MaybeInitializedLocals[src]

const BOTTOM_VALUE: bool[src]

bottom = uninit

impl BottomValue for MaybeLiveLocals[src]

impl BottomValue for MaybeStorageLive[src]

const BOTTOM_VALUE: bool[src]

bottom = dead

impl<'a, 'tcx> BottomValue for Borrows<'a, 'tcx>[src]

const BOTTOM_VALUE: bool[src]

bottom = nothing is reserved or activated yet;

impl<'a, 'tcx> BottomValue for DefinitelyInitializedPlaces<'a, 'tcx>[src]

const BOTTOM_VALUE: bool[src]

bottom = initialized (start_block_effect counters this at outset)

impl<'a, 'tcx> BottomValue for EverInitializedPlaces<'a, 'tcx>[src]

const BOTTOM_VALUE: bool[src]

bottom = no initialized variables by default

impl<'a, 'tcx> BottomValue for MaybeInitializedPlaces<'a, 'tcx>[src]

const BOTTOM_VALUE: bool[src]

bottom = uninitialized

impl<'a, 'tcx> BottomValue for MaybeUninitializedPlaces<'a, 'tcx>[src]

const BOTTOM_VALUE: bool[src]

bottom = initialized (start_block_effect counters this at outset)

impl<'mir, 'tcx> BottomValue for MaybeRequiresStorage<'mir, 'tcx>[src]

const BOTTOM_VALUE: bool[src]

bottom = dead

impl<K> BottomValue for MaybeBorrowedLocals<K>[src]

impl<Q, '_, '_, '_> BottomValue for FlowSensitiveAnalysis<'_, '_, '_, Q>[src]

Loading content...