|
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