MIR required_consts, mentioned_items: ensure we do not forget to fill these lists
This commit is contained in:
@@ -28,11 +28,10 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{
|
||||
traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs,
|
||||
LocalDecl, MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue,
|
||||
SourceInfo, Statement, StatementKind, TerminatorKind, START_BLOCK,
|
||||
AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
|
||||
MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||
Statement, StatementKind, TerminatorKind, START_BLOCK,
|
||||
};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::util::Providers;
|
||||
@@ -339,12 +338,15 @@ fn mir_promoted(
|
||||
|
||||
// Collect `required_consts` *before* promotion, so if there are any consts being promoted
|
||||
// we still add them to the list in the outer MIR body.
|
||||
let mut required_consts = Vec::new();
|
||||
let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts);
|
||||
for (bb, bb_data) in traversal::reverse_postorder(&body) {
|
||||
required_consts_visitor.visit_basic_block_data(bb, bb_data);
|
||||
RequiredConstsVisitor::compute_required_consts(&mut body);
|
||||
// If this has an associated by-move async closure body, that doesn't get run through these
|
||||
// passes itself, it gets "tagged along" by the pass manager. `RequiredConstsVisitor` is not
|
||||
// a regular pass so we have to also apply it manually to the other body.
|
||||
if let Some(coroutine) = body.coroutine.as_mut() {
|
||||
if let Some(by_move_body) = coroutine.by_move_body.as_mut() {
|
||||
RequiredConstsVisitor::compute_required_consts(by_move_body);
|
||||
}
|
||||
}
|
||||
body.required_consts = required_consts;
|
||||
|
||||
// What we need to run borrowck etc.
|
||||
let promote_pass = promote_consts::PromoteTemps::default();
|
||||
@@ -561,9 +563,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
tcx,
|
||||
body,
|
||||
&[
|
||||
// Before doing anything, remember which items are being mentioned so that the set of items
|
||||
// visited does not depend on the optimization level.
|
||||
&mentioned_items::MentionedItems,
|
||||
// Add some UB checks before any UB gets optimized away.
|
||||
&check_alignment::CheckAlignment,
|
||||
// Before inlining: trim down MIR with passes to reduce inlining work.
|
||||
@@ -657,6 +656,19 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
|
||||
return body;
|
||||
}
|
||||
|
||||
// Before doing anything, remember which items are being mentioned so that the set of items
|
||||
// visited does not depend on the optimization level.
|
||||
// We do not use `run_passes` for this as that might skip the pass if `injection_phase` is set.
|
||||
mentioned_items::MentionedItems.run_pass(tcx, &mut body);
|
||||
// If this has an associated by-move async closure body, that doesn't get run through these
|
||||
// passes itself, it gets "tagged along" by the pass manager. Since we're not using the pass
|
||||
// manager we have to do this by hand.
|
||||
if let Some(coroutine) = body.coroutine.as_mut() {
|
||||
if let Some(by_move_body) = coroutine.by_move_body.as_mut() {
|
||||
mentioned_items::MentionedItems.run_pass(tcx, by_move_body);
|
||||
}
|
||||
}
|
||||
|
||||
// If `mir_drops_elaborated_and_const_checked` found that the current body has unsatisfiable
|
||||
// predicates, it will shrink the MIR to a single `unreachable` terminator.
|
||||
// More generally, if MIR is a lone `unreachable`, there is nothing to optimize.
|
||||
|
||||
Reference in New Issue
Block a user