@@ -43,9 +43,11 @@ use rustc_data_structures::fingerprint::PackedFingerprint;
43
43
use rustc_data_structures:: fx:: FxHashMap ;
44
44
use rustc_data_structures:: profiling:: SelfProfilerRef ;
45
45
use rustc_data_structures:: sync:: Lock ;
46
+ use rustc_data_structures:: unhash:: UnhashMap ;
46
47
use rustc_index:: { Idx , IndexVec } ;
47
48
use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder , IntEncodedWithFixedSize , MemDecoder } ;
48
49
use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
50
+ use std:: iter;
49
51
use std:: marker:: PhantomData ;
50
52
51
53
// The maximum value of `SerializedDepNodeIndex` leaves the upper two bits
@@ -81,8 +83,9 @@ pub struct SerializedDepGraph<K: DepKind> {
81
83
/// A flattened list of all edge targets in the graph, stored in the same
82
84
/// varint encoding that we use on disk. Edge sources are implicit in edge_list_indices.
83
85
edge_list_data : Vec < u8 > ,
84
- /// Reciprocal map to `nodes`.
85
- index : FxHashMap < DepNode < K > , SerializedDepNodeIndex > ,
86
+ /// Stores a map from fingerprints to nodes per dep node kind.
87
+ /// This is the reciprocal of `nodes`.
88
+ index : Vec < UnhashMap < PackedFingerprint , SerializedDepNodeIndex > > ,
86
89
}
87
90
88
91
impl < K : DepKind > Default for SerializedDepGraph < K > {
@@ -137,7 +140,7 @@ impl<K: DepKind> SerializedDepGraph<K> {
137
140
138
141
#[ inline]
139
142
pub fn node_to_index_opt ( & self , dep_node : & DepNode < K > ) -> Option < SerializedDepNodeIndex > {
140
- self . index . get ( dep_node) . cloned ( )
143
+ self . index . get ( dep_node. kind . to_u16 ( ) as usize ) ? . get ( & dep_node . hash ) . cloned ( )
141
144
}
142
145
143
146
#[ inline]
@@ -147,7 +150,7 @@ impl<K: DepKind> SerializedDepGraph<K> {
147
150
148
151
#[ inline]
149
152
pub fn node_count ( & self ) -> usize {
150
- self . index . len ( )
153
+ self . nodes . len ( )
151
154
}
152
155
}
153
156
@@ -220,7 +223,8 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>>
220
223
for _index in 0 ..node_count {
221
224
// Decode the header for this edge; the header packs together as many of the fixed-size
222
225
// fields as possible to limit the number of times we update decoder state.
223
- let node_header = SerializedNodeHeader { bytes : d. read_array ( ) , _marker : PhantomData } ;
226
+ let node_header =
227
+ SerializedNodeHeader :: < K > { bytes : d. read_array ( ) , _marker : PhantomData } ;
224
228
225
229
let _i: SerializedDepNodeIndex = nodes. push ( node_header. node ( ) ) ;
226
230
debug_assert_eq ! ( _i. index( ) , _index) ;
@@ -251,8 +255,14 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>>
251
255
// end of the array. This padding ensure it doesn't.
252
256
edge_list_data. extend ( & [ 0u8 ; DEP_NODE_PAD ] ) ;
253
257
254
- let index: FxHashMap < _ , _ > =
255
- nodes. iter_enumerated ( ) . map ( |( idx, & dep_node) | ( dep_node, idx) ) . collect ( ) ;
258
+ // Read the number of each dep kind and use it to create an hash map with a suitable size.
259
+ let mut index: Vec < _ > = ( 0 ..( K :: MAX as usize + 1 ) )
260
+ . map ( |_| UnhashMap :: with_capacity_and_hasher ( d. read_u32 ( ) as usize , Default :: default ( ) ) )
261
+ . collect ( ) ;
262
+
263
+ for ( idx, node) in nodes. iter_enumerated ( ) {
264
+ index[ node. kind . to_u16 ( ) as usize ] . insert ( node. hash , idx) ;
265
+ }
256
266
257
267
SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }
258
268
}
@@ -419,6 +429,9 @@ struct EncoderState<K: DepKind> {
419
429
total_node_count : usize ,
420
430
total_edge_count : usize ,
421
431
stats : Option < FxHashMap < K , Stat < K > > > ,
432
+
433
+ /// Stores the number of times we've encoded each dep kind.
434
+ kind_stats : Vec < u32 > ,
422
435
}
423
436
424
437
impl < K : DepKind > EncoderState < K > {
@@ -428,6 +441,7 @@ impl<K: DepKind> EncoderState<K> {
428
441
total_edge_count : 0 ,
429
442
total_node_count : 0 ,
430
443
stats : record_stats. then ( FxHashMap :: default) ,
444
+ kind_stats : iter:: repeat ( 0 ) . take ( K :: MAX as usize + 1 ) . collect ( ) ,
431
445
}
432
446
}
433
447
@@ -438,6 +452,7 @@ impl<K: DepKind> EncoderState<K> {
438
452
) -> DepNodeIndex {
439
453
let index = DepNodeIndex :: new ( self . total_node_count ) ;
440
454
self . total_node_count += 1 ;
455
+ self . kind_stats [ node. node . kind . to_u16 ( ) as usize ] += 1 ;
441
456
442
457
let edge_count = node. edges . len ( ) ;
443
458
self . total_edge_count += edge_count;
@@ -463,11 +478,16 @@ impl<K: DepKind> EncoderState<K> {
463
478
}
464
479
465
480
fn finish ( self , profiler : & SelfProfilerRef ) -> FileEncodeResult {
466
- let Self { mut encoder, total_node_count, total_edge_count, stats : _ } = self ;
481
+ let Self { mut encoder, total_node_count, total_edge_count, stats : _, kind_stats } = self ;
467
482
468
483
let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
469
484
let edge_count = total_edge_count. try_into ( ) . unwrap ( ) ;
470
485
486
+ // Encode the number of each dep kind encountered
487
+ for count in kind_stats. iter ( ) {
488
+ count. encode ( & mut encoder) ;
489
+ }
490
+
471
491
debug ! ( ?node_count, ?edge_count) ;
472
492
debug ! ( "position: {:?}" , encoder. position( ) ) ;
473
493
IntEncodedWithFixedSize ( node_count) . encode ( & mut encoder) ;
0 commit comments