Skip to content

Commit 06f5a9d

Browse files
committed
mir-opt: Eliminate dead ref statements
1 parent 7f7b8ef commit 06f5a9d

File tree

60 files changed

+1730
-475
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1730
-475
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11461146
let opt_assignment_rhs_span =
11471147
self.find_assignments(local).first().map(|&location| {
11481148
if let Some(mir::Statement {
1149-
source_info: _,
11501149
kind:
11511150
mir::StatementKind::Assign(box (
11521151
_,

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,10 @@ pub struct BasicBlockData<'tcx> {
13421342
/// List of statements in this block.
13431343
pub statements: Vec<Statement<'tcx>>,
13441344

1345+
/// All debuginfos happen before the statement.
1346+
/// Put debuginfos here when the last statement is eliminated.
1347+
pub after_last_stmt_debuginfos: StmtDebugInfos<'tcx>,
1348+
13451349
/// Terminator for this block.
13461350
///
13471351
/// N.B., this should generally ONLY be `None` during construction.
@@ -1369,7 +1373,12 @@ impl<'tcx> BasicBlockData<'tcx> {
13691373
terminator: Option<Terminator<'tcx>>,
13701374
is_cleanup: bool,
13711375
) -> BasicBlockData<'tcx> {
1372-
BasicBlockData { statements, terminator, is_cleanup }
1376+
BasicBlockData {
1377+
statements,
1378+
after_last_stmt_debuginfos: StmtDebugInfos::default(),
1379+
terminator,
1380+
is_cleanup,
1381+
}
13731382
}
13741383

13751384
/// Accessor for terminator.
@@ -1404,6 +1413,36 @@ impl<'tcx> BasicBlockData<'tcx> {
14041413
self.terminator().successors()
14051414
}
14061415
}
1416+
1417+
pub fn retain_statements<F>(&mut self, mut f: F)
1418+
where
1419+
F: FnMut(&Statement<'tcx>) -> bool,
1420+
{
1421+
// Place debuginfos into the next retained statement,
1422+
// this `debuginfos` variable is used to cache debuginfos between two retained statements.
1423+
let mut debuginfos = StmtDebugInfos::default();
1424+
self.statements.retain_mut(|stmt| {
1425+
let retain = f(stmt);
1426+
if retain {
1427+
stmt.debuginfos.prepend(&mut debuginfos);
1428+
} else {
1429+
debuginfos.append(&mut stmt.debuginfos);
1430+
}
1431+
retain
1432+
});
1433+
self.after_last_stmt_debuginfos.prepend(&mut debuginfos);
1434+
}
1435+
1436+
pub fn strip_nops(&mut self) {
1437+
self.retain_statements(|stmt| !matches!(stmt.kind, StatementKind::Nop))
1438+
}
1439+
1440+
pub fn drop_debuginfo(&mut self) {
1441+
self.after_last_stmt_debuginfos.drop_debuginfo();
1442+
for stmt in self.statements.iter_mut() {
1443+
stmt.debuginfos.drop_debuginfo();
1444+
}
1445+
}
14071446
}
14081447

14091448
///////////////////////////////////////////////////////////////////////////
@@ -1708,10 +1747,10 @@ mod size_asserts {
17081747

17091748
use super::*;
17101749
// tidy-alphabetical-start
1711-
static_assert_size!(BasicBlockData<'_>, 128);
1750+
static_assert_size!(BasicBlockData<'_>, 152);
17121751
static_assert_size!(LocalDecl<'_>, 40);
17131752
static_assert_size!(SourceScopeData<'_>, 64);
1714-
static_assert_size!(Statement<'_>, 32);
1753+
static_assert_size!(Statement<'_>, 56);
17151754
static_assert_size!(Terminator<'_>, 96);
17161755
static_assert_size!(VarDebugInfo<'_>, 88);
17171756
// tidy-alphabetical-end

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,9 @@ where
741741
let mut current_location = Location { block, statement_index: 0 };
742742
for statement in &data.statements {
743743
extra_data(PassWhere::BeforeLocation(current_location), w)?;
744+
for debuginfo in statement.debuginfos.iter() {
745+
writeln!(w, "{INDENT}{INDENT}// DBG: {debuginfo:?};")?;
746+
}
744747
let indented_body = format!("{INDENT}{INDENT}{statement:?};");
745748
if options.include_extra_comments {
746749
writeln!(
@@ -775,6 +778,9 @@ where
775778

776779
// Terminator at the bottom.
777780
extra_data(PassWhere::BeforeLocation(current_location), w)?;
781+
for debuginfo in data.after_last_stmt_debuginfos.iter() {
782+
writeln!(w, "{INDENT}{INDENT}// DBG: {debuginfo:?};")?;
783+
}
778784
if data.terminator.is_some() {
779785
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
780786
if options.include_extra_comments {
@@ -854,6 +860,16 @@ impl Debug for Statement<'_> {
854860
}
855861
}
856862

863+
impl Debug for StmtDebugInfo<'_> {
864+
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
865+
match self {
866+
StmtDebugInfo::AssignRef(local, place) => {
867+
write!(fmt, "{local:?} = &{place:?}")
868+
}
869+
}
870+
}
871+
}
872+
857873
impl Display for NonDivergingIntrinsic<'_> {
858874
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
859875
match self {

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 100 additions & 3 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,17 +17,34 @@ use crate::ty::CoroutineArgsExt;
1517
pub struct Statement<'tcx> {
1618
pub source_info: SourceInfo,
1719
pub kind: StatementKind<'tcx>,
20+
/// Some debuginfos appearing before the primary statement.
21+
pub debuginfos: StmtDebugInfos<'tcx>,
1822
}
1923

2024
impl<'tcx> Statement<'tcx> {
2125
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
2226
/// invalidating statement indices in `Location`s.
23-
pub fn make_nop(&mut self) {
24-
self.kind = StatementKind::Nop
27+
pub fn make_nop(&mut self, drop_debuginfo: bool) {
28+
if matches!(self.kind, StatementKind::Nop) {
29+
return;
30+
}
31+
let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop);
32+
if !drop_debuginfo {
33+
match replaced_stmt {
34+
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place)))
35+
if let Some(local) = place.as_local() =>
36+
{
37+
self.debuginfos.push(StmtDebugInfo::AssignRef(local, ref_place));
38+
}
39+
_ => {
40+
bug!("debuginfo is not yet supported.")
41+
}
42+
}
43+
}
2544
}
2645

2746
pub fn new(source_info: SourceInfo, kind: StatementKind<'tcx>) -> Self {
28-
Statement { source_info, kind }
47+
Statement { source_info, kind, debuginfos: StmtDebugInfos::default() }
2948
}
3049
}
3150

@@ -63,6 +82,17 @@ impl<'tcx> StatementKind<'tcx> {
6382
_ => None,
6483
}
6584
}
85+
86+
pub fn as_debuginfo(&self) -> Option<StmtDebugInfo<'tcx>> {
87+
match self {
88+
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place)))
89+
if let Some(local) = place.as_local() =>
90+
{
91+
Some(StmtDebugInfo::AssignRef(local, *ref_place))
92+
}
93+
_ => None,
94+
}
95+
}
6696
}
6797

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

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ macro_rules! make_mir_visitor {
9595
self.super_source_scope_data(scope_data);
9696
}
9797

98+
fn visit_statement_debuginfo(
99+
&mut self,
100+
stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>,
101+
location: Location
102+
) {
103+
self.super_statement_debuginfo(stmt_debuginfo, location);
104+
}
105+
98106
fn visit_statement(
99107
&mut self,
100108
statement: & $($mutability)? Statement<'tcx>,
@@ -301,6 +309,7 @@ macro_rules! make_mir_visitor {
301309
{
302310
let BasicBlockData {
303311
statements,
312+
after_last_stmt_debuginfos,
304313
terminator,
305314
is_cleanup: _
306315
} = data;
@@ -312,8 +321,11 @@ macro_rules! make_mir_visitor {
312321
index += 1;
313322
}
314323

324+
let location = Location { block, statement_index: index };
325+
for debuginfo in after_last_stmt_debuginfos as & $($mutability)? [_] {
326+
self.visit_statement_debuginfo(debuginfo, location);
327+
}
315328
if let Some(terminator) = terminator {
316-
let location = Location { block, statement_index: index };
317329
self.visit_terminator(terminator, location);
318330
}
319331
}
@@ -376,14 +388,38 @@ macro_rules! make_mir_visitor {
376388
}
377389
}
378390

391+
fn super_statement_debuginfo(
392+
&mut self,
393+
stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>,
394+
location: Location
395+
) {
396+
match stmt_debuginfo {
397+
StmtDebugInfo::AssignRef(local, place) => {
398+
self.visit_local(
399+
$(& $mutability)? *local,
400+
PlaceContext::NonUse(NonUseContext::VarDebugInfo),
401+
location
402+
);
403+
self.visit_place(
404+
place,
405+
PlaceContext::NonUse(NonUseContext::VarDebugInfo),
406+
location
407+
);
408+
},
409+
}
410+
}
411+
379412
fn super_statement(
380413
&mut self,
381414
statement: & $($mutability)? Statement<'tcx>,
382415
location: Location
383416
) {
384-
let Statement { source_info, kind } = statement;
417+
let Statement { source_info, kind, debuginfos } = statement;
385418

386419
self.visit_source_info(source_info);
420+
for debuginfo in debuginfos as & $($mutability)? [_] {
421+
self.visit_statement_debuginfo(debuginfo, location);
422+
}
387423
match kind {
388424
StatementKind::Assign(box (place, rvalue)) => {
389425
self.visit_assign(place, rvalue, location);

compiler/rustc_mir_dataflow/src/debuginfo.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ use rustc_middle::mir::*;
55
/// Return the set of locals that appear in debuginfo.
66
pub fn debuginfo_locals(body: &Body<'_>) -> DenseBitSet<Local> {
77
let mut visitor = DebuginfoLocals(DenseBitSet::new_empty(body.local_decls.len()));
8-
for debuginfo in body.var_debug_info.iter() {
9-
visitor.visit_var_debug_info(debuginfo);
10-
}
8+
visitor.visit_body(body);
119
visitor.0
1210
}
1311

1412
struct DebuginfoLocals(DenseBitSet<Local>);
1513

1614
impl Visitor<'_> for DebuginfoLocals {
17-
fn visit_local(&mut self, local: Local, _: PlaceContext, _: Location) {
18-
self.0.insert(local);
15+
fn visit_local(&mut self, local: Local, place_context: PlaceContext, _: Location) {
16+
if place_context == PlaceContext::NonUse(NonUseContext::VarDebugInfo) {
17+
self.0.insert(local);
18+
}
1919
}
2020
}

0 commit comments

Comments
 (0)