[MIR] Make InlineAsm a Statement
Previously InlineAsm was an Rvalue, but its semantics doesn’t really match the semantics of an Rvalue – rather it behaves more like a Statement.
This commit is contained in:
parent
62eb6056d3
commit
4a3c66ad2f
@ -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,
|
||||
}
|
||||
@ -790,7 +796,10 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
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"),
|
||||
}
|
||||
}
|
||||
@ -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)]
|
||||
@ -1111,10 +1114,6 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
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 => "",
|
||||
|
@ -207,7 +207,6 @@ pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Opti
|
||||
}
|
||||
}
|
||||
}
|
||||
Rvalue::InlineAsm { .. } => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -333,6 +333,16 @@ fn super_statement(&mut self,
|
||||
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 => {}
|
||||
}
|
||||
}
|
||||
@ -526,17 +536,6 @@ fn super_rvalue(&mut self,
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,6 +473,7 @@ fn statement_effect(&self,
|
||||
}
|
||||
mir::StatementKind::StorageLive(_) |
|
||||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::InlineAsm { .. } |
|
||||
mir::StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -412,6 +412,7 @@ fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
|
||||
span_bug!(stmt.source_info.span,
|
||||
"SetDiscriminant should not exist during borrowck");
|
||||
}
|
||||
StatementKind::InlineAsm { .. } |
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
@ -436,8 +437,7 @@ fn gather_rvalue(&mut self, loc: Location, rvalue: &Rvalue<'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
|
||||
|
@ -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 => {
|
||||
|
@ -49,21 +49,6 @@ fn expr_as_rvalue(&mut self,
|
||||
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))
|
||||
@ -238,6 +223,7 @@ fn expr_as_rvalue(&mut self,
|
||||
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
|
||||
|
@ -232,6 +232,7 @@ pub fn into_expr(&mut self,
|
||||
ExprKind::AssignOp { .. } |
|
||||
ExprKind::Continue { .. } |
|
||||
ExprKind::Break { .. } |
|
||||
ExprKind::InlineAsm { .. } |
|
||||
ExprKind::Return {.. } => {
|
||||
this.stmt_expr(block, expr)
|
||||
}
|
||||
@ -257,7 +258,6 @@ pub fn into_expr(&mut self,
|
||||
ExprKind::Index { .. } |
|
||||
ExprKind::Deref { .. } |
|
||||
ExprKind::Literal { .. } |
|
||||
ExprKind::InlineAsm { .. } |
|
||||
ExprKind::Field { .. } => {
|
||||
debug_assert!(match Category::of(&expr.kind).unwrap() {
|
||||
Category::Rvalue(RvalueFunc::Into) => false,
|
||||
|
@ -117,6 +117,23 @@ pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd
|
||||
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());
|
||||
|
@ -774,10 +774,6 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rvalue::InlineAsm {..} => {
|
||||
self.not_const();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -933,6 +929,7 @@ fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, locat
|
||||
StatementKind::SetDiscriminant { .. } |
|
||||
StatementKind::StorageLive(_) |
|
||||
StatementKind::StorageDead(_) |
|
||||
StatementKind::InlineAsm {..} |
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
});
|
||||
|
@ -361,9 +361,9 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'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`.
|
||||
}
|
||||
StatementKind::SetDiscriminant{ ref lvalue, variant_index } => {
|
||||
let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx);
|
||||
@ -392,6 +392,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
StatementKind::InlineAsm { .. } |
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ fn visit_statement(&mut self,
|
||||
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);
|
||||
@ -198,7 +199,6 @@ fn visit_rvalue(&mut self,
|
||||
|
||||
"Rvalue::Aggregate"
|
||||
}
|
||||
Rvalue::InlineAsm { .. } => "Rvalue::InlineAsm",
|
||||
};
|
||||
self.record(rvalue_kind, rvalue);
|
||||
self.super_rvalue(rvalue, location);
|
||||
|
@ -287,8 +287,9 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalErr> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
use rustc::mir;
|
||||
use middle::lang_items::ExchangeMallocFnLangItem;
|
||||
|
||||
use asm;
|
||||
use base;
|
||||
use builder::Builder;
|
||||
use callee::Callee;
|
||||
@ -156,20 +155,6 @@ pub fn trans_rvalue(&mut self,
|
||||
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);
|
||||
@ -468,8 +453,7 @@ pub fn trans_rvalue_operand(&mut self,
|
||||
(bcx, operand)
|
||||
}
|
||||
mir::Rvalue::Repeat(..) |
|
||||
mir::Rvalue::Aggregate(..) |
|
||||
mir::Rvalue::InlineAsm { .. } => {
|
||||
mir::Rvalue::Aggregate(..) => {
|
||||
bug!("cannot generate operand from rvalue {:?}", rvalue);
|
||||
|
||||
}
|
||||
@ -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,
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
use rustc::mir;
|
||||
|
||||
use base;
|
||||
use asm;
|
||||
use common;
|
||||
use builder::Builder;
|
||||
|
||||
@ -73,6 +74,19 @@ pub fn trans_statement(&mut self,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user