summaryrefslogtreecommitdiff
path: root/compiler/rustc_middle
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-05-14 05:31:10 +0000
committerbors <bors@rust-lang.org>2023-05-14 05:31:10 +0000
commitbc888958c9e1fdde09791f15d3421bdc3b6d7d29 (patch)
tree7c58f002e19288e067a691a56b09cb71d7b3ad29 /compiler/rustc_middle
parentad6ab11234ae885913229f6de2c4465bdc0d76f3 (diff)
parent8fb888dfaa1618838a288c41a8dc8ad24d1dadd5 (diff)
downloadrust-bc888958c9e1fdde09791f15d3421bdc3b6d7d29.tar.gz
Auto merge of #111440 - cjgillot:refprop-debuginfo, r=oli-obk
Allow MIR debuginfo to point to a variable's address MIR optimizations currently do not to operate on borrowed locals. When enabling #106285, many borrows will be left as-is because they are used in debuginfo. This pass allows to replace this pattern directly in MIR debuginfo: ```rust a => _1 _1 = &raw? mut? _2 ``` becomes ```rust a => &_2 // No statement to borrow _2. ``` This pass is implemented as a drive-by in ReferencePropagation MIR pass. This transformation allows following following MIR opts to treat _2 as an unborrowed local, and optimize it as such, even in builds with debuginfo. In codegen, when encountering `a => &..&_2`, we create a list of allocas: ```llvm store ptr %_2.dbg.spill, ptr %a.ref0.dbg.spill store ptr %a.ref0.dbg.spill, ptr %a.ref1.dbg.spill ... call void `@llvm.dbg.declare(metadata` ptr %a.ref{n}.dbg.spill, /* ... */) ``` Caveat: this transformation looses the exact type, we do not differentiate `a` as a immutable, mutable reference or a raw pointer. Everything is declared to `*mut` to codegen. I'm not convinced this is a blocker.
Diffstat (limited to 'compiler/rustc_middle')
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs45
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs9
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs1
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
4 files changed, 40 insertions, 16 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 55991facd89..6b0401a4c9b 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1111,6 +1111,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,
}
///////////////////////////////////////////////////////////////////////////
@@ -1550,8 +1554,11 @@ impl<V, T> ProjectionElem<V, T> {
/// Returns `true` if this is accepted inside `VarDebugInfoContents::Place`.
pub fn can_use_in_debuginfo(&self) -> bool {
match self {
- Self::Deref | Self::Downcast(_, _) | Self::Field(_, _) => true,
- Self::ConstantIndex { .. }
+ Self::ConstantIndex { from_end: false, .. }
+ | Self::Deref
+ | Self::Downcast(_, _)
+ | Self::Field(_, _) => true,
+ Self::ConstantIndex { from_end: true, .. }
| Self::Index(_)
| Self::OpaqueCast(_)
| Self::Subslice { .. } => false,
@@ -1639,18 +1646,7 @@ impl<'tcx> Place<'tcx> {
return self;
}
- let mut v: Vec<PlaceElem<'tcx>>;
-
- let new_projections = if self.projection.is_empty() {
- more_projections
- } else {
- v = Vec::with_capacity(self.projection.len() + more_projections.len());
- v.extend(self.projection);
- v.extend(more_projections);
- &v
- };
-
- Place { local: self.local, projection: tcx.mk_place_elems(new_projections) }
+ self.as_ref().project_deeper(more_projections, tcx)
}
}
@@ -1721,6 +1717,27 @@ impl<'tcx> PlaceRef<'tcx> {
(base, *proj)
})
}
+
+ /// Generates a new place by appending `more_projections` to the existing ones
+ /// and interning the result.
+ pub fn project_deeper(
+ self,
+ more_projections: &[PlaceElem<'tcx>],
+ tcx: TyCtxt<'tcx>,
+ ) -> Place<'tcx> {
+ let mut v: Vec<PlaceElem<'tcx>>;
+
+ let new_projections = if self.projection.is_empty() {
+ more_projections
+ } else {
+ v = Vec::with_capacity(self.projection.len() + more_projections.len());
+ v.extend(self.projection);
+ v.extend(more_projections);
+ &v
+ };
+
+ Place { local: self.local, projection: tcx.mk_place_elems(new_projections) }
+ }
}
impl Debug for Place<'_> {
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index fa8a339631e..62c3d8cf239 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -551,8 +551,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,
);
writeln!(
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index d7a7fdebda6..596dd80bf48 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -842,6 +842,7 @@ macro_rules! make_mir_visitor {
source_info,
value,
argument_index: _,
+ references: _,
} = var_debug_info;
self.visit_source_info(source_info);
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 29a3bc8bb97..e73208b877f 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -204,6 +204,7 @@ CloneLiftImpls! {
(),
bool,
usize,
+ u8,
u16,
u32,
u64,