1
Fork 0

Extend -Z print-type-sizes to distinguish generator upvars and locals from "normal" ADT fields.

This commit is contained in:
Felix S. Klock II 2023-01-31 15:59:29 -05:00
parent a64ef7d07d
commit a37b3061fc
3 changed files with 27 additions and 6 deletions

View file

@ -19,8 +19,26 @@ pub enum SizeKind {
Min, Min,
} }
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum FieldKind {
AdtField,
Upvar,
GeneratorLocal,
}
impl std::fmt::Display for FieldKind {
fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FieldKind::AdtField => { write!(w, "field") }
FieldKind::Upvar => { write!(w, "upvar") }
FieldKind::GeneratorLocal => { write!(w, "local") }
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FieldInfo { pub struct FieldInfo {
pub kind: FieldKind,
pub name: Symbol, pub name: Symbol,
pub offset: u64, pub offset: u64,
pub size: u64, pub size: u64,
@ -145,7 +163,7 @@ impl CodeStats {
fields.sort_by_key(|f| (f.offset, f.size)); fields.sort_by_key(|f| (f.offset, f.size));
for field in fields { for field in fields {
let FieldInfo { ref name, offset, size, align } = field; let FieldInfo { kind, ref name, offset, size, align } = field;
if offset > min_offset { if offset > min_offset {
let pad = offset - min_offset; let pad = offset - min_offset;
@ -155,16 +173,16 @@ impl CodeStats {
if offset < min_offset { if offset < min_offset {
// If this happens it's probably a union. // If this happens it's probably a union.
println!( println!(
"print-type-size {indent}field `.{name}`: {size} bytes, \ "print-type-size {indent}{kind} `.{name}`: {size} bytes, \
offset: {offset} bytes, \ offset: {offset} bytes, \
alignment: {align} bytes" alignment: {align} bytes"
); );
} else if info.packed || offset == min_offset { } else if info.packed || offset == min_offset {
println!("print-type-size {indent}field `.{name}`: {size} bytes"); println!("print-type-size {indent}{kind} `.{name}`: {size} bytes");
} else { } else {
// Include field alignment in output only if it caused padding injection // Include field alignment in output only if it caused padding injection
println!( println!(
"print-type-size {indent}field `.{name}`: {size} bytes, \ "print-type-size {indent}{kind} `.{name}`: {size} bytes, \
alignment: {align} bytes" alignment: {align} bytes"
); );
} }

View file

@ -1,6 +1,6 @@
use crate::cgu_reuse_tracker::CguReuseTracker; use crate::cgu_reuse_tracker::CguReuseTracker;
use crate::code_stats::CodeStats; use crate::code_stats::CodeStats;
pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; pub use crate::code_stats::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use crate::config::Input; use crate::config::Input;
use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath}; use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, SwitchWithOptPath};
use crate::errors::{ use crate::errors::{

View file

@ -9,7 +9,7 @@ use rustc_middle::ty::layout::{
use rustc_middle::ty::{ use rustc_middle::ty::{
self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable, self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable,
}; };
use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_span::DUMMY_SP; use rustc_span::DUMMY_SP;
use rustc_target::abi::*; use rustc_target::abi::*;
@ -881,6 +881,7 @@ fn variant_info_for_adt<'tcx>(
let offset = layout.fields.offset(i); let offset = layout.fields.offset(i);
min_size = min_size.max(offset + field_layout.size); min_size = min_size.max(offset + field_layout.size);
FieldInfo { FieldInfo {
kind: FieldKind::AdtField,
name, name,
offset: offset.bytes(), offset: offset.bytes(),
size: field_layout.size.bytes(), size: field_layout.size.bytes(),
@ -960,6 +961,7 @@ fn variant_info_for_generator<'tcx>(
let offset = layout.fields.offset(field_idx); let offset = layout.fields.offset(field_idx);
upvars_size = upvars_size.max(offset + field_layout.size); upvars_size = upvars_size.max(offset + field_layout.size);
FieldInfo { FieldInfo {
kind: FieldKind::Upvar,
name: Symbol::intern(&name), name: Symbol::intern(&name),
offset: offset.bytes(), offset: offset.bytes(),
size: field_layout.size.bytes(), size: field_layout.size.bytes(),
@ -983,6 +985,7 @@ fn variant_info_for_generator<'tcx>(
// The struct is as large as the last field's end // The struct is as large as the last field's end
variant_size = variant_size.max(offset + field_layout.size); variant_size = variant_size.max(offset + field_layout.size);
FieldInfo { FieldInfo {
kind: FieldKind::GeneratorLocal,
name: state_specific_names.get(*local).copied().flatten().unwrap_or( name: state_specific_names.get(*local).copied().flatten().unwrap_or(
Symbol::intern(&format!(".generator_field{}", local.as_usize())), Symbol::intern(&format!(".generator_field{}", local.as_usize())),
), ),