Skip to content

Commit b3747a5

Browse files
committed
hir, mir: Separate HIR expressions / MIR operands from InlineAsm.
1 parent 6aeb54f commit b3747a5

File tree

22 files changed

+176
-209
lines changed

22 files changed

+176
-209
lines changed

src/librustc/middle/cfg/construct.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,19 +354,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
354354
self.straightline(expr, pred, Some(&**e).into_iter())
355355
}
356356

357-
hir::ExprInlineAsm(ref inline_asm) => {
358-
let inputs = inline_asm.inputs.iter();
359-
let outputs = inline_asm.outputs.iter();
360-
let post_inputs = self.exprs(inputs.map(|a| {
361-
debug!("cfg::construct InlineAsm id:{} input:{:?}", expr.id, a);
362-
let &(_, ref expr) = a;
363-
&**expr
364-
}), pred);
365-
let post_outputs = self.exprs(outputs.map(|a| {
366-
debug!("cfg::construct InlineAsm id:{} output:{:?}", expr.id, a);
367-
&*a.expr
368-
}), post_inputs);
369-
self.add_ast_node(expr.id, &[post_outputs])
357+
hir::ExprInlineAsm(_, ref outputs, ref inputs) => {
358+
let post_outputs = self.exprs(outputs.iter().map(|e| &**e), pred);
359+
let post_inputs = self.exprs(inputs.iter().map(|e| &**e), post_outputs);
360+
self.add_ast_node(expr.id, &[post_inputs])
370361
}
371362

372363
hir::ExprClosure(..) |

src/librustc/middle/expr_use_visitor.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -449,23 +449,20 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
449449
}
450450
}
451451

452-
hir::ExprInlineAsm(ref ia) => {
453-
for &(_, ref input) in &ia.inputs {
454-
self.consume_expr(&input);
455-
}
456-
457-
for output in &ia.outputs {
458-
if output.is_indirect {
459-
self.consume_expr(&output.expr);
452+
hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
453+
for (o, output) in ia.outputs.iter().zip(outputs) {
454+
if o.is_indirect {
455+
self.consume_expr(output);
460456
} else {
461-
self.mutate_expr(expr, &output.expr,
462-
if output.is_rw {
457+
self.mutate_expr(expr, output,
458+
if o.is_rw {
463459
MutateMode::WriteAndRead
464460
} else {
465461
MutateMode::JustWrite
466462
});
467463
}
468464
}
465+
self.consume_exprs(inputs);
469466
}
470467

471468
hir::ExprBreak(..) |

src/librustc/middle/liveness.rs

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,25 +1168,21 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11681168
self.propagate_through_expr(&e, succ)
11691169
}
11701170

1171-
hir::ExprInlineAsm(ref ia) => {
1172-
1173-
let succ = ia.outputs.iter().rev().fold(succ,
1174-
|succ, out| {
1175-
// see comment on lvalues
1176-
// in propagate_through_lvalue_components()
1177-
if out.is_indirect {
1178-
self.propagate_through_expr(&out.expr, succ)
1179-
} else {
1180-
let acc = if out.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
1181-
let succ = self.write_lvalue(&out.expr, succ, acc);
1182-
self.propagate_through_lvalue_components(&out.expr, succ)
1183-
}
1171+
hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
1172+
let succ = ia.outputs.iter().zip(outputs).rev().fold(succ, |succ, (o, output)| {
1173+
// see comment on lvalues
1174+
// in propagate_through_lvalue_components()
1175+
if o.is_indirect {
1176+
self.propagate_through_expr(output, succ)
1177+
} else {
1178+
let acc = if o.is_rw { ACC_WRITE|ACC_READ } else { ACC_WRITE };
1179+
let succ = self.write_lvalue(output, succ, acc);
1180+
self.propagate_through_lvalue_components(output, succ)
11841181
}
1185-
);
1182+
});
1183+
11861184
// Inputs are executed first. Propagate last because of rev order
1187-
ia.inputs.iter().rev().fold(succ, |succ, &(_, ref expr)| {
1188-
self.propagate_through_expr(&expr, succ)
1189-
})
1185+
self.propagate_through_exprs(inputs, succ)
11901186
}
11911187

11921188
hir::ExprLit(..) => {
@@ -1423,17 +1419,17 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
14231419
intravisit::walk_expr(this, expr);
14241420
}
14251421

1426-
hir::ExprInlineAsm(ref ia) => {
1427-
for &(_, ref input) in &ia.inputs {
1428-
this.visit_expr(&input);
1422+
hir::ExprInlineAsm(ref ia, ref outputs, ref inputs) => {
1423+
for input in inputs {
1424+
this.visit_expr(input);
14291425
}
14301426

14311427
// Output operands must be lvalues
1432-
for out in &ia.outputs {
1433-
if !out.is_indirect {
1434-
this.check_lvalue(&out.expr);
1428+
for (o, output) in ia.outputs.iter().zip(outputs) {
1429+
if !o.is_indirect {
1430+
this.check_lvalue(output);
14351431
}
1436-
this.visit_expr(&out.expr);
1432+
this.visit_expr(output);
14371433
}
14381434

14391435
intravisit::walk_expr(this, expr);

src/librustc/mir/repr.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,11 @@ pub enum Rvalue<'tcx> {
678678
from_end: usize,
679679
},
680680

681-
InlineAsm(InlineAsm),
681+
InlineAsm {
682+
asm: InlineAsm,
683+
outputs: Vec<Lvalue<'tcx>>,
684+
inputs: Vec<Operand<'tcx>>
685+
}
682686
}
683687

684688
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
@@ -763,7 +767,9 @@ impl<'tcx> Debug for Rvalue<'tcx> {
763767
BinaryOp(ref op, ref a, ref b) => write!(fmt, "{:?}({:?}, {:?})", op, a, b),
764768
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
765769
Box(ref t) => write!(fmt, "Box({:?})", t),
766-
InlineAsm(ref asm) => write!(fmt, "InlineAsm({:?})", asm),
770+
InlineAsm { ref asm, ref outputs, ref inputs } => {
771+
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
772+
}
767773
Slice { ref input, from_start, from_end } =>
768774
write!(fmt, "{:?}[{:?}..-{:?}]", input, from_start, from_end),
769775

src/librustc/mir/tcx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ impl<'tcx> Mir<'tcx> {
223223
}
224224
}
225225
Rvalue::Slice { .. } => None,
226-
Rvalue::InlineAsm(..) => None
226+
Rvalue::InlineAsm { .. } => None
227227
}
228228
}
229229
}

src/librustc/mir/visit.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,14 @@ macro_rules! make_mir_visitor {
261261
});
262262
}
263263

264-
Rvalue::InlineAsm(_) => {
264+
Rvalue::InlineAsm { ref $($mutability)* outputs,
265+
ref $($mutability)* inputs, .. } => {
266+
for output in & $($mutability)* outputs[..] {
267+
self.visit_lvalue(output, LvalueContext::Store);
268+
}
269+
for input in & $($mutability)* inputs[..] {
270+
self.visit_operand(input);
271+
}
265272
}
266273
}
267274
}

src/librustc_back/svh.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ mod svh_visitor {
279279
ExprBreak(id) => SawExprBreak(id.map(|id| id.node.name.as_str())),
280280
ExprAgain(id) => SawExprAgain(id.map(|id| id.node.name.as_str())),
281281
ExprRet(..) => SawExprRet,
282-
ExprInlineAsm(ref asm) => SawExprInlineAsm(asm),
282+
ExprInlineAsm(ref a,_,_) => SawExprInlineAsm(a),
283283
ExprStruct(..) => SawExprStruct,
284284
ExprRepeat(..) => SawExprRepeat,
285285
}

src/librustc_front/fold.rs

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,34 +1106,11 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
11061106
respan(folder.new_span(label.span), folder.fold_ident(label.node))
11071107
})),
11081108
ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))),
1109-
ExprInlineAsm(InlineAsm {
1110-
inputs,
1111-
outputs,
1112-
asm,
1113-
asm_str_style,
1114-
clobbers,
1115-
volatile,
1116-
alignstack,
1117-
dialect,
1118-
expn_id,
1119-
}) => ExprInlineAsm(InlineAsm {
1120-
inputs: inputs.move_map(|(c, input)| (c, folder.fold_expr(input))),
1121-
outputs: outputs.move_map(|out| {
1122-
InlineAsmOutput {
1123-
constraint: out.constraint,
1124-
expr: folder.fold_expr(out.expr),
1125-
is_rw: out.is_rw,
1126-
is_indirect: out.is_indirect,
1127-
}
1128-
}),
1129-
asm: asm,
1130-
asm_str_style: asm_str_style,
1131-
clobbers: clobbers,
1132-
volatile: volatile,
1133-
alignstack: alignstack,
1134-
dialect: dialect,
1135-
expn_id: expn_id,
1136-
}),
1109+
ExprInlineAsm(asm, outputs, inputs) => {
1110+
ExprInlineAsm(asm,
1111+
outputs.move_map(|x| folder.fold_expr(x)),
1112+
inputs.move_map(|x| folder.fold_expr(x)))
1113+
}
11371114
ExprStruct(path, fields, maybe_expr) => {
11381115
ExprStruct(folder.fold_path(path),
11391116
fields.move_map(|x| folder.fold_field(x)),

src/librustc_front/hir.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,8 @@ pub enum Expr_ {
793793
/// A `return`, with an optional value to be returned
794794
ExprRet(Option<P<Expr>>),
795795

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

799799
/// A struct literal expression.
800800
///
@@ -977,7 +977,6 @@ pub enum Ty_ {
977977
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
978978
pub struct InlineAsmOutput {
979979
pub constraint: InternedString,
980-
pub expr: P<Expr>,
981980
pub is_rw: bool,
982981
pub is_indirect: bool,
983982
}
@@ -987,7 +986,7 @@ pub struct InlineAsm {
987986
pub asm: InternedString,
988987
pub asm_str_style: StrStyle,
989988
pub outputs: HirVec<InlineAsmOutput>,
990-
pub inputs: HirVec<(InternedString, P<Expr>)>,
989+
pub inputs: HirVec<InternedString>,
991990
pub clobbers: HirVec<InternedString>,
992991
pub volatile: bool,
993992
pub alignstack: bool,

src/librustc_front/intravisit.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -798,12 +798,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
798798
ExprRet(ref optional_expression) => {
799799
walk_list!(visitor, visit_expr, optional_expression);
800800
}
801-
ExprInlineAsm(ref ia) => {
802-
for &(_, ref input) in &ia.inputs {
803-
visitor.visit_expr(&input)
801+
ExprInlineAsm(_, ref outputs, ref inputs) => {
802+
for output in outputs {
803+
visitor.visit_expr(output)
804804
}
805-
for output in &ia.outputs {
806-
visitor.visit_expr(&output.expr)
805+
for input in inputs {
806+
visitor.visit_expr(input)
807807
}
808808
}
809809
}

src/librustc_front/lowering.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,14 +1319,11 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
13191319
dialect,
13201320
expn_id,
13211321
}) => hir::ExprInlineAsm(hir::InlineAsm {
1322-
inputs: inputs.iter()
1323-
.map(|&(ref c, ref input)| (c.clone(), lower_expr(lctx, input)))
1324-
.collect(),
1322+
inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
13251323
outputs: outputs.iter()
13261324
.map(|out| {
13271325
hir::InlineAsmOutput {
13281326
constraint: out.constraint.clone(),
1329-
expr: lower_expr(lctx, &out.expr),
13301327
is_rw: out.is_rw,
13311328
is_indirect: out.is_indirect,
13321329
}
@@ -1339,7 +1336,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
13391336
alignstack: alignstack,
13401337
dialect: dialect,
13411338
expn_id: expn_id,
1342-
}),
1339+
}, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(),
1340+
inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()),
13431341
ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
13441342
hir::ExprStruct(lower_path(lctx, path),
13451343
fields.iter().map(|x| lower_field(lctx, x)).collect(),

src/librustc_front/print/pprust.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,12 +1481,13 @@ impl<'a> State<'a> {
14811481
_ => (),
14821482
}
14831483
}
1484-
hir::ExprInlineAsm(ref a) => {
1484+
hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => {
14851485
try!(word(&mut self.s, "asm!"));
14861486
try!(self.popen());
14871487
try!(self.print_string(&a.asm, a.asm_str_style));
14881488
try!(self.word_space(":"));
14891489

1490+
let mut out_idx = 0;
14901491
try!(self.commasep(Inconsistent, &a.outputs, |s, out| {
14911492
match out.constraint.slice_shift_char() {
14921493
Some(('=', operand)) if out.is_rw => {
@@ -1495,18 +1496,21 @@ impl<'a> State<'a> {
14951496
_ => try!(s.print_string(&out.constraint, ast::StrStyle::Cooked)),
14961497
}
14971498
try!(s.popen());
1498-
try!(s.print_expr(&out.expr));
1499+
try!(s.print_expr(&outputs[out_idx]));
14991500
try!(s.pclose());
1501+
out_idx += 1;
15001502
Ok(())
15011503
}));
15021504
try!(space(&mut self.s));
15031505
try!(self.word_space(":"));
15041506

1505-
try!(self.commasep(Inconsistent, &a.inputs, |s, &(ref co, ref o)| {
1507+
let mut in_idx = 0;
1508+
try!(self.commasep(Inconsistent, &a.inputs, |s, co| {
15061509
try!(s.print_string(&co, ast::StrStyle::Cooked));
15071510
try!(s.popen());
1508-
try!(s.print_expr(&o));
1511+
try!(s.print_expr(&inputs[in_idx]));
15091512
try!(s.pclose());
1513+
in_idx += 1;
15101514
Ok(())
15111515
}));
15121516
try!(space(&mut self.s));

src/librustc_mir/build/expr/as_rvalue.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,20 @@ impl<'a,'tcx> Builder<'a,'tcx> {
3939
ExprKind::Scope { extent, value } => {
4040
this.in_scope(extent, block, |this| this.as_rvalue(block, value))
4141
}
42-
ExprKind::InlineAsm { asm } => {
43-
block.and(Rvalue::InlineAsm(asm.clone()))
42+
ExprKind::InlineAsm { asm, outputs, inputs } => {
43+
let outputs = outputs.into_iter().map(|output| {
44+
unpack!(block = this.as_lvalue(block, output))
45+
}).collect();
46+
47+
let inputs = inputs.into_iter().map(|input| {
48+
unpack!(block = this.as_operand(block, input))
49+
}).collect();
50+
51+
block.and(Rvalue::InlineAsm {
52+
asm: asm.clone(),
53+
outputs: outputs,
54+
inputs: inputs
55+
})
4456
}
4557
ExprKind::Repeat { value, count } => {
4658
let value_operand = unpack!(block = this.as_operand(block, value));

src/librustc_mir/hair/cx/expr.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,12 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
327327
convert_path_expr(cx, self)
328328
}
329329

330-
hir::ExprInlineAsm(ref asm) => {
331-
ExprKind::InlineAsm { asm: asm }
330+
hir::ExprInlineAsm(ref asm, ref outputs, ref inputs) => {
331+
ExprKind::InlineAsm {
332+
asm: asm,
333+
outputs: outputs.to_ref(),
334+
inputs: inputs.to_ref()
335+
}
332336
}
333337

334338
// Now comes the rote stuff:

src/librustc_mir/hair/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ pub enum ExprKind<'tcx> {
230230
},
231231
InlineAsm {
232232
asm: &'tcx hir::InlineAsm,
233+
outputs: Vec<ExprRef<'tcx>>,
234+
inputs: Vec<ExprRef<'tcx>>
233235
},
234236
}
235237

src/librustc_mir/transform/erase_regions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
8787
Rvalue::BinaryOp(_, _, _) |
8888
Rvalue::UnaryOp(_, _) |
8989
Rvalue::Slice { input: _, from_start: _, from_end: _ } |
90-
Rvalue::InlineAsm(_) => {},
90+
Rvalue::InlineAsm {..} => {},
9191

9292
Rvalue::Repeat(_, ref mut value) => value.ty = self.tcx.erase_regions(&value.ty),
9393
Rvalue::Ref(ref mut region, _, _) => *region = ty::ReStatic,

src/librustc_passes/consts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
750750
// Expressions with side-effects.
751751
hir::ExprAssign(..) |
752752
hir::ExprAssignOp(..) |
753-
hir::ExprInlineAsm(_) => {
753+
hir::ExprInlineAsm(..) => {
754754
v.add_qualif(ConstQualif::NOT_CONST);
755755
if v.mode != Mode::Var {
756756
span_err!(v.tcx.sess, e.span, E0019,

0 commit comments

Comments
 (0)