@@ -25,6 +25,8 @@ use super::query::DepGraphQuery;
25
25
use super :: raii;
26
26
use super :: safe:: DepGraphSafe ;
27
27
use super :: edges:: { self , DepGraphEdges } ;
28
+ use super :: serialized:: { SerializedDepGraph , SerializedDepNodeIndex } ;
29
+ use super :: prev:: PreviousDepGraph ;
28
30
29
31
#[ derive( Clone ) ]
30
32
pub struct DepGraph {
@@ -68,6 +70,10 @@ struct DepGraphData {
68
70
/// current one anymore.
69
71
current : RefCell < CurrentDepGraph > ,
70
72
73
+ /// The dep-graph from the previous compilation session. It contains all
74
+ /// nodes and edges as well as all fingerprints of nodes that have them.
75
+ previous : PreviousDepGraph ,
76
+
71
77
/// When we load, there may be `.o` files, cached mir, or other such
72
78
/// things available to us. If we find that they are not dirty, we
73
79
/// load the path to the file storing those work-products here into
@@ -81,19 +87,24 @@ struct DepGraphData {
81
87
}
82
88
83
89
impl DepGraph {
84
- pub fn new ( enabled : bool ) -> DepGraph {
90
+
91
+ pub fn new ( prev_graph : PreviousDepGraph ) -> DepGraph {
85
92
DepGraph {
86
- data : if enabled {
87
- Some ( Rc :: new ( DepGraphData {
88
- previous_work_products : RefCell :: new ( FxHashMap ( ) ) ,
89
- work_products : RefCell :: new ( FxHashMap ( ) ) ,
90
- edges : RefCell :: new ( DepGraphEdges :: new ( ) ) ,
91
- dep_node_debug : RefCell :: new ( FxHashMap ( ) ) ,
92
- current : RefCell :: new ( CurrentDepGraph :: new ( ) ) ,
93
- } ) )
94
- } else {
95
- None
96
- } ,
93
+ data : Some ( Rc :: new ( DepGraphData {
94
+ previous_work_products : RefCell :: new ( FxHashMap ( ) ) ,
95
+ work_products : RefCell :: new ( FxHashMap ( ) ) ,
96
+ edges : RefCell :: new ( DepGraphEdges :: new ( ) ) ,
97
+ dep_node_debug : RefCell :: new ( FxHashMap ( ) ) ,
98
+ current : RefCell :: new ( CurrentDepGraph :: new ( ) ) ,
99
+ previous : prev_graph,
100
+ } ) ) ,
101
+ fingerprints : Rc :: new ( RefCell :: new ( FxHashMap ( ) ) ) ,
102
+ }
103
+ }
104
+
105
+ pub fn new_disabled ( ) -> DepGraph {
106
+ DepGraph {
107
+ data : None ,
97
108
fingerprints : Rc :: new ( RefCell :: new ( FxHashMap ( ) ) ) ,
98
109
}
99
110
}
@@ -231,7 +242,16 @@ impl DepGraph {
231
242
pub fn read ( & self , v : DepNode ) {
232
243
if let Some ( ref data) = self . data {
233
244
data. edges . borrow_mut ( ) . read ( v) ;
234
- data. current . borrow_mut ( ) . read ( v) ;
245
+
246
+ let mut current = data. current . borrow_mut ( ) ;
247
+ debug_assert ! ( current. node_to_node_index. contains_key( & v) ,
248
+ "DepKind {:?} should be pre-allocated but isn't." ,
249
+ v. kind) ;
250
+ if let Some ( & dep_node_index_new) = current. node_to_node_index . get ( & v) {
251
+ current. read_index ( dep_node_index_new) ;
252
+ } else {
253
+ bug ! ( "DepKind {:?} should be pre-allocated but isn't." , v. kind)
254
+ }
235
255
}
236
256
}
237
257
@@ -254,22 +274,12 @@ impl DepGraph {
254
274
self . data . as_ref ( ) . unwrap ( ) . edges . borrow_mut ( ) . add_node ( node) ;
255
275
}
256
276
257
- pub fn alloc_input_node ( & self , node : DepNode ) -> DepNodeIndex {
258
- if let Some ( ref data) = self . data {
259
- let dep_node_index_legacy = data. edges . borrow_mut ( ) . add_node ( node) ;
260
- let dep_node_index_new = data. current . borrow_mut ( )
261
- . alloc_node ( node, Vec :: new ( ) ) ;
262
- DepNodeIndex {
263
- legacy : dep_node_index_legacy,
264
- new : dep_node_index_new,
265
- }
266
- } else {
267
- DepNodeIndex :: INVALID
268
- }
277
+ pub fn fingerprint_of ( & self , dep_node : & DepNode ) -> Fingerprint {
278
+ self . fingerprints . borrow ( ) [ dep_node]
269
279
}
270
280
271
- pub fn fingerprint_of ( & self , dep_node : & DepNode ) -> Option < Fingerprint > {
272
- self . fingerprints . borrow ( ) . get ( dep_node ) . cloned ( )
281
+ pub fn prev_fingerprint_of ( & self , dep_node : & DepNode ) -> Fingerprint {
282
+ self . data . as_ref ( ) . unwrap ( ) . previous . fingerprint_of ( dep_node )
273
283
}
274
284
275
285
/// Indicates that a previous work product exists for `v`. This is
@@ -338,6 +348,44 @@ impl DepGraph {
338
348
pub ( super ) fn dep_node_debug_str ( & self , dep_node : DepNode ) -> Option < String > {
339
349
self . data . as_ref ( ) . and_then ( |t| t. dep_node_debug . borrow ( ) . get ( & dep_node) . cloned ( ) )
340
350
}
351
+
352
+ pub fn serialize ( & self ) -> SerializedDepGraph {
353
+ let fingerprints = self . fingerprints . borrow ( ) ;
354
+ let current_dep_graph = self . data . as_ref ( ) . unwrap ( ) . current . borrow ( ) ;
355
+
356
+ let nodes: IndexVec < _ , _ > = current_dep_graph. nodes . iter ( ) . map ( |dep_node| {
357
+ let fingerprint = fingerprints. get ( dep_node)
358
+ . cloned ( )
359
+ . unwrap_or ( Fingerprint :: zero ( ) ) ;
360
+ ( * dep_node, fingerprint)
361
+ } ) . collect ( ) ;
362
+
363
+ let total_edge_count: usize = current_dep_graph. edges . iter ( )
364
+ . map ( |v| v. len ( ) )
365
+ . sum ( ) ;
366
+
367
+ let mut edge_list_indices = IndexVec :: with_capacity ( nodes. len ( ) ) ;
368
+ let mut edge_list_data = Vec :: with_capacity ( total_edge_count) ;
369
+
370
+ for ( current_dep_node_index, edges) in current_dep_graph. edges . iter_enumerated ( ) {
371
+ let start = edge_list_data. len ( ) as u32 ;
372
+ // This should really just be a memcpy :/
373
+ edge_list_data. extend ( edges. iter ( ) . map ( |i| SerializedDepNodeIndex ( i. index ) ) ) ;
374
+ let end = edge_list_data. len ( ) as u32 ;
375
+
376
+ debug_assert_eq ! ( current_dep_node_index. index( ) , edge_list_indices. len( ) ) ;
377
+ edge_list_indices. push ( ( start, end) ) ;
378
+ }
379
+
380
+ debug_assert ! ( edge_list_data. len( ) <= :: std:: u32 :: MAX as usize ) ;
381
+ debug_assert_eq ! ( edge_list_data. len( ) , total_edge_count) ;
382
+
383
+ SerializedDepGraph {
384
+ nodes,
385
+ edge_list_indices,
386
+ edge_list_data,
387
+ }
388
+ }
341
389
}
342
390
343
391
/// A "work product" is an intermediate result that we save into the
@@ -478,11 +526,6 @@ impl CurrentDepGraph {
478
526
}
479
527
}
480
528
481
- fn read ( & mut self , source : DepNode ) {
482
- let dep_node_index = self . maybe_alloc_node ( source) ;
483
- self . read_index ( dep_node_index) ;
484
- }
485
-
486
529
fn read_index ( & mut self , source : DepNodeIndexNew ) {
487
530
match self . task_stack . last_mut ( ) {
488
531
Some ( & mut OpenTask :: Regular {
@@ -521,27 +564,6 @@ impl CurrentDepGraph {
521
564
self . edges . push ( edges) ;
522
565
dep_node_index
523
566
}
524
-
525
- fn maybe_alloc_node ( & mut self ,
526
- dep_node : DepNode )
527
- -> DepNodeIndexNew {
528
- debug_assert_eq ! ( self . edges. len( ) , self . nodes. len( ) ) ;
529
- debug_assert_eq ! ( self . node_to_node_index. len( ) , self . nodes. len( ) ) ;
530
-
531
- let CurrentDepGraph {
532
- ref mut node_to_node_index,
533
- ref mut nodes,
534
- ref mut edges,
535
- ..
536
- } = * self ;
537
-
538
- * node_to_node_index. entry ( dep_node) . or_insert_with ( || {
539
- let next_id = nodes. len ( ) ;
540
- nodes. push ( dep_node) ;
541
- edges. push ( Vec :: new ( ) ) ;
542
- DepNodeIndexNew :: new ( next_id)
543
- } )
544
- }
545
567
}
546
568
547
569
#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
0 commit comments