Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #117071

Merged
merged 23 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c564f81
rustdoc: align stability badge to baseline instead of bottom
notriddle Dec 13, 2022
193fec6
Preparing for merge from rustc
Oct 22, 2023
1f09dd2
Merge from rustc
Oct 22, 2023
8cbac82
clippy
RalfJung Oct 22, 2023
f6be93f
Auto merge of #3133 - rust-lang:rustup-2023-10-22, r=RalfJung
bors Oct 22, 2023
b53c34f
avoid AtomicU64 when a Cell is enough
RalfJung Oct 22, 2023
f35c36a
Auto merge of #3135 - RalfJung:nonatomic-clock, r=RalfJung
bors Oct 22, 2023
371883a
coverage: Split `FunctionCoverage` into distinct collector/finished p…
Zalathar Oct 6, 2023
86b55cc
coverage: Fetch expressions and mappings separately
Zalathar Oct 6, 2023
e985ae5
coverage: Build the global file table ahead of time
Zalathar Oct 3, 2023
88159ca
coverage: Encapsulate local-to-global file mappings
Zalathar Sep 28, 2023
de4cfbc
coverage: Encode function mappings without re-sorting them
Zalathar Sep 28, 2023
6af9fef
coverage: Emit the filenames section before encoding per-function map…
Zalathar Oct 6, 2023
dc00d03
add target csky-unknown-linux-gnuabiv2hf
Dirreke Oct 22, 2023
5454797
tidy docs
Dirreke Oct 22, 2023
bb67e0f
fix broken link: update incremental compilation url
gvozdvmozgu Oct 22, 2023
1f9f041
x.ps1: remove the check for Python from Windows Store
xobs Oct 23, 2023
e86f9b6
Rollup merge of #105666 - notriddle:notriddle/stab-baseline, r=Guilla…
matthiaskrgr Oct 23, 2023
dde77f7
Rollup merge of #117042 - Zalathar:file-table, r=cjgillot
matthiaskrgr Oct 23, 2023
fe4fde2
Rollup merge of #117044 - RalfJung:miri, r=RalfJung
matthiaskrgr Oct 23, 2023
9acb775
Rollup merge of #117049 - Dirreke:csky-unknown-linux-gunabiv2, r=bjorn3
matthiaskrgr Oct 23, 2023
2636745
Rollup merge of #117051 - gvozdvmozgu:fix-incremental-compilation-lin…
matthiaskrgr Oct 23, 2023
cec7d4a
Rollup merge of #117069 - xobs:x.ps1-remove-windows-store-check, r=al…
matthiaskrgr Oct 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3601,6 +3601,7 @@ version = "0.0.0"
dependencies = [
"bitflags 1.3.2",
"cstr",
"itertools",
"libc",
"measureme",
"object",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ test = false
[dependencies]
bitflags = "1.0"
cstr = "0.2"
itertools = "0.10.5"
libc = "0.2"
measureme = "10.0.0"
object = { version = "0.32.0", default-features = false, features = [
Expand Down
76 changes: 40 additions & 36 deletions compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};

use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::coverage::{
CodeRegion, CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, Op,
};
use rustc_middle::ty::Instance;
use rustc_span::Symbol;

/// Holds all of the coverage mapping data associated with a function instance,
/// collected during traversal of `Coverage` statements in the function's MIR.
#[derive(Debug)]
pub struct FunctionCoverage<'tcx> {
pub struct FunctionCoverageCollector<'tcx> {
/// Coverage info that was attached to this function by the instrumentor.
function_coverage_info: &'tcx FunctionCoverageInfo,
is_used: bool,
Expand All @@ -26,7 +28,7 @@ pub struct FunctionCoverage<'tcx> {
expressions_seen: BitSet<ExpressionId>,
}

impl<'tcx> FunctionCoverage<'tcx> {
impl<'tcx> FunctionCoverageCollector<'tcx> {
/// Creates a new set of coverage data for a used (called) function.
pub fn new(
instance: Instance<'tcx>,
Expand Down Expand Up @@ -76,11 +78,6 @@ impl<'tcx> FunctionCoverage<'tcx> {
}
}

/// Returns true for a used (called) function, and false for an unused function.
pub fn is_used(&self) -> bool {
self.is_used
}

/// Marks a counter ID as having been seen in a counter-increment statement.
#[instrument(level = "debug", skip(self))]
pub(crate) fn mark_counter_id_seen(&mut self, id: CounterId) {
Expand Down Expand Up @@ -165,72 +162,79 @@ impl<'tcx> FunctionCoverage<'tcx> {
ZeroExpressions(zero_expressions)
}

pub(crate) fn into_finished(self) -> FunctionCoverage<'tcx> {
let zero_expressions = self.identify_zero_expressions();
let FunctionCoverageCollector { function_coverage_info, is_used, counters_seen, .. } = self;

FunctionCoverage { function_coverage_info, is_used, counters_seen, zero_expressions }
}
}

pub(crate) struct FunctionCoverage<'tcx> {
function_coverage_info: &'tcx FunctionCoverageInfo,
is_used: bool,

counters_seen: BitSet<CounterId>,
zero_expressions: ZeroExpressions,
}

impl<'tcx> FunctionCoverage<'tcx> {
/// Returns true for a used (called) function, and false for an unused function.
pub(crate) fn is_used(&self) -> bool {
self.is_used
}

/// Return the source hash, generated from the HIR node structure, and used to indicate whether
/// or not the source code structure changed between different compilations.
pub fn source_hash(&self) -> u64 {
if self.is_used { self.function_coverage_info.function_source_hash } else { 0 }
}

/// Generate an array of CounterExpressions, and an iterator over all `Counter`s and their
/// associated `Regions` (from which the LLVM-specific `CoverageMapGenerator` will create
/// `CounterMappingRegion`s.
pub fn get_expressions_and_counter_regions(
&self,
) -> (Vec<CounterExpression>, impl Iterator<Item = (Counter, &CodeRegion)>) {
let zero_expressions = self.identify_zero_expressions();

let counter_expressions = self.counter_expressions(&zero_expressions);
// Expression IDs are indices into `self.expressions`, and on the LLVM
// side they will be treated as indices into `counter_expressions`, so
// the two vectors should correspond 1:1.
assert_eq!(self.function_coverage_info.expressions.len(), counter_expressions.len());

let counter_regions = self.counter_regions(zero_expressions);

(counter_expressions, counter_regions)
/// Returns an iterator over all filenames used by this function's mappings.
pub(crate) fn all_file_names(&self) -> impl Iterator<Item = Symbol> + Captures<'_> {
self.function_coverage_info.mappings.iter().map(|mapping| mapping.code_region.file_name)
}

/// Convert this function's coverage expression data into a form that can be
/// passed through FFI to LLVM.
fn counter_expressions(&self, zero_expressions: &ZeroExpressions) -> Vec<CounterExpression> {
pub(crate) fn counter_expressions(
&self,
) -> impl Iterator<Item = CounterExpression> + ExactSizeIterator + Captures<'_> {
// We know that LLVM will optimize out any unused expressions before
// producing the final coverage map, so there's no need to do the same
// thing on the Rust side unless we're confident we can do much better.
// (See `CounterExpressionsMinimizer` in `CoverageMappingWriter.cpp`.)

let counter_from_operand = |operand: CovTerm| match operand {
CovTerm::Expression(id) if zero_expressions.contains(id) => Counter::ZERO,
CovTerm::Expression(id) if self.zero_expressions.contains(id) => Counter::ZERO,
_ => Counter::from_term(operand),
};

self.function_coverage_info
.expressions
.iter()
.map(|&Expression { lhs, op, rhs }| CounterExpression {
self.function_coverage_info.expressions.iter().map(move |&Expression { lhs, op, rhs }| {
CounterExpression {
lhs: counter_from_operand(lhs),
kind: match op {
Op::Add => ExprKind::Add,
Op::Subtract => ExprKind::Subtract,
},
rhs: counter_from_operand(rhs),
})
.collect::<Vec<_>>()
}
})
}

/// Converts this function's coverage mappings into an intermediate form
/// that will be used by `mapgen` when preparing for FFI.
fn counter_regions(
pub(crate) fn counter_regions(
&self,
zero_expressions: ZeroExpressions,
) -> impl Iterator<Item = (Counter, &CodeRegion)> {
) -> impl Iterator<Item = (Counter, &CodeRegion)> + ExactSizeIterator {
// Historically, mappings were stored directly in counter/expression
// statements in MIR, and MIR optimizations would sometimes remove them.
// That's mostly no longer true, so now we detect cases where that would
// have happened, and zero out the corresponding mappings here instead.
let counter_for_term = move |term: CovTerm| {
let force_to_zero = match term {
CovTerm::Counter(id) => !self.counters_seen.contains(id),
CovTerm::Expression(id) => zero_expressions.contains(id),
CovTerm::Expression(id) => self.zero_expressions.contains(id),
CovTerm::Zero => false,
};
if force_to_zero { Counter::ZERO } else { Counter::from_term(term) }
Expand Down
Loading
Loading