semi-inline call/cc
in tail position
Effectively, change a `call/cc` call to `let/cc` when it appears in the tail position of a function. This change takes advantage of continuation-reification support that was built for continuation attachments. original commit: 4c015a5b55f7d04839a0efd8e5554fc237e4663b
This commit is contained in:
parent
bed6036b26
commit
f52283de7e
8
BUILDING
8
BUILDING
|
@ -15,6 +15,14 @@ limitations under the License.
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This variant of Chez Scheme is patched for Racket. It doesn't include
|
||||||
|
boot files; instead, Racket can generate initial boot files from Chez
|
||||||
|
Scheme's source. For more information, see "racket/src/cs/README.txt"
|
||||||
|
in Racket sources. After you have boot files, then the directions below
|
||||||
|
should work.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
This directory contains the sources for Chez Scheme, plus boot and header
|
This directory contains the sources for Chez Scheme, plus boot and header
|
||||||
files for various supported machine types.
|
files for various supported machine types.
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ InstallLZ4Target=
|
||||||
# no changes should be needed below this point #
|
# no changes should be needed below this point #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
Version=csv9.5.3.3
|
Version=csv9.5.3.4
|
||||||
Include=boot/$m
|
Include=boot/$m
|
||||||
PetiteBoot=boot/$m/petite.boot
|
PetiteBoot=boot/$m/petite.boot
|
||||||
SchemeBoot=boot/$m/scheme.boot
|
SchemeBoot=boot/$m/scheme.boot
|
||||||
|
|
|
@ -328,7 +328,7 @@
|
||||||
[(_ foo e1 e2) e1] ...
|
[(_ foo e1 e2) e1] ...
|
||||||
[(_ bar e1 e2) e2]))))])))
|
[(_ bar e1 e2) e2]))))])))
|
||||||
|
|
||||||
(define-constant scheme-version #x09050303)
|
(define-constant scheme-version #x09050304)
|
||||||
|
|
||||||
(define-syntax define-machine-types
|
(define-syntax define-machine-types
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
|
@ -2656,7 +2656,8 @@
|
||||||
(ormap1 #f 2 #f #t)
|
(ormap1 #f 2 #f #t)
|
||||||
(put-bytevector-some #f 4 #f #t)
|
(put-bytevector-some #f 4 #f #t)
|
||||||
(put-string-some #f 4 #f #t)
|
(put-string-some #f 4 #f #t)
|
||||||
(reify-cc #f 0 #f #f)
|
(reify-1cc #f 0 #f #f)
|
||||||
|
(maybe-reify-cc #f 0 #f #f)
|
||||||
(dofretu8* #f 1 #f #f)
|
(dofretu8* #f 1 #f #f)
|
||||||
(dofretu16* #f 1 #f #f)
|
(dofretu16* #f 1 #f #f)
|
||||||
(dofretu32* #f 1 #f #f)
|
(dofretu32* #f 1 #f #f)
|
||||||
|
|
|
@ -910,7 +910,8 @@
|
||||||
(declare-intrinsic dofretu32* dofretu32* (%ac0 %ts %td %cp %ac1) (%ac0) (%xp))
|
(declare-intrinsic dofretu32* dofretu32* (%ac0 %ts %td %cp %ac1) (%ac0) (%xp))
|
||||||
(declare-intrinsic get-room get-room () (%xp) (%xp))
|
(declare-intrinsic get-room get-room () (%xp) (%xp))
|
||||||
(declare-intrinsic scan-remembered-set scan-remembered-set () () ())
|
(declare-intrinsic scan-remembered-set scan-remembered-set () () ())
|
||||||
(declare-intrinsic reify-cc reify-cc (%xp %ac0 %ts) () (%td))
|
(declare-intrinsic reify-1cc reify-1cc (%xp %ac0 %ts) () (%td))
|
||||||
|
(declare-intrinsic maybe-reify-cc maybe-reify-cc (%xp %ac0 %ts) () (%td))
|
||||||
(declare-intrinsic dooverflow dooverflow () () ())
|
(declare-intrinsic dooverflow dooverflow () () ())
|
||||||
(declare-intrinsic dooverflood dooverflood () (%xp) ())
|
(declare-intrinsic dooverflood dooverflood () (%xp) ())
|
||||||
; a dorest routine takes all of the register and frame arguments from the rest
|
; a dorest routine takes all of the register and frame arguments from the rest
|
||||||
|
@ -1657,6 +1658,19 @@
|
||||||
[else
|
[else
|
||||||
;; Check dynamically for attachment, and also reify for tail
|
;; Check dynamically for attachment, and also reify for tail
|
||||||
`(let ([,x (attachment-consume ,e1)]) ,body)])]
|
`(let ([,x (attachment-consume ,e1)]) ,body)])]
|
||||||
|
[(call ,info ,mdcl ,pr
|
||||||
|
(case-lambda ,info2 (clause (,x) ,interface ,[body mode -> body])))
|
||||||
|
(guard (and (memq mode '(tail tail/none tail/some))
|
||||||
|
(eq? (primref-name pr) 'call/cc)
|
||||||
|
(= interface 1)))
|
||||||
|
;; Since we're in tail position, we can just reify the continuation and
|
||||||
|
;; put the stack link in the argument variable.
|
||||||
|
(let ([cop (case mode
|
||||||
|
[(tail/some tail/none)
|
||||||
|
;; Already reified
|
||||||
|
'get]
|
||||||
|
[else 'reify])])
|
||||||
|
`(let ([,x (continuation-get ,cop)]) ,body))]
|
||||||
[(call ,info ,mdcl ,[e 'non/none -> e] ,[e* 'non/none -> e*] ...)
|
[(call ,info ,mdcl ,[e 'non/none -> e] ,[e* 'non/none -> e*] ...)
|
||||||
(let ([info (case mode
|
(let ([info (case mode
|
||||||
[(non/some) (info-call->shifting-info-call info)]
|
[(non/some) (info-call->shifting-info-call info)]
|
||||||
|
@ -2204,7 +2218,7 @@
|
||||||
b*)
|
b*)
|
||||||
c))))))
|
c))))))
|
||||||
(module (make-bank deposit retain borrow)
|
(module (make-bank deposit retain borrow)
|
||||||
; NB: borrowing is probably cubic at present
|
; NB: borrowing is probably cubic at pre<sent
|
||||||
; might should represent bank as a prefix tree
|
; might should represent bank as a prefix tree
|
||||||
(define sort-free
|
(define sort-free
|
||||||
(lambda (free*)
|
(lambda (free*)
|
||||||
|
@ -10090,6 +10104,7 @@
|
||||||
(Triv* e*
|
(Triv* e*
|
||||||
(lambda (t*)
|
(lambda (t*)
|
||||||
(k `(attachment-set ,aop ,t* ...))))]
|
(k `(attachment-set ,aop ,t* ...))))]
|
||||||
|
[(continuation-get ,cop) (k `(continuation-get ,cop))]
|
||||||
[(foreign-call ,info ,e0 ,e1* ...)
|
[(foreign-call ,info ,e0 ,e1* ...)
|
||||||
(Triv* (cons e0 e1*)
|
(Triv* (cons e0 e1*)
|
||||||
(lambda (t*)
|
(lambda (t*)
|
||||||
|
@ -10451,6 +10466,8 @@
|
||||||
`(set! ,lvalue (attachment-get ,t* ...))]
|
`(set! ,lvalue (attachment-get ,t* ...))]
|
||||||
[(set! ,[lvalue] (attachment-consume ,[t*] ...))
|
[(set! ,[lvalue] (attachment-consume ,[t*] ...))
|
||||||
`(set! ,lvalue (attachment-consume ,t* ...))]
|
`(set! ,lvalue (attachment-consume ,t* ...))]
|
||||||
|
[(set! ,[lvalue] (continuation-get ,cop))
|
||||||
|
`(set! ,lvalue (continuation-get ,cop))]
|
||||||
[(label ,l ,[ebody]) `(seq (label ,l) ,ebody)]
|
[(label ,l ,[ebody]) `(seq (label ,l) ,ebody)]
|
||||||
[(trap-check ,ioc ,[ebody]) `(seq (trap-check ,ioc) ,ebody)]
|
[(trap-check ,ioc ,[ebody]) `(seq (trap-check ,ioc) ,ebody)]
|
||||||
[(overflow-check ,[ebody]) `(seq (overflow-check) ,ebody)]
|
[(overflow-check ,[ebody]) `(seq (overflow-check) ,ebody)]
|
||||||
|
@ -10469,7 +10486,8 @@
|
||||||
,(f `(seq (label ,(car l*)) ,(car e*)) (cdr l*) (cdr e*)))))
|
,(f `(seq (label ,(car l*)) ,(car e*)) (cdr l*) (cdr e*)))))
|
||||||
(label ,join)))]
|
(label ,join)))]
|
||||||
[(values ,info ,t* ...) `(nop)]
|
[(values ,info ,t* ...) `(nop)]
|
||||||
[(attachment-get ,t* ...) `(nop)])
|
[(attachment-get ,t* ...) `(nop)]
|
||||||
|
[(continuation-get ,cop) `(nop)])
|
||||||
(Tail : Expr (ir) -> Tail ()
|
(Tail : Expr (ir) -> Tail ()
|
||||||
[(inline ,info ,prim ,[t*] ...)
|
[(inline ,info ,prim ,[t*] ...)
|
||||||
(guard (pred-primitive? prim))
|
(guard (pred-primitive? prim))
|
||||||
|
@ -10668,11 +10686,11 @@
|
||||||
x)))))
|
x)))))
|
||||||
(define add-reify-cc-save
|
(define add-reify-cc-save
|
||||||
(lambda (live-reg* e)
|
(lambda (live-reg* e)
|
||||||
;; Save and restore any live registers that may be used by the `reify-cc` instrinsic.
|
;; Save and restore any live registers that may be used by the `reify-1cc` instrinsic.
|
||||||
;; Since we can't use temporaries at this point --- %sfp is already moved --- manually
|
;; Since we can't use temporaries at this point --- %sfp is already moved --- manually
|
||||||
;; allocate a few registers (that may not be real registers) and hope that we
|
;; allocate a few registers (that may not be real registers) and hope that we
|
||||||
;; have enough.
|
;; have enough.
|
||||||
(let* ([reify-cc-modify-reg* (intrinsic-modify-reg* reify-cc)]
|
(let* ([reify-cc-modify-reg* (intrinsic-modify-reg* reify-1cc)]
|
||||||
[tmp-reg* (reg-list %ac1 %yp)]
|
[tmp-reg* (reg-list %ac1 %yp)]
|
||||||
[save-reg* (fold-left (lambda (reg* r)
|
[save-reg* (fold-left (lambda (reg* r)
|
||||||
(cond
|
(cond
|
||||||
|
@ -10729,7 +10747,7 @@
|
||||||
[(mref ,x1 ,x2 ,imm) (cons x1 (cons x2 live-reg*))]
|
[(mref ,x1 ,x2 ,imm) (cons x1 (cons x2 live-reg*))]
|
||||||
[else live-reg*]))
|
[else live-reg*]))
|
||||||
(%seq
|
(%seq
|
||||||
(set! ,%td (inline ,(intrinsic-info-asmlib reify-cc #f) ,%asmlibcall))
|
(set! ,%td (inline ,(intrinsic-info-asmlib reify-1cc #f) ,%asmlibcall))
|
||||||
(set! ,%ts ,(%mref ,%td ,(constant continuation-attachments-disp)))
|
(set! ,%ts ,(%mref ,%td ,(constant continuation-attachments-disp)))
|
||||||
(set! ,(%mref ,%td ,(constant continuation-attachments-disp)) ,(%mref ,%ts ,(constant pair-cdr-disp)))))
|
(set! ,(%mref ,%td ,(constant continuation-attachments-disp)) ,(%mref ,%ts ,(constant pair-cdr-disp)))))
|
||||||
,e)]
|
,e)]
|
||||||
|
@ -11788,7 +11806,7 @@
|
||||||
`(set! ,lvalue ,t)
|
`(set! ,lvalue ,t)
|
||||||
(%seq
|
(%seq
|
||||||
(set! ,lvalue ,t)
|
(set! ,lvalue ,t)
|
||||||
(set! ,%td (inline ,(intrinsic-info-asmlib reify-cc #f) ,%asmlibcall))))
|
(set! ,%td (inline ,(intrinsic-info-asmlib reify-1cc #f) ,%asmlibcall))))
|
||||||
;; Reified with attachment
|
;; Reified with attachment
|
||||||
,(let ([get `(set! ,lvalue ,(%mref ,ats ,(constant pair-car-disp)))])
|
,(let ([get `(set! ,lvalue ,(%mref ,ats ,(constant pair-car-disp)))])
|
||||||
(if consume?
|
(if consume?
|
||||||
|
@ -11801,7 +11819,7 @@
|
||||||
`(set! ,lvalue ,t)
|
`(set! ,lvalue ,t)
|
||||||
(%seq
|
(%seq
|
||||||
(set! ,lvalue ,t)
|
(set! ,lvalue ,t)
|
||||||
(set! ,%td (inline ,(intrinsic-info-asmlib reify-cc #f) ,%asmlibcall))))))))))
|
(set! ,%td (inline ,(intrinsic-info-asmlib reify-1cc #f) ,%asmlibcall))))))))))
|
||||||
(Program : Program (ir) -> Program ()
|
(Program : Program (ir) -> Program ()
|
||||||
[(labels ([,l* ,le*] ...) ,l)
|
[(labels ([,l* ,le*] ...) ,l)
|
||||||
`(labels ([,l* ,(map CaseLambdaExpr le* l*)] ...) ,l)])
|
`(labels ([,l* ,(map CaseLambdaExpr le* l*)] ...) ,l)])
|
||||||
|
@ -11827,17 +11845,18 @@
|
||||||
[(dorest3) (make-do-rest 3 frame-args-offset)]
|
[(dorest3) (make-do-rest 3 frame-args-offset)]
|
||||||
[(dorest4) (make-do-rest 4 frame-args-offset)]
|
[(dorest4) (make-do-rest 4 frame-args-offset)]
|
||||||
[(dorest5) (make-do-rest 5 frame-args-offset)]
|
[(dorest5) (make-do-rest 5 frame-args-offset)]
|
||||||
[(reify-cc)
|
[(reify-1cc maybe-reify-cc)
|
||||||
(let ([other-reg* (fold-left (lambda (live* kill) (remq kill live*))
|
(let ([other-reg* (fold-left (lambda (live* kill) (remq kill live*))
|
||||||
(vector->list regvec)
|
(vector->list regvec)
|
||||||
;; Registers used by `reify-cc-help` output,
|
;; Registers used by `reify-cc-help` output,
|
||||||
;; plus `%ts` so that we have one to allocate
|
;; plus `%ts` so that we have one to allocate
|
||||||
(reg-list %xp %td %ac0 %ts))])
|
(reg-list %xp %td %ac0 %ts))]
|
||||||
`(lambda ,(make-named-info-lambda "reify-cc" '(0)) 0 ()
|
[1cc? (eq? sym 'reify-1cc)])
|
||||||
|
`(lambda ,(make-named-info-lambda (if 1cc? "reify-1cc" "maybe-reify-cc") '(0)) 0 ()
|
||||||
,(asm-enter
|
,(asm-enter
|
||||||
(%seq
|
(%seq
|
||||||
(check-live ,other-reg* ...)
|
(check-live ,other-reg* ...)
|
||||||
,(reify-cc-help #t #t
|
,(reify-cc-help 1cc? 1cc?
|
||||||
(lambda (reg)
|
(lambda (reg)
|
||||||
(if (eq? reg %td)
|
(if (eq? reg %td)
|
||||||
`(asm-return ,%td ,other-reg* ...)
|
`(asm-return ,%td ,other-reg* ...)
|
||||||
|
@ -11997,7 +12016,9 @@
|
||||||
[(attachment-get ,t* ...)
|
[(attachment-get ,t* ...)
|
||||||
($oops who "Effect is responsible for handling attachment-gets")]
|
($oops who "Effect is responsible for handling attachment-gets")]
|
||||||
[(attachment-consume ,t* ...)
|
[(attachment-consume ,t* ...)
|
||||||
($oops who "Effect is responsible for handling attachment-consumes")])
|
($oops who "Effect is responsible for handling attachment-consumes")]
|
||||||
|
[(continuation-get ,cop)
|
||||||
|
($oops who "Effect is responsible for handling continuatio-get")])
|
||||||
(Effect : Effect (ir) -> Effect ()
|
(Effect : Effect (ir) -> Effect ()
|
||||||
[(do-rest ,fixed-args)
|
[(do-rest ,fixed-args)
|
||||||
(if (fx<= fixed-args dorest-intrinsic-max)
|
(if (fx<= fixed-args dorest-intrinsic-max)
|
||||||
|
@ -12115,10 +12136,18 @@
|
||||||
(if ,(%inline eq? ,(%mref ,%td ,(constant continuation-attachments-disp)) ,ats)
|
(if ,(%inline eq? ,(%mref ,%td ,(constant continuation-attachments-disp)) ,ats)
|
||||||
(nop)
|
(nop)
|
||||||
(set! ,ats ,(%mref ,ats ,(constant pair-cdr-disp))))
|
(set! ,ats ,(%mref ,ats ,(constant pair-cdr-disp))))
|
||||||
(set! ,%td (inline ,(intrinsic-info-asmlib reify-cc #f) ,%asmlibcall)))
|
(set! ,%td (inline ,(intrinsic-info-asmlib reify-1cc #f) ,%asmlibcall)))
|
||||||
,(make-push)))]
|
,(make-push)))]
|
||||||
[else
|
[else
|
||||||
($oops who "unexpected attachment-set mode ~s" aop)]))])
|
($oops who "unexpected attachment-set mode ~s" aop)]))]
|
||||||
|
[(set! ,[lvalue] (continuation-get ,cop))
|
||||||
|
(case cop
|
||||||
|
[(get) `(set! ,lvalue ,(%tc-ref stack-link))]
|
||||||
|
[(reify) (%seq
|
||||||
|
(set! ,%td (inline ,(intrinsic-info-asmlib maybe-reify-cc #f) ,%asmlibcall))
|
||||||
|
(set! ,lvalue ,%td))]
|
||||||
|
[else
|
||||||
|
($oops who "unexpected continuation-set mode ~s" cop)])])
|
||||||
(Tail : Tail (ir) -> Tail ()
|
(Tail : Tail (ir) -> Tail ()
|
||||||
[(entry-point (,x* ...) ,dcl ,mcp ,tlbody)
|
[(entry-point (,x* ...) ,dcl ,mcp ,tlbody)
|
||||||
(unless (andmap (lambda (x) (eq? (uvar-type x) 'ptr)) x*)
|
(unless (andmap (lambda (x) (eq? (uvar-type x) 'ptr)) x*)
|
||||||
|
|
|
@ -112,7 +112,8 @@
|
||||||
;;; dounderflow & nuate must come before callcc
|
;;; dounderflow & nuate must come before callcc
|
||||||
(define-hand-coded-library-entry dounderflow)
|
(define-hand-coded-library-entry dounderflow)
|
||||||
(define-hand-coded-library-entry nuate)
|
(define-hand-coded-library-entry nuate)
|
||||||
(define-hand-coded-library-entry reify-cc)
|
(define-hand-coded-library-entry reify-1cc)
|
||||||
|
(define-hand-coded-library-entry maybe-reify-cc)
|
||||||
(define-hand-coded-library-entry callcc)
|
(define-hand-coded-library-entry callcc)
|
||||||
(define-hand-coded-library-entry call1cc)
|
(define-hand-coded-library-entry call1cc)
|
||||||
(define-hand-coded-library-entry dofargint32)
|
(define-hand-coded-library-entry dofargint32)
|
||||||
|
|
|
@ -387,15 +387,21 @@
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(memq x '(push pop set reify-and-set))))
|
(memq x '(push pop set reify-and-set))))
|
||||||
|
|
||||||
|
(define continuation-op?
|
||||||
|
(lambda (x)
|
||||||
|
(memq x '(get reify))))
|
||||||
|
|
||||||
; exposes continuation-attachment operations
|
; exposes continuation-attachment operations
|
||||||
(define-language L4.9375 (extends L4.875)
|
(define-language L4.9375 (extends L4.875)
|
||||||
(terminals
|
(terminals
|
||||||
(+ (attachment-op (aop))))
|
(+ (attachment-op (aop))
|
||||||
|
(continuation-op (cop))))
|
||||||
(entry CaseLambdaExpr)
|
(entry CaseLambdaExpr)
|
||||||
(Expr (e body)
|
(Expr (e body)
|
||||||
(+ (attachment-set aop e* ...)
|
(+ (attachment-set aop e* ...)
|
||||||
(attachment-get e* ...)
|
(attachment-get e* ...)
|
||||||
(attachment-consume e* ...))))
|
(attachment-consume e* ...)
|
||||||
|
(continuation-get cop))))
|
||||||
|
|
||||||
; moves all case lambda expressions into rhs of letrec
|
; moves all case lambda expressions into rhs of letrec
|
||||||
(define-language L5 (extends L4.9375)
|
(define-language L5 (extends L4.9375)
|
||||||
|
@ -672,7 +678,8 @@
|
||||||
(mvcall info e t) => (mvcall e t)
|
(mvcall info e t) => (mvcall e t)
|
||||||
(foreign-call info t t* ...)
|
(foreign-call info t t* ...)
|
||||||
(attachment-get t* ...)
|
(attachment-get t* ...)
|
||||||
(attachment-consume t* ...)))
|
(attachment-consume t* ...)
|
||||||
|
(continuation-get cop)))
|
||||||
(Expr (e body)
|
(Expr (e body)
|
||||||
(- lvalue
|
(- lvalue
|
||||||
(values info e* ...)
|
(values info e* ...)
|
||||||
|
@ -687,7 +694,8 @@
|
||||||
(mvcall info e1 e2)
|
(mvcall info e1 e2)
|
||||||
(foreign-call info e e* ...)
|
(foreign-call info e e* ...)
|
||||||
(attachment-get e* ...)
|
(attachment-get e* ...)
|
||||||
(attachment-consume e* ...))
|
(attachment-consume e* ...)
|
||||||
|
(continuation-get cop))
|
||||||
(+ rhs
|
(+ rhs
|
||||||
(values info t* ...)
|
(values info t* ...)
|
||||||
(set! lvalue rhs))))
|
(set! lvalue rhs))))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user