Hello list,
the attached patch was tested on i386, and measured to have almost no
overhead in runtime, when RTL checks are enabled:
Instruction Count before: 2328.6 M
Instruction Count after: 2334.4 M
which translates to some milliseconds, well within noise area.
Changelog:
2011-07-25 Dimitrios Apostolou <ji...@gmx.net>
* hard-reg-set.h (TEST_HARD_REG_BIT, SET_HARD_REG_BIT,
CLEAR_HARD_REG_BIT): Added some assert checks for test, set and clear
operations of HARD_REG_SETs, enabled when RTL checks are on. Runtime
overhead was measured as negligible.
Thanks,
Dimitris
=== modified file 'gcc/hard-reg-set.h'
--- gcc/hard-reg-set.h 2011-01-03 20:52:22 +0000
+++ gcc/hard-reg-set.h 2011-07-25 17:06:36 +0000
@@ -41,6 +41,13 @@ along with GCC; see the file COPYING3.
typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;
+#ifdef ENABLE_RTL_CHECKING
+#define gcc_rtl_assert(EXPR) gcc_assert (EXPR)
+#else
+#define gcc_rtl_assert(EXPR) ((void)(0 && (EXPR)))
+#endif
+
+
#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT
#define HARD_REG_SET HARD_REG_ELT_TYPE
@@ -91,14 +98,35 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[H
#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
-#ifdef HARD_REG_SET
-
#define SET_HARD_REG_BIT(SET, BIT) \
- ((SET) |= HARD_CONST (1) << (BIT))
+ hard_reg_set_set_bit (&(SET), (BIT))
#define CLEAR_HARD_REG_BIT(SET, BIT) \
- ((SET) &= ~(HARD_CONST (1) << (BIT)))
+ hard_reg_set_clear_bit(&(SET), (BIT))
#define TEST_HARD_REG_BIT(SET, BIT) \
- (!!((SET) & (HARD_CONST (1) << (BIT))))
+ hard_reg_set_bit_p((SET), (BIT))
+
+#ifdef HARD_REG_SET
+
+static inline void
+hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit)
+{
+ gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);
+ (*s) |= HARD_CONST (1) << bit;
+}
+
+static inline void
+hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit)
+{
+ gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);
+ (*s) &= ~(HARD_CONST (1) << bit);
+}
+
+static inline bool
+hard_reg_set_bit_p (const HARD_REG_SET s, unsigned int bit)
+{
+ gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);
+ return ((s >> bit) & HARD_CONST (1));
+}
#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
@@ -137,17 +165,32 @@ hard_reg_set_empty_p (const HARD_REG_SET
#else
-#define SET_HARD_REG_BIT(SET, BIT) \
- ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
- |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))
-
-#define CLEAR_HARD_REG_BIT(SET, BIT) \
- ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
- &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))
-
-#define TEST_HARD_REG_BIT(SET, BIT) \
- (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \
- & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))
+static inline void
+hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit)
+{
+ int byte = bit / UHOST_BITS_PER_WIDE_INT;
+ int bitpos = bit % UHOST_BITS_PER_WIDE_INT;
+ gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);
+ (*s)[byte] |= HARD_CONST (1) << bitpos;
+}
+
+static inline void
+hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit)
+{
+ int byte = bit / UHOST_BITS_PER_WIDE_INT;
+ int bitpos = bit % UHOST_BITS_PER_WIDE_INT;
+ gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);
+ (*s)[byte] &= ~(HARD_CONST (1) << bitpos);
+}
+
+static inline bool
+hard_reg_set_bit_p (const HARD_REG_SET s, unsigned int bit)
+{
+ int byte = bit / UHOST_BITS_PER_WIDE_INT;
+ int bitpos = bit % UHOST_BITS_PER_WIDE_INT;
+ gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);
+ return ((s[byte] >> bitpos) & HARD_CONST (1));
+}
#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
#define CLEAR_HARD_REG_SET(TO) \