Skip to content

Commit 71dd542

Browse files
Use new MIR pass manager
1 parent fca642c commit 71dd542

File tree

2 files changed

+79
-174
lines changed

2 files changed

+79
-174
lines changed

compiler/rustc_mir_transform/src/lib.rs

+73-168
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2727
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
2828
use rustc_index::vec::IndexVec;
2929
use rustc_middle::mir::visit::Visitor as _;
30-
use rustc_middle::mir::{dump_mir, traversal, Body, ConstQualifs, MirPass, MirPhase, Promoted};
30+
use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPass, MirPhase, Promoted};
3131
use rustc_middle::ty::query::Providers;
3232
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
3333
use rustc_span::{Span, Symbol};
3434

3535
#[macro_use]
3636
mod pass_manager;
3737

38-
use pass_manager::{Lint, MirLint};
38+
use pass_manager::{self as pm, Lint, MirLint};
3939

4040
mod abort_unwinding_calls;
4141
mod add_call_guards;
@@ -174,66 +174,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxHashSet<LocalDefId> {
174174
set
175175
}
176176

177-
fn run_passes(
178-
tcx: TyCtxt<'tcx>,
179-
body: &mut Body<'tcx>,
180-
mir_phase: MirPhase,
181-
passes: &[&[&dyn MirPass<'tcx>]],
182-
) {
183-
let phase_index = mir_phase.phase_index();
184-
let validate = tcx.sess.opts.debugging_opts.validate_mir;
185-
186-
if body.phase >= mir_phase {
187-
return;
188-
}
189-
190-
if validate {
191-
validate::Validator { when: format!("input to phase {:?}", mir_phase), mir_phase }
192-
.run_pass(tcx, body);
193-
}
194-
195-
let mut index = 0;
196-
let mut run_pass = |pass: &dyn MirPass<'tcx>| {
197-
let run_hooks = |body: &_, index, is_after| {
198-
let disambiguator = if is_after { "after" } else { "before" };
199-
dump_mir(
200-
tcx,
201-
Some(&format_args!("{:03}-{:03}", phase_index, index)),
202-
&pass.name(),
203-
&disambiguator,
204-
body,
205-
|_, _| Ok(()),
206-
);
207-
};
208-
run_hooks(body, index, false);
209-
pass.run_pass(tcx, body);
210-
run_hooks(body, index, true);
211-
212-
if validate {
213-
validate::Validator {
214-
when: format!("after {} in phase {:?}", pass.name(), mir_phase),
215-
mir_phase,
216-
}
217-
.run_pass(tcx, body);
218-
}
219-
220-
index += 1;
221-
};
222-
223-
for pass_group in passes {
224-
for pass in *pass_group {
225-
run_pass(*pass);
226-
}
227-
}
228-
229-
body.phase = mir_phase;
230-
231-
if mir_phase == MirPhase::Optimization {
232-
validate::Validator { when: format!("end of phase {:?}", mir_phase), mir_phase }
233-
.run_pass(tcx, body);
234-
}
235-
}
236-
237177
fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs {
238178
let const_kind = tcx.hir().body_const_context(def.did);
239179

@@ -285,19 +225,19 @@ fn mir_const<'tcx>(
285225

286226
rustc_middle::mir::dump_mir(tcx, None, "mir_map", &0, &body, |_, _| Ok(()));
287227

288-
run_passes(
228+
pm::run_passes(
289229
tcx,
290230
&mut body,
291-
MirPhase::Const,
292-
&[&[
231+
&[
293232
// MIR-level lints.
294233
&Lint(check_packed_ref::CheckPackedRef),
295234
&Lint(check_const_item_mutation::CheckConstItemMutation),
296235
&Lint(function_item_references::FunctionItemReferences),
297236
// What we need to do constant evaluation.
298237
&simplify::SimplifyCfg::new("initial"),
299238
&rustc_peek::SanityCheck, // Just a lint
300-
]],
239+
&marker::PhaseChange(MirPhase::Const),
240+
],
301241
);
302242
tcx.alloc_steal_mir(body)
303243
}
@@ -324,17 +264,17 @@ fn mir_promoted(
324264
}
325265
body.required_consts = required_consts;
326266

267+
// What we need to run borrowck etc.
327268
let promote_pass = promote_consts::PromoteTemps::default();
328-
let promote: &[&dyn MirPass<'tcx>] = &[
329-
// What we need to run borrowck etc.
330-
&promote_pass,
331-
&simplify::SimplifyCfg::new("promote-consts"),
332-
];
333-
334-
let opt_coverage: &[&dyn MirPass<'tcx>] =
335-
if tcx.sess.instrument_coverage() { &[&coverage::InstrumentCoverage] } else { &[] };
336-
337-
run_passes(tcx, &mut body, MirPhase::ConstPromotion, &[promote, opt_coverage]);
269+
pm::run_passes(
270+
tcx,
271+
&mut body,
272+
&[
273+
&promote_pass,
274+
&simplify::SimplifyCfg::new("promote-consts"),
275+
&coverage::InstrumentCoverage,
276+
],
277+
);
338278

339279
let promoted = promote_pass.promoted_fragments.into_inner();
340280
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
@@ -396,19 +336,10 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
396336
// Technically we want to not run on regular const items, but oli-obk doesn't know how to
397337
// conveniently detect that at this point without looking at the HIR.
398338
hir::ConstContext::Const => {
399-
#[rustfmt::skip]
400-
let optimizations: &[&dyn MirPass<'_>] = &[
401-
&const_prop::ConstProp,
402-
];
403-
404-
#[rustfmt::skip]
405-
run_passes(
339+
pm::run_passes(
406340
tcx,
407341
&mut body,
408-
MirPhase::Optimization,
409-
&[
410-
optimizations,
411-
],
342+
&[&const_prop::ConstProp, &marker::PhaseChange(MirPhase::Optimization)],
412343
);
413344
}
414345
}
@@ -453,19 +384,23 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
453384
let mut body = body.steal();
454385

455386
// IMPORTANT
456-
remove_false_edges::RemoveFalseEdges.run_pass(tcx, &mut body);
387+
pm::run_passes(tcx, &mut body, &[&remove_false_edges::RemoveFalseEdges]);
457388

458389
// Do a little drop elaboration before const-checking if `const_precise_live_drops` is enabled.
459-
//
460-
// FIXME: Can't use `run_passes` for these, since `run_passes` SILENTLY DOES NOTHING IF THE MIR
461-
// PHASE DOESN'T CHANGE.
462390
if check_consts::post_drop_elaboration::checking_enabled(&ConstCx::new(tcx, &body)) {
463-
simplify::SimplifyCfg::new("remove-false-edges").run_pass(tcx, &mut body);
464-
remove_uninit_drops::RemoveUninitDrops.run_pass(tcx, &mut body);
465-
check_consts::post_drop_elaboration::check_live_drops(tcx, &body);
391+
pm::run_passes(
392+
tcx,
393+
&mut body,
394+
&[
395+
&simplify::SimplifyCfg::new("remove-false-edges"),
396+
&remove_uninit_drops::RemoveUninitDrops,
397+
],
398+
);
399+
check_consts::post_drop_elaboration::check_live_drops(tcx, &body); // FIXME: make this a MIR lint
466400
}
467401

468402
run_post_borrowck_cleanup_passes(tcx, &mut body);
403+
assert!(body.phase == MirPhase::DropLowering);
469404
tcx.alloc_steal_mir(body)
470405
}
471406

@@ -499,95 +434,65 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
499434
&deaggregator::Deaggregator,
500435
];
501436

502-
run_passes(tcx, body, MirPhase::DropLowering, &[post_borrowck_cleanup]);
437+
pm::run_passes(tcx, body, post_borrowck_cleanup);
503438
}
504439

505440
fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
506-
let mir_opt_level = tcx.sess.mir_opt_level();
507-
508441
// Lowering generator control-flow and variables has to happen before we do anything else
509442
// to them. We run some optimizations before that, because they may be harder to do on the state
510443
// machine than on MIR with async primitives.
511-
let optimizations_with_generators: &[&dyn MirPass<'tcx>] = &[
512-
&reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
513-
&lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
514-
&normalize_array_len::NormalizeArrayLen, // has to run after `slice::len` lowering
515-
&unreachable_prop::UnreachablePropagation,
516-
&uninhabited_enum_branching::UninhabitedEnumBranching,
517-
&simplify::SimplifyCfg::new("after-uninhabited-enum-branching"),
518-
&inline::Inline,
519-
&generator::StateTransform,
520-
];
521-
522-
// Even if we don't do optimizations, we still have to lower generators for codegen.
523-
let no_optimizations_with_generators: &[&dyn MirPass<'tcx>] = &[&generator::StateTransform];
524-
525-
// The main optimizations that we do on MIR.
526-
let optimizations: &[&dyn MirPass<'tcx>] = &[
527-
&remove_storage_markers::RemoveStorageMarkers,
528-
&remove_zsts::RemoveZsts,
529-
&const_goto::ConstGoto,
530-
&remove_unneeded_drops::RemoveUnneededDrops,
531-
&match_branches::MatchBranchSimplification,
532-
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
533-
&multiple_return_terminators::MultipleReturnTerminators,
534-
&instcombine::InstCombine,
535-
&separate_const_switch::SeparateConstSwitch,
536-
&const_prop::ConstProp,
537-
&simplify_branches::SimplifyConstCondition::new("after-const-prop"),
538-
&early_otherwise_branch::EarlyOtherwiseBranch,
539-
&simplify_comparison_integral::SimplifyComparisonIntegral,
540-
&simplify_try::SimplifyArmIdentity,
541-
&simplify_try::SimplifyBranchSame,
542-
&dest_prop::DestinationPropagation,
543-
&simplify_branches::SimplifyConstCondition::new("final"),
544-
&remove_noop_landing_pads::RemoveNoopLandingPads,
545-
&simplify::SimplifyCfg::new("final"),
546-
&nrvo::RenameReturnPlace,
547-
&const_debuginfo::ConstDebugInfo,
548-
&simplify::SimplifyLocals,
549-
&multiple_return_terminators::MultipleReturnTerminators,
550-
&deduplicate_blocks::DeduplicateBlocks,
551-
];
552-
553-
// Optimizations to run even if mir optimizations have been disabled.
554-
let no_optimizations: &[&dyn MirPass<'tcx>] = &[
555-
// FIXME(#70073): This pass is responsible for both optimization as well as some lints.
556-
&const_prop::ConstProp,
557-
];
558-
559-
// Some cleanup necessary at least for LLVM and potentially other codegen backends.
560-
let pre_codegen_cleanup: &[&dyn MirPass<'tcx>] = &[
561-
&add_call_guards::CriticalCallEdges,
562-
// Dump the end result for testing and debugging purposes.
563-
&dump_mir::Marker("PreCodegen"),
564-
];
565-
566-
// End of pass declarations, now actually run the passes.
567-
// Generator Lowering
568-
#[rustfmt::skip]
569-
run_passes(
444+
pm::run_passes(
570445
tcx,
571446
body,
572-
MirPhase::GeneratorLowering,
573447
&[
574-
if mir_opt_level > 0 {
575-
optimizations_with_generators
576-
} else {
577-
no_optimizations_with_generators
578-
}
448+
&reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
449+
&lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
450+
&normalize_array_len::NormalizeArrayLen, // has to run after `slice::len` lowering
451+
&unreachable_prop::UnreachablePropagation,
452+
&uninhabited_enum_branching::UninhabitedEnumBranching,
453+
&simplify::SimplifyCfg::new("after-uninhabited-enum-branching"),
454+
&inline::Inline,
455+
&generator::StateTransform,
579456
],
580457
);
581458

582-
// Main optimization passes
583-
#[rustfmt::skip]
584-
run_passes(
459+
assert!(body.phase == MirPhase::GeneratorLowering);
460+
461+
// The main optimizations that we do on MIR.
462+
pm::run_passes(
585463
tcx,
586464
body,
587-
MirPhase::Optimization,
588465
&[
589-
if mir_opt_level > 0 { optimizations } else { no_optimizations },
590-
pre_codegen_cleanup,
466+
&remove_storage_markers::RemoveStorageMarkers,
467+
&remove_zsts::RemoveZsts,
468+
&const_goto::ConstGoto,
469+
&remove_unneeded_drops::RemoveUnneededDrops,
470+
&match_branches::MatchBranchSimplification,
471+
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
472+
&multiple_return_terminators::MultipleReturnTerminators,
473+
&instcombine::InstCombine,
474+
&separate_const_switch::SeparateConstSwitch,
475+
// FIXME(#70073): This pass is responsible for both optimization as well as some lints.
476+
&const_prop::ConstProp,
477+
&simplify_branches::SimplifyBranches::new("after-const-prop"),
478+
&early_otherwise_branch::EarlyOtherwiseBranch,
479+
&simplify_comparison_integral::SimplifyComparisonIntegral,
480+
&simplify_try::SimplifyArmIdentity,
481+
&simplify_try::SimplifyBranchSame,
482+
&dest_prop::DestinationPropagation,
483+
&simplify_branches::SimplifyBranches::new("final"),
484+
&remove_noop_landing_pads::RemoveNoopLandingPads,
485+
&simplify::SimplifyCfg::new("final"),
486+
&nrvo::RenameReturnPlace,
487+
&const_debuginfo::ConstDebugInfo,
488+
&simplify::SimplifyLocals,
489+
&multiple_return_terminators::MultipleReturnTerminators,
490+
&deduplicate_blocks::DeduplicateBlocks,
491+
// Some cleanup necessary at least for LLVM and potentially other codegen backends.
492+
&add_call_guards::CriticalCallEdges,
493+
&marker::PhaseChange(MirPhase::Optimization),
494+
// Dump the end result for testing and debugging purposes.
495+
&dump_mir::Marker("PreCodegen"),
591496
],
592497
);
593498
}

compiler/rustc_mir_transform/src/shim.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use std::iter;
1717

1818
use crate::util::expand_aggregate;
1919
use crate::{
20-
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, remove_noop_landing_pads,
21-
run_passes, simplify,
20+
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, marker, pass_manager as pm,
21+
remove_noop_landing_pads, simplify,
2222
};
2323
use rustc_middle::mir::patch::MirPatch;
2424
use rustc_mir_dataflow::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
@@ -75,17 +75,17 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
7575
};
7676
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
7777

78-
run_passes(
78+
pm::run_passes(
7979
tcx,
8080
&mut result,
81-
MirPhase::Const,
82-
&[&[
81+
&[
8382
&add_moves_for_packed_drops::AddMovesForPackedDrops,
8483
&remove_noop_landing_pads::RemoveNoopLandingPads,
8584
&simplify::SimplifyCfg::new("make_shim"),
8685
&add_call_guards::CriticalCallEdges,
8786
&abort_unwinding_calls::AbortUnwindingCalls,
88-
]],
87+
&marker::PhaseChange(MirPhase::Const),
88+
],
8989
);
9090

9191
debug!("make_shim({:?}) = {:?}", instance, result);

0 commit comments

Comments
 (0)