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 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.
This commit is contained in:
Scott McMurray 2017-12-19 17:05:14 -05:00
parent e7db42fb5b
commit fb245e0540
6 changed files with 18 additions and 2 deletions

View file

@ -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,

View file

@ -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,

View file

@ -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 {

View file

@ -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,

View file

@ -240,6 +240,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

View file

@ -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);