Skip to main content

Scev

Struct Scev 

Source
pub struct Scev<'a> { /* private fields */ }
Expand description

The analysis, which works out an answer when asked and remembers it.

Demand driven and memoized, per section 7.8, because the cost of scalar evolution is a function of how many distinct values get asked about rather than of the size of the function. The cache holds one loop’s worth of answers per loop and the whole thing is thrown away when anything about the loops changes, which per document 04.4 is any pass that touches one.

Implementations§

Source§

impl<'a> Scev<'a>

Source

pub fn new(func: &'a Func, cfg: &'a Cfg, loops: &'a Loops) -> Self

A fresh analysis over these loops, knowing nothing yet.

Source

pub fn evolution(&mut self, id: LoopId, value: Value) -> Evolution

How this value changes across the iterations of this loop.

The way in, and what it does before answering is settle Scev::holds for the loop. That has to happen out here rather than at the point Scev::extend wants it, because settling it means asking about other values and Scev::at parks a marker on the value it is working on. Asked from in there, the answer would depend on what was already in flight.

Source

pub fn bound(&mut self, id: LoopId) -> Option<Bound>

How many times this loop runs at most, and what that rests on.

Any one exit gives a valid upper bound, because a loop cannot run more times than the first exit that fires, so this takes the first exit it can solve rather than the smallest. That is max_loop_iterations and not estimate_numbers_of_iterations, which is why the answer is a Bound.

Source

pub fn estimate(&mut self, id: LoopId) -> Estimate

How many times this loop probably runs.

Trait Implementations§

Source§

impl<'a> Debug for Scev<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Scev<'a>

§

impl<'a> RefUnwindSafe for Scev<'a>

§

impl<'a> Send for Scev<'a>

§

impl<'a> Sync for Scev<'a>

§

impl<'a> Unpin for Scev<'a>

§

impl<'a> UnsafeUnpin for Scev<'a>

§

impl<'a> UnwindSafe for Scev<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.