Skip to content

Commit bb9f99c

Browse files
committed
Encode dep graph edges directly from the previous graph when promoting
1 parent 7c156d1 commit bb9f99c

File tree

2 files changed

+147
-38
lines changed

2 files changed

+147
-38
lines changed

Diff for: compiler/rustc_query_system/src/dep_graph/graph.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ impl<D: Deps> DepGraph<D> {
128128
encoder,
129129
record_graph,
130130
record_stats,
131+
prev_graph.clone(),
131132
);
132133

133134
let colors = DepNodeColorMap::new(prev_graph_node_count);
@@ -1085,6 +1086,7 @@ impl<D: Deps> CurrentDepGraph<D> {
10851086
encoder: FileEncoder,
10861087
record_graph: bool,
10871088
record_stats: bool,
1089+
previous: Arc<SerializedDepGraph>,
10881090
) -> Self {
10891091
use std::time::{SystemTime, UNIX_EPOCH};
10901092

@@ -1117,6 +1119,7 @@ impl<D: Deps> CurrentDepGraph<D> {
11171119
record_graph,
11181120
record_stats,
11191121
profiler,
1122+
previous,
11201123
),
11211124
new_node_to_index: Sharded::new(|| {
11221125
FxHashMap::with_capacity_and_hasher(
@@ -1237,16 +1240,14 @@ impl<D: Deps> CurrentDepGraph<D> {
12371240
match prev_index_to_index[prev_index] {
12381241
Some(dep_node_index) => dep_node_index,
12391242
None => {
1240-
let key = prev_graph.index_to_node(prev_index);
1241-
let edges = prev_graph
1242-
.edge_targets_from(prev_index)
1243-
.map(|i| prev_index_to_index[i].unwrap())
1244-
.collect();
1245-
let fingerprint = prev_graph.fingerprint_by_index(prev_index);
1246-
let dep_node_index = self.encoder.send(key, fingerprint, edges);
1243+
let dep_node_index = self.encoder.promote(prev_index, &mut *prev_index_to_index);
12471244
prev_index_to_index[prev_index] = Some(dep_node_index);
12481245
#[cfg(debug_assertions)]
1249-
self.record_edge(dep_node_index, key, fingerprint);
1246+
self.record_edge(
1247+
dep_node_index,
1248+
prev_graph.index_to_node(prev_index),
1249+
prev_graph.fingerprint_by_index(prev_index),
1250+
);
12501251
dep_node_index
12511252
}
12521253
}

Diff for: compiler/rustc_query_system/src/dep_graph/serialized.rs

+138-30
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl SerializedDepGraph {
121121
pub fn edge_targets_from(
122122
&self,
123123
source: SerializedDepNodeIndex,
124-
) -> impl Iterator<Item = SerializedDepNodeIndex> + '_ {
124+
) -> impl Iterator<Item = SerializedDepNodeIndex> + Clone + '_ {
125125
let header = self.edge_list_indices[source];
126126
let mut raw = &self.edge_list_data[header.start()..];
127127
// Figure out where the edge list for `source` ends by getting the start index of the next
@@ -393,21 +393,24 @@ impl<D: Deps> SerializedNodeHeader<D> {
393393
const MAX_INLINE_LEN: usize = (u16::MAX as usize >> (Self::TOTAL_BITS - Self::LEN_BITS)) - 1;
394394

395395
#[inline]
396-
fn new(node_info: &NodeInfo) -> Self {
396+
fn new(
397+
node: DepNode,
398+
fingerprint: Fingerprint,
399+
edge_max_index: u32,
400+
edge_count: usize,
401+
) -> Self {
397402
debug_assert_eq!(Self::TOTAL_BITS, Self::LEN_BITS + Self::WIDTH_BITS + Self::KIND_BITS);
398403

399-
let NodeInfo { node, fingerprint, edges } = node_info;
400-
401404
let mut head = node.kind.as_inner();
402405

403-
let free_bytes = edges.max_index().leading_zeros() as usize / 8;
406+
let free_bytes = edge_max_index.leading_zeros() as usize / 8;
404407
let bytes_per_index = (DEP_NODE_SIZE - free_bytes).saturating_sub(1);
405408
head |= (bytes_per_index as u16) << Self::KIND_BITS;
406409

407410
// Encode number of edges + 1 so that we can reserve 0 to indicate that the len doesn't fit
408411
// in this bitfield.
409-
if edges.len() <= Self::MAX_INLINE_LEN {
410-
head |= (edges.len() as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
412+
if edge_count <= Self::MAX_INLINE_LEN {
413+
head |= (edge_count as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
411414
}
412415

413416
let hash: Fingerprint = node.hash.into();
@@ -421,10 +424,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
421424
#[cfg(debug_assertions)]
422425
{
423426
let res = Self { bytes, _marker: PhantomData };
424-
assert_eq!(node_info.fingerprint, res.fingerprint());
425-
assert_eq!(node_info.node, res.node());
427+
assert_eq!(fingerprint, res.fingerprint());
428+
assert_eq!(node, res.node());
426429
if let Some(len) = res.len() {
427-
assert_eq!(node_info.edges.len(), len);
430+
assert_eq!(edge_count, len);
428431
}
429432
}
430433
Self { bytes, _marker: PhantomData }
@@ -487,20 +490,55 @@ struct NodeInfo {
487490

488491
impl NodeInfo {
489492
fn encode<D: Deps>(&self, e: &mut FileEncoder) {
490-
let header = SerializedNodeHeader::<D>::new(self);
493+
let NodeInfo { node, fingerprint, ref edges } = *self;
494+
let header =
495+
SerializedNodeHeader::<D>::new(node, fingerprint, edges.max_index(), edges.len());
496+
e.write_array(header.bytes);
497+
498+
if header.len().is_none() {
499+
e.emit_usize(edges.len());
500+
}
501+
502+
let bytes_per_index = header.bytes_per_index();
503+
for node_index in edges.iter() {
504+
e.write_with(|dest| {
505+
*dest = node_index.as_u32().to_le_bytes();
506+
bytes_per_index
507+
});
508+
}
509+
}
510+
511+
#[inline]
512+
fn encode_promoted<D: Deps>(
513+
e: &mut FileEncoder,
514+
node: DepNode,
515+
fingerprint: Fingerprint,
516+
prev_index: SerializedDepNodeIndex,
517+
prev_index_to_index: &mut IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>,
518+
previous: &SerializedDepGraph,
519+
) -> usize {
520+
let edges = previous.edge_targets_from(prev_index);
521+
let edge_count = edges.size_hint().0;
522+
let edge_max =
523+
edges.clone().map(|i| prev_index_to_index[i].unwrap().as_u32()).max().unwrap_or(0);
524+
525+
let header = SerializedNodeHeader::<D>::new(node, fingerprint, edge_max, edge_count);
491526
e.write_array(header.bytes);
492527

493528
if header.len().is_none() {
494-
e.emit_usize(self.edges.len());
529+
e.emit_usize(edge_count);
495530
}
496531

497532
let bytes_per_index = header.bytes_per_index();
498-
for node_index in self.edges.iter() {
533+
for node_index in edges {
534+
let node_index = prev_index_to_index[node_index].unwrap();
499535
e.write_with(|dest| {
500536
*dest = node_index.as_u32().to_le_bytes();
501537
bytes_per_index
502538
});
503539
}
540+
541+
edge_count
504542
}
505543
}
506544

@@ -511,6 +549,7 @@ struct Stat {
511549
}
512550

513551
struct EncoderState<D: Deps> {
552+
previous: Arc<SerializedDepGraph>,
514553
encoder: FileEncoder,
515554
total_node_count: usize,
516555
total_edge_count: usize,
@@ -522,8 +561,9 @@ struct EncoderState<D: Deps> {
522561
}
523562

524563
impl<D: Deps> EncoderState<D> {
525-
fn new(encoder: FileEncoder, record_stats: bool) -> Self {
564+
fn new(encoder: FileEncoder, record_stats: bool, previous: Arc<SerializedDepGraph>) -> Self {
526565
Self {
566+
previous,
527567
encoder,
528568
total_edge_count: 0,
529569
total_node_count: 0,
@@ -533,38 +573,90 @@ impl<D: Deps> EncoderState<D> {
533573
}
534574
}
535575

536-
fn encode_node(
576+
#[inline]
577+
fn record(
537578
&mut self,
538-
node: &NodeInfo,
579+
node: DepNode,
580+
edge_count: usize,
581+
edges: impl FnOnce(&mut Self) -> Vec<DepNodeIndex>,
539582
record_graph: &Option<Lock<DepGraphQuery>>,
540583
) -> DepNodeIndex {
541584
let index = DepNodeIndex::new(self.total_node_count);
542-
self.total_node_count += 1;
543-
self.kind_stats[node.node.kind.as_usize()] += 1;
544585

545-
let edge_count = node.edges.len();
586+
self.total_node_count += 1;
587+
self.kind_stats[node.kind.as_usize()] += 1;
546588
self.total_edge_count += edge_count;
547589

548590
if let Some(record_graph) = &record_graph {
549-
// Do not ICE when a query is called from within `with_query`.
550-
if let Some(record_graph) = &mut record_graph.try_lock() {
551-
record_graph.push(index, node.node, &node.edges);
552-
}
591+
let edges = edges(self);
592+
outline(move || {
593+
// Do not ICE when a query is called from within `with_query`.
594+
if let Some(record_graph) = &mut record_graph.try_lock() {
595+
record_graph.push(index, node, &edges);
596+
}
597+
});
553598
}
554599

555600
if let Some(stats) = &mut self.stats {
556-
let kind = node.node.kind;
601+
let kind = node.kind;
557602

558-
let stat = stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
559-
stat.node_counter += 1;
560-
stat.edge_counter += edge_count as u64;
603+
outline(move || {
604+
let stat =
605+
stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
606+
stat.node_counter += 1;
607+
stat.edge_counter += edge_count as u64;
608+
});
561609
}
562610

563-
let encoder = &mut self.encoder;
564-
node.encode::<D>(encoder);
565611
index
566612
}
567613

614+
fn encode_node(
615+
&mut self,
616+
node: &NodeInfo,
617+
record_graph: &Option<Lock<DepGraphQuery>>,
618+
) -> DepNodeIndex {
619+
node.encode::<D>(&mut self.encoder);
620+
self.record(
621+
node.node,
622+
node.edges.len(),
623+
|_| node.edges[..].iter().copied().collect(),
624+
record_graph,
625+
)
626+
}
627+
628+
#[inline]
629+
fn promote_node(
630+
&mut self,
631+
prev_index: SerializedDepNodeIndex,
632+
record_graph: &Option<Lock<DepGraphQuery>>,
633+
prev_index_to_index: &mut IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>,
634+
) -> DepNodeIndex {
635+
let node = self.previous.index_to_node(prev_index);
636+
637+
let fingerprint = self.previous.fingerprint_by_index(prev_index);
638+
let edge_count = NodeInfo::encode_promoted::<D>(
639+
&mut self.encoder,
640+
node,
641+
fingerprint,
642+
prev_index,
643+
prev_index_to_index,
644+
&self.previous,
645+
);
646+
647+
self.record(
648+
node,
649+
edge_count,
650+
|this| {
651+
this.previous
652+
.edge_targets_from(prev_index)
653+
.map(|i| prev_index_to_index[i].unwrap())
654+
.collect()
655+
},
656+
record_graph,
657+
)
658+
}
659+
568660
fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
569661
let Self {
570662
mut encoder,
@@ -573,6 +665,7 @@ impl<D: Deps> EncoderState<D> {
573665
stats: _,
574666
kind_stats,
575667
marker: _,
668+
previous: _,
576669
} = self;
577670

578671
let node_count = total_node_count.try_into().unwrap();
@@ -612,9 +705,10 @@ impl<D: Deps> GraphEncoder<D> {
612705
record_graph: bool,
613706
record_stats: bool,
614707
profiler: &SelfProfilerRef,
708+
previous: Arc<SerializedDepGraph>,
615709
) -> Self {
616710
let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
617-
let status = Lock::new(Some(EncoderState::new(encoder, record_stats)));
711+
let status = Lock::new(Some(EncoderState::new(encoder, record_stats, previous)));
618712
GraphEncoder { status, record_graph, profiler: profiler.clone() }
619713
}
620714

@@ -688,6 +782,20 @@ impl<D: Deps> GraphEncoder<D> {
688782
self.status.lock().as_mut().unwrap().encode_node(&node, &self.record_graph)
689783
}
690784

785+
#[inline]
786+
pub(crate) fn promote(
787+
&self,
788+
prev_index: SerializedDepNodeIndex,
789+
prev_index_to_index: &mut IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>,
790+
) -> DepNodeIndex {
791+
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
792+
self.status.lock().as_mut().unwrap().promote_node(
793+
prev_index,
794+
&self.record_graph,
795+
prev_index_to_index,
796+
)
797+
}
798+
691799
pub fn finish(&self) -> FileEncodeResult {
692800
let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
693801

0 commit comments

Comments
 (0)