// tidy-alphabetical-start
#![feature(const_type_name)]
#![feature(cow_is_borrowed)]
#![feature(deref_patterns)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iterator_try_collect)]
#![feature(option_into_flat_iter)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
// tidy-alphabetical-end

use hir::ConstContext;
use required_consts::RequiredConstsVisitor;
use rustc_const_eval::check_consts::{self, ConstCx};
use rustc_const_eval::util;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::steal::Steal;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::LocalDefId;
use rustc_index::IndexVec;
use rustc_middle::mir::{
    AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
    MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, START_BLOCK,
    SourceInfo, Statement, StatementKind, TerminatorKind, WithRetag,
};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_middle::util::Providers;
use rustc_middle::{bug, query, span_bug};
use rustc_span::{DUMMY_SP, Spanned, sym};
use tracing::debug;

#[macro_use]
mod pass_manager;

use std::sync::LazyLock;

use pass_manager::{self as pm, Lint, MirLint, MirPass, PassPolicy, WithMinOptLevel};

mod check_pointers;
mod cost_checker;
mod cross_crate_inline;
mod deduce_param_attrs;
mod diagnostics;
mod elaborate_drop;
mod ffi_unwind_calls;
mod lint;
mod lint_tail_expr_drop_order;
mod liveness;
mod patch;
mod shim;
mod ssa;
mod trivial_const;

/// Exposed for rustc drivers.
pub use shim::build_drop_shim;

/// We import passes via this macro so that we can have a static list of pass names
/// (used to verify CLI arguments). It takes a list of modules, followed by the passes
/// declared within them.
/// ```ignore,macro-test
/// declare_passes! {
///     // Declare a single pass from the module `abort_unwinding_calls`
///     mod abort_unwinding_calls : AbortUnwindingCalls;
///     // When passes are grouped together as an enum, declare the two constituent passes
///     mod add_call_guards : AddCallGuards {
///         AllCallEdges,
///         CriticalCallEdges
///     };
///     // Declares multiple pass groups, each containing their own constituent passes
///     mod simplify : SimplifyCfg {
///         Initial,
///         /* omitted */
///     }, SimplifyLocals {
///         BeforeConstProp,
///         /* omitted */
///     };
/// }
/// ```
macro_rules! declare_passes {
    (
        $(
            $vis:vis mod $mod_name:ident : $($pass_name:ident $( { $($ident:ident),* } )?),+ $(,)?;
        )*
    ) => {
        $(
            $vis mod $mod_name;
            $(
                // Make sure the type name is correct
                #[allow(unused_imports)]
                use $mod_name::$pass_name as _;
            )+
        )*

        static PASS_NAMES: LazyLock<FxIndexSet<&str>> = LazyLock::new(|| {
            let mut set = FxIndexSet::default();
            $(
                $(
                    set.extend(pass_names!($mod_name : $pass_name $( { $($ident),* } )? ));
                )+
            )*
            set
        });
    };
}

macro_rules! pass_names {
    // pass groups: only pass names inside are considered pass_names
    ($mod_name:ident : $pass_group:ident { $($pass_name:ident),* $(,)? }) => {
        [
            $(
                $mod_name::$pass_group::$pass_name.name(),
            )*
        ]
    };
    // lone pass names: stringify the struct or enum name
    ($mod_name:ident : $pass_name:ident) => {
        [stringify!($pass_name)]
    };
}

declare_passes! {
    mod abort_unwinding_calls : AbortUnwindingCalls;
    mod add_call_guards : AddCallGuards { AllCallEdges, CriticalCallEdges };
    mod add_moves_for_packed_drops : AddMovesForPackedDrops;
    mod add_subtyping_projections : Subtyper;
    mod check_inline : CheckForceInline;
    mod check_call_recursion : CheckCallRecursion, CheckDropRecursion;
    mod check_alignment : CheckAlignment;
    mod check_enums : CheckEnums;
    mod check_const_item_mutation : CheckConstItemMutation;
    mod check_null : CheckNull;
    mod check_packed_ref : CheckPackedRef;
    mod check_mut_restriction : CheckMutRestriction;
    // This pass is public to allow external drivers to perform MIR cleanup
    pub mod cleanup_post_borrowck : CleanupPostBorrowck;

    mod copy_prop : CopyProp;
    mod coroutine : StateTransform;
    mod coverage : InstrumentCoverage;
    mod ctfe_limit : CtfeLimit;
    mod dataflow_const_prop : DataflowConstProp;
    mod dead_store_elimination : DeadStoreElimination {
        Initial,
        Final
    };
    mod deref_separator : Derefer;
    mod dest_prop : DestinationPropagation;
    mod early_otherwise_branch : EarlyOtherwiseBranch;
    mod erase_deref_temps : EraseDerefTemps;
    mod elaborate_box_derefs : ElaborateBoxDerefs;
    mod elaborate_drops : ElaborateDrops;
    mod function_item_references : FunctionItemReferences;
    mod gvn : GVN;
    // Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
    // by custom rustc drivers, running all the steps by themselves. See #114628.
    pub mod inline : Inline, ForceInline;
    mod impossible_clauses : ImpossibleClauses;
    mod instsimplify : InstSimplify { BeforeInline, AfterSimplifyCfg };
    mod jump_threading : JumpThreading;
    mod known_panics_lint : KnownPanicsLint;
    mod large_enums : EnumSizeOpt;
    mod lint_and_remove_uninhabited : LintAndRemoveUninhabited;
    mod lower_intrinsics : LowerIntrinsics;
    mod lower_slice_len : LowerSliceLenCalls;
    mod match_branches : MatchBranchSimplification;
    mod mentioned_items : MentionedItems;
    mod multiple_return_terminators : MultipleReturnTerminators;
    mod post_drop_elaboration : CheckLiveDrops;
    mod prettify : ReorderBasicBlocks, ReorderLocals;
    mod promote_consts : PromoteTemps;
    mod ref_prop : ReferencePropagation;
    pub mod remove_noop_landing_pads : RemoveNoopLandingPads;
    mod remove_place_mention : RemovePlaceMention;
    mod remove_storage_markers : RemoveStorageMarkers;
    mod remove_uninit_drops : RemoveUninitDrops;
    mod remove_unneeded_drops : RemoveUnneededDrops;
    mod remove_zsts : RemoveZsts;
    mod required_consts : RequiredConstsVisitor;
    mod post_analysis_normalize : PostAnalysisNormalize;
    mod sanity_check : SanityCheck;
    // This pass is public to allow external drivers to perform MIR cleanup
    pub mod simplify :
        SimplifyCfg {
            Initial,
            PromoteConsts,
            RemoveFalseEdges,
            PostAnalysis,
            PreOptimizations,
            Final,
            MakeShim,
            AfterUnreachableEnumBranching
        },
        SimplifyLocals {
            BeforeConstProp,
            AfterGVN,
            Final
        };
    mod simplify_branches : SimplifyConstCondition {
        AfterInstSimplify,
        AfterConstProp,
        Final
    };
    mod simplify_comparison_integral : SimplifyComparisonIntegral;
    mod single_use_consts : SingleUseConsts;
    mod sroa : ScalarReplacementOfAggregates;
    mod strip_debuginfo : StripDebugInfo;
    mod ssa_range_prop: SsaRangePropagation;
    mod unreachable_enum_branching : UnreachableEnumBranching;
    mod unreachable_prop : UnreachablePropagation;
    mod validate : Validator;
}

pub fn provide(providers: &mut Providers) {
    coverage::query::provide(providers);
    ffi_unwind_calls::provide(&mut providers.queries);
    shim::provide(&mut providers.queries);
    cross_crate_inline::provide(&mut providers.queries);
    providers.queries = query::Providers {
        mir_keys,
        mir_built,
        mir_const_qualif,
        mir_promoted,
        mir_drops_elaborated_and_const_checked,
        mir_for_ctfe,
        mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses,
        optimized_mir,
        check_liveness: liveness::check_liveness,
        is_mir_available,
        mir_callgraph_cyclic: inline::cycle::mir_callgraph_cyclic,
        mir_inliner_callees: inline::cycle::mir_inliner_callees,
        promoted_mir,
        deduced_param_attrs: deduce_param_attrs::deduced_param_attrs,
        coroutine_by_move_body_def_id: coroutine::coroutine_by_move_body_def_id,
        trivial_const: trivial_const::trivial_const_provider,
        ..providers.queries
    };
}

fn remap_mir_for_const_eval_select<'tcx>(
    tcx: TyCtxt<'tcx>,
    mut body: Body<'tcx>,
    context: hir::Constness,
) -> Body<'tcx> {
    for bb in body.basic_blocks.as_mut().iter_mut() {
        let terminator = bb.terminator.as_mut().expect("invalid terminator");
        match terminator.kind {
            TerminatorKind::Call {
                func: Operand::Constant(ConstOperand { ref const_, .. }),
                ref mut args,
                destination,
                target,
                unwind,
                fn_span,
                ..
            } if let ty::FnDef(def_id, _) = *const_.ty().kind()
                && tcx.is_intrinsic(def_id, sym::const_eval_select) =>
            {
                let Ok([tupled_args, called_in_const, called_at_rt]) = take_array(args) else {
                    unreachable!()
                };
                let ty = tupled_args.node.ty(&body.local_decls, tcx);
                let fields = ty.tuple_fields();
                let num_args = fields.len();
                let func = match context {
                    // Using `const_eval_select` in always-const code is useful when used in macros
                    // that you don't know whether they are going to be used in `const fn` or in `const` items.
                    hir::Constness::Const { .. } => called_in_const,
                    hir::Constness::NotConst => called_at_rt,
                };
                let (method, place): (fn(Place<'tcx>) -> Operand<'tcx>, Place<'tcx>) =
                    match tupled_args.node {
                        Operand::Constant(_) | Operand::RuntimeChecks(_) => {
                            // There is no good way of extracting a tuple arg from a constant
                            // (const generic stuff) so we just create a temporary and deconstruct
                            // that.
                            let local = body.local_decls.push(LocalDecl::new(ty, fn_span));
                            bb.statements.push(Statement::new(
                                SourceInfo::outermost(fn_span),
                                StatementKind::Assign(Box::new((
                                    local.into(),
                                    Rvalue::Use(tupled_args.node.clone(), WithRetag::Yes),
                                ))),
                            ));
                            (Operand::Move, local.into())
                        }
                        Operand::Move(place) => (Operand::Move, place),
                        Operand::Copy(place) => (Operand::Copy, place),
                    };
                let place_elems = place.projection;
                let arguments = (0..num_args)
                    .map(|x| {
                        let mut place_elems = place_elems.to_vec();
                        place_elems.push(ProjectionElem::Field(x.into(), fields[x]));
                        let projection = tcx.mk_place_elems(&place_elems);
                        let place = Place { local: place.local, projection };
                        Spanned { node: method(place), span: DUMMY_SP }
                    })
                    .collect();
                terminator.kind = TerminatorKind::Call {
                    func: func.node,
                    args: arguments,
                    destination,
                    target,
                    unwind,
                    call_source: CallSource::Misc,
                    fn_span,
                };
            }
            _ => {}
        }
    }
    body
}

fn take_array<T, const N: usize>(b: &mut Box<[T]>) -> Result<[T; N], Box<[T]>> {
    let b: Box<[T; N]> = std::mem::take(b).try_into()?;
    Ok(*b)
}

fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
    tcx.mir_keys(()).contains(&def_id)
}

/// Finds the full set of `DefId`s within the current crate that have
/// MIR associated with them.
fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
    // All body-owners have MIR associated with them.
    let mut set: FxIndexSet<_> = tcx.hir_body_owners().collect();

    // Remove the fake bodies for `global_asm!`, since they're not useful
    // to be emitted (`--emit=mir`) or encoded (in metadata).
    set.retain(|&def_id| !matches!(tcx.def_kind(def_id), DefKind::GlobalAsm));

    // Coroutine-closures (e.g. async closures) have an additional by-move MIR
    // body that isn't in the HIR.
    for body_owner in tcx.hir_body_owners() {
        if let DefKind::Closure = tcx.def_kind(body_owner)
            && tcx.needs_coroutine_by_move_body_def_id(body_owner.to_def_id())
        {
            set.insert(tcx.coroutine_by_move_body_def_id(body_owner).expect_local());
        }
    }

    // tuple struct/variant constructors have MIR, but they don't have a BodyId,
    // so we need to build them separately.
    for item in tcx.hir_crate_items(()).free_items() {
        if let DefKind::Struct | DefKind::Enum = tcx.def_kind(item.owner_id) {
            for variant in tcx.adt_def(item.owner_id).variants() {
                if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
                    set.insert(ctor_def_id.expect_local());
                }
            }
        }
    }

    set
}

fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
    // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
    // cannot yet be stolen), because `mir_promoted()`, which steals
    // from `mir_built()`, forces this query to execute before
    // performing the steal.
    let body = &tcx.mir_built(def).borrow();
    let ccx = check_consts::ConstCx::new(tcx, body);
    // No need to const-check a non-const `fn`.
    match ccx.const_kind {
        Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {}
        None => span_bug!(
            tcx.def_span(def),
            "`mir_const_qualif` should only be called on const fns and const items"
        ),
    }

    if body.return_ty().references_error() {
        // It's possible to reach here without an error being emitted (#121103).
        tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
        return Default::default();
    }

    let mut validator = check_consts::check::Checker::new(&ccx);
    validator.check_body();

    // We return the qualifs in the return place for every MIR body, even though it is only used
    // when deciding to promote a reference to a `const` for now.
    validator.qualifs_in_return_place()
}

/// Implementation of the `mir_built` query.
fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
    // Delegate to the main MIR building code in the `rustc_mir_build` crate.
    // This is the one place that is allowed to call `build_mir_inner_impl`.
    let mut body = tcx.build_mir_inner_impl(def);

    // Identifying trivial consts based on their mir_built is easy, but a little wasteful.
    // Trying to push this logic earlier in the compiler and never even produce the Body would
    // probably improve compile time.
    if trivial_const::trivial_const(tcx, def, || &body).is_some() {
        // Skip all the passes below for trivial consts.
        let body = tcx.alloc_steal_mir(body);
        pass_manager::dump_mir_for_phase_change(tcx, &body.borrow());
        return body;
    }

    pass_manager::dump_mir_for_phase_change(tcx, &body);

    pm::run_passes(
        tcx,
        &mut body,
        &[
            // This used to be part of MIR building,
            // now done separately to separate concerns.
            &lint_and_remove_uninhabited::LintAndRemoveUninhabited,
            // MIR-level lints.
            &Lint(check_inline::CheckForceInline),
            &Lint(check_call_recursion::CheckCallRecursion),
            &Lint(check_packed_ref::CheckPackedRef),
            &Lint(check_const_item_mutation::CheckConstItemMutation),
            &Lint(check_mut_restriction::CheckMutRestriction),
            &Lint(function_item_references::FunctionItemReferences),
            // What we need to do constant evaluation.
            &simplify::SimplifyCfg::Initial,
            &Lint(sanity_check::SanityCheck),
        ],
        None,
    );
    tcx.alloc_steal_mir(body)
}

/// Compute the main MIR body and the list of MIR bodies of the promoteds.
fn mir_promoted(
    tcx: TyCtxt<'_>,
    def: LocalDefId,
) -> (&Steal<Body<'_>>, &Steal<IndexVec<Promoted, Body<'_>>>) {
    debug_assert!(!tcx.is_trivial_const(def), "Tried to get mir_promoted of a trivial const");
    debug_assert!(!tcx.is_constructor(def.to_def_id()));

    // Ensure that we compute the `mir_const_qualif` for constants at
    // this point, before we steal the mir-const result.
    // Also this means promotion can rely on all const checks having been done.

    let const_qualifs = match tcx.def_kind(def) {
        DefKind::Fn | DefKind::AssocFn | DefKind::Closure
            if matches!(tcx.constness(def), hir::Constness::Const { .. }) =>
        {
            tcx.mir_const_qualif(def)
        }
        DefKind::AssocConst { .. }
        | DefKind::Const { .. }
        | DefKind::Static { .. }
        | DefKind::AnonConst => tcx.mir_const_qualif(def),
        _ => ConstQualifs::default(),
    };

    // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
    tcx.ensure_done().has_ffi_unwind_calls(def);

    // the `by_move_body` query uses the raw mir, so make sure it is run.
    if tcx.needs_coroutine_by_move_body_def_id(def.to_def_id()) {
        tcx.ensure_done().coroutine_by_move_body_def_id(def);
    }

    // the `trivial_const` query uses mir_built, so make sure it is run.
    tcx.ensure_done().trivial_const(def);

    let mut body = tcx.mir_built(def).steal();
    if let Some(error_reported) = const_qualifs.tainted_by_errors {
        body.tainted_by_errors = Some(error_reported);
    }

    // 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.
    RequiredConstsVisitor::compute_required_consts(&mut body);

    // What we need to run borrowck etc.
    let promote_pass = promote_consts::PromoteTemps::default();
    pm::run_passes(
        tcx,
        &mut body,
        &[&promote_pass, &simplify::SimplifyCfg::PromoteConsts, &coverage::InstrumentCoverage],
        Some(MirPhase::Analysis(AnalysisPhase::Initial)),
    );

    lint_tail_expr_drop_order::run_lint(tcx, def, &body);

    let promoted = promote_pass.promoted_fragments.into_inner();
    (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
}

/// Compute the MIR that is used during CTFE (and thus has no optimizations run on it)
fn mir_for_ctfe(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &Body<'_> {
    debug_assert!(!tcx.is_trivial_const(def_id), "Tried to get mir_for_ctfe of a trivial const");
    tcx.arena.alloc(inner_mir_for_ctfe(tcx, def_id))
}

fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
    if tcx.is_constructor(def.to_def_id()) {
        // There's no reason to run all of the MIR passes on constructors when
        // we can just output the MIR we want directly. This also saves const
        // qualification and borrow checking the trouble of special casing
        // constructors.
        return shim::build_adt_ctor(tcx, def.to_def_id());
    }

    let body = tcx.mir_drops_elaborated_and_const_checked(def);
    let (body, always) = 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(), true)
        }
        Some(hir::ConstContext::ConstFn) => (body.borrow().clone(), false),
        None => bug!("`mir_for_ctfe` called on non-const {def:?}"),
    };

    let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::Const { always });
    // FIXME(reflection): probably need to look at this for comptime closures
    let passes: &[&dyn MirPass<'_>] = if matches!(tcx.def_kind(def), DefKind::Fn | DefKind::AssocFn)
        && matches!(tcx.constness(def), hir::Constness::Const { always: true })
    {
        // Need to generate mentioned items, as all functions are expected to have them, but for const
        // fns we just look at the optimized MIR, which generates it. For comptime fns, there is no
        // optimized MIR.
        &[&ctfe_limit::CtfeLimit, &mentioned_items::MentionedItems]
    } else {
        &[&ctfe_limit::CtfeLimit]
    };
    pm::run_passes(tcx, &mut body, passes, None);

    body
}

/// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
/// 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.is_coroutine(def.to_def_id()) {
        tcx.ensure_done().mir_coroutine_witnesses(def);
    }

    // We only need to borrowck non-synthetic MIR.
    let tainted_by_errors = if !tcx.is_synthetic_mir(def) {
        tcx.mir_borrowck(tcx.typeck_root_def_id_local(def)).err()
    } else {
        None
    };

    let is_fn_like = tcx.def_kind(def).is_fn_like();
    if is_fn_like {
        // Do not compute the mir call graph without said call graph actually being used.
        if pm::should_run_pass(tcx, &inline::Inline, pm::Optimizations::Allowed)
            || inline::ForceInline::should_run_pass_for_callee(tcx, def.to_def_id())
        {
            tcx.ensure_done().mir_inliner_callees(ty::InstanceKind::Item(def.to_def_id()));
        }
    }

    tcx.ensure_done().check_liveness(def);

    let (body, _) = tcx.mir_promoted(def);
    let mut body = body.steal();

    if let Some(error_reported) = tainted_by_errors {
        body.tainted_by_errors = Some(error_reported);
    }

    let root = tcx.typeck_root_def_id_local(def);
    if let Err(e) = tcx.check_transmutes(root) {
        body.tainted_by_errors = Some(e);
    }

    // Also taint the body if it's within a top-level item that is not well formed.
    //
    // We do this check here and not during `mir_promoted` because that may result
    // in borrowck cycles if WF requires looking into an opaque hidden type.
    match tcx.def_kind(root) {
        DefKind::Fn
        | DefKind::AssocFn
        | DefKind::Static { .. }
        | DefKind::Const { .. }
        | DefKind::AssocConst { .. } => {
            if let Err(guar) = tcx.ensure_result().check_well_formed(root) {
                body.tainted_by_errors = Some(guar);
            }
        }
        _ => {}
    }

    run_analysis_to_runtime_passes(tcx, &mut body);

    tcx.alloc_steal_mir(body)
}

// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
// by custom rustc drivers, running all the steps by themselves. See #114628.
pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
    assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial));
    let did = body.source.def_id();

    debug!("analysis_mir_cleanup({:?})", did);
    run_analysis_cleanup_passes(tcx, body);
    assert!(body.phase == MirPhase::Analysis(AnalysisPhase::PostCleanup));

    // Do a little drop elaboration before const-checking if `const_precise_live_drops` is enabled.
    if check_consts::post_drop_elaboration::checking_enabled(&ConstCx::new(tcx, body)) {
        pm::run_passes(
            tcx,
            body,
            &[
                &remove_uninit_drops::RemoveUninitDrops,
                &simplify::SimplifyCfg::RemoveFalseEdges,
                &Lint(post_drop_elaboration::CheckLiveDrops),
            ],
            None,
        );
    }

    debug!("runtime_mir_lowering({:?})", did);
    run_runtime_lowering_passes(tcx, body);
    assert!(body.phase == MirPhase::Runtime(RuntimePhase::Initial));

    debug!("runtime_mir_cleanup({:?})", did);
    run_runtime_cleanup_passes(tcx, body);
    assert!(body.phase == MirPhase::Runtime(RuntimePhase::PostCleanup));
}

// FIXME(JakobDegen): Can we make these lists of passes consts?

/// After this series of passes, no lifetime analysis based on borrowing can be done.
fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
    let passes: &[&dyn MirPass<'tcx>] = &[
        &impossible_clauses::ImpossibleClauses,
        &cleanup_post_borrowck::CleanupPostBorrowck,
        &remove_noop_landing_pads::RemoveNoopLandingPads,
        &simplify::SimplifyCfg::PostAnalysis,
        &deref_separator::Derefer,
    ];

    pm::run_passes(tcx, body, passes, Some(MirPhase::Analysis(AnalysisPhase::PostCleanup)));
}

/// Returns the sequence of passes that lowers analysis to runtime MIR.
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,
        // Must be done before drop elaboration because we need to drop opaque types, too.
        &post_analysis_normalize::PostAnalysisNormalize,
        // Calling this after `PostAnalysisNormalize` ensures that we don't deal with opaque types.
        &add_subtyping_projections::Subtyper,
        &elaborate_drops::ElaborateDrops,
        // Needs to happen after drop elaboration.
        &Lint(check_call_recursion::CheckDropRecursion),
        // This will remove extraneous landing pads which are no longer
        // necessary as well as forcing any call in a non-unwinding
        // function calling a possibly-unwinding function to abort the process.
        &abort_unwinding_calls::AbortUnwindingCalls,
        // AddMovesForPackedDrops needs to run after drop
        // elaboration.
        &add_moves_for_packed_drops::AddMovesForPackedDrops,
        &erase_deref_temps::EraseDerefTemps,
        &elaborate_box_derefs::ElaborateBoxDerefs,
        &coroutine::StateTransform,
        &Lint(known_panics_lint::KnownPanicsLint),
    ];
    pm::run_passes_no_validate(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::Initial)));
}

/// Returns the sequence of passes that do the initial cleanup of runtime MIR.
fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
    let passes: &[&dyn MirPass<'tcx>] = &[
        &lower_intrinsics::LowerIntrinsics,
        &remove_place_mention::RemovePlaceMention,
        &simplify::SimplifyCfg::PreOptimizations,
    ];

    pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup)));

    // Clear this by anticipation. Optimizations and runtime MIR have no reason to look
    // into this information, which is meant for borrowck diagnostics.
    for decl in &mut body.local_decls {
        decl.local_info = ClearCrossCrate::Clear;
    }
}

pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
    fn o1<T>(x: T) -> WithMinOptLevel<T> {
        WithMinOptLevel(1, x)
    }

    // The main optimizations that we do on MIR.
    pm::run_passes(
        tcx,
        body,
        &[
            // Add some UB checks before any UB gets optimized away.
            &check_alignment::CheckAlignment,
            &check_null::CheckNull,
            &check_enums::CheckEnums,
            // Before inlining: trim down MIR with passes to reduce inlining work.

            // Has to be done before inlining, otherwise actual call will be almost always inlined.
            // Also simple, so can just do first.
            &lower_slice_len::LowerSliceLenCalls,
            // Perform instsimplify before inline to eliminate some trivial calls (like clone
            // shims).
            &instsimplify::InstSimplify::BeforeInline,
            // Perform inlining of `#[rustc_force_inline]`-annotated callees.
            &inline::ForceInline,
            // Perform inlining, which may add a lot of code.
            &inline::Inline,
            // Inlining may have introduced a lot of redundant code and a large move pattern.
            // Now, we need to shrink the generated MIR.
            // Code from other crates may have storage markers, so this needs to happen after
            // inlining.
            &remove_storage_markers::RemoveStorageMarkers,
            // Inlining and instantiation may introduce ZST and useless drops.
            &remove_zsts::RemoveZsts,
            &remove_unneeded_drops::RemoveUnneededDrops,
            // Type instantiation may create uninhabited enums.
            // Also eliminates some unreachable branches based on variants of enums.
            &unreachable_enum_branching::UnreachableEnumBranching,
            &unreachable_prop::UnreachablePropagation,
            &o1(simplify::SimplifyCfg::AfterUnreachableEnumBranching),
            &multiple_return_terminators::MultipleReturnTerminators,
            // After simplifycfg, it allows us to discover new opportunities for peephole
            // optimizations. This invalidates CFG caches, so avoid putting between
            // `ReferencePropagation` and `GVN` which both use the dominator tree.
            &instsimplify::InstSimplify::AfterSimplifyCfg,
            // After `InstSimplify-after-simplifycfg` with `-Zub_checks=false`, simplify
            // ```
            // _13 = const false;
            // assume(copy _13);
            // Call(precondition_check);
            // ```
            // to unreachable to eliminate the call to help later passes.
            // This invalidates CFG caches also.
            &o1(simplify_branches::SimplifyConstCondition::AfterInstSimplify),
            &ref_prop::ReferencePropagation,
            &sroa::ScalarReplacementOfAggregates,
            &simplify::SimplifyLocals::BeforeConstProp,
            &dead_store_elimination::DeadStoreElimination::Initial,
            &gvn::GVN,
            &simplify::SimplifyLocals::AfterGVN,
            // This pass does attempt to track assignments.
            // Keep it close to GVN which merges identical values into the same local.
            &ssa_range_prop::SsaRangePropagation,
            &match_branches::MatchBranchSimplification,
            &dataflow_const_prop::DataflowConstProp,
            &single_use_consts::SingleUseConsts,
            &o1(simplify_branches::SimplifyConstCondition::AfterConstProp),
            &jump_threading::JumpThreading,
            &early_otherwise_branch::EarlyOtherwiseBranch,
            &simplify_comparison_integral::SimplifyComparisonIntegral,
            &o1(simplify_branches::SimplifyConstCondition::Final),
            &o1(remove_noop_landing_pads::RemoveNoopLandingPads),
            &o1(simplify::SimplifyCfg::Final),
            // After the last SimplifyCfg, because this wants one-block functions.
            &strip_debuginfo::StripDebugInfo,
            &copy_prop::CopyProp,
            &dead_store_elimination::DeadStoreElimination::Final,
            &dest_prop::DestinationPropagation,
            &simplify::SimplifyLocals::Final,
            &multiple_return_terminators::MultipleReturnTerminators,
            &large_enums::EnumSizeOpt { discrepancy: 128 },
            // Some cleanup necessary at least for LLVM and potentially other codegen backends.
            &add_call_guards::CriticalCallEdges,
            // Cleanup for human readability, off by default.
            &prettify::ReorderBasicBlocks,
            &prettify::ReorderLocals,
        ],
        Some(MirPhase::Runtime(RuntimePhase::Optimized)),
    );
}

/// Optimize the MIR and prepare it for codegen.
fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> {
    if tcx.is_constructor(did.to_def_id()) {
        // There's no reason to run all of the MIR passes on constructors when
        // we can just output the MIR we want directly. This also saves const
        // qualification and borrow checking the trouble of special casing
        // constructors.
        return tcx.mir_for_ctfe(did);
    }

    tcx.arena.alloc(inner_optimized_mir(tcx, did))
}

fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
    match tcx.hir_body_const_context(did) {
        // Run the `mir_for_ctfe` query, which depends on `mir_drops_elaborated_and_const_checked`
        // which we are going to steal below. Thus we need to run `mir_for_ctfe` first, so it
        // computes and caches its result.
        Some(hir::ConstContext::ConstFn) => tcx.ensure_done().mir_for_ctfe(did),
        None => {}
        Some(other) => panic!("do not use `optimized_mir` for constants: {other:?}"),
    }
    debug!("about to call mir_drops_elaborated...");
    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);

    if body.tainted_by_errors.is_some() {
        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 `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.
    if let TerminatorKind::Unreachable = body.basic_blocks[START_BLOCK].terminator().kind
        && body.basic_blocks[START_BLOCK].statements.is_empty()
    {
        return body;
    }

    run_optimization_passes(tcx, &mut body);

    body
}

/// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for
/// constant evaluation once all generic parameters become known.
fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_>> {
    if tcx.is_constructor(def.to_def_id()) {
        return tcx.arena.alloc(IndexVec::new());
    }

    if !tcx.is_synthetic_mir(def) {
        tcx.ensure_done().mir_borrowck(tcx.typeck_root_def_id_local(def));
    }
    let mut promoted = tcx.mir_promoted(def).1.steal();

    for body in &mut promoted {
        run_analysis_to_runtime_passes(tcx, body);
    }

    tcx.arena.alloc(promoted)
}
