Skip to content
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

Reimplement references VarDebugInfo #115030

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
};

self.cx.create_dbg_var(var.name, var_ty, dbg_scope, var_kind, span)
let name = if var.references > 0 {
Symbol::intern(&format!("{0:*<1$}{2}", "", var.references as usize, var.name))
} else {
var.name
};

self.cx.create_dbg_var(name, var_ty, dbg_scope, var_kind, span)
});

match var.value {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
VarDebugInfoContents::Const(_) => {}
VarDebugInfoContents::Place(place) => {
check_place(self, place);
if debuginfo.references != 0 && place.projection.last() == Some(&PlaceElem::Deref) {
self.fail(
START_BLOCK.start_location(),
format!("debuginfo {debuginfo:?}, has both ref and deref"),
);
}
}
VarDebugInfoContents::Composite { ty, ref fragments } => {
for f in fragments {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,10 @@ pub struct VarDebugInfo<'tcx> {
/// originated from (starting from 1). Note, if MIR inlining is enabled, then this is the
/// argument number in the original function before it was inlined.
pub argument_index: Option<u16>,

/// The data represents `name` dereferenced `references` times,
/// and not the direct value.
pub references: u8,
}

///////////////////////////////////////////////////////////////////////////
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,13 @@ fn write_scope_tree(
}

let indented_debug_info = format!(
"{0:1$}debug {2} => {3:?};",
INDENT, indent, var_debug_info.name, var_debug_info.value,
"{0:1$}debug {2} => {3:&<4$}{5:?};",
INDENT,
indent,
var_debug_info.name,
"",
var_debug_info.references as usize,
var_debug_info.value,
);

if tcx.sess.opts.unstable_opts.mir_include_spans {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ macro_rules! make_mir_visitor {
source_info,
value,
argument_index: _,
references: _,
} = var_debug_info;

self.visit_source_info(source_info);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ CloneLiftImpls! {
(),
bool,
usize,
u8,
u16,
u32,
u64,
Expand Down
68 changes: 67 additions & 1 deletion compiler/rustc_mir_build/src/build/custom/parse.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_index::IndexSlice;
use rustc_middle::{mir::*, thir::*, ty::Ty};
use rustc_middle::ty::{self, Ty};
use rustc_middle::{mir::*, thir::*};
use rustc_span::Span;

use super::{PResult, ParseCtxt, ParseError};
Expand Down Expand Up @@ -159,6 +160,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
);
self.parse_local_decls(local_decls.iter().copied())?;

let (debuginfo, rest) = parse_by_kind!(self, rest, _, "body with debuginfo",
ExprKind::Block { block } => {
let block = &self.thir[*block];
(&block.stmts, block.expr.unwrap())
},
);
self.parse_debuginfo(debuginfo.iter().copied())?;

let block_defs = parse_by_kind!(self, rest, _, "body with block defs",
ExprKind::Block { block } => &self.thir[*block].stmts,
);
Expand Down Expand Up @@ -195,6 +204,63 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
Ok(())
}

fn parse_debuginfo(&mut self, stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
for stmt in stmts {
let stmt = &self.thir[stmt];
let expr = match stmt.kind {
StmtKind::Let { span, .. } => {
return Err(ParseError {
span,
item_description: format!("{:?}", stmt),
expected: "debuginfo".to_string(),
});
}
StmtKind::Expr { expr, .. } => expr,
};
let span = self.thir[expr].span;
let (name, mut operand) = parse_by_kind!(self, expr, _, "debuginfo",
@call("mir_debuginfo", args) => {
(args[0], args[1])
},
);
let name = parse_by_kind!(self, name, _, "debuginfo",
ExprKind::Literal { lit, neg: false } => lit,
);
let Some(name) = name.node.str() else {
return Err(ParseError {
span,
item_description: format!("{:?}", name),
expected: "string".to_string(),
});
};
let mut references = 0;
loop {
parse_by_kind!(self, operand, _, "debuginfo",
ExprKind::Borrow { arg, .. } => {
references += 1;
operand = *arg;
},
_ => break,
);
}
let operand = self.parse_operand(operand)?;
let value = match operand {
Operand::Constant(c) => VarDebugInfoContents::Const(*c),
Operand::Copy(p) | Operand::Move(p) => VarDebugInfoContents::Place(p),
};
let dbginfo = VarDebugInfo {
name,
source_info: SourceInfo { span, scope: self.source_scope },
argument_index: None,
references,
value,
};
self.body.var_debug_info.push(dbginfo);
}

Ok(())
}

fn parse_let_statement(&mut self, stmt_id: StmtId) -> PResult<(LocalVarId, Ty<'tcx>, Span)> {
let pattern = match &self.thir[stmt_id].kind {
StmtKind::Let { pattern, .. } => pattern,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
)
}

fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
pub fn parse_operand(&self, expr_id: ExprId) -> PResult<Operand<'tcx>> {
parse_by_kind!(self, expr_id, expr, "operand",
@call("mir_move", args) => self.parse_place(args[0]).map(Operand::Move),
@call("mir_static", args) => self.parse_static(args[0]),
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2242,6 +2242,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info: debug_source_info,
references: 0,
value: VarDebugInfoContents::Place(for_arm_body.into()),
argument_index: None,
});
Expand All @@ -2261,6 +2262,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info: debug_source_info,
references: 0,
value: VarDebugInfoContents::Place(ref_for_guard.into()),
argument_index: None,
});
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
self.var_debug_info.push(VarDebugInfo {
name,
references: 0,
source_info: SourceInfo::outermost(captured_place.var_ident.span),
value: VarDebugInfoContents::Place(use_place),
argument_index: None,
Expand Down Expand Up @@ -850,6 +851,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info,
references: 0,
value: VarDebugInfoContents::Place(arg_local.into()),
argument_index: Some(argument_index as u16 + 1),
});
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_mir_transform/src/ref_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ fn compute_replacement<'tcx>(
targets,
storage_to_remove,
allowed_replacements,
fully_replacable_locals,
any_replacement: false,
};

Expand Down Expand Up @@ -345,6 +346,7 @@ struct Replacer<'tcx> {
storage_to_remove: BitSet<Local>,
allowed_replacements: FxHashSet<(Local, Location)>,
any_replacement: bool,
fully_replacable_locals: BitSet<Local>,
}

impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
Expand All @@ -364,6 +366,12 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'tcx> {
if let Some((&PlaceElem::Deref, rest)) = target.projection.split_last() {
*place = Place::from(target.local).project_deeper(rest, self.tcx);
self.any_replacement = true;
} else if self.fully_replacable_locals.contains(place.local)
&& let Some(references) = debuginfo.references.checked_add(1)
{
debuginfo.references = references;
*place = target;
self.any_replacement = true;
} else {
break
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/src/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ TrivialTypeTraversalImpls! {
(),
bool,
usize,
u8,
u16,
u32,
u64,
Expand Down
41 changes: 28 additions & 13 deletions library/core/src/intrinsics/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
//!
//! Typical usage will look like this:
//!
//! ```rust
#![cfg_attr(bootstrap, doc = "```rust,ignore")]
#![cfg_attr(not(bootstrap), doc = "```rust")]
//! #![feature(core_intrinsics, custom_mir)]
#![cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
//!
Expand Down Expand Up @@ -62,7 +63,8 @@
//!
//! # Examples
//!
//! ```rust
#![cfg_attr(bootstrap, doc = "```rust,ignore")]
#![cfg_attr(not(bootstrap), doc = "```rust")]
//! #![feature(core_intrinsics, custom_mir)]
#![cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
//!
Expand Down Expand Up @@ -316,9 +318,10 @@ define!(
///
/// # Examples
///
/// ```rust
#[cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
#[cfg_attr(bootstrap, doc = "```rust,ignore")]
#[cfg_attr(not(bootstrap), doc = "```rust")]
/// #![feature(custom_mir, core_intrinsics)]
#[cfg_attr(not(bootstrap), doc = "#![allow(internal_features)]")]
///
/// use core::intrinsics::mir::*;
///
Expand Down Expand Up @@ -360,6 +363,11 @@ define!(
#[doc(hidden)]
fn __internal_make_place<T>(place: T) -> *mut T
);
define!(
"mir_debuginfo",
#[doc(hidden)]
fn __debuginfo<T>(name: &'static str, s: T)
);

/// Macro for generating custom MIR.
///
Expand All @@ -370,6 +378,7 @@ pub macro mir {
(
$(type RET = $ret_ty:ty ;)?
$(let $local_decl:ident $(: $local_decl_ty:ty)? ;)*
$(debug $dbg_name:ident => $dbg_data:expr ;)*

{
$($entry:tt)*
Expand All @@ -393,26 +402,32 @@ pub macro mir {
$(
let $local_decl $(: $local_decl_ty)? ;
)*

::core::intrinsics::mir::__internal_extract_let!($($entry)*);
$(
::core::intrinsics::mir::__internal_extract_let!($($block)*);
)*

{
// Finally, the contents of the basic blocks
::core::intrinsics::mir::__internal_remove_let!({
{}
{ $($entry)* }
});
// Now debuginfo
$(
__debuginfo(stringify!($dbg_name), $dbg_data);
)*

{
// Finally, the contents of the basic blocks
::core::intrinsics::mir::__internal_remove_let!({
{}
{ $($block)* }
{ $($entry)* }
});
)*
$(
::core::intrinsics::mir::__internal_remove_let!({
{}
{ $($block)* }
});
)*

RET
RET
}
}
}
}}
Expand Down
32 changes: 16 additions & 16 deletions tests/codegen/slice-ref-equality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,48 +44,48 @@ pub fn is_zero_array(data: &[u8; 4]) -> bool {
// equality for non-byte types also just emit a `bcmp`, not a loop.

// CHECK-LABEL: @eq_slice_of_nested_u8(
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %1
// CHECK-SAME: [[USIZE]] noundef %3
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1
// CHECK-SAME: [[USIZE]] noundef %y.1
#[no_mangle]
fn eq_slice_of_nested_u8(x: &[[u8; 3]], y: &[[u8; 3]]) -> bool {
// CHECK: icmp eq [[USIZE]] %1, %3
// CHECK: %[[BYTES:.+]] = mul nsw [[USIZE]] %1, 3
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
// CHECK: %[[BYTES:.+]] = mul nsw [[USIZE]] %x.1, 3
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
x == y
}

// CHECK-LABEL: @eq_slice_of_i32(
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %1
// CHECK-SAME: [[USIZE]] noundef %3
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1
// CHECK-SAME: [[USIZE]] noundef %y.1
#[no_mangle]
fn eq_slice_of_i32(x: &[i32], y: &[i32]) -> bool {
// CHECK: icmp eq [[USIZE]] %1, %3
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %1, 2
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %x.1, 2
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
x == y
}

// CHECK-LABEL: @eq_slice_of_nonzero(
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %1
// CHECK-SAME: [[USIZE]] noundef %3
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1
// CHECK-SAME: [[USIZE]] noundef %y.1
#[no_mangle]
fn eq_slice_of_nonzero(x: &[NonZeroU32], y: &[NonZeroU32]) -> bool {
// CHECK: icmp eq [[USIZE]] %1, %3
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %1, 2
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %x.1, 2
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
x == y
}

// CHECK-LABEL: @eq_slice_of_option_of_nonzero(
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %1
// CHECK-SAME: [[USIZE]] noundef %3
// CHECK-SAME: [[USIZE:i16|i32|i64]] noundef %x.1
// CHECK-SAME: [[USIZE]] noundef %y.1
#[no_mangle]
fn eq_slice_of_option_of_nonzero(x: &[Option<NonZeroI16>], y: &[Option<NonZeroI16>]) -> bool {
// CHECK: icmp eq [[USIZE]] %1, %3
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %1, 1
// CHECK: icmp eq [[USIZE]] %x.1, %y.1
// CHECK: %[[BYTES:.+]] = shl nsw [[USIZE]] %x.1, 1
// CHECK: tail call{{( noundef)?}} i32 @{{bcmp|memcmp}}(ptr
// CHECK-SAME: , [[USIZE]]{{( noundef)?}} %[[BYTES]])
x == y
Expand Down
Loading