Skip to content

Commit

Permalink
Make HasTop and HasBottom consts.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed May 9, 2023
1 parent f7b831a commit 71138e9
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 34 deletions.
20 changes: 6 additions & 14 deletions compiler/rustc_mir_dataflow/src/framework/lattice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ pub trait MeetSemiLattice: Eq {

/// A set that has a "bottom" element, which is less than or equal to any other element.
pub trait HasBottom {
fn bottom() -> Self;
const BOTTOM: Self;
}

/// A set that has a "top" element, which is greater than or equal to any other element.
pub trait HasTop {
fn top() -> Self;
const TOP: Self;
}

/// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom:
Expand Down Expand Up @@ -113,15 +113,11 @@ impl MeetSemiLattice for bool {
}

impl HasBottom for bool {
fn bottom() -> Self {
false
}
const BOTTOM: Self = false;
}

impl HasTop for bool {
fn top() -> Self {
true
}
const TOP: Self = true;
}

/// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation
Expand Down Expand Up @@ -274,13 +270,9 @@ impl<T: Clone + Eq> MeetSemiLattice for FlatSet<T> {
}

impl<T> HasBottom for FlatSet<T> {
fn bottom() -> Self {
Self::Bottom
}
const BOTTOM: Self = Self::Bottom;
}

impl<T> HasTop for FlatSet<T> {
fn top() -> Self {
Self::Top
}
const TOP: Self = Self::Top;
}
34 changes: 16 additions & 18 deletions compiler/rustc_mir_dataflow/src/value_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ pub trait ValueAnalysis<'tcx> {
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
// StorageLive leaves the local in an uninitialized state.
// StorageDead makes it UB to access the local afterwards.
state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::bottom());
state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::BOTTOM);
}
StatementKind::Deinit(box place) => {
// Deinit makes the place uninitialized.
state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM);
}
StatementKind::Retag(..) => {
// We don't track references.
Expand Down Expand Up @@ -154,7 +154,7 @@ pub trait ValueAnalysis<'tcx> {
Rvalue::CopyForDeref(place) => self.handle_operand(&Operand::Copy(*place), state),
Rvalue::Ref(..) | Rvalue::AddressOf(..) => {
// We don't track such places.
ValueOrPlace::top()
ValueOrPlace::TOP
}
Rvalue::Repeat(..)
| Rvalue::ThreadLocalRef(..)
Expand All @@ -168,7 +168,7 @@ pub trait ValueAnalysis<'tcx> {
| Rvalue::Aggregate(..)
| Rvalue::ShallowInitBox(..) => {
// No modification is possible through these r-values.
ValueOrPlace::top()
ValueOrPlace::TOP
}
}
}
Expand Down Expand Up @@ -196,7 +196,7 @@ pub trait ValueAnalysis<'tcx> {
self.map()
.find(place.as_ref())
.map(ValueOrPlace::Place)
.unwrap_or(ValueOrPlace::top())
.unwrap_or(ValueOrPlace::TOP)
}
}
}
Expand All @@ -214,7 +214,7 @@ pub trait ValueAnalysis<'tcx> {
_constant: &Constant<'tcx>,
_state: &mut State<Self::Value>,
) -> Self::Value {
Self::Value::top()
Self::Value::TOP
}

/// The effect of a successful function call return should not be
Expand All @@ -229,7 +229,7 @@ pub trait ValueAnalysis<'tcx> {
// Effect is applied by `handle_call_return`.
}
TerminatorKind::Drop { place, .. } => {
state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM);
}
TerminatorKind::Yield { .. } => {
// They would have an effect, but are not allowed in this phase.
Expand Down Expand Up @@ -307,7 +307,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
// The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥.
assert!(matches!(state.0, StateData::Unreachable));
let values = IndexVec::from_elem_n(T::Value::bottom(), self.0.map().value_count);
let values = IndexVec::from_elem_n(T::Value::BOTTOM, self.0.map().value_count);
*state = State(StateData::Reachable(values));
for arg in body.args_iter() {
state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map());
Expand Down Expand Up @@ -437,7 +437,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
}

pub fn flood_all(&mut self) {
self.flood_all_with(V::top())
self.flood_all_with(V::TOP)
}

pub fn flood_all_with(&mut self, value: V) {
Expand All @@ -455,7 +455,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
}

pub fn flood(&mut self, place: PlaceRef<'_>, map: &Map) {
self.flood_with(place, map, V::top())
self.flood_with(place, map, V::TOP)
}

pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
Expand All @@ -468,7 +468,7 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
}

pub fn flood_discr(&mut self, place: PlaceRef<'_>, map: &Map) {
self.flood_discr_with(place, map, V::top())
self.flood_discr_with(place, map, V::TOP)
}

/// Low-level method that assigns to a place.
Expand Down Expand Up @@ -538,26 +538,26 @@ impl<V: Clone + HasTop + HasBottom> State<V> {

/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
pub fn get(&self, place: PlaceRef<'_>, map: &Map) -> V {
map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::top())
map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::TOP)
}

/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
pub fn get_discr(&self, place: PlaceRef<'_>, map: &Map) -> V {
match map.find_discr(place) {
Some(place) => self.get_idx(place, map),
None => V::top(),
None => V::TOP,
}
}

/// Retrieve the value stored for a place index, or ⊤ if it is not tracked.
pub fn get_idx(&self, place: PlaceIndex, map: &Map) -> V {
match &self.0 {
StateData::Reachable(values) => {
map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::top())
map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::TOP)
}
StateData::Unreachable => {
// Because this is unreachable, we can return any value we want.
V::bottom()
V::BOTTOM
}
}
}
Expand Down Expand Up @@ -909,9 +909,7 @@ pub enum ValueOrPlace<V> {
}

impl<V: HasTop> ValueOrPlace<V> {
pub fn top() -> Self {
ValueOrPlace::Value(V::top())
}
pub const TOP: Self = ValueOrPlace::Value(V::TOP);
}

/// The set of projection elements that can be used by a tracked place.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/dataflow_const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
_ => unreachable!(),
}
.map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty)))
.unwrap_or(ValueOrPlace::top()),
_ => ValueOrPlace::top(),
.unwrap_or(ValueOrPlace::TOP),
_ => ValueOrPlace::TOP,
},
Rvalue::BinaryOp(op, box (left, right)) => {
// Overflows must be ignored here.
Expand Down

0 comments on commit 71138e9

Please sign in to comment.