1
Fork 0

Clarify which kinds of MIR are allowed during which phases.

This enhances documentation with these details and extends the validator to check these requirements
more thoroughly. As a part of this, we add a new `Deaggregated` phase, and rename other phases so
that their names more naturally correspond to what they represent.
This commit is contained in:
Jakob Degen 2022-03-05 20:37:04 -05:00
parent 547369d3d8
commit fe40240e4d
8 changed files with 98 additions and 52 deletions

View file

@ -127,14 +127,11 @@ pub trait MirPass<'tcx> {
/// These phases all describe dialects of MIR. Since all MIR uses the same datastructures, the
/// dialects forbid certain variants or values in certain phases.
///
/// Note: Each phase's validation checks all invariants of the *previous* phases' dialects. A phase
/// that changes the dialect documents what invariants must be upheld *after* that phase finishes.
///
/// Warning: ordering of variants is significant.
#[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(HashStable)]
pub enum MirPhase {
Build = 0,
Built = 0,
// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
// We used to have this for pre-miri MIR based const eval.
Const = 1,
@ -142,17 +139,32 @@ pub enum MirPhase {
/// by creating a new MIR body per promoted element. After this phase (and thus the termination
/// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir`
/// query.
ConstPromotion = 2,
/// After this phase
/// * the only `AggregateKind`s allowed are `Array` and `Generator`,
/// * `DropAndReplace` is gone for good
/// * `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop` terminator
/// means that the auto-generated drop glue will be invoked.
DropLowering = 3,
/// After this phase, generators are explicit state machines (no more `Yield`).
/// `AggregateKind::Generator` is gone for good.
GeneratorLowering = 4,
Optimization = 5,
ConstsPromoted = 2,
/// Beginning with this phase, the following variants are disallowed:
/// * [`TerminatorKind::DropAndReplace`](terminator::TerminatorKind::DropAndReplace)
/// * [`TerminatorKind::FalseUnwind`](terminator::TerminatorKind::FalseUnwind)
/// * [`TerminatorKind::FalseEdge`](terminator::TerminatorKind::FalseEdge)
/// * [`StatementKind::FakeRead`]
/// * [`StatementKind::AscribeUserType`]
/// * [`Rvalue::Ref`] with `BorrowKind::Shallow`
///
/// And the following variant is allowed:
/// * [`StatementKind::Retag`]
///
/// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop`
/// terminator means that the auto-generated drop glue will be invoked.
DropsLowered = 3,
/// Beginning with this phase, the following variant is disallowed:
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
///
/// And the following variant is allowed:
/// * [`StatementKind::SetDiscriminant`]
Deaggregated = 4,
/// Beginning with this phase, the following variants are disallowed:
/// * [`TerminatorKind::Yield`](terminator::TerminatorKind::Yield)
/// * [`TerminatorKind::GeneratorDrop](terminator::TerminatorKind::GeneratorDrop)
GeneratorsLowered = 5,
Optimized = 6,
}
impl MirPhase {
@ -311,7 +323,7 @@ impl<'tcx> Body<'tcx> {
);
let mut body = Body {
phase: MirPhase::Build,
phase: MirPhase::Built,
source,
basic_blocks,
source_scopes,
@ -346,7 +358,7 @@ impl<'tcx> Body<'tcx> {
/// crate.
pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
let mut body = Body {
phase: MirPhase::Build,
phase: MirPhase::Built,
source: MirSource::item(DefId::local(CRATE_DEF_INDEX)),
basic_blocks,
source_scopes: IndexVec::new(),
@ -1541,6 +1553,11 @@ impl Statement<'_> {
}
}
/// The various kinds of statements that can appear in MIR.
///
/// Not all of these are allowed at every [`MirPhase`]. Check the documentation there to see which
/// ones you do not have to worry about. The MIR validator will generally enforce such restrictions,
/// causing an ICE if they are violated.
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable)]
pub enum StatementKind<'tcx> {
/// Write the RHS Rvalue to the LHS Place.
@ -2223,6 +2240,11 @@ impl<'tcx> Operand<'tcx> {
/// Rvalues
#[derive(Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
/// The various kinds of rvalues that can appear in MIR.
///
/// Not all of these are allowed at every [`MirPhase`]. Check the documentation there to see which
/// ones you do not have to worry about. The MIR validator will generally enforce such restrictions,
/// causing an ICE if they are violated.
pub enum Rvalue<'tcx> {
/// x (either a move or copy, depending on type of x)
Use(Operand<'tcx>),