hwint.cc reflect_hwi uses a naive for loop approach to
emulate __builtin_bitreverse64 ().
This is slow compared to using __builtin_bitreverse64 () plus bitshift.
This is useful for bootstrapping GCC since r17-523.
Also add assert on BITWIDTH <= 64.

For reflect_hwi and ira-color.cc, add STAGE0_CXX_HAS_BUILTIN
in system.h to test for specific builtins.

Bootstrapped and regtested on x86_64-pc-linux-gnu.

        PR middle-end/126625

gcc/ChangeLog:

        * hwint.cc (reflect_hwi): Use STAGE0_CXX_HAS_BUILTIN
        for __builtin_bitreverse64.
        * ira-color.cc (HAS_SMUL_OVERFLOW): Remove
        and use STAGE0_CXX_HAS_BUILTIN instead.
        * system.h (STAGE0_CXX_HAS_BUILTIN): New macro.

Signed-off-by: Kael Andrew Franco <[email protected]>
---
 gcc/hwint.cc     | 13 ++++++++++++-
 gcc/ira-color.cc |  7 +------
 gcc/system.h     |  8 ++++++++
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/gcc/hwint.cc b/gcc/hwint.cc
index f3b3e7b8408..da7bc05f085 100644
--- a/gcc/hwint.cc
+++ b/gcc/hwint.cc
@@ -189,12 +189,21 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
   return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
 }
 
-/* Reflect (reverse) the bits of a given VALUE within a specified BITWIDTH.  */
+/* Reflect (reverse) the bits of a given VALUE within a specified BITWIDTH <= 
64.  */
 
 unsigned HOST_WIDE_INT
 reflect_hwi (unsigned HOST_WIDE_INT value, unsigned bitwidth)
 {
+  if (bitwidth == 0)
+    return 0;
+
+  gcc_checking_assert (bitwidth <= 64);
+
+#if STAGE0_CXX_HAS_BUILTIN (bitreverse64)
+  return __builtin_bitreverse64 (value) >> (64 - bitwidth);
+#else
   unsigned HOST_WIDE_INT reflected_value = 0;
+
   /* Loop through each bit in the specified BITWIDTH.  */
   for (size_t i = 0; i < bitwidth; i++)
     {
@@ -204,5 +213,7 @@ reflect_hwi (unsigned HOST_WIDE_INT value, unsigned 
bitwidth)
       reflected_value |= (value & 1);
       value >>= 1;
     }
+
   return reflected_value;
+#endif
 }
diff --git a/gcc/ira-color.cc b/gcc/ira-color.cc
index 2b389b5aab1..866d5b6bec3 100644
--- a/gcc/ira-color.cc
+++ b/gcc/ira-color.cc
@@ -3154,14 +3154,9 @@ setup_allocno_priorities (ira_allocno_t 
*consideration_allocnos, int n)
       ira_assert (mult >= 0);
       mult *= ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)];
       diff = ALLOCNO_MEMORY_COST (a) - ALLOCNO_CLASS_COST (a);
-#ifdef __has_builtin
-#if __has_builtin(__builtin_smul_overflow)
-#define HAS_SMUL_OVERFLOW
-#endif
-#endif
       /* Multiplication can overflow for very large functions.
         Check the overflow and constrain the result if necessary: */
-#ifdef HAS_SMUL_OVERFLOW
+#if STAGE0_CXX_HAS_BUILTIN (smul_overflow)
       if (__builtin_smul_overflow (mult, diff, &priority)
          || priority < -INT_MAX)
        priority = diff >= 0 ? INT_MAX : -INT_MAX;
diff --git a/gcc/system.h b/gcc/system.h
index f0fa062d469..08fefd6f054 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -22,6 +22,14 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_SYSTEM_H
 #define GCC_SYSTEM_H
 
+/* True if __builtin_* () is supported.
+   This is done for optimizing GCC itself.  */
+#ifdef __has_builtin
+# define STAGE0_CXX_HAS_BUILTIN(NAME) __has_builtin (__builtin_ ## NAME)
+#else
+# define STAGE0_CXX_HAS_BUILTIN(NAME) 0
+#endif
+
 /* Define this so that inttypes.h defines the PRI?64 macros even
    when compiling with a C++ compiler.  Define it here so in the
    event inttypes.h gets pulled in by another header it is already
-- 
2.55.0

Reply via email to