[PATCH 1/2] middle-end: If supported, use __builtin_*. [PR126625]

Kael Andrew Alonzo Franco <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.