1919 - (cptypes ir ctxt types) -> (values ir ret types t-types f-types)
2020 + arguments
2121 ir: expression to be optimized
22- ctxt: 'effect 'test 'value
22+ ctxt: 'effect 'test 'value 'tail
2323 types: an immutable dictionary (currently an intmap).
2424 The dictionary connects the counter of a prelex with the types
2525 discovered previously.
@@ -753,10 +753,10 @@ Notes:
753753 ; ; here because we know an error will be raised); we need to keep
754754 ; ; those non-tail:
755755 (single-valued? e))
756- ; ; A 'test or 'effect context cannot have an active attachment,
756+ ; ; A 'test, 'effect or 'value context cannot have an active attachment,
757757 ; ; and they are non-tail with respect to the enclosing function,
758758 ; ; so ok to have `e` immediately:
759- (not (eq? 'value ctxt)))
759+ (not (eq? 'tail ctxt)))
760760 ; ; => It's ok to potentially move `e` into tail position
761761 ; ; from a continuation-marks perspective. Although an
762762 ; ; error may trigger a handler that has continuation-mark
@@ -1478,8 +1478,8 @@ Notes:
14781478 types2 t-types2 f-types2))])))
14791479
14801480 (define-specialize/unrestricted 2 $call-setting-continuation-attachment
1481- ; ; body is in 'value context, because called with a mark
1482- [(e1 e2) (handle-call-attachment preinfo pr e1 e2 ctxt oldtypes plxc 'value )])
1481+ ; ; body is in 'tail context, because called with a mark
1482+ [(e1 e2) (handle-call-attachment preinfo pr e1 e2 ctxt oldtypes plxc 'tail )])
14831483
14841484 (define-specialize/unrestricted 2 $call-getting-continuation-attachment
14851485 [(e1 e2) (handle-call-attachment preinfo pr e1 e2 ctxt oldtypes plxc ctxt)])
@@ -1607,6 +1607,25 @@ Notes:
16071607 [r* (if unsafe nr* r*)])
16081608 (fold-primref/try-predicate preinfo pr e* ret r* ctxt ntypes oldtypes plxc))]))))
16091609
1610+ (define (wrap/result ctxt ir qret ntypes )
1611+ ; Assume cret is a quoted constant, that can be used as result in the expression
1612+ ; and also as the the predicate in ret.
1613+ (let ([ir (cond
1614+ [(eq? ctxt 'effect )
1615+ ir]
1616+ [(and (eq? ctxt 'tail )
1617+ (>= (debug-level) 2 )
1618+ (nanopass-case (Lsrc Expr) ir
1619+ [(call ,preinfo ,pr ,e* ...)
1620+ (let ([flags (primref-flags pr)])
1621+ (and (not (all-set? (prim-mask unsafe) flags))
1622+ (not (all-set? (prim-mask unrestricted) flags))))]
1623+ [else #t ]))
1624+ ir]
1625+ [else
1626+ (make-seq ctxt ir qret)])])
1627+ (values ir qret ntypes #f #f )))
1628+
16101629 (define (fold-primref/try-predicate preinfo pr e* ret r* ctxt ntypes oldtypes plxc )
16111630 (cond
16121631 [(not (and (fx= (length e*) 1 ) (primref->predicate pr #t )))
@@ -1617,11 +1636,9 @@ Notes:
16171636 (primref->argument-predicate pr 0 1 #t ))])
16181637 (cond
16191638 [(predicate-implies? r (primref->predicate pr #f ))
1620- (values (make-seq ctxt `(call ,preinfo ,pr ,e) true-rec)
1621- true-rec ntypes #f #f )]
1639+ (wrap/result ctxt `(call ,preinfo ,pr ,e) true-rec ntypes)]
16221640 [(predicate-disjoint? r (primref->predicate pr #t ))
1623- (values (make-seq ctxt `(call ,preinfo ,pr ,e) false-rec)
1624- false-rec ntypes #f #f )]
1641+ (wrap/result ctxt `(call ,preinfo ,pr ,e) false-rec ntypes)]
16251642 [else
16261643 (let ([ttypes (and (eq? ctxt 'test )
16271644 (pred-env-add/ref ntypes e (primref->predicate pr #t ) plxc))]
@@ -1717,7 +1734,7 @@ Notes:
17171734 (let*-values ([(ntypes e* r* t* t-t* f-t*)
17181735 (map-Expr/delayed e* oldtypes plxc)]
17191736 [(e0 ret0 types0 t-types0 f-types0 e0-bottom?)
1720- (Expr/call e0 'value ntypes oldtypes plxc)])
1737+ (Expr/call e0 'tail ntypes oldtypes plxc)])
17211738 (cond
17221739 [(or (and e0-bottom? e0)
17231740 (ormap (lambda (e r ) (and (predicate-implies? r 'bottom ) e)) e* r*))
@@ -1926,7 +1943,7 @@ Notes:
19261943 (values (if (unsafe-unreachable? e2)
19271944 (make-seq ctxt e1 e3)
19281945 (if (or (< (debug-level) 2 )
1929- (not (eq? ctxt 'value )))
1946+ (not (eq? ctxt 'tail )))
19301947 (make-seq ctxt `(if ,e1 ,e2 ,void-rec) e3)
19311948 ; ; If `debug-level` >= 2, may need to keep in tail position
19321949 ir))
@@ -1935,7 +1952,7 @@ Notes:
19351952 (values (if (unsafe-unreachable? e3)
19361953 (make-seq ctxt e1 e2)
19371954 (if (or (< (debug-level) 2 )
1938- (not (eq? ctxt 'value )))
1955+ (not (eq? ctxt 'tail )))
19391956 (make-seq ctxt `(if ,e1 ,void-rec ,e3) e2)
19401957 ; ; As above:
19411958 ir))
@@ -1986,7 +2003,7 @@ Notes:
19862003 (nanopass-case (Lsrc CaseLambdaClause) cl
19872004 [(clause (,x* ...) ,interface ,body)
19882005 (let-values ([(body ret types t-types f-types)
1989- (Expr body 'value types plxc)])
2006+ (Expr body 'tail types plxc)]) ; use 'tail context just in case
19902007 (for-each (lambda (x ) (prelex-operand-set! x #f )) x*)
19912008 (with-output-language (Lsrc CaseLambdaClause)
19922009 `(clause (,x* ...) ,interface ,body)))]))
@@ -2107,7 +2124,7 @@ Notes:
21072124 ; external version of cptypes: Lsrc -> Lsrc
21082125 (define (Scptypes ir )
21092126 (let-values ([(ir ret types t-types f-types)
2110- (Expr ir 'value pred-env-empty (box 0 ))])
2127+ (Expr ir 'tail pred-env-empty (box 0 ))])
21112128 ir))
21122129
21132130 (set! $cptypes Scptypes)
0 commit comments