On Mon, Sep 13, 2021 at 1:50 PM Nick Desaulniers ndesaulniers@google.com wrote:
On Mon, Sep 13, 2021 at 1:42 PM Linus Torvalds torvalds@linux-foundation.org wrote:
On Mon, Sep 13, 2021 at 1:16 PM Nick Desaulniers ndesaulniers@google.com wrote:
Do we have access to _Generic in GCC 4.9?
We've ended up using it unconditionally since last year, so yes.
Sorry, grepping would have taken < 1s. I'm very lazy. http://threevirtues.com/
In fact, the compiler version tests got removed when we raised the gcc version requirement to 4.9 in commit 6ec4476ac825 ("Raise gcc version requirement to 4.9"):
"In particular, raising the minimum to 4.9 means that we can now just assume _Generic() exists, which is likely the much better replacement for a lot of very convoluted built-time magic with conditionals on sizeof and/or __builtin_choose_expr() with same_type() etc"
but we haven't used it much since.
The "seqprop" code for picking the right lock for seqlock is perhaps the main example, and staring at that code will make you go blind, so look away.
Looking at my patch: https://lore.kernel.org/stable/20210913203201.1844253-1-ndesaulniers@google.... I don't think _Generic helps us in the case of dispatching based on the result of is_signed_type() (the operands could undergo type promotion, so we'd need lots of cases that are more concisely covered by is_signed_type()). It could replace the nested checks in div_64 with nested _Generics, I think. Not sure it's a huge win for readability. Maybe cut the number of expansions of the parameters in half though. Let me give it a try just to see what it looks like.
Is this more readable? Same line count. I'm not sure if there's such a thing as "fallthrough" between the "cases" of _Generic to minimize duplication, or whether this could be factored further. Needs lots more () around macro param use and tab'ed out line endings...
diff --git a/include/linux/math64.h b/include/linux/math64.h index 8652a8a35d70..8fc4d56a45b9 100644 --- a/include/linux/math64.h +++ b/include/linux/math64.h @@ -162,17 +162,17 @@ static inline s64 div_s64(s64 dividend, s32 divisor) div_u64(dividend, divisor)); \ })
-#define __div_64(dividend) _Generic((divisor), \ - s64: div64_x64, \ - u64: div64_x64, \ - default: div_x64) +#define __div_64(dividend, divisor) _Generic((divisor), \ + s64: div64_x64(dividend, divisor), \ + u64: div64_x64(dividend, divisor), \ + default: div_x64(dividend, divisor))
#define div_64(dividend, divisor) ({ \ BUILD_BUG_ON_MSG(sizeof(dividend) > sizeof(u64), \ "128b div unsupported"); \ _Generic((dividend), \ - s64: __div_64(dividend)(dividend, divisor), \ - u64: __div_64(dividend)(dividend, divisor), \ + s64: __div_64(dividend, divisor), \ + u64: __div_64(dividend, divisor), \ default: dividend / divisor); \ })