Propagate locals, even if they have unpropagatable assignments somewhere.

This commit is contained in:
Oliver Scherer 2020-05-12 13:14:47 +02:00
parent c849a0d087
commit de434d8e44
2 changed files with 31 additions and 4 deletions

View File

@ -775,6 +775,10 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
// Projections are fine, because `&mut foo.x` will be caught by
// `MutatingUseContext::Borrow` elsewhere.
MutatingUse(MutatingUseContext::Projection)
// These are just stores, where the storing is not propagatable, but there may be later
// mutations of the same local via `Store`
| MutatingUse(MutatingUseContext::Call)
// Actual store that can possibly even propagate a value
| MutatingUse(MutatingUseContext::Store) => {
if !self.found_assignment.insert(local) {
match &mut self.can_const_prop[local] {
@ -799,7 +803,21 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
| NonMutatingUse(NonMutatingUseContext::Inspect)
| NonMutatingUse(NonMutatingUseContext::Projection)
| NonUse(_) => {}
_ => {
// These could be propagated with a smarter analysis or just some careful thinking about
// whether they'd be fine right now.
MutatingUse(MutatingUseContext::AsmOutput)
| MutatingUse(MutatingUseContext::Yield)
| MutatingUse(MutatingUseContext::Drop)
| MutatingUse(MutatingUseContext::Retag)
// These can't ever be propagated under any scheme, as we can't reason about indirect
// mutation.
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
| NonMutatingUse(NonMutatingUseContext::ShallowBorrow)
| NonMutatingUse(NonMutatingUseContext::UniqueBorrow)
| NonMutatingUse(NonMutatingUseContext::AddressOf)
| MutatingUse(MutatingUseContext::Borrow)
| MutatingUse(MutatingUseContext::AddressOf) => {
trace!("local {:?} can't be propagaged because it's used: {:?}", local, context);
self.can_const_prop[local] = ConstPropMode::NoPropagation;
}

View File

@ -29,17 +29,26 @@
// + ty: i32
// + val: Value(Scalar(0x00000063))
// mir::Constant
// + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:11: 6:13
- // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:11: 6:13
+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:6:5: 6:13
// + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
(_1.0: i32) = const 42i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:7:5: 7:13
// ty::Const
// + ty: i32
// + val: Value(Scalar(0x0000002a))
// mir::Constant
// + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:11: 7:13
- // + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:11: 7:13
+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:7:5: 7:13
// + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) }
StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:9: 8:10
_2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
- _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
+ _2 = const 99i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
+ // ty::Const
+ // + ty: i32
+ // + val: Value(Scalar(0x00000063))
+ // mir::Constant
+ // + span: $DIR/mutable_variable_aggregate_partial_read.rs:8:13: 8:16
+ // + literal: Const { ty: i32, val: Value(Scalar(0x00000063)) }
_0 = const (); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:4:11: 9:2
// ty::Const
// + ty: ()