diff options
| author | DianQK <dianqk@dianqk.net> | 2024-02-28 22:54:37 +0800 |
|---|---|---|
| committer | DianQK <dianqk@dianqk.net> | 2024-03-08 08:15:18 +0800 |
| commit | 2884230df2bdf6ff23d51808f5e2f270dfbe0d3a (patch) | |
| tree | 768e92d484e1d7e4ff04b593d9aebf0a09f53be8 /compiler/rustc_mir_transform/src | |
| parent | b5bd98d5403c1376dadbc635ae426888320f3f9a (diff) | |
| download | rust-2884230df2bdf6ff23d51808f5e2f270dfbe0d3a.tar.gz rust-2884230df2bdf6ff23d51808f5e2f270dfbe0d3a.zip | |
Add a workaround for the `TailDuplicator` compile time overhead
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index 840a7eda27b..57fe46ad75a 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -4,7 +4,8 @@ use crate::MirPass; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::{ - BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, TerminatorKind, + BasicBlock, BasicBlockData, BasicBlocks, Body, Local, Operand, Rvalue, StatementKind, + TerminatorKind, }; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{Ty, TyCtxt}; @@ -118,9 +119,28 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { unreachable_targets.push(index); } } - - let replace_otherwise_to_unreachable = allowed_variants.len() <= 1 - && !body.basic_blocks[targets.otherwise()].is_empty_unreachable(); + let otherwise_is_empty_unreachable = + body.basic_blocks[targets.otherwise()].is_empty_unreachable(); + // After resolving https://github.com/llvm/llvm-project/issues/78578, + // we can remove the limit on the number of successors. + fn check_successors(basic_blocks: &BasicBlocks<'_>, bb: BasicBlock) -> bool { + let mut successors = basic_blocks[bb].terminator().successors(); + let Some(first_successor) = successors.next() else { return true }; + if successors.next().is_some() { + return true; + } + if let TerminatorKind::SwitchInt { .. } = + &basic_blocks[first_successor].terminator().kind + { + return false; + }; + true + } + let otherwise_is_last_variant = !otherwise_is_empty_unreachable + && allowed_variants.len() == 1 + && check_successors(&body.basic_blocks, targets.otherwise()); + let replace_otherwise_to_unreachable = otherwise_is_last_variant + || !otherwise_is_empty_unreachable && allowed_variants.is_empty(); if unreachable_targets.is_empty() && !replace_otherwise_to_unreachable { continue; @@ -129,7 +149,6 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { let unreachable_block = patch.unreachable_no_cleanup_block(); let mut targets = targets.clone(); if replace_otherwise_to_unreachable { - let otherwise_is_last_variant = !allowed_variants.is_empty(); if otherwise_is_last_variant { #[allow(rustc::potential_query_instability)] let last_variant = *allowed_variants.iter().next().unwrap(); |
