Skip to content

Commit a7fc76a

Browse files
committed
We don't need NonNull::as_ptr debuginfo
Stop pessimizing the use of local variables in core by skipping debug info for MIR temporaries in tiny (single-BB) functions. For functions as simple as this -- `Pin::new`, etc -- nobody every actually wants debuginfo for them in the first place. They're more like intrinsics than real functions, and stepping over them is good.
1 parent 96e51d9 commit a7fc76a

11 files changed

+170
-106
lines changed

Diff for: compiler/rustc_mir_transform/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ declare_passes! {
189189
mod simplify_comparison_integral : SimplifyComparisonIntegral;
190190
mod single_use_consts : SingleUseConsts;
191191
mod sroa : ScalarReplacementOfAggregates;
192+
mod strip_debuginfo : StripDebugInfo;
192193
mod unreachable_enum_branching : UnreachableEnumBranching;
193194
mod unreachable_prop : UnreachablePropagation;
194195
mod validate : Validator;
@@ -699,6 +700,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
699700
&o1(simplify_branches::SimplifyConstCondition::Final),
700701
&o1(remove_noop_landing_pads::RemoveNoopLandingPads),
701702
&o1(simplify::SimplifyCfg::Final),
703+
// After the last SimplifyCfg, because this wants one-block functions.
704+
&strip_debuginfo::StripDebugInfo,
702705
&copy_prop::CopyProp,
703706
&dead_store_elimination::DeadStoreElimination::Final,
704707
&nrvo::RenameReturnPlace,

Diff for: compiler/rustc_mir_transform/src/strip_debuginfo.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use rustc_middle::mir::*;
2+
use rustc_middle::ty::TyCtxt;
3+
use rustc_session::config::MirStripDebugInfo;
4+
5+
/// Conditionally remove some of the VarDebugInfo in MIR.
6+
///
7+
/// In particular, stripping non-parameter debug info for tiny, primitive-like
8+
/// methods in core saves work later, and nobody ever wanted to use it anyway.
9+
pub(super) struct StripDebugInfo;
10+
11+
impl<'tcx> crate::MirPass<'tcx> for StripDebugInfo {
12+
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
13+
sess.opts.unstable_opts.mir_strip_debuginfo != MirStripDebugInfo::None
14+
}
15+
16+
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
17+
match tcx.sess.opts.unstable_opts.mir_strip_debuginfo {
18+
MirStripDebugInfo::None => return,
19+
MirStripDebugInfo::AllLocals => {}
20+
MirStripDebugInfo::LocalsInTinyFunctions
21+
if let TerminatorKind::Return { .. } =
22+
body.basic_blocks[START_BLOCK].terminator().kind => {}
23+
MirStripDebugInfo::LocalsInTinyFunctions => return,
24+
}
25+
26+
body.var_debug_info.retain(|vdi| {
27+
matches!(
28+
vdi.value,
29+
VarDebugInfoContents::Place(place)
30+
if place.local.as_usize() <= body.arg_count && place.local != RETURN_PLACE,
31+
)
32+
});
33+
}
34+
}

Diff for: compiler/rustc_session/src/config.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,13 @@ impl ToString for DebugInfoCompression {
472472
}
473473
}
474474

475+
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
476+
pub enum MirStripDebugInfo {
477+
None,
478+
LocalsInTinyFunctions,
479+
AllLocals,
480+
}
481+
475482
/// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
476483
/// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
477484
/// uses DWARF for debug-information.
@@ -2900,10 +2907,10 @@ pub(crate) mod dep_tracking {
29002907
BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
29012908
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
29022909
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
2903-
LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
2904-
PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks,
2905-
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
2906-
WasiExecModel,
2910+
LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName,
2911+
OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents,
2912+
ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
2913+
SymbolManglingVersion, WasiExecModel,
29072914
};
29082915
use crate::lint;
29092916
use crate::utils::NativeLib;
@@ -2971,6 +2978,7 @@ pub(crate) mod dep_tracking {
29712978
LtoCli,
29722979
DebugInfo,
29732980
DebugInfoCompression,
2981+
MirStripDebugInfo,
29742982
CollapseMacroDebuginfo,
29752983
UnstableFeatures,
29762984
NativeLib,

Diff for: compiler/rustc_session/src/options.rs

+14
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ mod desc {
391391
pub(crate) const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
392392
pub(crate) const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
393393
pub(crate) const parse_debuginfo_compression: &str = "one of `none`, `zlib`, or `zstd`";
394+
pub(crate) const parse_mir_strip_debuginfo: &str =
395+
"one of `none`, `locals-in-tiny-functions`, or `all-locals`";
394396
pub(crate) const parse_collapse_macro_debuginfo: &str = "one of `no`, `external`, or `yes`";
395397
pub(crate) const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
396398
pub(crate) const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
@@ -925,6 +927,16 @@ pub mod parse {
925927
true
926928
}
927929

930+
pub(crate) fn parse_mir_strip_debuginfo(slot: &mut MirStripDebugInfo, v: Option<&str>) -> bool {
931+
match v {
932+
Some("none") => *slot = MirStripDebugInfo::None,
933+
Some("locals-in-tiny-functions") => *slot = MirStripDebugInfo::LocalsInTinyFunctions,
934+
Some("all-locals") => *slot = MirStripDebugInfo::AllLocals,
935+
_ => return false,
936+
};
937+
true
938+
}
939+
928940
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
929941
match v.and_then(LinkerFlavorCli::from_str) {
930942
Some(lf) => *slot = Some(lf),
@@ -1893,6 +1905,8 @@ options! {
18931905
#[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")]
18941906
mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
18951907
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
1908+
mir_strip_debuginfo: MirStripDebugInfo = (MirStripDebugInfo::None, parse_mir_strip_debuginfo, [TRACKED],
1909+
"Whether to remove some of the MIR debug info from methods. Default: None"),
18961910
move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],
18971911
"the size at which the `large_assignments` lint starts to be emitted"),
18981912
mutable_noalias: bool = (true, parse_bool, [TRACKED],

Diff for: src/bootstrap/src/core/builder/cargo.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,11 @@ impl Builder<'_> {
12081208
// even if we're not going to output debuginfo for the crate we're currently building,
12091209
// so that it'll be available when downstream consumers of std try to use it.
12101210
rustflags.arg("-Zinline-mir-preserve-debug");
1211+
1212+
// FIXME: always pass this after the next `#[cfg(bootstrap)]` update.
1213+
if compiler.stage != 0 {
1214+
rustflags.arg("-Zmir_strip_debuginfo=locals-in-tiny-functions");
1215+
}
12111216
}
12121217

12131218
Cargo {

Diff for: tests/codegen/mem-replace-big-type.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
2525
// CHECK-NOT: call void @llvm.memcpy
2626

2727
// For a large type, we expect exactly three `memcpy`s
28-
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret([56 x i8])
28+
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}(ptr
29+
// CHECK-SAME: sret([56 x i8]){{.+}}[[RESULT:%.+]], ptr{{.+}}%dest, ptr{{.+}}%src)
2930
// CHECK-NOT: call void @llvm.memcpy
30-
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %result, ptr align 8 %dest, i{{.*}} 56, i1 false)
31+
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 [[RESULT]], ptr align 8 %dest, i{{.*}} 56, i1 false)
3132
// CHECK-NOT: call void @llvm.memcpy
3233
// CHECK: call void @llvm.memcpy.{{.+}}(ptr align 8 %dest, ptr align 8 %src, i{{.*}} 56, i1 false)
3334
// CHECK-NOT: call void @llvm.memcpy

Diff for: tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) {
1717
+ debug pointer => _3;
1818
+ scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new_unchecked) {
19-
+ debug pointer => _3;
2019
+ }
2120
+ }
2221
+ scope 5 (inlined g::{closure#0}) {

Diff for: tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) {
1717
+ debug pointer => _3;
1818
+ scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new_unchecked) {
19-
+ debug pointer => _3;
2019
+ }
2120
+ }
2221
+ scope 5 (inlined g::{closure#0}) {

Diff for: tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir

+30-49
Original file line numberDiff line numberDiff line change
@@ -7,48 +7,36 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
77
debug self => _1;
88
scope 2 (inlined Vec::<u8>::as_slice) {
99
debug self => _1;
10-
let mut _9: *const u8;
11-
let mut _10: usize;
10+
let mut _7: *const u8;
11+
let mut _8: usize;
1212
scope 3 (inlined Vec::<u8>::as_ptr) {
1313
debug self => _1;
14-
let mut _2: &alloc::raw_vec::RawVec<u8>;
15-
let mut _8: *mut u8;
14+
let mut _6: *mut u8;
1615
scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
17-
debug self => _2;
18-
let mut _3: &alloc::raw_vec::RawVecInner;
1916
scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
20-
debug self => _3;
21-
let mut _7: std::ptr::NonNull<u8>;
17+
let mut _5: std::ptr::NonNull<u8>;
2218
scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
23-
debug self => _3;
24-
let mut _4: std::ptr::NonNull<u8>;
19+
let mut _2: std::ptr::NonNull<u8>;
2520
scope 7 (inlined Unique::<u8>::cast::<u8>) {
26-
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
27-
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
2821
scope 8 (inlined NonNull::<u8>::cast::<u8>) {
29-
debug self => _4;
30-
let mut _5: *mut u8;
31-
let mut _6: *const u8;
22+
let mut _3: *mut u8;
23+
let mut _4: *const u8;
3224
scope 9 (inlined NonNull::<u8>::as_ptr) {
33-
debug self => _4;
3425
}
3526
}
3627
}
3728
scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
38-
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
39-
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
4029
}
4130
}
4231
scope 11 (inlined NonNull::<u8>::as_ptr) {
43-
debug self => _7;
4432
}
4533
}
4634
}
4735
}
4836
scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
49-
debug data => _9;
50-
debug len => _10;
51-
let _11: *const [u8];
37+
debug data => _7;
38+
debug len => _8;
39+
let _9: *const [u8];
5240
scope 13 (inlined core::ub_checks::check_language_ub) {
5341
scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
5442
}
@@ -58,49 +46,42 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
5846
scope 16 (inlined align_of::<u8>) {
5947
}
6048
scope 17 (inlined slice_from_raw_parts::<u8>) {
61-
debug data => _9;
62-
debug len => _10;
49+
debug data => _7;
50+
debug len => _8;
6351
scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
64-
debug data_pointer => _9;
65-
debug metadata => _10;
52+
debug data_pointer => _7;
6653
}
6754
}
6855
}
6956
}
7057
}
7158

7259
bb0: {
73-
StorageLive(_8);
74-
StorageLive(_9);
60+
StorageLive(_6);
61+
StorageLive(_7);
62+
StorageLive(_5);
7563
StorageLive(_2);
76-
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
64+
_2 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
7765
StorageLive(_3);
78-
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
79-
StorageLive(_7);
8066
StorageLive(_4);
81-
_4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
82-
StorageLive(_5);
83-
StorageLive(_6);
84-
_5 = copy _4 as *mut u8 (Transmute);
85-
_6 = copy _5 as *const u8 (PtrToPtr);
86-
_7 = NonNull::<u8> { pointer: move _6 };
87-
StorageDead(_6);
88-
StorageDead(_5);
67+
_3 = copy _2 as *mut u8 (Transmute);
68+
_4 = copy _3 as *const u8 (PtrToPtr);
69+
_5 = NonNull::<u8> { pointer: move _4 };
8970
StorageDead(_4);
90-
_8 = copy _7 as *mut u8 (Transmute);
91-
StorageDead(_7);
9271
StorageDead(_3);
93-
_9 = copy _8 as *const u8 (PtrToPtr);
9472
StorageDead(_2);
95-
StorageLive(_10);
96-
_10 = copy ((*_1).1: usize);
97-
StorageLive(_11);
98-
_11 = *const [u8] from (copy _9, copy _10);
99-
_0 = &(*_11);
100-
StorageDead(_11);
101-
StorageDead(_10);
73+
_6 = copy _5 as *mut u8 (Transmute);
74+
StorageDead(_5);
75+
_7 = copy _6 as *const u8 (PtrToPtr);
76+
StorageLive(_8);
77+
_8 = copy ((*_1).1: usize);
78+
StorageLive(_9);
79+
_9 = *const [u8] from (copy _7, copy _8);
80+
_0 = &(*_9);
10281
StorageDead(_9);
10382
StorageDead(_8);
83+
StorageDead(_7);
84+
StorageDead(_6);
10485
return;
10586
}
10687
}

0 commit comments

Comments
 (0)