93
93
//! inlining, even when they are not marked `#[inline]`.
94
94
95
95
mod default;
96
- mod merging;
97
96
98
97
use std:: cmp;
99
98
use std:: fs:: { self , File } ;
@@ -129,7 +128,7 @@ impl<'tcx> Partition<'tcx> for Partitioner {
129
128
& mut self ,
130
129
cx : & PartitioningCx < ' _ , ' tcx > ,
131
130
mono_items : & mut I ,
132
- ) -> PreInliningPartitioning < ' tcx >
131
+ ) -> PlacedRootMonoItems < ' tcx >
133
132
where
134
133
I : Iterator < Item = MonoItem < ' tcx > > ,
135
134
{
@@ -142,24 +141,23 @@ impl<'tcx> Partition<'tcx> for Partitioner {
142
141
fn merge_codegen_units (
143
142
& mut self ,
144
143
cx : & PartitioningCx < ' _ , ' tcx > ,
145
- initial_partitioning : & mut PreInliningPartitioning < ' tcx > ,
144
+ codegen_units : & mut Vec < CodegenUnit < ' tcx > > ,
146
145
) {
147
146
match self {
148
- Partitioner :: Default ( partitioner) => {
149
- partitioner. merge_codegen_units ( cx, initial_partitioning)
150
- }
147
+ Partitioner :: Default ( partitioner) => partitioner. merge_codegen_units ( cx, codegen_units) ,
151
148
Partitioner :: Unknown => cx. tcx . sess . emit_fatal ( UnknownPartitionStrategy ) ,
152
149
}
153
150
}
154
151
155
152
fn place_inlined_mono_items (
156
153
& mut self ,
157
154
cx : & PartitioningCx < ' _ , ' tcx > ,
158
- initial_partitioning : PreInliningPartitioning < ' tcx > ,
159
- ) -> PostInliningPartitioning < ' tcx > {
155
+ codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
156
+ roots : FxHashSet < MonoItem < ' tcx > > ,
157
+ ) -> FxHashMap < MonoItem < ' tcx > , MonoItemPlacement > {
160
158
match self {
161
159
Partitioner :: Default ( partitioner) => {
162
- partitioner. place_inlined_mono_items ( cx, initial_partitioning )
160
+ partitioner. place_inlined_mono_items ( cx, codegen_units , roots )
163
161
}
164
162
Partitioner :: Unknown => cx. tcx . sess . emit_fatal ( UnknownPartitionStrategy ) ,
165
163
}
@@ -168,48 +166,62 @@ impl<'tcx> Partition<'tcx> for Partitioner {
168
166
fn internalize_symbols (
169
167
& mut self ,
170
168
cx : & PartitioningCx < ' _ , ' tcx > ,
171
- post_inlining_partitioning : & mut PostInliningPartitioning < ' tcx > ,
169
+ codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
170
+ mono_item_placements : FxHashMap < MonoItem < ' tcx > , MonoItemPlacement > ,
171
+ internalization_candidates : FxHashSet < MonoItem < ' tcx > > ,
172
172
) {
173
173
match self {
174
- Partitioner :: Default ( partitioner) => {
175
- partitioner. internalize_symbols ( cx, post_inlining_partitioning)
176
- }
174
+ Partitioner :: Default ( partitioner) => partitioner. internalize_symbols (
175
+ cx,
176
+ codegen_units,
177
+ mono_item_placements,
178
+ internalization_candidates,
179
+ ) ,
177
180
Partitioner :: Unknown => cx. tcx . sess . emit_fatal ( UnknownPartitionStrategy ) ,
178
181
}
179
182
}
180
183
}
181
184
182
- pub struct PartitioningCx < ' a , ' tcx > {
185
+ struct PartitioningCx < ' a , ' tcx > {
183
186
tcx : TyCtxt < ' tcx > ,
184
187
target_cgu_count : usize ,
185
188
inlining_map : & ' a InliningMap < ' tcx > ,
186
189
}
187
190
191
+ pub struct PlacedRootMonoItems < ' tcx > {
192
+ codegen_units : Vec < CodegenUnit < ' tcx > > ,
193
+ roots : FxHashSet < MonoItem < ' tcx > > ,
194
+ internalization_candidates : FxHashSet < MonoItem < ' tcx > > ,
195
+ }
196
+
188
197
trait Partition < ' tcx > {
189
198
fn place_root_mono_items < I > (
190
199
& mut self ,
191
200
cx : & PartitioningCx < ' _ , ' tcx > ,
192
201
mono_items : & mut I ,
193
- ) -> PreInliningPartitioning < ' tcx >
202
+ ) -> PlacedRootMonoItems < ' tcx >
194
203
where
195
204
I : Iterator < Item = MonoItem < ' tcx > > ;
196
205
197
206
fn merge_codegen_units (
198
207
& mut self ,
199
208
cx : & PartitioningCx < ' _ , ' tcx > ,
200
- initial_partitioning : & mut PreInliningPartitioning < ' tcx > ,
209
+ codegen_units : & mut Vec < CodegenUnit < ' tcx > > ,
201
210
) ;
202
211
203
212
fn place_inlined_mono_items (
204
213
& mut self ,
205
214
cx : & PartitioningCx < ' _ , ' tcx > ,
206
- initial_partitioning : PreInliningPartitioning < ' tcx > ,
207
- ) -> PostInliningPartitioning < ' tcx > ;
215
+ codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
216
+ roots : FxHashSet < MonoItem < ' tcx > > ,
217
+ ) -> FxHashMap < MonoItem < ' tcx > , MonoItemPlacement > ;
208
218
209
219
fn internalize_symbols (
210
220
& mut self ,
211
221
cx : & PartitioningCx < ' _ , ' tcx > ,
212
- partitioning : & mut PostInliningPartitioning < ' tcx > ,
222
+ codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
223
+ mono_item_placements : FxHashMap < MonoItem < ' tcx > , MonoItemPlacement > ,
224
+ internalization_candidates : FxHashSet < MonoItem < ' tcx > > ,
213
225
) ;
214
226
}
215
227
@@ -225,7 +237,7 @@ fn get_partitioner(tcx: TyCtxt<'_>) -> Partitioner {
225
237
}
226
238
}
227
239
228
- pub fn partition < ' tcx , I > (
240
+ fn partition < ' tcx , I > (
229
241
tcx : TyCtxt < ' tcx > ,
230
242
mono_items : & mut I ,
231
243
max_cgu_count : usize ,
@@ -241,52 +253,59 @@ where
241
253
// In the first step, we place all regular monomorphizations into their
242
254
// respective 'home' codegen unit. Regular monomorphizations are all
243
255
// functions and statics defined in the local crate.
244
- let mut initial_partitioning = {
256
+ let PlacedRootMonoItems { mut codegen_units , roots , internalization_candidates } = {
245
257
let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_place_roots" ) ;
246
258
partitioner. place_root_mono_items ( cx, mono_items)
247
259
} ;
248
260
249
- for cgu in & mut initial_partitioning . codegen_units {
261
+ for cgu in & mut codegen_units {
250
262
cgu. create_size_estimate ( tcx) ;
251
263
}
252
264
253
- debug_dump ( tcx, "INITIAL PARTITIONING" , & initial_partitioning . codegen_units ) ;
265
+ debug_dump ( tcx, "INITIAL PARTITIONING" , & codegen_units) ;
254
266
255
267
// Merge until we have at most `max_cgu_count` codegen units.
268
+ // `merge_codegen_units` is responsible for updating the CGU size
269
+ // estimates.
256
270
{
257
271
let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_merge_cgus" ) ;
258
- partitioner. merge_codegen_units ( cx, & mut initial_partitioning ) ;
259
- debug_dump ( tcx, "POST MERGING" , & initial_partitioning . codegen_units ) ;
272
+ partitioner. merge_codegen_units ( cx, & mut codegen_units ) ;
273
+ debug_dump ( tcx, "POST MERGING" , & codegen_units) ;
260
274
}
261
275
262
276
// In the next step, we use the inlining map to determine which additional
263
277
// monomorphizations have to go into each codegen unit. These additional
264
278
// monomorphizations can be drop-glue, functions from external crates, and
265
279
// local functions the definition of which is marked with `#[inline]`.
266
- let mut post_inlining = {
280
+ let mono_item_placements = {
267
281
let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_place_inline_items" ) ;
268
- partitioner. place_inlined_mono_items ( cx, initial_partitioning )
282
+ partitioner. place_inlined_mono_items ( cx, & mut codegen_units , roots )
269
283
} ;
270
284
271
- for cgu in & mut post_inlining . codegen_units {
285
+ for cgu in & mut codegen_units {
272
286
cgu. create_size_estimate ( tcx) ;
273
287
}
274
288
275
- debug_dump ( tcx, "POST INLINING" , & post_inlining . codegen_units ) ;
289
+ debug_dump ( tcx, "POST INLINING" , & codegen_units) ;
276
290
277
291
// Next we try to make as many symbols "internal" as possible, so LLVM has
278
292
// more freedom to optimize.
279
293
if !tcx. sess . link_dead_code ( ) {
280
294
let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_internalize_symbols" ) ;
281
- partitioner. internalize_symbols ( cx, & mut post_inlining) ;
295
+ partitioner. internalize_symbols (
296
+ cx,
297
+ & mut codegen_units,
298
+ mono_item_placements,
299
+ internalization_candidates,
300
+ ) ;
282
301
}
283
302
284
303
let instrument_dead_code =
285
304
tcx. sess . instrument_coverage ( ) && !tcx. sess . instrument_coverage_except_unused_functions ( ) ;
286
305
287
306
if instrument_dead_code {
288
307
assert ! (
289
- post_inlining . codegen_units. len( ) > 0 ,
308
+ codegen_units. len( ) > 0 ,
290
309
"There must be at least one CGU that code coverage data can be generated in."
291
310
) ;
292
311
@@ -297,7 +316,7 @@ where
297
316
// the object file (CGU) containing the dead function stubs is included
298
317
// in the final binary. This will probably require forcing these
299
318
// function symbols to be included via `-u` or `/include` linker args.
300
- let mut cgus: Vec < _ > = post_inlining . codegen_units . iter_mut ( ) . collect ( ) ;
319
+ let mut cgus: Vec < _ > = codegen_units. iter_mut ( ) . collect ( ) ;
301
320
cgus. sort_by_key ( |cgu| cgu. size_estimate ( ) ) ;
302
321
303
322
let dead_code_cgu =
@@ -308,29 +327,17 @@ where
308
327
} else {
309
328
// If there are no CGUs that have externally linked items,
310
329
// then we just pick the first CGU as a fallback.
311
- & mut post_inlining . codegen_units [ 0 ]
330
+ & mut codegen_units[ 0 ]
312
331
} ;
313
332
dead_code_cgu. make_code_coverage_dead_code_cgu ( ) ;
314
333
}
315
334
316
335
// Finally, sort by codegen unit name, so that we get deterministic results.
317
- let PostInliningPartitioning {
318
- codegen_units : mut result,
319
- mono_item_placements : _,
320
- internalization_candidates : _,
321
- } = post_inlining;
336
+ codegen_units. sort_by ( |a, b| a. name ( ) . as_str ( ) . cmp ( b. name ( ) . as_str ( ) ) ) ;
322
337
323
- result . sort_by ( |a , b| a . name ( ) . as_str ( ) . cmp ( b . name ( ) . as_str ( ) ) ) ;
338
+ debug_dump ( tcx , "FINAL" , & codegen_units ) ;
324
339
325
- debug_dump ( tcx, "FINAL" , & result) ;
326
-
327
- result
328
- }
329
-
330
- pub struct PreInliningPartitioning < ' tcx > {
331
- codegen_units : Vec < CodegenUnit < ' tcx > > ,
332
- roots : FxHashSet < MonoItem < ' tcx > > ,
333
- internalization_candidates : FxHashSet < MonoItem < ' tcx > > ,
340
+ codegen_units
334
341
}
335
342
336
343
/// For symbol internalization, we need to know whether a symbol/mono-item is
@@ -342,12 +349,6 @@ enum MonoItemPlacement {
342
349
MultipleCgus ,
343
350
}
344
351
345
- struct PostInliningPartitioning < ' tcx > {
346
- codegen_units : Vec < CodegenUnit < ' tcx > > ,
347
- mono_item_placements : FxHashMap < MonoItem < ' tcx > , MonoItemPlacement > ,
348
- internalization_candidates : FxHashSet < MonoItem < ' tcx > > ,
349
- }
350
-
351
352
fn debug_dump < ' a , ' tcx : ' a > ( tcx : TyCtxt < ' tcx > , label : & str , cgus : & [ CodegenUnit < ' tcx > ] ) {
352
353
let dump = move || {
353
354
use std:: fmt:: Write ;
0 commit comments