Hello list, the attached patch changes hard-reg-set.h in the following areas:
1) HARD_REG_SET is now always a struct so that it can be used in files where we don't want to include tm.h. Many thanks to Paolo for providing the idea and the original patch.
2) Code for specific HARD_REG_SET_LONG values is deleted and only generic code is left, making the file much more readable/maintainable. I was expecting gcc would unroll, even at -O2, loops with 2-3 iterations, so performance should have been the same.
I don't intend for this to go mainline, Jakub has explained on IRC that certain ABIs make it slower to pass structs and we wouldn't want that. Nevertheless I'd appreciate comments on whether any part of this patch is worth keeping. FWIW I've profiled this on i386 to be about 4 M instr slower out of ~1.5 G inst. I'll be now checking the profiler to see where exactly the overhead is.
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-29 22:32:27 +0000 @@ -24,35 +24,31 @@ along with GCC; see the file COPYING3. /* Define the type of a set of hard registers. */ /* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which - will be used for hard reg sets, either alone or in an array. - - If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE, - and it has enough bits to represent all the target machine's hard - registers. Otherwise, it is a typedef for a suitably sized array - of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many. + will be used for hard reg sets. An HARD_REG_ELT_TYPE, or an + array of them is wrapped in a struct. Note that lots of code assumes that the first part of a regset is the same format as a HARD_REG_SET. To help make sure this is true, we only try the widest fast integer mode (HOST_WIDEST_FAST_INT) - instead of all the smaller types. This approach loses only if - there are very few registers and then only in the few cases where - we have an array of HARD_REG_SETs, so it needn't be as complex as - it used to be. */ - -typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE; - -#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT - -#define HARD_REG_SET HARD_REG_ELT_TYPE + instead of all the smaller types. */ +#ifdef ENABLE_RTL_CHECKING +#define gcc_rtl_assert(EXPR) gcc_assert (EXPR) #else +#define gcc_rtl_assert(EXPR) ((void)(0 && (EXPR))) +#endif + +typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE; #define HARD_REG_SET_LONGS \ ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1) \ / HOST_BITS_PER_WIDEST_FAST_INT) -typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; -#endif +#define HARD_REG_SET struct hard_reg_set + +struct hard_reg_set { + HARD_REG_ELT_TYPE elems[HARD_REG_SET_LONGS]; +}; /* HARD_CONST is used to cast a constant to the appropriate type for use with a HARD_REG_SET. */ @@ -89,343 +85,108 @@ typedef HARD_REG_ELT_TYPE HARD_REG_SET[H hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect. hard_reg_set_empty_p (X), which returns true if X is empty. */ -#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) -#ifdef HARD_REG_SET +#define HARD_REG_ELT_BITS ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) #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)))) - -#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) -#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) - -#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM)) -#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) - -#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) -#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) -#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) -#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x & ~y) == HARD_CONST (0); -} + hard_reg_set_bit_p((SET), (BIT)) -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x == y; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x & y) != HARD_CONST (0); -} - -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +static inline void +hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit) { - return x == HARD_CONST (0); -} - +#if HARD_REG_SET_LONGS > 1 + int word = bit / HARD_REG_ELT_BITS; + int bitpos = bit % HARD_REG_ELT_BITS; #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)))) - -#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0; -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x[0] == y[0] && x[1] == y[1]; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0; + int word = 0; + int bitpos = bit; +#endif + gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER); + (s->elems)[word] |= HARD_CONST (1) << bitpos; } -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +static inline void +hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit) { - return x[0] == 0 && x[1] == 0; -} - +#if HARD_REG_SET_LONGS > 1 + int word = bit / HARD_REG_ELT_BITS; + int bitpos = bit % HARD_REG_ELT_BITS; #else -#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; \ - scan_tp_[2] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; \ - scan_tp_[2] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; \ - scan_tp_[2] = scan_fp_[2]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; \ - scan_tp_[2] = ~ scan_fp_[2]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; \ - scan_tp_[2] &= scan_fp_[2]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; \ - scan_tp_[2] &= ~ scan_fp_[2]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; \ - scan_tp_[2] |= scan_fp_[2]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; \ - scan_tp_[2] |= ~ scan_fp_[2]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & ~y[0]) == 0 - && (x[1] & ~y[1]) == 0 - && (x[2] & ~y[2]) == 0); -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x[0] == y[0] && x[1] == y[1] && x[2] == y[2]; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & y[0]) != 0 - || (x[1] & y[1]) != 0 - || (x[2] & y[2]) != 0); + int word = 0; + int bitpos = bit; +#endif + gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER); + (s->elems)[word] &= ~(HARD_CONST (1) << bitpos); } static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) +hard_reg_set_bit_p (const HARD_REG_SET s, unsigned int bit) { - return x[0] == 0 && x[1] == 0 && x[2] == 0; -} - +#if HARD_REG_SET_LONGS > 1 + int word = bit / HARD_REG_ELT_BITS; + int bitpos = bit % HARD_REG_ELT_BITS; #else -#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT -#define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = 0; \ - scan_tp_[1] = 0; \ - scan_tp_[2] = 0; \ - scan_tp_[3] = 0; } while (0) - -#define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ - scan_tp_[0] = -1; \ - scan_tp_[1] = -1; \ - scan_tp_[2] = -1; \ - scan_tp_[3] = -1; } while (0) - -#define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = scan_fp_[0]; \ - scan_tp_[1] = scan_fp_[1]; \ - scan_tp_[2] = scan_fp_[2]; \ - scan_tp_[3] = scan_fp_[3]; } while (0) - -#define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] = ~ scan_fp_[0]; \ - scan_tp_[1] = ~ scan_fp_[1]; \ - scan_tp_[2] = ~ scan_fp_[2]; \ - scan_tp_[3] = ~ scan_fp_[3]; } while (0) - -#define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= scan_fp_[0]; \ - scan_tp_[1] &= scan_fp_[1]; \ - scan_tp_[2] &= scan_fp_[2]; \ - scan_tp_[3] &= scan_fp_[3]; } while (0) - -#define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] &= ~ scan_fp_[0]; \ - scan_tp_[1] &= ~ scan_fp_[1]; \ - scan_tp_[2] &= ~ scan_fp_[2]; \ - scan_tp_[3] &= ~ scan_fp_[3]; } while (0) - -#define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= scan_fp_[0]; \ - scan_tp_[1] |= scan_fp_[1]; \ - scan_tp_[2] |= scan_fp_[2]; \ - scan_tp_[3] |= scan_fp_[3]; } while (0) - -#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ - scan_tp_[0] |= ~ scan_fp_[0]; \ - scan_tp_[1] |= ~ scan_fp_[1]; \ - scan_tp_[2] |= ~ scan_fp_[2]; \ - scan_tp_[3] |= ~ scan_fp_[3]; } while (0) - -static inline bool -hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & ~y[0]) == 0 - && (x[1] & ~y[1]) == 0 - && (x[2] & ~y[2]) == 0 - && (x[3] & ~y[3]) == 0); -} - -static inline bool -hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3]; -} - -static inline bool -hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y) -{ - return ((x[0] & y[0]) != 0 - || (x[1] & y[1]) != 0 - || (x[2] & y[2]) != 0 - || (x[3] & y[3]) != 0); -} - -static inline bool -hard_reg_set_empty_p (const HARD_REG_SET x) -{ - return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0; + int word = 0; + int bitpos = bit; +#endif + gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER); + return ((s.elems[word] >> bitpos) & HARD_CONST (1)); } -#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */ - #define CLEAR_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = 0; } while (0) #define SET_HARD_REG_SET(TO) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = -1; } while (0) #define COPY_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = *scan_fp_++; } while (0) #define COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ = ~ *scan_fp_++; } while (0) #define AND_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ &= *scan_fp_++; } while (0) #define AND_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ &= ~ *scan_fp_++; } while (0) #define IOR_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ |= *scan_fp_++; } while (0) #define IOR_COMPL_HARD_REG_SET(TO, FROM) \ -do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ +do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems; \ + HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems; \ int i; \ for (i = 0; i < HARD_REG_SET_LONGS; i++) \ *scan_tp_++ |= ~ *scan_fp_++; } while (0) @@ -436,7 +197,7 @@ hard_reg_set_subset_p (const HARD_REG_SE int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((x[i] & ~y[i]) != 0) + if ((x.elems[i] & ~y.elems[i]) != 0) return false; return true; } @@ -447,7 +208,7 @@ hard_reg_set_equal_p (const HARD_REG_SET int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if (x[i] != y[i]) + if (x.elems[i] != y.elems[i]) return false; return true; } @@ -458,7 +219,7 @@ hard_reg_set_intersect_p (const HARD_REG int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if ((x[i] & y[i]) != 0) + if ((x.elems[i] & y.elems[i]) != 0) return true; return false; } @@ -469,15 +230,11 @@ hard_reg_set_empty_p (const HARD_REG_SET int i; for (i = 0; i < HARD_REG_SET_LONGS; i++) - if (x[i] != 0) + if (x.elems[i] != 0) return false; return true; } -#endif -#endif -#endif -#endif /* Iterator for hard register sets. */ @@ -486,9 +243,6 @@ typedef struct /* Pointer to the current element. */ HARD_REG_ELT_TYPE *pelt; - /* The length of the set. */ - unsigned short length; - /* Word within the current element. */ unsigned short word_no; @@ -498,30 +252,26 @@ typedef struct HARD_REG_ELT_TYPE bits; } hard_reg_set_iterator; -#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT - /* The implementation of the iterator functions is fully analogous to the bitmap iterators. */ static inline void hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set, unsigned min, unsigned *regno) { -#ifdef HARD_REG_SET_LONGS - iter->pelt = set; - iter->length = HARD_REG_SET_LONGS; + gcc_rtl_assert (min < FIRST_PSEUDO_REGISTER); +#if HARD_REG_SET_LONGS > 1 + iter->word_no = min / HARD_REG_ELT_BITS; #else - iter->pelt = &set; - iter->length = 1; + iter->word_no = 0; #endif - iter->word_no = min / HARD_REG_ELT_BITS; - if (iter->word_no < iter->length) - { - iter->bits = iter->pelt[iter->word_no]; - iter->bits >>= min % HARD_REG_ELT_BITS; + iter->pelt = set.elems; + + iter->bits = iter->pelt[iter->word_no]; + iter->bits >>= min % HARD_REG_ELT_BITS; + + /* This is required for correct search of the next bit. */ + min += !iter->bits; - /* This is required for correct search of the next bit. */ - min += !iter->bits; - } *regno = min; } @@ -531,7 +281,7 @@ hard_reg_set_iter_set (hard_reg_set_iter while (1) { /* Return false when we're advanced past the end of the set. */ - if (iter->word_no >= iter->length) + if (iter->word_no >= HARD_REG_SET_LONGS) return false; if (iter->bits) @@ -550,7 +300,7 @@ hard_reg_set_iter_set (hard_reg_set_iter *regno -= *regno % HARD_REG_ELT_BITS; /* Find the next non-zero word. */ - while (++iter->word_no < iter->length) + while (++iter->word_no < HARD_REG_SET_LONGS) { iter->bits = iter->pelt[iter->word_no]; if (iter->bits)