@@ -1252,70 +1252,6 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
12521252 unanalyzableDefBounds ( def , v , _, result )
12531253}
12541254
1255- /**
1256- * Get the lower bounds for a `RangeSsaDefinition`. Most of the work is
1257- * done by `getDefLowerBoundsImpl`, but this is where widening is applied
1258- * to prevent the analysis from exploding due to a recursive definition.
1259- */
1260- private float getDefLowerBounds ( RangeSsaDefinition def , StackVariable v ) {
1261- exists ( float newLB , float truncatedLB |
1262- newLB = getDefLowerBoundsImpl ( def , v ) and
1263- if varMinVal ( v ) <= newLB and newLB <= varMaxVal ( v )
1264- then truncatedLB = newLB
1265- else truncatedLB = varMinVal ( v )
1266- |
1267- // Widening: check whether the new lower bound is from a source which
1268- // depends recursively on the current definition.
1269- if isRecursiveDef ( def , v )
1270- then
1271- // The new lower bound is from a recursive source, so we round
1272- // down to one of a limited set of values to prevent the
1273- // recursion from exploding.
1274- result =
1275- max ( float widenLB |
1276- widenLB = wideningLowerBounds ( getVariableRangeType ( v ) ) and
1277- not widenLB > truncatedLB
1278- |
1279- widenLB
1280- )
1281- else result = truncatedLB
1282- )
1283- or
1284- // The definition might overflow positively and wrap. If so, the lower
1285- // bound is `typeLowerBound`.
1286- defMightOverflowPositively ( def , v ) and result = varMinVal ( v )
1287- }
1288-
1289- /** See comment for `getDefLowerBounds`, above. */
1290- private float getDefUpperBounds ( RangeSsaDefinition def , StackVariable v ) {
1291- exists ( float newUB , float truncatedUB |
1292- newUB = getDefUpperBoundsImpl ( def , v ) and
1293- if varMinVal ( v ) <= newUB and newUB <= varMaxVal ( v )
1294- then truncatedUB = newUB
1295- else truncatedUB = varMaxVal ( v )
1296- |
1297- // Widening: check whether the new upper bound is from a source which
1298- // depends recursively on the current definition.
1299- if isRecursiveDef ( def , v )
1300- then
1301- // The new upper bound is from a recursive source, so we round
1302- // up to one of a fixed set of values to prevent the recursion
1303- // from exploding.
1304- result =
1305- min ( float widenUB |
1306- widenUB = wideningUpperBounds ( getVariableRangeType ( v ) ) and
1307- not widenUB < truncatedUB
1308- |
1309- widenUB
1310- )
1311- else result = truncatedUB
1312- )
1313- or
1314- // The definition might overflow negatively and wrap. If so, the upper
1315- // bound is `typeUpperBound`.
1316- defMightOverflowNegatively ( def , v ) and result = varMaxVal ( v )
1317- }
1318-
13191255/**
13201256 * Helper for `getDefLowerBounds` and `getDefUpperBounds`. Find the set of
13211257 * unanalyzable definitions (such as function parameters) and make their
@@ -1675,6 +1611,70 @@ module SimpleRangeAnalysisInternal {
16751611 float getFullyConvertedUpperBounds ( Expr expr ) {
16761612 result = getTruncatedUpperBounds ( expr .getFullyConverted ( ) )
16771613 }
1614+
1615+ /**
1616+ * Get the lower bounds for a `RangeSsaDefinition`. Most of the work is
1617+ * done by `getDefLowerBoundsImpl`, but this is where widening is applied
1618+ * to prevent the analysis from exploding due to a recursive definition.
1619+ */
1620+ float getDefLowerBounds ( RangeSsaDefinition def , StackVariable v ) {
1621+ exists ( float newLB , float truncatedLB |
1622+ newLB = getDefLowerBoundsImpl ( def , v ) and
1623+ if varMinVal ( v ) <= newLB and newLB <= varMaxVal ( v )
1624+ then truncatedLB = newLB
1625+ else truncatedLB = varMinVal ( v )
1626+ |
1627+ // Widening: check whether the new lower bound is from a source which
1628+ // depends recursively on the current definition.
1629+ if isRecursiveDef ( def , v )
1630+ then
1631+ // The new lower bound is from a recursive source, so we round
1632+ // down to one of a limited set of values to prevent the
1633+ // recursion from exploding.
1634+ result =
1635+ max ( float widenLB |
1636+ widenLB = wideningLowerBounds ( getVariableRangeType ( v ) ) and
1637+ not widenLB > truncatedLB
1638+ |
1639+ widenLB
1640+ )
1641+ else result = truncatedLB
1642+ )
1643+ or
1644+ // The definition might overflow positively and wrap. If so, the lower
1645+ // bound is `typeLowerBound`.
1646+ defMightOverflowPositively ( def , v ) and result = varMinVal ( v )
1647+ }
1648+
1649+ /** See comment for `getDefLowerBounds`, above. */
1650+ float getDefUpperBounds ( RangeSsaDefinition def , StackVariable v ) {
1651+ exists ( float newUB , float truncatedUB |
1652+ newUB = getDefUpperBoundsImpl ( def , v ) and
1653+ if varMinVal ( v ) <= newUB and newUB <= varMaxVal ( v )
1654+ then truncatedUB = newUB
1655+ else truncatedUB = varMaxVal ( v )
1656+ |
1657+ // Widening: check whether the new upper bound is from a source which
1658+ // depends recursively on the current definition.
1659+ if isRecursiveDef ( def , v )
1660+ then
1661+ // The new upper bound is from a recursive source, so we round
1662+ // up to one of a fixed set of values to prevent the recursion
1663+ // from exploding.
1664+ result =
1665+ min ( float widenUB |
1666+ widenUB = wideningUpperBounds ( getVariableRangeType ( v ) ) and
1667+ not widenUB < truncatedUB
1668+ |
1669+ widenUB
1670+ )
1671+ else result = truncatedUB
1672+ )
1673+ or
1674+ // The definition might overflow negatively and wrap. If so, the upper
1675+ // bound is `typeUpperBound`.
1676+ defMightOverflowNegatively ( def , v ) and result = varMaxVal ( v )
1677+ }
16781678}
16791679
16801680private import SimpleRangeAnalysisInternal
0 commit comments