From f5a5a37062a4ace189dbf98a4e653a18312a12fc Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 15 Jun 2025 13:59:41 +0000 Subject: [PATCH 1/2] Inform RegionRenumberer that it preserves MIR CFG. --- compiler/rustc_borrowck/src/renumber.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index ff92b4168a86c..037ebc9c0a7a3 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -21,10 +21,10 @@ pub(crate) fn renumber_mir<'tcx>( let mut renumberer = RegionRenumberer { infcx }; for body in promoted.iter_mut() { - renumberer.visit_body(body); + renumberer.visit_body_preserves_cfg(body); } - renumberer.visit_body(body); + renumberer.visit_body_preserves_cfg(body); } // The fields are used only for debugging output in `sccs_info`. From 184e17c48dc4f2851373aa61ec638a94306ffddd Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 15 Jun 2025 14:16:11 +0000 Subject: [PATCH 2/2] Use an Arc to share caches between clones. --- compiler/rustc_middle/src/mir/basic_blocks.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 0d2e23609ce35..aae815c0be046 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -1,4 +1,4 @@ -use std::sync::OnceLock; +use std::sync::{Arc, OnceLock}; use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{Dominators, dominators}; @@ -14,7 +14,8 @@ use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK}; #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] pub struct BasicBlocks<'tcx> { basic_blocks: IndexVec>, - cache: Cache, + /// Use an `Arc` so we can share the cache when we clone the MIR body, as borrowck does. + cache: Arc, } // Typically 95%+ of basic blocks have 4 or fewer predecessors. @@ -38,9 +39,10 @@ struct Cache { impl<'tcx> BasicBlocks<'tcx> { #[inline] pub fn new(basic_blocks: IndexVec>) -> Self { - BasicBlocks { basic_blocks, cache: Cache::default() } + BasicBlocks { basic_blocks, cache: Arc::new(Cache::default()) } } + #[inline] pub fn dominators(&self) -> &Dominators { self.cache.dominators.get_or_init(|| dominators(self)) } @@ -104,7 +106,14 @@ impl<'tcx> BasicBlocks<'tcx> { /// All other methods that allow you to mutate the basic blocks also call this method /// themselves, thereby avoiding any risk of accidentally cache invalidation. pub fn invalidate_cfg_cache(&mut self) { - self.cache = Cache::default(); + if let Some(cache) = Arc::get_mut(&mut self.cache) { + // If we only have a single reference to this cache, clear it. + *cache = Cache::default(); + } else { + // If we have several references to this cache, overwrite the pointer itself so other + // users can continue to use their (valid) cache. + self.cache = Arc::new(Cache::default()); + } } }