@@ -113,6 +113,37 @@ signature module DeltaSig {
113
113
}
114
114
115
115
signature module LangSig< DeltaSig D> {
116
+ /** A reason for an inferred bound. */
117
+ class SemReason {
118
+ /**
119
+ * Returns `this` if `reason` is not a `SemTypeReason`. Otherwise,
120
+ * this predicate returns `SemTypeReason`.
121
+ *
122
+ * This predicate ensures that we propagate `SemTypeReason` all the way
123
+ * to the top-level of a call to `semBounded` if the inferred bound is
124
+ * based on type-information.
125
+ */
126
+ bindingset [ this , reason]
127
+ SemReason combineWith ( SemReason reason ) ;
128
+ }
129
+
130
+ /**
131
+ * A reason for an inferred bound that indicates that the bound is inferred
132
+ * without going through a bounding condition.
133
+ */
134
+ class SemNoReason extends SemReason ;
135
+
136
+ /** A reason for an inferred bound pointing to a condition. */
137
+ class SemCondReason extends SemReason {
138
+ SemGuard getCond ( ) ;
139
+ }
140
+
141
+ /**
142
+ * A reason for an inferred bound that indicates that the bound is inferred
143
+ * based on type-information.
144
+ */
145
+ class SemTypeReason extends SemReason ;
146
+
116
147
/**
117
148
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
118
149
*
@@ -249,6 +280,14 @@ module RangeStage<
249
280
DeltaSig D, BoundSig< D > Bounds, OverflowSig< D > OverflowParam, LangSig< D > LangParam,
250
281
UtilSig< D > UtilParam>
251
282
{
283
+ class SemReason = LangParam:: SemReason ;
284
+
285
+ class SemCondReason = LangParam:: SemCondReason ;
286
+
287
+ class SemNoReason = LangParam:: SemNoReason ;
288
+
289
+ class SemTypeReason = LangParam:: SemTypeReason ;
290
+
252
291
private import Bounds
253
292
private import LangParam
254
293
private import UtilParam
@@ -509,36 +548,6 @@ module RangeStage<
509
548
)
510
549
}
511
550
512
- private newtype TSemReason =
513
- TSemNoReason ( ) or
514
- TSemCondReason ( SemGuard guard ) { possibleReason ( guard ) }
515
-
516
- /**
517
- * A reason for an inferred bound. This can either be `CondReason` if the bound
518
- * is due to a specific condition, or `NoReason` if the bound is inferred
519
- * without going through a bounding condition.
520
- */
521
- abstract class SemReason extends TSemReason {
522
- /** Gets a textual representation of this reason. */
523
- abstract string toString ( ) ;
524
- }
525
-
526
- /**
527
- * A reason for an inferred bound that indicates that the bound is inferred
528
- * without going through a bounding condition.
529
- */
530
- class SemNoReason extends SemReason , TSemNoReason {
531
- override string toString ( ) { result = "NoReason" }
532
- }
533
-
534
- /** A reason for an inferred bound pointing to a condition. */
535
- class SemCondReason extends SemReason , TSemCondReason {
536
- /** Gets the condition that is the reason for the bound. */
537
- SemGuard getCond ( ) { this = TSemCondReason ( result ) }
538
-
539
- override string toString ( ) { result = this .getCond ( ) .toString ( ) }
540
- }
541
-
542
551
/**
543
552
* Holds if `e + delta` is a valid bound for `v` at `pos`.
544
553
* - `upper = true` : `v <= e + delta`
@@ -551,13 +560,13 @@ module RangeStage<
551
560
semSsaUpdateStep ( v , e , delta ) and
552
561
pos .hasReadOfVar ( v ) and
553
562
( upper = true or upper = false ) and
554
- reason = TSemNoReason ( )
563
+ reason instanceof SemNoReason
555
564
or
556
565
exists ( SemGuard guard , boolean testIsTrue |
557
566
pos .hasReadOfVar ( v ) and
558
567
guard = boundFlowCond ( v , e , delta , upper , testIsTrue ) and
559
568
semGuardDirectlyControlsSsaRead ( guard , pos , testIsTrue ) and
560
- reason = TSemCondReason ( guard )
569
+ reason . ( SemCondReason ) . getCond ( ) = guard
561
570
)
562
571
}
563
572
@@ -570,7 +579,7 @@ module RangeStage<
570
579
pos .hasReadOfVar ( v ) and
571
580
guard = semEqFlowCond ( v , e , delta , false , testIsTrue ) and
572
581
semGuardDirectlyControlsSsaRead ( guard , pos , testIsTrue ) and
573
- reason = TSemCondReason ( guard )
582
+ reason . ( SemCondReason ) . getCond ( ) = guard
574
583
)
575
584
}
576
585
@@ -700,7 +709,7 @@ module RangeStage<
700
709
// upper = true: v <= mid + d1 <= b + d1 + d2 = b + delta
701
710
// upper = false: v >= mid + d1 >= b + d1 + d2 = b + delta
702
711
delta = D:: fromFloat ( D:: toFloat ( d1 ) + D:: toFloat ( d2 ) ) and
703
- ( if r1 instanceof SemNoReason then reason = r2 else reason = r1 )
712
+ ( if r1 instanceof SemNoReason then reason = r2 else reason = r1 . combineWith ( r2 ) )
704
713
)
705
714
or
706
715
exists ( D:: Delta d , SemReason r1 , SemReason r2 |
@@ -714,9 +723,9 @@ module RangeStage<
714
723
upper = false and delta = D:: fromFloat ( D:: toFloat ( d ) + 1 )
715
724
) and
716
725
(
717
- reason = r1
726
+ reason = r1 . combineWith ( r2 )
718
727
or
719
- reason = r2 and not r2 instanceof SemNoReason
728
+ reason = r2 . combineWith ( r1 ) and not r2 instanceof SemNoReason
720
729
)
721
730
)
722
731
}
@@ -786,7 +795,7 @@ module RangeStage<
786
795
( upper = true or upper = false ) and
787
796
fromBackEdge0 = false and
788
797
origdelta = D:: fromFloat ( 0 ) and
789
- reason = TSemNoReason ( )
798
+ reason instanceof SemNoReason
790
799
|
791
800
if semBackEdge ( phi , inp , edge )
792
801
then
@@ -1044,13 +1053,13 @@ module RangeStage<
1044
1053
( upper = true or upper = false ) and
1045
1054
fromBackEdge = false and
1046
1055
origdelta = delta and
1047
- reason = TSemNoReason ( )
1056
+ reason instanceof SemNoReason
1048
1057
or
1049
1058
baseBound ( e , delta , upper ) and
1050
1059
b instanceof SemZeroBound and
1051
1060
fromBackEdge = false and
1052
1061
origdelta = delta and
1053
- reason = TSemNoReason ( )
1062
+ reason instanceof SemNoReason
1054
1063
or
1055
1064
exists ( SemSsaVariable v , SemSsaReadPositionBlock bb |
1056
1065
boundedSsa ( v , bb , b , delta , upper , fromBackEdge , origdelta , reason ) and
@@ -1104,9 +1113,9 @@ module RangeStage<
1104
1113
boundedConditionalExpr ( cond , b , upper , true , d1 , fbe1 , od1 , r1 ) and
1105
1114
boundedConditionalExpr ( cond , b , upper , false , d2 , fbe2 , od2 , r2 ) and
1106
1115
(
1107
- delta = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1
1116
+ delta = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1 . combineWith ( r2 )
1108
1117
or
1109
- delta = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2
1118
+ delta = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 . combineWith ( r1 )
1110
1119
)
1111
1120
|
1112
1121
upper = true and delta = D:: fromFloat ( D:: toFloat ( d1 ) .maximum ( D:: toFloat ( d2 ) ) )
@@ -1132,9 +1141,15 @@ module RangeStage<
1132
1141
delta = D:: fromFloat ( D:: toFloat ( dLeft ) + D:: toFloat ( dRight ) ) and
1133
1142
fromBackEdge = fbeLeft .booleanOr ( fbeRight )
1134
1143
|
1135
- b = bLeft and origdelta = odLeft and reason = rLeft and bRight instanceof SemZeroBound
1144
+ b = bLeft and
1145
+ origdelta = odLeft and
1146
+ reason = rLeft .combineWith ( rRight ) and
1147
+ bRight instanceof SemZeroBound
1136
1148
or
1137
- b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
1149
+ b = bRight and
1150
+ origdelta = odRight and
1151
+ reason = rRight .combineWith ( rLeft ) and
1152
+ bLeft instanceof SemZeroBound
1138
1153
)
1139
1154
or
1140
1155
exists (
@@ -1150,9 +1165,9 @@ module RangeStage<
1150
1165
(
1151
1166
if D:: toFloat ( d1 ) .abs ( ) > D:: toFloat ( d2 ) .abs ( )
1152
1167
then (
1153
- d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1
1168
+ d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1 . combineWith ( r2 )
1154
1169
) else (
1155
- d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2
1170
+ d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 . combineWith ( r1 )
1156
1171
)
1157
1172
)
1158
1173
|
@@ -1168,11 +1183,14 @@ module RangeStage<
1168
1183
boundedMulOperand ( e , upper , true , dLeft , fbeLeft , odLeft , rLeft ) and
1169
1184
boundedMulOperand ( e , upper , false , dRight , fbeRight , odRight , rRight ) and
1170
1185
delta = D:: fromFloat ( D:: toFloat ( dLeft ) * D:: toFloat ( dRight ) ) and
1171
- fromBackEdge = fbeLeft .booleanOr ( fbeRight )
1186
+ fromBackEdge = fbeLeft .booleanOr ( fbeRight ) and
1187
+ b instanceof SemZeroBound
1172
1188
|
1173
- b instanceof SemZeroBound and origdelta = odLeft and reason = rLeft
1189
+ origdelta = odLeft and
1190
+ reason = rLeft .combineWith ( rRight )
1174
1191
or
1175
- b instanceof SemZeroBound and origdelta = odRight and reason = rRight
1192
+ origdelta = odRight and
1193
+ reason = rRight .combineWith ( rLeft )
1176
1194
)
1177
1195
)
1178
1196
}
0 commit comments