@@ -377,8 +377,16 @@ impl<O: ForestObligation> ObligationForest<O> {
377377 {
378378 let mut stack = self . scratch . take ( ) . unwrap ( ) ;
379379
380- for node in 0 ..self . nodes . len ( ) {
381- self . find_cycles_from_node ( & mut stack, processor, node) ;
380+ for index in 0 ..self . nodes . len ( ) {
381+ // For rustc-benchmarks/inflate-0.1.0 this state test is extremely
382+ // hot and the state is almost always `Pending` or `Waiting`. It's
383+ // a win to handle the no-op cases immediately to avoid the cost of
384+ // the function call.
385+ let state = self . nodes [ index] . state . get ( ) ;
386+ match state {
387+ NodeState :: Waiting | NodeState :: Pending | NodeState :: Done | NodeState :: Error => { } ,
388+ _ => self . find_cycles_from_node ( & mut stack, processor, index) ,
389+ }
382390 }
383391
384392 self . scratch = Some ( stack) ;
@@ -476,7 +484,18 @@ impl<O: ForestObligation> ObligationForest<O> {
476484 trace
477485 }
478486
479- /// Marks all nodes that depend on a pending node as NodeState;:Waiting.
487+ #[ inline]
488+ fn mark_neighbors_as_waiting_from ( & self , node : & Node < O > ) {
489+ if let Some ( parent) = node. parent {
490+ self . mark_as_waiting_from ( & self . nodes [ parent. get ( ) ] ) ;
491+ }
492+
493+ for dependent in & node. dependents {
494+ self . mark_as_waiting_from ( & self . nodes [ dependent. get ( ) ] ) ;
495+ }
496+ }
497+
498+ /// Marks all nodes that depend on a pending node as NodeState::Waiting.
480499 fn mark_as_waiting ( & self ) {
481500 for node in & self . nodes {
482501 if node. state . get ( ) == NodeState :: Waiting {
@@ -486,27 +505,19 @@ impl<O: ForestObligation> ObligationForest<O> {
486505
487506 for node in & self . nodes {
488507 if node. state . get ( ) == NodeState :: Pending {
489- self . mark_as_waiting_from ( node)
508+ self . mark_neighbors_as_waiting_from ( node) ;
490509 }
491510 }
492511 }
493512
494513 fn mark_as_waiting_from ( & self , node : & Node < O > ) {
495514 match node. state . get ( ) {
496- NodeState :: Pending | NodeState :: Done => { } ,
497515 NodeState :: Waiting | NodeState :: Error | NodeState :: OnDfsStack => return ,
498- NodeState :: Success => {
499- node. state . set ( NodeState :: Waiting ) ;
500- }
501- }
502-
503- if let Some ( parent) = node. parent {
504- self . mark_as_waiting_from ( & self . nodes [ parent. get ( ) ] ) ;
516+ NodeState :: Success => node. state . set ( NodeState :: Waiting ) ,
517+ NodeState :: Pending | NodeState :: Done => { } ,
505518 }
506519
507- for dependent in & node. dependents {
508- self . mark_as_waiting_from ( & self . nodes [ dependent. get ( ) ] ) ;
509- }
520+ self . mark_neighbors_as_waiting_from ( node) ;
510521 }
511522
512523 /// Compresses the vector, removing all popped nodes. This adjusts
@@ -532,28 +543,28 @@ impl<O: ForestObligation> ObligationForest<O> {
532543 // self.nodes[i..] are unchanged
533544 for i in 0 ..self . nodes . len ( ) {
534545 match self . nodes [ i] . state . get ( ) {
546+ NodeState :: Pending | NodeState :: Waiting => {
547+ if dead_nodes > 0 {
548+ self . nodes . swap ( i, i - dead_nodes) ;
549+ node_rewrites[ i] -= dead_nodes;
550+ }
551+ }
535552 NodeState :: Done => {
536553 self . waiting_cache . remove ( self . nodes [ i] . obligation . as_predicate ( ) ) ;
537554 // FIXME(HashMap): why can't I get my key back?
538555 self . done_cache . insert ( self . nodes [ i] . obligation . as_predicate ( ) . clone ( ) ) ;
556+ node_rewrites[ i] = nodes_len;
557+ dead_nodes += 1 ;
539558 }
540559 NodeState :: Error => {
541560 // We *intentionally* remove the node from the cache at this point. Otherwise
542561 // tests must come up with a different type on every type error they
543562 // check against.
544563 self . waiting_cache . remove ( self . nodes [ i] . obligation . as_predicate ( ) ) ;
564+ node_rewrites[ i] = nodes_len;
565+ dead_nodes += 1 ;
545566 }
546- _ => { }
547- }
548-
549- if self . nodes [ i] . is_popped ( ) {
550- node_rewrites[ i] = nodes_len;
551- dead_nodes += 1 ;
552- } else {
553- if dead_nodes > 0 {
554- self . nodes . swap ( i, i - dead_nodes) ;
555- node_rewrites[ i] -= dead_nodes;
556- }
567+ NodeState :: OnDfsStack | NodeState :: Success => unreachable ! ( )
557568 }
558569 }
559570
@@ -633,12 +644,4 @@ impl<O> Node<O> {
633644 dependents : vec ! [ ] ,
634645 }
635646 }
636-
637- fn is_popped ( & self ) -> bool {
638- match self . state . get ( ) {
639- NodeState :: Pending | NodeState :: Waiting => false ,
640- NodeState :: Error | NodeState :: Done => true ,
641- NodeState :: OnDfsStack | NodeState :: Success => unreachable ! ( )
642- }
643- }
644647}
0 commit comments