Skip to content

Commit fe12323

Browse files
authoredJun 1, 2023
Rollup merge of #112128 - nnethercote:no-inlining-advance, r=wesleywiser
Don't compute inlining status of mono items in advance. We record inlining status for mono items in `MonoItems`, and then transfer it to `InliningMap`, for later use in `InliningMap::with_inlining_candidates`. But we can just compute inlining status directly in `InliningMap::with_inlining_candidates`, because the mono item is right there. There's no need to compute it in advance. This commit changes the code to do that, removing the need for `MonoItems` and `InliningMap::inlines`. This does result in more calls to `instantiation_mode` (one per static occurrence) but the performance effect is negligible. r? ``@wesleywiser``
2 parents 02c4b4b + cc21d9a commit fe12323

File tree

2 files changed

+17
-66
lines changed

2 files changed

+17
-66
lines changed
 

‎compiler/rustc_monomorphize/src/collector.rs

+13-63
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ use rustc_hir as hir;
179179
use rustc_hir::def::DefKind;
180180
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
181181
use rustc_hir::lang_items::LangItem;
182-
use rustc_index::bit_set::GrowableBitSet;
183182
use rustc_middle::mir::interpret::{AllocId, ConstValue};
184183
use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
185184
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
@@ -220,78 +219,29 @@ pub struct InliningMap<'tcx> {
220219
// The range selects elements within the `targets` vecs.
221220
index: FxHashMap<MonoItem<'tcx>, Range<usize>>,
222221
targets: Vec<MonoItem<'tcx>>,
223-
224-
// Contains one bit per mono item in the `targets` field. That bit
225-
// is true if that mono item needs to be inlined into every CGU.
226-
inlines: GrowableBitSet<usize>,
227-
}
228-
229-
/// Struct to store mono items in each collecting and if they should
230-
/// be inlined. We call `instantiation_mode` to get their inlining
231-
/// status when inserting new elements, which avoids calling it in
232-
/// `inlining_map.lock_mut()`. See the `collect_items_rec` implementation
233-
/// below.
234-
struct MonoItems<'tcx> {
235-
// If this is false, we do not need to compute whether items
236-
// will need to be inlined.
237-
compute_inlining: bool,
238-
239-
// The TyCtxt used to determine whether the a item should
240-
// be inlined.
241-
tcx: TyCtxt<'tcx>,
242-
243-
// The collected mono items. The bool field in each element
244-
// indicates whether this element should be inlined.
245-
items: Vec<(Spanned<MonoItem<'tcx>>, bool /*inlined*/)>,
246222
}
247223

248-
impl<'tcx> MonoItems<'tcx> {
249-
#[inline]
250-
fn push(&mut self, item: Spanned<MonoItem<'tcx>>) {
251-
self.extend([item]);
252-
}
253-
254-
#[inline]
255-
fn extend<T: IntoIterator<Item = Spanned<MonoItem<'tcx>>>>(&mut self, iter: T) {
256-
self.items.extend(iter.into_iter().map(|mono_item| {
257-
let inlined = if !self.compute_inlining {
258-
false
259-
} else {
260-
mono_item.node.instantiation_mode(self.tcx) == InstantiationMode::LocalCopy
261-
};
262-
(mono_item, inlined)
263-
}))
264-
}
265-
}
224+
type MonoItems<'tcx> = Vec<Spanned<MonoItem<'tcx>>>;
266225

267226
impl<'tcx> InliningMap<'tcx> {
268227
fn new() -> InliningMap<'tcx> {
269-
InliningMap {
270-
index: FxHashMap::default(),
271-
targets: Vec::new(),
272-
inlines: GrowableBitSet::with_capacity(1024),
273-
}
228+
InliningMap { index: FxHashMap::default(), targets: Vec::new() }
274229
}
275230

276231
fn record_accesses<'a>(
277232
&mut self,
278233
source: MonoItem<'tcx>,
279-
new_targets: &'a [(Spanned<MonoItem<'tcx>>, bool)],
234+
new_targets: &'a [Spanned<MonoItem<'tcx>>],
280235
) where
281236
'tcx: 'a,
282237
{
283238
let start_index = self.targets.len();
284239
let new_items_count = new_targets.len();
285-
let new_items_count_total = new_items_count + self.targets.len();
286240

287241
self.targets.reserve(new_items_count);
288-
self.inlines.ensure(new_items_count_total);
289242

290-
for (i, (Spanned { node: mono_item, .. }, inlined)) in new_targets.into_iter().enumerate() {
243+
for Spanned { node: mono_item, .. } in new_targets.into_iter() {
291244
self.targets.push(*mono_item);
292-
if *inlined {
293-
self.inlines.insert(i + start_index);
294-
}
295245
}
296246

297247
let end_index = self.targets.len();
@@ -300,13 +250,14 @@ impl<'tcx> InliningMap<'tcx> {
300250

301251
/// Internally iterate over all items referenced by `source` which will be
302252
/// made available for inlining.
303-
pub fn with_inlining_candidates<F>(&self, source: MonoItem<'tcx>, mut f: F)
253+
pub fn with_inlining_candidates<F>(&self, tcx: TyCtxt<'tcx>, source: MonoItem<'tcx>, mut f: F)
304254
where
305255
F: FnMut(MonoItem<'tcx>),
306256
{
307257
if let Some(range) = self.index.get(&source) {
308-
for (i, candidate) in self.targets[range.clone()].iter().enumerate() {
309-
if self.inlines.contains(range.start + i) {
258+
for candidate in self.targets[range.clone()].iter() {
259+
let is_inlined = candidate.instantiation_mode(tcx) == InstantiationMode::LocalCopy;
260+
if is_inlined {
310261
f(*candidate);
311262
}
312263
}
@@ -367,7 +318,7 @@ pub fn collect_crate_mono_items(
367318
#[instrument(skip(tcx, mode), level = "debug")]
368319
fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<'_>> {
369320
debug!("collecting roots");
370-
let mut roots = MonoItems { compute_inlining: false, tcx, items: Vec::new() };
321+
let mut roots = Vec::new();
371322

372323
{
373324
let entry_fn = tcx.entry_fn(());
@@ -393,9 +344,8 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
393344
// whose predicates hold. Luckily, items that aren't instantiable
394345
// can't actually be used, so we can just skip codegenning them.
395346
roots
396-
.items
397347
.into_iter()
398-
.filter_map(|(Spanned { node: mono_item, .. }, _)| {
348+
.filter_map(|Spanned { node: mono_item, .. }| {
399349
mono_item.is_instantiable(tcx).then_some(mono_item)
400350
})
401351
.collect()
@@ -417,7 +367,7 @@ fn collect_items_rec<'tcx>(
417367
return;
418368
}
419369

420-
let mut neighbors = MonoItems { compute_inlining: true, tcx, items: Vec::new() };
370+
let mut neighbors = Vec::new();
421371
let recursion_depth_reset;
422372

423373
//
@@ -542,9 +492,9 @@ fn collect_items_rec<'tcx>(
542492
formatted_item,
543493
});
544494
}
545-
inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors.items);
495+
inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors);
546496

547-
for (neighbour, _) in neighbors.items {
497+
for neighbour in neighbors {
548498
collect_items_rec(tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map);
549499
}
550500

‎compiler/rustc_monomorphize/src/partitioning.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ fn place_inlined_mono_items<'tcx>(
424424
// Collect all items that need to be available in this codegen unit.
425425
let mut reachable = FxHashSet::default();
426426
for root in old_codegen_unit.items().keys() {
427-
follow_inlining(*root, cx.inlining_map, &mut reachable);
427+
follow_inlining(cx.tcx, *root, cx.inlining_map, &mut reachable);
428428
}
429429

430430
let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
@@ -478,6 +478,7 @@ fn place_inlined_mono_items<'tcx>(
478478
return mono_item_placements;
479479

480480
fn follow_inlining<'tcx>(
481+
tcx: TyCtxt<'tcx>,
481482
mono_item: MonoItem<'tcx>,
482483
inlining_map: &InliningMap<'tcx>,
483484
visited: &mut FxHashSet<MonoItem<'tcx>>,
@@ -486,8 +487,8 @@ fn place_inlined_mono_items<'tcx>(
486487
return;
487488
}
488489

489-
inlining_map.with_inlining_candidates(mono_item, |target| {
490-
follow_inlining(target, inlining_map, visited);
490+
inlining_map.with_inlining_candidates(tcx, mono_item, |target| {
491+
follow_inlining(tcx, target, inlining_map, visited);
491492
});
492493
}
493494
}

0 commit comments

Comments
 (0)
Please sign in to comment.