From bd95721f862876dac7d1560806b18015bb5bbeb6 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 5 Aug 2010 12:41:31 -0700 Subject: 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 --- gcc/toplev.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'gcc/toplev.c') diff --git a/gcc/toplev.c b/gcc/toplev.c index 3836d0c..ff82466 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -484,9 +484,9 @@ set_random_seed (const char *val) #if GCC_VERSION < 3004 -/* The functions floor_log2 and exact_log2 are defined as inline - functions in toplev.h if GCC_VERSION >= 3004. The definitions here - are used for older versions of gcc. */ +/* The functions clz_hwi, ctz_hwi, ffs_hwi, floor_log2 and exact_log2 + are defined as inline functions in toplev.h if GCC_VERSION >= 3004. + The definitions here are used for older versions of gcc. */ /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. If X is 0, return -1. */ @@ -530,6 +530,32 @@ exact_log2 (unsigned HOST_WIDE_INT x) return floor_log2 (x); } +/* Given X, an unsigned number, return the number of least significant bits + that are zero. When X == 0, the result is the word size. */ + +int +ctz_hwi (unsigned HOST_WIDE_INT x) +{ + return x ? floor_log2 (x & -x) : HOST_BITS_PER_WIDE_INT; +} + +/* Similarly for most significant bits. */ + +int +clz_hwi (unsigned HOST_WIDE_INT x) +{ + return HOST_BITS_PER_WIDE_INT - 1 - floor_log2(x); +} + +/* Similar to ctz_hwi, except that the least significant bit is numbered + starting from 1, and X == 0 yields 0. */ + +int +ffs_hwi (unsigned HOST_WIDE_INT x) +{ + return 1 + floor_log2 (x & -x); +} + #endif /* GCC_VERSION < 3004 */ /* Handler for fatal signals, such as SIGSEGV. These are transformed -- cgit v1.1