Hi Corinna,

Corinna Vinschen wrote:
On Jul  7 00:41, Mark Geisert wrote:
The current version of <sys/cpuset.h> cannot be compiled by Clang due to
the use of __builtin* functions.  Their presence here was a dubious
optimization anyway, so their usage has been converted to standard
library functions.  A popcnt (population count of 1 bits in a word)
function is provided here because there isn't one in the standard library
or elsewhere in the Cygwin DLL.

And clang really doesn't provide it?  That's unfortunate.

Do you really think it's not worth to use it if it's available?

I don't know for sure. I'd guess the popcnt op should be optimized if available; the others probably don't need it.

You could workaround it like this:

+/* Modern CPUs have popcnt* instructions but the need here is not worth
+ * worrying about builtins or inline assembler for different compilers. */
+static inline int
+__maskpopcnt (__cpu_mask mask)
+{
#if (__GNUC__ >= 4)
      return __builtin_popcountl (mask);
#else
+  int res = 0;
+  unsigned long ulmask = (unsigned long) mask;
+
+  while (ulmask != 0)
+    {
+      if (ulmask & 1)
+        ++res;
+      ulmask >>= 1;
+    }
+  return res;
#endif
+}
+

The first version of the patch (unsubmitted) worked something like that, though it was a chore figuring out how to tell the difference between gcc and clang. clang #defines __GNUC__ (?!) for example. I ended up using __GNUC_PREREQ__ with the hope clang version numbers stay lower than gcc version numbers. Has to be a better way than that.

On the other hand, one compilation with clang or clang++, I forget which, and with some optimization flag, recognized the 'while' loop in that function and turned it into the Hackers Delight algorithm for popcnt in ~20 instructions and no loop.

TL;DR let me ponder this over the weekend.
Thanks for listening,

..mark

Reply via email to