Skip to content

Commit

Permalink
Add MIR phase and query for drop elaboration
Browse files Browse the repository at this point in the history
  • Loading branch information
ecstatic-morse committed Jun 13, 2020
1 parent f5370fa commit a43e486
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/librustc_middle/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ pub enum MirPhase {
Build = 0,
Const = 1,
Validated = 2,
Optimized = 3,
DropElab = 3,
Optimized = 4,
}

impl MirPhase {
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_middle/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ rustc_queries! {
no_hash
}

query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> Steal<mir::Body<'tcx>> {
storage(ArenaCacheSelector<'tcx>)
no_hash
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) }
}

query mir_validated(key: LocalDefId) ->
(
Steal<mir::Body<'tcx>>,
Expand Down
49 changes: 40 additions & 9 deletions src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
mir_const,
mir_const_qualif,
mir_validated,
mir_drops_elaborated_and_const_checked,
optimized_mir,
is_mir_available,
promoted_mir,
Expand Down Expand Up @@ -294,12 +295,31 @@ fn mir_validated(
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
}

fn run_optimization_passes<'tcx>(
fn mir_drops_elaborated_and_const_checked<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> Steal<Body<'tcx>> {
// (Mir-)Borrowck uses `mir_validated`, so we have to force it to
// execute before we can steal.
tcx.ensure().mir_borrowck(def_id);

let (body, _) = tcx.mir_validated(def_id);
let mut body = body.steal();

run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, None);
check_consts::post_drop_elaboration::check_live_drops(tcx, def_id, &body);
tcx.alloc_steal_mir(body)
}

/// After this series of passes, no lifetime analysis based on borrowing can be done.
fn run_post_borrowck_cleanup_passes<'tcx>(
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
def_id: LocalDefId,
promoted: Option<Promoted>,
) {
debug!("post_borrowck_cleanup({:?})", def_id);

let post_borrowck_cleanup: &[&dyn MirPass<'tcx>] = &[
// Remove all things only needed by analysis
&no_landing_pads::NoLandingPads::new(tcx),
Expand All @@ -318,9 +338,24 @@ fn run_optimization_passes<'tcx>(
// but before optimizations begin.
&add_retag::AddRetag,
&simplify::SimplifyCfg::new("elaborate-drops"),
// No lifetime analysis based on borrowing can be done from here on out.
];

run_passes(
tcx,
body,
InstanceDef::Item(def_id.to_def_id()),
promoted,
MirPhase::DropElab,
&[post_borrowck_cleanup],
);
}

fn run_optimization_passes<'tcx>(
tcx: TyCtxt<'tcx>,
body: &mut Body<'tcx>,
def_id: LocalDefId,
promoted: Option<Promoted>,
) {
let optimizations: &[&dyn MirPass<'tcx>] = &[
&unreachable_prop::UnreachablePropagation,
&uninhabited_enum_branching::UninhabitedEnumBranching,
Expand Down Expand Up @@ -368,14 +403,14 @@ fn run_optimization_passes<'tcx>(

let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;

#[rustfmt::skip]
run_passes(
tcx,
body,
InstanceDef::Item(def_id.to_def_id()),
promoted,
MirPhase::Optimized,
&[
post_borrowck_cleanup,
if mir_opt_level > 0 { optimizations } else { no_optimizations },
pre_codegen_cleanup,
],
Expand All @@ -393,12 +428,7 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {

let def_id = def_id.expect_local();

// (Mir-)Borrowck uses `mir_validated`, so we have to force it to
// execute before we can steal.
tcx.ensure().mir_borrowck(def_id);

let (body, _) = tcx.mir_validated(def_id);
let mut body = body.steal();
let mut body = tcx.mir_drops_elaborated_and_const_checked(def_id).steal();
run_optimization_passes(tcx, &mut body, def_id, None);

debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR");
Expand All @@ -418,6 +448,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def_id: DefId) -> IndexVec<Promoted, Body<'_>>
let mut promoted = promoted.steal();

for (p, mut body) in promoted.iter_enumerated_mut() {
run_post_borrowck_cleanup_passes(tcx, &mut body, def_id, Some(p));
run_optimization_passes(tcx, &mut body, def_id, Some(p));
}

Expand Down

0 comments on commit a43e486

Please sign in to comment.