Rollup merge of #107411 - cjgillot:dataflow-discriminant, r=oli-obk
Handle discriminant in DataflowConstProp cc ``@jachris`` r? ``@JakobDegen`` This PR attempts to extend the DataflowConstProp pass to handle propagation of discriminants. We handle this by adding 2 new variants to `TrackElem`: `TrackElem::Variant` for enum variants and `TrackElem::Discriminant` for the enum discriminant pseudo-place. The difficulty is that the enum discriminant and enum variants may alias each another. This is the issue of the `Option<NonZeroUsize>` test, which is the equivalent of https://github.com/rust-lang/unsafe-code-guidelines/issues/84 with a direct write. To handle that, we generalize the flood process to flood all the potentially aliasing places. In particular: - any write to `(PLACE as Variant)`, either direct or through a projection, floods `(PLACE as OtherVariant)` for all other variants and `discriminant(PLACE)`; - `SetDiscriminant(PLACE)` floods `(PLACE as Variant)` for each variant. This implies that flooding is not hierarchical any more, and that an assignment to a non-tracked place may need to flood a tracked place. This is handled by `for_each_aliasing_place` which generalizes `preorder_invoke`. As we deaggregate enums by putting `SetDiscriminant` last, this allows to propagate the value of the discriminant. This refactor will allow to make https://github.com/rust-lang/rust/pull/107009 able to handle discriminants too.
This commit is contained in:
@@ -1642,6 +1642,14 @@ impl<'tcx> PlaceRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `Place` contains a `Deref` projection.
|
||||
///
|
||||
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
|
||||
/// same region of memory as its base.
|
||||
pub fn is_indirect(&self) -> bool {
|
||||
self.projection.iter().any(|elem| elem.is_indirect())
|
||||
}
|
||||
|
||||
/// If MirPhase >= Derefered and if projection contains Deref,
|
||||
/// It's guaranteed to be in the first place
|
||||
pub fn has_deref(&self) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user