Skip to content

Commit 9e6d698

Browse files
committed
Auto merge of rust-lang#133609 - Zalathar:rollup-1825fa8, r=Zalathar
Rollup of 7 pull requests Successful merges: - rust-lang#131323 (Support `clobber_abi` in AVR inline assembly) - rust-lang#133092 (Always set the deployment target when building std) - rust-lang#133134 (Don't use a SyntheticProvider for literally every type) - rust-lang#133538 (Better diagnostic for fn items in variadic functions) - rust-lang#133590 (Rename `-Zparse-only`) - rust-lang#133592 (Misc: better instructions for envrc, ignore `/build` instead of `build/`) - rust-lang#133608 (Revert rust-lang#133418 (Store coverage source regions as `Span`) due to regression rust-lang#133606) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d6f8829 + 088868c commit 9e6d698

Some content is hidden

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

51 files changed

+594
-345
lines changed

.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ no_llvm_build
4646
/inst/
4747
/llvm/
4848
/mingw-build/
49-
build/
50-
!/compiler/rustc_mir_build/src/build/
49+
/build
5150
/build-rust-analyzer/
5251
/dist/
5352
/unicode-downloads

compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs

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

35
/// Must match the layout of `LLVMRustCounterKind`.
46
#[derive(Copy, Clone, Debug)]
@@ -124,31 +126,45 @@ pub(crate) struct CoverageSpan {
124126
/// Local index into the function's local-to-global file ID table.
125127
/// The value at that index is itself an index into the coverage filename
126128
/// table in the CGU's `__llvm_covmap` section.
127-
pub(crate) file_id: u32,
129+
file_id: u32,
128130

129131
/// 1-based starting line of the source code span.
130-
pub(crate) start_line: u32,
132+
start_line: u32,
131133
/// 1-based starting column of the source code span.
132-
pub(crate) start_col: u32,
134+
start_col: u32,
133135
/// 1-based ending line of the source code span.
134-
pub(crate) end_line: u32,
136+
end_line: u32,
135137
/// 1-based ending column of the source code span. High bit must be unset.
136-
pub(crate) end_col: u32,
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+
}
137153
}
138154

139155
/// Must match the layout of `LLVMRustCoverageCodeRegion`.
140156
#[derive(Clone, Debug)]
141157
#[repr(C)]
142158
pub(crate) struct CodeRegion {
143-
pub(crate) cov_span: CoverageSpan,
159+
pub(crate) span: CoverageSpan,
144160
pub(crate) counter: Counter,
145161
}
146162

147163
/// Must match the layout of `LLVMRustCoverageBranchRegion`.
148164
#[derive(Clone, Debug)]
149165
#[repr(C)]
150166
pub(crate) struct BranchRegion {
151-
pub(crate) cov_span: CoverageSpan,
167+
pub(crate) span: CoverageSpan,
152168
pub(crate) true_counter: Counter,
153169
pub(crate) false_counter: Counter,
154170
}
@@ -157,7 +173,7 @@ pub(crate) struct BranchRegion {
157173
#[derive(Clone, Debug)]
158174
#[repr(C)]
159175
pub(crate) struct MCDCBranchRegion {
160-
pub(crate) cov_span: CoverageSpan,
176+
pub(crate) span: CoverageSpan,
161177
pub(crate) true_counter: Counter,
162178
pub(crate) false_counter: Counter,
163179
pub(crate) mcdc_branch_params: mcdc::BranchParameters,
@@ -167,6 +183,6 @@ pub(crate) struct MCDCBranchRegion {
167183
#[derive(Clone, Debug)]
168184
#[repr(C)]
169185
pub(crate) struct MCDCDecisionRegion {
170-
pub(crate) cov_span: CoverageSpan,
186+
pub(crate) span: CoverageSpan,
171187
pub(crate) mcdc_decision_params: mcdc::DecisionParameters,
172188
}

compiler/rustc_codegen_llvm/src/coverageinfo/map_data.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use rustc_data_structures::fx::FxIndexSet;
33
use rustc_index::bit_set::BitSet;
44
use rustc_middle::mir::coverage::{
55
CounterId, CovTerm, Expression, ExpressionId, FunctionCoverageInfo, Mapping, MappingKind, Op,
6+
SourceRegion,
67
};
78
use rustc_middle::ty::Instance;
8-
use rustc_span::Span;
99
use tracing::{debug, instrument};
1010

1111
use crate::coverageinfo::ffi::{Counter, CounterExpression, ExprKind};
@@ -220,16 +220,16 @@ impl<'tcx> FunctionCoverage<'tcx> {
220220
})
221221
}
222222

223-
/// Yields all this function's coverage mappings, after simplifying away
224-
/// unused counters and counter expressions.
225-
pub(crate) fn mapping_spans(
223+
/// Converts this function's coverage mappings into an intermediate form
224+
/// that will be used by `mapgen` when preparing for FFI.
225+
pub(crate) fn counter_regions(
226226
&self,
227-
) -> impl Iterator<Item = (MappingKind, Span)> + ExactSizeIterator + Captures<'_> {
227+
) -> impl Iterator<Item = (MappingKind, &SourceRegion)> + ExactSizeIterator {
228228
self.function_coverage_info.mappings.iter().map(move |mapping| {
229-
let &Mapping { ref kind, span } = mapping;
229+
let Mapping { kind, source_region } = mapping;
230230
let kind =
231231
kind.map_terms(|term| if self.is_zero_term(term) { CovTerm::Zero } else { term });
232-
(kind, span)
232+
(kind, source_region)
233233
})
234234
}
235235

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+63-66
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
mod spans;
2-
31
use std::ffi::CString;
4-
use std::sync::Arc;
2+
use std::iter;
53

64
use itertools::Itertools as _;
75
use rustc_abi::Align;
86
use rustc_codegen_ssa::traits::{
97
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
108
};
11-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
9+
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
1210
use rustc_hir::def_id::{DefId, LocalDefId};
1311
use rustc_index::IndexVec;
1412
use rustc_middle::mir::coverage::MappingKind;
@@ -17,7 +15,7 @@ use rustc_middle::{bug, mir};
1715
use rustc_session::RemapFileNameExt;
1816
use rustc_session::config::RemapPathScopeComponents;
1917
use rustc_span::def_id::DefIdSet;
20-
use rustc_span::{SourceFile, StableSourceFileId};
18+
use rustc_span::{Span, Symbol};
2119
use rustc_target::spec::HasTargetSpec;
2220
use tracing::debug;
2321

@@ -74,11 +72,11 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
7472
.map(|(instance, function_coverage)| (instance, function_coverage.into_finished()))
7573
.collect::<Vec<_>>();
7674

77-
let all_files = function_coverage_entries
75+
let all_file_names = function_coverage_entries
7876
.iter()
7977
.map(|(_, fn_cov)| fn_cov.function_coverage_info.body_span)
80-
.map(|span| tcx.sess.source_map().lookup_source_file(span.lo()));
81-
let global_file_table = GlobalFileTable::new(all_files);
78+
.map(|span| span_file_name(tcx, span));
79+
let global_file_table = GlobalFileTable::new(all_file_names);
8280

8381
// Encode all filenames referenced by coverage mappings in this CGU.
8482
let filenames_buffer = global_file_table.make_filenames_buffer(tcx);
@@ -105,8 +103,15 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
105103
encode_mappings_for_function(tcx, &global_file_table, &function_coverage);
106104

107105
if coverage_mapping_buffer.is_empty() {
108-
debug!("function has no mappings to embed; skipping");
109-
continue;
106+
if function_coverage.is_used() {
107+
bug!(
108+
"A used function should have had coverage mapping data but did not: {}",
109+
mangled_function_name
110+
);
111+
} else {
112+
debug!("unused function had no coverage mapping data: {}", mangled_function_name);
113+
continue;
114+
}
110115
}
111116

112117
if !is_used {
@@ -143,62 +148,54 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
143148
}
144149
}
145150

146-
/// Maps "global" (per-CGU) file ID numbers to their underlying source files.
151+
/// Maps "global" (per-CGU) file ID numbers to their underlying filenames.
147152
struct GlobalFileTable {
148-
/// This "raw" table doesn't include the working dir, so a file's
153+
/// This "raw" table doesn't include the working dir, so a filename's
149154
/// global ID is its index in this set **plus one**.
150-
raw_file_table: FxIndexMap<StableSourceFileId, Arc<SourceFile>>,
155+
raw_file_table: FxIndexSet<Symbol>,
151156
}
152157

153158
impl GlobalFileTable {
154-
fn new(all_files: impl IntoIterator<Item = Arc<SourceFile>>) -> Self {
155-
// Collect all of the files into a set. Files usually come in contiguous
156-
// runs, so we can dedup adjacent ones to save work.
157-
let mut raw_file_table = all_files
158-
.into_iter()
159-
.dedup_by(|a, b| a.stable_id == b.stable_id)
160-
.map(|f| (f.stable_id, f))
161-
.collect::<FxIndexMap<StableSourceFileId, Arc<SourceFile>>>();
159+
fn new(all_file_names: impl IntoIterator<Item = Symbol>) -> Self {
160+
// Collect all of the filenames into a set. Filenames usually come in
161+
// contiguous runs, so we can dedup adjacent ones to save work.
162+
let mut raw_file_table = all_file_names.into_iter().dedup().collect::<FxIndexSet<Symbol>>();
162163

163-
// Sort the file table by its underlying filenames.
164-
raw_file_table.sort_unstable_by(|_, a, _, b| {
165-
Ord::cmp(&a.name, &b.name).then_with(|| Ord::cmp(&a.stable_id, &b.stable_id))
166-
});
164+
// Sort the file table by its actual string values, not the arbitrary
165+
// ordering of its symbols.
166+
raw_file_table.sort_unstable_by(|a, b| a.as_str().cmp(b.as_str()));
167167

168168
Self { raw_file_table }
169169
}
170170

171-
fn global_file_id_for_file(&self, file: &SourceFile) -> GlobalFileId {
172-
let raw_id = self.raw_file_table.get_index_of(&file.stable_id).unwrap_or_else(|| {
173-
bug!("file not found in prepared global file table: {:?}", file.name);
171+
fn global_file_id_for_file_name(&self, file_name: Symbol) -> GlobalFileId {
172+
let raw_id = self.raw_file_table.get_index_of(&file_name).unwrap_or_else(|| {
173+
bug!("file name not found in prepared global file table: {file_name}");
174174
});
175175
// The raw file table doesn't include an entry for the working dir
176176
// (which has ID 0), so add 1 to get the correct ID.
177177
GlobalFileId::from_usize(raw_id + 1)
178178
}
179179

180180
fn make_filenames_buffer(&self, tcx: TyCtxt<'_>) -> Vec<u8> {
181-
let mut table = Vec::with_capacity(self.raw_file_table.len() + 1);
182-
183181
// LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
184182
// requires setting the first filename to the compilation directory.
185183
// Since rustc generates coverage maps with relative paths, the
186184
// compilation directory can be combined with the relative paths
187185
// to get absolute paths, if needed.
188-
table.push(
189-
tcx.sess
190-
.opts
191-
.working_dir
192-
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
193-
.to_string_lossy(),
194-
);
195-
196-
// Add the regular entries after the base directory.
197-
table.extend(self.raw_file_table.values().map(|file| {
198-
file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy()
199-
}));
200-
201-
llvm_cov::write_filenames_to_buffer(table.iter().map(|f| f.as_ref()))
186+
use rustc_session::RemapFileNameExt;
187+
use rustc_session::config::RemapPathScopeComponents;
188+
let working_dir: &str = &tcx
189+
.sess
190+
.opts
191+
.working_dir
192+
.for_scope(tcx.sess, RemapPathScopeComponents::MACRO)
193+
.to_string_lossy();
194+
195+
// Insert the working dir at index 0, before the other filenames.
196+
let filenames =
197+
iter::once(working_dir).chain(self.raw_file_table.iter().map(Symbol::as_str));
198+
llvm_cov::write_filenames_to_buffer(filenames)
202199
}
203200
}
204201

@@ -211,7 +208,7 @@ rustc_index::newtype_index! {
211208
/// An index into a function's list of global file IDs. That underlying list
212209
/// of local-to-global mappings will be embedded in the function's record in
213210
/// the `__llvm_covfun` linker section.
214-
struct LocalFileId {}
211+
pub(crate) struct LocalFileId {}
215212
}
216213

217214
/// Holds a mapping from "local" (per-function) file IDs to "global" (per-CGU)
@@ -237,6 +234,13 @@ impl VirtualFileMapping {
237234
}
238235
}
239236

237+
fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol {
238+
let source_file = tcx.sess.source_map().lookup_source_file(span.lo());
239+
let name =
240+
source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy();
241+
Symbol::intern(&name)
242+
}
243+
240244
/// Using the expressions and counter regions collected for a single function,
241245
/// generate the variable-sized payload of its corresponding `__llvm_covfun`
242246
/// entry. The payload is returned as a vector of bytes.
@@ -247,13 +251,11 @@ fn encode_mappings_for_function(
247251
global_file_table: &GlobalFileTable,
248252
function_coverage: &FunctionCoverage<'_>,
249253
) -> Vec<u8> {
250-
let mapping_spans = function_coverage.mapping_spans();
251-
if mapping_spans.is_empty() {
254+
let counter_regions = function_coverage.counter_regions();
255+
if counter_regions.is_empty() {
252256
return Vec::new();
253257
}
254258

255-
let fn_cov_info = function_coverage.function_coverage_info;
256-
257259
let expressions = function_coverage.counter_expressions().collect::<Vec<_>>();
258260

259261
let mut virtual_file_mapping = VirtualFileMapping::default();
@@ -263,47 +265,42 @@ fn encode_mappings_for_function(
263265
let mut mcdc_decision_regions = vec![];
264266

265267
// Currently a function's mappings must all be in the same file as its body span.
266-
let source_map = tcx.sess.source_map();
267-
let source_file = source_map.lookup_source_file(fn_cov_info.body_span.lo());
268+
let file_name = span_file_name(tcx, function_coverage.function_coverage_info.body_span);
268269

269-
// Look up the global file ID for that file.
270-
let global_file_id = global_file_table.global_file_id_for_file(&source_file);
270+
// Look up the global file ID for that filename.
271+
let global_file_id = global_file_table.global_file_id_for_file_name(file_name);
271272

272273
// Associate that global file ID with a local file ID for this function.
273274
let local_file_id = virtual_file_mapping.local_id_for_global(global_file_id);
275+
debug!(" file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'");
274276

275-
let make_cov_span = |span| {
276-
spans::make_coverage_span(local_file_id, source_map, fn_cov_info, &source_file, span)
277-
};
278-
279-
// For each coverage mapping span in this function+file, convert it to a
277+
// For each counter/region pair in this function+file, convert it to a
280278
// form suitable for FFI.
281-
for (mapping_kind, span) in mapping_spans {
282-
debug!("Adding counter {mapping_kind:?} to map for {span:?}");
283-
let Some(cov_span) = make_cov_span(span) else { continue };
279+
for (mapping_kind, region) in counter_regions {
280+
debug!("Adding counter {mapping_kind:?} to map for {region:?}");
281+
let span = ffi::CoverageSpan::from_source_region(local_file_id, region);
284282
match mapping_kind {
285283
MappingKind::Code(term) => {
286-
code_regions
287-
.push(ffi::CodeRegion { cov_span, counter: ffi::Counter::from_term(term) });
284+
code_regions.push(ffi::CodeRegion { span, counter: ffi::Counter::from_term(term) });
288285
}
289286
MappingKind::Branch { true_term, false_term } => {
290287
branch_regions.push(ffi::BranchRegion {
291-
cov_span,
288+
span,
292289
true_counter: ffi::Counter::from_term(true_term),
293290
false_counter: ffi::Counter::from_term(false_term),
294291
});
295292
}
296293
MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => {
297294
mcdc_branch_regions.push(ffi::MCDCBranchRegion {
298-
cov_span,
295+
span,
299296
true_counter: ffi::Counter::from_term(true_term),
300297
false_counter: ffi::Counter::from_term(false_term),
301298
mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params),
302299
});
303300
}
304301
MappingKind::MCDCDecision(mcdc_decision_params) => {
305302
mcdc_decision_regions.push(ffi::MCDCDecisionRegion {
306-
cov_span,
303+
span,
307304
mcdc_decision_params: ffi::mcdc::DecisionParameters::from(mcdc_decision_params),
308305
});
309306
}

0 commit comments

Comments
 (0)