From: Nicholas Nethercote Date: Tue, 2 Apr 2019 09:07:09 +0000 (+1100) Subject: Shrink `mir::Statement`. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=d00d639c54ae49a35c0c215cd8161af8c7d2e8ee;p=rust.git Shrink `mir::Statement`. The `InlineAsm` variant is extremely rare, and `mir::Statement` often contributes significantly to peak memory usage. --- diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a7ab0d6cb04..41cc118f70c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -4,7 +4,7 @@ use crate::hir::def::{CtorKind, Namespace}; 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::visit::MirVisitable; 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. #[cfg(target_arch = "x86_64")] -static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::>() == 56); +static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::>() == 48); impl<'tcx> Statement<'tcx> { /// 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. StorageDead(Local), - /// Executes a piece of inline Assembly. - InlineAsm { - asm: Box, - outputs: Box<[Place<'tcx>]>, - inputs: Box<[(Span, Operand<'tcx>)]>, - }, + /// Executes a piece of inline Assembly. Stored in a Box to keep the size + /// of `StatementKind` low. + InlineAsm(Box>), /// 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 @@ -1858,6 +1855,13 @@ pub enum FakeReadCause { 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> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { use self::StatementKind::*; @@ -1880,11 +1884,8 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { ref place, variant_index, } => write!(fmt, "discriminant({:?}) = {:?}", place, variant_index), - InlineAsm { - ref asm, - ref outputs, - ref inputs, - } => write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs), + InlineAsm(ref asm) => + write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs), AscribeUserType(ref place, ref variance, ref c_ty) => { write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty) } @@ -3140,13 +3141,21 @@ impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> { (StatementKind::SetDiscriminant) { place, variant_index }, (StatementKind::StorageLive)(a), (StatementKind::StorageDead)(a), - (StatementKind::InlineAsm) { asm, outputs, inputs }, + (StatementKind::InlineAsm)(a), (StatementKind::Retag)(kind, place), (StatementKind::AscribeUserType)(a, v, b), (StatementKind::Nop), } } +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for InlineAsm<'tcx> { + asm, + outputs, + inputs, + } +} + EnumTypeFoldableImpl! { impl<'tcx, T> TypeFoldable<'tcx> for ClearCrossCrate { (ClearCrossCrate::Clear), diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 4d44dc197cb..5a9a7de598e 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -391,15 +391,15 @@ fn super_statement(&mut self, location ); } - StatementKind::InlineAsm { outputs, inputs, asm: _ } => { - for output in & $($mutability)? outputs[..] { + StatementKind::InlineAsm(asm) => { + for output in & $($mutability)? asm.outputs[..] { self.visit_place( output, PlaceContext::MutatingUse(MutatingUseContext::AsmOutput), location ); } - for (span, input) in & $($mutability)? inputs[..] { + for (span, input) in & $($mutability)? asm.inputs[..] { self.visit_span(span); self.visit_operand(input, location); } diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 97729e8aeb3..618d05245d2 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -68,13 +68,13 @@ pub fn codegen_statement( } bx } - mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { - let outputs = outputs.iter().map(|output| { + mir::StatementKind::InlineAsm(ref asm) => { + let outputs = asm.outputs.iter().map(|output| { self.codegen_place(&mut bx, output) }).collect(); - let input_vals = inputs.iter() - .fold(Vec::with_capacity(inputs.len()), |mut acc, (span, input)| { + let input_vals = asm.inputs.iter() + .fold(Vec::with_capacity(asm.inputs.len()), |mut acc, (span, input)| { let op = self.codegen_operand(&mut bx, input); if let OperandValue::Immediate(_) = op.val { acc.push(op.immediate()); @@ -85,8 +85,8 @@ pub fn codegen_statement( acc }); - if input_vals.len() == inputs.len() { - let res = bx.codegen_inline_asm(asm, outputs, input_vals); + if input_vals.len() == asm.inputs.len() { + let res = bx.codegen_inline_asm(&asm.asm, outputs, input_vals); if !res { span_err!(bx.sess(), statement.source_info.span, E0668, "malformed inline assembly"); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 820a990c633..cc3c46ed6c1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -525,16 +525,12 @@ fn visit_statement_entry( flow_state, ); } - StatementKind::InlineAsm { - ref asm, - ref outputs, - ref inputs, - } => { + StatementKind::InlineAsm(ref asm) => { 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 { // FIXME(eddyb) indirect inline asm outputs should - // be encoeded through MIR place derefs instead. + // be encoded through MIR place derefs instead. self.access_place( context, (output, o.span), @@ -558,7 +554,7 @@ fn visit_statement_entry( ); } } - for (_, input) in inputs.iter() { + for (_, input) in asm.inputs.iter() { self.consume_operand(context, (input, span), flow_state); } } diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 9f51fb9e969..8217200b057 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -92,16 +92,12 @@ fn visit_statement( JustWrite, ); } - StatementKind::InlineAsm { - ref asm, - ref outputs, - ref inputs, - } => { + StatementKind::InlineAsm(ref asm) => { 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 { // FIXME(eddyb) indirect inline asm outputs should - // be encoeded through MIR place derefs instead. + // be encoded through MIR place derefs instead. self.access_place( context, output, @@ -117,7 +113,7 @@ fn visit_statement( ); } } - for (_, input) in inputs.iter() { + for (_, input) in asm.inputs.iter() { self.consume_operand(context, input); } } diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 9527a232795..b58914b017f 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -188,11 +188,11 @@ pub fn stmt_expr(&mut self, block, Statement { source_info, - kind: StatementKind::InlineAsm { - asm: box asm.clone(), + kind: StatementKind::InlineAsm(box InlineAsm { + asm: asm.clone(), outputs, inputs, - }, + }), }, ); this.block_context.pop(); diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index b47aff3a4f8..5a3105ed160 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -288,8 +288,8 @@ fn statement_effect(&self, sets: &mut BlockSets<'_, BorrowIndex>, location: Loca self.kill_borrows_on_place(sets, &Place::Base(PlaceBase::Local(local))); } - mir::StatementKind::InlineAsm { ref outputs, ref asm, .. } => { - for (output, kind) in outputs.iter().zip(&asm.outputs) { + mir::StatementKind::InlineAsm(ref asm) => { + for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { if !kind.is_indirect && !kind.is_rw { self.kill_borrows_on_place(sets, output); } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 71805fd02b8..cf17204e82e 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -272,13 +272,13 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) { StatementKind::FakeRead(_, ref place) => { self.create_move_path(place); } - StatementKind::InlineAsm { ref outputs, ref inputs, ref asm } => { - for (output, kind) in outputs.iter().zip(&asm.outputs) { + StatementKind::InlineAsm(ref asm) => { + for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) { if !kind.is_indirect { self.gather_init(output, InitKind::Deep); } } - for (_, input) in inputs.iter() { + for (_, input) in asm.inputs.iter() { self.gather_operand(input); } }