[PATCH] log2: make is_power_of_2() integer constant expression when possible

From: Jani Nikula
Date: Fri Mar 01 2019 - 07:50:26 EST


While is_power_of_2() is an inline function and likely gets optimized
for compile time constant arguments, it still doesn't produce an integer
constant expression that could be used in, say, static data
initialization or case labels.

Make is_power_of_2() an integer constant expression when possible,
otherwise using the inline function to avoid multiple evaluation of the
parameter.

Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx>

---

The alternative would be to define both a function and a macro version
of is_power_of_2(), and let the callers decide what to use.
---
include/linux/log2.h | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/include/linux/log2.h b/include/linux/log2.h
index 2af7f77866d0..035932f52aeb 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -37,6 +37,14 @@ int __ilog2_u64(u64 n)
}
#endif

+#define __IS_POWER_OF_2(__n) ((__n) != 0 && (((__n) & ((__n) - 1)) == 0))
+
+static inline __attribute__((const))
+bool __is_power_of_2(unsigned long n)
+{
+ return __IS_POWER_OF_2(n);
+}
+
/**
* is_power_of_2() - check if a value is a power of two
* @n: the value to check
@@ -45,11 +53,8 @@ int __ilog2_u64(u64 n)
* *not* considered a power of two.
* Return: true if @n is a power of 2, otherwise false.
*/
-static inline __attribute__((const))
-bool is_power_of_2(unsigned long n)
-{
- return (n != 0 && ((n & (n - 1)) == 0));
-}
+#define is_power_of_2(n) \
+ __builtin_choose_expr(__builtin_constant_p(n), __IS_POWER_OF_2(n), __is_power_of_2(n))

/**
* __roundup_pow_of_two() - round up to nearest power of two
--
2.20.1