@@ -437,20 +437,98 @@ module SignAnalysis<DeltaSig D> {
437437 not hasGuard ( v , pos , result )
438438 }
439439
440+ private SemExpr posBoundGetElement ( int i , SemSsaVariable v , SsaReadPosition pos ) {
441+ result =
442+ rank [ i + 1 ] ( SemExpr bound , SemBasicBlock b , int blockOrder , int indexOrder |
443+ posBound ( bound , v , pos ) and
444+ b = bound .getBasicBlock ( ) and
445+ blockOrder = b .getUniqueId ( ) and
446+ bound = b .getInstruction ( indexOrder )
447+ |
448+ bound order by blockOrder , indexOrder
449+ )
450+ }
451+
452+ private predicate posBoundOkFromIndex ( int i , SemSsaVariable v , SsaReadPosition pos ) {
453+ i = 0 and
454+ posBoundOk ( posBoundGetElement ( i , v , pos ) , v , pos )
455+ or
456+ posBoundOkFromIndex ( i - 1 , v , pos ) and
457+ posBoundOk ( posBoundGetElement ( i , v , pos ) , v , pos )
458+ }
459+
460+ private predicate posBoundGuardedSsaSignOk ( SemSsaVariable v , SsaReadPosition pos ) {
461+ posBoundOkFromIndex ( max ( int i | exists ( posBoundGetElement ( i , v , pos ) ) ) , v , pos )
462+ }
463+
464+ private SemExpr negBoundGetElement ( int i , SemSsaVariable v , SsaReadPosition pos ) {
465+ result =
466+ rank [ i + 1 ] ( SemExpr bound , SemBasicBlock b , int blockOrder , int indexOrder |
467+ negBound ( bound , v , pos ) and
468+ b = bound .getBasicBlock ( ) and
469+ blockOrder = b .getUniqueId ( ) and
470+ bound = b .getInstruction ( indexOrder )
471+ |
472+ bound order by blockOrder , indexOrder
473+ )
474+ }
475+
476+ private predicate negBoundOkFromIndex ( int i , SemSsaVariable v , SsaReadPosition pos ) {
477+ i = 0 and
478+ negBoundOk ( negBoundGetElement ( i , v , pos ) , v , pos )
479+ or
480+ negBoundOkFromIndex ( i - 1 , v , pos ) and
481+ negBoundOk ( negBoundGetElement ( i , v , pos ) , v , pos )
482+ }
483+
484+ private predicate negBoundGuardedSsaSignOk ( SemSsaVariable v , SsaReadPosition pos ) {
485+ negBoundOkFromIndex ( max ( int i | exists ( negBoundGetElement ( i , v , pos ) ) ) , v , pos )
486+ }
487+
488+ private SemExpr zeroBoundGetElement ( int i , SemSsaVariable v , SsaReadPosition pos ) {
489+ result =
490+ rank [ i + 1 ] ( SemExpr bound , SemBasicBlock b , int blockOrder , int indexOrder |
491+ zeroBound ( bound , v , pos ) and
492+ b = bound .getBasicBlock ( ) and
493+ blockOrder = b .getUniqueId ( ) and
494+ bound = b .getInstruction ( indexOrder )
495+ |
496+ bound order by blockOrder , indexOrder
497+ )
498+ }
499+
500+ private predicate zeroBoundOkFromIndex ( int i , SemSsaVariable v , SsaReadPosition pos ) {
501+ i = 0 and
502+ zeroBoundOk ( zeroBoundGetElement ( i , v , pos ) , v , pos )
503+ or
504+ zeroBoundOkFromIndex ( i - 1 , v , pos ) and
505+ zeroBoundOk ( zeroBoundGetElement ( i , v , pos ) , v , pos )
506+ }
507+
508+ private predicate zeroBoundGuardedSsaSignOk ( SemSsaVariable v , SsaReadPosition pos ) {
509+ zeroBoundOkFromIndex ( max ( int i | exists ( zeroBoundGetElement ( i , v , pos ) ) ) , v , pos )
510+ }
511+
440512 /**
441513 * Gets a possible sign of `v` at read position `pos`, where a guard could have
442514 * ruled out the sign but does not.
443515 * This does not check that the definition of `v` also allows the sign.
444516 */
445517 private Sign guardedSsaSignOk ( SemSsaVariable v , SsaReadPosition pos ) {
446518 result = TPos ( ) and
447- forex ( SemExpr bound | posBound ( bound , v , pos ) | posBoundOk ( bound , v , pos ) )
519+ // optimised version of
520+ // `forex(SemExpr bound | posBound(bound, v, pos) | posBoundOk(bound, v, pos))`
521+ posBoundGuardedSsaSignOk ( v , pos )
448522 or
449523 result = TNeg ( ) and
450- forex ( SemExpr bound | negBound ( bound , v , pos ) | negBoundOk ( bound , v , pos ) )
524+ // optimised version of
525+ // `forex(SemExpr bound | negBound(bound, v, pos) | negBoundOk(bound, v, pos))`
526+ negBoundGuardedSsaSignOk ( v , pos )
451527 or
452528 result = TZero ( ) and
453- forex ( SemExpr bound | zeroBound ( bound , v , pos ) | zeroBoundOk ( bound , v , pos ) )
529+ // optimised version of
530+ // `forex(SemExpr bound | zeroBound(bound, v, pos) | zeroBoundOk(bound, v, pos))`
531+ zeroBoundGuardedSsaSignOk ( v , pos )
454532 }
455533
456534 /** Gets a possible sign for `v` at `pos`. */
0 commit comments