~ chicken-core (chicken-5) 954e75a3b8074d0edc0eebc1f9f6618399968e11


commit 954e75a3b8074d0edc0eebc1f9f6618399968e11
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Tue Dec 27 17:53:40 2016 +0100
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Thu Jan 12 11:48:48 2017 +0100

    Add __builtin_expect to help branch prediction.
    
    Currently applied to all C_demand() checks, which are unlikely to fail.
    So we make sure the C compiler knows the default branch is more likely.
    
    Signed-off-by: felix <felix@call-with-current-continuation.org>

diff --git a/c-backend.scm b/c-backend.scm
index 9b09312e..f8faba29 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -833,10 +833,10 @@
 		      (when target-stack-size
 			(gen #t "C_resize_stack(" target-stack-size ");") ) )
 		    (gen #t "C_check_nursery_minimum(C_calculate_demand(" demand ",c," max-av "));"
-			 #t "if(!C_demand(C_calculate_demand(" demand ",c," max-av "))){"
+			 #t "if(C_unlikely(!C_demand(C_calculate_demand(" demand ",c," max-av ")))){"
 			 #t "C_save_and_reclaim((void*)C_" topname ",c,av);}"
 			 #t "toplevel_initialized=1;"
-			 #t "if(!C_demand_2(" ldemand ")){"
+			 #t "if(C_unlikely(!C_demand_2(" ldemand "))){"
 			 #t "C_save(t1);"
 			 #t "C_rereclaim2(" ldemand "*sizeof(C_word),1);"
 			 #t "t1=C_restore;}"
@@ -851,7 +851,7 @@
 		  (when (and (not unsafe) (not no-argc-checks) (> n 2) (not empty-closure))
 		    (gen #t "if(c<" n ") C_bad_min_argc_2(c," n ",t0);") )
 		  (when insert-timer-checks (gen #t "C_check_for_interrupt;"))
-		  (gen #t "if(!C_demand(C_calculate_demand((c-" n ")*C_SIZEOF_PAIR +" demand ",c," max-av "))){"))
+		  (gen #t "if(C_unlikely(!C_demand(C_calculate_demand((c-" n ")*C_SIZEOF_PAIR +" demand ",c," max-av ")))){"))
 		 (else
 		  (unless direct (gen #t "C_word *a;"))
 		  (when (and direct (not unsafe) (not disable-stack-overflow-checking))
@@ -866,10 +866,10 @@
 			 ;; The interrupt handler may fill the stack, so we only
 			 ;; check for an interrupt when the procedure is restartable
 			 (when insert-timer-checks (gen #t "C_check_for_interrupt;"))
-			 (gen #t "if(!C_demand(C_calculate_demand("
+			 (gen #t "if(C_unlikely(!C_demand(C_calculate_demand("
 			      demand
 			      (if customizable ",0," ",c,")
-			      max-av "))){"))
+			      max-av ")))){"))
 			(else
 			 (gen #\{)))))
 	   (cond ((and (not (eq? 'toplevel id)) (not direct))
diff --git a/chicken.h b/chicken.h
index 0f619aa4..76661a7c 100644
--- a/chicken.h
+++ b/chicken.h
@@ -222,6 +222,8 @@ void *alloca ();
 #endif
 
 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
+# define C_unlikely(x)             __builtin_expect((x), 0)
+# define C_likely(x)               __builtin_expect((x), 1)
 # ifndef __cplusplus
 #  define C_cblock                ({
 #  define C_cblockend             })
@@ -236,6 +238,9 @@ void *alloca ();
 # if defined(__i386__) && !defined(__clang__)
 #  define C_regparm               __attribute__ ((regparm(3)))
 # endif
+#else
+# define C_unlikely(x)             (x)
+# define C_likely(x)               (x)
 #endif
 
 #ifndef C_cblock
Trap