@@ -90,6 +90,12 @@ type limitFact struct {
90
90
}
91
91
92
92
// factsTable keeps track of relations between pairs of values.
93
+ //
94
+ // The fact table logic is sound, but incomplete. Outside of a few
95
+ // special cases, it performs no deduction or arithmetic. While there
96
+ // are known decision procedures for this, the ad hoc approach taken
97
+ // by the facts table is effective for real code while remaining very
98
+ // efficient.
93
99
type factsTable struct {
94
100
facts map [pair ]relation // current known set of relation
95
101
stack []fact // previous sets of relations
@@ -433,8 +439,8 @@ var (
433
439
// TODO: OpIsInBounds actually test 0 <= a < b. This means
434
440
// that the positive branch learns signed/LT and unsigned/LT
435
441
// but the negative branch only learns unsigned/GE.
436
- OpIsInBounds : {unsigned , lt },
437
- OpIsSliceInBounds : {unsigned , lt | eq },
442
+ OpIsInBounds : {unsigned , lt }, // 0 <= arg0 < arg1
443
+ OpIsSliceInBounds : {unsigned , lt | eq }, // 0 <= arg0 <= arg1
438
444
}
439
445
)
440
446
@@ -625,6 +631,7 @@ func updateRestrictions(parent *Block, ft *factsTable, t domain, v, w *Value, r
625
631
// simplifyBlock simplifies block known the restrictions in ft.
626
632
// Returns which branch must always be taken.
627
633
func simplifyBlock (ft * factsTable , b * Block ) branch {
634
+ // Replace OpSlicemask operations in b with constants where possible.
628
635
for _ , v := range b .Values {
629
636
if v .Op != OpSlicemask {
630
637
continue
0 commit comments