|
11 | 11 | use rustc::dep_graph::DepNode;
|
12 | 12 | use rustc::hir::def_id::DefId;
|
13 | 13 | use rustc::hir::svh::Svh;
|
| 14 | +use rustc::hir::map::DefPathHash; |
14 | 15 | use rustc::ich::Fingerprint;
|
15 | 16 | use rustc::middle::cstore::EncodedMetadataHashes;
|
16 | 17 | use rustc::session::Session;
|
17 | 18 | use rustc::ty::TyCtxt;
|
18 | 19 | use rustc_data_structures::fx::FxHashMap;
|
| 20 | +use rustc_data_structures::graph; |
| 21 | +use rustc_data_structures::indexed_vec::IndexVec; |
19 | 22 | use rustc_serialize::Encodable as RustcEncodable;
|
20 | 23 | use rustc_serialize::opaque::Encoder;
|
21 | 24 | use std::io::{self, Cursor, Write};
|
@@ -175,65 +178,73 @@ pub fn encode_dep_graph(tcx: TyCtxt,
|
175 | 178 | dep_node.map_def(|&def_id| Some(tcx.def_path_hash(def_id))).unwrap()
|
176 | 179 | };
|
177 | 180 |
|
178 |
| - // Create a flat list of (Input, WorkProduct) edges for |
179 |
| - // serialization. |
180 |
| - let mut edges = FxHashMap(); |
181 |
| - for edge in preds.reduced_graph.all_edges() { |
182 |
| - let source = *preds.reduced_graph.node_data(edge.source()); |
183 |
| - let target = *preds.reduced_graph.node_data(edge.target()); |
184 |
| - match *target { |
185 |
| - DepNode::MetaData(ref def_id) => { |
186 |
| - // Metadata *targets* are always local metadata nodes. We have |
187 |
| - // already handled those in `encode_metadata_hashes`. |
188 |
| - assert!(def_id.is_local()); |
189 |
| - continue; |
190 |
| - } |
191 |
| - _ => (), |
192 |
| - } |
193 |
| - debug!("serialize edge: {:?} -> {:?}", source, target); |
194 |
| - let source = to_hash_based_node(source); |
195 |
| - let target = to_hash_based_node(target); |
196 |
| - edges.entry(source).or_insert(vec![]).push(target); |
197 |
| - } |
| 181 | + // NB: We rely on this Vec being indexable by reduced_graph's NodeIndex. |
| 182 | + let nodes: IndexVec<DepNodeIndex, DepNode<DefPathHash>> = preds |
| 183 | + .reduced_graph |
| 184 | + .all_nodes() |
| 185 | + .iter() |
| 186 | + .map(|node| to_hash_based_node(node.data)) |
| 187 | + .collect(); |
198 | 188 |
|
199 |
| - if tcx.sess.opts.debugging_opts.incremental_dump_hash { |
200 |
| - for (dep_node, hash) in &preds.hashes { |
201 |
| - println!("HIR hash for {:?} is {}", dep_node, hash); |
| 189 | + let mut edge_list_indices = Vec::with_capacity(nodes.len()); |
| 190 | + let mut edge_list_data = Vec::with_capacity(preds.reduced_graph.len_edges()); |
| 191 | + |
| 192 | + for node_index in 0 .. nodes.len() { |
| 193 | + let start = edge_list_data.len() as u32; |
| 194 | + |
| 195 | + for target in preds.reduced_graph.successor_nodes(graph::NodeIndex(node_index)) { |
| 196 | + edge_list_data.push(DepNodeIndex::new(target.node_id())); |
202 | 197 | }
|
| 198 | + |
| 199 | + let end = edge_list_data.len() as u32; |
| 200 | + debug_assert_eq!(node_index, edge_list_indices.len()); |
| 201 | + edge_list_indices.push((start, end)); |
203 | 202 | }
|
204 | 203 |
|
205 |
| - // Create the serialized dep-graph. |
206 |
| - let bootstrap_outputs = preds.bootstrap_outputs |
207 |
| - .iter() |
208 |
| - .map(|n| to_hash_based_node(n)) |
209 |
| - .collect(); |
210 |
| - let edges = edges.into_iter() |
211 |
| - .map(|(k, v)| SerializedEdgeSet { source: k, targets: v }) |
212 |
| - .collect(); |
| 204 | + // Let's make we had no overflow there. |
| 205 | + assert!(edge_list_data.len() <= ::std::u32::MAX as usize); |
| 206 | + // Check that we have a consistent number of edges. |
| 207 | + assert_eq!(edge_list_data.len(), preds.reduced_graph.len_edges()); |
| 208 | + |
| 209 | + let bootstrap_outputs = preds |
| 210 | + .bootstrap_outputs |
| 211 | + .iter() |
| 212 | + .map(|n| to_hash_based_node(n)) |
| 213 | + .collect(); |
| 214 | + |
| 215 | + let hashes = preds |
| 216 | + .hashes |
| 217 | + .iter() |
| 218 | + .map(|(&dep_node, &hash)| { |
| 219 | + SerializedHash { |
| 220 | + dep_node: to_hash_based_node(dep_node), |
| 221 | + hash: hash, |
| 222 | + } |
| 223 | + }) |
| 224 | + .collect(); |
| 225 | + |
213 | 226 | let graph = SerializedDepGraph {
|
| 227 | + nodes, |
| 228 | + edge_list_indices, |
| 229 | + edge_list_data, |
214 | 230 | bootstrap_outputs,
|
215 |
| - edges, |
216 |
| - hashes: preds.hashes |
217 |
| - .iter() |
218 |
| - .map(|(&dep_node, &hash)| { |
219 |
| - SerializedHash { |
220 |
| - dep_node: to_hash_based_node(dep_node), |
221 |
| - hash: hash, |
222 |
| - } |
223 |
| - }) |
224 |
| - .collect(), |
| 231 | + hashes, |
225 | 232 | };
|
226 | 233 |
|
| 234 | + // Encode the graph data. |
| 235 | + graph.encode(encoder)?; |
| 236 | + |
227 | 237 | if tcx.sess.opts.debugging_opts.incremental_info {
|
228 |
| - println!("incremental: {} nodes in reduced dep-graph", preds.reduced_graph.len_nodes()); |
229 |
| - println!("incremental: {} edges in serialized dep-graph", graph.edges.len()); |
| 238 | + println!("incremental: {} nodes in reduced dep-graph", graph.nodes.len()); |
| 239 | + println!("incremental: {} edges in serialized dep-graph", graph.edge_list_data.len()); |
230 | 240 | println!("incremental: {} hashes in serialized dep-graph", graph.hashes.len());
|
231 | 241 | }
|
232 | 242 |
|
233 |
| - debug!("graph = {:#?}", graph); |
234 |
| - |
235 |
| - // Encode the graph data. |
236 |
| - graph.encode(encoder)?; |
| 243 | + if tcx.sess.opts.debugging_opts.incremental_dump_hash { |
| 244 | + for (dep_node, hash) in &preds.hashes { |
| 245 | + println!("ICH for {:?} is {}", dep_node, hash); |
| 246 | + } |
| 247 | + } |
237 | 248 |
|
238 | 249 | Ok(())
|
239 | 250 | }
|
|
0 commit comments