@@ -650,6 +650,20 @@ pub trait BottomValue {
650
650
const BOTTOM_VALUE : bool ;
651
651
652
652
/// Merges `in_set` into `inout_set`, returning `true` if `inout_set` changed.
653
+ ///
654
+ /// You usually don't need to override this, since it automatically applies
655
+ /// * `inout_set & in_set` if `BOTTOM_VALUE == true`
656
+ /// * `inout_set | in_set` if `BOTTOM_VALUE == false`
657
+ ///
658
+ /// This means that if a bit is not `BOTTOM_VALUE`, it is propagated into all target blocks.
659
+ /// For clarity, the above statement again from a different perspective:
660
+ /// A block's initial bit value is `!BOTTOM_VALUE` if *any* predecessor block's bit value is
661
+ /// `!BOTTOM_VALUE`.
662
+ /// There are situations where you want the opposite behaviour: propagate only if *all*
663
+ /// predecessor blocks's value is `!BOTTOM_VALUE`. In that case you need to
664
+ /// 1. Invert `BOTTOM_VALUE`
665
+ /// 2. Reset the `entry_set` in `start_block_effect` to `!BOTTOM_VALUE`
666
+ /// 3. Override `join` to do the opposite from what it's doing now.
653
667
#[ inline]
654
668
fn join < T : Idx > ( & self , inout_set : & mut BitSet < T > , in_set : & BitSet < T > ) -> bool {
655
669
if Self :: BOTTOM_VALUE == false {
@@ -667,7 +681,9 @@ pub trait BottomValue {
667
681
/// for each block individually. The entry set for all other basic blocks is
668
682
/// initialized to `Self::BOTTOM_VALUE`. The dataflow analysis then
669
683
/// iteratively modifies the various entry sets (but leaves the the transfer
670
- /// function unchanged).
684
+ /// function unchanged). `BottomValue::join` is used to merge the bitsets from
685
+ /// two blocks (e.g. when two blocks' terminator jumps to a single block, that
686
+ /// target block's state is the merged state of both incoming blocks).
671
687
pub trait BitDenotation < ' tcx > : BottomValue {
672
688
/// Specifies what index type is used to access the bitvector.
673
689
type Idx : Idx ;
0 commit comments