@@ -668,6 +668,26 @@ pub trait BottomValue {
668
668
const BOTTOM_VALUE : bool ;
669
669
670
670
/// Merges `in_set` into `inout_set`, returning `true` if `inout_set` changed.
671
+ ///
672
+ /// It is almost certainly wrong to override this, since it automatically applies
673
+ /// * `inout_set & in_set` if `BOTTOM_VALUE == true`
674
+ /// * `inout_set | in_set` if `BOTTOM_VALUE == false`
675
+ ///
676
+ /// This means that if a bit is not `BOTTOM_VALUE`, it is propagated into all target blocks.
677
+ /// For clarity, the above statement again from a different perspective:
678
+ /// A bit in the block's entry set is `!BOTTOM_VALUE` if *any* predecessor block's bit value is
679
+ /// `!BOTTOM_VALUE`.
680
+ ///
681
+ /// There are situations where you want the opposite behaviour: propagate only if *all*
682
+ /// predecessor blocks's value is `!BOTTOM_VALUE`.
683
+ /// E.g. if you want to know whether a bit is *definitely* set at a specific location. This
684
+ /// means that all code paths leading to the location must have set the bit, instead of any
685
+ /// code path leading there.
686
+ ///
687
+ /// If you want this kind of "definitely set" analysis, you need to
688
+ /// 1. Invert `BOTTOM_VALUE`
689
+ /// 2. Reset the `entry_set` in `start_block_effect` to `!BOTTOM_VALUE`
690
+ /// 3. Override `join` to do the opposite from what it's doing now.
671
691
#[ inline]
672
692
fn join < T : Idx > ( & self , inout_set : & mut BitSet < T > , in_set : & BitSet < T > ) -> bool {
673
693
if Self :: BOTTOM_VALUE == false {
@@ -685,7 +705,9 @@ pub trait BottomValue {
685
705
/// for each block individually. The entry set for all other basic blocks is
686
706
/// initialized to `Self::BOTTOM_VALUE`. The dataflow analysis then
687
707
/// iteratively modifies the various entry sets (but leaves the the transfer
688
- /// function unchanged).
708
+ /// function unchanged). `BottomValue::join` is used to merge the bitsets from
709
+ /// two blocks (e.g. when two blocks' terminator jumps to a single block, that
710
+ /// target block's state is the merged state of both incoming blocks).
689
711
pub trait BitDenotation < ' tcx > : BottomValue {
690
712
/// Specifies what index type is used to access the bitvector.
691
713
type Idx : Idx ;
0 commit comments