-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Introduce debuginfo to statements in MIR #142771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
06f5a9d
29357bc
a0b4fe1
ec25192
458ad93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
//! Functionality for statements, operands, places, and things that appear in them. | ||
|
||
use std::ops; | ||
|
||
use tracing::{debug, instrument}; | ||
|
||
use super::interpret::GlobalAlloc; | ||
|
@@ -15,17 +17,34 @@ use crate::ty::CoroutineArgsExt; | |
pub struct Statement<'tcx> { | ||
pub source_info: SourceInfo, | ||
pub kind: StatementKind<'tcx>, | ||
/// Some debuginfos appearing before the primary statement. | ||
pub debuginfos: StmtDebugInfos<'tcx>, | ||
} | ||
|
||
impl<'tcx> Statement<'tcx> { | ||
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids | ||
/// invalidating statement indices in `Location`s. | ||
pub fn make_nop(&mut self) { | ||
self.kind = StatementKind::Nop | ||
pub fn make_nop(&mut self, drop_debuginfo: bool) { | ||
if matches!(self.kind, StatementKind::Nop) { | ||
return; | ||
} | ||
let replaced_stmt = std::mem::replace(&mut self.kind, StatementKind::Nop); | ||
if !drop_debuginfo { | ||
match replaced_stmt { | ||
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place))) | ||
if let Some(local) = place.as_local() => | ||
{ | ||
self.debuginfos.push(StmtDebugInfo::AssignRef(local, ref_place)); | ||
} | ||
_ => { | ||
bug!("debuginfo is not yet supported.") | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn new(source_info: SourceInfo, kind: StatementKind<'tcx>) -> Self { | ||
Statement { source_info, kind } | ||
Statement { source_info, kind, debuginfos: StmtDebugInfos::default() } | ||
} | ||
} | ||
|
||
|
@@ -63,6 +82,17 @@ impl<'tcx> StatementKind<'tcx> { | |
_ => None, | ||
} | ||
} | ||
|
||
pub fn as_debuginfo(&self) -> Option<StmtDebugInfo<'tcx>> { | ||
match self { | ||
StatementKind::Assign(box (place, Rvalue::Ref(_, _, ref_place))) | ||
if let Some(local) = place.as_local() => | ||
{ | ||
Some(StmtDebugInfo::AssignRef(local, *ref_place)) | ||
} | ||
_ => None, | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Used in dead_store_elimination.rs and liveness.rs. I used it to get or check debuginfo. |
||
} | ||
|
||
/////////////////////////////////////////////////////////////////////////// | ||
|
@@ -939,3 +969,70 @@ impl RawPtrKind { | |
} | ||
} | ||
} | ||
|
||
#[derive(Default, Debug, Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] | ||
pub struct StmtDebugInfos<'tcx>(Vec<StmtDebugInfo<'tcx>>); | ||
|
||
impl<'tcx> StmtDebugInfos<'tcx> { | ||
pub fn push(&mut self, debuginfo: StmtDebugInfo<'tcx>) { | ||
self.0.push(debuginfo); | ||
} | ||
|
||
pub fn drop_debuginfo(&mut self) { | ||
self.0.clear(); | ||
} | ||
|
||
pub fn is_empty(&self) -> bool { | ||
self.0.is_empty() | ||
} | ||
|
||
pub fn prepend(&mut self, debuginfos: &mut Self) { | ||
if debuginfos.is_empty() { | ||
return; | ||
}; | ||
debuginfos.0.append(self); | ||
std::mem::swap(debuginfos, self); | ||
} | ||
|
||
pub fn append(&mut self, debuginfos: &mut Self) { | ||
if debuginfos.is_empty() { | ||
return; | ||
}; | ||
self.0.append(debuginfos); | ||
} | ||
|
||
pub fn extend(&mut self, debuginfos: &Self) { | ||
if debuginfos.is_empty() { | ||
return; | ||
}; | ||
self.0.extend_from_slice(debuginfos); | ||
} | ||
|
||
pub fn retain<F>(&mut self, f: F) | ||
where | ||
F: FnMut(&StmtDebugInfo<'tcx>) -> bool, | ||
{ | ||
self.0.retain(f); | ||
} | ||
} | ||
|
||
impl<'tcx> ops::Deref for StmtDebugInfos<'tcx> { | ||
type Target = Vec<StmtDebugInfo<'tcx>>; | ||
|
||
#[inline] | ||
fn deref(&self) -> &Vec<StmtDebugInfo<'tcx>> { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl<'tcx> ops::DerefMut for StmtDebugInfos<'tcx> { | ||
#[inline] | ||
fn deref_mut(&mut self) -> &mut Vec<StmtDebugInfo<'tcx>> { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] | ||
pub enum StmtDebugInfo<'tcx> { | ||
AssignRef(Local, Place<'tcx>), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,6 +95,14 @@ macro_rules! make_mir_visitor { | |
self.super_source_scope_data(scope_data); | ||
} | ||
|
||
fn visit_statement_debuginfo( | ||
&mut self, | ||
stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>, | ||
location: Location | ||
) { | ||
self.super_statement_debuginfo(stmt_debuginfo, location); | ||
} | ||
|
||
fn visit_statement( | ||
&mut self, | ||
statement: & $($mutability)? Statement<'tcx>, | ||
|
@@ -301,6 +309,7 @@ macro_rules! make_mir_visitor { | |
{ | ||
let BasicBlockData { | ||
statements, | ||
after_last_stmt_debuginfos, | ||
terminator, | ||
is_cleanup: _ | ||
} = data; | ||
|
@@ -312,8 +321,11 @@ macro_rules! make_mir_visitor { | |
index += 1; | ||
} | ||
|
||
let location = Location { block, statement_index: index }; | ||
for debuginfo in after_last_stmt_debuginfos as & $($mutability)? [_] { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
self.visit_statement_debuginfo(debuginfo, location); | ||
} | ||
if let Some(terminator) = terminator { | ||
let location = Location { block, statement_index: index }; | ||
self.visit_terminator(terminator, location); | ||
} | ||
} | ||
|
@@ -376,14 +388,38 @@ macro_rules! make_mir_visitor { | |
} | ||
} | ||
|
||
fn super_statement_debuginfo( | ||
&mut self, | ||
stmt_debuginfo: & $($mutability)? StmtDebugInfo<'tcx>, | ||
location: Location | ||
) { | ||
match stmt_debuginfo { | ||
StmtDebugInfo::AssignRef(local, place) => { | ||
self.visit_local( | ||
$(& $mutability)? *local, | ||
PlaceContext::NonUse(NonUseContext::VarDebugInfo), | ||
location | ||
); | ||
self.visit_place( | ||
place, | ||
PlaceContext::NonUse(NonUseContext::VarDebugInfo), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can now have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like we only need to adapt |
||
location | ||
); | ||
}, | ||
} | ||
} | ||
|
||
fn super_statement( | ||
&mut self, | ||
statement: & $($mutability)? Statement<'tcx>, | ||
location: Location | ||
) { | ||
let Statement { source_info, kind } = statement; | ||
let Statement { source_info, kind, debuginfos } = statement; | ||
|
||
self.visit_source_info(source_info); | ||
for debuginfo in debuginfos as & $($mutability)? [_] { | ||
self.visit_statement_debuginfo(debuginfo, location); | ||
} | ||
match kind { | ||
StatementKind::Assign(box (place, rvalue)) => { | ||
self.visit_assign(place, rvalue, location); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder: should we attempt to keep debuginfo in most cases, and only drop statements that we do not know how to convert? I mean, consider
drop_debuginfo
to be always false, and replace thebug!
by a no-op?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to do this after we've reviewed most of the MIR statements.