Skip to content

Commit 78f97c9

Browse files
committed
Auto merge of rust-lang#113911 - matthiaskrgr:rollup-wk6cr7v, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#113380 (style-guide: clean up "must"/"should"/"may") - rust-lang#113723 (Resurrect: rustc_llvm: Add a -Z `print-codegen-stats` option to expose LLVM statistics.) - rust-lang#113780 (Support `--print KIND=PATH` command line syntax) - rust-lang#113810 (Make {Rc,Arc}::allocator associated functions) - rust-lang#113907 (Minor improvements to Windows TLS dtors) Failed merges: - rust-lang#113392 (style-guide: Some cleanups from the fmt-rfcs repo history) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1a44b45 + 8c6ef1d commit 78f97c9

File tree

38 files changed

+689
-448
lines changed

38 files changed

+689
-448
lines changed

compiler/rustc_codegen_gcc/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ impl WriteBackendMethods for GccCodegenBackend {
239239
unimplemented!();
240240
}
241241

242+
fn print_statistics(&self) {
243+
unimplemented!()
244+
}
245+
242246
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
243247
module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
244248
Ok(())

compiler/rustc_codegen_llvm/src/lib.rs

+42-19
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ use rustc_metadata::EncodedMetadata;
4040
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
4141
use rustc_middle::query::Providers;
4242
use rustc_middle::ty::TyCtxt;
43-
use rustc_session::config::{OptLevel, OutputFilenames, PrintRequest};
43+
use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest};
4444
use rustc_session::Session;
4545
use rustc_span::symbol::Symbol;
4646

4747
use std::any::Any;
4848
use std::ffi::CStr;
49+
use std::io::Write;
4950

5051
mod back {
5152
pub mod archive;
@@ -178,7 +179,28 @@ impl WriteBackendMethods for LlvmCodegenBackend {
178179
type ThinBuffer = back::lto::ThinBuffer;
179180
fn print_pass_timings(&self) {
180181
unsafe {
181-
llvm::LLVMRustPrintPassTimings();
182+
let mut size = 0;
183+
let cstr = llvm::LLVMRustPrintPassTimings(&mut size as *mut usize);
184+
if cstr.is_null() {
185+
println!("failed to get pass timings");
186+
} else {
187+
let timings = std::slice::from_raw_parts(cstr as *const u8, size);
188+
std::io::stdout().write_all(timings).unwrap();
189+
libc::free(cstr as *mut _);
190+
}
191+
}
192+
}
193+
fn print_statistics(&self) {
194+
unsafe {
195+
let mut size = 0;
196+
let cstr = llvm::LLVMRustPrintStatistics(&mut size as *mut usize);
197+
if cstr.is_null() {
198+
println!("failed to get pass stats");
199+
} else {
200+
let stats = std::slice::from_raw_parts(cstr as *const u8, size);
201+
std::io::stdout().write_all(stats).unwrap();
202+
libc::free(cstr as *mut _);
203+
}
182204
}
183205
}
184206
fn run_link(
@@ -262,10 +284,10 @@ impl CodegenBackend for LlvmCodegenBackend {
262284
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
263285
}
264286

265-
fn print(&self, req: PrintRequest, sess: &Session) {
266-
match req {
267-
PrintRequest::RelocationModels => {
268-
println!("Available relocation models:");
287+
fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) {
288+
match req.kind {
289+
PrintKind::RelocationModels => {
290+
writeln!(out, "Available relocation models:");
269291
for name in &[
270292
"static",
271293
"pic",
@@ -276,26 +298,27 @@ impl CodegenBackend for LlvmCodegenBackend {
276298
"ropi-rwpi",
277299
"default",
278300
] {
279-
println!(" {}", name);
301+
writeln!(out, " {}", name);
280302
}
281-
println!();
303+
writeln!(out);
282304
}
283-
PrintRequest::CodeModels => {
284-
println!("Available code models:");
305+
PrintKind::CodeModels => {
306+
writeln!(out, "Available code models:");
285307
for name in &["tiny", "small", "kernel", "medium", "large"] {
286-
println!(" {}", name);
308+
writeln!(out, " {}", name);
287309
}
288-
println!();
310+
writeln!(out);
289311
}
290-
PrintRequest::TlsModels => {
291-
println!("Available TLS models:");
312+
PrintKind::TlsModels => {
313+
writeln!(out, "Available TLS models:");
292314
for name in &["global-dynamic", "local-dynamic", "initial-exec", "local-exec"] {
293-
println!(" {}", name);
315+
writeln!(out, " {}", name);
294316
}
295-
println!();
317+
writeln!(out);
296318
}
297-
PrintRequest::StackProtectorStrategies => {
298-
println!(
319+
PrintKind::StackProtectorStrategies => {
320+
writeln!(
321+
out,
299322
r#"Available stack protector strategies:
300323
all
301324
Generate stack canaries in all functions.
@@ -319,7 +342,7 @@ impl CodegenBackend for LlvmCodegenBackend {
319342
"#
320343
);
321344
}
322-
req => llvm_util::print(req, sess),
345+
_other => llvm_util::print(req, out, sess),
323346
}
324347
}
325348

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1868,7 +1868,10 @@ extern "C" {
18681868
pub fn LLVMRustGetLastError() -> *const c_char;
18691869

18701870
/// Print the pass timings since static dtors aren't picking them up.
1871-
pub fn LLVMRustPrintPassTimings();
1871+
pub fn LLVMRustPrintPassTimings(size: *const size_t) -> *const c_char;
1872+
1873+
/// Print the statistics since static dtors aren't picking them up.
1874+
pub fn LLVMRustPrintStatistics(size: *const size_t) -> *const c_char;
18721875

18731876
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
18741877

@@ -2280,7 +2283,12 @@ extern "C" {
22802283

22812284
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
22822285

2283-
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine, cpu: *const c_char);
2286+
pub fn LLVMRustPrintTargetCPUs(
2287+
T: &TargetMachine,
2288+
cpu: *const c_char,
2289+
print: unsafe extern "C" fn(out: *mut c_void, string: *const c_char, len: usize),
2290+
out: *mut c_void,
2291+
);
22842292
pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
22852293
pub fn LLVMRustGetTargetFeature(
22862294
T: &TargetMachine,

compiler/rustc_codegen_llvm/src/llvm_util.rs

+34-17
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ use libc::c_int;
88
use rustc_codegen_ssa::target_features::{
99
supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
1010
};
11+
use rustc_codegen_ssa::traits::PrintBackendInfo;
1112
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1213
use rustc_data_structures::small_c_str::SmallCStr;
1314
use rustc_fs_util::path_to_c_string;
1415
use rustc_middle::bug;
15-
use rustc_session::config::PrintRequest;
16+
use rustc_session::config::{PrintKind, PrintRequest};
1617
use rustc_session::Session;
1718
use rustc_span::symbol::Symbol;
1819
use rustc_target::spec::{MergeFunctions, PanicStrategy};
19-
use std::ffi::{CStr, CString};
2020

21+
use std::ffi::{c_char, c_void, CStr, CString};
2122
use std::path::Path;
2223
use std::ptr;
2324
use std::slice;
@@ -110,6 +111,10 @@ unsafe fn configure_llvm(sess: &Session) {
110111
// Use non-zero `import-instr-limit` multiplier for cold callsites.
111112
add("-import-cold-multiplier=0.1", false);
112113

114+
if sess.print_llvm_stats() {
115+
add("-stats", false);
116+
}
117+
113118
for arg in sess_args {
114119
add(&(*arg), true);
115120
}
@@ -350,7 +355,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
350355
ret
351356
}
352357

353-
fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
358+
fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) {
354359
let mut llvm_target_features = llvm_target_features(tm);
355360
let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
356361
let mut rustc_target_features = supported_target_features(sess)
@@ -383,36 +388,48 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
383388
.max()
384389
.unwrap_or(0);
385390

386-
println!("Features supported by rustc for this target:");
391+
writeln!(out, "Features supported by rustc for this target:");
387392
for (feature, desc) in &rustc_target_features {
388-
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
393+
writeln!(out, " {1:0$} - {2}.", max_feature_len, feature, desc);
389394
}
390-
println!("\nCode-generation features supported by LLVM for this target:");
395+
writeln!(out, "\nCode-generation features supported by LLVM for this target:");
391396
for (feature, desc) in &llvm_target_features {
392-
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
397+
writeln!(out, " {1:0$} - {2}.", max_feature_len, feature, desc);
393398
}
394399
if llvm_target_features.is_empty() {
395-
println!(" Target features listing is not supported by this LLVM version.");
400+
writeln!(out, " Target features listing is not supported by this LLVM version.");
396401
}
397-
println!("\nUse +feature to enable a feature, or -feature to disable it.");
398-
println!("For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
399-
println!("Code-generation features cannot be used in cfg or #[target_feature],");
400-
println!("and may be renamed or removed in a future version of LLVM or rustc.\n");
402+
writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.");
403+
writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
404+
writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],");
405+
writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n");
401406
}
402407

403-
pub(crate) fn print(req: PrintRequest, sess: &Session) {
408+
pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) {
404409
require_inited();
405410
let tm = create_informational_target_machine(sess);
406-
match req {
407-
PrintRequest::TargetCPUs => {
411+
match req.kind {
412+
PrintKind::TargetCPUs => {
408413
// SAFETY generate a C compatible string from a byte slice to pass
409414
// the target CPU name into LLVM, the lifetime of the reference is
410415
// at least as long as the C function
411416
let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
412417
.unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
413-
unsafe { llvm::LLVMRustPrintTargetCPUs(tm, cpu_cstring.as_ptr()) };
418+
unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
419+
let out = &mut *(out as *mut &mut dyn PrintBackendInfo);
420+
let bytes = slice::from_raw_parts(string as *const u8, len);
421+
write!(out, "{}", String::from_utf8_lossy(bytes));
422+
}
423+
unsafe {
424+
llvm::LLVMRustPrintTargetCPUs(
425+
tm,
426+
cpu_cstring.as_ptr(),
427+
callback,
428+
&mut out as *mut &mut dyn PrintBackendInfo as *mut c_void,
429+
);
430+
}
414431
}
415-
PrintRequest::TargetFeatures => print_target_features(sess, tm),
432+
PrintKind::TargetFeatures => print_target_features(out, sess, tm),
416433
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
417434
}
418435
}

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libr
197197
198198
codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
199199
200+
codegen_ssa_static_library_native_artifacts_to_file = Native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms.
201+
200202
codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status}
201203
.note = {$output}
202204

compiler/rustc_codegen_ssa/src/back/link.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
1212
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
1313
use rustc_middle::middle::dependency_format::Linkage;
1414
use rustc_middle::middle::exported_symbols::SymbolExportKind;
15-
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, Strip};
16-
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
15+
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, OutFileName, Strip};
16+
use rustc_session::config::{OutputFilenames, OutputType, PrintKind, SplitDwarfKind};
1717
use rustc_session::cstore::DllImport;
1818
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
1919
use rustc_session::search_paths::PathKind;
@@ -596,8 +596,10 @@ fn link_staticlib<'a>(
596596

597597
all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries);
598598

599-
if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) {
600-
print_native_static_libs(sess, &all_native_libs, &all_rust_dylibs);
599+
for print in &sess.opts.prints {
600+
if print.kind == PrintKind::NativeStaticLibs {
601+
print_native_static_libs(sess, &print.out, &all_native_libs, &all_rust_dylibs);
602+
}
601603
}
602604

603605
Ok(())
@@ -744,8 +746,11 @@ fn link_natively<'a>(
744746
cmd.env_remove(k.as_ref());
745747
}
746748

747-
if sess.opts.prints.contains(&PrintRequest::LinkArgs) {
748-
println!("{:?}", &cmd);
749+
for print in &sess.opts.prints {
750+
if print.kind == PrintKind::LinkArgs {
751+
let content = format!("{:?}", cmd);
752+
print.out.overwrite(&content, sess);
753+
}
749754
}
750755

751756
// May have not found libraries in the right formats.
@@ -1386,6 +1391,7 @@ enum RlibFlavor {
13861391

13871392
fn print_native_static_libs(
13881393
sess: &Session,
1394+
out: &OutFileName,
13891395
all_native_libs: &[NativeLib],
13901396
all_rust_dylibs: &[&Path],
13911397
) {
@@ -1459,11 +1465,22 @@ fn print_native_static_libs(
14591465
lib_args.push(format!("-l{}", lib));
14601466
}
14611467
}
1462-
if !lib_args.is_empty() {
1463-
sess.emit_note(errors::StaticLibraryNativeArtifacts);
1464-
// Prefix for greppability
1465-
// Note: This must not be translated as tools are allowed to depend on this exact string.
1466-
sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
1468+
1469+
match out {
1470+
OutFileName::Real(path) => {
1471+
out.overwrite(&lib_args.join(" "), sess);
1472+
if !lib_args.is_empty() {
1473+
sess.emit_note(errors::StaticLibraryNativeArtifactsToFile { path });
1474+
}
1475+
}
1476+
OutFileName::Stdout => {
1477+
if !lib_args.is_empty() {
1478+
sess.emit_note(errors::StaticLibraryNativeArtifacts);
1479+
// Prefix for greppability
1480+
// Note: This must not be translated as tools are allowed to depend on this exact string.
1481+
sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
1482+
}
1483+
}
14671484
}
14681485
}
14691486

compiler/rustc_codegen_ssa/src/back/write.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1945,6 +1945,10 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
19451945
self.backend.print_pass_timings()
19461946
}
19471947

1948+
if sess.print_llvm_stats() {
1949+
self.backend.print_statistics()
1950+
}
1951+
19481952
(
19491953
CodegenResults {
19501954
metadata: self.metadata,

compiler/rustc_codegen_ssa/src/errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,12 @@ pub struct LinkerFileStem;
455455
#[diag(codegen_ssa_static_library_native_artifacts)]
456456
pub struct StaticLibraryNativeArtifacts;
457457

458+
#[derive(Diagnostic)]
459+
#[diag(codegen_ssa_static_library_native_artifacts_to_file)]
460+
pub struct StaticLibraryNativeArtifactsToFile<'a> {
461+
pub path: &'a Path,
462+
}
463+
458464
#[derive(Diagnostic)]
459465
#[diag(codegen_ssa_link_script_unavailable)]
460466
pub struct LinkScriptUnavailable;

compiler/rustc_codegen_ssa/src/traits/backend.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use rustc_span::symbol::Symbol;
2323
use rustc_target::abi::call::FnAbi;
2424
use rustc_target::spec::Target;
2525

26+
use std::fmt;
27+
2628
pub trait BackendTypes {
2729
type Value: CodegenObject;
2830
type Function: CodegenObject;
@@ -61,7 +63,7 @@ pub trait CodegenBackend {
6163
fn locale_resource(&self) -> &'static str;
6264

6365
fn init(&self, _sess: &Session) {}
64-
fn print(&self, _req: PrintRequest, _sess: &Session) {}
66+
fn print(&self, _req: &PrintRequest, _out: &mut dyn PrintBackendInfo, _sess: &Session) {}
6567
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
6668
vec![]
6769
}
@@ -162,3 +164,19 @@ pub trait ExtraBackendMethods:
162164
std::thread::Builder::new().name(name).spawn(f)
163165
}
164166
}
167+
168+
pub trait PrintBackendInfo {
169+
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>);
170+
}
171+
172+
impl PrintBackendInfo for String {
173+
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>) {
174+
fmt::Write::write_fmt(self, args).unwrap();
175+
}
176+
}
177+
178+
impl dyn PrintBackendInfo + '_ {
179+
pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) {
180+
self.infallible_write_fmt(args);
181+
}
182+
}

0 commit comments

Comments
 (0)