@@ -43,9 +43,11 @@ use rustc_data_structures::fingerprint::PackedFingerprint;
4343use rustc_data_structures:: fx:: FxHashMap ;
4444use rustc_data_structures:: profiling:: SelfProfilerRef ;
4545use rustc_data_structures:: sync:: Lock ;
46+ use rustc_data_structures:: unhash:: UnhashMap ;
4647use rustc_index:: { Idx , IndexVec } ;
4748use rustc_serialize:: opaque:: { FileEncodeResult , FileEncoder , IntEncodedWithFixedSize , MemDecoder } ;
4849use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
50+ use std:: iter;
4951use std:: marker:: PhantomData ;
5052
5153// The maximum value of `SerializedDepNodeIndex` leaves the upper two bits
@@ -81,8 +83,9 @@ pub struct SerializedDepGraph<K: DepKind> {
8183 /// A flattened list of all edge targets in the graph, stored in the same
8284 /// varint encoding that we use on disk. Edge sources are implicit in edge_list_indices.
8385 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 > > ,
8689}
8790
8891impl < K : DepKind > Default for SerializedDepGraph < K > {
@@ -137,7 +140,7 @@ impl<K: DepKind> SerializedDepGraph<K> {
137140
138141 #[ inline]
139142 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 ( )
141144 }
142145
143146 #[ inline]
@@ -147,7 +150,7 @@ impl<K: DepKind> SerializedDepGraph<K> {
147150
148151 #[ inline]
149152 pub fn node_count ( & self ) -> usize {
150- self . index . len ( )
153+ self . nodes . len ( )
151154 }
152155}
153156
@@ -220,7 +223,8 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>>
220223 for _index in 0 ..node_count {
221224 // Decode the header for this edge; the header packs together as many of the fixed-size
222225 // 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 } ;
224228
225229 let _i: SerializedDepNodeIndex = nodes. push ( node_header. node ( ) ) ;
226230 debug_assert_eq ! ( _i. index( ) , _index) ;
@@ -251,8 +255,14 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>>
251255 // end of the array. This padding ensure it doesn't.
252256 edge_list_data. extend ( & [ 0u8 ; DEP_NODE_PAD ] ) ;
253257
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+ }
256266
257267 SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }
258268 }
@@ -419,6 +429,9 @@ struct EncoderState<K: DepKind> {
419429 total_node_count : usize ,
420430 total_edge_count : usize ,
421431 stats : Option < FxHashMap < K , Stat < K > > > ,
432+
433+ /// Stores the number of times we've encoded each dep kind.
434+ kind_stats : Vec < u32 > ,
422435}
423436
424437impl < K : DepKind > EncoderState < K > {
@@ -428,6 +441,7 @@ impl<K: DepKind> EncoderState<K> {
428441 total_edge_count : 0 ,
429442 total_node_count : 0 ,
430443 stats : record_stats. then ( FxHashMap :: default) ,
444+ kind_stats : iter:: repeat ( 0 ) . take ( K :: MAX as usize + 1 ) . collect ( ) ,
431445 }
432446 }
433447
@@ -438,6 +452,7 @@ impl<K: DepKind> EncoderState<K> {
438452 ) -> DepNodeIndex {
439453 let index = DepNodeIndex :: new ( self . total_node_count ) ;
440454 self . total_node_count += 1 ;
455+ self . kind_stats [ node. node . kind . to_u16 ( ) as usize ] += 1 ;
441456
442457 let edge_count = node. edges . len ( ) ;
443458 self . total_edge_count += edge_count;
@@ -463,11 +478,16 @@ impl<K: DepKind> EncoderState<K> {
463478 }
464479
465480 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 ;
467482
468483 let node_count = total_node_count. try_into ( ) . unwrap ( ) ;
469484 let edge_count = total_edge_count. try_into ( ) . unwrap ( ) ;
470485
486+ // Encode the number of each dep kind encountered
487+ for count in kind_stats. iter ( ) {
488+ count. encode ( & mut encoder) ;
489+ }
490+
471491 debug ! ( ?node_count, ?edge_count) ;
472492 debug ! ( "position: {:?}" , encoder. position( ) ) ;
473493 IntEncodedWithFixedSize ( node_count) . encode ( & mut encoder) ;
0 commit comments