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:
parent
e7db42fb5b
commit
fb245e0540
6 changed files with 18 additions and 2 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue