@@ -20,7 +20,7 @@ use crate::{
20
20
chunk:: { ChunkableModule , ChunkingType } ,
21
21
module:: Module ,
22
22
module_graph:: {
23
- chunk_group_info:: { ChunkGroupInfo , RoaringBitmapWrapper } ,
23
+ chunk_group_info:: { ChunkGroupInfo , ChunkGroupKey , RoaringBitmapWrapper } ,
24
24
module_batch:: { ModuleBatch , ModuleBatchGroup , ModuleOrBatch } ,
25
25
traced_di_graph:: { iter_neighbors_rev, TracedDiGraph } ,
26
26
GraphTraversalAction , ModuleGraph ,
@@ -48,6 +48,8 @@ pub struct ModuleBatchesGraphEdge {
48
48
pub module : Option < ResolvedVc < Box < dyn Module > > > ,
49
49
}
50
50
51
+ type EntriesList = FxIndexSet < ResolvedVc < Box < dyn Module > > > ;
52
+
51
53
#[ turbo_tasks:: value( cell = "new" , eq = "manual" , into = "new" ) ]
52
54
pub struct ModuleBatchesGraph {
53
55
graph : TracedDiGraph < ModuleOrBatch , ModuleBatchesGraphEdge > ,
@@ -61,6 +63,12 @@ pub struct ModuleBatchesGraph {
61
63
#[ turbo_tasks( trace_ignore) ]
62
64
entries : FxHashMap < ResolvedVc < Box < dyn Module > > , NodeIndex > ,
63
65
batch_groups : FxHashMap < ModuleOrBatch , ResolvedVc < ModuleBatchGroup > > ,
66
+
67
+ /// For chunk groups where the postorder of entries is different than the order of the
68
+ /// `ChunkGroup::entries()` this contains Some with the postorder list of entries of that chunk
69
+ /// group. The index in this list corresponds to the index in the
70
+ /// chunk_group_info.chunk_groups.
71
+ ordered_entries : Vec < Option < EntriesList > > ,
64
72
}
65
73
66
74
impl ModuleBatchesGraph {
@@ -79,6 +87,28 @@ impl ModuleBatchesGraph {
79
87
Ok ( * entry)
80
88
}
81
89
90
+ pub fn get_ordered_entries < ' l > (
91
+ & ' l self ,
92
+ chunk_group_info : & ' l ChunkGroupInfo ,
93
+ idx : usize ,
94
+ ) -> impl Iterator < Item = ResolvedVc < Box < dyn Module > > > + ' l {
95
+ if let Some ( ordered_entries) = self
96
+ . ordered_entries
97
+ . get ( idx)
98
+ . as_ref ( )
99
+ . and_then ( |o| o. as_ref ( ) )
100
+ {
101
+ if let Some ( chunk_group) = chunk_group_info. chunk_groups . get_index ( idx) {
102
+ debug_assert_eq ! ( ordered_entries. len( ) , chunk_group. entries_count( ) ) ;
103
+ }
104
+ Either :: Left ( Either :: Left ( ordered_entries. iter ( ) . copied ( ) ) )
105
+ } else if let Some ( chunk_group) = chunk_group_info. chunk_groups . get_index ( idx) {
106
+ Either :: Right ( chunk_group. entries ( ) )
107
+ } else {
108
+ Either :: Left ( Either :: Right ( std:: iter:: empty ( ) ) )
109
+ }
110
+ }
111
+
82
112
pub fn get_batch_group (
83
113
& self ,
84
114
module_or_batch : & ModuleOrBatch ,
@@ -323,6 +353,8 @@ pub async fn compute_module_batches(
323
353
let mut pre_batches = PreBatches :: new ( ) ;
324
354
let mut queue: VecDeque < ( ResolvedVc < Box < dyn Module > > , PreBatchIndex ) > = VecDeque :: new ( ) ;
325
355
356
+ let mut chunk_group_indicies_with_merged_children = FxHashSet :: default ( ) ;
357
+
326
358
// Start with the entries
327
359
for chunk_group in & chunk_group_info. chunk_groups {
328
360
for entry in chunk_group. entries ( ) {
@@ -340,6 +372,9 @@ pub async fn compute_module_batches(
340
372
pre_batches. single_module_entries . insert ( entry) ;
341
373
}
342
374
}
375
+ if let Some ( parent) = chunk_group. get_merged_parent ( ) {
376
+ chunk_group_indicies_with_merged_children. insert ( parent) ;
377
+ }
343
378
}
344
379
345
380
let mut initial_pre_batch_items = 0 ;
@@ -360,6 +395,83 @@ pub async fn compute_module_batches(
360
395
span. record ( "initial_pre_batch_items" , initial_pre_batch_items) ;
361
396
span. record ( "initial_pre_batches" , pre_batches. batches . len ( ) ) ;
362
397
398
+ // Figure out the order of all merged groups
399
+ let mut ordered_entries: Vec < Option < EntriesList > > =
400
+ vec ! [ None ; chunk_group_info. chunk_groups. len( ) ] ;
401
+ for ( i, chunk_group) in chunk_group_info. chunk_groups . iter ( ) . enumerate ( ) {
402
+ if !chunk_group_indicies_with_merged_children. contains ( & i) {
403
+ continue ;
404
+ }
405
+ let mut merged_modules: FxHashMap < ChunkingType , FxIndexSet < _ > > = FxHashMap :: default ( ) ;
406
+ let mut stack = ordered_entries[ i]
407
+ . as_ref ( )
408
+ . map_or_else (
409
+ || Either :: Left ( chunk_group. entries ( ) ) ,
410
+ |v| Either :: Right ( v. iter ( ) . copied ( ) ) ,
411
+ )
412
+ . filter_map ( |module| {
413
+ if let Some ( chunkable_module) = ResolvedVc :: try_downcast ( module) {
414
+ let idx = * pre_batches. entries . get ( & chunkable_module) . unwrap ( ) ;
415
+ Some ( ( idx, 0 ) )
416
+ } else {
417
+ None
418
+ }
419
+ } )
420
+ . collect :: < Vec < _ > > ( ) ;
421
+ stack. reverse ( ) ;
422
+ let mut visited = FxHashSet :: default ( ) ;
423
+ while let Some ( ( idx, mut pos) ) = stack. pop ( ) {
424
+ let batch = & pre_batches. batches [ idx] ;
425
+ while let Some ( item) = batch. items . get_index ( pos) {
426
+ match item {
427
+ PreBatchItem :: ParallelModule ( _) => { }
428
+ PreBatchItem :: ParallelReference ( other_idx) => {
429
+ if visited. insert ( * other_idx) {
430
+ stack. push ( ( idx, pos + 1 ) ) ;
431
+ stack. push ( ( * other_idx, 0 ) ) ;
432
+ break ;
433
+ }
434
+ }
435
+ PreBatchItem :: NonParallelEdge ( chunking_type, module) => {
436
+ if chunking_type. is_merged ( ) {
437
+ merged_modules
438
+ . entry ( chunking_type. clone ( ) )
439
+ . or_default ( )
440
+ . insert ( * module) ;
441
+ }
442
+ }
443
+ }
444
+ pos += 1 ;
445
+ }
446
+ }
447
+ if !merged_modules. is_empty ( ) {
448
+ for ( ty, merged_modules) in merged_modules {
449
+ let chunk_group_key = match ty {
450
+ ChunkingType :: Isolated {
451
+ merge_tag : Some ( merge_tag) ,
452
+ ..
453
+ } => ChunkGroupKey :: IsolatedMerged {
454
+ parent : i. into ( ) ,
455
+ merge_tag : merge_tag. clone ( ) ,
456
+ } ,
457
+ ChunkingType :: Shared {
458
+ merge_tag : Some ( merge_tag) ,
459
+ ..
460
+ } => ChunkGroupKey :: SharedMerged {
461
+ parent : i. into ( ) ,
462
+ merge_tag : merge_tag. clone ( ) ,
463
+ } ,
464
+ _ => unreachable ! ( ) ,
465
+ } ;
466
+ let idx = chunk_group_info
467
+ . chunk_group_keys
468
+ . get_index_of ( & chunk_group_key)
469
+ . unwrap ( ) ;
470
+ ordered_entries[ idx] = Some ( merged_modules) ;
471
+ }
472
+ }
473
+ }
474
+
363
475
// Create a map of parallel module to the batches they are contained in.
364
476
let mut parallel_module_to_pre_batch: FxIndexMap < _ , Vec < PreBatchIndex > > =
365
477
FxIndexMap :: default ( ) ;
@@ -748,6 +860,7 @@ pub async fn compute_module_batches(
748
860
graph : TracedDiGraph ( graph) ,
749
861
entries,
750
862
batch_groups,
863
+ ordered_entries,
751
864
}
752
865
. cell ( ) )
753
866
}
0 commit comments