~ chicken-core (chicken-5) 05646e8ec553dfc8857c9324597829a9976a286f
commit 05646e8ec553dfc8857c9324597829a9976a286f 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:23:37 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 594ed438..ca94014e 100644 --- a/c-backend.scm +++ b/c-backend.scm @@ -510,19 +510,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