Struct rustc_mir_transform::coverage::counters::BcbCounters
source · struct BcbCounters<'a> {
coverage_counters: &'a mut CoverageCounters,
basic_coverage_blocks: &'a mut CoverageGraph,
}
Expand description
Traverse the CoverageGraph
and add either a Counter
or Expression
to every BCB, to be
injected with CoverageSpan
s. 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 mut CoverageGraph
Implementations
sourceimpl<'a> BcbCounters<'a>
impl<'a> BcbCounters<'a>
fn new(
coverage_counters: &'a mut CoverageCounters,
basic_coverage_blocks: &'a mut CoverageGraph
) -> Self
sourcefn make_bcb_counters(
&mut self,
coverage_spans: &[CoverageSpan]
) -> Result<Vec<CoverageKind>, Error>
fn make_bcb_counters(
&mut self,
coverage_spans: &[CoverageSpan]
) -> Result<Vec<CoverageKind>, 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: ExpressionOperandId,
collect_intermediate_expressions: &mut Vec<CoverageKind>
) -> Result<(), Error>
fn get_or_make_counter_operand(
&mut self,
bcb: BasicCoverageBlock,
collect_intermediate_expressions: &mut Vec<CoverageKind>
) -> Result<ExpressionOperandId, Error>
fn recursive_get_or_make_counter_operand(
&mut self,
bcb: BasicCoverageBlock,
collect_intermediate_expressions: &mut Vec<CoverageKind>,
debug_indent_level: usize
) -> Result<ExpressionOperandId, Error>
fn get_or_make_edge_counter_operand(
&mut self,
from_bcb: BasicCoverageBlock,
to_bcb: BasicCoverageBlock,
collect_intermediate_expressions: &mut Vec<CoverageKind>
) -> Result<ExpressionOperandId, Error>
fn recursive_get_or_make_edge_counter_operand(
&mut self,
from_bcb: BasicCoverageBlock,
to_bcb: BasicCoverageBlock,
collect_intermediate_expressions: &mut Vec<CoverageKind>,
debug_indent_level: usize
) -> Result<ExpressionOperandId, 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
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_is_dominated_by(
&self,
node: BasicCoverageBlock,
dom: BasicCoverageBlock
) -> bool
fn format_counter(&self, counter_kind: &CoverageKind) -> String
Auto Trait Implementations
impl<'a> RefUnwindSafe for BcbCounters<'a>
impl<'a> Send for BcbCounters<'a>
impl<'a> Sync for BcbCounters<'a>
impl<'a> Unpin for BcbCounters<'a>
impl<'a> !UnwindSafe for BcbCounters<'a>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn 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