pub(crate) struct LoopSensitivityAnalyzer<'tcx> {
tcx: TyCtxt<'tcx>,
}Expand description
Computes the repeat plan for one verification target.
The analyzer is intentionally target-local. It does not cache across functions because MIR bodies, SCCs, and property roots are small enough for the current auto pass, and keeping the state local prevents stale repeat choices when the same function is checked under a virtual target.
Fields§
§tcx: TyCtxt<'tcx>Implementations§
Source§impl<'tcx> LoopSensitivityAnalyzer<'tcx>
impl<'tcx> LoopSensitivityAnalyzer<'tcx>
Sourcepub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self
pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self
Create an analyzer over the current compiler type context.
Sourcepub(crate) fn analyze(&self, target: &FunctionTarget<'tcx>) -> RepeatPlan
pub(crate) fn analyze(&self, target: &FunctionTarget<'tcx>) -> RepeatPlan
Build a loop-sensitivity repeat plan for target.
The algorithm is:
- Collect all safety sinks and bind their roots to caller locals.
- Build an SCC-aware
PathGraphfor the target function. - Build a whole-function local dependency index.
- Produce dataflow-distance hints from loop-carried local transfers.
- Produce numeric-range hints from simple induction-sensitive sinks.
- Calibrate both hint streams into one repeat budget.
This is a conservative planner: it may choose a deeper repeat for loops that turn out to be safe, but it avoids adding tag-specific verifier reruns or new user-visible output.
Sourcefn dataflow_distance_hints<'target>(
&self,
sinks: &[SafetySink<'target, 'tcx>],
graph: &PathGraph<'_>,
dependencies: &LocalDependencyIndex,
component_summaries: &[(LoopComponent, LoopLocalSummary, LoopNumericSummary)],
) -> Vec<DataflowDistanceHint>
fn dataflow_distance_hints<'target>( &self, sinks: &[SafetySink<'target, 'tcx>], graph: &PathGraph<'_>, dependencies: &LocalDependencyIndex, component_summaries: &[(LoopComponent, LoopLocalSummary, LoopNumericSummary)], ) -> Vec<DataflowDistanceHint>
Compute loop-carried dataflow hints for every safety sink.
This detector is tag-agnostic: it only asks whether the sink’s caller locals depend on state locals that are redefined across an SCC. The concrete safety checker remains responsible for deciding whether the propagated value is actually invalid once the deeper path is enumerated.
Sourcefn numeric_range_hints<'target>(
&self,
sinks: &[SafetySink<'target, 'tcx>],
graph: &PathGraph<'_>,
dependencies: &LocalDependencyIndex,
component_summaries: &[(LoopComponent, LoopLocalSummary, LoopNumericSummary)],
) -> Vec<NumericRangeHint>
fn numeric_range_hints<'target>( &self, sinks: &[SafetySink<'target, 'tcx>], graph: &PathGraph<'_>, dependencies: &LocalDependencyIndex, component_summaries: &[(LoopComponent, LoopLocalSummary, LoopNumericSummary)], ) -> Vec<NumericRangeHint>
Compute numeric/index range hints for induction-sensitive sinks.
This is intentionally small but already separates numeric planning from
generic dataflow. ValidNum tries to recover a concrete violating
iteration for positive affine increments; InBound currently marks the
first iteration missed by shallow unrolling when the pointer/index root
depends on an induction variable.
Sourcefn collect_sinks<'target>(
&self,
target: &'target FunctionTarget<'tcx>,
) -> Vec<SafetySink<'target, 'tcx>>
fn collect_sinks<'target>( &self, target: &'target FunctionTarget<'tcx>, ) -> Vec<SafetySink<'target, 'tcx>>
Collect caller-side sinks from all checkpoint kinds in a target.
This mirrors VerifyDriver::properties_for_callsite so the planner and
verifier operate on the same obligations. Keeping it here avoids
constructing a VerifyDriver only to learn whether a deeper repeat is
needed before path extraction.
Auto Trait Implementations§
impl<'tcx> !RefUnwindSafe for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> !Send for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> !Sync for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> !UnwindSafe for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> DynSend for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> DynSync for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> Freeze for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> Unpin for LoopSensitivityAnalyzer<'tcx>
impl<'tcx> UnsafeUnpin for LoopSensitivityAnalyzer<'tcx>
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> 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