Skip to main content

Frequencies

Struct Frequencies 

Source
pub struct Frequencies { /* private fields */ }
Expand description

How often every block in a function runs, with the entry at one.

The predictions this was worked out from are kept, because every consumer of a frequency wants the edge probabilities as well and because the two have to be the same pair of numbers or the check in Frequencies::problems is checking one against something else.

Implementations§

Source§

impl Frequencies

Source

pub fn of(func: &Func, cfg: &Cfg, loops: &Loops, callees: &Callees) -> Self

Predicts every branch and then works out every block’s frequency from that.

One walk of the loop forest and one reverse-postorder walk of the function, which is what section 11.7 says this costs. A function with no entry, which is a declaration, gets an empty answer rather than an error, because a pipeline is handed declarations.

Source

pub fn told(&self) -> &Predictions

The predictions the frequencies were worked out from.

Source

pub fn taken(&self, block: Block, index: usize) -> Probability

How likely this edge out of this block is to be the one taken.

The index is into Cfg::successors, which is the order Predictions::edges is in.

Source

pub fn get(&self, block: Block) -> Frequency

How often this block runs, with the entry at one.

Source

pub fn entry(&self) -> Frequency

The entry’s own frequency, which is what every other one is relative to.

Source

pub fn is_reliable(&self, block: Block) -> bool

Whether this block’s frequency means anything.

False inside an irreducible region and anywhere downstream of one. A consumer that cares about being right rather than fast should decline these rather than treat them as cold, which is what they will look like.

Source

pub fn is_capped(&self, block: Block) -> bool

Whether this block is a loop header whose iteration count hit the cap.

Which is a loop nothing predicted an exit for, so the answer is MAX_PREDICTED_ITERATIONS rather than a number anybody worked out.

Source

pub fn is_hot(&self, block: Block) -> bool

Whether this block is hot compared with the rest of its function, per section 11.4.

Source

pub fn cyclic(&self, id: LoopId) -> Probability

How likely this loop is to go round again.

Source

pub fn iterations(&self, id: LoopId) -> u32

How many times this loop is estimated to run, which is one over the chance of leaving.

Capped at MAX_PREDICTED_ITERATIONS, and that cap is what a loop nothing predicted an exit for gets. This is the estimate unrolling and loop alignment want, and it is a guess unless it says otherwise.

Source

pub fn hottest(&self, func: &Func) -> Option<Block>

The block that runs most often, and None for a function with no blocks.

Source

pub fn problems(&self, func: &Func, cfg: &Cfg) -> Vec<String>

What section 11.5 asks the verifier to check after every pass.

Two things. The probabilities out of a block sum to one, and the frequencies arriving at a block sum to the block’s own frequency. The second is exact in real arithmetic even at a loop header, where the entry and the back edge add up to the header precisely because the series says they do, so a tolerance of PROFILE_SUM_TOLERANCE_PERCENT is there for the remainder every fixed point division throws away and for nothing else.

Three kinds of block are not checked, and each of them is a place where the sum is known not to hold: the entry, which nothing arrives at; a header whose count was capped, where the cap is deliberately not the sum; and anything in or downstream of an irreducible region, where the frequency was never claimed to mean anything.

What this catches is the pass that split a block and forgot to split its count, which section 11.6 says is the failure that costs the most and shows up the least. What it does not catch is a proportionally wrong but consistent assignment, and nothing does except review.

Trait Implementations§

Source§

impl Clone for Frequencies

Source§

fn clone(&self) -> Frequencies

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Frequencies

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Eq for Frequencies

Source§

impl PartialEq for Frequencies

Source§

fn eq(&self, other: &Frequencies) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Frequencies

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.