~ 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