Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit bfa5eb1

Browse files
committed
Auto merge of rust-lang#134516 - matthiaskrgr:rollup-aqwxii0, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#134463 (compiletest: don't register predefined `MSVC`/`NONMSVC` FileCheck prefixes) - rust-lang#134487 (Add reference annotations for the `coverage` attribute) - rust-lang#134497 (coverage: Store coverage source regions as `Span` until codegen (take 2)) - rust-lang#134502 (Update std libc version to 0.2.169) - rust-lang#134506 (Remove a duplicated check that doesn't do anything anymore.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3bf62cc + 4f053b1 commit bfa5eb1

File tree

68 files changed

+531
-488
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+531
-488
lines changed

‎Cargo.lock‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,9 +2012,9 @@ checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401"
20122012

20132013
[[package]]
20142014
name = "libc"
2015-
version = "0.2.168"
2015+
version = "0.2.169"
20162016
source = "registry+https://github.com/rust-lang/crates.io-index"
2017-
checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
2017+
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
20182018

20192019
[[package]]
20202020
name = "libdbus-sys"

‎compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs‎

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId, SourceRegion};
2-
3-
use crate::coverageinfo::mapgen::LocalFileId;
1+
use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId};
42

53
/// Must match the layout of `LLVMRustCounterKind`.
64
#[derive(Copy, Clone, Debug)]
@@ -126,30 +124,16 @@ pub(crate) struct CoverageSpan {
126124
/// Local index into the function's local-to-global file ID table.
127125
/// The value at that index is itself an index into the coverage filename
128126
/// table in the CGU's `__llvm_covmap` section.
129-
file_id: u32,
127+
pub(crate)file_id: u32,
130128

131129
/// 1-based starting line of the source code span.
132-
start_line: u32,
130+
pub(crate)start_line: u32,
133131
/// 1-based starting column of the source code span.
134-
start_col: u32,
132+
pub(crate)start_col: u32,
135133
/// 1-based ending line of the source code span.
136-
end_line: u32,
134+
pub(crate)end_line: u32,
137135
/// 1-based ending column of the source code span. High bit must be unset.
138-
end_col: u32,
139-
}
140-
141-
impl CoverageSpan {
142-
pub(crate) fn from_source_region(
143-
local_file_id: LocalFileId,
144-
code_region: &SourceRegion,
145-
) -> Self {
146-
let file_id = local_file_id.as_u32();
147-
let &SourceRegion { start_line, start_col, end_line, end_col } = code_region;
148-
// Internally, LLVM uses the high bit of `end_col` to distinguish between
149-
// code regions and gap regions, so it can't be used by the column number.
150-
assert!(end_col & (1u32 << 31) == 0, "high bit of `end_col` must be unset: {end_col:#X}");
151-
Self { file_id, start_line, start_col, end_line, end_col }
152-
}
136+
pub(crate) end_col: u32,
153137
}
154138

155139
/// Holds tables of the various region types in one struct.
@@ -184,15 +168,15 @@ impl Regions {
184168
#[derive(Clone, Debug)]
185169
#[repr(C)]
186170
pub(crate) struct CodeRegion {
187-
pub(crate) span: CoverageSpan,
171+
pub(crate) cov_span: CoverageSpan,
188172
pub(crate) counter: Counter,
189173
}
190174

191175
/// Must match the layout of `LLVMRustCoverageBranchRegion`.
192176
#[derive(Clone, Debug)]
193177
#[repr(C)]
194178
pub(crate) struct BranchRegion {
195-
pub(crate) span: CoverageSpan,
179+
pub(crate) cov_span: CoverageSpan,
196180
pub(crate) true_counter: Counter,
197181
pub(crate) false_counter: Counter,
198182
}
@@ -201,7 +185,7 @@ pub(crate) struct BranchRegion {
201185
#[derive(Clone, Debug)]
202186
#[repr(C)]
203187
pub(crate) struct MCDCBranchRegion {
204-
pub(crate) span: CoverageSpan,
188+
pub(crate) cov_span: CoverageSpan,
205189
pub(crate) true_counter: Counter,
206190
pub(crate) false_counter: Counter,
207191
pub(crate) mcdc_branch_params: mcdc::BranchParameters,
@@ -211,6 +195,6 @@ pub(crate) struct MCDCBranchRegion {
211195
#[derive(Clone, Debug)]
212196
#[repr(C)]
213197
pub(crate) struct MCDCDecisionRegion {
214-
pub(crate) span: CoverageSpan,
198+
pub(crate) cov_span: CoverageSpan,
215199
pub(crate) mcdc_decision_params: mcdc::DecisionParameters,
216200
}

‎compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,10 @@ pub(crate) fn create_pgo_func_name_var<'ll>(
4040
}
4141
}
4242

43-
pub(crate) fn write_filenames_to_buffer<'a>(
44-
filenames: impl IntoIterator<Item = &'a str>,
45-
) -> Vec<u8> {
43+
pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef<str>]) -> Vec<u8> {
4644
let (pointers, lengths) = filenames
4745
.into_iter()
46+
.map(AsRef::as_ref)
4847
.map(|s: &str| (s.as_c_char_ptr(), s.len()))
4948
.unzip::<_, _, Vec<_>, Vec<_>>();
5049

‎compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs‎

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
use std::iter;
1+
use std::sync::Arc;
22

33
use itertools::Itertools;
44
use rustc_abi::Align;
55
use rustc_codegen_ssa::traits::{
66
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
77
};
8-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap,FxIndexSet};
8+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
99
use rustc_hir::def_id::{DefId, LocalDefId};
1010
use rustc_index::IndexVec;
1111
use rustc_middle::mir;
1212
use rustc_middle::ty::{self, TyCtxt};
1313
use rustc_session::RemapFileNameExt;
1414
use rustc_session::config::RemapPathScopeComponents;
1515
use rustc_span::def_id::DefIdSet;
16-
use rustc_span::{Span,Symbol};
16+
use rustc_span::{SourceFile,StableSourceFileId};
1717
use tracing::debug;
1818

1919
use crate::common::CodegenCx;
@@ -22,6 +22,7 @@ use crate::coverageinfo::mapgen::covfun::prepare_covfun_record;
2222
use crate::llvm;
2323

2424
mod covfun;
25+
mod spans;
2526

2627
/// Generates and exports the coverage map, which is embedded in special
2728
/// linker sections in the final binary.
@@ -131,45 +132,51 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
131132
generate_covmap_record(cx, covmap_version, &filenames_buffer);
132133
}
133134

134-
/// Maps "global" (per-CGU) file ID numbers to their underlying filenames.
135+
/// Maps "global" (per-CGU) file ID numbers to their underlying source files.
135136
struct GlobalFileTable {
136-
/// This "raw" table doesn't include the working dir, so a filename's
137+
/// This "raw" table doesn't include the working dir, so a file's
137138
/// global ID is its index in this set **plus one**.
138-
raw_file_table: FxIndexSet<Symbol>,
139+
raw_file_table: FxIndexMap<StableSourceFileId,Arc<SourceFile>>,
139140
}
140141

141142
impl GlobalFileTable {
142143
fn new() -> Self {
143-
Self { raw_file_table: FxIndexSet::default() }
144+
Self { raw_file_table: FxIndexMap::default() }
144145
}
145146

146-
fn global_file_id_for_file_name(&mut self, file_name:Symbol) -> GlobalFileId {
147+
fn global_file_id_for_file(&mut self, file:&Arc<SourceFile>) -> GlobalFileId {
147148
// Ensure the given file has a table entry, and get its index.
148-
let (raw_id, _) = self.raw_file_table.insert_full(file_name);
149+
let entry = self.raw_file_table.entry(file.stable_id);
150+
let raw_id = entry.index();
151+
entry.or_insert_with(|| Arc::clone(file));
152+
149153
// The raw file table doesn't include an entry for the working dir
150154
// (which has ID 0), so add 1 to get the correct ID.
151155
GlobalFileId::from_usize(raw_id + 1)
152156
}
153157

154158
fn make_filenames_buffer(&self, tcx: TyCtxt<'_>) -> Vec<u8> {
159+
let mut table = Vec::with_capacity(self.raw_file_table.len() + 1);
160+
155161
// LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
156162
// requires setting the first filename to the compilation directory.
157163
// Since rustc generates coverage maps with relative paths, the
158164
// compilation directory can be combined with the relative paths
159165
// to get absolute paths, if needed.
160-
use rustc_session::RemapFileNameExt;
161-
use rustc_session::config::RemapPathScopeComponents;
162-
let working_dir: &str = &tcx
163-
.sess
164-
.opts
165-
.working_dir
166-
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
167-
.to_string_lossy();
168-
169-
// Insert the working dir at index 0, before the other filenames.
170-
let filenames =
171-
iter::once(working_dir).chain(self.raw_file_table.iter().map(Symbol::as_str));
172-
llvm_cov::write_filenames_to_buffer(filenames)
166+
table.push(
167+
tcx.sess
168+
.opts
169+
.working_dir
170+
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
171+
.to_string_lossy(),
172+
);
173+
174+
// Add the regular entries after the base directory.
175+
table.extend(self.raw_file_table.values().map(|file| {
176+
file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy()
177+
}));
178+
179+
llvm_cov::write_filenames_to_buffer(&table)
173180
}
174181
}
175182

@@ -182,7 +189,7 @@ rustc_index::newtype_index! {
182189
/// An index into a function's list of global file IDs. That underlying list
183190
/// of local-to-global mappings will be embedded in the function's record in
184191
/// the `__llvm_covfun` linker section.
185-
pub(crate)struct LocalFileId {}
192+
struct LocalFileId {}
186193
}
187194

188195
/// Holds a mapping from "local" (per-function) file IDs to "global" (per-CGU)
@@ -208,13 +215,6 @@ impl VirtualFileMapping {
208215
}
209216
}
210217

211-
fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
212-
let source_file = tcx.sess.source_map().lookup_source_file(span.lo());
213-
let name =
214-
source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy();
215-
Symbol::intern(&name)
216-
}
217-
218218
/// Generates the contents of the covmap record for this CGU, which mostly
219219
/// consists of a header and a list of filenames. The record is then stored
220220
/// as a global variable in the `__llvm_covmap` section.

‎compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs‎

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ use rustc_abi::Align;
1010
use rustc_codegen_ssa::traits::{
1111
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
1212
};
13-
use rustc_middle::bug;
1413
use rustc_middle::mir::coverage::{
1514
CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping, MappingKind, Op,
1615
};
1716
use rustc_middle::ty::{Instance, TyCtxt};
17+
use rustc_span::Span;
1818
use rustc_target::spec::HasTargetSpec;
1919
use tracing::debug;
2020

2121
use crate::common::CodegenCx;
22-
use crate::coverageinfo::mapgen::{GlobalFileTable, VirtualFileMapping, span_file_name};
22+
use crate::coverageinfo::mapgen::{GlobalFileTable, VirtualFileMapping, spans};
2323
use crate::coverageinfo::{ffi, llvm_cov};
2424
use crate::llvm;
2525

@@ -67,12 +67,8 @@ pub(crate) fn prepare_covfun_record<'tcx>(
6767
fill_region_tables(tcx, global_file_table, fn_cov_info, ids_info, &mut covfun);
6868

6969
if covfun.regions.has_no_regions() {
70-
if covfun.is_used {
71-
bug!("a used function should have had coverage mapping data but did not: {covfun:?}");
72-
} else {
73-
debug!(?covfun, "unused function had no coverage mapping data");
74-
return None;
75-
}
70+
debug!(?covfun, "function has no mappings to embed; skipping");
71+
return None;
7672
}
7773

7874
Some(covfun)
@@ -121,49 +117,66 @@ fn fill_region_tables<'tcx>(
121117
covfun: &mut CovfunRecord<'tcx>,
122118
) {
123119
// Currently a function's mappings must all be in the same file as its body span.
124-
let file_name = span_file_name(tcx, fn_cov_info.body_span);
120+
let source_map = tcx.sess.source_map();
121+
let source_file = source_map.lookup_source_file(fn_cov_info.body_span.lo());
125122

126-
// Look up the global file ID for that filename.
127-
let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
123+
// Look up the global file ID for that file.
124+
let global_file_id = global_file_table.global_file_id_for_file(&source_file);
128125

129126
// Associate that global file ID with a local file ID for this function.
130127
let local_file_id = covfun.virtual_file_mapping.local_id_for_global(global_file_id);
131-
debug!(" file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'");
132128

133129
let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
134130
&mut covfun.regions;
135131

132+
let make_cov_span = |span: Span| {
133+
spans::make_coverage_span(local_file_id, source_map, fn_cov_info, &source_file, span)
134+
};
135+
let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen();
136+
136137
// For each counter/region pair in this function+file, convert it to a
137138
// form suitable for FFI.
138139
let is_zero_term = |term| !covfun.is_used || ids_info.is_zero_term(term);
139-
for Mapping { kind, ref source_region } in &fn_cov_info.mappings {
140+
for &Mapping { refkind, span } in &fn_cov_info.mappings {
140141
// If the mapping refers to counters/expressions that were removed by
141142
// MIR opts, replace those occurrences with zero.
142143
let kind = kind.map_terms(|term| if is_zero_term(term) { CovTerm::Zero } else { term });
143144

144-
let span = ffi::CoverageSpan::from_source_region(local_file_id, source_region);
145+
// Convert the `Span` into coordinates that we can pass to LLVM, or
146+
// discard the span if conversion fails. In rare, cases _all_ of a
147+
// function's spans are discarded, and the rest of coverage codegen
148+
// needs to handle that gracefully to avoid a repeat of #133606.
149+
// We don't have a good test case for triggering that organically, so
150+
// instead we set `-Zcoverage-options=discard-all-spans-in-codegen`
151+
// to force it to occur.
152+
let Some(cov_span) = make_cov_span(span) else { continue };
153+
if discard_all {
154+
continue;
155+
}
156+
145157
match kind {
146158
MappingKind::Code(term) => {
147-
code_regions.push(ffi::CodeRegion { span, counter: ffi::Counter::from_term(term) });
159+
code_regions
160+
.push(ffi::CodeRegion { cov_span, counter: ffi::Counter::from_term(term) });
148161
}
149162
MappingKind::Branch { true_term, false_term } => {
150163
branch_regions.push(ffi::BranchRegion {
151-
span,
164+
cov_span,
152165
true_counter: ffi::Counter::from_term(true_term),
153166
false_counter: ffi::Counter::from_term(false_term),
154167
});
155168
}
156169
MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
157170
mcdc_branch_regions.push(ffi::MCDCBranchRegion {
158-
span,
171+
cov_span,
159172
true_counter: ffi::Counter::from_term(true_term),
160173
false_counter: ffi::Counter::from_term(false_term),
161174
mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params),
162175
});
163176
}
164177
MappingKind::MCDCDecision(mcdc_decision_params) => {
165178
mcdc_decision_regions.push(ffi::MCDCDecisionRegion {
166-
span,
179+
cov_span,
167180
mcdc_decision_params: ffi::mcdc::DecisionParameters::from(mcdc_decision_params),
168181
});
169182
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /