about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2017-02-15 21:21:36 +0200
committerSimonas Kazlauskas <git@kazlauskas.me>2017-02-15 21:21:36 +0200
commit4a3c66ad2f4211137fcb98a31d1e1033d5765e22 (patch)
tree0df586ce976a709322f9dd83b73f4fae0fcc7b37
parent62eb6056d332be09206dc664f2e949ae64341e64 (diff)
downloadrust-4a3c66ad2f4211137fcb98a31d1e1033d5765e22.tar.gz
rust-4a3c66ad2f4211137fcb98a31d1e1033d5765e22.zip
[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.
-rw-r--r--src/librustc/mir/mod.rs21
-rw-r--r--src/librustc/mir/tcx.rs1
-rw-r--r--src/librustc/mir/visit.rs21
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow/impls.rs1
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs1
-rw-r--r--src/librustc_borrowck/borrowck/mir/gather_moves.rs4
-rw-r--r--src/librustc_borrowck/borrowck/mir/mod.rs1
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs16
-rw-r--r--src/librustc_mir/build/expr/into.rs2
-rw-r--r--src/librustc_mir/build/expr/stmt.rs17
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs5
-rw-r--r--src/librustc_mir/transform/type_check.rs5
-rw-r--r--src/librustc_passes/mir_stats.rs2
-rw-r--r--src/librustc_trans/mir/constant.rs3
-rw-r--r--src/librustc_trans/mir/rvalue.rs21
-rw-r--r--src/librustc_trans/mir/statement.rs14
16 files changed, 67 insertions, 68 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index d8212807eb2..3403cf04774 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -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 @@ 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"),
         }
     }
@@ -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 @@ 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 => "",
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 7b0863b4c42..5c8d031caf6 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -207,7 +207,6 @@ impl<'tcx> Rvalue<'tcx> {
                     }
                 }
             }
-            Rvalue::InlineAsm { .. } => None
         }
     }
 }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index be3c43db7ba..7cdbd5cae06 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -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 => {}
                 }
             }
@@ -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);
-                        }
-                    }
                 }
             }
 
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
index 1fa4da94dd6..7888a56d39d 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
@@ -473,6 +473,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
             }
             mir::StatementKind::StorageLive(_) |
             mir::StatementKind::StorageDead(_) |
+            mir::StatementKind::InlineAsm { .. } |
             mir::StatementKind::Nop => {}
         }
     }
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
index ea6ef423c92..940dd5433a0 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
@@ -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,
diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
index 0c7e922c48a..35ace6628cf 100644
--- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
@@ -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 => {}
         }
     }
@@ -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
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index a0c36139ddc..d9283e7037f 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -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 => {
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index dad1d713168..7adcc0e730b 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -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))
@@ -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
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 35841c2cbdf..e66f2b4e2bf 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -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)
             }
@@ -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,
diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs
index f04d630379a..c577aab40db 100644
--- a/src/librustc_mir/build/expr/stmt.rs
+++ b/src/librustc_mir/build/expr/stmt.rs
@@ -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());
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 922521726c6..4459142cfb2 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -774,10 +774,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     }
                 }
             }
-
-            Rvalue::InlineAsm {..} => {
-                self.not_const();
-            }
         }
     }
 
@@ -933,6 +929,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 StatementKind::SetDiscriminant { .. } |
                 StatementKind::StorageLive(_) |
                 StatementKind::StorageDead(_) |
+                StatementKind::InlineAsm {..} |
                 StatementKind::Nop => {}
             }
         });
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 8ede7aaab5f..8d108815e0f 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -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`.
             }
             StatementKind::SetDiscriminant{ ref lvalue, variant_index } => {
                 let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx);
@@ -392,6 +392,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     }
                 }
             }
+            StatementKind::InlineAsm { .. } |
             StatementKind::Nop => {}
         }
     }
diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs
index 517a4720563..33b7089c382 100644
--- a/src/librustc_passes/mir_stats.rs
+++ b/src/librustc_passes/mir_stats.rs
@@ -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);
@@ -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);
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 19139301bb0..7e17ae5f1d3 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -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);
                     }
                 }
             }
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs
index 38ee67796c6..7d4f542addb 100644
--- a/src/librustc_trans/mir/rvalue.rs
+++ b/src/librustc_trans/mir/rvalue.rs
@@ -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;
@@ -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);
@@ -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);
 
             }
@@ -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,
     }
 
diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs
index 48fc9720e4b..29a0648c8f8 100644
--- a/src/librustc_trans/mir/statement.rs
+++ b/src/librustc_trans/mir/statement.rs
@@ -11,6 +11,7 @@
 use rustc::mir;
 
 use base;
+use asm;
 use common;
 use builder::Builder;
 
@@ -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,
         }
     }