Skip to content

Commit

Permalink
Rollup merge of rust-lang#78963 - richkadel:llvm-coverage-counters-2.…
Browse files Browse the repository at this point in the history
…0.4, r=tmandry

Added some unit tests as requested

As discussed in PR rust-lang#78267, for example:

* rust-lang#78267 (comment)
* rust-lang#78267 (comment)

r? ```@tmandry```
FYI: ```@wesleywiser```

This is pretty much self contained, but depending on feedback and timing, I may have a chance to add a few more unit tests requested against `counters.rs`. I'm looking at those now.
  • Loading branch information
Dylan-DPC committed Nov 14, 2020
2 parents dd9485e + b4b0ef3 commit 09cafd7
Show file tree
Hide file tree
Showing 11 changed files with 788 additions and 25 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,13 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"

[[package]]
name = "coverage_test_macros"
version = "0.0.0"
dependencies = [
"proc-macro2",
]

[[package]]
name = "cpuid-bool"
version = "0.1.2"
Expand Down Expand Up @@ -3922,6 +3929,7 @@ dependencies = [
name = "rustc_mir"
version = "0.0.0"
dependencies = [
"coverage_test_macros",
"either",
"itertools 0.9.0",
"polonius-engine",
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,18 @@ pub struct TyS<'tcx> {
outer_exclusive_binder: ty::DebruijnIndex,
}

impl<'tcx> TyS<'tcx> {
/// A constructor used only for internal testing.
#[allow(rustc::usage_of_ty_tykind)]
pub fn make_for_test(
kind: TyKind<'tcx>,
flags: TypeFlags,
outer_exclusive_binder: ty::DebruijnIndex,
) -> TyS<'tcx> {
TyS { kind, flags, outer_exclusive_binder }
}
}

// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(TyS<'_>, 32);
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ rustc_ast = { path = "../rustc_ast" }
rustc_span = { path = "../rustc_span" }
rustc_apfloat = { path = "../rustc_apfloat" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }

[dev-dependencies]
coverage_test_macros = { path = "src/transform/coverage/test_macros" }
5 changes: 2 additions & 3 deletions compiler/rustc_mir/src/transform/coverage/counters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::mir::coverage::*;

/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
/// `Coverage` statements.
pub(crate) struct CoverageCounters {
pub(super) struct CoverageCounters {
function_source_hash: u64,
next_counter_id: u32,
num_expressions: u32,
Expand All @@ -37,7 +37,7 @@ impl CoverageCounters {
self.debug_counters.enable();
}

/// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlocks` directly or
/// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
/// indirectly associated with `CoverageSpans`, and returns additional `Expression`s
/// representing intermediate values.
pub fn make_bcb_counters(
Expand Down Expand Up @@ -120,7 +120,6 @@ struct BcbCounters<'a> {
basic_coverage_blocks: &'a mut CoverageGraph,
}

// FIXME(richkadel): Add unit tests for `BcbCounters` functions/algorithms.
impl<'a> BcbCounters<'a> {
fn new(
coverage_counters: &'a mut CoverageCounters,
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_mir/src/transform/coverage/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub const NESTED_INDENT: &str = " ";

const RUSTC_COVERAGE_DEBUG_OPTIONS: &str = "RUSTC_COVERAGE_DEBUG_OPTIONS";

pub(crate) fn debug_options<'a>() -> &'a DebugOptions {
pub(super) fn debug_options<'a>() -> &'a DebugOptions {
static DEBUG_OPTIONS: SyncOnceCell<DebugOptions> = SyncOnceCell::new();

&DEBUG_OPTIONS.get_or_init(|| DebugOptions::from_env())
Expand All @@ -136,7 +136,7 @@ pub(crate) fn debug_options<'a>() -> &'a DebugOptions {
/// Parses and maintains coverage-specific debug options captured from the environment variable
/// "RUSTC_COVERAGE_DEBUG_OPTIONS", if set.
#[derive(Debug, Clone)]
pub(crate) struct DebugOptions {
pub(super) struct DebugOptions {
pub allow_unused_expressions: bool,
counter_format: ExpressionFormat,
}
Expand Down Expand Up @@ -250,7 +250,7 @@ impl Default for ExpressionFormat {
///
/// `DebugCounters` supports a recursive rendering of `Expression` counters, so they can be
/// presented as nested expressions such as `(bcb3 - (bcb0 + bcb1))`.
pub(crate) struct DebugCounters {
pub(super) struct DebugCounters {
some_counters: Option<FxHashMap<ExpressionOperandId, DebugCounter>>,
}

Expand Down Expand Up @@ -386,7 +386,7 @@ impl DebugCounter {

/// If enabled, this data structure captures additional debugging information used when generating
/// a Graphviz (.dot file) representation of the `CoverageGraph`, for debugging purposes.
pub(crate) struct GraphvizData {
pub(super) struct GraphvizData {
some_bcb_to_coverage_spans_with_counters:
Option<FxHashMap<BasicCoverageBlock, Vec<(CoverageSpan, CoverageKind)>>>,
some_bcb_to_dependency_counters: Option<FxHashMap<BasicCoverageBlock, Vec<CoverageKind>>>,
Expand Down Expand Up @@ -496,7 +496,7 @@ impl GraphvizData {
/// directly or indirectly, to compute the coverage counts for all `CoverageSpan`s, and any that are
/// _not_ used are retained in the `unused_expressions` Vec, to be included in debug output (logs
/// and/or a `CoverageGraph` graphviz output).
pub(crate) struct UsedExpressions {
pub(super) struct UsedExpressions {
some_used_expression_operands:
Option<FxHashMap<ExpressionOperandId, Vec<InjectedExpressionId>>>,
some_unused_expressions:
Expand Down Expand Up @@ -626,7 +626,7 @@ impl UsedExpressions {
}

/// Generates the MIR pass `CoverageSpan`-specific spanview dump file.
pub(crate) fn dump_coverage_spanview(
pub(super) fn dump_coverage_spanview(
tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>,
basic_coverage_blocks: &CoverageGraph,
Expand Down Expand Up @@ -666,7 +666,7 @@ fn span_viewables(
}

/// Generates the MIR pass coverage-specific graphviz dump file.
pub(crate) fn dump_coverage_graphviz(
pub(super) fn dump_coverage_graphviz(
tcx: TyCtxt<'tcx>,
mir_body: &mir::Body<'tcx>,
pass_name: &str,
Expand Down Expand Up @@ -815,7 +815,7 @@ fn bcb_to_string_sections(

/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any
/// values it might hold.
pub(crate) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
pub(super) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
match kind {
TerminatorKind::Goto { .. } => "Goto",
TerminatorKind::SwitchInt { .. } => "SwitchInt",
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_mir/src/transform/coverage/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const ID_SEPARATOR: &str = ",";
/// `CoverageKind` counter (to be added by `CoverageCounters::make_bcb_counters`), and an optional
/// set of additional counters--if needed--to count incoming edges, if there are more than one.
/// (These "edge counters" are eventually converted into new MIR `BasicBlock`s.)
pub(crate) struct CoverageGraph {
#[derive(Debug)]
pub(super) struct CoverageGraph {
bcbs: IndexVec<BasicCoverageBlock, BasicCoverageBlockData>,
bb_to_bcb: IndexVec<BasicBlock, Option<BasicCoverageBlock>>,
pub successors: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
Expand Down Expand Up @@ -275,7 +276,7 @@ impl graph::WithPredecessors for CoverageGraph {

rustc_index::newtype_index! {
/// A node in the [control-flow graph][CFG] of CoverageGraph.
pub(crate) struct BasicCoverageBlock {
pub(super) struct BasicCoverageBlock {
DEBUG_FORMAT = "bcb{}",
}
}
Expand Down Expand Up @@ -305,7 +306,7 @@ rustc_index::newtype_index! {
/// queries (`is_dominated_by()`, `predecessors`, `successors`, etc.) have branch (control flow)
/// significance.
#[derive(Debug, Clone)]
pub(crate) struct BasicCoverageBlockData {
pub(super) struct BasicCoverageBlockData {
pub basic_blocks: Vec<BasicBlock>,
pub counter_kind: Option<CoverageKind>,
edge_from_bcbs: Option<FxHashMap<BasicCoverageBlock, CoverageKind>>,
Expand Down Expand Up @@ -431,7 +432,7 @@ impl BasicCoverageBlockData {
/// the specific branching BCB, representing the edge between the two. The latter case
/// distinguishes this incoming edge from other incoming edges to the same `target_bcb`.
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct BcbBranch {
pub(super) struct BcbBranch {
pub edge_from_bcb: Option<BasicCoverageBlock>,
pub target_bcb: BasicCoverageBlock,
}
Expand Down Expand Up @@ -498,9 +499,8 @@ fn bcb_filtered_successors<'a, 'tcx>(
/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the
/// CoverageGraph outside all loops. This supports traversing the BCB CFG in a way that
/// ensures a loop is completely traversed before processing Blocks after the end of the loop.
// FIXME(richkadel): Add unit tests for TraversalContext.
#[derive(Debug)]
pub(crate) struct TraversalContext {
pub(super) struct TraversalContext {
/// From one or more backedges returning to a loop header.
pub loop_backedges: Option<(Vec<BasicCoverageBlock>, BasicCoverageBlock)>,

Expand All @@ -510,7 +510,7 @@ pub(crate) struct TraversalContext {
pub worklist: Vec<BasicCoverageBlock>,
}

pub(crate) struct TraverseCoverageGraphWithLoops {
pub(super) struct TraverseCoverageGraphWithLoops {
pub backedges: IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>>,
pub context_stack: Vec<TraversalContext>,
visited: BitSet<BasicCoverageBlock>,
Expand Down Expand Up @@ -642,7 +642,7 @@ impl TraverseCoverageGraphWithLoops {
}
}

fn find_loop_backedges(
pub(super) fn find_loop_backedges(
basic_coverage_blocks: &CoverageGraph,
) -> IndexVec<BasicCoverageBlock, Vec<BasicCoverageBlock>> {
let num_bcbs = basic_coverage_blocks.num_nodes();
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_mir/src/transform/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ mod debug;
mod graph;
mod spans;

#[cfg(test)]
mod tests;

use counters::CoverageCounters;
use graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph};
use spans::{CoverageSpan, CoverageSpans};
Expand All @@ -31,7 +34,7 @@ use rustc_span::{CharPos, Pos, SourceFile, Span, Symbol};

/// A simple error message wrapper for `coverage::Error`s.
#[derive(Debug)]
pub(crate) struct Error {
struct Error {
message: String,
}

Expand Down
16 changes: 11 additions & 5 deletions compiler/rustc_mir/src/transform/coverage/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_span::{BytePos, Span, SyntaxContext};
use std::cmp::Ordering;

#[derive(Debug, Copy, Clone)]
pub(crate) enum CoverageStatement {
pub(super) enum CoverageStatement {
Statement(BasicBlock, Span, usize),
Terminator(BasicBlock, Span),
}
Expand Down Expand Up @@ -66,7 +66,7 @@ impl CoverageStatement {
/// or is subsumed by the `Span` associated with this `CoverageSpan`, and it's `BasicBlock`
/// `is_dominated_by()` the `BasicBlock`s in this `CoverageSpan`.
#[derive(Debug, Clone)]
pub(crate) struct CoverageSpan {
pub(super) struct CoverageSpan {
pub span: Span,
pub bcb: BasicCoverageBlock,
pub coverage_statements: Vec<CoverageStatement>,
Expand Down Expand Up @@ -214,7 +214,7 @@ pub struct CoverageSpans<'a, 'tcx> {
}

impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
pub(crate) fn generate_coverage_spans(
pub(super) fn generate_coverage_spans(
mir_body: &'a mir::Body<'tcx>,
body_span: Span,
basic_coverage_blocks: &'a CoverageGraph,
Expand Down Expand Up @@ -645,7 +645,10 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
}
}

fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> Option<Span> {
pub(super) fn filtered_statement_span(
statement: &'a Statement<'tcx>,
body_span: Span,
) -> Option<Span> {
match statement.kind {
// These statements have spans that are often outside the scope of the executed source code
// for their parent `BasicBlock`.
Expand Down Expand Up @@ -686,7 +689,10 @@ fn filtered_statement_span(statement: &'a Statement<'tcx>, body_span: Span) -> O
}
}

fn filtered_terminator_span(terminator: &'a Terminator<'tcx>, body_span: Span) -> Option<Span> {
pub(super) fn filtered_terminator_span(
terminator: &'a Terminator<'tcx>,
body_span: Span,
) -> Option<Span> {
match terminator.kind {
// These terminators have spans that don't positively contribute to computing a reasonable
// span of actually executed source code. (For example, SwitchInt terminators extracted from
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
authors = ["The Rust Project Developers"]
name = "coverage_test_macros"
version = "0.0.0"
edition = "2018"

[lib]
proc-macro = true
doctest = false

[dependencies]
proc-macro2 = "1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use proc_macro::TokenStream;

#[proc_macro]
pub fn let_bcb(item: TokenStream) -> TokenStream {
format!("let bcb{} = graph::BasicCoverageBlock::from_usize({});", item, item).parse().unwrap()
}
Loading

0 comments on commit 09cafd7

Please sign in to comment.