2020-10-23 03:28:16 +00:00
|
|
|
use super::debug;
|
|
|
|
|
|
|
|
use debug::DebugCounters;
|
|
|
|
|
2020-10-23 07:45:07 +00:00
|
|
|
use rustc_middle::mir::coverage::*;
|
|
|
|
|
|
|
|
/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
|
|
|
|
/// `Coverage` statements.
|
|
|
|
pub(crate) struct CoverageCounters {
|
|
|
|
function_source_hash: u64,
|
|
|
|
next_counter_id: u32,
|
|
|
|
num_expressions: u32,
|
2020-10-23 03:28:16 +00:00
|
|
|
pub debug_counters: DebugCounters,
|
2020-10-23 07:45:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl CoverageCounters {
|
|
|
|
pub fn new(function_source_hash: u64) -> Self {
|
|
|
|
Self {
|
|
|
|
function_source_hash,
|
|
|
|
next_counter_id: CounterValueReference::START.as_u32(),
|
|
|
|
num_expressions: 0,
|
2020-10-23 03:28:16 +00:00
|
|
|
debug_counters: DebugCounters::new(),
|
2020-10-23 07:45:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-23 03:28:16 +00:00
|
|
|
/// Activate the `DebugCounters` data structures, to provide additional debug formatting
|
|
|
|
/// features when formating `CoverageKind` (counter) values.
|
|
|
|
pub fn enable_debug(&mut self) {
|
|
|
|
self.debug_counters.enable();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn make_counter<F>(&mut self, debug_block_label_fn: F) -> CoverageKind
|
|
|
|
where
|
|
|
|
F: Fn() -> Option<String>,
|
|
|
|
{
|
|
|
|
let counter = CoverageKind::Counter {
|
2020-10-23 07:45:07 +00:00
|
|
|
function_source_hash: self.function_source_hash,
|
|
|
|
id: self.next_counter(),
|
2020-10-23 03:28:16 +00:00
|
|
|
};
|
|
|
|
if self.debug_counters.is_enabled() {
|
|
|
|
self.debug_counters.add_counter(&counter, (debug_block_label_fn)());
|
2020-10-23 07:45:07 +00:00
|
|
|
}
|
2020-10-23 03:28:16 +00:00
|
|
|
counter
|
2020-10-23 07:45:07 +00:00
|
|
|
}
|
|
|
|
|
2020-10-23 03:28:16 +00:00
|
|
|
pub fn make_expression<F>(
|
2020-10-23 07:45:07 +00:00
|
|
|
&mut self,
|
|
|
|
lhs: ExpressionOperandId,
|
|
|
|
op: Op,
|
|
|
|
rhs: ExpressionOperandId,
|
2020-10-23 03:28:16 +00:00
|
|
|
debug_block_label_fn: F,
|
|
|
|
) -> CoverageKind
|
|
|
|
where
|
|
|
|
F: Fn() -> Option<String>,
|
|
|
|
{
|
2020-10-23 07:45:07 +00:00
|
|
|
let id = self.next_expression();
|
2020-10-23 03:28:16 +00:00
|
|
|
let expression = CoverageKind::Expression { id, lhs, op, rhs };
|
|
|
|
if self.debug_counters.is_enabled() {
|
|
|
|
self.debug_counters.add_counter(&expression, (debug_block_label_fn)());
|
|
|
|
}
|
|
|
|
expression
|
2020-10-23 07:45:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Counter IDs start from one and go up.
|
|
|
|
fn next_counter(&mut self) -> CounterValueReference {
|
|
|
|
assert!(self.next_counter_id < u32::MAX - self.num_expressions);
|
|
|
|
let next = self.next_counter_id;
|
|
|
|
self.next_counter_id += 1;
|
|
|
|
CounterValueReference::from(next)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Expression IDs start from u32::MAX and go down because a Expression can reference
|
|
|
|
/// (add or subtract counts) of both Counter regions and Expression regions. The counter
|
|
|
|
/// expression operand IDs must be unique across both types.
|
|
|
|
fn next_expression(&mut self) -> InjectedExpressionId {
|
|
|
|
assert!(self.next_counter_id < u32::MAX - self.num_expressions);
|
|
|
|
let next = u32::MAX - self.num_expressions;
|
|
|
|
self.num_expressions += 1;
|
|
|
|
InjectedExpressionId::from(next)
|
|
|
|
}
|
|
|
|
}
|