Normalize MIR with RevealAll before optimizations.
This commit is contained in:
parent
1d6f24210c
commit
2fa9b11804
6 changed files with 206 additions and 4 deletions
|
@ -65,6 +65,7 @@ mod remove_storage_markers;
|
|||
mod remove_unneeded_drops;
|
||||
mod remove_zsts;
|
||||
mod required_consts;
|
||||
mod reveal_all;
|
||||
mod separate_const_switch;
|
||||
mod shim;
|
||||
mod simplify;
|
||||
|
@ -488,6 +489,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
// to them. We run some optimizations before that, because they may be harder to do on the state
|
||||
// machine than on MIR with async primitives.
|
||||
let optimizations_with_generators: &[&dyn MirPass<'tcx>] = &[
|
||||
&reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
|
||||
&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
|
||||
&normalize_array_len::NormalizeArrayLen, // has to run after `slice::len` lowering
|
||||
&unreachable_prop::UnreachablePropagation,
|
||||
|
|
58
compiler/rustc_mir_transform/src/reveal_all.rs
Normal file
58
compiler/rustc_mir_transform/src/reveal_all.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
//! Normalizes MIR in RevealAll mode.
|
||||
|
||||
use crate::MirPass;
|
||||
use rustc_middle::mir::visit::*;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
|
||||
pub struct RevealAll;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RevealAll {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
// This pass must run before inlining, since we insert callee bodies in RevealAll mode.
|
||||
// Do not apply this transformation to generators.
|
||||
if (tcx.sess.mir_opt_level() >= 3 || !super::inline::is_enabled(tcx))
|
||||
&& body.generator.is_none()
|
||||
{
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
||||
RevealAllVisitor { tcx, param_env }.visit_body(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RevealAllVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
|
||||
#[inline]
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
|
||||
*ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn process_projection_elem(
|
||||
&mut self,
|
||||
elem: PlaceElem<'tcx>,
|
||||
_: Location,
|
||||
) -> Option<PlaceElem<'tcx>> {
|
||||
match elem {
|
||||
PlaceElem::Field(field, ty) => {
|
||||
let new_ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
|
||||
if ty != new_ty { Some(PlaceElem::Field(field, new_ty)) } else { None }
|
||||
}
|
||||
// None of those contain a Ty.
|
||||
PlaceElem::Index(..)
|
||||
| PlaceElem::Deref
|
||||
| PlaceElem::ConstantIndex { .. }
|
||||
| PlaceElem::Subslice { .. }
|
||||
| PlaceElem::Downcast(..) => None,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue