@@ -463,7 +463,19 @@ impl<V: Clone> Clone for State<V> {
463
463
}
464
464
}
465
465
466
- impl < V : Clone + HasTop + HasBottom > State < V > {
466
+ impl < V : Clone > State < V > {
467
+ pub fn new ( init : V , map : & Map ) -> State < V > {
468
+ let values = IndexVec :: from_elem_n ( init, map. value_count ) ;
469
+ State ( StateData :: Reachable ( values) )
470
+ }
471
+
472
+ pub fn all ( & self , f : impl Fn ( & V ) -> bool ) -> bool {
473
+ match self . 0 {
474
+ StateData :: Unreachable => true ,
475
+ StateData :: Reachable ( ref values) => values. iter ( ) . all ( f) ,
476
+ }
477
+ }
478
+
467
479
pub fn is_reachable ( & self ) -> bool {
468
480
matches ! ( & self . 0 , StateData :: Reachable ( _) )
469
481
}
@@ -472,7 +484,10 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
472
484
self . 0 = StateData :: Unreachable ;
473
485
}
474
486
475
- pub fn flood_all ( & mut self ) {
487
+ pub fn flood_all ( & mut self )
488
+ where
489
+ V : HasTop ,
490
+ {
476
491
self . flood_all_with ( V :: TOP )
477
492
}
478
493
@@ -482,27 +497,40 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
482
497
}
483
498
484
499
pub fn flood_with ( & mut self , place : PlaceRef < ' _ > , map : & Map , value : V ) {
485
- let StateData :: Reachable ( values) = & mut self . 0 else { return } ;
486
- map. for_each_aliasing_place ( place, None , & mut |vi| {
487
- values[ vi] = value. clone ( ) ;
488
- } ) ;
500
+ self . flood_with_extra ( place, None , map, value)
489
501
}
490
502
491
- pub fn flood ( & mut self , place : PlaceRef < ' _ > , map : & Map ) {
503
+ pub fn flood ( & mut self , place : PlaceRef < ' _ > , map : & Map )
504
+ where
505
+ V : HasTop ,
506
+ {
492
507
self . flood_with ( place, map, V :: TOP )
493
508
}
494
509
495
510
pub fn flood_discr_with ( & mut self , place : PlaceRef < ' _ > , map : & Map , value : V ) {
496
- let StateData :: Reachable ( values) = & mut self . 0 else { return } ;
497
- map. for_each_aliasing_place ( place, Some ( TrackElem :: Discriminant ) , & mut |vi| {
498
- values[ vi] = value. clone ( ) ;
499
- } ) ;
511
+ self . flood_with_extra ( place, Some ( TrackElem :: Discriminant ) , map, value)
500
512
}
501
513
502
- pub fn flood_discr ( & mut self , place : PlaceRef < ' _ > , map : & Map ) {
514
+ pub fn flood_discr ( & mut self , place : PlaceRef < ' _ > , map : & Map )
515
+ where
516
+ V : HasTop ,
517
+ {
503
518
self . flood_discr_with ( place, map, V :: TOP )
504
519
}
505
520
521
+ pub fn flood_with_extra (
522
+ & mut self ,
523
+ place : PlaceRef < ' _ > ,
524
+ tail_elem : Option < TrackElem > ,
525
+ map : & Map ,
526
+ value : V ,
527
+ ) {
528
+ let StateData :: Reachable ( values) = & mut self . 0 else { return } ;
529
+ map. for_each_aliasing_place ( place, tail_elem, & mut |vi| {
530
+ values[ vi] = value. clone ( ) ;
531
+ } ) ;
532
+ }
533
+
506
534
/// Low-level method that assigns to a place.
507
535
/// This does nothing if the place is not tracked.
508
536
///
@@ -553,44 +581,87 @@ impl<V: Clone + HasTop + HasBottom> State<V> {
553
581
}
554
582
555
583
/// Helper method to interpret `target = result`.
556
- pub fn assign ( & mut self , target : PlaceRef < ' _ > , result : ValueOrPlace < V > , map : & Map ) {
584
+ pub fn assign ( & mut self , target : PlaceRef < ' _ > , result : ValueOrPlace < V > , map : & Map )
585
+ where
586
+ V : HasTop ,
587
+ {
557
588
self . flood ( target, map) ;
558
589
if let Some ( target) = map. find ( target) {
559
590
self . insert_idx ( target, result, map) ;
560
591
}
561
592
}
562
593
563
594
/// Helper method for assignments to a discriminant.
564
- pub fn assign_discr ( & mut self , target : PlaceRef < ' _ > , result : ValueOrPlace < V > , map : & Map ) {
595
+ pub fn assign_discr ( & mut self , target : PlaceRef < ' _ > , result : ValueOrPlace < V > , map : & Map )
596
+ where
597
+ V : HasTop ,
598
+ {
565
599
self . flood_discr ( target, map) ;
566
600
if let Some ( target) = map. find_discr ( target) {
567
601
self . insert_idx ( target, result, map) ;
568
602
}
569
603
}
570
604
571
605
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
572
- pub fn get ( & self , place : PlaceRef < ' _ > , map : & Map ) -> V {
606
+ pub fn try_get ( & self , place : PlaceRef < ' _ > , map : & Map ) -> Option < V > {
607
+ let place = map. find ( place) ?;
608
+ self . try_get_idx ( place, map)
609
+ }
610
+
611
+ /// Retrieve the value stored for a place, or ⊤ if it is not tracked.
612
+ pub fn try_get_discr ( & self , place : PlaceRef < ' _ > , map : & Map ) -> Option < V > {
613
+ let place = map. find_discr ( place) ?;
614
+ self . try_get_idx ( place, map)
615
+ }
616
+
617
+ /// Retrieve the value stored for a place index, or ⊤ if it is not tracked.
618
+ pub fn try_get_idx ( & self , place : PlaceIndex , map : & Map ) -> Option < V > {
619
+ match & self . 0 {
620
+ StateData :: Reachable ( values) => {
621
+ map. places [ place] . value_index . map ( |v| values[ v] . clone ( ) )
622
+ }
623
+ StateData :: Unreachable => {
624
+ // Because this is unreachable, we can return any value we want.
625
+ None
626
+ }
627
+ }
628
+ }
629
+
630
+ /// Retrieve the value stored for a place, or ⊤ if it is not tracked.
631
+ pub fn get ( & self , place : PlaceRef < ' _ > , map : & Map ) -> V
632
+ where
633
+ V : HasBottom + HasTop ,
634
+ {
573
635
map. find ( place) . map ( |place| self . get_idx ( place, map) ) . unwrap_or ( V :: TOP )
574
636
}
575
637
576
638
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
577
- pub fn get_discr ( & self , place : PlaceRef < ' _ > , map : & Map ) -> V {
639
+ pub fn get_discr ( & self , place : PlaceRef < ' _ > , map : & Map ) -> V
640
+ where
641
+ V : HasBottom + HasTop ,
642
+ {
578
643
match map. find_discr ( place) {
579
644
Some ( place) => self . get_idx ( place, map) ,
580
645
None => V :: TOP ,
581
646
}
582
647
}
583
648
584
649
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
585
- pub fn get_len ( & self , place : PlaceRef < ' _ > , map : & Map ) -> V {
650
+ pub fn get_len ( & self , place : PlaceRef < ' _ > , map : & Map ) -> V
651
+ where
652
+ V : HasBottom + HasTop ,
653
+ {
586
654
match map. find_len ( place) {
587
655
Some ( place) => self . get_idx ( place, map) ,
588
656
None => V :: TOP ,
589
657
}
590
658
}
591
659
592
660
/// Retrieve the value stored for a place index, or ⊤ if it is not tracked.
593
- pub fn get_idx ( & self , place : PlaceIndex , map : & Map ) -> V {
661
+ pub fn get_idx ( & self , place : PlaceIndex , map : & Map ) -> V
662
+ where
663
+ V : HasBottom + HasTop ,
664
+ {
594
665
match & self . 0 {
595
666
StateData :: Reachable ( values) => {
596
667
map. places [ place] . value_index . map ( |v| values[ v] . clone ( ) ) . unwrap_or ( V :: TOP )
0 commit comments