pub struct Ranges<'a> { /* private fields */ }Expand description
The range analysis of one function.
Queries take &mut self because a query fills the cache and moves the counters, which is the
design and not an accident: an analysis that answered without recording what it was asked
could not report the losses in section 10.7.
Implementations§
Source§impl<'a> Ranges<'a>
impl<'a> Ranges<'a>
Sourcepub fn new(func: &'a Func, cfg: &'a Cfg, dom: &'a Dominators) -> Self
pub fn new(func: &'a Func, cfg: &'a Cfg, dom: &'a Dominators) -> Self
The analysis of this function, with the limits at their defaults.
Sourcepub fn with(
func: &'a Func,
cfg: &'a Cfg,
dom: &'a Dominators,
options: Options,
) -> Self
pub fn with( func: &'a Func, cfg: &'a Cfg, dom: &'a Dominators, options: Options, ) -> Self
The same, with the limits the command line asked for.
Sourcepub fn at(&mut self, value: Value, block: Block) -> Range
pub fn at(&mut self, value: Value, block: Block) -> Range
What this value can be on entry to this block.
The block has to be one the definition reaches, which for a use is the block the use is in. Asking about a block the definition does not dominate is not wrong, it just gets an answer that ignored the branches it could not see.
Sourcepub fn at_inst(&mut self, value: Value, inst: Inst) -> Range
pub fn at_inst(&mut self, value: Value, inst: Inst) -> Range
What this value can be at this instruction.
The same as Ranges::at on the block holding it. Ranges within a block do not change
in rucc’s IR, because there is nothing between two instructions that could narrow one:
the branches are all at the ends of blocks.
Sourcepub fn compare(
&mut self,
pred: IntPred,
a: Value,
b: Value,
block: Block,
) -> Truth
pub fn compare( &mut self, pred: IntPred, a: Value, b: Value, block: Block, ) -> Truth
Whether this comparison is settled where it stands.
The ranges answer first, because they answer more often. The oracle answers the cases they cannot, which are the ones where the two values are related without either being pinned down, and section 10.3 says that is most of what removes a repeated bounds check.
Sourcepub fn relation(&mut self, a: Value, b: Value, block: Block) -> Option<IntPred>
pub fn relation(&mut self, a: Value, b: Value, block: Block) -> Option<IntPred>
What is known to hold between these two values in this block, if anything.
What was recorded on a dominating edge, read in the order asked, plus one step through an intermediate value. Not the transitive closure: section 10.3 says computing that is where the cost of a relational oracle goes and that one step pays for most of it.