@@ -377,8 +377,16 @@ impl<O: ForestObligation> ObligationForest<O> {
377
377
{
378
378
let mut stack = self . scratch . take ( ) . unwrap ( ) ;
379
379
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
+ }
382
390
}
383
391
384
392
self . scratch = Some ( stack) ;
@@ -476,7 +484,18 @@ impl<O: ForestObligation> ObligationForest<O> {
476
484
trace
477
485
}
478
486
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.
480
499
fn mark_as_waiting ( & self ) {
481
500
for node in & self . nodes {
482
501
if node. state . get ( ) == NodeState :: Waiting {
@@ -486,27 +505,19 @@ impl<O: ForestObligation> ObligationForest<O> {
486
505
487
506
for node in & self . nodes {
488
507
if node. state . get ( ) == NodeState :: Pending {
489
- self . mark_as_waiting_from ( node)
508
+ self . mark_neighbors_as_waiting_from ( node) ;
490
509
}
491
510
}
492
511
}
493
512
494
513
fn mark_as_waiting_from ( & self , node : & Node < O > ) {
495
514
match node. state . get ( ) {
496
- NodeState :: Pending | NodeState :: Done => { } ,
497
515
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 => { } ,
505
518
}
506
519
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) ;
510
521
}
511
522
512
523
/// Compresses the vector, removing all popped nodes. This adjusts
@@ -532,28 +543,28 @@ impl<O: ForestObligation> ObligationForest<O> {
532
543
// self.nodes[i..] are unchanged
533
544
for i in 0 ..self . nodes . len ( ) {
534
545
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
+ }
535
552
NodeState :: Done => {
536
553
self . waiting_cache . remove ( self . nodes [ i] . obligation . as_predicate ( ) ) ;
537
554
// FIXME(HashMap): why can't I get my key back?
538
555
self . done_cache . insert ( self . nodes [ i] . obligation . as_predicate ( ) . clone ( ) ) ;
556
+ node_rewrites[ i] = nodes_len;
557
+ dead_nodes += 1 ;
539
558
}
540
559
NodeState :: Error => {
541
560
// We *intentionally* remove the node from the cache at this point. Otherwise
542
561
// tests must come up with a different type on every type error they
543
562
// check against.
544
563
self . waiting_cache . remove ( self . nodes [ i] . obligation . as_predicate ( ) ) ;
564
+ node_rewrites[ i] = nodes_len;
565
+ dead_nodes += 1 ;
545
566
}
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 ! ( )
557
568
}
558
569
}
559
570
@@ -633,12 +644,4 @@ impl<O> Node<O> {
633
644
dependents : vec ! [ ] ,
634
645
}
635
646
}
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
- }
644
647
}
0 commit comments