}
}
+/// The various "big phases" that MIR goes through.
+///
+/// Warning: ordering of variants is significant
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub enum MirPhase {
+ Build,
+ Const,
+ Validated,
+ Optimized,
+}
+
/// Lowered representation of a single function.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Mir<'tcx> {
/// that indexes into this vector.
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
+ /// Records how far through the "desugaring and optimization" process this particular
+ /// MIR has traversed. This is particularly useful when inlining, since in that context
+ /// we instantiate the promoted constants and add them to our promoted vector -- but those
+ /// promoted items have already been optimized, whereas ours have not. This field allows
+ /// us to see the difference and forego optimization on the inlined promoted items.
+ pub phase: MirPhase,
+
/// List of source scopes; these are referenced by statements
/// and used for debuginfo. Indexed by a `SourceScope`.
pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
);
Mir {
+ phase: MirPhase::Build,
basic_blocks,
source_scopes,
source_scope_local_data,
}
impl_stable_hash_for!(struct Mir<'tcx> {
+ phase,
basic_blocks,
source_scopes,
source_scope_local_data,
None
});
+impl_stable_hash_for!(enum self::MirPhase {
+ Build,
+ Const,
+ Validated,
+ Optimized,
+});
+
mod binding_form_impl {
use ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
CloneTypeFoldableAndLiftImpls! {
BlockTailInfo,
+ MirPhase,
Mutability,
SourceInfo,
UpvarDecl,
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
+ phase,
basic_blocks,
source_scopes,
source_scope_local_data,
use borrow_check::nll::type_check;
use build;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::mir::{Mir, Promoted};
+use rustc::mir::{Mir, MirPhase, Promoted};
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use rustc::ty::steal::Steal;
mir: &mut Mir<'tcx>);
}
-pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $($pass:expr,)*) {{
+pub macro run_passes(
+ $tcx:ident,
+ $mir:ident,
+ $def_id:ident,
+ $suite_index:expr,
+ $mir_phase:expr;
+ $($pass:expr,)*
+) {{
let suite_index: usize = $suite_index;
let run_passes = |mir: &mut _, promoted| {
+ let mir: &mut Mir<'_> = mir;
+
+ if mir.phase >= $mir_phase {
+ return;
+ }
+
let source = MirSource {
def_id: $def_id,
promoted
index += 1;
};
$(run_pass(&$pass);)*
+
+ mir.phase = $mir_phase;
};
run_passes(&mut $mir, None);
let _ = tcx.unsafety_check_result(def_id);
let mut mir = tcx.mir_built(def_id).steal();
- run_passes![tcx, mir, def_id, 0;
+ run_passes![tcx, mir, def_id, 0, MirPhase::Const;
// Remove all `EndRegion` statements that are not involved in borrows.
cleanup_post_borrowck::CleanEndRegions,
}
let mut mir = tcx.mir_const(def_id).steal();
- run_passes![tcx, mir, def_id, 1;
+ run_passes![tcx, mir, def_id, 1, MirPhase::Validated;
// What we need to run borrowck etc.
qualify_consts::QualifyAndPromoteConstants,
simplify::SimplifyCfg::new("qualify-consts"),
}
let mut mir = tcx.mir_validated(def_id).steal();
- run_passes![tcx, mir, def_id, 2;
+ run_passes![tcx, mir, def_id, 2, MirPhase::Optimized;
// Remove all things not needed by analysis
no_landing_pads::NoLandingPads,
simplify_branches::SimplifyBranches::new("initial"),