Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIR] Make InlineAsm a Statement #39854

Merged
merged 1 commit into from
Feb 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,12 @@ pub enum StatementKind<'tcx> {
/// End the current live range for the storage of the local.
StorageDead(Lvalue<'tcx>),

InlineAsm {
asm: InlineAsm,
outputs: Vec<Lvalue<'tcx>>,
inputs: Vec<Operand<'tcx>>
},

/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
}
Expand All @@ -790,7 +796,10 @@ impl<'tcx> Debug for Statement<'tcx> {
StorageDead(ref lv) => write!(fmt, "StorageDead({:?})", lv),
SetDiscriminant{lvalue: ref lv, variant_index: index} => {
write!(fmt, "discriminant({:?}) = {:?}", lv, index)
}
},
InlineAsm { ref asm, ref outputs, ref inputs } => {
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
},
Nop => write!(fmt, "nop"),
}
}
Expand Down Expand Up @@ -1004,12 +1013,6 @@ pub enum Rvalue<'tcx> {
/// that `Foo` has a destructor. These rvalues can be optimized
/// away after type-checking and before lowering.
Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),

InlineAsm {
asm: InlineAsm,
outputs: Vec<Lvalue<'tcx>>,
inputs: Vec<Operand<'tcx>>
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
Expand Down Expand Up @@ -1111,10 +1114,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
Box(ref t) => write!(fmt, "Box({:?})", t),
InlineAsm { ref asm, ref outputs, ref inputs } => {
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
}

Ref(_, borrow_kind, ref lv) => {
let kind_str = match borrow_kind {
BorrowKind::Shared => "",
Expand Down
1 change: 0 additions & 1 deletion src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ impl<'tcx> Rvalue<'tcx> {
}
}
}
Rvalue::InlineAsm { .. } => None
}
}
}
Expand Down
21 changes: 10 additions & 11 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,16 @@ macro_rules! make_mir_visitor {
StatementKind::StorageDead(ref $($mutability)* lvalue) => {
self.visit_lvalue(lvalue, LvalueContext::StorageDead, location);
}
StatementKind::InlineAsm { ref $($mutability)* outputs,
ref $($mutability)* inputs,
asm: _ } => {
for output in & $($mutability)* outputs[..] {
self.visit_lvalue(output, LvalueContext::Store, location);
}
for input in & $($mutability)* inputs[..] {
self.visit_operand(input, location);
}
}
StatementKind::Nop => {}
}
}
Expand Down Expand Up @@ -526,17 +536,6 @@ macro_rules! make_mir_visitor {
self.visit_operand(operand, location);
}
}

Rvalue::InlineAsm { ref $($mutability)* outputs,
ref $($mutability)* inputs,
asm: _ } => {
for output in & $($mutability)* outputs[..] {
self.visit_lvalue(output, LvalueContext::Store, location);
}
for input in & $($mutability)* inputs[..] {
self.visit_operand(input, location);
}
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
}
mir::StatementKind::StorageLive(_) |
mir::StatementKind::StorageDead(_) |
mir::StatementKind::InlineAsm { .. } |
mir::StatementKind::Nop => {}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
mir::StatementKind::StorageLive(_) |
mir::StatementKind::StorageDead(_) |
mir::StatementKind::InlineAsm { .. } |
mir::StatementKind::Nop => continue,
mir::StatementKind::SetDiscriminant{ .. } =>
span_bug!(stmt.source_info.span,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_borrowck/borrowck/mir/gather_moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
span_bug!(stmt.source_info.span,
"SetDiscriminant should not exist during borrowck");
}
StatementKind::InlineAsm { .. } |
StatementKind::Nop => {}
}
}
Expand All @@ -436,8 +437,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
}
Rvalue::Ref(..) |
Rvalue::Discriminant(..) |
Rvalue::Len(..) |
Rvalue::InlineAsm { .. } => {}
Rvalue::Len(..) => {}
Rvalue::Box(..) => {
// This returns an rvalue with uninitialized contents. We can't
// move out of it here because it is an rvalue - assignments always
Expand Down
1 change: 1 addition & 0 deletions src/librustc_borrowck/borrowck/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
}
mir::StatementKind::StorageLive(_) |
mir::StatementKind::StorageDead(_) |
mir::StatementKind::InlineAsm { .. } |
mir::StatementKind::Nop => {}
},
None => {
Expand Down
16 changes: 1 addition & 15 deletions src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::Scope { extent, value } => {
this.in_scope(extent, block, |this| this.as_rvalue(block, value))
}
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));
block.and(Rvalue::Repeat(value_operand, count))
Expand Down Expand Up @@ -238,6 +223,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::Break { .. } |
ExprKind::Continue { .. } |
ExprKind::Return { .. } |
ExprKind::InlineAsm { .. } |
ExprKind::StaticRef { .. } => {
// these do not have corresponding `Rvalue` variants,
// so make an operand and then return that
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::AssignOp { .. } |
ExprKind::Continue { .. } |
ExprKind::Break { .. } |
ExprKind::InlineAsm { .. } |
ExprKind::Return {.. } => {
this.stmt_expr(block, expr)
}
Expand All @@ -257,7 +258,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ExprKind::Index { .. } |
ExprKind::Deref { .. } |
ExprKind::Literal { .. } |
ExprKind::InlineAsm { .. } |
ExprKind::Field { .. } => {
debug_assert!(match Category::of(&expr.kind).unwrap() {
Category::Rvalue(RvalueFunc::Into) => false,
Expand Down
17 changes: 17 additions & 0 deletions src/librustc_mir/build/expr/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.exit_scope(expr_span, extent, block, return_block);
this.cfg.start_new_block().unit()
}
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();
this.cfg.push(block, Statement {
source_info: source_info,
kind: StatementKind::InlineAsm {
asm: asm.clone(),
outputs: outputs,
inputs: inputs
},
});
block.unit()
}
_ => {
let expr_ty = expr.ty;
let temp = this.temp(expr.ty.clone());
Expand Down
5 changes: 1 addition & 4 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,10 +774,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
}
}
}

Rvalue::InlineAsm {..} => {
self.not_const();
}
}
}

Expand Down Expand Up @@ -933,6 +929,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
StatementKind::SetDiscriminant { .. } |
StatementKind::StorageLive(_) |
StatementKind::StorageDead(_) |
StatementKind::InlineAsm {..} |
StatementKind::Nop => {}
}
});
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_mir/transform/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}",
lv_ty, rv_ty, terr);
}
// FIXME: rvalue with undeterminable type - e.g. inline
// asm.
}
// FIXME: rvalue with undeterminable type - e.g. AggregateKind::Array branch that
// returns `None`.
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, this case (the only remaining case that returns None now that InlineAsm is gone) is for empty arrays. I think that returning [!; 0] would be the correct behavior, removing the need to return an Option.

Copy link
Member Author

Choose a reason for hiding this comment

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

At least currently [T; 0] is not a subtype of [!; 0] so no, that would not work.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the problem is that Array ought to carry the type of its elements.

}
StatementKind::SetDiscriminant{ ref lvalue, variant_index } => {
let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx);
Expand Down Expand Up @@ -392,6 +392,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}
}
StatementKind::InlineAsm { .. } |
StatementKind::Nop => {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_passes/mir_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant",
StatementKind::StorageLive(..) => "StatementKind::StorageLive",
StatementKind::StorageDead(..) => "StatementKind::StorageDead",
StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm",
StatementKind::Nop => "StatementKind::Nop",
}, &statement.kind);
self.super_statement(block, statement, location);
Expand Down Expand Up @@ -198,7 +199,6 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {

"Rvalue::Aggregate"
}
Rvalue::InlineAsm { .. } => "Rvalue::InlineAsm",
};
self.record(rvalue_kind, rvalue);
self.super_rvalue(rvalue, location);
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_trans/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
mir::StatementKind::StorageLive(_) |
mir::StatementKind::StorageDead(_) |
mir::StatementKind::Nop => {}
mir::StatementKind::InlineAsm { .. } |
mir::StatementKind::SetDiscriminant{ .. } => {
span_bug!(span, "SetDiscriminant should not appear in constants?");
span_bug!(span, "{:?} should not appear in constants?", statement.kind);
}
}
}
Expand Down
21 changes: 2 additions & 19 deletions src/librustc_trans/mir/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc::mir::tcx::LvalueTy;
use rustc::mir;
use middle::lang_items::ExchangeMallocFnLangItem;

use asm;
use base;
use builder::Builder;
use callee::Callee;
Expand Down Expand Up @@ -156,20 +155,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
bcx
}

mir::Rvalue::InlineAsm { ref asm, ref outputs, ref inputs } => {
let outputs = outputs.iter().map(|output| {
let lvalue = self.trans_lvalue(&bcx, output);
(lvalue.llval, lvalue.ty.to_ty(bcx.tcx()))
}).collect();

let input_vals = inputs.iter().map(|input| {
self.trans_operand(&bcx, input).immediate()
}).collect();

asm::trans_inline_asm(&bcx, asm, outputs, input_vals);
bcx
}

_ => {
assert!(rvalue_creates_operand(rvalue));
let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue);
Expand Down Expand Up @@ -468,8 +453,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
(bcx, operand)
}
mir::Rvalue::Repeat(..) |
mir::Rvalue::Aggregate(..) |
mir::Rvalue::InlineAsm { .. } => {
mir::Rvalue::Aggregate(..) => {
bug!("cannot generate operand from rvalue {:?}", rvalue);

}
Expand Down Expand Up @@ -669,8 +653,7 @@ pub fn rvalue_creates_operand(rvalue: &mir::Rvalue) -> bool {
mir::Rvalue::Use(..) =>
true,
mir::Rvalue::Repeat(..) |
mir::Rvalue::Aggregate(..) |
mir::Rvalue::InlineAsm { .. } =>
mir::Rvalue::Aggregate(..) =>
false,
}

Expand Down
14 changes: 14 additions & 0 deletions src/librustc_trans/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use rustc::mir;

use base;
use asm;
use common;
use builder::Builder;

Expand Down Expand Up @@ -73,6 +74,19 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
mir::StatementKind::StorageDead(ref lvalue) => {
self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End)
}
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
let outputs = outputs.iter().map(|output| {
let lvalue = self.trans_lvalue(&bcx, output);
(lvalue.llval, lvalue.ty.to_ty(bcx.tcx()))
}).collect();

let input_vals = inputs.iter().map(|input| {
self.trans_operand(&bcx, input).immediate()
}).collect();

asm::trans_inline_asm(&bcx, asm, outputs, input_vals);
bcx
}
mir::StatementKind::Nop => bcx,
}
}
Expand Down