Skip to content

Commit e9a76fe

Browse files
committed
mir: Simplify the handling of debuginfos
1 parent 8717385 commit e9a76fe

File tree

4 files changed

+96
-51
lines changed

4 files changed

+96
-51
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 & 18 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
}
@@ -1420,36 +1420,27 @@ impl<'tcx> BasicBlockData<'tcx> {
14201420
{
14211421
// Place debuginfos into the next retained statement,
14221422
// this `debuginfos` variable is used to cache debuginfos between two retained statements.
1423-
let mut debuginfos = Vec::new();
1423+
let mut debuginfos = StmtDebugInfos::default();
14241424
self.statements.retain_mut(|stmt| {
14251425
let retain = f(stmt);
14261426
if retain {
1427-
if !debuginfos.is_empty() {
1428-
if !stmt.debuginfos.is_empty() {
1429-
debuginfos.append(&mut stmt.debuginfos);
1430-
}
1431-
mem::swap(&mut debuginfos, &mut stmt.debuginfos);
1432-
}
1427+
stmt.debuginfos.prepend(&mut debuginfos);
14331428
} else {
1434-
if !stmt.debuginfos.is_empty() {
1435-
debuginfos.append(&mut stmt.debuginfos);
1436-
}
1429+
debuginfos.append(&mut stmt.debuginfos);
14371430
}
14381431
retain
14391432
});
1440-
if !debuginfos.is_empty() {
1441-
self.after_last_stmt_debuginfos.append(&mut debuginfos);
1442-
}
1433+
self.after_last_stmt_debuginfos.prepend(&mut debuginfos);
14431434
}
14441435

14451436
pub fn strip_nops(&mut self) {
14461437
self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
14471438
}
14481439

14491440
pub fn drop_debuginfo(&mut self) {
1450-
self.after_last_stmt_debuginfos = Vec::new();
1441+
self.after_last_stmt_debuginfos.drop_debuginfo();
14511442
for stmt in self.statements.iter_mut() {
1452-
stmt.debuginfos = Vec::new();
1443+
stmt.debuginfos.drop_debuginfo();
14531444
}
14541445
}
14551446
}

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 66 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;
@@ -16,7 +18,7 @@ pub struct Statement<'tcx> {
1618
pub source_info: SourceInfo,
1719
pub kind: StatementKind<'tcx>,
1820
/// Some debuginfos appearing before the primary statement.
19-
pub debuginfos: Vec<StmtDebugInfo<'tcx>>,
21+
pub debuginfos: StmtDebugInfos<'tcx>,
2022
}
2123

2224
impl<'tcx> Statement<'tcx> {
@@ -36,7 +38,7 @@ impl<'tcx> Statement<'tcx> {
3638
}
3739

3840
pub fn new(source_info: SourceInfo, kind: StatementKind<'tcx>) -> Self {
39-
Statement { source_info, kind, debuginfos: Vec::new() }
41+
Statement { source_info, kind, debuginfos: StmtDebugInfos::default() }
4042
}
4143
}
4244

@@ -962,6 +964,68 @@ impl RawPtrKind {
962964
}
963965
}
964966

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