From 5d65e8cc7aec3cdcd99367c58367a16c99a8ae22 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 7 Feb 2019 16:03:57 +1100 Subject: [PATCH] Reduce the size of `hir::Expr`. From 104 bytes to 72 bytes on x86-64. This slightly reduces instruction counts. Also add an assertion about the size. --- src/librustc/hir/lowering.rs | 10 +++++----- src/librustc/hir/mod.rs | 8 ++++++-- src/librustc_save_analysis/lib.rs | 9 +++++++-- src/librustc_typeck/check/demand.rs | 6 +++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index cc5b105bad0d4..84487c40f8745 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3859,7 +3859,7 @@ impl<'a> LoweringContext<'a> { hir::ExprKind::Call(f, args.iter().map(|x| self.lower_expr(x)).collect()) } ExprKind::MethodCall(ref seg, ref args) => { - let hir_seg = self.lower_path_segment( + let hir_seg = P(self.lower_path_segment( e.span, seg, ParamMode::Optional, @@ -3867,7 +3867,7 @@ impl<'a> LoweringContext<'a> { ParenthesizedGenericArgs::Err, ImplTraitContext::disallowed(), None, - ); + )); let args = args.iter().map(|x| self.lower_expr(x)).collect(); hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args) } @@ -4148,7 +4148,7 @@ impl<'a> LoweringContext<'a> { node: if is_unit { hir::ExprKind::Path(struct_path) } else { - hir::ExprKind::Struct(struct_path, fields, None) + hir::ExprKind::Struct(P(struct_path), fields, None) }, span: e.span, attrs: e.attrs.clone(), @@ -4220,13 +4220,13 @@ impl<'a> LoweringContext<'a> { hir::ExprKind::InlineAsm(P(hir_asm), outputs, inputs) } ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprKind::Struct( - self.lower_qpath( + P(self.lower_qpath( e.id, &None, path, ParamMode::Optional, ImplTraitContext::disallowed(), - ), + )), fields.iter().map(|x| self.lower_field(x)).collect(), maybe_expr.as_ref().map(|x| P(self.lower_expr(x))), ), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index bf16ec0be83e7..e389b918d3c35 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1319,6 +1319,10 @@ pub struct Expr { pub hir_id: HirId, } +// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::() == 72); + impl Expr { pub fn precedence(&self) -> ExprPrecedence { match self.node { @@ -1438,7 +1442,7 @@ pub enum ExprKind { /// and the remaining elements are the rest of the arguments. /// Thus, `x.foo::(a, b, c, d)` is represented as /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. - MethodCall(PathSegment, Span, HirVec), + MethodCall(P, Span, HirVec), /// A tuple (e.g., `(a, b, c ,d)`). Tup(HirVec), /// A binary operation (e.g., `a + b`, `a * b`). @@ -1506,7 +1510,7 @@ pub enum ExprKind { /// /// For example, `Foo {x: 1, y: 2}`, or /// `Foo {x: 1, .. base}`, where `base` is the `Option`. - Struct(QPath, HirVec, Option>), + Struct(P, HirVec, Option>), /// An array literal constructed from one repeated element. /// diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 8d20c44a5a4ef..8ab9a8e8dda86 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -614,11 +614,16 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Some(def) if def != HirDef::Err => def, _ => self.get_path_def(self.tcx.hir().get_parent_node(id)), } - }, + } + Node::Expr(&hir::Expr { node: hir::ExprKind::Struct(ref qpath, ..), .. - }) | + }) => { + let hir_id = self.tcx.hir().node_to_hir_id(id); + self.tables.qpath_def(qpath, hir_id) + } + Node::Expr(&hir::Expr { node: hir::ExprKind::Path(ref qpath), .. diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 33e93b582e540..f6a0fd5caccdb 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -430,7 +430,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match expr.node { // All built-in range literals but `..=` and `..` desugar to Structs - ExprKind::Struct(QPath::Resolved(None, ref path), _, _) | + ExprKind::Struct(ref qpath, _, _) => { + if let QPath::Resolved(None, ref path) = **qpath { + return is_range_path(&path) && span_is_range_literal(&expr.span); + } + } // `..` desugars to its struct path ExprKind::Path(QPath::Resolved(None, ref path)) => { return is_range_path(&path) && span_is_range_literal(&expr.span);