Compare commits

...

6 Commits

Author SHA1 Message Date
rust-bors[bot]
8bf899e558
Auto merge of #147045 - notriddle:search-index-entrydata-path, r=<try>
rustdoc-search: use the same ID for entry and path to same item
2025-09-25 20:55:22 +00:00
Michael Howell
b9037f97e3 rustdoc-search: use the same ID for entry and path to same item
This decreases the size of the compiler-doc from 57MiB to 56MiB.
2025-09-25 13:48:29 -07:00
bors
eabf390b4c Auto merge of #146697 - cjgillot:invalidate-patch, r=lcnr
Avoid invalidating CFG caches from MirPatch::apply.

Small effort to reduce invalidating CFG caches.
2025-09-25 17:19:29 +00:00
Camille Gillot
ce677c7db8
Update compiler/rustc_mir_transform/src/patch.rs
Co-authored-by: lcnr <rust@lcnr.de>
2025-09-23 20:38:38 -03:00
Camille Gillot
3c232fe38f Make term_patch_map sparse. 2025-09-20 13:53:58 +00:00
Camille Gillot
b216cf34b1 Avoid invalidating from MirPatch::apply. 2025-09-18 01:09:53 +00:00
2 changed files with 45 additions and 23 deletions

View File

@ -1,4 +1,5 @@
use rustc_index::{Idx, IndexVec}; use rustc_data_structures::fx::FxHashMap;
use rustc_index::Idx;
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use rustc_span::Span; use rustc_span::Span;
@ -9,7 +10,7 @@ use tracing::debug;
/// and replacement of terminators, and then apply the queued changes all at /// and replacement of terminators, and then apply the queued changes all at
/// once with `apply`. This is useful for MIR transformation passes. /// once with `apply`. This is useful for MIR transformation passes.
pub(crate) struct MirPatch<'tcx> { pub(crate) struct MirPatch<'tcx> {
term_patch_map: IndexVec<BasicBlock, Option<TerminatorKind<'tcx>>>, term_patch_map: FxHashMap<BasicBlock, TerminatorKind<'tcx>>,
new_blocks: Vec<BasicBlockData<'tcx>>, new_blocks: Vec<BasicBlockData<'tcx>>,
new_statements: Vec<(Location, StatementKind<'tcx>)>, new_statements: Vec<(Location, StatementKind<'tcx>)>,
new_locals: Vec<LocalDecl<'tcx>>, new_locals: Vec<LocalDecl<'tcx>>,
@ -22,17 +23,21 @@ pub(crate) struct MirPatch<'tcx> {
terminate_block: Option<(BasicBlock, UnwindTerminateReason)>, terminate_block: Option<(BasicBlock, UnwindTerminateReason)>,
body_span: Span, body_span: Span,
next_local: usize, next_local: usize,
/// The number of blocks at the start of the transformation. New blocks
/// get appended at the end.
next_block: usize,
} }
impl<'tcx> MirPatch<'tcx> { impl<'tcx> MirPatch<'tcx> {
/// Creates a new, empty patch. /// Creates a new, empty patch.
pub(crate) fn new(body: &Body<'tcx>) -> Self { pub(crate) fn new(body: &Body<'tcx>) -> Self {
let mut result = MirPatch { let mut result = MirPatch {
term_patch_map: IndexVec::from_elem(None, &body.basic_blocks), term_patch_map: Default::default(),
new_blocks: vec![], new_blocks: vec![],
new_statements: vec![], new_statements: vec![],
new_locals: vec![], new_locals: vec![],
next_local: body.local_decls.len(), next_local: body.local_decls.len(),
next_block: body.basic_blocks.len(),
resume_block: None, resume_block: None,
unreachable_cleanup_block: None, unreachable_cleanup_block: None,
unreachable_no_cleanup_block: None, unreachable_no_cleanup_block: None,
@ -141,7 +146,7 @@ impl<'tcx> MirPatch<'tcx> {
/// Has a replacement of this block's terminator been queued in this patch? /// Has a replacement of this block's terminator been queued in this patch?
pub(crate) fn is_term_patched(&self, bb: BasicBlock) -> bool { pub(crate) fn is_term_patched(&self, bb: BasicBlock) -> bool {
self.term_patch_map[bb].is_some() self.term_patch_map.contains_key(&bb)
} }
/// Universal getter for block data, either it is in 'old' blocks or in patched ones /// Universal getter for block data, either it is in 'old' blocks or in patched ones
@ -194,18 +199,17 @@ impl<'tcx> MirPatch<'tcx> {
/// Queues the addition of a new basic block. /// Queues the addition of a new basic block.
pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock { pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock {
let block = self.term_patch_map.next_index(); let block = BasicBlock::from_usize(self.next_block + self.new_blocks.len());
debug!("MirPatch: new_block: {:?}: {:?}", block, data); debug!("MirPatch: new_block: {:?}: {:?}", block, data);
self.new_blocks.push(data); self.new_blocks.push(data);
self.term_patch_map.push(None);
block block
} }
/// Queues the replacement of a block's terminator. /// Queues the replacement of a block's terminator.
pub(crate) fn patch_terminator(&mut self, block: BasicBlock, new: TerminatorKind<'tcx>) { pub(crate) fn patch_terminator(&mut self, block: BasicBlock, new: TerminatorKind<'tcx>) {
assert!(self.term_patch_map[block].is_none()); assert!(!self.term_patch_map.contains_key(&block));
debug!("MirPatch: patch_terminator({:?}, {:?})", block, new); debug!("MirPatch: patch_terminator({:?}, {:?})", block, new);
self.term_patch_map[block] = Some(new); self.term_patch_map.insert(block, new);
} }
/// Queues the insertion of a statement at a given location. The statement /// Queues the insertion of a statement at a given location. The statement
@ -244,6 +248,7 @@ impl<'tcx> MirPatch<'tcx> {
self.new_blocks.len(), self.new_blocks.len(),
body.basic_blocks.len() body.basic_blocks.len()
); );
debug_assert_eq!(self.next_block, body.basic_blocks.len());
let bbs = if self.term_patch_map.is_empty() && self.new_blocks.is_empty() { let bbs = if self.term_patch_map.is_empty() && self.new_blocks.is_empty() {
body.basic_blocks.as_mut_preserves_cfg() body.basic_blocks.as_mut_preserves_cfg()
} else { } else {
@ -251,11 +256,12 @@ impl<'tcx> MirPatch<'tcx> {
}; };
bbs.extend(self.new_blocks); bbs.extend(self.new_blocks);
body.local_decls.extend(self.new_locals); body.local_decls.extend(self.new_locals);
for (src, patch) in self.term_patch_map.into_iter_enumerated() {
if let Some(patch) = patch { // The order in which we patch terminators does not change the result.
debug!("MirPatch: patching block {:?}", src); #[allow(rustc::potential_query_instability)]
bbs[src].terminator_mut().kind = patch; for (src, patch) in self.term_patch_map {
} debug!("MirPatch: patching block {:?}", src);
bbs[src].terminator_mut().kind = patch;
} }
let mut new_statements = self.new_statements; let mut new_statements = self.new_statements;
@ -273,8 +279,8 @@ impl<'tcx> MirPatch<'tcx> {
} }
debug!("MirPatch: adding statement {:?} at loc {:?}+{}", stmt, loc, delta); debug!("MirPatch: adding statement {:?} at loc {:?}+{}", stmt, loc, delta);
loc.statement_index += delta; loc.statement_index += delta;
let source_info = Self::source_info_for_index(&body[loc.block], loc); let source_info = Self::source_info_for_index(&bbs[loc.block], loc);
body[loc.block] bbs[loc.block]
.statements .statements
.insert(loc.statement_index, Statement::new(source_info, stmt)); .insert(loc.statement_index, Statement::new(source_info, stmt));
delta += 1; delta += 1;

View File

@ -241,6 +241,26 @@ impl SerializedSearchIndex {
self.alias_pointers.push(alias_pointer); self.alias_pointers.push(alias_pointer);
index index
} }
fn add_entry(&mut self, name: Symbol, entry_data: EntryData, desc: String) -> usize {
let fqp = if let Some(module_path_index) = entry_data.module_path {
let mut fqp = self.path_data[module_path_index].as_ref().unwrap().module_path.clone();
fqp.push(Symbol::intern(&self.names[module_path_index]));
fqp.push(name);
fqp
} else {
vec![name]
};
if let Some(&other_path) = self.crate_paths_index.get(&(entry_data.ty, fqp))
&& self.entry_data[other_path].is_none()
&& self.descs[other_path].is_empty()
{
self.entry_data[other_path] = Some(entry_data);
self.descs[other_path] = desc;
other_path
} else {
self.push(name.as_str().to_string(), None, Some(entry_data), desc, None, None, None)
}
}
fn push_path(&mut self, name: String, path_data: PathData) -> usize { fn push_path(&mut self, name: String, path_data: PathData) -> usize {
self.push(name, Some(path_data), None, String::new(), None, None, None) self.push(name, Some(path_data), None, String::new(), None, None, None)
} }
@ -1516,10 +1536,9 @@ pub(crate) fn build_index(
.as_ref() .as_ref()
.map(|path| serialized_index.get_id_by_module_path(path)); .map(|path| serialized_index.get_id_by_module_path(path));
let new_entry_id = serialized_index.push( let new_entry_id = serialized_index.add_entry(
item.name.as_str().to_string(), item.name,
None, EntryData {
Some(EntryData {
ty: item.ty, ty: item.ty,
parent: item.parent_idx, parent: item.parent_idx,
module_path, module_path,
@ -1538,11 +1557,8 @@ pub(crate) fn build_index(
None None
}, },
krate: crate_idx, krate: crate_idx,
}), },
item.desc.to_string(), item.desc.to_string(),
None, // filled in after all the types have been indexed
None,
None,
); );
// Aliases // Aliases