Struct LoopInfo
pub struct LoopInfo {
pub header: NodeId,
pub body: BitSet,
pub latches: Vec<NodeId>,
pub preheader: Option<NodeId>,
pub exits: Vec<LoopExit>,
pub depth: usize,
pub loop_type: LoopType,
pub parent: Option<NodeId>,
pub children: Vec<NodeId>,
}Expand description
Comprehensive loop information.
This extends NaturalLoop with additional structural information needed
for loop canonicalization and optimization.
Fields§
§header: NodeIdThe header block (single entry point, dominates all loop nodes).
body: BitSetAll blocks in the loop body (including header).
latches: Vec<NodeId>Back edge sources (blocks that jump to the header from within the loop).
preheader: Option<NodeId>Preheader block if one exists (single non-loop predecessor of header).
None if header has multiple non-loop predecessors or none.
exits: Vec<LoopExit>Exit edges from the loop.
depth: usizeLoop nesting depth (0 = outermost).
loop_type: LoopTypeClassification of the loop type.
parent: Option<NodeId>Parent loop header, if this loop is nested.
children: Vec<NodeId>Immediate child loop headers.
Implementations§
Source§impl LoopInfo
impl LoopInfo
Sourcepub fn new(header: NodeId, node_count: usize) -> LoopInfo
pub fn new(header: NodeId, node_count: usize) -> LoopInfo
Creates a new LoopInfo with the given header.
Sourcepub fn contains(&self, node: NodeId) -> bool
pub fn contains(&self, node: NodeId) -> bool
Returns true if this loop contains the given block.
Sourcepub fn has_single_latch(&self) -> bool
pub fn has_single_latch(&self) -> bool
Returns true if the loop has a single latch (canonical form).
Sourcepub fn single_latch(&self) -> Option<NodeId>
pub fn single_latch(&self) -> Option<NodeId>
Returns the single latch if there is exactly one.
Sourcepub fn has_preheader(&self) -> bool
pub fn has_preheader(&self) -> bool
Returns true if the loop has a preheader (canonical form).
Sourcepub fn is_canonical(&self) -> bool
pub fn is_canonical(&self) -> bool
Returns true if the loop is in canonical form.
A canonical loop has:
- A single preheader
- A single latch
Sourcepub fn is_innermost(&self) -> bool
pub fn is_innermost(&self) -> bool
Returns true if this is an innermost loop (no children).
Sourcepub fn is_outermost(&self) -> bool
pub fn is_outermost(&self) -> bool
Returns true if this is an outermost loop (no parent).
Sourcepub fn exit_blocks(&self) -> impl Iterator<Item = NodeId>
pub fn exit_blocks(&self) -> impl Iterator<Item = NodeId>
Returns all exit blocks (blocks outside loop reachable from inside).
Sourcepub fn exiting_blocks(&self) -> impl Iterator<Item = NodeId>
pub fn exiting_blocks(&self) -> impl Iterator<Item = NodeId>
Returns all exiting blocks (blocks inside loop that branch out).
Sourcepub fn exit_count(&self) -> usize
pub fn exit_count(&self) -> usize
Returns the number of exits from this loop.
Sourcepub fn header_is_exiting(&self) -> bool
pub fn header_is_exiting(&self) -> bool
Returns true if the header is also an exiting block.
This indicates a pre-tested loop (condition at entry).
Sourcepub fn latch_is_exiting(&self) -> bool
pub fn latch_is_exiting(&self) -> bool
Returns true if a latch is also an exiting block.
This indicates a post-tested loop (condition at end).
Sourcepub fn find_condition_in_body<T>(&self, ssa: &SsaFunction<T>) -> Option<NodeId>where
T: Target,
pub fn find_condition_in_body<T>(&self, ssa: &SsaFunction<T>) -> Option<NodeId>where
T: Target,
Finds the condition block inside the loop body.
For control-flow flattened code (e.g., ConfuserEx), the actual loop
condition is often inside a case block rather than at the dispatcher
header. This method searches for blocks with Branch instructions
within the loop body.
§Returns
Some(NodeId)- The first block found with a conditional branchNone- No conditional branch found in the loop body
Sourcepub fn find_all_conditions_in_body<T>(
&self,
ssa: &SsaFunction<T>,
) -> Vec<NodeId>where
T: Target,
pub fn find_all_conditions_in_body<T>(
&self,
ssa: &SsaFunction<T>,
) -> Vec<NodeId>where
T: Target,
Finds all conditional blocks within the loop body.
Unlike find_condition_in_body, this returns all blocks with
conditional branches, useful for complex loops with multiple exit points.
Sourcepub fn find_induction_vars<T>(&self, ssa: &SsaFunction<T>) -> Vec<InductionVar>where
T: Target,
pub fn find_induction_vars<T>(&self, ssa: &SsaFunction<T>) -> Vec<InductionVar>where
T: Target,
Identifies induction variables in this loop.
An induction variable is identified by finding phi nodes at the loop header where:
- One operand comes from outside the loop (initial value)
- One operand comes from inside the loop (updated value)
The method attempts to classify the update kind (add, sub, etc.) by analyzing the instruction that produces the update value.
§Returns
A vector of InductionVar structures describing each induction variable.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for LoopInfo
impl RefUnwindSafe for LoopInfo
impl Send for LoopInfo
impl Sync for LoopInfo
impl Unpin for LoopInfo
impl UnsafeUnpin for LoopInfo
impl UnwindSafe for LoopInfo
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for T
impl<T> Downcast for T
impl<T> ErasedDestructor for Twhere
T: 'static,
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 moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.