Skip to content

Commit 2c2f1c2

Browse files
authored
Rollup merge of #76694 - wesleywiser:partitioning_cx_trait, r=davidtwco
Introduce a PartitioningCx struct This contains all the data used by the partitioning algorithm and allows that data to be used at each stage of the partitioning. This is useful for other approaches to partitioning which may want different pieces of the data available at each step. cc @rust-lang/wg-incr-comp
2 parents c8bfbad + c9686cb commit 2c2f1c2

File tree

3 files changed

+38
-34
lines changed

3 files changed

+38
-34
lines changed

compiler/rustc_mir/src/monomorphize/partitioning/default.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_middle::ty::print::characteristic_def_id_of_type;
1111
use rustc_middle::ty::{self, DefIdTree, InstanceDef, TyCtxt};
1212
use rustc_span::symbol::Symbol;
1313

14+
use super::PartitioningCx;
1415
use crate::monomorphize::collector::InliningMap;
1516
use crate::monomorphize::partitioning::merging;
1617
use crate::monomorphize::partitioning::{
@@ -22,35 +23,36 @@ pub struct DefaultPartitioning;
2223
impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
2324
fn place_root_mono_items(
2425
&mut self,
25-
tcx: TyCtxt<'tcx>,
26+
cx: &PartitioningCx<'_, 'tcx>,
2627
mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>,
2728
) -> PreInliningPartitioning<'tcx> {
2829
let mut roots = FxHashSet::default();
2930
let mut codegen_units = FxHashMap::default();
30-
let is_incremental_build = tcx.sess.opts.incremental.is_some();
31+
let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
3132
let mut internalization_candidates = FxHashSet::default();
3233

3334
// Determine if monomorphizations instantiated in this crate will be made
3435
// available to downstream crates. This depends on whether we are in
3536
// share-generics mode and whether the current crate can even have
3637
// downstream crates.
37-
let export_generics = tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics();
38+
let export_generics =
39+
cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics();
3840

39-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
41+
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
4042
let cgu_name_cache = &mut FxHashMap::default();
4143

4244
for mono_item in mono_items {
43-
match mono_item.instantiation_mode(tcx) {
45+
match mono_item.instantiation_mode(cx.tcx) {
4446
InstantiationMode::GloballyShared { .. } => {}
4547
InstantiationMode::LocalCopy => continue,
4648
}
4749

48-
let characteristic_def_id = characteristic_def_id_of_mono_item(tcx, mono_item);
50+
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
4951
let is_volatile = is_incremental_build && mono_item.is_generic_fn();
5052

5153
let codegen_unit_name = match characteristic_def_id {
5254
Some(def_id) => compute_codegen_unit_name(
53-
tcx,
55+
cx.tcx,
5456
cgu_name_builder,
5557
def_id,
5658
is_volatile,
@@ -65,7 +67,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
6567

6668
let mut can_be_internalized = true;
6769
let (linkage, visibility) = mono_item_linkage_and_visibility(
68-
tcx,
70+
cx.tcx,
6971
&mono_item,
7072
&mut can_be_internalized,
7173
export_generics,
@@ -97,17 +99,16 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
9799

98100
fn merge_codegen_units(
99101
&mut self,
100-
tcx: TyCtxt<'tcx>,
102+
cx: &PartitioningCx<'_, 'tcx>,
101103
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
102-
target_cgu_count: usize,
103104
) {
104-
merging::merge_codegen_units(tcx, initial_partitioning, target_cgu_count);
105+
merging::merge_codegen_units(cx, initial_partitioning);
105106
}
106107

107108
fn place_inlined_mono_items(
108109
&mut self,
110+
cx: &PartitioningCx<'_, 'tcx>,
109111
initial_partitioning: PreInliningPartitioning<'tcx>,
110-
inlining_map: &InliningMap<'tcx>,
111112
) -> PostInliningPartitioning<'tcx> {
112113
let mut new_partitioning = Vec::new();
113114
let mut mono_item_placements = FxHashMap::default();
@@ -124,7 +125,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
124125
// Collect all items that need to be available in this codegen unit.
125126
let mut reachable = FxHashSet::default();
126127
for root in old_codegen_unit.items().keys() {
127-
follow_inlining(*root, inlining_map, &mut reachable);
128+
follow_inlining(*root, cx.inlining_map, &mut reachable);
128129
}
129130

130131
let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name());
@@ -198,9 +199,8 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
198199

199200
fn internalize_symbols(
200201
&mut self,
201-
_tcx: TyCtxt<'tcx>,
202+
cx: &PartitioningCx<'_, 'tcx>,
202203
partitioning: &mut PostInliningPartitioning<'tcx>,
203-
inlining_map: &InliningMap<'tcx>,
204204
) {
205205
if partitioning.codegen_units.len() == 1 {
206206
// Fast path for when there is only one codegen unit. In this case we
@@ -218,7 +218,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
218218
// Build a map from every monomorphization to all the monomorphizations that
219219
// reference it.
220220
let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
221-
inlining_map.iter_accesses(|accessor, accessees| {
221+
cx.inlining_map.iter_accesses(|accessor, accessees| {
222222
for accessee in accessees {
223223
accessor_map.entry(*accessee).or_default().push(accessor);
224224
}

compiler/rustc_mir/src/monomorphize/partitioning/merging.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@ use std::cmp;
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_hir::def_id::LOCAL_CRATE;
55
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder};
6-
use rustc_middle::ty::TyCtxt;
76
use rustc_span::symbol::{Symbol, SymbolStr};
87

8+
use super::PartitioningCx;
99
use crate::monomorphize::partitioning::PreInliningPartitioning;
1010

1111
pub fn merge_codegen_units<'tcx>(
12-
tcx: TyCtxt<'tcx>,
12+
cx: &PartitioningCx<'_, 'tcx>,
1313
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
14-
target_cgu_count: usize,
1514
) {
16-
assert!(target_cgu_count >= 1);
15+
assert!(cx.target_cgu_count >= 1);
1716
let codegen_units = &mut initial_partitioning.codegen_units;
1817

1918
// Note that at this point in time the `codegen_units` here may not be in a
@@ -32,7 +31,7 @@ pub fn merge_codegen_units<'tcx>(
3231
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name().as_str()])).collect();
3332

3433
// Merge the two smallest codegen units until the target size is reached.
35-
while codegen_units.len() > target_cgu_count {
34+
while codegen_units.len() > cx.target_cgu_count {
3635
// Sort small cgus to the back
3736
codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
3837
let mut smallest = codegen_units.pop().unwrap();
@@ -56,9 +55,9 @@ pub fn merge_codegen_units<'tcx>(
5655
);
5756
}
5857

59-
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
58+
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
6059

61-
if tcx.sess.opts.incremental.is_some() {
60+
if cx.tcx.sess.opts.incremental.is_some() {
6261
// If we are doing incremental compilation, we want CGU names to
6362
// reflect the path of the source level module they correspond to.
6463
// For CGUs that contain the code of multiple modules because of the
@@ -84,7 +83,7 @@ pub fn merge_codegen_units<'tcx>(
8483

8584
for cgu in codegen_units.iter_mut() {
8685
if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
87-
if tcx.sess.opts.debugging_opts.human_readable_cgu_names {
86+
if cx.tcx.sess.opts.debugging_opts.human_readable_cgu_names {
8887
cgu.set_name(Symbol::intern(&new_cgu_name));
8988
} else {
9089
// If we don't require CGU names to be human-readable, we

compiler/rustc_mir/src/monomorphize/partitioning/mod.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -108,31 +108,35 @@ use rustc_span::symbol::Symbol;
108108
use crate::monomorphize::collector::InliningMap;
109109
use crate::monomorphize::collector::{self, MonoItemCollectionMode};
110110

111+
pub struct PartitioningCx<'a, 'tcx> {
112+
tcx: TyCtxt<'tcx>,
113+
target_cgu_count: usize,
114+
inlining_map: &'a InliningMap<'tcx>,
115+
}
116+
111117
trait Partitioner<'tcx> {
112118
fn place_root_mono_items(
113119
&mut self,
114-
tcx: TyCtxt<'tcx>,
120+
cx: &PartitioningCx<'_, 'tcx>,
115121
mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>,
116122
) -> PreInliningPartitioning<'tcx>;
117123

118124
fn merge_codegen_units(
119125
&mut self,
120-
tcx: TyCtxt<'tcx>,
126+
cx: &PartitioningCx<'_, 'tcx>,
121127
initial_partitioning: &mut PreInliningPartitioning<'tcx>,
122-
target_cgu_count: usize,
123128
);
124129

125130
fn place_inlined_mono_items(
126131
&mut self,
132+
cx: &PartitioningCx<'_, 'tcx>,
127133
initial_partitioning: PreInliningPartitioning<'tcx>,
128-
inlining_map: &InliningMap<'tcx>,
129134
) -> PostInliningPartitioning<'tcx>;
130135

131136
fn internalize_symbols(
132137
&mut self,
133-
tcx: TyCtxt<'tcx>,
138+
cx: &PartitioningCx<'_, 'tcx>,
134139
partitioning: &mut PostInliningPartitioning<'tcx>,
135-
inlining_map: &InliningMap<'tcx>,
136140
);
137141
}
138142

@@ -157,12 +161,13 @@ pub fn partition<'tcx>(
157161
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning");
158162

159163
let mut partitioner = get_partitioner(tcx);
164+
let cx = &PartitioningCx { tcx, target_cgu_count: max_cgu_count, inlining_map };
160165
// In the first step, we place all regular monomorphizations into their
161166
// respective 'home' codegen unit. Regular monomorphizations are all
162167
// functions and statics defined in the local crate.
163168
let mut initial_partitioning = {
164169
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
165-
partitioner.place_root_mono_items(tcx, mono_items)
170+
partitioner.place_root_mono_items(cx, mono_items)
166171
};
167172

168173
initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx));
@@ -172,7 +177,7 @@ pub fn partition<'tcx>(
172177
// Merge until we have at most `max_cgu_count` codegen units.
173178
{
174179
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_merge_cgus");
175-
partitioner.merge_codegen_units(tcx, &mut initial_partitioning, max_cgu_count);
180+
partitioner.merge_codegen_units(cx, &mut initial_partitioning);
176181
debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
177182
}
178183

@@ -182,7 +187,7 @@ pub fn partition<'tcx>(
182187
// local functions the definition of which is marked with `#[inline]`.
183188
let mut post_inlining = {
184189
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
185-
partitioner.place_inlined_mono_items(initial_partitioning, inlining_map)
190+
partitioner.place_inlined_mono_items(cx, initial_partitioning)
186191
};
187192

188193
post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx));
@@ -193,7 +198,7 @@ pub fn partition<'tcx>(
193198
// more freedom to optimize.
194199
if !tcx.sess.link_dead_code() {
195200
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
196-
partitioner.internalize_symbols(tcx, &mut post_inlining, inlining_map);
201+
partitioner.internalize_symbols(cx, &mut post_inlining);
197202
}
198203

199204
// Finally, sort by codegen unit name, so that we get deterministic results.

0 commit comments

Comments
 (0)