summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_transform/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_transform/src/lib.rs')
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs28
1 files changed, 18 insertions, 10 deletions
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index bf798adee..c0a09b7a7 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -2,6 +2,7 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(box_patterns)]
+#![feature(decl_macro)]
#![feature(is_sorted)]
#![feature(let_chains)]
#![feature(map_try_insert)]
@@ -30,9 +31,9 @@ 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, ConstQualifs, Constant, LocalDecl,
- MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
- Statement, StatementKind, TerminatorKind, START_BLOCK,
+ traversal, AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs,
+ LocalDecl, MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue,
+ SourceInfo, Statement, StatementKind, TerminatorKind, START_BLOCK,
};
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
@@ -53,6 +54,7 @@ mod check_packed_ref;
pub mod check_unsafety;
mod remove_place_mention;
// This pass is public to allow external drivers to perform MIR cleanup
+mod add_subtyping_projections;
pub mod cleanup_post_borrowck;
mod const_debuginfo;
mod const_goto;
@@ -75,6 +77,7 @@ mod errors;
mod ffi_unwind_calls;
mod function_item_references;
mod generator;
+mod gvn;
pub mod inline;
mod instsimplify;
mod large_enums;
@@ -148,14 +151,14 @@ fn remap_mir_for_const_eval_select<'tcx>(
let terminator = bb.terminator.as_mut().expect("invalid terminator");
match terminator.kind {
TerminatorKind::Call {
- func: Operand::Constant(box Constant { ref literal, .. }),
+ func: Operand::Constant(box ConstOperand { ref const_, .. }),
ref mut args,
destination,
target,
unwind,
fn_span,
..
- } if let ty::FnDef(def_id, _) = *literal.ty().kind()
+ } if let ty::FnDef(def_id, _) = *const_.ty().kind()
&& tcx.item_name(def_id) == sym::const_eval_select
&& tcx.is_intrinsic(def_id) =>
{
@@ -342,7 +345,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
let body = match tcx.hir().body_const_context(def) {
// consts and statics do not have `optimized_mir`, so we can steal the body instead of
// cloning it.
- Some(hir::ConstContext::Const | hir::ConstContext::Static(_)) => body.steal(),
+ Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => body.steal(),
Some(hir::ConstContext::ConstFn) => body.borrow().clone(),
None => bug!("`mir_for_ctfe` called on non-const {def:?}"),
};
@@ -357,9 +360,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
/// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
/// end up missing the source MIR due to stealing happening.
fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
- if tcx.sess.opts.unstable_opts.drop_tracking_mir
- && let DefKind::Generator = tcx.def_kind(def)
- {
+ if let DefKind::Generator = tcx.def_kind(def) {
tcx.ensure_with_value().mir_generator_witnesses(def);
}
let mir_borrowck = tcx.mir_borrowck(def);
@@ -480,6 +481,8 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let passes: &[&dyn MirPass<'tcx>] = &[
// These next passes must be executed together
&add_call_guards::CriticalCallEdges,
+ &reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
+ &add_subtyping_projections::Subtyper, // calling this after reveal_all ensures that we don't deal with opaque types
&elaborate_drops::ElaborateDrops,
// This will remove extraneous landing pads which are no longer
// necessary as well as well as forcing any call in a non-unwinding
@@ -526,7 +529,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
body,
&[
&check_alignment::CheckAlignment,
- &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
&unreachable_prop::UnreachablePropagation,
&uninhabited_enum_branching::UninhabitedEnumBranching,
@@ -550,6 +552,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// latter pass will leverage the created opportunities.
&separate_const_switch::SeparateConstSwitch,
&const_prop::ConstProp,
+ &gvn::GVN,
&dataflow_const_prop::DataflowConstProp,
//
// Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0.
@@ -605,6 +608,11 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
let body = tcx.mir_drops_elaborated_and_const_checked(did).steal();
let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst);
debug!("body: {:#?}", body);
+
+ if body.tainted_by_errors.is_some() {
+ return body;
+ }
+
run_optimization_passes(tcx, &mut body);
body