Skip to content

Commit 3a4b4a7

Browse files
committed
Infer nounwind and use it in MIR opts
1 parent 827a0d6 commit 3a4b4a7

31 files changed

+113
-49
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
894894
});
895895
sess.time("MIR_effect_checking", || {
896896
tcx.par_hir_body_owners(|def_id| {
897-
tcx.ensure_ok().has_ffi_unwind_calls(def_id);
897+
tcx.ensure_ok().mir_flags(def_id);
898898

899899
// If we need to codegen, ensure that we emit all errors from
900900
// `mir_drops_elaborated_and_const_checked` now, to avoid discovering

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ provide! { tcx, def_id, other, cdata,
347347
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
348348
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
349349
cross_crate_inlinable => { table_direct }
350+
mir_flags => { table_direct }
350351

351352
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
352353
is_private_dep => { cdata.private_dep }

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2525
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
2626
use rustc_middle::middle::lib_features::FeatureStability;
2727
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
28+
use rustc_middle::mir::MirFlags;
2829
use rustc_middle::ty::fast_reject::SimplifiedType;
2930
use rustc_middle::ty::{
3031
self, DeducedParamAttrs, ParameterizedOverTcx, Ty, TyCtxt, UnusedGenericParams,
@@ -401,6 +402,7 @@ define_tables! {
401402
// individually instead of `DefId`s.
402403
module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
403404
cross_crate_inlinable: Table<DefIndex, bool>,
405+
mir_flags: Table<DefIndex, MirFlags>,
404406

405407
- optional:
406408
attributes: Table<DefIndex, LazyArray<hir::Attribute>>,

compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ impl IsDefault for UnusedGenericParams {
5353
}
5454
}
5555

56+
impl IsDefault for MirFlags {
57+
fn is_default(&self) -> bool {
58+
*self == Self::default()
59+
}
60+
}
61+
5662
/// Helper trait, for encoding to, and decoding from, a fixed number of bytes.
5763
/// Used mainly for Lazy positions and lengths.
5864
/// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`,
@@ -291,6 +297,21 @@ impl FixedSizeEncoding for AttrFlags {
291297
}
292298
}
293299

300+
impl FixedSizeEncoding for MirFlags {
301+
type ByteArray = [u8; 1];
302+
303+
#[inline]
304+
fn from_bytes(b: &[u8; 1]) -> Self {
305+
MirFlags::from_bits_truncate(b[0])
306+
}
307+
308+
#[inline]
309+
fn write_to_bytes(self, b: &mut [u8; 1]) {
310+
debug_assert!(!self.is_default());
311+
b[0] = self.bits();
312+
}
313+
}
314+
294315
impl FixedSizeEncoding for bool {
295316
type ByteArray = [u8; 1];
296317

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,16 @@ pub fn find_self_call<'tcx>(
18321832
None
18331833
}
18341834

1835+
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
1836+
pub struct MirFlags(u8);
1837+
1838+
bitflags::bitflags! {
1839+
impl MirFlags: u8 {
1840+
const IS_NOUNWIND = 1 << 0;
1841+
const HAS_FFI_UNWIND_CALLS = 1 << 1;
1842+
}
1843+
}
1844+
18351845
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
18361846
#[cfg(target_pointer_width = "64")]
18371847
mod size_asserts {

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ trivial! {
285285
rustc_middle::middle::resolve_bound_vars::ResolvedArg,
286286
rustc_middle::middle::stability::DeprecationEntry,
287287
rustc_middle::mir::ConstQualifs,
288+
rustc_middle::mir::MirFlags,
288289
rustc_middle::mir::interpret::AllocId,
289290
rustc_middle::mir::interpret::CtfeProvenance,
290291
rustc_middle::mir::interpret::ErrorHandled,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use crate::middle::lib_features::LibFeatures;
5353
use crate::middle::privacy::EffectiveVisibilities;
5454
use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg};
5555
use crate::middle::stability::{self, DeprecationEntry};
56+
use crate::mir::MirFlags;
5657
use crate::mir::interpret::{
5758
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
5859
EvalToValTreeResult, GlobalId, LitToConstInput,
@@ -1668,9 +1669,10 @@ rustc_queries! {
16681669
desc { "checking if a crate is `#![profiler_runtime]`" }
16691670
separate_provide_extern
16701671
}
1671-
query has_ffi_unwind_calls(key: LocalDefId) -> bool {
1672-
desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) }
1673-
cache_on_disk_if { true }
1672+
query mir_flags(key: DefId) -> MirFlags {
1673+
desc { |tcx| "stashing some local properties of `{}` before the body is stolen", tcx.def_path_str(key) }
1674+
cache_on_disk_if { key.is_local() }
1675+
separate_provide_extern
16741676
}
16751677
query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> {
16761678
fatal_cycle

compiler/rustc_middle/src/ty/context.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use crate::metadata::ModChild;
6565
use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
6666
use crate::middle::{resolve_bound_vars, stability};
6767
use crate::mir::interpret::{self, Allocation, ConstAllocation};
68-
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
68+
use crate::mir::{Body, Local, MirFlags, Place, PlaceElem, ProjectionKind, Promoted};
6969
use crate::query::plumbing::QuerySystem;
7070
use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
7171
use crate::thir::Thir;
@@ -3264,6 +3264,14 @@ impl<'tcx> TyCtxt<'tcx> {
32643264
}
32653265
}
32663266

3267+
pub fn is_nounwind(self, def_id: DefId) -> bool {
3268+
self.mir_flags(def_id).contains(MirFlags::IS_NOUNWIND)
3269+
}
3270+
3271+
pub fn has_ffi_unwind_calls(self, def_id: DefId) -> bool {
3272+
self.mir_flags(def_id).contains(MirFlags::HAS_FFI_UNWIND_CALLS)
3273+
}
3274+
32673275
/// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
32683276
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
32693277
self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()

compiler/rustc_middle/src/ty/parameterized.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ trivially_parameterized_over_tcx! {
9898
rustc_hir::OpaqueTyOrigin<rustc_hir::def_id::DefId>,
9999
rustc_index::bit_set::DenseBitSet<u32>,
100100
rustc_index::bit_set::FiniteBitSet<u32>,
101+
rustc_middle::mir::MirFlags,
101102
rustc_session::cstore::ForeignModule,
102103
rustc_session::cstore::LinkagePreference,
103104
rustc_session::cstore::NativeLib,

compiler/rustc_mir_transform/src/ffi_unwind_calls.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_abi::ExternAbi;
2-
use rustc_hir::def_id::{LOCAL_CRATE, LocalDefId};
2+
use rustc_hir::def_id::LOCAL_CRATE;
33
use rustc_middle::mir::*;
44
use rustc_middle::query::{LocalCrate, Providers};
55
use rustc_middle::ty::{self, TyCtxt, layout};
@@ -11,17 +11,10 @@ use tracing::debug;
1111
use crate::errors;
1212

1313
// Check if the body of this def_id can possibly leak a foreign unwind into Rust code.
14-
fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
15-
debug!("has_ffi_unwind_calls({local_def_id:?})");
14+
pub(crate) fn has_ffi_unwind_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
15+
let def_id = body.source.def_id();
1616

17-
// Only perform check on functions because constants cannot call FFI functions.
18-
let def_id = local_def_id.to_def_id();
19-
let kind = tcx.def_kind(def_id);
20-
if !kind.is_fn_like() {
21-
return false;
22-
}
23-
24-
let body = &*tcx.mir_built(local_def_id).borrow();
17+
debug!("has_ffi_unwind_calls({def_id:?})");
2518

2619
let body_ty = tcx.type_of(def_id).skip_binder();
2720
let body_abi = match body_ty.kind() {
@@ -114,7 +107,7 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrate
114107
}
115108

116109
for def_id in tcx.hir_body_owners() {
117-
if tcx.has_ffi_unwind_calls(def_id) {
110+
if tcx.has_ffi_unwind_calls(def_id.into()) {
118111
// Given that this crate is compiled in `-C panic=unwind`, the `AbortUnwindingCalls`
119112
// MIR pass will not be run on FFI-unwind call sites, therefore a foreign exception
120113
// can enter Rust through these sites.
@@ -145,5 +138,5 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrate
145138
}
146139

147140
pub(crate) fn provide(providers: &mut Providers) {
148-
*providers = Providers { has_ffi_unwind_calls, required_panic_strategy, ..*providers };
141+
*providers = Providers { required_panic_strategy, ..*providers };
149142
}

0 commit comments

Comments
 (0)