Skip to content

Commit 9260be3

Browse files
committed
Auto merge of rust-lang#132184 - jieyouxu:rollup-81ht12w, r=jieyouxu
Rollup of 5 pull requests Successful merges: - rust-lang#132124 (coverage: Consolidate creation of covmap/covfun records) - rust-lang#132140 (Enable LSX feature for LoongArch Linux targets) - rust-lang#132169 (Deny calls to non-`#[const_trait]` methods in MIR constck) - rust-lang#132174 (x86 target features: make pclmulqdq imply sse2) - rust-lang#132180 (Print unsafety of attribute in AST pretty print) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 17f8215 + 50e78b8 commit 9260be3

File tree

84 files changed

+576
-471
lines changed

Some content is hidden

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

84 files changed

+576
-471
lines changed

compiler/rustc_ast_pretty/src/pprust/state.rs

+11
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,13 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
627627

628628
fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
629629
self.ibox(0);
630+
match item.unsafety {
631+
ast::Safety::Unsafe(_) => {
632+
self.word("unsafe");
633+
self.popen();
634+
}
635+
ast::Safety::Default | ast::Safety::Safe(_) => {}
636+
}
630637
match &item.args {
631638
AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common(
632639
Some(MacHeader::Path(&item.path)),
@@ -655,6 +662,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
655662
self.word(token_str);
656663
}
657664
}
665+
match item.unsafety {
666+
ast::Safety::Unsafe(_) => self.pclose(),
667+
ast::Safety::Default | ast::Safety::Safe(_) => {}
668+
}
658669
self.end();
659670
}
660671

compiler/rustc_codegen_llvm/src/context.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub(crate) struct CodegenCx<'ll, 'tcx> {
8080

8181
pub isize_ty: &'ll Type,
8282

83+
/// Extra codegen state needed when coverage instrumentation is enabled.
8384
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
8485
pub dbg_cx: Option<debuginfo::CodegenUnitDebugContext<'ll, 'tcx>>,
8586

@@ -592,11 +593,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
592593
&self.statics_to_rauw
593594
}
594595

596+
/// Extra state that is only available when coverage instrumentation is enabled.
595597
#[inline]
596-
pub(crate) fn coverage_context(
597-
&self,
598-
) -> Option<&coverageinfo::CrateCoverageContext<'ll, 'tcx>> {
599-
self.coverage_cx.as_ref()
598+
pub(crate) fn coverage_cx(&self) -> &coverageinfo::CrateCoverageContext<'ll, 'tcx> {
599+
self.coverage_cx.as_ref().expect("only called when coverage instrumentation is enabled")
600600
}
601601

602602
pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+65-35
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
use std::ffi::CStr;
1+
use std::ffi::CString;
22

33
use itertools::Itertools as _;
4-
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
4+
use rustc_abi::Align;
5+
use rustc_codegen_ssa::traits::{
6+
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
7+
};
58
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
69
use rustc_hir::def_id::{DefId, LocalDefId};
710
use rustc_index::IndexVec;
@@ -10,6 +13,7 @@ use rustc_middle::ty::{self, TyCtxt};
1013
use rustc_middle::{bug, mir};
1114
use rustc_span::Symbol;
1215
use rustc_span::def_id::DefIdSet;
16+
use rustc_target::spec::HasTargetSpec;
1317
use tracing::debug;
1418

1519
use crate::common::CodegenCx;
@@ -50,11 +54,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
5054
add_unused_functions(cx);
5155
}
5256

53-
let function_coverage_map = match cx.coverage_context() {
54-
Some(ctx) => ctx.take_function_coverage_map(),
55-
None => return,
56-
};
57-
57+
let function_coverage_map = cx.coverage_cx().take_function_coverage_map();
5858
if function_coverage_map.is_empty() {
5959
// This module has no functions with coverage instrumentation
6060
return;
@@ -78,11 +78,9 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
7878

7979
// Generate the coverage map header, which contains the filenames used by
8080
// this CGU's coverage mappings, and store it in a well-known global.
81-
let cov_data_val = generate_coverage_map(cx, covmap_version, filenames_size, filenames_val);
82-
coverageinfo::save_cov_data_to_mod(cx, cov_data_val);
81+
generate_covmap_record(cx, covmap_version, filenames_size, filenames_val);
8382

8483
let mut unused_function_names = Vec::new();
85-
let covfun_section_name = coverageinfo::covfun_section_name(cx);
8684

8785
// Encode coverage mappings and generate function records
8886
for (instance, function_coverage) in function_coverage_entries {
@@ -111,9 +109,8 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
111109
unused_function_names.push(mangled_function_name);
112110
}
113111

114-
save_function_record(
112+
generate_covfun_record(
115113
cx,
116-
&covfun_section_name,
117114
mangled_function_name,
118115
source_hash,
119116
filenames_ref,
@@ -308,15 +305,15 @@ fn encode_mappings_for_function(
308305
})
309306
}
310307

311-
/// Construct coverage map header and the array of function records, and combine them into the
312-
/// coverage map. Save the coverage map data into the LLVM IR as a static global using a
313-
/// specific, well-known section and name.
314-
fn generate_coverage_map<'ll>(
308+
/// Generates the contents of the covmap record for this CGU, which mostly
309+
/// consists of a header and a list of filenames. The record is then stored
310+
/// as a global variable in the `__llvm_covmap` section.
311+
fn generate_covmap_record<'ll>(
315312
cx: &CodegenCx<'ll, '_>,
316313
version: u32,
317314
filenames_size: usize,
318315
filenames_val: &'ll llvm::Value,
319-
) -> &'ll llvm::Value {
316+
) {
320317
debug!("cov map: filenames_size = {}, 0-based version = {}", filenames_size, version);
321318

322319
// Create the coverage data header (Note, fields 0 and 2 are now always zero,
@@ -331,15 +328,37 @@ fn generate_coverage_map<'ll>(
331328
);
332329

333330
// Create the complete LLVM coverage data value to add to the LLVM IR
334-
cx.const_struct(&[cov_data_header_val, filenames_val], /*packed=*/ false)
331+
let covmap_data =
332+
cx.const_struct(&[cov_data_header_val, filenames_val], /*packed=*/ false);
333+
334+
let covmap_var_name = CString::new(llvm::build_byte_buffer(|s| unsafe {
335+
llvm::LLVMRustCoverageWriteMappingVarNameToString(s);
336+
}))
337+
.unwrap();
338+
debug!("covmap var name: {:?}", covmap_var_name);
339+
340+
let covmap_section_name = CString::new(llvm::build_byte_buffer(|s| unsafe {
341+
llvm::LLVMRustCoverageWriteMapSectionNameToString(cx.llmod, s);
342+
}))
343+
.expect("covmap section name should not contain NUL");
344+
debug!("covmap section name: {:?}", covmap_section_name);
345+
346+
let llglobal = llvm::add_global(cx.llmod, cx.val_ty(covmap_data), &covmap_var_name);
347+
llvm::set_initializer(llglobal, covmap_data);
348+
llvm::set_global_constant(llglobal, true);
349+
llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
350+
llvm::set_section(llglobal, &covmap_section_name);
351+
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
352+
// <https://llvm.org/docs/CoverageMappingFormat.html>
353+
llvm::set_alignment(llglobal, Align::EIGHT);
354+
cx.add_used_global(llglobal);
335355
}
336356

337-
/// Construct a function record and combine it with the function's coverage mapping data.
338-
/// Save the function record into the LLVM IR as a static global using a
339-
/// specific, well-known section and name.
340-
fn save_function_record(
357+
/// Generates the contents of the covfun record for this function, which
358+
/// contains the function's coverage mapping data. The record is then stored
359+
/// as a global variable in the `__llvm_covfun` section.
360+
fn generate_covfun_record(
341361
cx: &CodegenCx<'_, '_>,
342-
covfun_section_name: &CStr,
343362
mangled_function_name: &str,
344363
source_hash: u64,
345364
filenames_ref: u64,
@@ -366,13 +385,28 @@ fn save_function_record(
366385
/*packed=*/ true,
367386
);
368387

369-
coverageinfo::save_func_record_to_mod(
370-
cx,
371-
covfun_section_name,
372-
func_name_hash,
373-
func_record_val,
374-
is_used,
375-
);
388+
// Choose a variable name to hold this function's covfun data.
389+
// Functions that are used have a suffix ("u") to distinguish them from
390+
// unused copies of the same function (from different CGUs), so that if a
391+
// linker sees both it won't discard the used copy's data.
392+
let func_record_var_name =
393+
CString::new(format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" }))
394+
.unwrap();
395+
debug!("function record var name: {:?}", func_record_var_name);
396+
397+
let llglobal = llvm::add_global(cx.llmod, cx.val_ty(func_record_val), &func_record_var_name);
398+
llvm::set_initializer(llglobal, func_record_val);
399+
llvm::set_global_constant(llglobal, true);
400+
llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
401+
llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
402+
llvm::set_section(llglobal, cx.covfun_section_name());
403+
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
404+
// <https://llvm.org/docs/CoverageMappingFormat.html>
405+
llvm::set_alignment(llglobal, Align::EIGHT);
406+
if cx.target_spec().supports_comdat() {
407+
llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
408+
}
409+
cx.add_used_global(llglobal);
376410
}
377411

378412
/// Each CGU will normally only emit coverage metadata for the functions that it actually generates.
@@ -504,9 +538,5 @@ fn add_unused_function_coverage<'tcx>(
504538
// zero, because none of its counters/expressions are marked as seen.
505539
let function_coverage = FunctionCoverageCollector::unused(instance, function_coverage_info);
506540

507-
if let Some(coverage_context) = cx.coverage_context() {
508-
coverage_context.function_coverage_map.borrow_mut().insert(instance, function_coverage);
509-
} else {
510-
bug!("Could not get the `coverage_context`");
511-
}
541+
cx.coverage_cx().function_coverage_map.borrow_mut().insert(instance, function_coverage);
512542
}

0 commit comments

Comments
 (0)