Skip to content

Commit c7ae4c2

Browse files
committed
Splitting transform/instrument_coverage.rs into transform/coverage/...
1 parent c7747cc commit c7ae4c2

File tree

7 files changed

+766
-730
lines changed

7 files changed

+766
-730
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use rustc_middle::mir::coverage::*;
2+
3+
/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
4+
/// `Coverage` statements.
5+
pub(crate) struct CoverageCounters {
6+
function_source_hash: u64,
7+
next_counter_id: u32,
8+
num_expressions: u32,
9+
}
10+
11+
impl CoverageCounters {
12+
pub fn new(function_source_hash: u64) -> Self {
13+
Self {
14+
function_source_hash,
15+
next_counter_id: CounterValueReference::START.as_u32(),
16+
num_expressions: 0,
17+
}
18+
}
19+
20+
pub fn make_counter(&mut self) -> CoverageKind {
21+
CoverageKind::Counter {
22+
function_source_hash: self.function_source_hash,
23+
id: self.next_counter(),
24+
}
25+
}
26+
27+
pub fn make_expression(
28+
&mut self,
29+
lhs: ExpressionOperandId,
30+
op: Op,
31+
rhs: ExpressionOperandId,
32+
) -> CoverageKind {
33+
let id = self.next_expression();
34+
CoverageKind::Expression { id, lhs, op, rhs }
35+
}
36+
37+
/// Counter IDs start from one and go up.
38+
fn next_counter(&mut self) -> CounterValueReference {
39+
assert!(self.next_counter_id < u32::MAX - self.num_expressions);
40+
let next = self.next_counter_id;
41+
self.next_counter_id += 1;
42+
CounterValueReference::from(next)
43+
}
44+
45+
/// Expression IDs start from u32::MAX and go down because a Expression can reference
46+
/// (add or subtract counts) of both Counter regions and Expression regions. The counter
47+
/// expression operand IDs must be unique across both types.
48+
fn next_expression(&mut self) -> InjectedExpressionId {
49+
assert!(self.next_counter_id < u32::MAX - self.num_expressions);
50+
let next = u32::MAX - self.num_expressions;
51+
self.num_expressions += 1;
52+
InjectedExpressionId::from(next)
53+
}
54+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use super::graph::BasicCoverageBlocks;
2+
use super::spans::CoverageSpan;
3+
4+
use crate::util::pretty;
5+
use crate::util::spanview::{self, SpanViewable};
6+
7+
use rustc_middle::mir::{self, TerminatorKind};
8+
use rustc_middle::ty::TyCtxt;
9+
10+
/// Generates the MIR pass `CoverageSpan`-specific spanview dump file.
11+
pub(crate) fn dump_coverage_spanview(
12+
tcx: TyCtxt<'tcx>,
13+
mir_body: &mir::Body<'tcx>,
14+
basic_coverage_blocks: &BasicCoverageBlocks,
15+
pass_name: &str,
16+
coverage_spans: &Vec<CoverageSpan>,
17+
) {
18+
let mir_source = mir_body.source;
19+
let def_id = mir_source.def_id();
20+
21+
let span_viewables = span_viewables(tcx, mir_body, basic_coverage_blocks, &coverage_spans);
22+
let mut file = pretty::create_dump_file(tcx, "html", None, pass_name, &0, mir_source)
23+
.expect("Unexpected error creating MIR spanview HTML file");
24+
let crate_name = tcx.crate_name(def_id.krate);
25+
let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate();
26+
let title = format!("{}.{} - Coverage Spans", crate_name, item_name);
27+
spanview::write_document(tcx, def_id, span_viewables, &title, &mut file)
28+
.expect("Unexpected IO error dumping coverage spans as HTML");
29+
}
30+
31+
/// Converts the computed `BasicCoverageBlock`s into `SpanViewable`s.
32+
fn span_viewables(
33+
tcx: TyCtxt<'tcx>,
34+
mir_body: &mir::Body<'tcx>,
35+
basic_coverage_blocks: &BasicCoverageBlocks,
36+
coverage_spans: &Vec<CoverageSpan>,
37+
) -> Vec<SpanViewable> {
38+
let mut span_viewables = Vec::new();
39+
for coverage_span in coverage_spans {
40+
let tooltip = coverage_span.format_coverage_statements(tcx, mir_body);
41+
let CoverageSpan { span, bcb_leader_bb: bb, .. } = coverage_span;
42+
let bcb = &basic_coverage_blocks[*bb];
43+
let id = bcb.id();
44+
let leader_bb = bcb.leader_bb();
45+
span_viewables.push(SpanViewable { bb: leader_bb, span: *span, id, tooltip });
46+
}
47+
span_viewables
48+
}
49+
50+
/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any
51+
/// values it might hold.
52+
pub(crate) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
53+
match kind {
54+
TerminatorKind::Goto { .. } => "Goto",
55+
TerminatorKind::SwitchInt { .. } => "SwitchInt",
56+
TerminatorKind::Resume => "Resume",
57+
TerminatorKind::Abort => "Abort",
58+
TerminatorKind::Return => "Return",
59+
TerminatorKind::Unreachable => "Unreachable",
60+
TerminatorKind::Drop { .. } => "Drop",
61+
TerminatorKind::DropAndReplace { .. } => "DropAndReplace",
62+
TerminatorKind::Call { .. } => "Call",
63+
TerminatorKind::Assert { .. } => "Assert",
64+
TerminatorKind::Yield { .. } => "Yield",
65+
TerminatorKind::GeneratorDrop => "GeneratorDrop",
66+
TerminatorKind::FalseEdge { .. } => "FalseEdge",
67+
TerminatorKind::FalseUnwind { .. } => "FalseUnwind",
68+
TerminatorKind::InlineAsm { .. } => "InlineAsm",
69+
}
70+
}

0 commit comments

Comments
 (0)