Author: danielsh
Date: Mon Jul 29 18:35:25 2013
New Revision: 1508170

URL: http://svn.apache.org/r1508170
Log:
Follow-up to r1507366: svn_hash_gets: compute the length of string literal
keys (common case) at compile-time, without multiply-evaluating dynamically-
computed keys.

Review by: philip
           breser

* build/ac-macros/svn-macros.m4
  (SVN_CHECK_FOR_DUNDER_BUILTINS): New macro.

* configure.ac:
    Call SVN_CHECK_FOR_DUNDER_BUILTINS() and set -D SVN_HAS_DUNDER_BUILTINS.

* subversion/include/svn_hash.h
  (svn_hash_gets): Use __builtin_choose_expr() and __builtin_constant_p(),
    when available.

Modified:
    subversion/trunk/build/ac-macros/svn-macros.m4
    subversion/trunk/configure.ac
    subversion/trunk/subversion/include/svn_hash.h

Modified: subversion/trunk/build/ac-macros/svn-macros.m4
URL: 
http://svn.apache.org/viewvc/subversion/trunk/build/ac-macros/svn-macros.m4?rev=1508170&r1=1508169&r2=1508170&view=diff
==============================================================================
--- subversion/trunk/build/ac-macros/svn-macros.m4 (original)
+++ subversion/trunk/build/ac-macros/svn-macros.m4 Mon Jul 29 18:35:25 2013
@@ -163,3 +163,26 @@ AC_DEFUN([SVN_CHECK_FOR_ATOMIC_BUILTINS]
       return 0;
   }], [svn_cv_atomic_builtins=yes], [svn_cv_atomic_builtins=no], 
[svn_cv_atomic_builtins=no])])
 ])
+
+AC_DEFUN([SVN_CHECK_FOR_DUNDER_BUILTINS],
+[
+  AC_CACHE_CHECK([whether the compiler provides dunder builtins], 
[svn_cv_dunder_builtins],
+  [
+    AC_RUN_IFELSE([AC_LANG_SOURCE([[
+      int main(int argc)
+      {
+        return (!__builtin_choose_expr(__builtin_constant_p(argc), 1, 0)
+                && __builtin_choose_expr(__builtin_constant_p("foobar"), 1, 0))
+               ? 0 /* EXIT_SUCCESS */ : 1 /* EXIT_FAILURE */;
+      }]])],
+      svn_cv_dunder_builtins="yes",
+      svn_cv_dunder_builtins="no",
+      [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+        int main(void){
+         return __builtin_choose_expr(__builtin_constant_p("foobar"), 0, 1);
+        }]])],
+        svn_cv_dunder_builtins="yes",
+        svn_cv_dunder_builtins="no")
+      ])
+  ])
+])

Modified: subversion/trunk/configure.ac
URL: 
http://svn.apache.org/viewvc/subversion/trunk/configure.ac?rev=1508170&r1=1508169&r2=1508170&view=diff
==============================================================================
--- subversion/trunk/configure.ac (original)
+++ subversion/trunk/configure.ac Mon Jul 29 18:35:25 2013
@@ -167,11 +167,15 @@ if test -n "$sqlite_compat_ver" && test 
 fi
 
 SVN_CHECK_FOR_ATOMIC_BUILTINS
-
 if test "$svn_cv_atomic_builtins" = "yes"; then
     AC_DEFINE(SVN_HAS_ATOMIC_BUILTINS, 1, [Define if compiler provides atomic 
builtins])
 fi
 
+SVN_CHECK_FOR_DUNDER_BUILTINS
+if test "$svn_cv_dunder_builtins" = "yes"; then
+    AC_DEFINE(SVN_HAS_DUNDER_BUILTINS, 1, [Define if compiler provides 
__builtin_constant_p and __builtin_choose_expr])
+fi
+
 dnl Set up a number of directories ---------------------
 
 dnl Create SVN_BINDIR for proper substitution

Modified: subversion/trunk/subversion/include/svn_hash.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_hash.h?rev=1508170&r1=1508169&r2=1508170&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_hash.h (original)
+++ subversion/trunk/subversion/include/svn_hash.h Mon Jul 29 18:35:25 2013
@@ -244,8 +244,25 @@ svn_hash_from_cstring_keys(apr_hash_t **
  *
  * @since New in 1.8.
  */
-#define svn_hash_gets(ht, key) \
+#if SVN_HAS_DUNDER_BUILTINS
+/* We have two use-cases:
+   1. (common) KEY is a string literal.
+   2. (rare) KEY is the result of an expensive function call.
+   For the former, we want to evaluate the string length at compile time.  (We
+   use strlen(), which gets optimized to a constant.)  For the latter, however,
+   we want to avoid having the macro multiply-evaluate KEY.  So, if our
+   compiler is smart enough (that includes at least gcc and clang), we use
+   __builtin_constant_p() to have our cake and eat it too: */
+#  define svn_hash_gets(ht, key) \
+            apr_hash_get(ht, key, \
+                         __builtin_constant_p(strlen(key)) \
+                         ? strlen(key) : APR_HASH_KEY_STRING)
+#else
+/* ... and when our compiler is anything else, we take the hit and compute the
+   length of string literals at run-time. */
+#  define svn_hash_gets(ht, key) \
             apr_hash_get(ht, key, APR_HASH_KEY_STRING)
+#endif
 
 /** Shortcut for apr_hash_set() with a const char * key.
  *


Reply via email to