coverage: Simplify the coverageinfo
query to a single pass
This commit is contained in:
parent
3f549466a8
commit
f191b1c2fc
@ -29,18 +29,12 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||||||
/// calls may not work; but computing the number of counters or expressions by adding `1` to the
|
/// calls may not work; but computing the number of counters or expressions by adding `1` to the
|
||||||
/// highest ID (for a given instrumented function) is valid.
|
/// highest ID (for a given instrumented function) is valid.
|
||||||
///
|
///
|
||||||
/// This visitor runs twice, first with `add_missing_operands` set to `false`, to find the maximum
|
/// It's possible for a coverage expression to remain in MIR while one or both of its operands
|
||||||
/// counter ID and maximum expression ID based on their enum variant `id` fields; then, as a
|
/// have been optimized away. To avoid problems in codegen, we include those operands' IDs when
|
||||||
/// safeguard, with `add_missing_operands` set to `true`, to find any other counter or expression
|
/// determining the maximum counter/expression ID, even if the underlying counter/expression is
|
||||||
/// IDs referenced by expression operands, if not already seen.
|
/// no longer present.
|
||||||
///
|
|
||||||
/// Ideally, each operand ID in a MIR `CoverageKind::Expression` will have a separate MIR `Coverage`
|
|
||||||
/// statement for the `Counter` or `Expression` with the referenced ID. but since current or future
|
|
||||||
/// MIR optimizations can theoretically optimize out segments of a MIR, it may not be possible to
|
|
||||||
/// guarantee this, so the second pass ensures the `CoverageInfo` counts include all referenced IDs.
|
|
||||||
struct CoverageVisitor {
|
struct CoverageVisitor {
|
||||||
info: CoverageInfo,
|
info: CoverageInfo,
|
||||||
add_missing_operands: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CoverageVisitor {
|
impl CoverageVisitor {
|
||||||
@ -73,20 +67,14 @@ impl CoverageVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_coverage(&mut self, coverage: &Coverage) {
|
fn visit_coverage(&mut self, coverage: &Coverage) {
|
||||||
if self.add_missing_operands {
|
|
||||||
match coverage.kind {
|
match coverage.kind {
|
||||||
CoverageKind::Expression { lhs, rhs, .. } => {
|
CoverageKind::Counter { id, .. } => self.update_num_counters(id),
|
||||||
|
CoverageKind::Expression { id, lhs, rhs, .. } => {
|
||||||
|
self.update_num_expressions(id);
|
||||||
self.update_from_expression_operand(lhs);
|
self.update_from_expression_operand(lhs);
|
||||||
self.update_from_expression_operand(rhs);
|
self.update_from_expression_operand(rhs);
|
||||||
}
|
}
|
||||||
_ => {}
|
CoverageKind::Unreachable => {}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match coverage.kind {
|
|
||||||
CoverageKind::Counter { id, .. } => self.update_num_counters(id),
|
|
||||||
CoverageKind::Expression { id, .. } => self.update_num_expressions(id),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,16 +82,11 @@ impl CoverageVisitor {
|
|||||||
fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> CoverageInfo {
|
fn coverageinfo<'tcx>(tcx: TyCtxt<'tcx>, instance_def: ty::InstanceDef<'tcx>) -> CoverageInfo {
|
||||||
let mir_body = tcx.instance_mir(instance_def);
|
let mir_body = tcx.instance_mir(instance_def);
|
||||||
|
|
||||||
let mut coverage_visitor = CoverageVisitor {
|
let mut coverage_visitor =
|
||||||
info: CoverageInfo { num_counters: 0, num_expressions: 0 },
|
CoverageVisitor { info: CoverageInfo { num_counters: 0, num_expressions: 0 } };
|
||||||
add_missing_operands: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
coverage_visitor.visit_body(mir_body);
|
coverage_visitor.visit_body(mir_body);
|
||||||
|
|
||||||
coverage_visitor.add_missing_operands = true;
|
|
||||||
coverage_visitor.visit_body(mir_body);
|
|
||||||
|
|
||||||
coverage_visitor.info
|
coverage_visitor.info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user