mir-opt: Eliminate dead statements even if they are used by debuginfos

This commit is contained in:
dianqk
2025-07-19 18:49:47 +08:00
parent 1bd89bd42e
commit 8da04285cf
20 changed files with 178 additions and 109 deletions

View File

@@ -657,6 +657,22 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
self.tcx
}
fn visit_statement_debuginfo(
&mut self,
stmt_debuginfo: &mut StmtDebugInfo<'tcx>,
location: Location,
) {
match stmt_debuginfo {
StmtDebugInfo::AssignRef(local, place) => {
if place.as_ref().accessed_locals().any(|local| self.map[local].is_none()) {
*stmt_debuginfo = StmtDebugInfo::InvalidAssign(*local);
}
}
StmtDebugInfo::InvalidAssign(_) => {}
}
self.super_statement_debuginfo(stmt_debuginfo, location);
}
fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
*l = self.map[*l].unwrap();
}

View File

@@ -1,5 +1,6 @@
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::debuginfo::debuginfo_locals;
use rustc_session::config::MirStripDebugInfo;
/// Conditionally remove some of the VarDebugInfo in MIR.
@@ -30,6 +31,22 @@ impl<'tcx> crate::MirPass<'tcx> for StripDebugInfo {
if place.local.as_usize() <= body.arg_count && place.local != RETURN_PLACE,
)
});
let debuginfo_locals = debuginfo_locals(body);
for data in body.basic_blocks.as_mut_preserves_cfg() {
for stmt in data.statements.iter_mut() {
stmt.debuginfos.retain(|debuginfo| match debuginfo {
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
debuginfo_locals.contains(*local)
}
});
}
data.after_last_stmt_debuginfos.retain(|debuginfo| match debuginfo {
StmtDebugInfo::AssignRef(local, _) | StmtDebugInfo::InvalidAssign(local) => {
debuginfo_locals.contains(*local)
}
});
}
}
fn is_required(&self) -> bool {