|
2 | 2 |
|
3 | 3 | use crate::simplify::simplify_duplicate_switch_targets; |
4 | 4 | use rustc_middle::mir::*; |
| 5 | +use rustc_middle::ty::layout; |
5 | 6 | use rustc_middle::ty::layout::ValidityRequirement; |
6 | 7 | use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt}; |
7 | 8 | use rustc_span::symbol::Symbol; |
8 | 9 | use rustc_target::abi::FieldIdx; |
| 10 | +use rustc_target::spec::abi::Abi; |
9 | 11 |
|
10 | 12 | pub struct InstSimplify; |
11 | 13 |
|
@@ -38,6 +40,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify { |
38 | 40 | block.terminator.as_mut().unwrap(), |
39 | 41 | &mut block.statements, |
40 | 42 | ); |
| 43 | + ctx.simplify_nounwind_call(block.terminator.as_mut().unwrap()); |
41 | 44 | simplify_duplicate_switch_targets(block.terminator.as_mut().unwrap()); |
42 | 45 | } |
43 | 46 | } |
@@ -252,6 +255,28 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { |
252 | 255 | terminator.kind = TerminatorKind::Goto { target: destination_block }; |
253 | 256 | } |
254 | 257 |
|
| 258 | + fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) { |
| 259 | + let TerminatorKind::Call { func, unwind, .. } = &mut terminator.kind else { |
| 260 | + return; |
| 261 | + }; |
| 262 | + |
| 263 | + let Some((def_id, _)) = func.const_fn_def() else { |
| 264 | + return; |
| 265 | + }; |
| 266 | + |
| 267 | + let body_ty = self.tcx.type_of(def_id).skip_binder(); |
| 268 | + let body_abi = match body_ty.kind() { |
| 269 | + ty::FnDef(..) => body_ty.fn_sig(self.tcx).abi(), |
| 270 | + ty::Closure(..) => Abi::RustCall, |
| 271 | + ty::Coroutine(..) => Abi::Rust, |
| 272 | + _ => bug!("unexpected body ty: {:?}", body_ty), |
| 273 | + }; |
| 274 | + |
| 275 | + if !layout::fn_can_unwind(self.tcx, Some(def_id), body_abi) { |
| 276 | + *unwind = UnwindAction::Unreachable; |
| 277 | + } |
| 278 | + } |
| 279 | + |
255 | 280 | fn simplify_intrinsic_assert( |
256 | 281 | &self, |
257 | 282 | terminator: &mut Terminator<'tcx>, |
|
0 commit comments