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