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};
// `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
/// 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
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::*;
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)
}
(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),
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);
}
}
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());
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");
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),
);
}
}
- for (_, input) in inputs.iter() {
+ for (_, input) in asm.inputs.iter() {
self.consume_operand(context, (input, span), flow_state);
}
}
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,
);
}
}
- for (_, input) in inputs.iter() {
+ for (_, input) in asm.inputs.iter() {
self.consume_operand(context, input);
}
}
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();
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);
}
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);
}
}