Rollup merge of #59630 - nnethercote:shrink-mir-Statement, r=pnkfelix
Shrink `mir::Statement`. The `InlineAsm` variant is extremely rare, and `mir::Statement` often contributes significantly to peak memory usage.
This commit is contained in:
commit
d31d80b7d4
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use crate::hir::def::{CtorKind, Namespace};
|
use crate::hir::def::{CtorKind, Namespace};
|
||||||
use crate::hir::def_id::DefId;
|
use crate::hir::def_id::DefId;
|
||||||
use crate::hir::{self, HirId, InlineAsm};
|
use crate::hir::{self, HirId, InlineAsm as HirInlineAsm};
|
||||||
use crate::mir::interpret::{ConstValue, InterpError, Scalar};
|
use crate::mir::interpret::{ConstValue, InterpError, Scalar};
|
||||||
use crate::mir::visit::MirVisitable;
|
use crate::mir::visit::MirVisitable;
|
||||||
use rustc_apfloat::ieee::{Double, Single};
|
use rustc_apfloat::ieee::{Double, Single};
|
||||||
@ -1735,7 +1735,7 @@ pub struct Statement<'tcx> {
|
|||||||
|
|
||||||
// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Statement<'_>>() == 56);
|
static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Statement<'_>>() == 48);
|
||||||
|
|
||||||
impl<'tcx> Statement<'tcx> {
|
impl<'tcx> Statement<'tcx> {
|
||||||
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
|
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
|
||||||
@ -1779,12 +1779,9 @@ pub enum StatementKind<'tcx> {
|
|||||||
/// End the current live range for the storage of the local.
|
/// End the current live range for the storage of the local.
|
||||||
StorageDead(Local),
|
StorageDead(Local),
|
||||||
|
|
||||||
/// Executes a piece of inline Assembly.
|
/// Executes a piece of inline Assembly. Stored in a Box to keep the size
|
||||||
InlineAsm {
|
/// of `StatementKind` low.
|
||||||
asm: Box<InlineAsm>,
|
InlineAsm(Box<InlineAsm<'tcx>>),
|
||||||
outputs: Box<[Place<'tcx>]>,
|
|
||||||
inputs: Box<[(Span, Operand<'tcx>)]>,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Retag references in the given place, ensuring they got fresh tags. This is
|
/// Retag references in the given place, ensuring they got fresh tags. This is
|
||||||
/// part of the Stacked Borrows model. These statements are currently only interpreted
|
/// part of the Stacked Borrows model. These statements are currently only interpreted
|
||||||
@ -1858,6 +1855,13 @@ pub enum FakeReadCause {
|
|||||||
ForLet,
|
ForLet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
|
pub struct InlineAsm<'tcx> {
|
||||||
|
pub asm: HirInlineAsm,
|
||||||
|
pub outputs: Box<[Place<'tcx>]>,
|
||||||
|
pub inputs: Box<[(Span, Operand<'tcx>)]>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> Debug for Statement<'tcx> {
|
impl<'tcx> Debug for Statement<'tcx> {
|
||||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||||
use self::StatementKind::*;
|
use self::StatementKind::*;
|
||||||
@ -1880,11 +1884,8 @@ impl<'tcx> Debug for Statement<'tcx> {
|
|||||||
ref place,
|
ref place,
|
||||||
variant_index,
|
variant_index,
|
||||||
} => write!(fmt, "discriminant({:?}) = {:?}", place, variant_index),
|
} => write!(fmt, "discriminant({:?}) = {:?}", place, variant_index),
|
||||||
InlineAsm {
|
InlineAsm(ref asm) =>
|
||||||
ref asm,
|
write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs),
|
||||||
ref outputs,
|
|
||||||
ref inputs,
|
|
||||||
} => write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs),
|
|
||||||
AscribeUserType(ref place, ref variance, ref c_ty) => {
|
AscribeUserType(ref place, ref variance, ref c_ty) => {
|
||||||
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
|
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
|
||||||
}
|
}
|
||||||
@ -3149,13 +3150,21 @@ EnumTypeFoldableImpl! {
|
|||||||
(StatementKind::SetDiscriminant) { place, variant_index },
|
(StatementKind::SetDiscriminant) { place, variant_index },
|
||||||
(StatementKind::StorageLive)(a),
|
(StatementKind::StorageLive)(a),
|
||||||
(StatementKind::StorageDead)(a),
|
(StatementKind::StorageDead)(a),
|
||||||
(StatementKind::InlineAsm) { asm, outputs, inputs },
|
(StatementKind::InlineAsm)(a),
|
||||||
(StatementKind::Retag)(kind, place),
|
(StatementKind::Retag)(kind, place),
|
||||||
(StatementKind::AscribeUserType)(a, v, b),
|
(StatementKind::AscribeUserType)(a, v, b),
|
||||||
(StatementKind::Nop),
|
(StatementKind::Nop),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BraceStructTypeFoldableImpl! {
|
||||||
|
impl<'tcx> TypeFoldable<'tcx> for InlineAsm<'tcx> {
|
||||||
|
asm,
|
||||||
|
outputs,
|
||||||
|
inputs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EnumTypeFoldableImpl! {
|
EnumTypeFoldableImpl! {
|
||||||
impl<'tcx, T> TypeFoldable<'tcx> for ClearCrossCrate<T> {
|
impl<'tcx, T> TypeFoldable<'tcx> for ClearCrossCrate<T> {
|
||||||
(ClearCrossCrate::Clear),
|
(ClearCrossCrate::Clear),
|
||||||
|
@ -391,15 +391,15 @@ macro_rules! make_mir_visitor {
|
|||||||
location
|
location
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StatementKind::InlineAsm { outputs, inputs, asm: _ } => {
|
StatementKind::InlineAsm(asm) => {
|
||||||
for output in & $($mutability)? outputs[..] {
|
for output in & $($mutability)? asm.outputs[..] {
|
||||||
self.visit_place(
|
self.visit_place(
|
||||||
output,
|
output,
|
||||||
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
|
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
|
||||||
location
|
location
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (span, input) in & $($mutability)? inputs[..] {
|
for (span, input) in & $($mutability)? asm.inputs[..] {
|
||||||
self.visit_span(span);
|
self.visit_span(span);
|
||||||
self.visit_operand(input, location);
|
self.visit_operand(input, location);
|
||||||
}
|
}
|
||||||
|
@ -68,13 +68,13 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
}
|
}
|
||||||
bx
|
bx
|
||||||
}
|
}
|
||||||
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
|
mir::StatementKind::InlineAsm(ref asm) => {
|
||||||
let outputs = outputs.iter().map(|output| {
|
let outputs = asm.outputs.iter().map(|output| {
|
||||||
self.codegen_place(&mut bx, output)
|
self.codegen_place(&mut bx, output)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let input_vals = inputs.iter()
|
let input_vals = asm.inputs.iter()
|
||||||
.fold(Vec::with_capacity(inputs.len()), |mut acc, (span, input)| {
|
.fold(Vec::with_capacity(asm.inputs.len()), |mut acc, (span, input)| {
|
||||||
let op = self.codegen_operand(&mut bx, input);
|
let op = self.codegen_operand(&mut bx, input);
|
||||||
if let OperandValue::Immediate(_) = op.val {
|
if let OperandValue::Immediate(_) = op.val {
|
||||||
acc.push(op.immediate());
|
acc.push(op.immediate());
|
||||||
@ -85,8 +85,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
acc
|
acc
|
||||||
});
|
});
|
||||||
|
|
||||||
if input_vals.len() == inputs.len() {
|
if input_vals.len() == asm.inputs.len() {
|
||||||
let res = bx.codegen_inline_asm(asm, outputs, input_vals);
|
let res = bx.codegen_inline_asm(&asm.asm, outputs, input_vals);
|
||||||
if !res {
|
if !res {
|
||||||
span_err!(bx.sess(), statement.source_info.span, E0668,
|
span_err!(bx.sess(), statement.source_info.span, E0668,
|
||||||
"malformed inline assembly");
|
"malformed inline assembly");
|
||||||
|
@ -525,16 +525,12 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
|||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StatementKind::InlineAsm {
|
StatementKind::InlineAsm(ref asm) => {
|
||||||
ref asm,
|
|
||||||
ref outputs,
|
|
||||||
ref inputs,
|
|
||||||
} => {
|
|
||||||
let context = ContextKind::InlineAsm.new(location);
|
let context = ContextKind::InlineAsm.new(location);
|
||||||
for (o, output) in asm.outputs.iter().zip(outputs.iter()) {
|
for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) {
|
||||||
if o.is_indirect {
|
if o.is_indirect {
|
||||||
// FIXME(eddyb) indirect inline asm outputs should
|
// FIXME(eddyb) indirect inline asm outputs should
|
||||||
// be encoeded through MIR place derefs instead.
|
// be encoded through MIR place derefs instead.
|
||||||
self.access_place(
|
self.access_place(
|
||||||
context,
|
context,
|
||||||
(output, o.span),
|
(output, o.span),
|
||||||
@ -558,7 +554,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (_, input) in inputs.iter() {
|
for (_, input) in asm.inputs.iter() {
|
||||||
self.consume_operand(context, (input, span), flow_state);
|
self.consume_operand(context, (input, span), flow_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,16 +92,12 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
|
|||||||
JustWrite,
|
JustWrite,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StatementKind::InlineAsm {
|
StatementKind::InlineAsm(ref asm) => {
|
||||||
ref asm,
|
|
||||||
ref outputs,
|
|
||||||
ref inputs,
|
|
||||||
} => {
|
|
||||||
let context = ContextKind::InlineAsm.new(location);
|
let context = ContextKind::InlineAsm.new(location);
|
||||||
for (o, output) in asm.outputs.iter().zip(outputs.iter()) {
|
for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) {
|
||||||
if o.is_indirect {
|
if o.is_indirect {
|
||||||
// FIXME(eddyb) indirect inline asm outputs should
|
// FIXME(eddyb) indirect inline asm outputs should
|
||||||
// be encoeded through MIR place derefs instead.
|
// be encoded through MIR place derefs instead.
|
||||||
self.access_place(
|
self.access_place(
|
||||||
context,
|
context,
|
||||||
output,
|
output,
|
||||||
@ -117,7 +113,7 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (_, input) in inputs.iter() {
|
for (_, input) in asm.inputs.iter() {
|
||||||
self.consume_operand(context, input);
|
self.consume_operand(context, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,11 +188,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
block,
|
block,
|
||||||
Statement {
|
Statement {
|
||||||
source_info,
|
source_info,
|
||||||
kind: StatementKind::InlineAsm {
|
kind: StatementKind::InlineAsm(box InlineAsm {
|
||||||
asm: box asm.clone(),
|
asm: asm.clone(),
|
||||||
outputs,
|
outputs,
|
||||||
inputs,
|
inputs,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
this.block_context.pop();
|
this.block_context.pop();
|
||||||
|
@ -288,8 +288,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> {
|
|||||||
self.kill_borrows_on_place(sets, &Place::Base(PlaceBase::Local(local)));
|
self.kill_borrows_on_place(sets, &Place::Base(PlaceBase::Local(local)));
|
||||||
}
|
}
|
||||||
|
|
||||||
mir::StatementKind::InlineAsm { ref outputs, ref asm, .. } => {
|
mir::StatementKind::InlineAsm(ref asm) => {
|
||||||
for (output, kind) in outputs.iter().zip(&asm.outputs) {
|
for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
|
||||||
if !kind.is_indirect && !kind.is_rw {
|
if !kind.is_indirect && !kind.is_rw {
|
||||||
self.kill_borrows_on_place(sets, output);
|
self.kill_borrows_on_place(sets, output);
|
||||||
}
|
}
|
||||||
|
@ -272,13 +272,13 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
|||||||
StatementKind::FakeRead(_, ref place) => {
|
StatementKind::FakeRead(_, ref place) => {
|
||||||
self.create_move_path(place);
|
self.create_move_path(place);
|
||||||
}
|
}
|
||||||
StatementKind::InlineAsm { ref outputs, ref inputs, ref asm } => {
|
StatementKind::InlineAsm(ref asm) => {
|
||||||
for (output, kind) in outputs.iter().zip(&asm.outputs) {
|
for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
|
||||||
if !kind.is_indirect {
|
if !kind.is_indirect {
|
||||||
self.gather_init(output, InitKind::Deep);
|
self.gather_init(output, InitKind::Deep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (_, input) in inputs.iter() {
|
for (_, input) in asm.inputs.iter() {
|
||||||
self.gather_operand(input);
|
self.gather_operand(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user