@@ -113,6 +113,37 @@ signature module DeltaSig {
113113}
114114
115115signature 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+
116147 /**
117148 * Holds if the specified expression should be excluded from the result of `ssaRead()`.
118149 *
@@ -249,6 +280,14 @@ module RangeStage<
249280 DeltaSig D, BoundSig< D > Bounds, OverflowSig< D > OverflowParam, LangSig< D > LangParam,
250281 UtilSig< D > UtilParam>
251282{
283+ class SemReason = LangParam:: SemReason ;
284+
285+ class SemCondReason = LangParam:: SemCondReason ;
286+
287+ class SemNoReason = LangParam:: SemNoReason ;
288+
289+ class SemTypeReason = LangParam:: SemTypeReason ;
290+
252291 private import Bounds
253292 private import LangParam
254293 private import UtilParam
@@ -509,36 +548,6 @@ module RangeStage<
509548 )
510549 }
511550
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-
542551 /**
543552 * Holds if `e + delta` is a valid bound for `v` at `pos`.
544553 * - `upper = true` : `v <= e + delta`
@@ -551,13 +560,13 @@ module RangeStage<
551560 semSsaUpdateStep ( v , e , delta ) and
552561 pos .hasReadOfVar ( v ) and
553562 ( upper = true or upper = false ) and
554- reason = TSemNoReason ( )
563+ reason instanceof SemNoReason
555564 or
556565 exists ( SemGuard guard , boolean testIsTrue |
557566 pos .hasReadOfVar ( v ) and
558567 guard = boundFlowCond ( v , e , delta , upper , testIsTrue ) and
559568 semGuardDirectlyControlsSsaRead ( guard , pos , testIsTrue ) and
560- reason = TSemCondReason ( guard )
569+ reason . ( SemCondReason ) . getCond ( ) = guard
561570 )
562571 }
563572
@@ -570,7 +579,7 @@ module RangeStage<
570579 pos .hasReadOfVar ( v ) and
571580 guard = semEqFlowCond ( v , e , delta , false , testIsTrue ) and
572581 semGuardDirectlyControlsSsaRead ( guard , pos , testIsTrue ) and
573- reason = TSemCondReason ( guard )
582+ reason . ( SemCondReason ) . getCond ( ) = guard
574583 )
575584 }
576585
@@ -700,7 +709,7 @@ module RangeStage<
700709 // upper = true: v <= mid + d1 <= b + d1 + d2 = b + delta
701710 // upper = false: v >= mid + d1 >= b + d1 + d2 = b + delta
702711 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 ) )
704713 )
705714 or
706715 exists ( D:: Delta d , SemReason r1 , SemReason r2 |
@@ -714,9 +723,9 @@ module RangeStage<
714723 upper = false and delta = D:: fromFloat ( D:: toFloat ( d ) + 1 )
715724 ) and
716725 (
717- reason = r1
726+ reason = r1 . combineWith ( r2 )
718727 or
719- reason = r2 and not r2 instanceof SemNoReason
728+ reason = r2 . combineWith ( r1 ) and not r2 instanceof SemNoReason
720729 )
721730 )
722731 }
@@ -786,7 +795,7 @@ module RangeStage<
786795 ( upper = true or upper = false ) and
787796 fromBackEdge0 = false and
788797 origdelta = D:: fromFloat ( 0 ) and
789- reason = TSemNoReason ( )
798+ reason instanceof SemNoReason
790799 |
791800 if semBackEdge ( phi , inp , edge )
792801 then
@@ -1044,13 +1053,13 @@ module RangeStage<
10441053 ( upper = true or upper = false ) and
10451054 fromBackEdge = false and
10461055 origdelta = delta and
1047- reason = TSemNoReason ( )
1056+ reason instanceof SemNoReason
10481057 or
10491058 baseBound ( e , delta , upper ) and
10501059 b instanceof SemZeroBound and
10511060 fromBackEdge = false and
10521061 origdelta = delta and
1053- reason = TSemNoReason ( )
1062+ reason instanceof SemNoReason
10541063 or
10551064 exists ( SemSsaVariable v , SemSsaReadPositionBlock bb |
10561065 boundedSsa ( v , bb , b , delta , upper , fromBackEdge , origdelta , reason ) and
@@ -1104,9 +1113,9 @@ module RangeStage<
11041113 boundedConditionalExpr ( cond , b , upper , true , d1 , fbe1 , od1 , r1 ) and
11051114 boundedConditionalExpr ( cond , b , upper , false , d2 , fbe2 , od2 , r2 ) and
11061115 (
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 )
11081117 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 )
11101119 )
11111120 |
11121121 upper = true and delta = D:: fromFloat ( D:: toFloat ( d1 ) .maximum ( D:: toFloat ( d2 ) ) )
@@ -1132,9 +1141,15 @@ module RangeStage<
11321141 delta = D:: fromFloat ( D:: toFloat ( dLeft ) + D:: toFloat ( dRight ) ) and
11331142 fromBackEdge = fbeLeft .booleanOr ( fbeRight )
11341143 |
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
11361148 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
11381153 )
11391154 or
11401155 exists (
@@ -1150,9 +1165,9 @@ module RangeStage<
11501165 (
11511166 if D:: toFloat ( d1 ) .abs ( ) > D:: toFloat ( d2 ) .abs ( )
11521167 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 )
11541169 ) 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 )
11561171 )
11571172 )
11581173 |
@@ -1168,11 +1183,14 @@ module RangeStage<
11681183 boundedMulOperand ( e , upper , true , dLeft , fbeLeft , odLeft , rLeft ) and
11691184 boundedMulOperand ( e , upper , false , dRight , fbeRight , odRight , rRight ) and
11701185 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
11721188 |
1173- b instanceof SemZeroBound and origdelta = odLeft and reason = rLeft
1189+ origdelta = odLeft and
1190+ reason = rLeft .combineWith ( rRight )
11741191 or
1175- b instanceof SemZeroBound and origdelta = odRight and reason = rRight
1192+ origdelta = odRight and
1193+ reason = rRight .combineWith ( rLeft )
11761194 )
11771195 )
11781196 }
0 commit comments