From 9158e17997db0a21a27774a66b944539f4ef441a Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sun, 15 Dec 2019 09:42:09 +0100 Subject: [PATCH] Document more use cases of dataflow --- src/librustc_mir/dataflow/mod.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index ad0f75d77254..af16adf9eb32 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -650,6 +650,20 @@ pub trait BottomValue { const BOTTOM_VALUE: bool; /// Merges `in_set` into `inout_set`, returning `true` if `inout_set` changed. + /// + /// You usually don't need 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 block's initial bit value 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`. In that case 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. #[inline] fn join(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool { if Self::BOTTOM_VALUE == false { @@ -667,7 +681,9 @@ pub trait BottomValue { /// for each block individually. The entry set for all other basic blocks is /// initialized to `Self::BOTTOM_VALUE`. The dataflow analysis then /// iteratively modifies the various entry sets (but leaves the the transfer -/// function unchanged). +/// function unchanged). `BottomValue::join` is used to merge the bitsets from +/// two blocks (e.g. when two blocks' terminator jumps to a single block, that +/// target block's state is the merged state of both incoming blocks). pub trait BitDenotation<'tcx>: BottomValue { /// Specifies what index type is used to access the bitvector. type Idx: Idx;