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
impl Frequencies
Sourcepub fn of(func: &Func, cfg: &Cfg, loops: &Loops, callees: &Callees) -> Self
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.
Sourcepub fn told(&self) -> &Predictions
pub fn told(&self) -> &Predictions
The predictions the frequencies were worked out from.
Sourcepub fn taken(&self, block: Block, index: usize) -> Probability
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.
Sourcepub fn entry(&self) -> Frequency
pub fn entry(&self) -> Frequency
The entry’s own frequency, which is what every other one is relative to.
Sourcepub fn is_reliable(&self, block: Block) -> bool
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.
Sourcepub fn is_capped(&self, block: Block) -> bool
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.
Sourcepub fn is_hot(&self, block: Block) -> bool
pub fn is_hot(&self, block: Block) -> bool
Whether this block is hot compared with the rest of its function, per section 11.4.
Sourcepub fn cyclic(&self, id: LoopId) -> Probability
pub fn cyclic(&self, id: LoopId) -> Probability
How likely this loop is to go round again.
Sourcepub fn iterations(&self, id: LoopId) -> u32
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.
Sourcepub fn hottest(&self, func: &Func) -> Option<Block>
pub fn hottest(&self, func: &Func) -> Option<Block>
The block that runs most often, and None for a function with no blocks.
Sourcepub fn problems(&self, func: &Func, cfg: &Cfg) -> Vec<String>
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
impl Clone for Frequencies
Source§fn clone(&self) -> Frequencies
fn clone(&self) -> Frequencies
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more