@@ -302,7 +302,7 @@ since it will not be called), and adds a new `FunctionCoverage`, with
302
302
test suite.)] ( ./tests/compiletest.md#coverage-tests )
303
303
304
304
Coverage instrumentation in the MIR is validated by a ` mir-opt ` test:
305
- [ ` tests/mir-opt/instrument_coverage.rs ` ] .
305
+ [ ` tests/mir-opt/coverage/ instrument_coverage.rs ` ] .
306
306
307
307
Coverage instrumentation in LLVM IR is validated by the [ ` tests/coverage ` ]
308
308
test suite in ` coverage-map ` mode.
@@ -321,7 +321,7 @@ human-readable coverage report.
321
321
> directive, so they will be skipped if the profiler runtime has not been
322
322
> [ enabled in ` config.toml ` ] ( #recommended-configtoml-settings ) .
323
323
324
- Finally, the [ ` coverage-llvmir ` ] test compiles a simple Rust program
324
+ Finally, the [ ` tests/codegen/instrument-coverage/testprog.rs ` ] test compiles a simple Rust program
325
325
with ` -C instrument-coverage ` and compares the compiled program's LLVM IR to
326
326
expected LLVM IR instructions and structured data for a coverage-enabled
327
327
program, including various checks for Coverage Map-related metadata and the LLVM
@@ -336,63 +336,36 @@ and `mir-opt` tests can be refreshed by running:
336
336
./x test tests/mir-opt --bless
337
337
```
338
338
339
- [ `tests/mir-opt/instrument_coverage.rs` ] : https://github.com/rust-lang/rust/blob/master/tests/mir-opt/instrument_coverage.rs
339
+ [ `tests/mir-opt/coverage/ instrument_coverage.rs` ] : https://github.com/rust-lang/rust/blob/master/tests/mir-opt/coverage /instrument_coverage.rs
340
340
[ `tests/coverage` ] : https://github.com/rust-lang/rust/tree/master/tests/coverage
341
341
[ `src/tools/coverage-dump` ] : https://github.com/rust-lang/rust/tree/master/src/tools/coverage-dump
342
342
[ `tests/coverage-run-rustdoc` ] : https://github.com/rust-lang/rust/tree/master/tests/coverage-run-rustdoc
343
- [ `coverage-llvmir ` ] : https://github.com/rust-lang/rust/tree /master/tests/run-make /coverage-llvmir
343
+ [ `tests/codegen/instrument-coverage/testprog.rs ` ] : https://github.com/rust-lang/rust/blob /master/tests/mir-opt /coverage/instrument_coverage.rs
344
344
345
345
## Implementation Details of the ` InstrumentCoverage ` MIR Pass
346
346
347
347
The bulk of the implementation of the ` InstrumentCoverage ` MIR pass is performed
348
- by the [ ` Instrumentor ` ] [ instrumentor ] . For each MIR (each non-const, non-inlined
349
- function, generic, or closure), the ` Instrumentor ` 's constructor prepares a
350
- [ ` CoverageGraph ` ] [ coverage-graph ] and then executes
351
- [ ` inject_counters() ` ] [ inject-counters ] .
348
+ by [ ` instrument_function_for_coverage ` ] . For each eligible MIR body, the instrumentor:
352
349
353
- ``` rust
354
- Instrumentor :: new (& self . name (), tcx , mir_body ). inject_counters ();
355
- ```
350
+ - Prepares a [ coverage graph]
351
+ - Extracts mapping information from MIR
352
+ - Prepares counters for each relevant node/edge in the coverage graph
353
+ - Creates mapping data to be embedded in side-tables attached to the MIR body
354
+ - Injects counters and other coverage statements into MIR
356
355
357
- The ` CoverageGraph ` is a coverage-specific simplification of the MIR control
356
+ The [ coverage graph ] is a coverage-specific simplification of the MIR control
358
357
flow graph (CFG). Its nodes are [ ` BasicCoverageBlock ` s] [ bcb ] , which
359
358
encompass one or more sequentially-executed MIR ` BasicBlock ` s
360
359
(with no internal branching).
361
360
362
361
Nodes and edges in the graph can have associated [ ` BcbCounter ` ] s, which are
363
362
stored in [ ` CoverageCounters ` ] .
364
363
365
- The ` Instrumentor ` 's ` inject_counters() ` uses the ` CoverageGraph ` to
366
- compute the best places to inject coverage counters, as MIR ` Statement ` s,
367
- with the following steps:
368
-
369
- 1 . [ ` generate_coverage_spans() ` ] [ generate-coverage-spans ] computes the minimum set of distinct,
370
- non-branching code regions, from the MIR. These ` CoverageSpan ` s
371
- represent a span of code that must be counted.
372
- 2 . [ ` make_bcb_counters() ` ] [ make-bcb-counters ] generates ` BcbCounter::Counter ` s and
373
- ` BcbCounter::Expression ` s for each ` CoverageSpan ` , plus additional
374
- _ intermediate expressions_ [ ^ intermediate-expressions ] that are not associated
375
- with any ` CodeRegion ` , but
376
- are required to compute a final ` Expression ` value for a ` CodeRegion ` .
377
- 3 . Inject the new counters into the MIR, as new ` StatementKind::Coverage `
378
- statements.
379
- 4 . Attach all other necessary coverage information to the function's body as
380
- [ ` FunctionCoverageInfo ` ] .
381
-
382
- [ ^ intermediate-expressions ] : Intermediate expressions are sometimes required
383
- because ` Expression ` s are limited to binary additions or subtractions. For
384
- example, ` A + (B - C) ` might represent an ` Expression ` count computed from three
385
- other counters, ` A ` , ` B ` , and ` C ` , but computing that value requires an
386
- intermediate expression for ` B - C ` .
387
-
388
- [ instrumentor ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/struct.Instrumentor.html
389
- [ coverage-graph ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/graph/struct.CoverageGraph.html
390
- [ inject-counters ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/struct.Instrumentor.html#method.inject_counters
364
+ [ `instrument_function_for_coverage` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/fn.instrument_function_for_coverage.html
365
+ [ coverage graph ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/graph/struct.CoverageGraph.html
391
366
[ bcb ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/graph/struct.BasicCoverageBlock.html
392
367
[ `BcbCounter` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/counters/enum.BcbCounter.html
393
368
[ `CoverageCounters` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/counters/struct.CoverageCounters.html
394
- [ generate-coverage-spans ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/spans/struct.CoverageSpans.html#method.generate_coverage_spans
395
- [ make-bcb-counters ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/counters/struct.BcbCounters.html#method.make_bcb_counters
396
369
397
370
### The ` CoverageGraph `
398
371
@@ -445,37 +418,16 @@ The BCB CFG is critical to simplifying the coverage analysis by ensuring graph p
445
418
queries (` is_dominated_by() ` , ` predecessors ` , ` successors ` , etc.) have branch (control flow)
446
419
significance.
447
420
448
- [ directed-graph ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/graph/trait.DirectedGraph.html
421
+ [ directed-graph ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/graph/trait.DirectedGraph.html_bogus
449
422
[ graph-traits ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/graph/index.html#traits
450
423
[ mir-dev-guide ] : mir/index.md
451
424
[ compute-basic-coverage-blocks ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/graph/struct.CoverageGraph.html#method.compute_basic_coverage_blocks
452
425
[ simplify-cfg ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/simplify/enum.SimplifyCfg.html
453
426
[ rust-lang/rust#78544 ] : https://github.com/rust-lang/rust/issues/78544
454
427
455
- ### ` CoverageSpans `
456
-
457
- The ` struct ` [ ` CoverageSpans ` ] [ coverage-spans ] builds and refines a final set of
458
- [ ` CoverageSpan ` ] [ coverage-span ] s, each representing the largest contiguous ` Span `
459
- of source within a single BCB. By definition--since each ` Span ` falls within a
460
- BCB, the ` Span ` is also non-branching; so if any code in that ` Span ` has executed,
461
- all code in the ` Span ` will have executed, the same number of times.
462
-
463
- [ ` CoverageSpans::generate_coverage_spans() ` ] [ generate-coverage-spans ] constructs
464
- an initial set of ` CoverageSpan ` s from the ` Span ` s associated with each MIR
465
- ` Statement ` and ` Terminator ` .
466
-
467
- The final stage of ` generate_coverage_spans() ` is handled by
468
- [ ` to_refined_spans() ` ] [ to-refined-spans ] , which iterates through the ` CoverageSpan ` s,
469
- merges and de-duplicates them, and returns an optimal, minimal set of ` CoverageSpan ` s
470
- that can be used to assign coverage ` Counter ` s or ` Expression ` s, one-for-one.
471
-
472
- [ coverage-spans ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/spans/struct.CoverageSpans.html
473
- [ coverage-span ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/spans/struct.CoverageSpan.html
474
- [ to-refined-spans ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/spans/struct.CoverageSpans.html#method.to_refined_spans
475
-
476
428
### ` make_bcb_counters() `
477
429
478
- [ ` make_bcb_counters() ` ] [ make-bcb-counters ] traverses the ` CoverageGraph ` and adds a
430
+ [ ` make_bcb_counters ` ] traverses the ` CoverageGraph ` and adds a
479
431
` Counter ` or ` Expression ` to every BCB. It uses _ Control Flow Analysis_
480
432
to determine where an ` Expression ` can be used in place of a ` Counter ` .
481
433
` Expressions ` have no runtime overhead, so if a viable expression (adding or
@@ -534,5 +486,6 @@ of `Counter` vs. `Expression` also depends on the order of counter
534
486
assignments, and whether a BCB or incoming edge counter already has
535
487
its ` Counter ` or ` Expression ` .
536
488
489
+ [ `make_bcb_counters` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/counters/struct.CoverageCounters.html#method.make_bcb_counters
537
490
[ bcb-counters ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/counters/struct.BcbCounters.html
538
491
[ traverse-coverage-graph-with-loops ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_transform/coverage/graph/struct.TraverseCoverageGraphWithLoops.html
0 commit comments