@@ -11,7 +11,7 @@ use rustc_data_structures::outline;
1111use rustc_data_structures:: profiling:: QueryInvocationId ;
1212use rustc_data_structures:: sharded:: { self , ShardedHashMap } ;
1313use 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 } ;
1515use rustc_data_structures:: unord:: UnordMap ;
1616use rustc_errors:: DiagInner ;
1717use rustc_index:: IndexVec ;
@@ -68,18 +68,9 @@ pub struct MarkFrame<'a> {
6868
6969#[ derive( Debug ) ]
7070pub ( 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
8576pub ( 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.
13231314pub ( 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.
13291319const COMPRESSED_RED : u32 = u32:: MAX - 1 ;
1320+ const COMPRESSED_UNKNOWN : u32 = u32:: MAX ;
13301321
13311322impl 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:?}" ) ;
0 commit comments