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