midenc_hir/ir/
usable.rs

1use super::{
2    entity::EntityIter, EntityCursor, EntityCursorMut, EntityList, EntityListItem,
3    UnsafeIntrusiveEntityRef,
4};
5
6/// The [Usable] trait is implemented for IR entities which are _defined_ and _used_, and as a
7/// result, require a data structure called the _use-def list_.
8///
9/// A _definition_ of an IR entity, is a unique instantiation of that entity, the result of which
10/// is different from all other definitions, even if the data associated with that definition is
11/// the same as another definition. For example, SSA values are defined as either block arguments
12/// or operation results, and a given value can only be defined once.
13///
14/// A _use_ represents a unique reference to a _definition_ of some IR entity. Each use is unique,
15/// and can be used to obtain not only the _user_ of the reference, but the location of that use
16/// within the user. Uses are tracked in a _use list_, also called the _use-def list_, which
17/// associates all uses to the definition, or _def_, that they reference. For example, operations
18/// in HIR _use_ SSA values defined previously in the program.
19///
20/// A _user_ does not have to be of the same IR type as the _definition_, and the type representing
21/// the _use_ is typically different than both, and represents the type of relationship between the
22/// two. For example, an `OpOperand` represents a single use of a `Value` by an `Op`. The entity
23/// being defined is a `Value`, the entity using that definition is an `Op`, and the data associated
24/// with each use is represented by `OpOperand`.
25pub trait Usable {
26    /// The type associated with each unique use, e.g. `OpOperand`
27    type Use: EntityListItem;
28
29    /// Get a list of uses of this definition
30    fn uses(&self) -> &EntityList<Self::Use>;
31    /// Get a mutable list of uses of this definition
32    fn uses_mut(&mut self) -> &mut EntityList<Self::Use>;
33
34    /// Returns true if this definition is used
35    #[inline]
36    fn is_used(&self) -> bool {
37        !self.uses().is_empty()
38    }
39    /// Get an iterator over the uses of this definition
40    #[inline]
41    fn iter_uses(&self) -> EntityIter<'_, Self::Use> {
42        self.uses().iter()
43    }
44    /// Get a cursor positioned on the first use of this definition, or the null cursor if unused.
45    fn first_use(&self) -> EntityCursor<'_, Self::Use> {
46        self.uses().front()
47    }
48    /// Get a mutable cursor positioned on the first use of this definition, or the null cursor if
49    /// unused.
50    #[inline]
51    fn first_use_mut(&mut self) -> EntityCursorMut<'_, Self::Use> {
52        self.uses_mut().front_mut()
53    }
54    /// Add `user` to the set of uses of this definition
55    fn insert_use(&mut self, user: UnsafeIntrusiveEntityRef<Self::Use>) {
56        self.uses_mut().push_back(user);
57    }
58}