hir, mir: Separate HIR expressions / MIR operands from InlineAsm.

This commit is contained in:
Eduard Burtescu 2016-03-09 22:17:02 +02:00
parent 415d95fbeb
commit 856185dbb2
22 changed files with 176 additions and 209 deletions

View file

@ -354,19 +354,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
self.straightline(expr, pred, Some(&**e).into_iter())
}
hir::ExprInlineAsm(ref inline_asm) => {
let inputs = inline_asm.inputs.iter();
let outputs = inline_asm.outputs.iter();
let post_inputs = self.exprs(inputs.map(|a| {
debug!("cfg::construct InlineAsm id:{} input:{:?}", expr.id, a);
let &(_, ref expr) = a;
&**expr
}), pred);
let post_outputs = self.exprs(outputs.map(|a| {
debug!("cfg::construct InlineAsm id:{} output:{:?}", expr.id, a);
&*a.expr
}), post_inputs);
self.add_ast_node(expr.id, &[post_outputs])
hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
let post_outputs = self.exprs(outputs.iter().map(|e| &**e), pred);
let post_inputs = self.exprs(inputs.iter().map(|e| &**e), post_outputs);
self.add_ast_node(expr.id, &[post_inputs])
}
hir::ExprClosure(..) |

View file

@ -449,23 +449,20 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
}
}
hir::ExprInlineAsm(ref ia) => {
for &(_, ref input) in &ia.inputs {
self.consume_expr(&input);
}
for output in &ia.outputs {
if output.is_indirect {
self.consume_expr(&output.expr);
hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
for (o, output) in ia.outputs.iter().zip(outputs) {
if o.is_indirect {
self.consume_expr(output);
} else {
self.mutate_expr(expr, &output.expr,
if output.is_rw {
self.mutate_expr(expr, output,
if o.is_rw {
MutateMode::WriteAndRead
} else {
MutateMode::JustWrite
});
}
}
self.consume_exprs(inputs);
}
hir::ExprBreak(..) |

View file

@ -1170,25 +1170,21 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&e, succ)
}
hir::ExprInlineAsm(ref ia) => {
let succ = ia.outputs.iter().rev().fold(succ,
|succ, out| {
// see comment on lvalues
// in propagate_through_lvalue_components()
if out.is_indirect {
self.propagate_through_expr(&out.expr, succ)
} else {
let acc = if out.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
let succ = self.write_lvalue(&out.expr, succ, acc);
self.propagate_through_lvalue_components(&out.expr, succ)
}
hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
// see comment on lvalues
// in propagate_through_lvalue_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_lvalue(output, succ, acc);
self.propagate_through_lvalue_components(output, succ)
}
);
});
// Inputs are executed first. Propagate last because of rev order
ia.inputs.iter().rev().fold(succ, |succ, &(_, ref expr)| {
self.propagate_through_expr(&expr, succ)
})
self.propagate_through_exprs(inputs, succ)
}
hir::ExprLit(..) => {
@ -1425,17 +1421,17 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
intravisit::walk_expr(this, expr);
}
hir::ExprInlineAsm(ref ia) => {
for &(_, ref input) in &ia.inputs {
this.visit_expr(&input);
hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
for input in inputs {
this.visit_expr(input);
}
// Output operands must be lvalues
for out in &ia.outputs {
if !out.is_indirect {
this.check_lvalue(&out.expr);
for (o, output) in ia.outputs.iter().zip(outputs) {
if !o.is_indirect {
this.check_lvalue(output);
}
this.visit_expr(&out.expr);
this.visit_expr(output);
}
intravisit::walk_expr(this, expr);

View file

@ -680,7 +680,11 @@ pub enum Rvalue<'tcx> {
from_end: usize,
},
InlineAsm(InlineAsm),
InlineAsm {
asm: InlineAsm,
outputs: Vec<Lvalue<'tcx>>,
inputs: Vec<Operand<'tcx>>
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
@ -765,7 +769,9 @@ impl<'tcx> Debug for Rvalue<'tcx> {
BinaryOp(ref op, ref a, ref b) => write!(fmt, "{:?}({:?}, {:?})", op, a, b),
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
Box(ref t) => write!(fmt, "Box({:?})", t),
InlineAsm(ref asm) => write!(fmt, "InlineAsm({:?})", asm),
InlineAsm { ref asm, ref outputs, ref inputs } => {
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
}
Slice { ref input, from_start, from_end } =>
write!(fmt, "{:?}[{:?}..-{:?}]", input, from_start, from_end),

View file

@ -220,7 +220,7 @@ impl<'tcx> Mir<'tcx> {
}
}
Rvalue::Slice { .. } => None,
Rvalue::InlineAsm(..) => None
Rvalue::InlineAsm { .. } => None
}
}
}

View file

@ -261,7 +261,14 @@ macro_rules! make_mir_visitor {
});
}
Rvalue::InlineAsm(_) => {
Rvalue::InlineAsm { ref $($mutability)* outputs,
ref $($mutability)* inputs, .. } => {
for output in & $($mutability)* outputs[..] {
self.visit_lvalue(output, LvalueContext::Store);
}
for input in & $($mutability)* inputs[..] {
self.visit_operand(input);
}
}
}
}