Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit cc9057d

Browse files
committed
Auto merge of rust-lang#130909 - saethlin:infer-nounwind, r=<try>
Infer nounwind and use it in MIR opts r? `@ghost` Sinking this into `layout::fn_can_unwind` yields bigger MIR diffs. That's something to try tweaking. But also, this analysis reduces incrementality because call sites depend on callee bodies. So I've currently disabled it when incremental is enabled. That's another tweak I want to try.
2 parents f6cb952 + 5bf6851 commit cc9057d

28 files changed

+109
-46
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
870870
});
871871
sess.time("MIR_effect_checking", || {
872872
for def_id in tcx.hir().body_owners() {
873-
tcx.ensure().has_ffi_unwind_calls(def_id);
873+
tcx.ensure().mir_flags(def_id);
874874

875875
// If we need to codegen, ensure that we emit all errors from
876876
// `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
@@ -348,6 +348,7 @@ provide! { tcx, def_id, other, cdata,
348348
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
349349
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
350350
cross_crate_inlinable => { table_direct }
351+
mir_flags => { table_direct }
351352

352353
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
353354
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<ast::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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,15 @@ impl DefLocation {
17931793
}
17941794
}
17951795

1796+
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
1797+
pub struct MirFlags(u8);
1798+
bitflags::bitflags! {
1799+
impl MirFlags: u8 {
1800+
const IS_NOUNWIND = 1 << 0;
1801+
const HAS_FFI_UNWIND_CALLS = 1 << 1;
1802+
}
1803+
}
1804+
17961805
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
17971806
#[cfg(target_pointer_width = "64")]
17981807
mod size_asserts {

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ trivial! {
293293
rustc_middle::middle::resolve_bound_vars::ResolvedArg,
294294
rustc_middle::middle::stability::DeprecationEntry,
295295
rustc_middle::mir::ConstQualifs,
296+
rustc_middle::mir::MirFlags,
296297
rustc_middle::mir::interpret::AllocId,
297298
rustc_middle::mir::interpret::CtfeProvenance,
298299
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
@@ -56,6 +56,7 @@ use crate::middle::lib_features::LibFeatures;
5656
use crate::middle::privacy::EffectiveVisibilities;
5757
use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg};
5858
use crate::middle::stability::{self, DeprecationEntry};
59+
use crate::mir::MirFlags;
5960
use crate::mir::interpret::{
6061
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
6162
EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput,
@@ -1547,9 +1548,10 @@ rustc_queries! {
15471548
desc { "checking if a crate is `#![profiler_runtime]`" }
15481549
separate_provide_extern
15491550
}
1550-
query has_ffi_unwind_calls(key: LocalDefId) -> bool {
1551-
desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) }
1552-
cache_on_disk_if { true }
1551+
query mir_flags(key: DefId) -> MirFlags {
1552+
desc { |tcx| "stashing some local properties of `{}` before the body is stolen", tcx.def_path_str(key) }
1553+
cache_on_disk_if { key.is_local() }
1554+
separate_provide_extern
15531555
}
15541556
query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> {
15551557
fatal_cycle

compiler/rustc_middle/src/ty/context.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use crate::metadata::ModChild;
6464
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
6565
use crate::middle::{resolve_bound_vars, stability};
6666
use crate::mir::interpret::{self, Allocation, ConstAllocation};
67-
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
67+
use crate::mir::{Body, Local, MirFlags, Place, PlaceElem, ProjectionKind, Promoted};
6868
use crate::query::plumbing::QuerySystem;
6969
use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
7070
use crate::thir::Thir;
@@ -3206,6 +3206,14 @@ impl<'tcx> TyCtxt<'tcx> {
32063206
}
32073207
}
32083208

3209+
pub fn is_nounwind(self, def_id: DefId) -> bool {
3210+
self.mir_flags(def_id).contains(MirFlags::IS_NOUNWIND)
3211+
}
3212+
3213+
pub fn has_ffi_unwind_calls(self, def_id: DefId) -> bool {
3214+
self.mir_flags(def_id).contains(MirFlags::HAS_FFI_UNWIND_CALLS)
3215+
}
3216+
32093217
/// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
32103218
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
32113219
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::BitSet<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() {
@@ -112,7 +105,7 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrate
112105
}
113106

114107
for def_id in tcx.hir().body_owners() {
115-
if tcx.has_ffi_unwind_calls(def_id) {
108+
if tcx.has_ffi_unwind_calls(def_id.into()) {
116109
// Given that this crate is compiled in `-C panic=unwind`, the `AbortUnwindingCalls`
117110
// MIR pass will not be run on FFI-unwind call sites, therefore a foreign exception
118111
// can enter Rust through these sites.
@@ -143,5 +136,5 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrate
143136
}
144137

145138
pub(crate) fn provide(providers: &mut Providers) {
146-
*providers = Providers { has_ffi_unwind_calls, required_panic_strategy, ..*providers };
139+
*providers = Providers { required_panic_strategy, ..*providers };
147140
}

0 commit comments

Comments
 (0)