@@ -121,7 +121,7 @@ impl SerializedDepGraph {
121
121
pub fn edge_targets_from (
122
122
& self ,
123
123
source : SerializedDepNodeIndex ,
124
- ) -> impl Iterator < Item = SerializedDepNodeIndex > + ' _ {
124
+ ) -> impl Iterator < Item = SerializedDepNodeIndex > + Clone + ' _ {
125
125
let header = self . edge_list_indices [ source] ;
126
126
let mut raw = & self . edge_list_data [ header. start ( ) ..] ;
127
127
// Figure out where the edge list for `source` ends by getting the start index of the next
@@ -393,21 +393,24 @@ impl<D: Deps> SerializedNodeHeader<D> {
393
393
const MAX_INLINE_LEN : usize = ( u16:: MAX as usize >> ( Self :: TOTAL_BITS - Self :: LEN_BITS ) ) - 1 ;
394
394
395
395
#[ inline]
396
- fn new ( node_info : & NodeInfo ) -> Self {
396
+ fn new (
397
+ node : DepNode ,
398
+ fingerprint : Fingerprint ,
399
+ edge_max_index : u32 ,
400
+ edge_count : usize ,
401
+ ) -> Self {
397
402
debug_assert_eq ! ( Self :: TOTAL_BITS , Self :: LEN_BITS + Self :: WIDTH_BITS + Self :: KIND_BITS ) ;
398
403
399
- let NodeInfo { node, fingerprint, edges } = node_info;
400
-
401
404
let mut head = node. kind . as_inner ( ) ;
402
405
403
- let free_bytes = edges . max_index ( ) . leading_zeros ( ) as usize / 8 ;
406
+ let free_bytes = edge_max_index . leading_zeros ( ) as usize / 8 ;
404
407
let bytes_per_index = ( DEP_NODE_SIZE - free_bytes) . saturating_sub ( 1 ) ;
405
408
head |= ( bytes_per_index as u16 ) << Self :: KIND_BITS ;
406
409
407
410
// Encode number of edges + 1 so that we can reserve 0 to indicate that the len doesn't fit
408
411
// in this bitfield.
409
- if edges . len ( ) <= Self :: MAX_INLINE_LEN {
410
- head |= ( edges . len ( ) as u16 + 1 ) << ( Self :: KIND_BITS + Self :: WIDTH_BITS ) ;
412
+ if edge_count <= Self :: MAX_INLINE_LEN {
413
+ head |= ( edge_count as u16 + 1 ) << ( Self :: KIND_BITS + Self :: WIDTH_BITS ) ;
411
414
}
412
415
413
416
let hash: Fingerprint = node. hash . into ( ) ;
@@ -421,10 +424,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
421
424
#[ cfg( debug_assertions) ]
422
425
{
423
426
let res = Self { bytes, _marker : PhantomData } ;
424
- assert_eq ! ( node_info . fingerprint, res. fingerprint( ) ) ;
425
- assert_eq ! ( node_info . node, res. node( ) ) ;
427
+ assert_eq ! ( fingerprint, res. fingerprint( ) ) ;
428
+ assert_eq ! ( node, res. node( ) ) ;
426
429
if let Some ( len) = res. len ( ) {
427
- assert_eq ! ( node_info . edges . len ( ) , len) ;
430
+ assert_eq ! ( edge_count , len) ;
428
431
}
429
432
}
430
433
Self { bytes, _marker : PhantomData }
@@ -487,20 +490,55 @@ struct NodeInfo {
487
490
488
491
impl NodeInfo {
489
492
fn encode < D : Deps > ( & self , e : & mut FileEncoder ) {
490
- let header = SerializedNodeHeader :: < D > :: new ( self ) ;
493
+ let NodeInfo { node, fingerprint, ref edges } = * self ;
494
+ let header =
495
+ SerializedNodeHeader :: < D > :: new ( node, fingerprint, edges. max_index ( ) , edges. len ( ) ) ;
496
+ e. write_array ( header. bytes ) ;
497
+
498
+ if header. len ( ) . is_none ( ) {
499
+ e. emit_usize ( edges. len ( ) ) ;
500
+ }
501
+
502
+ let bytes_per_index = header. bytes_per_index ( ) ;
503
+ for node_index in edges. iter ( ) {
504
+ e. write_with ( |dest| {
505
+ * dest = node_index. as_u32 ( ) . to_le_bytes ( ) ;
506
+ bytes_per_index
507
+ } ) ;
508
+ }
509
+ }
510
+
511
+ #[ inline]
512
+ fn encode_promoted < D : Deps > (
513
+ e : & mut FileEncoder ,
514
+ node : DepNode ,
515
+ fingerprint : Fingerprint ,
516
+ prev_index : SerializedDepNodeIndex ,
517
+ prev_index_to_index : & mut IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > ,
518
+ previous : & SerializedDepGraph ,
519
+ ) -> usize {
520
+ let edges = previous. edge_targets_from ( prev_index) ;
521
+ let edge_count = edges. size_hint ( ) . 0 ;
522
+ let edge_max =
523
+ edges. clone ( ) . map ( |i| prev_index_to_index[ i] . unwrap ( ) . as_u32 ( ) ) . max ( ) . unwrap_or ( 0 ) ;
524
+
525
+ let header = SerializedNodeHeader :: < D > :: new ( node, fingerprint, edge_max, edge_count) ;
491
526
e. write_array ( header. bytes ) ;
492
527
493
528
if header. len ( ) . is_none ( ) {
494
- e. emit_usize ( self . edges . len ( ) ) ;
529
+ e. emit_usize ( edge_count ) ;
495
530
}
496
531
497
532
let bytes_per_index = header. bytes_per_index ( ) ;
498
- for node_index in self . edges . iter ( ) {
533
+ for node_index in edges {
534
+ let node_index = prev_index_to_index[ node_index] . unwrap ( ) ;
499
535
e. write_with ( |dest| {
500
536
* dest = node_index. as_u32 ( ) . to_le_bytes ( ) ;
501
537
bytes_per_index
502
538
} ) ;
503
539
}
540
+
541
+ edge_count
504
542
}
505
543
}
506
544
@@ -511,6 +549,7 @@ struct Stat {
511
549
}
512
550
513
551
struct EncoderState < D : Deps > {
552
+ previous : Arc < SerializedDepGraph > ,
514
553
encoder : FileEncoder ,
515
554
total_node_count : usize ,
516
555
total_edge_count : usize ,
@@ -522,8 +561,9 @@ struct EncoderState<D: Deps> {
522
561
}
523
562
524
563
impl < D : Deps > EncoderState < D > {
525
- fn new ( encoder : FileEncoder , record_stats : bool ) -> Self {
564
+ fn new ( encoder : FileEncoder , record_stats : bool , previous : Arc < SerializedDepGraph > ) -> Self {
526
565
Self {
566
+ previous,
527
567
encoder,
528
568
total_edge_count : 0 ,
529
569
total_node_count : 0 ,
@@ -533,38 +573,90 @@ impl<D: Deps> EncoderState<D> {
533
573
}
534
574
}
535
575
536
- fn encode_node (
576
+ #[ inline]
577
+ fn record (
537
578
& mut self ,
538
- node : & NodeInfo ,
579
+ node : DepNode ,
580
+ edge_count : usize ,
581
+ edges : impl FnOnce ( & mut Self ) -> Vec < DepNodeIndex > ,
539
582
record_graph : & Option < Lock < DepGraphQuery > > ,
540
583
) -> DepNodeIndex {
541
584
let index = DepNodeIndex :: new ( self . total_node_count ) ;
542
- self . total_node_count += 1 ;
543
- self . kind_stats [ node. node . kind . as_usize ( ) ] += 1 ;
544
585
545
- let edge_count = node. edges . len ( ) ;
586
+ self . total_node_count += 1 ;
587
+ self . kind_stats [ node. kind . as_usize ( ) ] += 1 ;
546
588
self . total_edge_count += edge_count;
547
589
548
590
if let Some ( record_graph) = & record_graph {
549
- // Do not ICE when a query is called from within `with_query`.
550
- if let Some ( record_graph) = & mut record_graph. try_lock ( ) {
551
- record_graph. push ( index, node. node , & node. edges ) ;
552
- }
591
+ let edges = edges ( self ) ;
592
+ outline ( move || {
593
+ // Do not ICE when a query is called from within `with_query`.
594
+ if let Some ( record_graph) = & mut record_graph. try_lock ( ) {
595
+ record_graph. push ( index, node, & edges) ;
596
+ }
597
+ } ) ;
553
598
}
554
599
555
600
if let Some ( stats) = & mut self . stats {
556
- let kind = node. node . kind ;
601
+ let kind = node. kind ;
557
602
558
- let stat = stats. entry ( kind) . or_insert ( Stat { kind, node_counter : 0 , edge_counter : 0 } ) ;
559
- stat. node_counter += 1 ;
560
- stat. edge_counter += edge_count as u64 ;
603
+ outline ( move || {
604
+ let stat =
605
+ stats. entry ( kind) . or_insert ( Stat { kind, node_counter : 0 , edge_counter : 0 } ) ;
606
+ stat. node_counter += 1 ;
607
+ stat. edge_counter += edge_count as u64 ;
608
+ } ) ;
561
609
}
562
610
563
- let encoder = & mut self . encoder ;
564
- node. encode :: < D > ( encoder) ;
565
611
index
566
612
}
567
613
614
+ fn encode_node (
615
+ & mut self ,
616
+ node : & NodeInfo ,
617
+ record_graph : & Option < Lock < DepGraphQuery > > ,
618
+ ) -> DepNodeIndex {
619
+ node. encode :: < D > ( & mut self . encoder ) ;
620
+ self . record (
621
+ node. node ,
622
+ node. edges . len ( ) ,
623
+ |_| node. edges [ ..] . iter ( ) . copied ( ) . collect ( ) ,
624
+ record_graph,
625
+ )
626
+ }
627
+
628
+ #[ inline]
629
+ fn promote_node (
630
+ & mut self ,
631
+ prev_index : SerializedDepNodeIndex ,
632
+ record_graph : & Option < Lock < DepGraphQuery > > ,
633
+ prev_index_to_index : & mut IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > ,
634
+ ) -> DepNodeIndex {
635
+ let node = self . previous . index_to_node ( prev_index) ;
636
+
637
+ let fingerprint = self . previous . fingerprint_by_index ( prev_index) ;
638
+ let edge_count = NodeInfo :: encode_promoted :: < D > (
639
+ & mut self . encoder ,
640
+ node,
641
+ fingerprint,
642
+ prev_index,
643
+ prev_index_to_index,
644
+ & self . previous ,
645
+ ) ;
646
+
647
+ self . record (
648
+ node,
649
+ edge_count,
650
+ |this| {
651
+ this. previous
652
+ . edge_targets_from ( prev_index)
653
+ . map ( |i| prev_index_to_index[ i] . unwrap ( ) )
654
+ . collect ( )
655
+ } ,
656
+ record_graph,
657
+ )
658
+ }
659
+
568
660
fn finish ( self , profiler : & SelfProfilerRef ) -> FileEncodeResult {
569
661
let Self {
570
662
mut encoder,
@@ -573,6 +665,7 @@ impl<D: Deps> EncoderState<D> {
573
665
stats : _,
574
666
kind_stats,
575
667
marker : _,
668
+ previous : _,
576
669
} = self ;
577
670
578
671
let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
@@ -612,9 +705,10 @@ impl<D: Deps> GraphEncoder<D> {
612
705
record_graph : bool ,
613
706
record_stats : bool ,
614
707
profiler : & SelfProfilerRef ,
708
+ previous : Arc < SerializedDepGraph > ,
615
709
) -> Self {
616
710
let record_graph = record_graph. then ( || Lock :: new ( DepGraphQuery :: new ( prev_node_count) ) ) ;
617
- let status = Lock :: new ( Some ( EncoderState :: new ( encoder, record_stats) ) ) ;
711
+ let status = Lock :: new ( Some ( EncoderState :: new ( encoder, record_stats, previous ) ) ) ;
618
712
GraphEncoder { status, record_graph, profiler : profiler. clone ( ) }
619
713
}
620
714
@@ -688,6 +782,20 @@ impl<D: Deps> GraphEncoder<D> {
688
782
self . status . lock ( ) . as_mut ( ) . unwrap ( ) . encode_node ( & node, & self . record_graph )
689
783
}
690
784
785
+ #[ inline]
786
+ pub ( crate ) fn promote (
787
+ & self ,
788
+ prev_index : SerializedDepNodeIndex ,
789
+ prev_index_to_index : & mut IndexVec < SerializedDepNodeIndex , Option < DepNodeIndex > > ,
790
+ ) -> DepNodeIndex {
791
+ let _prof_timer = self . profiler . generic_activity ( "incr_comp_encode_dep_graph" ) ;
792
+ self . status . lock ( ) . as_mut ( ) . unwrap ( ) . promote_node (
793
+ prev_index,
794
+ & self . record_graph ,
795
+ prev_index_to_index,
796
+ )
797
+ }
798
+
691
799
pub fn finish ( & self ) -> FileEncodeResult {
692
800
let _prof_timer = self . profiler . generic_activity ( "incr_comp_encode_dep_graph_finish" ) ;
693
801
0 commit comments