From c4bf37d35824cf22dade0c1c4595186a29a8714d Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 2 Jul 2025 18:10:57 +0200 Subject: [PATCH 1/5] Always inline InterpCx::layout_of after perf regression --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 068d6369f8769..41fc8d47cd369 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -96,7 +96,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// This inherent method takes priority over the trait method with the same name in LayoutOf, /// and allows wrapping the actual [LayoutOf::layout_of] with a tracing span. /// See [LayoutOf::layout_of] for the original documentation. - #[inline] + #[inline(always)] pub fn layout_of( &self, ty: Ty<'tcx>, From 07143afee43a4b516ca446e5e49570411043dfdb Mon Sep 17 00:00:00 2001 From: Stypox Date: Sat, 5 Jul 2025 11:13:04 +0200 Subject: [PATCH 2/5] Replace TRACING_ENABLED with enter_trace_span() Hopefully this will make tracing calls be optimized out properly when tracing is disabled --- .../rustc_const_eval/src/interpret/machine.rs | 20 +++++++++------- .../rustc_const_eval/src/interpret/mod.rs | 1 + .../rustc_const_eval/src/interpret/util.rs | 23 +++++++++---------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 844c19fea2dba..33afadd94f56b 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -18,8 +18,8 @@ use rustc_target::callconv::FnAbi; use super::{ AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation, - CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind, - Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup, + CtfeProvenance, EnteredTraceSpan, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, + MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, RangeSet, interp_ok, throw_unsup, }; /// Data returned by [`Machine::after_stack_pop`], and consumed by @@ -147,12 +147,6 @@ pub trait Machine<'tcx>: Sized { /// already been checked before. const ALL_CONSTS_ARE_PRECHECKED: bool = true; - /// Determines whether rustc_const_eval functions that make use of the [Machine] should make - /// tracing calls (to the `tracing` library). By default this is `false`, meaning the tracing - /// calls will supposedly be optimized out. This flag is set to `true` inside Miri, to allow - /// tracing the interpretation steps, among other things. - const TRACING_ENABLED: bool = false; - /// Whether memory accesses should be alignment-checked. fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool; @@ -634,6 +628,16 @@ pub trait Machine<'tcx>: Sized { /// Compute the value passed to the constructors of the `AllocBytes` type for /// abstract machine allocations. fn get_default_alloc_params(&self) -> ::AllocParams; + + /// Allows enabling/disabling tracing calls from within `rustc_const_eval` at compile time, by + /// delegating the entering of [tracing::Span]s to implementors of the [Machine] trait. The + /// default implementation corresponds to tracing being disabled, meaning the tracing calls will + /// supposedly be optimized out completely. To enable tracing, override this trait method and + /// return `span.entered()`. Also see [crate::enter_trace_span]. + #[must_use] + fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { + () + } } /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 8303f891f98b1..2fc372dd01978 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -37,6 +37,7 @@ pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; use self::place::{MemPlace, Place}; pub use self::projection::{OffsetMode, Projectable}; pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo}; +pub use self::util::EnteredTraceSpan; pub(crate) use self::util::create_static_alloc; pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking}; pub use self::visitor::ValueVisitor; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 99add01f95c60..eeab32fd79c67 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -46,21 +46,20 @@ pub(crate) fn create_static_alloc<'tcx>( interp_ok(ecx.ptr_to_mplace(Pointer::from(alloc_id).into(), layout)) } -/// This struct is needed to enforce `#[must_use]` on [tracing::span::EnteredSpan] -/// while wrapping them in an `Option`. -#[must_use] -pub enum MaybeEnteredSpan { - Some(tracing::span::EnteredSpan), - None, -} +/// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a +/// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when +/// tracing is disabled. +pub trait EnteredTraceSpan {} +impl EnteredTraceSpan for () {} +impl EnteredTraceSpan for tracing::span::EnteredSpan {} +/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span]. +/// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the +/// default implementation (i.e. when it does not actually enter the span but instead returns `()`). +/// Note: the result of this macro **must be used** because the span is exited when it's dropped. #[macro_export] macro_rules! enter_trace_span { ($machine:ident, $($tt:tt)*) => { - if $machine::TRACING_ENABLED { - $crate::interpret::util::MaybeEnteredSpan::Some(tracing::info_span!($($tt)*).entered()) - } else { - $crate::interpret::util::MaybeEnteredSpan::None - } + $machine::enter_trace_span(tracing::info_span!($($tt)*)) } } From 3cacaa7d0ebd8994f521fbcfc5277f8725f9348c Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 08:53:50 +0200 Subject: [PATCH 3/5] Add inline(always) to Machine::enter_trace_span --- compiler/rustc_const_eval/src/interpret/machine.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 33afadd94f56b..64aa971d14e9b 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -635,6 +635,7 @@ pub trait Machine<'tcx>: Sized { /// supposedly be optimized out completely. To enable tracing, override this trait method and /// return `span.entered()`. Also see [crate::enter_trace_span]. #[must_use] + #[inline(always)] fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { () } From e8c8330ba1a0fb7dcf8e74a8758569ab71261ef7 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 6 Jul 2025 08:58:19 +0200 Subject: [PATCH 4/5] Make enter_trace_span take a closure for better optimization --- compiler/rustc_const_eval/src/interpret/machine.rs | 2 +- compiler/rustc_const_eval/src/interpret/util.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 64aa971d14e9b..d150ed69250e5 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -636,7 +636,7 @@ pub trait Machine<'tcx>: Sized { /// return `span.entered()`. Also see [crate::enter_trace_span]. #[must_use] #[inline(always)] - fn enter_trace_span(_span: tracing::Span) -> impl EnteredTraceSpan { + fn enter_trace_span(_span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan { () } } diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index eeab32fd79c67..72650d545c3ca 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -60,6 +60,6 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {} #[macro_export] macro_rules! enter_trace_span { ($machine:ident, $($tt:tt)*) => { - $machine::enter_trace_span(tracing::info_span!($($tt)*)) + $machine::enter_trace_span(|| tracing::info_span!($($tt)*)) } } From e5f7d4d783c1567ddc16e02091bae8bacfca1418 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 8 Jul 2025 15:37:01 +0200 Subject: [PATCH 5/5] Implement enter_trace_span() in MiriMachine --- src/tools/miri/src/machine.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 693b8916d89f3..35399dbf4cb0c 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1014,8 +1014,6 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { const PANIC_ON_ALLOC_FAIL: bool = false; - const TRACING_ENABLED: bool = cfg!(feature = "tracing"); - #[inline(always)] fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool { ecx.machine.check_alignment != AlignmentCheck::None @@ -1827,6 +1825,16 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { #[cfg(not(target_os = "linux"))] MiriAllocParams::Global } + + fn enter_trace_span(span: impl FnOnce() -> tracing::Span) -> impl EnteredTraceSpan { + #[cfg(feature = "tracing")] + { span().entered() } + #[cfg(not(feature = "tracing"))] + { + let _ = span; // so we avoid the "unused variable" warning + () + } + } } /// Trait for callbacks handling asynchronous machine operations.