~ chicken-core (chicken-5) aaca4af5b1fd9cc9c064fcae4e9a4a6ce67a0485


commit aaca4af5b1fd9cc9c064fcae4e9a4a6ce67a0485
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Tue Dec 27 18:06:12 2016 +0100
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Thu Jan 12 11:39:45 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 9631f62d..3bb2171b 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -819,10 +819,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;}"
@@ -837,7 +837,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))
@@ -852,10 +852,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 733958dc..4ae93e09 100644
--- a/chicken.h
+++ b/chicken.h
@@ -245,6 +245,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             })
@@ -261,6 +263,11 @@ void *alloca ();
 # endif
 #elif defined(__WATCOMC__)
 # define C_ccall                  __cdecl
+# define C_unlikely(x)             (x)
+# define C_likely(x)               (x)
+#else
+# define C_unlikely(x)             (x)
+# define C_likely(x)               (x)
 #endif
 
 #ifndef C_cblock
Trap