@@ -98,7 +98,11 @@ use std::fs::{self, File};
9898use std:: io:: { BufWriter , Write } ;
9999use std:: path:: { Path , PathBuf } ;
100100
101+ use rustc_data_structures:: base_n:: ToBaseN ;
101102use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
103+ use rustc_data_structures:: stable_hasher:: Hash64 ;
104+ use rustc_data_structures:: stable_hasher:: HashStable ;
105+ use rustc_data_structures:: stable_hasher:: StableHasher ;
102106use rustc_data_structures:: sync;
103107use rustc_data_structures:: unord:: { UnordMap , UnordSet } ;
104108use rustc_hir:: def:: DefKind ;
@@ -195,10 +199,73 @@ where
195199 codegen_units
196200}
197201
202+ fn place_mono_items_incr < ' tcx , I > (
203+ cx : & PartitioningCx < ' _ , ' tcx > ,
204+ mono_items : I ,
205+ ) -> PlacedMonoItems < ' tcx >
206+ where
207+ I : Iterator < Item = MonoItem < ' tcx > > ,
208+ {
209+ let mut codegen_units = UnordMap :: default ( ) ;
210+
211+ let mut reachable_inlined_items = FxIndexSet :: default ( ) ;
212+
213+ for mono_item in mono_items {
214+ // Instantiate everything as GloballyShared in its own CGU
215+ let symbol_name = mono_item. symbol_name ( cx. tcx ) . name ;
216+
217+ let hash = cx. tcx . with_stable_hashing_context ( |mut hcx| {
218+ let mut hasher = StableHasher :: new ( ) ;
219+ symbol_name. hash_stable ( & mut hcx, & mut hasher) ;
220+ hasher. finish :: < Hash64 > ( ) . as_u64 ( )
221+ } ) ;
222+
223+ let cgu_name = Symbol :: intern ( & hash. to_base ( 62 ) ) ;
224+
225+ let cgu = codegen_units. entry ( cgu_name) . or_insert_with ( || CodegenUnit :: new ( cgu_name) ) ;
226+
227+ let linkage = Linkage :: External ;
228+ let visibility = Visibility :: Default ;
229+
230+ let size_estimate = mono_item. size_estimate ( cx. tcx ) ;
231+
232+ cgu. items_mut ( )
233+ . insert ( mono_item, MonoItemData { inlined : false , linkage, visibility, size_estimate } ) ;
234+
235+ get_reachable_inlined_items ( cx. tcx , mono_item, cx. usage_map , & mut reachable_inlined_items) ;
236+ }
237+
238+ let symbol = Symbol :: intern ( "upstream" ) ;
239+ let cgu = codegen_units. entry ( symbol) . or_insert_with ( || CodegenUnit :: new ( symbol) ) ;
240+
241+ for inlined_item in reachable_inlined_items {
242+ cgu. items_mut ( ) . entry ( inlined_item) . or_insert_with ( || MonoItemData {
243+ inlined : false ,
244+ linkage : Linkage :: External ,
245+ visibility : Visibility :: Default ,
246+ size_estimate : inlined_item. size_estimate ( cx. tcx ) ,
247+ } ) ;
248+ }
249+
250+ let mut codegen_units: Vec < _ > = cx. tcx . with_stable_hashing_context ( |ref hcx| {
251+ codegen_units. into_items ( ) . map ( |( _, cgu) | cgu) . collect_sorted ( hcx, true )
252+ } ) ;
253+
254+ for cgu in codegen_units. iter_mut ( ) {
255+ cgu. compute_size_estimate ( ) ;
256+ }
257+
258+ return PlacedMonoItems { codegen_units, internalization_candidates : UnordSet :: default ( ) } ;
259+ }
260+
198261fn place_mono_items < ' tcx , I > ( cx : & PartitioningCx < ' _ , ' tcx > , mono_items : I ) -> PlacedMonoItems < ' tcx >
199262where
200263 I : Iterator < Item = MonoItem < ' tcx > > ,
201264{
265+ if cx. tcx . sess . opts . incremental . is_some ( ) {
266+ return place_mono_items_incr ( cx, mono_items) ;
267+ }
268+
202269 let mut codegen_units = UnordMap :: default ( ) ;
203270 let is_incremental_build = cx. tcx . sess . opts . incremental . is_some ( ) ;
204271 let mut internalization_candidates = UnordSet :: default ( ) ;
@@ -295,20 +362,20 @@ where
295362 }
296363
297364 return PlacedMonoItems { codegen_units, internalization_candidates } ;
365+ }
298366
299- fn get_reachable_inlined_items < ' tcx > (
300- tcx : TyCtxt < ' tcx > ,
301- item : MonoItem < ' tcx > ,
302- usage_map : & UsageMap < ' tcx > ,
303- visited : & mut FxIndexSet < MonoItem < ' tcx > > ,
304- ) {
305- usage_map. for_each_inlined_used_item ( tcx, item, |inlined_item| {
306- let is_new = visited. insert ( inlined_item) ;
307- if is_new {
308- get_reachable_inlined_items ( tcx, inlined_item, usage_map, visited) ;
309- }
310- } ) ;
311- }
367+ fn get_reachable_inlined_items < ' tcx > (
368+ tcx : TyCtxt < ' tcx > ,
369+ item : MonoItem < ' tcx > ,
370+ usage_map : & UsageMap < ' tcx > ,
371+ visited : & mut FxIndexSet < MonoItem < ' tcx > > ,
372+ ) {
373+ usage_map. for_each_inlined_used_item ( tcx, item, |inlined_item| {
374+ let is_new = visited. insert ( inlined_item) ;
375+ if is_new {
376+ get_reachable_inlined_items ( tcx, inlined_item, usage_map, visited) ;
377+ }
378+ } ) ;
312379}
313380
314381// This function requires the CGUs to be sorted by name on input, and ensures
@@ -322,6 +389,10 @@ fn merge_codegen_units<'tcx>(
322389 // A sorted order here ensures merging is deterministic.
323390 assert ! ( codegen_units. is_sorted_by( |a, b| a. name( ) . as_str( ) <= b. name( ) . as_str( ) ) ) ;
324391
392+ if cx. tcx . sess . opts . incremental . is_some ( ) {
393+ return ;
394+ }
395+
325396 // This map keeps track of what got merged into what.
326397 let mut cgu_contents: UnordMap < Symbol , Vec < Symbol > > =
327398 codegen_units. iter ( ) . map ( |cgu| ( cgu. name ( ) , vec ! [ cgu. name( ) ] ) ) . collect ( ) ;
0 commit comments