Skip to content

Commit 94ddfe6

Browse files
committed
mir: Simplify the handling of debuginfos
1 parent 10fb5e3 commit 94ddfe6

File tree

4 files changed

+104
-56
lines changed

4 files changed

+104
-56
lines changed

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo};
1+
use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo, StmtDebugInfos};
22
use rustc_middle::{bug, span_bug};
33
use tracing::instrument;
44

@@ -165,9 +165,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
165165
pub(crate) fn codegen_stmt_debuginfos(
166166
&mut self,
167167
bx: &mut Bx,
168-
debuginfos: &[StmtDebugInfo<'tcx>],
168+
debuginfos: &StmtDebugInfos<'tcx>,
169169
) {
170-
for debuginfo in debuginfos {
170+
for debuginfo in debuginfos.iter() {
171171
self.codegen_stmt_debuginfo(bx, debuginfo);
172172
}
173173
}

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
55
use std::borrow::Cow;
66
use std::fmt::{self, Debug, Formatter};
7+
use std::iter;
78
use std::ops::{Index, IndexMut};
8-
use std::{iter, mem};
99

1010
pub use basic_blocks::{BasicBlocks, SwitchTargetValue};
1111
use either::Either;
@@ -1344,7 +1344,7 @@ pub struct BasicBlockData<'tcx> {
13441344

13451345
/// All debuginfos happen before the statement.
13461346
/// Put debuginfos here when the last statement is eliminated.
1347-
pub after_last_stmt_debuginfos: Vec<StmtDebugInfo<'tcx>>,
1347+
pub after_last_stmt_debuginfos: StmtDebugInfos<'tcx>,
13481348

13491349
/// Terminator for this block.
13501350
///
@@ -1375,7 +1375,7 @@ impl<'tcx> BasicBlockData<'tcx> {
13751375
) -> BasicBlockData<'tcx> {
13761376
BasicBlockData {
13771377
statements,
1378-
after_last_stmt_debuginfos: Vec::new(),
1378+
after_last_stmt_debuginfos: StmtDebugInfos::default(),
13791379
terminator,
13801380
is_cleanup,
13811381
}
@@ -1418,41 +1418,27 @@ impl<'tcx> BasicBlockData<'tcx> {
14181418
where
14191419
F: FnMut(&Statement<'tcx>) -> bool,
14201420
{
1421-
// Fast path without debugging information
1422-
if self.statements.iter().all(|stmt| stmt.debuginfos.is_empty()) {
1423-
self.statements.retain_mut(|stmt| f(stmt));
1424-
return;
1425-
}
1426-
let mut debuginfos = Vec::new();
1421+
let mut debuginfos = StmtDebugInfos::default();
14271422
self.statements.retain_mut(|stmt| {
14281423
let retain = f(stmt);
14291424
if retain {
1430-
if !debuginfos.is_empty() {
1431-
if !stmt.debuginfos.is_empty() {
1432-
debuginfos.append(&mut stmt.debuginfos);
1433-
}
1434-
mem::swap(&mut debuginfos, &mut stmt.debuginfos);
1435-
}
1425+
stmt.debuginfos.prepend(&mut debuginfos);
14361426
} else {
1437-
if !stmt.debuginfos.is_empty() {
1438-
debuginfos.append(&mut stmt.debuginfos);
1439-
}
1427+
debuginfos.append(&mut stmt.debuginfos);
14401428
}
14411429
retain
14421430
});
1443-
if !debuginfos.is_empty() {
1444-
self.after_last_stmt_debuginfos.append(&mut debuginfos);
1445-
}
1431+
self.after_last_stmt_debuginfos.prepend(&mut debuginfos);
14461432
}
14471433

14481434
pub fn strip_nops(&mut self) {
14491435
self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
14501436
}
14511437

14521438
pub fn drop_debuginfo(&mut self) {
1453-
self.after_last_stmt_debuginfos = Vec::new();
1439+
self.after_last_stmt_debuginfos.drop_debuginfo();
14541440
for stmt in self.statements.iter_mut() {
1455-
stmt.debuginfos = Vec::new();
1441+
stmt.debuginfos.drop_debuginfo();
14561442
}
14571443
}
14581444
}

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Functionality for statements, operands, places, and things that appear in them.
22
3+
use std::ops;
4+
35
use tracing::{debug, instrument};
46

57
use super::interpret::GlobalAlloc;
@@ -15,7 +17,7 @@ use crate::ty::CoroutineArgsExt;
1517
pub struct Statement<'tcx> {
1618
pub source_info: SourceInfo,
1719
pub kind: StatementKind<'tcx>,
18-
pub debuginfos: Vec<StmtDebugInfo<'tcx>>,
20+
pub debuginfos: StmtDebugInfos<'tcx>,
1921
}
2022

2123
impl<'tcx> Statement<'tcx> {
@@ -35,7 +37,7 @@ impl<'tcx> Statement<'tcx> {
3537
}
3638

3739
pub fn new(source_info: SourceInfo, kind: StatementKind<'tcx>) -> Self {
38-
Statement { source_info, kind, debuginfos: Vec::new() }
40+
Statement { source_info, kind, debuginfos: StmtDebugInfos::default() }
3941
}
4042
}
4143

@@ -961,6 +963,76 @@ impl RawPtrKind {
961963
}
962964
}
963965

966+
#[derive(Default, Debug, Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
967+
pub struct StmtDebugInfos<'tcx>(Vec<StmtDebugInfo<'tcx>>);
968+
969+
impl<'tcx> StmtDebugInfos<'tcx> {
970+
pub fn push(&mut self, debuginfo: StmtDebugInfo<'tcx>) {
971+
self.0.push(debuginfo);
972+
}
973+
974+
pub fn drop_debuginfo(&mut self) {
975+
self.0.clear();
976+
}
977+
978+
pub fn is_empty(&self) -> bool {
979+
self.0.is_empty()
980+
}
981+
982+
pub fn prepend(&mut self, debuginfos: &mut Self) {
983+
if debuginfos.is_empty() {
984+
return;
985+
};
986+
if self.is_empty() {
987+
std::mem::swap(self, debuginfos);
988+
return;
989+
};
990+
debuginfos.0.append(self);
991+
std::mem::swap(debuginfos, self);
992+
}
993+
994+
pub fn append(&mut self, debuginfos: &mut Self) {
995+
if debuginfos.is_empty() {
996+
return;
997+
};
998+
if self.is_empty() {
999+
std::mem::swap(self, debuginfos);
1000+
return;
1001+
};
1002+
self.0.append(debuginfos);
1003+
}
1004+
1005+
pub fn extend(&mut self, debuginfos: &Self) {
1006+
if debuginfos.is_empty() {
1007+
return;
1008+
};
1009+
self.0.extend_from_slice(debuginfos);
1010+
}
1011+
1012+
pub fn retain<F>(&mut self, f: F)
1013+
where
1014+
F: FnMut(&StmtDebugInfo<'tcx>) -> bool,
1015+
{
1016+
self.0.retain(f);
1017+
}
1018+
}
1019+
1020+
impl<'tcx> ops::Deref for StmtDebugInfos<'tcx> {
1021+
type Target = Vec<StmtDebugInfo<'tcx>>;
1022+
1023+
#[inline]
1024+
fn deref(&self) -> &Vec<StmtDebugInfo<'tcx>> {
1025+
&self.0
1026+
}
1027+
}
1028+
1029+
impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> {
1030+
#[inline]
1031+
fn deref_mut(&mut self) -> &mut Vec<StmtDebugInfo<'tcx>> {
1032+
&mut self.0
1033+
}
1034+
}
1035+
9641036
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
9651037
pub enum StmtDebugInfo<'tcx> {
9661038
AssignRef(Local, Option<Place<'tcx>>),

compiler/rustc_mir_transform/src/simplify.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -158,20 +158,16 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
158158
let mut terminator =
159159
self.basic_blocks[bb].terminator.take().expect("invalid terminator state");
160160

161-
let mut debuginfos = Vec::new();
162-
if let Some(mut unique_succ) = terminator.identical_successor() {
163-
self.collapse_goto_chain(&mut unique_succ, &mut changed, &mut debuginfos);
164-
terminator.successors_mut(|successor| {
165-
*successor = unique_succ;
166-
});
161+
let identical_succ = terminator.identical_successor();
162+
terminator.successors_mut(|successor| {
163+
self.collapse_goto_chain(successor, &mut changed);
164+
});
165+
if changed && let Some(identical_succ) = identical_succ {
167166
// Add debugging information from the goto chain only when all successors are identical,
168167
// otherwise, we may provide misleading debugging information within a branch.
169-
self.basic_blocks[bb].after_last_stmt_debuginfos.append(&mut debuginfos);
170-
} else {
171-
terminator.successors_mut(|successor| {
172-
debuginfos.clear();
173-
self.collapse_goto_chain(successor, &mut changed, &mut debuginfos)
174-
});
168+
let mut succ_debuginfos =
169+
self.basic_blocks[identical_succ].after_last_stmt_debuginfos.clone();
170+
self.basic_blocks[bb].after_last_stmt_debuginfos.append(&mut succ_debuginfos);
175171
}
176172

177173
let mut inner_changed = true;
@@ -193,12 +189,11 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
193189
std::mem::take(&mut self.basic_blocks[bb].after_last_stmt_debuginfos);
194190
for &from in &merged_blocks {
195191
if let Some(stmt) = self.basic_blocks[from].statements.first_mut() {
196-
parent_bb_last_debuginfos.append(&mut stmt.debuginfos);
197-
std::mem::swap(&mut parent_bb_last_debuginfos, &mut stmt.debuginfos);
192+
stmt.debuginfos.prepend(&mut parent_bb_last_debuginfos);
198193
}
199194
statements.append(&mut self.basic_blocks[from].statements);
200-
parent_bb_last_debuginfos
201-
.append(&mut self.basic_blocks[from].after_last_stmt_debuginfos);
195+
parent_bb_last_debuginfos =
196+
std::mem::take(&mut self.basic_blocks[from].after_last_stmt_debuginfos);
202197
}
203198
self.basic_blocks[bb].statements = statements;
204199
self.basic_blocks[bb].after_last_stmt_debuginfos = parent_bb_last_debuginfos;
@@ -236,12 +231,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
236231
}
237232

238233
/// Collapse a goto chain starting from `start`
239-
fn collapse_goto_chain(
240-
&mut self,
241-
start: &mut BasicBlock,
242-
changed: &mut bool,
243-
pred_debuginfos: &mut Vec<StmtDebugInfo<'tcx>>,
244-
) {
234+
fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) {
245235
// Using `SmallVec` here, because in some logs on libcore oli-obk saw many single-element
246236
// goto chains. We should probably benchmark different sizes.
247237
let mut terminators: SmallVec<[_; 1]> = Default::default();
@@ -254,20 +244,20 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
254244
current = target;
255245
}
256246
let last = current;
247+
*changed |= *start != last;
257248
*start = last;
249+
let mut succ = last;
258250
while let Some((current, mut terminator)) = terminators.pop() {
259251
let Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } = terminator
260252
else {
261253
unreachable!();
262254
};
263255
if *target != last {
264-
self.basic_blocks[current]
265-
.after_last_stmt_debuginfos
266-
.extend_from_slice(pred_debuginfos);
256+
let mut succ_debuginfos =
257+
self.basic_blocks[succ].after_last_stmt_debuginfos.clone();
258+
self.basic_blocks[current].after_last_stmt_debuginfos.extend(&mut succ_debuginfos);
267259
}
268-
pred_debuginfos
269-
.extend_from_slice(&self.basic_blocks[current].after_last_stmt_debuginfos);
270-
*changed |= *target != last;
260+
succ = current;
271261
*target = last;
272262
debug!("collapsing goto chain from {:?} to {:?}", current, target);
273263

0 commit comments

Comments
 (0)