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

Commit 2696107

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 fa724e5 + f0b3a5e commit 2696107

26 files changed

+106
-44
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
808808
});
809809
sess.time("MIR_effect_checking", || {
810810
for def_id in tcx.hir().body_owners() {
811-
tcx.ensure().has_ffi_unwind_calls(def_id);
811+
tcx.ensure().mir_flags(def_id);
812812

813813
// If we need to codegen, ensure that we emit all errors from
814814
// `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
@@ -352,6 +352,7 @@ provide! { tcx, def_id, other, cdata,
352352
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
353353
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
354354
cross_crate_inlinable => { table_direct }
355+
mir_flags => { table_direct }
355356

356357
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
357358
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
@@ -24,6 +24,7 @@ use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2424
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
2525
use rustc_middle::middle::lib_features::FeatureStability;
2626
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
27+
use rustc_middle::mir::MirFlags;
2728
use rustc_middle::ty::fast_reject::SimplifiedType;
2829
use rustc_middle::ty::{
2930
self, DeducedParamAttrs, ParameterizedOverTcx, ReprOptions, Ty, TyCtxt, UnusedGenericParams,
@@ -404,6 +405,7 @@ define_tables! {
404405
// individually instead of `DefId`s.
405406
module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
406407
cross_crate_inlinable: Table<DefIndex, bool>,
408+
mir_flags: Table<DefIndex, MirFlags>,
407409

408410
- optional:
409411
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
@@ -54,6 +54,12 @@ impl IsDefault for UnusedGenericParams {
5454
}
5555
}
5656

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

294+
impl FixedSizeEncoding for MirFlags {
295+
type ByteArray = [u8; 1];
296+
297+
#[inline]
298+
fn from_bytes(b: &[u8; 1]) -> Self {
299+
MirFlags::from_bits_truncate(b[0])
300+
}
301+
302+
#[inline]
303+
fn write_to_bytes(self, b: &mut [u8; 1]) {
304+
debug_assert!(!self.is_default());
305+
b[0] = self.bits();
306+
}
307+
}
308+
288309
impl FixedSizeEncoding for bool {
289310
type ByteArray = [u8; 1];
290311

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,15 @@ impl DefLocation {
17811781
}
17821782
}
17831783

1784+
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
1785+
pub struct MirFlags(u8);
1786+
bitflags::bitflags! {
1787+
impl MirFlags: u8 {
1788+
const IS_NOUNWIND = 1 << 0;
1789+
const HAS_FFI_UNWIND_CALLS = 1 << 1;
1790+
}
1791+
}
1792+
17841793
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
17851794
#[cfg(target_pointer_width = "64")]
17861795
mod size_asserts {

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ trivial! {
289289
rustc_middle::middle::resolve_bound_vars::ResolvedArg,
290290
rustc_middle::middle::stability::DeprecationEntry,
291291
rustc_middle::mir::ConstQualifs,
292+
rustc_middle::mir::MirFlags,
292293
rustc_middle::mir::interpret::AllocId,
293294
rustc_middle::mir::interpret::CtfeProvenance,
294295
rustc_middle::mir::interpret::ErrorHandled,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use crate::middle::lib_features::LibFeatures;
5454
use crate::middle::privacy::EffectiveVisibilities;
5555
use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg};
5656
use crate::middle::stability::{self, DeprecationEntry};
57+
use crate::mir::MirFlags;
5758
use crate::mir::interpret::{
5859
EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
5960
EvalToValTreeResult, GlobalId, LitToConstError, LitToConstInput,
@@ -1501,9 +1502,9 @@ rustc_queries! {
15011502
desc { "checking if a crate is `#![profiler_runtime]`" }
15021503
separate_provide_extern
15031504
}
1504-
query has_ffi_unwind_calls(key: LocalDefId) -> bool {
1505-
desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) }
1506-
cache_on_disk_if { true }
1505+
query mir_flags(key: DefId) -> MirFlags {
1506+
desc { |tcx| "stashing some local properties of `{}` before the body is stolen", tcx.def_path_str(key) }
1507+
separate_provide_extern
15071508
}
15081509
query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> {
15091510
fatal_cycle

compiler/rustc_middle/src/ty/context.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use crate::metadata::ModChild;
6666
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
6767
use crate::middle::{resolve_bound_vars, stability};
6868
use crate::mir::interpret::{self, Allocation, ConstAllocation};
69-
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
69+
use crate::mir::{Body, Local, MirFlags, Place, PlaceElem, ProjectionKind, Promoted};
7070
use crate::query::plumbing::QuerySystem;
7171
use crate::query::{IntoQueryParam, LocalCrate, Providers, TyCtxtAt};
7272
use crate::thir::Thir;
@@ -3180,6 +3180,14 @@ impl<'tcx> TyCtxt<'tcx> {
31803180
}
31813181
}
31823182

3183+
pub fn is_nounwind(self, def_id: DefId) -> bool {
3184+
self.mir_flags(def_id).contains(MirFlags::IS_NOUNWIND)
3185+
}
3186+
3187+
pub fn has_ffi_unwind_calls(self, def_id: DefId) -> bool {
3188+
self.mir_flags(def_id).contains(MirFlags::HAS_FFI_UNWIND_CALLS)
3189+
}
3190+
31833191
/// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]`
31843192
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
31853193
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
@@ -96,6 +96,7 @@ trivially_parameterized_over_tcx! {
9696
rustc_hir::definitions::DefKey,
9797
rustc_index::bit_set::BitSet<u32>,
9898
rustc_index::bit_set::FiniteBitSet<u32>,
99+
rustc_middle::mir::MirFlags,
99100
rustc_session::cstore::ForeignModule,
100101
rustc_session::cstore::LinkagePreference,
101102
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,4 +1,4 @@
1-
use rustc_hir::def_id::{LOCAL_CRATE, LocalDefId};
1+
use rustc_hir::def_id::LOCAL_CRATE;
22
use rustc_middle::mir::*;
33
use rustc_middle::query::{LocalCrate, Providers};
44
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() {
@@ -108,7 +101,7 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrate
108101
}
109102

110103
for def_id in tcx.hir().body_owners() {
111-
if tcx.has_ffi_unwind_calls(def_id) {
104+
if tcx.has_ffi_unwind_calls(def_id.into()) {
112105
// Given that this crate is compiled in `-C panic=unwind`, the `AbortUnwindingCalls`
113106
// MIR pass will not be run on FFI-unwind call sites, therefore a foreign exception
114107
// can enter Rust through these sites.
@@ -139,5 +132,5 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrate
139132
}
140133

141134
pub(crate) fn provide(providers: &mut Providers) {
142-
*providers = Providers { has_ffi_unwind_calls, required_panic_strategy, ..*providers };
135+
*providers = Providers { required_panic_strategy, ..*providers };
143136
}

0 commit comments

Comments
 (0)