diff options
author | Richard Henderson <rth@redhat.com> | 2010-08-05 12:41:31 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2010-08-05 12:41:31 -0700 |
commit | bd95721f862876dac7d1560806b18015bb5bbeb6 (patch) | |
tree | ebb0bcbba694540435097fb9c41ec0f70c57ab41 /gcc/toplev.h | |
parent | 55b324a67cf91568372f4e93c7dae01a572de9f4 (diff) | |
download | gcc-bd95721f862876dac7d1560806b18015bb5bbeb6.tar.gz |
Replace exact_log2(x & -x) in favor of more direct computation.
* toplev.h (ctz_hwi, clz_hwi, ffs_hwi): New.
(floor_log2): Use clz_hwi.
(exact_log2): Use ctz_hwi.
* toplev.c (ctz_hwi, clz_hwi, ffs_hwi): New.
* builtins.c (fold_builtin_bitop): Use them.
* simplify-rtx.c (simplify_const_unary_operation): Likewise.
* combine.c (get_pos_from_mask): Use ctz_hwi.
* double-int.c (double_int_ctz): Likewise.
* explow.c (force_reg): Likewise.
* tree.h (SET_DECL_OFFSET_ALIGN): Use ffs_hwi.
From-SVN: r162920
Diffstat (limited to 'gcc/toplev.h')
-rw-r--r-- | gcc/toplev.h | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/gcc/toplev.h b/gcc/toplev.h index 44920ed7a00..6de27a092bf 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -111,6 +111,10 @@ extern bool fast_math_flags_struct_set_p (struct cl_optimization *); /* Inline versions of the above for speed. */ #if GCC_VERSION < 3004 +extern int clz_hwi (unsigned HOST_WIDE_INT x); +extern int ctz_hwi (unsigned HOST_WIDE_INT x); +extern int ffs_hwi (unsigned HOST_WIDE_INT x); + /* Return log2, or -1 if not exact. */ extern int exact_log2 (unsigned HOST_WIDE_INT); @@ -119,27 +123,57 @@ extern int floor_log2 (unsigned HOST_WIDE_INT); #else /* GCC_VERSION >= 3004 */ +/* For convenience, define 0 -> word_size. */ +static inline int +clz_hwi (unsigned HOST_WIDE_INT x) +{ + if (x == 0) + return HOST_BITS_PER_WIDE_INT; +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + return __builtin_clzl (x); +# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG + return __builtin_clzll (x); +# else + return __builtin_clz (x); +# endif +} + +static inline int +ctz_hwi (unsigned HOST_WIDE_INT x) +{ + if (x == 0) + return HOST_BITS_PER_WIDE_INT; +# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG + return __builtin_ctzl (x); +# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG + return __builtin_ctzll (x); +# else + return __builtin_ctz (x); +# endif +} + +static inline int +ffs_hwi (unsigned HOST_WIDE_INT x) +{ # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG -# define CLZ_HWI __builtin_clzl -# define CTZ_HWI __builtin_ctzl + return __builtin_ffsl (x); # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG -# define CLZ_HWI __builtin_clzll -# define CTZ_HWI __builtin_ctzll + return __builtin_ffsll (x); # else -# define CLZ_HWI __builtin_clz -# define CTZ_HWI __builtin_ctz + return __builtin_ffs (x); # endif +} static inline int floor_log2 (unsigned HOST_WIDE_INT x) { - return x ? HOST_BITS_PER_WIDE_INT - 1 - (int) CLZ_HWI (x) : -1; + return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x); } static inline int exact_log2 (unsigned HOST_WIDE_INT x) { - return x == (x & -x) && x ? (int) CTZ_HWI (x) : -1; + return x == (x & -x) && x ? ctz_hwi (x) : -1; } #endif /* GCC_VERSION >= 3004 */ |