Skip to content

Commit ffa991c

Browse files
Auto merge of #146973 - Zalathar:args-memo, r=<try>
Compute quoted args for debuginfo at most once per session
2 parents 3e887f5 + 1fc6b19 commit ffa991c

File tree

13 files changed

+128
-60
lines changed

13 files changed

+128
-60
lines changed

compiler/rustc_codegen_llvm/src/back/command_line_args.rs

Lines changed: 0 additions & 37 deletions
This file was deleted.

compiler/rustc_codegen_llvm/src/back/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
pub(crate) mod archive;
2-
mod command_line_args;
32
pub(crate) mod lto;
43
pub(crate) mod owned_target_machine;
54
mod profiling;

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
2222
use rustc_data_structures::small_c_str::SmallCStr;
2323
use rustc_errors::{DiagCtxtHandle, Level};
2424
use rustc_fs_util::{link_or_copy, path_to_c_string};
25+
use rustc_middle::middle::debuginfo::CommandLineArgsForDebuginfo;
2526
use rustc_middle::ty::TyCtxt;
2627
use rustc_session::Session;
2728
use rustc_session::config::{
@@ -31,7 +32,6 @@ use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym};
3132
use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
3233
use tracing::{debug, trace};
3334

34-
use crate::back::command_line_args::quote_command_line_args;
3535
use crate::back::lto::ThinBuffer;
3636
use crate::back::owned_target_machine::OwnedTargetMachine;
3737
use crate::back::profiling::{
@@ -108,7 +108,11 @@ pub(crate) fn create_informational_target_machine(
108108
sess: &Session,
109109
only_base_features: bool,
110110
) -> OwnedTargetMachine {
111-
let config = TargetMachineFactoryConfig { split_dwarf_file: None, output_obj_file: None };
111+
let config = TargetMachineFactoryConfig {
112+
split_dwarf_file: None,
113+
output_obj_file: None,
114+
args_for_debuginfo: None,
115+
};
112116
// Can't use query system here quite yet because this function is invoked before the query
113117
// system/tcx is set up.
114118
let features = llvm_util::global_llvm_features(sess, false, only_base_features);
@@ -133,7 +137,12 @@ pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTar
133137
mod_name,
134138
tcx.sess.invocation_temp.as_deref(),
135139
));
136-
let config = TargetMachineFactoryConfig { split_dwarf_file, output_obj_file };
140+
141+
let config = TargetMachineFactoryConfig {
142+
split_dwarf_file,
143+
output_obj_file,
144+
args_for_debuginfo: Some(Arc::clone(tcx.args_for_debuginfo())),
145+
};
137146

138147
target_machine_factory(
139148
tcx.sess,
@@ -253,19 +262,6 @@ pub(crate) fn target_machine_factory(
253262

254263
let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated);
255264

256-
// Command-line information to be included in the target machine.
257-
// This seems to only be used for embedding in PDB debuginfo files.
258-
// FIXME(Zalathar): Maybe skip this for non-PDB targets?
259-
let argv0 = std::env::current_exe()
260-
.unwrap_or_default()
261-
.into_os_string()
262-
.into_string()
263-
.unwrap_or_default();
264-
let command_line_args = quote_command_line_args(&sess.expanded_args);
265-
// Self-profile counter for the number of bytes produced by command-line quoting.
266-
// Values are summed, so the summary result is cumulative across all TM factories.
267-
sess.prof.artifact_size("quoted_command_line_args", "-", command_line_args.len() as u64);
268-
269265
let debuginfo_compression = sess.opts.debuginfo_compression.to_string();
270266
match sess.opts.debuginfo_compression {
271267
rustc_session::config::DebugInfoCompression::Zlib => {
@@ -304,6 +300,14 @@ pub(crate) fn target_machine_factory(
304300
let split_dwarf_file = path_to_cstring_helper(config.split_dwarf_file);
305301
let output_obj_file = path_to_cstring_helper(config.output_obj_file);
306302

303+
let (argv0, quoted_args) = config
304+
.args_for_debuginfo
305+
.as_deref()
306+
.map(|CommandLineArgsForDebuginfo { argv0, quoted_args }| {
307+
(argv0.as_str(), quoted_args.as_str())
308+
})
309+
.unwrap_or_default();
310+
307311
OwnedTargetMachine::new(
308312
&triple,
309313
&cpu,
@@ -326,8 +330,8 @@ pub(crate) fn target_machine_factory(
326330
&output_obj_file,
327331
&debuginfo_compression,
328332
use_emulated_tls,
329-
&argv0,
330-
&command_line_args,
333+
argv0,
334+
quoted_args,
331335
use_wasm_eh,
332336
)
333337
})

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_incremental::{
2525
use rustc_metadata::fs::copy_to_stdout;
2626
use rustc_middle::bug;
2727
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
28+
use rustc_middle::middle::debuginfo::CommandLineArgsForDebuginfo;
2829
use rustc_middle::ty::TyCtxt;
2930
use rustc_session::Session;
3031
use rustc_session::config::{
@@ -283,6 +284,10 @@ pub struct TargetMachineFactoryConfig {
283284
/// The name of the output object file. Used for setting OutputFilenames in target options
284285
/// so that LLVM can emit the CodeView S_OBJNAME record in pdb files
285286
pub output_obj_file: Option<PathBuf>,
287+
288+
/// Contains a copy of [`TyCtxt::args_for_debuginfo`] for codegen,
289+
/// or `None` if the target machine is informational only.
290+
pub args_for_debuginfo: Option<Arc<CommandLineArgsForDebuginfo>>,
286291
}
287292

288293
impl TargetMachineFactoryConfig {
@@ -306,7 +311,12 @@ impl TargetMachineFactoryConfig {
306311
module_name,
307312
cgcx.invocation_temp.as_deref(),
308313
));
309-
TargetMachineFactoryConfig { split_dwarf_file, output_obj_file }
314+
315+
TargetMachineFactoryConfig {
316+
split_dwarf_file,
317+
output_obj_file,
318+
args_for_debuginfo: Some(Arc::clone(&cgcx.args_for_debuginfo)),
319+
}
310320
}
311321
}
312322

@@ -350,7 +360,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
350360
/// This will only be used within debug info, e.g. in the pdb file on windows
351361
/// This is mainly useful for other tools that reads that debuginfo to figure out
352362
/// how to call the compiler with the same arguments.
353-
pub expanded_args: Vec<String>,
363+
pub args_for_debuginfo: Arc<CommandLineArgsForDebuginfo>,
354364

355365
/// Emitter to use for diagnostics produced during codegen.
356366
pub diag_emitter: SharedEmitter,
@@ -1153,7 +1163,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
11531163
remark: sess.opts.cg.remark.clone(),
11541164
remark_dir,
11551165
incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()),
1156-
expanded_args: tcx.sess.expanded_args.clone(),
1166+
args_for_debuginfo: Arc::clone(tcx.args_for_debuginfo()),
11571167
diag_emitter: shared_emitter.clone(),
11581168
output_filenames: Arc::clone(tcx.output_filenames(())),
11591169
module_config: regular_config,
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use std::sync::Arc;
2+
3+
use rustc_middle::middle::debuginfo::CommandLineArgsForDebuginfo;
4+
use rustc_middle::ty::TyCtxt;
5+
use rustc_middle::util::Providers;
6+
7+
#[cfg(test)]
8+
mod tests;
9+
10+
pub(crate) fn provide(providers: &mut Providers) {
11+
providers.hooks.args_for_debuginfo = args_for_debuginfo;
12+
}
13+
14+
/// Hook implementation for [`TyCtxt::args_for_debuginfo`].
15+
fn args_for_debuginfo<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx Arc<CommandLineArgsForDebuginfo> {
16+
tcx.args_for_debuginfo_cache.get_or_init(|| {
17+
// Command-line information to be included in the target machine.
18+
// This seems to only be used for embedding in PDB debuginfo files.
19+
// FIXME(Zalathar): Maybe skip this for non-PDB targets?
20+
let argv0 = std::env::current_exe()
21+
.unwrap_or_default()
22+
.into_os_string()
23+
.into_string()
24+
.unwrap_or_default();
25+
let quoted_args = quote_command_line_args(&tcx.sess.expanded_args);
26+
27+
// Self-profile counter for the number of bytes produced by command-line quoting.
28+
tcx.prof.artifact_size("quoted_command_line_args", "-", quoted_args.len() as u64);
29+
30+
Arc::new(CommandLineArgsForDebuginfo { argv0, quoted_args })
31+
})
32+
}
33+
34+
/// Joins command-line arguments into a single space-separated string, quoting
35+
/// and escaping individual arguments as necessary.
36+
///
37+
/// The result is intended to be informational, for embedding in debug metadata,
38+
/// and might not be properly quoted/escaped for actual command-line use.
39+
fn quote_command_line_args(args: &[String]) -> String {
40+
// Start with a decent-sized buffer, since rustc invocations tend to be long.
41+
let mut buf = String::with_capacity(128);
42+
43+
for arg in args {
44+
if !buf.is_empty() {
45+
buf.push(' ');
46+
}
47+
48+
print_arg_quoted(&mut buf, arg);
49+
}
50+
51+
buf
52+
}
53+
54+
/// Equivalent to LLVM's `sys::printArg` with quoting always enabled
55+
/// (see llvm/lib/Support/Program.cpp).
56+
fn print_arg_quoted(buf: &mut String, arg: &str) {
57+
buf.reserve(arg.len() + 2);
58+
59+
buf.push('"');
60+
for ch in arg.chars() {
61+
if matches!(ch, '"' | '\\' | '$') {
62+
buf.push('\\');
63+
}
64+
buf.push(ch);
65+
}
66+
buf.push('"');
67+
}
File renamed without changes.

compiler/rustc_codegen_ssa/src/debuginfo/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_middle::bug;
33
use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
44
use rustc_middle::ty::{self, Ty, TyCtxt};
55

6-
// FIXME(eddyb) find a place for this (or a way to replace it).
6+
pub(crate) mod command_line_args;
77
pub mod type_names;
88

99
/// Returns true if we want to generate a DW_TAG_enumeration_type description for

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Type Names for Debug Info.
22
3+
// FIXME(eddyb) find a place for this (or a way to replace it).
4+
35
// Notes on targeting MSVC:
46
// In general, MSVC's debugger attempts to parse all arguments as C++ expressions,
57
// even if the argument is explicitly a symbol name.

compiler/rustc_codegen_ssa/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ pub enum CodegenErrors {
271271
pub fn provide(providers: &mut Providers) {
272272
crate::back::symbol_export::provide(providers);
273273
crate::base::provide(providers);
274+
crate::debuginfo::command_line_args::provide(providers);
274275
crate::target_features::provide(providers);
275276
crate::codegen_attrs::provide(providers);
276277
providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![];

compiler/rustc_middle/src/hooks/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
//! similar to queries, but queries come with a lot of machinery for caching and incremental
44
//! compilation, whereas hooks are just plain function pointers without any of the query magic.
55
6+
use std::sync::Arc;
7+
68
use rustc_hir::def_id::{DefId, DefPathHash};
79
use rustc_session::StableCrateId;
810
use rustc_span::def_id::{CrateNum, LocalDefId};
911
use rustc_span::{ExpnHash, ExpnId};
1012

13+
use crate::middle::debuginfo::CommandLineArgsForDebuginfo;
1114
use crate::mir;
1215
use crate::ty::{Ty, TyCtxt};
1316

@@ -102,6 +105,13 @@ declare_hooks! {
102105
/// Ensure the given scalar is valid for the given type.
103106
/// This checks non-recursive runtime validity.
104107
hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool;
108+
109+
/// Builds a quoted form of _all_ command-line args, for inclusion in some
110+
/// forms of debuginfo (specifically PDB).
111+
///
112+
/// This needs to _not_ be a query, because it would ruin incremental
113+
/// compilation for CGUs that would otherwise be considered up-to-date.
114+
hook args_for_debuginfo() -> &'tcx Arc<CommandLineArgsForDebuginfo>;
105115
}
106116

107117
#[cold]

0 commit comments

Comments
 (0)