@@ -437,20 +437,98 @@ module SignAnalysis<DeltaSig D> {
437
437
not hasGuard ( v , pos , result )
438
438
}
439
439
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
+
440
512
/**
441
513
* Gets a possible sign of `v` at read position `pos`, where a guard could have
442
514
* ruled out the sign but does not.
443
515
* This does not check that the definition of `v` also allows the sign.
444
516
*/
445
517
private Sign guardedSsaSignOk ( SemSsaVariable v , SsaReadPosition pos ) {
446
518
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 )
448
522
or
449
523
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 )
451
527
or
452
528
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 )
454
532
}
455
533
456
534
/** Gets a possible sign for `v` at `pos`. */
0 commit comments