@@ -17,9 +17,9 @@ use rustc::ich::Fingerprint;
1717use rustc:: session:: Session ;
1818use rustc:: ty:: TyCtxt ;
1919use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
20+ use rustc_data_structures:: indexed_vec:: IndexVec ;
2021use rustc_serialize:: Decodable as RustcDecodable ;
2122use rustc_serialize:: opaque:: Decoder ;
22- use std:: default:: Default ;
2323use std:: path:: { Path } ;
2424
2525use IncrementalHashesMap ;
@@ -32,7 +32,7 @@ use super::work_product;
3232
3333// The key is a dirty node. The value is **some** base-input that we
3434// can blame it on.
35- pub type DirtyNodes = FxHashMap < DepNode , DepNode > ;
35+ pub type DirtyNodes = FxHashMap < DepNodeIndex , DepNodeIndex > ;
3636
3737/// If we are in incremental mode, and a previous dep-graph exists,
3838/// then load up those nodes/edges that are still valid into the
@@ -166,48 +166,35 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
166166
167167 let serialized_dep_graph = SerializedDepGraph :: decode ( & mut dep_graph_decoder) ?;
168168
169- let edge_map: FxHashMap < DepNode , Vec < DepNode > > = {
170- let capacity = serialized_dep_graph. edge_list_data . len ( ) ;
171- let mut edge_map = FxHashMap :: with_capacity_and_hasher ( capacity, Default :: default ( ) ) ;
172-
173- for ( node_index, source) in serialized_dep_graph. nodes . iter ( ) . enumerate ( ) {
174- let ( start, end) = serialized_dep_graph. edge_list_indices [ node_index] ;
175- let targets =
176- ( & serialized_dep_graph. edge_list_data [ start as usize .. end as usize ] )
177- . into_iter ( )
178- . map ( |& node_index| serialized_dep_graph. nodes [ node_index] . clone ( ) )
179- . collect ( ) ;
180-
181- edge_map. insert ( source. clone ( ) , targets) ;
182- }
183-
184- edge_map
185- } ;
186-
187169 // Compute the set of nodes from the old graph where some input
188- // has changed or been removed. These are "raw" source nodes,
189- // which means that they still use the original `DefPathIndex`
190- // values from the encoding, rather than having been retraced to a
191- // `DefId`. The reason for this is that this way we can include
192- // nodes that have been removed (which no longer have a `DefId` in
193- // the current compilation).
170+ // has changed or been removed.
194171 let dirty_raw_nodes = initial_dirty_nodes ( tcx,
195172 incremental_hashes_map,
173+ & serialized_dep_graph. nodes ,
196174 & serialized_dep_graph. hashes ) ;
197- let dirty_raw_nodes = transitive_dirty_nodes ( & edge_map, dirty_raw_nodes) ;
175+ let dirty_raw_nodes = transitive_dirty_nodes ( & serialized_dep_graph,
176+ dirty_raw_nodes) ;
198177
199178 // Recreate the edges in the graph that are still clean.
200179 let mut clean_work_products = FxHashSet ( ) ;
201180 let mut dirty_work_products = FxHashSet ( ) ; // incomplete; just used to suppress debug output
202- for ( source, targets) in & edge_map {
203- for target in targets {
204- process_edge ( tcx, source, target, & dirty_raw_nodes,
205- & mut clean_work_products, & mut dirty_work_products) ;
181+ for ( source, targets) in serialized_dep_graph. edge_list_indices . iter_enumerated ( ) {
182+ let target_begin = targets. 0 as usize ;
183+ let target_end = targets. 1 as usize ;
184+
185+ for & target in & serialized_dep_graph. edge_list_data [ target_begin .. target_end] {
186+ process_edge ( tcx,
187+ source,
188+ target,
189+ & serialized_dep_graph. nodes ,
190+ & dirty_raw_nodes,
191+ & mut clean_work_products,
192+ & mut dirty_work_products) ;
206193 }
207194 }
208195
209- // Recreate bootstrap outputs, which are outputs that have no incoming edges (and hence cannot
210- // be dirty).
196+ // Recreate bootstrap outputs, which are outputs that have no incoming edges
197+ // (and hence cannot be dirty).
211198 for bootstrap_output in & serialized_dep_graph. bootstrap_outputs {
212199 if let DepKind :: WorkProduct = bootstrap_output. kind {
213200 let wp_id = WorkProductId :: from_fingerprint ( bootstrap_output. hash ) ;
@@ -225,7 +212,9 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
225212 // dirty.
226213 reconcile_work_products ( tcx, work_products, & clean_work_products) ;
227214
228- dirty_clean:: check_dirty_clean_annotations ( tcx, & dirty_raw_nodes) ;
215+ dirty_clean:: check_dirty_clean_annotations ( tcx,
216+ & serialized_dep_graph. nodes ,
217+ & dirty_raw_nodes) ;
229218
230219 load_prev_metadata_hashes ( tcx,
231220 & mut * incremental_hashes_map. prev_metadata_hashes . borrow_mut ( ) ) ;
@@ -236,19 +225,20 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
236225/// a bit vector where the index is the DefPathIndex.
237226fn initial_dirty_nodes < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
238227 incremental_hashes_map : & IncrementalHashesMap ,
239- serialized_hashes : & [ SerializedHash ] )
228+ nodes : & IndexVec < DepNodeIndex , DepNode > ,
229+ serialized_hashes : & [ ( DepNodeIndex , Fingerprint ) ] )
240230 -> DirtyNodes {
241231 let mut hcx = HashContext :: new ( tcx, incremental_hashes_map) ;
242232 let mut dirty_nodes = FxHashMap ( ) ;
243233
244- for hash in serialized_hashes {
245- let dep_node = hash . dep_node ;
234+ for & ( dep_node_index , prev_hash ) in serialized_hashes {
235+ let dep_node = nodes [ dep_node_index ] ;
246236 if does_still_exist ( tcx, & dep_node) {
247237 let current_hash = hcx. hash ( & dep_node) . unwrap_or_else ( || {
248238 bug ! ( "Cannot find current ICH for input that still exists?" )
249239 } ) ;
250240
251- if current_hash == hash . hash {
241+ if current_hash == prev_hash {
252242 debug ! ( "initial_dirty_nodes: {:?} is clean (hash={:?})" ,
253243 dep_node,
254244 current_hash) ;
@@ -259,44 +249,41 @@ fn initial_dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
259249 println ! ( "node {:?} is dirty as hash is {:?}, was {:?}" ,
260250 dep_node,
261251 current_hash,
262- hash . hash ) ;
252+ prev_hash ) ;
263253 }
264254
265255 debug ! ( "initial_dirty_nodes: {:?} is dirty as hash is {:?}, was {:?}" ,
266256 dep_node,
267257 current_hash,
268- hash . hash ) ;
258+ prev_hash ) ;
269259 } else {
270260 if tcx. sess . opts . debugging_opts . incremental_dump_hash {
271261 println ! ( "node {:?} is dirty as it was removed" , dep_node) ;
272262 }
273263
274264 debug ! ( "initial_dirty_nodes: {:?} is dirty as it was removed" , dep_node) ;
275265 }
276-
277- dirty_nodes. insert ( hash. dep_node . clone ( ) , hash. dep_node . clone ( ) ) ;
266+ dirty_nodes. insert ( dep_node_index, dep_node_index) ;
278267 }
279268
280269 dirty_nodes
281270}
282271
283- fn transitive_dirty_nodes ( edge_map : & FxHashMap < DepNode , Vec < DepNode > > ,
272+ fn transitive_dirty_nodes ( serialized_dep_graph : & SerializedDepGraph ,
284273 mut dirty_nodes : DirtyNodes )
285274 -> DirtyNodes
286275{
287- let mut stack: Vec < ( DepNode , DepNode ) > = vec ! [ ] ;
288- stack. extend ( dirty_nodes. iter ( ) . map ( |( s, b) | ( s. clone ( ) , b. clone ( ) ) ) ) ;
276+ let mut stack: Vec < ( DepNodeIndex , DepNodeIndex ) > = vec ! [ ] ;
277+ stack. extend ( dirty_nodes. iter ( ) . map ( |( & s, & b) | ( s, b) ) ) ;
289278 while let Some ( ( source, blame) ) = stack. pop ( ) {
290279 // we know the source is dirty (because of the node `blame`)...
291- assert ! ( dirty_nodes. contains_key( & source) ) ;
280+ debug_assert ! ( dirty_nodes. contains_key( & source) ) ;
292281
293282 // ...so we dirty all the targets (with the same blame)
294- if let Some ( targets) = edge_map. get ( & source) {
295- for target in targets {
296- if !dirty_nodes. contains_key ( target) {
297- dirty_nodes. insert ( target. clone ( ) , blame. clone ( ) ) ;
298- stack. push ( ( target. clone ( ) , blame. clone ( ) ) ) ;
299- }
283+ for & target in serialized_dep_graph. edge_targets_from ( source) {
284+ if !dirty_nodes. contains_key ( & target) {
285+ dirty_nodes. insert ( target, blame) ;
286+ stack. push ( ( target, blame) ) ;
300287 }
301288 }
302289 }
@@ -402,16 +389,18 @@ fn load_prev_metadata_hashes(tcx: TyCtxt,
402389
403390fn process_edge < ' a , ' tcx , ' edges > (
404391 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
405- source : & ' edges DepNode ,
406- target : & ' edges DepNode ,
392+ source : DepNodeIndex ,
393+ target : DepNodeIndex ,
394+ nodes : & IndexVec < DepNodeIndex , DepNode > ,
407395 dirty_raw_nodes : & DirtyNodes ,
408396 clean_work_products : & mut FxHashSet < WorkProductId > ,
409397 dirty_work_products : & mut FxHashSet < WorkProductId > )
410398{
411399 // If the target is dirty, skip the edge. If this is an edge
412400 // that targets a work-product, we can print the blame
413401 // information now.
414- if let Some ( blame) = dirty_raw_nodes. get ( target) {
402+ if let Some ( & blame) = dirty_raw_nodes. get ( & target) {
403+ let target = nodes[ target] ;
415404 if let DepKind :: WorkProduct = target. kind {
416405 if tcx. sess . opts . debugging_opts . incremental_info {
417406 let wp_id = WorkProductId :: from_fingerprint ( target. hash ) ;
@@ -420,6 +409,7 @@ fn process_edge<'a, 'tcx, 'edges>(
420409 // Try to reconstruct the human-readable version of the
421410 // DepNode. This cannot be done for things that where
422411 // removed.
412+ let blame = nodes[ blame] ;
423413 let blame_str = if let Some ( def_id) = blame. extract_def_id ( tcx) {
424414 format ! ( "{:?}({})" ,
425415 blame. kind,
@@ -444,21 +434,23 @@ fn process_edge<'a, 'tcx, 'edges>(
444434
445435 // We should never have an edge where the target is clean but the source
446436 // was dirty. Otherwise something was wrong with the dirtying pass above:
447- debug_assert ! ( !dirty_raw_nodes. contains_key( source) ) ;
437+ debug_assert ! ( !dirty_raw_nodes. contains_key( & source) ) ;
448438
449439 // We also never should encounter an edge going from a removed input to a
450440 // clean target because removing the input would have dirtied the input
451441 // node and transitively dirtied the target.
452- debug_assert ! ( match source. kind {
442+ debug_assert ! ( match nodes [ source] . kind {
453443 DepKind :: Hir | DepKind :: HirBody | DepKind :: MetaData => {
454- does_still_exist( tcx, source)
444+ does_still_exist( tcx, & nodes [ source] )
455445 }
456446 _ => true ,
457447 } ) ;
458448
459- if !dirty_raw_nodes. contains_key ( target) {
460- let _task = tcx. dep_graph . in_task ( * target) ;
461- tcx. dep_graph . read ( * source) ;
449+ if !dirty_raw_nodes. contains_key ( & target) {
450+ let target = nodes[ target] ;
451+ let source = nodes[ source] ;
452+ let _task = tcx. dep_graph . in_task ( target) ;
453+ tcx. dep_graph . read ( source) ;
462454
463455 if let DepKind :: WorkProduct = target. kind {
464456 let wp_id = WorkProductId :: from_fingerprint ( target. hash ) ;
0 commit comments