pub struct ReachingDefinitions {
pub reach_in: HashMap<BlockId, HashSet<VarId>>,
pub reach_out: HashMap<BlockId, HashSet<VarId>>,
pub def_use_chains: HashMap<VarId, HashSet<BlockId>>,
pub precise_def_use: HashMap<Definition, HashSet<ProgramPoint>>,
pub use_def_chains: HashMap<Use, HashSet<Definition>>,
pub all_definitions: Vec<Definition>,
pub all_uses: Vec<Use>,
}Expand description
Reaching definitions analysis (forward data flow analysis).
Tracks which variable definitions reach each program point. This enables def-use chain construction and SSA-like analysis.
§Example
let cfg = ControlFlowGraph::from_block(&block);
let reaching = ReachingDefinitions::analyze(&cfg);
// Check which definitions of x reach a specific block
let var_id = VarId { name_id: 0, version: 0 };
if let Some(defs) = reaching.reach_in.get(&block_id) {
if defs.contains(&var_id) {
println!("Definition of x.0 reaches this block");
}
}
// Statement-level: check if a specific definition is dead
for def in &reaching.all_definitions {
if reaching.is_dead_definition(def) {
println!("Dead store at {:?}", def.point);
}
}Fields§
§reach_in: HashMap<BlockId, HashSet<VarId>>Definitions that reach the entry of each block
reach_out: HashMap<BlockId, HashSet<VarId>>Definitions that reach the exit of each block
def_use_chains: HashMap<VarId, HashSet<BlockId>>Def-use chains at block level (backward compatibility)
precise_def_use: HashMap<Definition, HashSet<ProgramPoint>>Precise def-use chains: definition point → use points
use_def_chains: HashMap<Use, HashSet<Definition>>Use-def chains (inverse): use point → reaching definitions
all_definitions: Vec<Definition>All definitions in the program
all_uses: Vec<Use>All uses in the program
Implementations§
Source§impl ReachingDefinitions
impl ReachingDefinitions
Sourcepub fn analyze(cfg: &ControlFlowGraph) -> Self
pub fn analyze(cfg: &ControlFlowGraph) -> Self
Compute reaching definitions for a CFG using forward data flow analysis.
This performs both block-level analysis (for backward compatibility) and statement-level analysis for precise def-use chains.
Sourcepub fn get_uses_of(&self, def: &Definition) -> Option<&HashSet<ProgramPoint>>
pub fn get_uses_of(&self, def: &Definition) -> Option<&HashSet<ProgramPoint>>
Get all uses of a specific definition (statement-level).
Sourcepub fn get_defs_of(&self, use_point: &Use) -> Option<&HashSet<Definition>>
pub fn get_defs_of(&self, use_point: &Use) -> Option<&HashSet<Definition>>
Get all definitions that reach a specific use (statement-level).
Sourcepub fn is_dead_definition(&self, def: &Definition) -> bool
pub fn is_dead_definition(&self, def: &Definition) -> bool
Check if a definition is dead (no uses).
Sourcepub fn find_same_block_dead_stores(&self) -> Vec<Definition>
pub fn find_same_block_dead_stores(&self) -> Vec<Definition>
Find same-block dead stores: defs with no uses at all.
Sourcepub fn get_unique_def(&self, use_point: &Use) -> Option<Definition>
pub fn get_unique_def(&self, use_point: &Use) -> Option<Definition>
Get the single reaching definition for a use (if unique).
Trait Implementations§
Source§impl Clone for ReachingDefinitions
impl Clone for ReachingDefinitions
Source§fn clone(&self) -> ReachingDefinitions
fn clone(&self) -> ReachingDefinitions
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ReachingDefinitions
impl Debug for ReachingDefinitions
Source§impl Default for ReachingDefinitions
impl Default for ReachingDefinitions
Source§fn default() -> ReachingDefinitions
fn default() -> ReachingDefinitions
Auto Trait Implementations§
impl Freeze for ReachingDefinitions
impl RefUnwindSafe for ReachingDefinitions
impl Send for ReachingDefinitions
impl Sync for ReachingDefinitions
impl Unpin for ReachingDefinitions
impl UnsafeUnpin for ReachingDefinitions
impl UnwindSafe for ReachingDefinitions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> EnsureExt<T> for T
impl<T> EnsureExt<T> for T
Source§fn ensure<P, E>(self, predicate: P, error: E) -> Validation<T, NonEmptyVec<E>>where
P: Predicate<T>,
fn ensure<P, E>(self, predicate: P, error: E) -> Validation<T, NonEmptyVec<E>>where
P: Predicate<T>,
Source§fn ensure_with<P, E, F>(
self,
predicate: P,
error_fn: F,
) -> Validation<T, NonEmptyVec<E>>
fn ensure_with<P, E, F>( self, predicate: P, error_fn: F, ) -> Validation<T, NonEmptyVec<E>>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more