hir, mir: Separate HIR expressions / MIR operands from InlineAsm.
This commit is contained in:
parent
415d95fbeb
commit
856185dbb2
22 changed files with 176 additions and 209 deletions
|
|
@ -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(..) |
|
||||
|
|
|
|||
|
|
@ -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(..) |
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ impl<'tcx> Mir<'tcx> {
|
|||
}
|
||||
}
|
||||
Rvalue::Slice { .. } => None,
|
||||
Rvalue::InlineAsm(..) => None
|
||||
Rvalue::InlineAsm { .. } => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue