about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-12-20 21:22:03 +0800
committerGitHub <noreply@github.com>2017-12-20 21:22:03 +0800
commit5efa045bbea9ff456d385f1850bede03b2677f77 (patch)
treef6bc3875674248a2df9bc27eeae65e7134b5db63
parent0c29c7b1e48136c3fac6bb7fe9235672ae56a9c6 (diff)
parentfb245e05404ad5bbe689dcdc5bd5f4750f4e3730 (diff)
downloadrust-5efa045bbea9ff456d385f1850bede03b2677f77.tar.gz
rust-5efa045bbea9ff456d385f1850bede03b2677f77.zip
Rollup merge of #46852 - scottmcm:asm-placecontext, r=arielb1
Split PlaceContext::Store into Store & AsmOutput

Outputs in InlineAsm can be read-write, so splitting it out is useful for things like Store-Store folding, as that's unsound for a Store-AsmOutput.

This PR is intended to make no changes, just be the mechanical split of the enum.  Future changes can use the split, like a MIR pass I'm working on and perhaps two-phase borrows (see this FIXME: https://github.com/rust-lang/rust/pull/46852/files#diff-74dcd7740ab2104cd2b9a3b68dd4f208R543)
-rw-r--r--src/librustc/mir/visit.rs10
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs4
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs1
-rw-r--r--src/librustc_mir/transform/promote_consts.rs1
-rw-r--r--src/librustc_mir/util/liveness.rs3
-rw-r--r--src/librustc_trans/mir/analyze.rs1
6 files changed, 18 insertions, 2 deletions
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index d90bf1b61a7..a50a9c819f6 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -376,7 +376,7 @@ macro_rules! make_mir_visitor {
                                                ref $($mutability)* inputs,
                                                asm: _ } => {
                         for output in & $($mutability)* outputs[..] {
-                            self.visit_place(output, PlaceContext::Store, location);
+                            self.visit_place(output, PlaceContext::AsmOutput, location);
                         }
                         for input in & $($mutability)* inputs[..] {
                             self.visit_operand(input, location);
@@ -835,6 +835,11 @@ pub enum PlaceContext<'tcx> {
     // Appears as LHS of an assignment
     Store,
 
+    // Can often be treated as a Store, but needs to be separate because
+    // ASM is allowed to read outputs as well, so a Store-AsmOutput sequence
+    // cannot be simplified the way a Store-Store can be.
+    AsmOutput,
+
     // Dest of a call
     Call,
 
@@ -910,7 +915,7 @@ impl<'tcx> PlaceContext<'tcx> {
     /// Returns true if this place context represents a use that potentially changes the value.
     pub fn is_mutating_use(&self) -> bool {
         match *self {
-            PlaceContext::Store | PlaceContext::Call |
+            PlaceContext::Store | PlaceContext::AsmOutput | PlaceContext::Call |
             PlaceContext::Borrow { kind: BorrowKind::Mut, .. } |
             PlaceContext::Projection(Mutability::Mut) |
             PlaceContext::Drop => true,
@@ -932,6 +937,7 @@ impl<'tcx> PlaceContext<'tcx> {
             PlaceContext::Projection(Mutability::Not) |
             PlaceContext::Copy | PlaceContext::Move => true,
             PlaceContext::Borrow { kind: BorrowKind::Mut, .. } | PlaceContext::Store |
+            PlaceContext::AsmOutput |
             PlaceContext::Call | PlaceContext::Projection(Mutability::Mut) |
             PlaceContext::Drop | PlaceContext::StorageLive | PlaceContext::StorageDead |
             PlaceContext::Validate => false,
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index c61a57cdda0..2504aa5ff37 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -540,6 +540,10 @@ impl<'a, 'b, 'tcx> FindPlaceUses<'a, 'b, 'tcx> {
             // "deep" does validation go?
             PlaceContext::Validate => false,
 
+            // FIXME: This is here to not change behaviour from before
+            // AsmOutput existed, but it's not necessarily a pure overwrite.
+            // so it's possible this should activate the place.
+            PlaceContext::AsmOutput |
             // pure overwrites of an place do not activate it. (note
             // PlaceContext::Call is solely about dest place)
             PlaceContext::Store | PlaceContext::Call => false,
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 524fa5cd433..e7ce5285071 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -173,6 +173,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                     ty::TyAdt(adt, _) => {
                         if adt.is_union() {
                             if context == PlaceContext::Store ||
+                                context == PlaceContext::AsmOutput ||
                                 context == PlaceContext::Drop
                             {
                                 let elem_ty = match elem {
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 1e5b0bc1392..1545040f2da 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -103,6 +103,7 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
         if *temp == TempState::Undefined {
             match context {
                 PlaceContext::Store |
+                PlaceContext::AsmOutput |
                 PlaceContext::Call => {
                     *temp = TempState::Defined {
                         location,
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index 5163f74dd25..45c9c350e7e 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -273,6 +273,9 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
 
             PlaceContext::Store |
 
+            // This is potentially both a def and a use...
+            PlaceContext::AsmOutput |
+
             // We let Call define the result in both the success and
             // unwind cases. This is not really correct, however it
             // does not seem to be observable due to the way that we
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index b5e5dd3b9ce..cfe55aba0d3 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -193,6 +193,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
 
             PlaceContext::Inspect |
             PlaceContext::Store |
+            PlaceContext::AsmOutput |
             PlaceContext::Borrow { .. } |
             PlaceContext::Projection(..) => {
                 self.mark_as_memory(index);