Struct rustc_mir_transform::coverage::counters::MakeBcbCounters
source · struct MakeBcbCounters<'a> {
coverage_counters: &'a mut CoverageCounters,
basic_coverage_blocks: &'a CoverageGraph,
}
Expand description
Traverse the CoverageGraph
and add either a Counter
or Expression
to every BCB, to be
injected with coverage spans. Expressions
have no runtime overhead, so if a viable expression
(adding or subtracting two other counters or expressions) can compute the same result as an
embedded counter, an Expression
should be used.
Fields§
§coverage_counters: &'a mut CoverageCounters
§basic_coverage_blocks: &'a CoverageGraph
Implementations§
source§impl<'a> MakeBcbCounters<'a>
impl<'a> MakeBcbCounters<'a>
fn new( coverage_counters: &'a mut CoverageCounters, basic_coverage_blocks: &'a CoverageGraph ) -> Self
sourcefn make_bcb_counters(
&mut self,
bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool
) -> Result<(), Error>
fn make_bcb_counters( &mut self, bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool ) -> Result<(), Error>
If two BasicCoverageBlock
s branch from another BasicCoverageBlock
, one of the branches
can be counted by Expression
by subtracting the other branch from the branching
block. Otherwise, the BasicCoverageBlock
executed the least should have the Counter
.
One way to predict which branch executes the least is by considering loops. A loop is exited
at a branch, so the branch that jumps to a BasicCoverageBlock
outside the loop is almost
always executed less than the branch that does not exit the loop.
Returns any non-code-span expressions created to represent intermediate values (such as to add two counters so the result can be subtracted from another counter), or an Error with message for subsequent debugging.
fn make_branch_counters( &mut self, traversal: &mut TraverseCoverageGraphWithLoops, branching_bcb: BasicCoverageBlock, branching_counter_operand: Operand ) -> Result<(), Error>
fn get_or_make_counter_operand( &mut self, bcb: BasicCoverageBlock ) -> Result<Operand, Error>
fn recursive_get_or_make_counter_operand( &mut self, bcb: BasicCoverageBlock, debug_indent_level: usize ) -> Result<Operand, Error>
fn get_or_make_edge_counter_operand( &mut self, from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock ) -> Result<Operand, Error>
fn recursive_get_or_make_edge_counter_operand( &mut self, from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock, debug_indent_level: usize ) -> Result<Operand, Error>
sourcefn choose_preferred_expression_branch(
&self,
traversal: &TraverseCoverageGraphWithLoops,
branches: &[BcbBranch]
) -> BcbBranch
fn choose_preferred_expression_branch( &self, traversal: &TraverseCoverageGraphWithLoops, branches: &[BcbBranch] ) -> BcbBranch
Select a branch for the expression, either the recommended reloop_branch
, or if none was
found, select any branch.
sourcefn find_some_reloop_branch(
&self,
traversal: &TraverseCoverageGraphWithLoops,
branches: &[BcbBranch]
) -> Option<BcbBranch>
fn find_some_reloop_branch( &self, traversal: &TraverseCoverageGraphWithLoops, branches: &[BcbBranch] ) -> Option<BcbBranch>
At most, one of the branches (or its edge, from the branching_bcb, if the branch has multiple incoming edges) can have a counter computed by expression.
If at least one of the branches leads outside of a loop (found_loop_exit
is
true), and at least one other branch does not exit the loop (the first of which
is captured in some_reloop_branch
), it’s likely any reloop branch will be
executed far more often than loop exit branch, making the reloop branch a better
candidate for an expression.
fn bcb_predecessors(&self, bcb: BasicCoverageBlock) -> &[BasicCoverageBlock]
fn bcb_successors(&self, bcb: BasicCoverageBlock) -> &[BasicCoverageBlock]
fn bcb_branches(&self, from_bcb: BasicCoverageBlock) -> Vec<BcbBranch>
fn bcb_needs_branch_counters(&self, bcb: BasicCoverageBlock) -> bool
fn branch_has_no_counter(&self, branch: &BcbBranch) -> bool
fn branch_counter(&self, branch: &BcbBranch) -> Option<&BcbCounter>
sourcefn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool
fn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool
Returns true if the BasicCoverageBlock has zero or one incoming edge. (If zero, it should be the entry point for the function.)
fn bcb_dominates( &self, dom: BasicCoverageBlock, node: BasicCoverageBlock ) -> bool
Auto Trait Implementations§
impl<'a> RefUnwindSafe for MakeBcbCounters<'a>
impl<'a> Send for MakeBcbCounters<'a>
impl<'a> Sync for MakeBcbCounters<'a>
impl<'a> Unpin for MakeBcbCounters<'a>
impl<'a> !UnwindSafe for MakeBcbCounters<'a>
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
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 16 bytes