|
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