]> git.lizzy.rs Git - rust.git/commitdiff
Split PlaceContext::Store into Store & AsmOutput
authorScott McMurray <scottmcm@users.noreply.github.com>
Tue, 19 Dec 2017 22:05:14 +0000 (17:05 -0500)
committerScott McMurray <scottmcm@users.noreply.github.com>
Tue, 19 Dec 2017 22:05:14 +0000 (17:05 -0500)
Outputs in InlineAsm can be read-write, so splitting it out is useful for things like Store-Store folding, as it cannot be done 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.

src/librustc/mir/visit.rs
src/librustc_mir/dataflow/impls/borrows.rs
src/librustc_mir/transform/check_unsafety.rs
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/util/liveness.rs
src/librustc_trans/mir/analyze.rs

index d90bf1b61a7d31bde107340606270a3dbc48b878..a50a9c819f6ecb57cc95a1229a826b8be8fef3f3 100644 (file)
@@ -376,7 +376,7 @@ fn super_statement(&mut self,
                                                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 @@ pub fn is_storage_dead_marker(&self) -> bool {
     /// 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 @@ pub fn is_nonmutating_use(&self) -> bool {
             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,
index c61a57cdda0e91bfbb9964dff95eb38ae25ed8c7..2504aa5ff378acf9f07ec2401ead0bc9e2ea8f24 100644 (file)
@@ -540,6 +540,10 @@ fn is_potential_use(context: PlaceContext) -> bool {
             // "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,
index 7833f4bbac7aaff50c3748e8611f5505cd4a2f90..d9ef5235d1939d51f9be7efb52680a1ef10b4295 100644 (file)
@@ -173,6 +173,7 @@ fn visit_place(&mut self,
                     ty::TyAdt(adt, _) => {
                         if adt.is_union() {
                             if context == PlaceContext::Store ||
+                                context == PlaceContext::AsmOutput ||
                                 context == PlaceContext::Drop
                             {
                                 let elem_ty = match elem {
index 1e5b0bc1392bcf30eb722c893a50f0230b6c3bba..1545040f2da796a688747fdbaaba9aa81852f698 100644 (file)
@@ -103,6 +103,7 @@ fn visit_local(&mut self,
         if *temp == TempState::Undefined {
             match context {
                 PlaceContext::Store |
+                PlaceContext::AsmOutput |
                 PlaceContext::Call => {
                     *temp = TempState::Defined {
                         location,
index 45c3fcd8a615dbd86f809261347776696686e571..0af08e1bc8ac9ac0ef06d48882d8900fcd52fe19 100644 (file)
@@ -240,6 +240,9 @@ fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Locati
 
             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
index b5e5dd3b9ce166c1ad6f779a58b7870f0a4643d8..cfe55aba0d3c5e0019520887b16bdd88bbebc4ec 100644 (file)
@@ -193,6 +193,7 @@ fn visit_local(&mut self,
 
             PlaceContext::Inspect |
             PlaceContext::Store |
+            PlaceContext::AsmOutput |
             PlaceContext::Borrow { .. } |
             PlaceContext::Projection(..) => {
                 self.mark_as_memory(index);