diff options
| author | bors <bors@rust-lang.org> | 2022-11-15 23:52:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-11-15 23:52:22 +0000 |
| commit | 79146baa9c7e00b716cc41f8660a56cd2acdf8bd (patch) | |
| tree | d0fe6175d864e6210b871dbe8433d00c87ae80cc /compiler/rustc_middle/src | |
| parent | a00f8ba7fcac1b27341679c51bf5a3271fa82df3 (diff) | |
| parent | a18de7084a729ad2400f5821bf467829660fe184 (diff) | |
Auto merge of #102570 - cjgillot:deagg-debuginfo, r=oli-obk
Perform simple scalar replacement of aggregates (SROA) MIR opt This is a re-open of https://github.com/rust-lang/rust/pull/85796 I copied the debuginfo implementation (first commit) from `@eddyb's` own SROA PR. This pass replaces plain field accesses by simple locals when possible. To be eligible, the replaced locals: - must not be enums or unions; - must not be used whole; - must not have their address taken. The storage and deinit statements are duplicated on each created local. cc `@tmiasko` who reviewed the former version of this PR.
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 53 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/visit.rs | 11 |
2 files changed, 64 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 4781651071d..12e9ebfeaec 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1071,6 +1071,18 @@ pub enum VarDebugInfoContents<'tcx> { /// based on a `Local`, not a `Static`, and contains no indexing. Place(Place<'tcx>), Const(Constant<'tcx>), + /// The user variable's data is split across several fragments, + /// each described by a `VarDebugInfoFragment`. + /// See DWARF 5's "2.6.1.2 Composite Location Descriptions" + /// and LLVM's `DW_OP_LLVM_fragment` for more details on + /// the underlying debuginfo feature this relies on. + Composite { + /// Type of the original user variable. + ty: Ty<'tcx>, + /// All the parts of the original user variable, which ended + /// up in disjoint places, due to optimizations. + fragments: Vec<VarDebugInfoFragment<'tcx>>, + }, } impl<'tcx> Debug for VarDebugInfoContents<'tcx> { @@ -1078,7 +1090,48 @@ impl<'tcx> Debug for VarDebugInfoContents<'tcx> { match self { VarDebugInfoContents::Const(c) => write!(fmt, "{}", c), VarDebugInfoContents::Place(p) => write!(fmt, "{:?}", p), + VarDebugInfoContents::Composite { ty, fragments } => { + write!(fmt, "{:?}{{ ", ty)?; + for f in fragments.iter() { + write!(fmt, "{:?}, ", f)?; + } + write!(fmt, "}}") + } + } + } +} + +#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +pub struct VarDebugInfoFragment<'tcx> { + /// Where in the composite user variable this fragment is, + /// represented as a "projection" into the composite variable. + /// At lower levels, this corresponds to a byte/bit range. + // NOTE(eddyb) there's an unenforced invariant that this contains + // only `Field`s, and not into `enum` variants or `union`s. + // FIXME(eddyb) support this for `enum`s by either using DWARF's + // more advanced control-flow features (unsupported by LLVM?) + // to match on the discriminant, or by using custom type debuginfo + // with non-overlapping variants for the composite variable. + pub projection: Vec<PlaceElem<'tcx>>, + + /// Where the data for this fragment can be found. + // NOTE(eddyb) There's an unenforced invariant that this `Place` is + // contains no indexing (with a non-constant index). + pub contents: Place<'tcx>, +} + +impl Debug for VarDebugInfoFragment<'_> { + fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { + for elem in self.projection.iter() { + match elem { + ProjectionElem::Field(field, _) => { + write!(fmt, ".{:?}", field.index())?; + } + _ => bug!("unsupported fragment projection `{:?}`", elem), + } } + + write!(fmt, " => {:?}", self.contents) } } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index d87eb28970e..b21f50ae5ea 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -847,6 +847,17 @@ macro_rules! make_mir_visitor { PlaceContext::NonUse(NonUseContext::VarDebugInfo), location ), + VarDebugInfoContents::Composite { ty, fragments } => { + // FIXME(eddyb) use a better `TyContext` here. + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + for VarDebugInfoFragment { projection: _, contents } in fragments { + self.visit_place( + contents, + PlaceContext::NonUse(NonUseContext::VarDebugInfo), + location, + ); + } + } } } |
