Skip to content

Commit

Permalink
hir, mir: Separate HIR expressions / MIR operands from InlineAsm.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Mar 10, 2016
1 parent 6aeb54f commit b3747a5
Show file tree
Hide file tree
Showing 22 changed files with 176 additions and 209 deletions.
17 changes: 4 additions & 13 deletions src/librustc/middle/cfg/construct.rs
Expand Up @@ -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(..) |
Expand Down
17 changes: 7 additions & 10 deletions src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -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(..) |
Expand Down
44 changes: 20 additions & 24 deletions src/librustc/middle/liveness.rs
Expand Up @@ -1168,25 +1168,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(..) => {
Expand Down Expand Up @@ -1423,17 +1419,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);
Expand Down
10 changes: 8 additions & 2 deletions src/librustc/mir/repr.rs
Expand Up @@ -678,7 +678,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)]
Expand Down Expand Up @@ -763,7 +767,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),

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/tcx.rs
Expand Up @@ -223,7 +223,7 @@ impl<'tcx> Mir<'tcx> {
}
}
Rvalue::Slice { .. } => None,
Rvalue::InlineAsm(..) => None
Rvalue::InlineAsm { .. } => None
}
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/librustc/mir/visit.rs
Expand Up @@ -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);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/svh.rs
Expand Up @@ -279,7 +279,7 @@ mod svh_visitor {
ExprBreak(id) => SawExprBreak(id.map(|id| id.node.name.as_str())),
ExprAgain(id) => SawExprAgain(id.map(|id| id.node.name.as_str())),
ExprRet(..) => SawExprRet,
ExprInlineAsm(ref asm) => SawExprInlineAsm(asm),
ExprInlineAsm(ref a,_,_) => SawExprInlineAsm(a),
ExprStruct(..) => SawExprStruct,
ExprRepeat(..) => SawExprRepeat,
}
Expand Down
33 changes: 5 additions & 28 deletions src/librustc_front/fold.rs
Expand Up @@ -1106,34 +1106,11 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
respan(folder.new_span(label.span), folder.fold_ident(label.node))
})),
ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
ExprInlineAsm(InlineAsm {
inputs,
outputs,
asm,
asm_str_style,
clobbers,
volatile,
alignstack,
dialect,
expn_id,
}) => ExprInlineAsm(InlineAsm {
inputs: inputs.move_map(|(c, input)| (c, folder.fold_expr(input))),
outputs: outputs.move_map(|out| {
InlineAsmOutput {
constraint: out.constraint,
expr: folder.fold_expr(out.expr),
is_rw: out.is_rw,
is_indirect: out.is_indirect,
}
}),
asm: asm,
asm_str_style: asm_str_style,
clobbers: clobbers,
volatile: volatile,
alignstack: alignstack,
dialect: dialect,
expn_id: expn_id,
}),
ExprInlineAsm(asm, outputs, inputs) => {

This comment has been minimized.

Copy link
@nikomatsakis

nikomatsakis Mar 15, 2016

omg so much better

ExprInlineAsm(asm,
outputs.move_map(|x| folder.fold_expr(x)),
inputs.move_map(|x| folder.fold_expr(x)))
}
ExprStruct(path, fields, maybe_expr) => {
ExprStruct(folder.fold_path(path),
fields.move_map(|x| folder.fold_field(x)),
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_front/hir.rs
Expand Up @@ -793,8 +793,8 @@ pub enum Expr_ {
/// A `return`, with an optional value to be returned
ExprRet(Option<P<Expr>>),

/// Output of the `asm!()` macro
ExprInlineAsm(InlineAsm),
/// Inline assembly (from `asm!`), with its outputs and inputs.
ExprInlineAsm(InlineAsm, Vec<P<Expr>>, Vec<P<Expr>>),

/// A struct literal expression.
///
Expand Down Expand Up @@ -977,7 +977,6 @@ pub enum Ty_ {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct InlineAsmOutput {
pub constraint: InternedString,
pub expr: P<Expr>,
pub is_rw: bool,
pub is_indirect: bool,
}
Expand All @@ -987,7 +986,7 @@ pub struct InlineAsm {
pub asm: InternedString,
pub asm_str_style: StrStyle,
pub outputs: HirVec<InlineAsmOutput>,
pub inputs: HirVec<(InternedString, P<Expr>)>,
pub inputs: HirVec<InternedString>,
pub clobbers: HirVec<InternedString>,
pub volatile: bool,
pub alignstack: bool,
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_front/intravisit.rs
Expand Up @@ -798,12 +798,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
ExprRet(ref optional_expression) => {
walk_list!(visitor, visit_expr, optional_expression);
}
ExprInlineAsm(ref ia) => {
for &(_, ref input) in &ia.inputs {
visitor.visit_expr(&input)
ExprInlineAsm(_, ref outputs, ref inputs) => {
for output in outputs {
visitor.visit_expr(output)
}
for output in &ia.outputs {
visitor.visit_expr(&output.expr)
for input in inputs {
visitor.visit_expr(input)
}
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/librustc_front/lowering.rs
Expand Up @@ -1319,14 +1319,11 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
dialect,
expn_id,
}) => hir::ExprInlineAsm(hir::InlineAsm {
inputs: inputs.iter()
.map(|&(ref c, ref input)| (c.clone(), lower_expr(lctx, input)))
.collect(),
inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
outputs: outputs.iter()
.map(|out| {
hir::InlineAsmOutput {
constraint: out.constraint.clone(),
expr: lower_expr(lctx, &out.expr),
is_rw: out.is_rw,
is_indirect: out.is_indirect,
}
Expand All @@ -1339,7 +1336,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
alignstack: alignstack,
dialect: dialect,
expn_id: expn_id,
}),
}, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(),
inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()),
ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
hir::ExprStruct(lower_path(lctx, path),
fields.iter().map(|x| lower_field(lctx, x)).collect(),
Expand Down
12 changes: 8 additions & 4 deletions src/librustc_front/print/pprust.rs
Expand Up @@ -1481,12 +1481,13 @@ impl<'a> State<'a> {
_ => (),
}
}
hir::ExprInlineAsm(ref a) => {
hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => {
try!(word(&mut self.s, "asm!"));
try!(self.popen());
try!(self.print_string(&a.asm, a.asm_str_style));
try!(self.word_space(":"));

let mut out_idx = 0;
try!(self.commasep(Inconsistent, &a.outputs, |s, out| {
match out.constraint.slice_shift_char() {
Some(('=', operand)) if out.is_rw => {
Expand All @@ -1495,18 +1496,21 @@ impl<'a> State<'a> {
_ => try!(s.print_string(&out.constraint, ast::StrStyle::Cooked)),
}
try!(s.popen());
try!(s.print_expr(&out.expr));
try!(s.print_expr(&outputs[out_idx]));
try!(s.pclose());
out_idx += 1;
Ok(())
}));
try!(space(&mut self.s));
try!(self.word_space(":"));

try!(self.commasep(Inconsistent, &a.inputs, |s, &(ref co, ref o)| {
let mut in_idx = 0;
try!(self.commasep(Inconsistent, &a.inputs, |s, co| {
try!(s.print_string(&co, ast::StrStyle::Cooked));
try!(s.popen());
try!(s.print_expr(&o));
try!(s.print_expr(&inputs[in_idx]));
try!(s.pclose());
in_idx += 1;
Ok(())
}));
try!(space(&mut self.s));
Expand Down
16 changes: 14 additions & 2 deletions src/librustc_mir/build/expr/as_rvalue.rs
Expand Up @@ -39,8 +39,20 @@ impl<'a,'tcx> Builder<'a,'tcx> {
ExprKind::Scope { extent, value } => {
this.in_scope(extent, block, |this| this.as_rvalue(block, value))
}
ExprKind::InlineAsm { asm } => {
block.and(Rvalue::InlineAsm(asm.clone()))
ExprKind::InlineAsm { asm, outputs, inputs } => {
let outputs = outputs.into_iter().map(|output| {
unpack!(block = this.as_lvalue(block, output))
}).collect();

let inputs = inputs.into_iter().map(|input| {
unpack!(block = this.as_operand(block, input))
}).collect();

block.and(Rvalue::InlineAsm {
asm: asm.clone(),
outputs: outputs,
inputs: inputs
})
}
ExprKind::Repeat { value, count } => {
let value_operand = unpack!(block = this.as_operand(block, value));
Expand Down
8 changes: 6 additions & 2 deletions src/librustc_mir/hair/cx/expr.rs
Expand Up @@ -327,8 +327,12 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
convert_path_expr(cx, self)
}

hir::ExprInlineAsm(ref asm) => {
ExprKind::InlineAsm { asm: asm }
hir::ExprInlineAsm(ref asm, ref outputs, ref inputs) => {
ExprKind::InlineAsm {
asm: asm,
outputs: outputs.to_ref(),
inputs: inputs.to_ref()
}
}

// Now comes the rote stuff:
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_mir/hair/mod.rs
Expand Up @@ -230,6 +230,8 @@ pub enum ExprKind<'tcx> {
},
InlineAsm {
asm: &'tcx hir::InlineAsm,
outputs: Vec<ExprRef<'tcx>>,
inputs: Vec<ExprRef<'tcx>>
},
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/erase_regions.rs
Expand Up @@ -87,7 +87,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
Rvalue::BinaryOp(_, _, _) |
Rvalue::UnaryOp(_, _) |
Rvalue::Slice { input: _, from_start: _, from_end: _ } |
Rvalue::InlineAsm(_) => {},
Rvalue::InlineAsm {..} => {},

Rvalue::Repeat(_, ref mut value) => value.ty = self.tcx.erase_regions(&value.ty),
Rvalue::Ref(ref mut region, _, _) => *region = ty::ReStatic,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_passes/consts.rs
Expand Up @@ -750,7 +750,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
// Expressions with side-effects.
hir::ExprAssign(..) |
hir::ExprAssignOp(..) |
hir::ExprInlineAsm(_) => {
hir::ExprInlineAsm(..) => {
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
span_err!(v.tcx.sess, e.span, E0019,
Expand Down

1 comment on commit b3747a5

@nikomatsakis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

Please sign in to comment.