mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 11:40:18 +02:00
CPS conversion calls module variables through trampolines
* module/language/tree-il/compile-cps.scm (module-call-stubs): (module-call-label, convert, cps-convert/thunk): Arrange to call module variables through out-of-line trampolines with unchecked arity. This should speed up compile time in large files and reduce code size on hot paths.
This commit is contained in:
parent
2b58c49e59
commit
c52dc02bbe
1 changed files with 86 additions and 2 deletions
|
@ -1,6 +1,6 @@
|
||||||
;;; Continuation-passing style (CPS) intermediate language (IL)
|
;;; Continuation-passing style (CPS) intermediate language (IL)
|
||||||
|
|
||||||
;; Copyright (C) 2013-2015,2017-2020 Free Software Foundation, Inc.
|
;; Copyright (C) 2013-2015,2017-2021 Free Software Foundation, Inc.
|
||||||
|
|
||||||
;;;; This library is free software; you can redistribute it and/or
|
;;;; This library is free software; you can redistribute it and/or
|
||||||
;;;; modify it under the terms of the GNU Lesser General Public
|
;;;; modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -1393,6 +1393,75 @@
|
||||||
(scope-counter (1+ scope-id))
|
(scope-counter (1+ scope-id))
|
||||||
scope-id))
|
scope-id))
|
||||||
|
|
||||||
|
;;; For calls to known imported values, we don't want to duplicate the
|
||||||
|
;;; "resolve the import" code at each call site. Instead we generate a
|
||||||
|
;;; stub per callee, and have callers call-label the callees.
|
||||||
|
;;;
|
||||||
|
(define module-call-stubs (make-parameter #f))
|
||||||
|
(define (module-call-label cps mod name public? nargs)
|
||||||
|
"Return three values: the new CPS, the label to call, and the value to
|
||||||
|
use as the proc slot."
|
||||||
|
(define call-stub-key (list mod name public? nargs))
|
||||||
|
(define var-cache-key (list mod name public?))
|
||||||
|
(define var-cache
|
||||||
|
(build-exp ($primcall 'cache-ref var-cache-key ())))
|
||||||
|
(match (assoc-ref (module-call-stubs) call-stub-key)
|
||||||
|
(#f
|
||||||
|
(let* ((trampoline-name (string->symbol
|
||||||
|
(format #f "~a~a~a"
|
||||||
|
name (if public? "@" "@@")
|
||||||
|
(string-join (map symbol->string mod)
|
||||||
|
"/"))))
|
||||||
|
(cached (fresh-var))
|
||||||
|
(args (let lp ((n 0))
|
||||||
|
(if (< n nargs)
|
||||||
|
(cons (fresh-var) (lp (1+ n)))
|
||||||
|
'())))
|
||||||
|
(argv (cons cached args))
|
||||||
|
(names (let lp ((n 0))
|
||||||
|
(if (< n (1+ nargs))
|
||||||
|
(cons (string->symbol
|
||||||
|
(string-append "arg" (number->string n)))
|
||||||
|
(lp (1+ n)))
|
||||||
|
'()))))
|
||||||
|
(with-cps cps
|
||||||
|
(letv fresh-var var proc)
|
||||||
|
(letk ktail ($ktail))
|
||||||
|
(letk kcall
|
||||||
|
($kargs ('proc) (proc)
|
||||||
|
($continue ktail #f ($call proc args))))
|
||||||
|
(letk kref
|
||||||
|
($kargs ('var) (var)
|
||||||
|
($continue kcall #f
|
||||||
|
($primcall 'scm-ref/immediate '(box . 1) (var)))))
|
||||||
|
(letk kcache2
|
||||||
|
($kargs () ()
|
||||||
|
($continue kref #f ($values (fresh-var)))))
|
||||||
|
(letk kcache
|
||||||
|
($kargs ('var) (fresh-var)
|
||||||
|
($continue kcache2 #f
|
||||||
|
($primcall 'cache-set! var-cache-key (fresh-var)))))
|
||||||
|
(letk klookup
|
||||||
|
($kargs () ()
|
||||||
|
($continue kcache #f
|
||||||
|
($primcall (if public?
|
||||||
|
'lookup-bound-public
|
||||||
|
'lookup-bound-private)
|
||||||
|
(list mod name) ()))))
|
||||||
|
(letk kcached
|
||||||
|
($kargs () ()
|
||||||
|
($continue kref #f ($values (cached)))))
|
||||||
|
(letk kentry
|
||||||
|
($kargs names argv
|
||||||
|
($branch klookup kcached #f 'heap-object? #f (cached))))
|
||||||
|
(letk kfun ($kfun #f `((name . ,trampoline-name)) #f ktail kentry))
|
||||||
|
($ ((lambda (cps)
|
||||||
|
(module-call-stubs
|
||||||
|
(acons call-stub-key kfun (module-call-stubs)))
|
||||||
|
(values cps kfun var-cache)))))))
|
||||||
|
(kfun
|
||||||
|
(values cps kfun var-cache))))
|
||||||
|
|
||||||
(define (toplevel-box cps src name bound? have-var)
|
(define (toplevel-box cps src name bound? have-var)
|
||||||
(match (current-topbox-scope)
|
(match (current-topbox-scope)
|
||||||
(#f
|
(#f
|
||||||
|
@ -1867,6 +1936,20 @@
|
||||||
(build-term
|
(build-term
|
||||||
($continue kmod src ($primcall 'current-module #f ())))))))))
|
($continue kmod src ($primcall 'current-module #f ())))))))))
|
||||||
|
|
||||||
|
(($ <call> src ($ <module-ref> src2 mod name public?) args)
|
||||||
|
(convert-args cps args
|
||||||
|
(lambda (cps args)
|
||||||
|
(call-with-values
|
||||||
|
(lambda () (module-call-label cps mod name public? (length args)))
|
||||||
|
(lambda (cps kfun proc-exp)
|
||||||
|
(with-cps cps
|
||||||
|
(letv cache)
|
||||||
|
(letk kcall ($kargs ('cache) (cache)
|
||||||
|
($continue k src
|
||||||
|
($callk kfun #f ,(cons cache args)))))
|
||||||
|
(build-term
|
||||||
|
($continue kcall src2 ,proc-exp))))))))
|
||||||
|
|
||||||
(($ <call> src proc args)
|
(($ <call> src proc args)
|
||||||
(convert-args cps (cons proc args)
|
(convert-args cps (cons proc args)
|
||||||
(match-lambda*
|
(match-lambda*
|
||||||
|
@ -2287,7 +2370,8 @@ integer."
|
||||||
(define (cps-convert/thunk exp)
|
(define (cps-convert/thunk exp)
|
||||||
(parameterize ((label-counter 0)
|
(parameterize ((label-counter 0)
|
||||||
(var-counter 0)
|
(var-counter 0)
|
||||||
(scope-counter 0))
|
(scope-counter 0)
|
||||||
|
(module-call-stubs '()))
|
||||||
(with-cps empty-intmap
|
(with-cps empty-intmap
|
||||||
(letv init)
|
(letv init)
|
||||||
;; Allocate kinit first so that we know that the entry point's
|
;; Allocate kinit first so that we know that the entry point's
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue