@@ -1068,6 +1068,17 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
1068
1068
}
1069
1069
}
1070
1070
1071
+ private newtype TNodeAndBoolean = MkNodeAndBoolean ( NodeEx n , Boolean b ) { Stage1:: revFlow ( n ) }
1072
+
1073
+ /** A `NodeEx` tagged with a `Boolean`. */
1074
+ private class NodeAndBoolean extends TNodeAndBoolean {
1075
+ NodeEx getNodeEx ( ) { this = MkNodeAndBoolean ( result , _) }
1076
+
1077
+ boolean getBoolean ( ) { this = MkNodeAndBoolean ( _, result ) }
1078
+
1079
+ string toString ( ) { result = this .getNodeEx ( ) .toString ( ) + " " + this .getBoolean ( ) }
1080
+ }
1081
+
1071
1082
private predicate sinkNode = Stage1:: sinkNode / 2 ;
1072
1083
1073
1084
private predicate sourceModel ( NodeEx node , string model ) {
@@ -2551,16 +2562,23 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2551
2562
/** Input from previous iteration. */
2552
2563
private signature predicate storeReachesReadSig ( NodeEx node1 , NodeEx node2 ) ;
2553
2564
2554
- private module StoreReachesRead< storeReachesReadSig / 2 storeReachesReadIn> {
2565
+ private module StoreReachesRead<
2566
+ storeReachesReadSig / 2 storeReachesReadPrevDelta,
2567
+ storeReachesReadSig / 2 storeReachesReadPrevPrev>
2568
+ {
2555
2569
pragma [ nomagic]
2556
- private predicate step ( NodeEx node1 , NodeEx node2 ) {
2557
- valueStep ( node1 , node2 )
2570
+ private predicate step ( NodeEx node1 , NodeEx node2 , boolean usesPrevDelta ) {
2571
+ valueStep ( node1 , node2 ) and
2572
+ usesPrevDelta = false
2558
2573
or
2559
2574
exists ( FlowState state , Ap ap |
2560
2575
revFlow ( node1 , pragma [ only_bind_into ] ( state ) , _, _, pragma [ only_bind_into ] ( ap ) ) and
2561
2576
revFlow ( node2 , pragma [ only_bind_into ] ( state ) , _, _, pragma [ only_bind_into ] ( ap ) ) and
2562
- not ap instanceof ApNil and
2563
- storeReachesReadIn ( node1 , node2 )
2577
+ not ap instanceof ApNil
2578
+ |
2579
+ storeReachesReadPrevDelta ( node1 , node2 ) and usesPrevDelta = true
2580
+ or
2581
+ storeReachesReadPrevPrev ( node1 , node2 ) and usesPrevDelta = false
2564
2582
)
2565
2583
}
2566
2584
@@ -2573,7 +2591,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2573
2591
}
2574
2592
2575
2593
private predicate stepNodeOrContent ( ContentOrNodeContent n1 , ContentOrNodeContent n2 ) {
2576
- step ( n1 .asNodeEx ( ) , n2 .asNodeEx ( ) )
2594
+ step ( n1 .asNodeEx ( ) , n2 .asNodeEx ( ) , _ )
2577
2595
or
2578
2596
storeStepCand0 ( _, _, n1 .asContent ( ) , n2 .asNodeEx ( ) , _, _)
2579
2597
or
@@ -2599,68 +2617,117 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
2599
2617
)
2600
2618
}
2601
2619
2602
- private predicate isStoreTarget ( NodeEx node ) {
2620
+ private predicate isStoreTarget ( NodeAndBoolean node ) {
2603
2621
exists ( Content c |
2604
2622
contentIsReadAndStored ( c ) and
2605
- storeStepCand0 ( _, _, c , node , _, _)
2623
+ storeStepCand0 ( _, _, c , node .getNodeEx ( ) , _, _) and
2624
+ node .getBoolean ( ) = false
2606
2625
)
2607
2626
}
2608
2627
2609
- private predicate isReadSource ( NodeEx node ) {
2628
+ private predicate isReadSource ( NodeAndBoolean node ) {
2610
2629
exists ( Content c |
2611
2630
contentIsReadAndStored ( c ) and
2612
- readStepCand0 ( node , c , _)
2631
+ readStepCand0 ( node .getNodeEx ( ) , c , _) and
2632
+ node .getBoolean ( ) = true
2613
2633
)
2614
2634
}
2615
2635
2616
- private predicate storeReachesReadTc ( NodeEx node1 , NodeEx node2 ) =
2617
- doublyBoundedFastTC( step / 2 , isStoreTarget / 1 , isReadSource / 1 ) ( node1 , node2 )
2636
+ pragma [ nomagic]
2637
+ private predicate step0 ( NodeAndBoolean node1 , NodeAndBoolean node2 ) {
2638
+ exists ( boolean usesPrevDelta |
2639
+ step ( node1 .getNodeEx ( ) , node2 .getNodeEx ( ) , usesPrevDelta )
2640
+ |
2641
+ node2 .getBoolean ( ) = node1 .getBoolean ( ) .booleanOr ( usesPrevDelta )
2642
+ )
2643
+ }
2644
+
2645
+ private predicate storeReachesReadTc ( NodeAndBoolean node1 , NodeAndBoolean node2 ) =
2646
+ doublyBoundedFastTC( step0 / 2 , isStoreTarget / 1 , isReadSource / 1 ) ( node1 , node2 )
2618
2647
2619
2648
pragma [ nomagic]
2620
- private predicate storeStepCandIsReadAndStored ( NodeEx node1 , Content c , NodeEx node2 ) {
2649
+ private predicate storeStepCandIsReadAndStored (
2650
+ NodeEx node1 , Content c , NodeAndBoolean node2
2651
+ ) {
2621
2652
contentIsReadAndStored ( c ) and
2622
- storeStepCand0 ( node1 , _, c , node2 , _, _)
2653
+ storeStepCand0 ( node1 , _, c , node2 .getNodeEx ( ) , _, _) and
2654
+ node2 .getBoolean ( ) = false
2623
2655
}
2624
2656
2625
2657
pragma [ nomagic]
2626
- private predicate readStepCandIsReadAndStored ( NodeEx node1 , Content c , NodeEx node2 ) {
2658
+ private predicate readStepCandIsReadAndStored (
2659
+ NodeAndBoolean node1 , Content c , NodeEx node2
2660
+ ) {
2627
2661
contentIsReadAndStored ( c ) and
2628
- readStepCand0 ( node1 , c , node2 )
2662
+ readStepCand0 ( node1 .getNodeEx ( ) , c , node2 ) and
2663
+ node1 .getBoolean ( ) = true
2629
2664
}
2630
2665
2631
2666
pragma [ nomagic]
2632
- predicate storeReachesReadOut ( NodeEx storeSource , NodeEx readTarget ) {
2633
- exists ( Content c , NodeEx storeTarget , NodeEx readSource |
2667
+ predicate storeReachesReadPrev ( NodeEx storeSource , NodeEx readTarget ) {
2668
+ storeReachesReadPrevDelta ( storeSource , readTarget )
2669
+ or
2670
+ storeReachesReadPrevPrev ( storeSource , readTarget )
2671
+ }
2672
+
2673
+ pragma [ nomagic]
2674
+ predicate storeReachesReadDelta ( NodeEx storeSource , NodeEx readTarget ) {
2675
+ exists ( Content c , NodeAndBoolean storeTarget , NodeAndBoolean readSource |
2634
2676
storeReachesReadTc ( storeTarget , readSource ) and
2635
2677
storeStepCandIsReadAndStored ( storeSource , c , storeTarget ) and
2636
2678
readStepCandIsReadAndStored ( readSource , c , readTarget )
2637
2679
)
2638
- or
2639
- exists ( Content c , NodeEx storeTargetReadSource |
2640
- storeStepCandIsReadAndStored ( storeSource , c , storeTargetReadSource ) and
2641
- readStepCandIsReadAndStored ( storeTargetReadSource , c , readTarget )
2642
- )
2643
2680
}
2644
2681
}
2645
2682
2646
- private predicate storeReachesRead0 ( NodeEx node1 , NodeEx node2 ) { none ( ) }
2683
+ private predicate storeReachesReadPrevDelta0 ( NodeEx node1 , NodeEx node2 ) { node1 = node2 }
2684
+
2685
+ private predicate storeReachesReadPrevPrev0 ( NodeEx node1 , NodeEx node2 ) { none ( ) }
2686
+
2687
+ private module StoreReachesRead1 =
2688
+ StoreReachesRead< storeReachesReadPrevDelta0 / 2 , storeReachesReadPrevPrev0 / 2 > ;
2689
+
2690
+ private predicate storeReachesReadPrevDelta1 ( NodeEx storeSource , NodeEx readTarget ) {
2691
+ StoreReachesRead1:: storeReachesReadDelta ( storeSource , readTarget )
2692
+ or
2693
+ exists ( Content c , NodeEx storeTargetReadSource |
2694
+ StoreReachesRead1:: contentIsReadAndStored ( c ) and
2695
+ storeStepCand0 ( storeSource , _, c , storeTargetReadSource , _, _) and
2696
+ readStepCand0 ( storeTargetReadSource , c , readTarget )
2697
+ )
2698
+ }
2647
2699
2648
- private predicate storeReachesRead1 =
2649
- StoreReachesRead< storeReachesRead0 / 2 > :: storeReachesReadOut / 2 ;
2700
+ private predicate storeReachesReadPrevPrev1 ( NodeEx storeSource , NodeEx readTarget ) {
2701
+ none ( )
2702
+ }
2650
2703
2651
- private predicate storeReachesRead2 =
2652
- StoreReachesRead< storeReachesRead1 / 2 > :: storeReachesReadOut / 2 ;
2704
+ private module StoreReachesRead2 =
2705
+ StoreReachesRead< storeReachesReadPrevDelta1 / 2 , storeReachesReadPrevPrev1 / 2 > ;
2653
2706
2654
- private predicate storeReachesRead3 =
2655
- StoreReachesRead< storeReachesRead2 / 2 > :: storeReachesReadOut / 2 ;
2707
+ private predicate storeReachesReadPrevDelta2 = StoreReachesRead2:: storeReachesReadDelta / 2 ;
2656
2708
2657
- private predicate storeReachesRead4 =
2658
- StoreReachesRead< storeReachesRead3 / 2 > :: storeReachesReadOut / 2 ;
2709
+ private predicate storeReachesReadPrevPrev2 = StoreReachesRead2:: storeReachesReadPrev / 2 ;
2710
+
2711
+ private module StoreReachesRead3 =
2712
+ StoreReachesRead< storeReachesReadPrevDelta2 / 2 , storeReachesReadPrevPrev2 / 2 > ;
2713
+
2714
+ private predicate storeReachesReadPrevDelta3 = StoreReachesRead3:: storeReachesReadDelta / 2 ;
2715
+
2716
+ private predicate storeReachesReadPrevPrev3 = StoreReachesRead3:: storeReachesReadPrev / 2 ;
2717
+
2718
+ private module StoreReachesRead4 =
2719
+ StoreReachesRead< storeReachesReadPrevDelta3 / 2 , storeReachesReadPrevPrev3 / 2 > ;
2720
+
2721
+ predicate storeReachesRead ( NodeEx storeSource , NodeEx readTarget ) {
2722
+ StoreReachesRead4:: storeReachesReadDelta ( storeSource , readTarget )
2723
+ or
2724
+ StoreReachesRead4:: storeReachesReadPrev ( storeSource , readTarget )
2725
+ }
2659
2726
2660
- import StoreReachesRead < storeReachesRead4 / 2 >
2727
+ predicate contentIsReadAndStored = StoreReachesRead4 :: contentIsReadAndStored / 1 ;
2661
2728
}
2662
2729
2663
- predicate storeReachesRead = StoreReadReachability:: storeReachesReadOut / 2 ;
2730
+ predicate storeReachesRead = StoreReadReachability:: storeReachesRead / 2 ;
2664
2731
2665
2732
pragma [ nomagic]
2666
2733
predicate storeStepCand (
0 commit comments