]> git.lizzy.rs Git - rust.git/commitdiff
Shrink `mir::Statement`.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 2 Apr 2019 09:07:09 +0000 (20:07 +1100)
committerNicholas Nethercote <nnethercote@mozilla.com>
Tue, 2 Apr 2019 22:09:59 +0000 (09:09 +1100)
The `InlineAsm` variant is extremely rare, and `mir::Statement` often
contributes significantly to peak memory usage.

src/librustc/mir/mod.rs
src/librustc/mir/visit.rs
src/librustc_codegen_ssa/mir/statement.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll/invalidation.rs
src/librustc_mir/build/expr/stmt.rs
src/librustc_mir/dataflow/impls/borrows.rs
src/librustc_mir/dataflow/move_paths/builder.rs

index a7ab0d6cb0408cca715fdcccf166a8496abcf575..41cc118f70c5867d9f72d4344e24878c82ef97da 100644 (file)
@@ -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::<Statement<'_>>() == 56);
+static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Statement<'_>>() == 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<InlineAsm>,
-        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<InlineAsm<'tcx>>),
 
     /// 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<T> {
         (ClearCrossCrate::Clear),
index 4d44dc197cb783e7eb698126382a930d997a5d26..5a9a7de598e95abfead0062581648c0677191553 100644 (file)
@@ -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);
                         }
index 97729e8aeb35fce44b4e627120dcdcc16be7a1e5..618d05245d2caddfa38c2d199c91125eb4414cc3 100644 (file)
@@ -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");
index 820a990c633e04f5f78dce181fe61fd45649c0ce..cc3c46ed6c17add61e29e5dd70585a651a380b72 100644 (file)
@@ -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);
                 }
             }
index 9f51fb9e969c30c7e1b667fb26c36ee1b9dbd990..8217200b05788f96707a0a24008fe42265a33cfb 100644 (file)
@@ -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);
                 }
             }
index 9527a23279570a060ec8fe07c23998b993f9fb9f..b58914b017fd4601f4a677772ed2fa9d93c0ac17 100644 (file)
@@ -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();
index b47aff3a4f8557ea19bd6174bcf53ff83193fcf0..5a3105ed160492b1751b7d2ecda94e1d1a01bcc5 100644 (file)
@@ -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);
                     }
index 71805fd02b85714e650ced49e7e590a363c91996..cf17204e82e3426d8828543da7789e479f3fea25 100644 (file)
@@ -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);
                 }
             }