Skip to content

Commit 5767910

Browse files
committed
Auto merge of #147423 - nnethercote:DepNodeColor-tweaks, r=cjgillot
`DepNodeColor` tweaks A follow-up to #147293, where I attempted and mostly failed to make things faster again, but I found a few cleanups worth doing. r? `@saethlin`
2 parents 4fd3181 + 19423b7 commit 5767910

File tree

3 files changed

+61
-82
lines changed

3 files changed

+61
-82
lines changed

compiler/rustc_query_system/src/dep_graph/graph.rs

Lines changed: 55 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::outline;
1111
use rustc_data_structures::profiling::QueryInvocationId;
1212
use rustc_data_structures::sharded::{self, ShardedHashMap};
1313
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
14-
use rustc_data_structures::sync::{AtomicU64, Lock, is_dyn_thread_safe};
14+
use rustc_data_structures::sync::{AtomicU64, Lock};
1515
use rustc_data_structures::unord::UnordMap;
1616
use rustc_errors::DiagInner;
1717
use rustc_index::IndexVec;
@@ -68,18 +68,9 @@ pub struct MarkFrame<'a> {
6868

6969
#[derive(Debug)]
7070
pub(super) enum DepNodeColor {
71-
Red,
7271
Green(DepNodeIndex),
73-
}
74-
75-
impl DepNodeColor {
76-
#[inline]
77-
fn is_green(self) -> bool {
78-
match self {
79-
DepNodeColor::Red => false,
80-
DepNodeColor::Green(_) => true,
81-
}
82-
}
72+
Red,
73+
Unknown,
8374
}
8475

8576
pub(crate) struct DepGraphData<D: Deps> {
@@ -148,10 +139,9 @@ impl<D: Deps> DepGraph<D> {
148139
);
149140
assert_eq!(red_node_index, DepNodeIndex::FOREVER_RED_NODE);
150141
if prev_graph_node_count > 0 {
151-
colors.insert(
152-
SerializedDepNodeIndex::from_u32(DepNodeIndex::FOREVER_RED_NODE.as_u32()),
153-
DepNodeColor::Red,
154-
);
142+
colors.insert_red(SerializedDepNodeIndex::from_u32(
143+
DepNodeIndex::FOREVER_RED_NODE.as_u32(),
144+
));
155145
}
156146

157147
DepGraph {
@@ -625,7 +615,7 @@ impl<D: Deps> DepGraphData<D> {
625615
) {
626616
if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) {
627617
let current = self.colors.get(prev_index);
628-
assert!(current.is_none(), "{}", msg())
618+
assert_matches!(current, DepNodeColor::Unknown, "{}", msg())
629619
} else if let Some(nodes_in_current_session) = &self.current.nodes_in_current_session {
630620
outline(|| {
631621
let seen = nodes_in_current_session.lock().contains_key(dep_node);
@@ -634,20 +624,20 @@ impl<D: Deps> DepGraphData<D> {
634624
}
635625
}
636626

637-
fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> {
627+
fn node_color(&self, dep_node: &DepNode) -> DepNodeColor {
638628
if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) {
639629
self.colors.get(prev_index)
640630
} else {
641631
// This is a node that did not exist in the previous compilation session.
642-
None
632+
DepNodeColor::Unknown
643633
}
644634
}
645635

646636
/// Returns true if the given node has been marked as green during the
647637
/// current compilation session. Used in various assertions
648638
#[inline]
649639
pub(crate) fn is_index_green(&self, prev_index: SerializedDepNodeIndex) -> bool {
650-
self.colors.get(prev_index).is_some_and(|c| c.is_green())
640+
matches!(self.colors.get(prev_index), DepNodeColor::Green(_))
651641
}
652642

653643
#[inline]
@@ -821,12 +811,12 @@ impl<D: Deps> DepGraph<D> {
821811
self.data.as_ref()?.dep_node_debug.borrow().get(&dep_node).cloned()
822812
}
823813

824-
fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> {
814+
fn node_color(&self, dep_node: &DepNode) -> DepNodeColor {
825815
if let Some(ref data) = self.data {
826816
return data.node_color(dep_node);
827817
}
828818

829-
None
819+
DepNodeColor::Unknown
830820
}
831821

832822
pub fn try_mark_green<Qcx: QueryContext<Deps = D>>(
@@ -855,9 +845,9 @@ impl<D: Deps> DepGraphData<D> {
855845
let prev_index = self.previous.node_to_index_opt(dep_node)?;
856846

857847
match self.colors.get(prev_index) {
858-
Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)),
859-
Some(DepNodeColor::Red) => None,
860-
None => {
848+
DepNodeColor::Green(dep_node_index) => Some((prev_index, dep_node_index)),
849+
DepNodeColor::Red => None,
850+
DepNodeColor::Unknown => {
861851
// This DepNode and the corresponding query invocation existed
862852
// in the previous compilation session too, so we can try to
863853
// mark it as green by recursively marking all of its
@@ -873,12 +863,12 @@ impl<D: Deps> DepGraphData<D> {
873863
&self,
874864
qcx: Qcx,
875865
parent_dep_node_index: SerializedDepNodeIndex,
876-
frame: Option<&MarkFrame<'_>>,
866+
frame: &MarkFrame<'_>,
877867
) -> Option<()> {
878868
let get_dep_dep_node = || self.previous.index_to_node(parent_dep_node_index);
879869

880870
match self.colors.get(parent_dep_node_index) {
881-
Some(DepNodeColor::Green(_)) => {
871+
DepNodeColor::Green(_) => {
882872
// This dependency has been marked as green before, we are
883873
// still fine and can continue with checking the other
884874
// dependencies.
@@ -889,15 +879,15 @@ impl<D: Deps> DepGraphData<D> {
889879
debug!("dependency {:?} was immediately green", get_dep_dep_node());
890880
return Some(());
891881
}
892-
Some(DepNodeColor::Red) => {
882+
DepNodeColor::Red => {
893883
// We found a dependency the value of which has changed
894884
// compared to the previous compilation session. We cannot
895885
// mark the DepNode as green and also don't need to bother
896886
// with checking any of the other dependencies.
897887
debug!("dependency {:?} was immediately red", get_dep_dep_node());
898888
return None;
899889
}
900-
None => {}
890+
DepNodeColor::Unknown => {}
901891
}
902892

903893
let dep_dep_node = &get_dep_dep_node();
@@ -911,7 +901,7 @@ impl<D: Deps> DepGraphData<D> {
911901
);
912902

913903
let node_index =
914-
self.try_mark_previous_green(qcx, parent_dep_node_index, dep_dep_node, frame);
904+
self.try_mark_previous_green(qcx, parent_dep_node_index, dep_dep_node, Some(frame));
915905

916906
if node_index.is_some() {
917907
debug!("managed to MARK dependency {dep_dep_node:?} as green");
@@ -928,15 +918,15 @@ impl<D: Deps> DepGraphData<D> {
928918
}
929919

930920
match self.colors.get(parent_dep_node_index) {
931-
Some(DepNodeColor::Green(_)) => {
921+
DepNodeColor::Green(_) => {
932922
debug!("managed to FORCE dependency {dep_dep_node:?} to green");
933923
return Some(());
934924
}
935-
Some(DepNodeColor::Red) => {
925+
DepNodeColor::Red => {
936926
debug!("dependency {dep_dep_node:?} was red after forcing");
937927
return None;
938928
}
939-
None => {}
929+
DepNodeColor::Unknown => {}
940930
}
941931

942932
if let None = qcx.dep_context().sess().dcx().has_errors_or_delayed_bugs() {
@@ -976,7 +966,7 @@ impl<D: Deps> DepGraphData<D> {
976966
let prev_deps = self.previous.edge_targets_from(prev_dep_node_index);
977967

978968
for dep_dep_node_index in prev_deps {
979-
self.try_mark_parent_green(qcx, dep_dep_node_index, Some(&frame))?;
969+
self.try_mark_parent_green(qcx, dep_dep_node_index, &frame)?;
980970
}
981971

982972
// If we got here without hitting a `return` that means that all
@@ -1001,13 +991,13 @@ impl<D: Deps> DepGraph<D> {
1001991
/// Returns true if the given node has been marked as red during the
1002992
/// current compilation session. Used in various assertions
1003993
pub fn is_red(&self, dep_node: &DepNode) -> bool {
1004-
matches!(self.node_color(dep_node), Some(DepNodeColor::Red))
994+
matches!(self.node_color(dep_node), DepNodeColor::Red)
1005995
}
1006996

1007997
/// Returns true if the given node has been marked as green during the
1008998
/// current compilation session. Used in various assertions
1009999
pub fn is_green(&self, dep_node: &DepNode) -> bool {
1010-
self.node_color(dep_node).is_some_and(|c| c.is_green())
1000+
matches!(self.node_color(dep_node), DepNodeColor::Green(_))
10111001
}
10121002

10131003
pub fn assert_dep_node_not_yet_allocated_in_current_session<S: std::fmt::Display>(
@@ -1034,11 +1024,11 @@ impl<D: Deps> DepGraph<D> {
10341024
let data = self.data.as_ref().unwrap();
10351025
for prev_index in data.colors.values.indices() {
10361026
match data.colors.get(prev_index) {
1037-
Some(DepNodeColor::Green(_)) => {
1027+
DepNodeColor::Green(_) => {
10381028
let dep_node = data.previous.index_to_node(prev_index);
10391029
tcx.try_load_from_on_disk_cache(dep_node);
10401030
}
1041-
None | Some(DepNodeColor::Red) => {
1031+
DepNodeColor::Unknown | DepNodeColor::Red => {
10421032
// We can skip red nodes because a node can only be marked
10431033
// as red if the query result was recomputed and thus is
10441034
// already in memory.
@@ -1318,23 +1308,21 @@ impl Default for TaskDeps {
13181308
}
13191309
}
13201310
}
1311+
13211312
// A data structure that stores Option<DepNodeColor> values as a contiguous
13221313
// array, using one u32 per entry.
13231314
pub(super) struct DepNodeColorMap {
13241315
values: IndexVec<SerializedDepNodeIndex, AtomicU32>,
1325-
sync: bool,
13261316
}
13271317

1328-
const COMPRESSED_NONE: u32 = u32::MAX;
1318+
// All values below `COMPRESSED_RED` are green.
13291319
const COMPRESSED_RED: u32 = u32::MAX - 1;
1320+
const COMPRESSED_UNKNOWN: u32 = u32::MAX;
13301321

13311322
impl DepNodeColorMap {
13321323
fn new(size: usize) -> DepNodeColorMap {
13331324
debug_assert!(COMPRESSED_RED > DepNodeIndex::MAX_AS_U32);
1334-
DepNodeColorMap {
1335-
values: (0..size).map(|_| AtomicU32::new(COMPRESSED_NONE)).collect(),
1336-
sync: is_dyn_thread_safe(),
1337-
}
1325+
DepNodeColorMap { values: (0..size).map(|_| AtomicU32::new(COMPRESSED_UNKNOWN)).collect() }
13381326
}
13391327

13401328
#[inline]
@@ -1353,58 +1341,48 @@ impl DepNodeColorMap {
13531341
index: DepNodeIndex,
13541342
) -> Result<(), DepNodeIndex> {
13551343
let value = &self.values[prev_index];
1356-
if self.sync {
1357-
match value.compare_exchange(
1358-
COMPRESSED_NONE,
1359-
index.as_u32(),
1360-
Ordering::Relaxed,
1361-
Ordering::Relaxed,
1362-
) {
1363-
Ok(_) => Ok(()),
1364-
Err(v) => Err(DepNodeIndex::from_u32(v)),
1365-
}
1366-
} else {
1367-
let v = value.load(Ordering::Relaxed);
1368-
if v == COMPRESSED_NONE {
1369-
value.store(index.as_u32(), Ordering::Relaxed);
1370-
Ok(())
1371-
} else {
1372-
Err(DepNodeIndex::from_u32(v))
1373-
}
1344+
match value.compare_exchange(
1345+
COMPRESSED_UNKNOWN,
1346+
index.as_u32(),
1347+
Ordering::Relaxed,
1348+
Ordering::Relaxed,
1349+
) {
1350+
Ok(_) => Ok(()),
1351+
Err(v) => Err(DepNodeIndex::from_u32(v)),
13741352
}
13751353
}
13761354

13771355
#[inline]
1378-
pub(super) fn get(&self, index: SerializedDepNodeIndex) -> Option<DepNodeColor> {
1379-
match self.values[index].load(Ordering::Acquire) {
1380-
COMPRESSED_NONE => None,
1381-
COMPRESSED_RED => Some(DepNodeColor::Red),
1382-
value => Some(DepNodeColor::Green(DepNodeIndex::from_u32(value))),
1356+
pub(super) fn get(&self, index: SerializedDepNodeIndex) -> DepNodeColor {
1357+
let value = self.values[index].load(Ordering::Acquire);
1358+
// Green is by far the most common case. Check for that first so we can succeed with a
1359+
// single comparison.
1360+
if value < COMPRESSED_RED {
1361+
DepNodeColor::Green(DepNodeIndex::from_u32(value))
1362+
} else if value == COMPRESSED_RED {
1363+
DepNodeColor::Red
1364+
} else {
1365+
debug_assert_eq!(value, COMPRESSED_UNKNOWN);
1366+
DepNodeColor::Unknown
13831367
}
13841368
}
13851369

13861370
#[inline]
1387-
pub(super) fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) {
1388-
self.values[index].store(
1389-
match color {
1390-
DepNodeColor::Red => COMPRESSED_RED,
1391-
DepNodeColor::Green(index) => index.as_u32(),
1392-
},
1393-
Ordering::Release,
1394-
)
1371+
pub(super) fn insert_red(&self, index: SerializedDepNodeIndex) {
1372+
self.values[index].store(COMPRESSED_RED, Ordering::Release)
13951373
}
13961374
}
13971375

13981376
#[inline(never)]
13991377
#[cold]
1400-
pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: Option<&MarkFrame<'_>>) {
1378+
pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: &MarkFrame<'_>) {
14011379
let data = graph.data.as_ref().unwrap();
14021380

14031381
eprintln!("there was a panic while trying to force a dep node");
14041382
eprintln!("try_mark_green dep node stack:");
14051383

14061384
let mut i = 0;
1407-
let mut current = frame;
1385+
let mut current = Some(frame);
14081386
while let Some(frame) = current {
14091387
let node = data.previous.index_to_node(frame.index);
14101388
eprintln!("#{i} {node:?}");

compiler/rustc_query_system/src/dep_graph/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub trait DepContext: Copy {
6363
self,
6464
dep_node: DepNode,
6565
prev_index: SerializedDepNodeIndex,
66-
frame: Option<&MarkFrame<'_>>,
66+
frame: &MarkFrame<'_>,
6767
) -> bool {
6868
let cb = self.dep_kind_info(dep_node.kind);
6969
if let Some(f) = cb.force_from_dep_node {

compiler/rustc_query_system/src/dep_graph/serialized.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
5959
use rustc_session::Session;
6060
use tracing::{debug, instrument};
6161

62-
use super::graph::{CurrentDepGraph, DepNodeColor, DepNodeColorMap};
62+
use super::graph::{CurrentDepGraph, DepNodeColorMap};
6363
use super::query::DepGraphQuery;
6464
use super::{DepKind, DepNode, DepNodeIndex, Deps};
6565
use crate::dep_graph::edges::EdgesVec;
@@ -906,16 +906,17 @@ impl<D: Deps> GraphEncoder<D> {
906906
Err(dep_node_index) => return dep_node_index,
907907
}
908908
} else {
909-
colors.insert(prev_index, DepNodeColor::Red);
909+
colors.insert_red(prev_index);
910910
}
911911

912912
self.status.bump_index(&mut *local);
913913
self.status.encode_node(index, &node, &self.record_graph, &mut *local);
914914
index
915915
}
916916

917-
/// Encodes a node that was promoted from the previous graph. It reads the information directly from
918-
/// the previous dep graph and expects all edges to already have a new dep node index assigned.
917+
/// Encodes a node that was promoted from the previous graph. It reads the information directly
918+
/// from the previous dep graph and expects all edges to already have a new dep node index
919+
/// assigned.
919920
///
920921
/// This will also ensure the dep node is marked green.
921922
#[inline]

0 commit comments

Comments
 (0)