Hi!

The following patch uses __builtin_is_constant_evaluated for
__constant_string_p and __constant_char_array_p - in constexpr contexts,
all the strings or arrays should be constant, and by doing it this way the
compiler should be able to optimize better the callers of these inline
functions already shortly after early inlining rather than having to wait
until fold builtins pass much later.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-01-19  Jakub Jelinek  <ja...@redhat.com>

        PR libstdc++/86590
        * include/bits/char_traits.h (__constant_string_p,
        __constant_char_array_p): Use __builtin_is_constant_evaluated if
        available.

--- libstdc++-v3/include/bits/char_traits.h.jj  2019-01-07 17:59:25.415908887 
+0100
+++ libstdc++-v3/include/bits/char_traits.h     2019-01-19 09:27:44.036336100 
+0100
@@ -230,9 +230,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     static _GLIBCXX_ALWAYS_INLINE constexpr bool
     __constant_string_p(const _CharT* __s)
     {
+#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+      (void) __s;
+      // In constexpr contexts all strings should be constant.
+      return __builtin_is_constant_evaluated();
+#else
       while (__builtin_constant_p(*__s) && *__s)
        __s++;
       return __builtin_constant_p(*__s);
+#endif
     }
 
   /**
@@ -247,10 +253,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     static _GLIBCXX_ALWAYS_INLINE constexpr bool
     __constant_char_array_p(const _CharT* __a, size_t __n)
     {
+#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+      (void) __a;
+      (void) __n;
+      // In constexpr contexts all character arrays should be constant.
+      return __builtin_is_constant_evaluated();
+#else
       size_t __i = 0;
       while (__builtin_constant_p(__a[__i]) && __i < __n)
        __i++;
       return __i == __n;
+#endif
     }
 #endif
 

        Jakub

Reply via email to