Rollup merge of #66515 - Centril:cheaper-inline-asm, r=oli-obk
Reduce size of `hir::Expr` by boxing more of `hir::InlineAsm` r? @oli-obk
This commit is contained in:
commit
d7bb37d663
@ -1086,10 +1086,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
||||
ExprKind::Ret(ref optional_expression) => {
|
||||
walk_list!(visitor, visit_expr, optional_expression);
|
||||
}
|
||||
ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
|
||||
for expr in outputs.iter().chain(inputs.iter()) {
|
||||
visitor.visit_expr(expr)
|
||||
}
|
||||
ExprKind::InlineAsm(ref asm) => {
|
||||
walk_list!(visitor, visit_expr, &asm.outputs_exprs);
|
||||
walk_list!(visitor, visit_expr, &asm.inputs_exprs);
|
||||
}
|
||||
ExprKind::Yield(ref subexpression, _) => {
|
||||
visitor.visit_expr(subexpression);
|
||||
|
@ -966,7 +966,7 @@ impl LoweringContext<'_> {
|
||||
}
|
||||
|
||||
fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind {
|
||||
let hir_asm = hir::InlineAsm {
|
||||
let inner = hir::InlineAsmInner {
|
||||
inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
|
||||
outputs: asm.outputs
|
||||
.iter()
|
||||
@ -984,18 +984,18 @@ impl LoweringContext<'_> {
|
||||
alignstack: asm.alignstack,
|
||||
dialect: asm.dialect,
|
||||
};
|
||||
|
||||
let outputs = asm.outputs
|
||||
.iter()
|
||||
.map(|out| self.lower_expr(&out.expr))
|
||||
.collect();
|
||||
|
||||
let inputs = asm.inputs
|
||||
.iter()
|
||||
.map(|&(_, ref input)| self.lower_expr(input))
|
||||
.collect();
|
||||
|
||||
hir::ExprKind::InlineAsm(P(hir_asm), outputs, inputs)
|
||||
let hir_asm = hir::InlineAsm {
|
||||
inner,
|
||||
inputs_exprs: asm.inputs
|
||||
.iter()
|
||||
.map(|&(_, ref input)| self.lower_expr(input))
|
||||
.collect(),
|
||||
outputs_exprs: asm.outputs
|
||||
.iter()
|
||||
.map(|out| self.lower_expr(&out.expr))
|
||||
.collect(),
|
||||
};
|
||||
hir::ExprKind::InlineAsm(P(hir_asm))
|
||||
}
|
||||
|
||||
fn lower_field(&mut self, f: &Field) -> hir::Field {
|
||||
|
@ -1457,7 +1457,7 @@ pub struct Expr {
|
||||
|
||||
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(Expr, 72);
|
||||
static_assert_size!(Expr, 64);
|
||||
|
||||
impl Expr {
|
||||
pub fn precedence(&self) -> ExprPrecedence {
|
||||
@ -1656,7 +1656,7 @@ pub enum ExprKind {
|
||||
Ret(Option<P<Expr>>),
|
||||
|
||||
/// Inline assembly (from `asm!`), with its outputs and inputs.
|
||||
InlineAsm(P<InlineAsm>, HirVec<Expr>, HirVec<Expr>),
|
||||
InlineAsm(P<InlineAsm>),
|
||||
|
||||
/// A struct or struct-like variant literal expression.
|
||||
///
|
||||
@ -2063,7 +2063,7 @@ pub struct InlineAsmOutput {
|
||||
// NOTE(eddyb) This is used within MIR as well, so unlike the rest of the HIR,
|
||||
// it needs to be `Clone` and use plain `Vec<T>` instead of `HirVec<T>`.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub struct InlineAsm {
|
||||
pub struct InlineAsmInner {
|
||||
pub asm: Symbol,
|
||||
pub asm_str_style: StrStyle,
|
||||
pub outputs: Vec<InlineAsmOutput>,
|
||||
@ -2074,6 +2074,13 @@ pub struct InlineAsm {
|
||||
pub dialect: AsmDialect,
|
||||
}
|
||||
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub struct InlineAsm {
|
||||
pub inner: InlineAsmInner,
|
||||
pub outputs_exprs: HirVec<Expr>,
|
||||
pub inputs_exprs: HirVec<Expr>,
|
||||
}
|
||||
|
||||
/// Represents a parameter in a function header.
|
||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
|
||||
pub struct Param {
|
||||
|
@ -1365,14 +1365,15 @@ impl<'a> State<'a> {
|
||||
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::InlineAsm(ref a, ref outputs, ref inputs) => {
|
||||
hir::ExprKind::InlineAsm(ref a) => {
|
||||
let i = &a.inner;
|
||||
self.s.word("asm!");
|
||||
self.popen();
|
||||
self.print_string(&a.asm.as_str(), a.asm_str_style);
|
||||
self.print_string(&i.asm.as_str(), i.asm_str_style);
|
||||
self.word_space(":");
|
||||
|
||||
let mut out_idx = 0;
|
||||
self.commasep(Inconsistent, &a.outputs, |s, out| {
|
||||
self.commasep(Inconsistent, &i.outputs, |s, out| {
|
||||
let constraint = out.constraint.as_str();
|
||||
let mut ch = constraint.chars();
|
||||
match ch.next() {
|
||||
@ -1383,7 +1384,7 @@ impl<'a> State<'a> {
|
||||
_ => s.print_string(&constraint, ast::StrStyle::Cooked),
|
||||
}
|
||||
s.popen();
|
||||
s.print_expr(&outputs[out_idx]);
|
||||
s.print_expr(&a.outputs_exprs[out_idx]);
|
||||
s.pclose();
|
||||
out_idx += 1;
|
||||
});
|
||||
@ -1391,28 +1392,28 @@ impl<'a> State<'a> {
|
||||
self.word_space(":");
|
||||
|
||||
let mut in_idx = 0;
|
||||
self.commasep(Inconsistent, &a.inputs, |s, co| {
|
||||
self.commasep(Inconsistent, &i.inputs, |s, co| {
|
||||
s.print_string(&co.as_str(), ast::StrStyle::Cooked);
|
||||
s.popen();
|
||||
s.print_expr(&inputs[in_idx]);
|
||||
s.print_expr(&a.inputs_exprs[in_idx]);
|
||||
s.pclose();
|
||||
in_idx += 1;
|
||||
});
|
||||
self.s.space();
|
||||
self.word_space(":");
|
||||
|
||||
self.commasep(Inconsistent, &a.clobbers, |s, co| {
|
||||
self.commasep(Inconsistent, &i.clobbers, |s, co| {
|
||||
s.print_string(&co.as_str(), ast::StrStyle::Cooked);
|
||||
});
|
||||
|
||||
let mut options = vec![];
|
||||
if a.volatile {
|
||||
if i.volatile {
|
||||
options.push("volatile");
|
||||
}
|
||||
if a.alignstack {
|
||||
if i.alignstack {
|
||||
options.push("alignstack");
|
||||
}
|
||||
if a.dialect == ast::AsmDialect::Intel {
|
||||
if i.dialect == ast::AsmDialect::Intel {
|
||||
options.push("intel");
|
||||
}
|
||||
|
||||
|
@ -283,15 +283,15 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
self.borrow_expr(&base, bk);
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
|
||||
for (o, output) in ia.outputs.iter().zip(outputs) {
|
||||
hir::ExprKind::InlineAsm(ref ia) => {
|
||||
for (o, output) in ia.inner.outputs.iter().zip(&ia.outputs_exprs) {
|
||||
if o.is_indirect {
|
||||
self.consume_expr(output);
|
||||
} else {
|
||||
self.mutate_expr(output);
|
||||
}
|
||||
}
|
||||
self.consume_exprs(inputs);
|
||||
self.consume_exprs(&ia.inputs_exprs);
|
||||
}
|
||||
|
||||
hir::ExprKind::Continue(..) |
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
use crate::hir::def::{CtorKind, Namespace};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::hir::{self, InlineAsm as HirInlineAsm};
|
||||
use crate::hir;
|
||||
use crate::mir::interpret::{PanicInfo, Scalar};
|
||||
use crate::mir::visit::MirVisitable;
|
||||
use crate::ty::adjustment::PointerCast;
|
||||
@ -1638,7 +1638,7 @@ pub enum FakeReadCause {
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||
pub struct InlineAsm<'tcx> {
|
||||
pub asm: HirInlineAsm,
|
||||
pub asm: hir::InlineAsmInner,
|
||||
pub outputs: Box<[Place<'tcx>]>,
|
||||
pub inputs: Box<[(Span, Operand<'tcx>)]>,
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ CloneTypeFoldableAndLiftImpls! {
|
||||
::syntax_pos::symbol::Symbol,
|
||||
crate::hir::def::Res,
|
||||
crate::hir::def_id::DefId,
|
||||
crate::hir::InlineAsm,
|
||||
crate::hir::InlineAsmInner,
|
||||
crate::hir::MatchSource,
|
||||
crate::hir::Mutability,
|
||||
crate::hir::Unsafety,
|
||||
|
@ -17,7 +17,7 @@ use libc::{c_uint, c_char};
|
||||
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
fn codegen_inline_asm(
|
||||
&mut self,
|
||||
ia: &hir::InlineAsm,
|
||||
ia: &hir::InlineAsmInner,
|
||||
outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
|
||||
mut inputs: Vec<&'ll Value>,
|
||||
span: Span,
|
||||
|
@ -1,13 +1,13 @@
|
||||
use super::BackendTypes;
|
||||
use crate::mir::place::PlaceRef;
|
||||
use rustc::hir::{GlobalAsm, InlineAsm};
|
||||
use rustc::hir::{GlobalAsm, InlineAsmInner};
|
||||
use syntax_pos::Span;
|
||||
|
||||
pub trait AsmBuilderMethods<'tcx>: BackendTypes {
|
||||
/// Take an inline assembly expression and splat it out via LLVM
|
||||
fn codegen_inline_asm(
|
||||
&mut self,
|
||||
ia: &InlineAsm,
|
||||
ia: &InlineAsmInner,
|
||||
outputs: Vec<PlaceRef<'tcx, Self::Value>>,
|
||||
inputs: Vec<Self::Value>,
|
||||
span: Span,
|
||||
|
@ -533,11 +533,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
|
||||
convert_path_expr(cx, expr, res)
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref asm, ref outputs, ref inputs) => {
|
||||
hir::ExprKind::InlineAsm(ref asm) => {
|
||||
ExprKind::InlineAsm {
|
||||
asm,
|
||||
outputs: outputs.to_ref(),
|
||||
inputs: inputs.to_ref(),
|
||||
asm: &asm.inner,
|
||||
outputs: asm.outputs_exprs.to_ref(),
|
||||
inputs: asm.inputs_exprs.to_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,10 @@ pub enum StmtKind<'tcx> {
|
||||
},
|
||||
}
|
||||
|
||||
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
rustc_data_structures::static_assert_size!(Expr<'_>, 168);
|
||||
|
||||
/// The Hair trait implementor lowers their expressions (`&'tcx H::Expr`)
|
||||
/// into instances of this `Expr` enum. This lowering can be done
|
||||
/// basically as lazily or as eagerly as desired: every recursive
|
||||
@ -264,7 +268,7 @@ pub enum ExprKind<'tcx> {
|
||||
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
|
||||
},
|
||||
InlineAsm {
|
||||
asm: &'tcx hir::InlineAsm,
|
||||
asm: &'tcx hir::InlineAsmInner,
|
||||
outputs: Vec<ExprRef<'tcx>>,
|
||||
inputs: Vec<ExprRef<'tcx>>
|
||||
},
|
||||
|
@ -1184,17 +1184,21 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
self.propagate_through_expr(&e, succ)
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
|
||||
hir::ExprKind::InlineAsm(ref asm) => {
|
||||
let ia = &asm.inner;
|
||||
let outputs = &asm.outputs_exprs;
|
||||
let inputs = &asm.inputs_exprs;
|
||||
let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
|
||||
// see comment on places
|
||||
// in propagate_through_place_components()
|
||||
if o.is_indirect {
|
||||
self.propagate_through_expr(output, succ)
|
||||
} else {
|
||||
let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
|
||||
let succ = self.write_place(output, succ, acc);
|
||||
self.propagate_through_place_components(output, succ)
|
||||
}});
|
||||
// see comment on places
|
||||
// in propagate_through_place_components()
|
||||
if o.is_indirect {
|
||||
self.propagate_through_expr(output, succ)
|
||||
} else {
|
||||
let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
|
||||
let succ = self.write_place(output, succ, acc);
|
||||
self.propagate_through_place_components(output, succ)
|
||||
}
|
||||
});
|
||||
|
||||
// Inputs are executed first. Propagate last because of rev order
|
||||
self.propagate_through_exprs(inputs, succ)
|
||||
@ -1395,13 +1399,13 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr) {
|
||||
}
|
||||
}
|
||||
|
||||
hir::ExprKind::InlineAsm(ref ia, ref outputs, ref inputs) => {
|
||||
for input in inputs {
|
||||
hir::ExprKind::InlineAsm(ref asm) => {
|
||||
for input in &asm.inputs_exprs {
|
||||
this.visit_expr(input);
|
||||
}
|
||||
|
||||
// Output operands must be places
|
||||
for (o, output) in ia.outputs.iter().zip(outputs) {
|
||||
for (o, output) in asm.inner.outputs.iter().zip(&asm.outputs_exprs) {
|
||||
if !o.is_indirect {
|
||||
this.check_place(output);
|
||||
}
|
||||
|
@ -244,8 +244,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ExprKind::Path(ref qpath) => {
|
||||
self.check_expr_path(qpath, expr)
|
||||
}
|
||||
ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
|
||||
for expr in outputs.iter().chain(inputs.iter()) {
|
||||
ExprKind::InlineAsm(ref asm) => {
|
||||
for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) {
|
||||
self.check_expr(expr);
|
||||
}
|
||||
tcx.mk_unit()
|
||||
|
Loading…
x
Reference in New Issue
Block a user