~ chicken-core (chicken-5) 6b9ebc427aa2b3bcd9ae30e7258e9b9ffe0a4bc8
commit 6b9ebc427aa2b3bcd9ae30e7258e9b9ffe0a4bc8 Author: Peter Bex <peter@more-magic.net> AuthorDate: Thu Dec 15 23:44:35 2016 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Thu Jan 12 12:17:57 2017 +0100 Statically determine if av can be reused or not. This is faster due to avoiding branch prediction misses. Signed-off-by: felix <felix@call-with-current-continuation.org> diff --git a/c-backend.scm b/c-backend.scm index 3bb2171b..a5e0f5d9 100644 --- a/c-backend.scm +++ b/c-backend.scm @@ -491,19 +491,27 @@ (let* ((n (length args)) (avl (+ n (if selfarg 1 0))) (caller-has-av? (not (or (lambda-literal-customizable ll) - (lambda-literal-direct ll))))) + (lambda-literal-direct ll)))) + (caller-argcount (lambda-literal-argument-count ll)) + (caller-rest-mode (lambda-literal-rest-argument-mode ll))) ;; Try to re-use argvector from current function if it is ;; large enough. push-args gets used only for functions in ;; CPS context, so callee never returns to current function. ;; And even so, av[] is already copied into temporaries. - (cond (caller-has-av? - (gen #t "C_word *av2;") - (gen #t "if(c >= " avl ") {") - (gen #t " av2=av; /* Re-use our own argvector */") - (gen #t "} else {") - (gen #t " av2=C_alloc(" avl ");") - (gen #t "}")) - (else (gen #t "C_word av2[" avl "];"))) + (cond + ((or (not caller-has-av?) ; Argvec missing or + (and (< caller-argcount avl) ; known to be too small? + (eq? caller-rest-mode 'none))) + (gen #t "C_word av2[" avl "];")) + ((>= caller-argcount avl) ; Argvec known to be re-usable? + (gen #t "C_word *av2=av; /* Re-use our own argvector */")) + (else ; Need to determine dynamically. This is slower. + (gen #t "C_word *av2;") + (gen #t "if(c >= " avl ") {") + (gen #t " av2=av; /* Re-use our own argvector */") + (gen #t "} else {") + (gen #t " av2=C_alloc(" avl ");") + (gen #t "}"))) (when selfarg (gen #t "av2[0]=" selfarg ";")) (do ((j (if selfarg 1 0) (add1 j)) (args args (cdr args)))Trap