[PATCH] D48147: Add comment to scatter-bit operation, make it faster and rename it.

Rui Ueyama via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 13 13:04:40 PDT 2018


ruiu created this revision.
ruiu added a reviewer: sidneym.
Herald added subscribers: arichardson, emaste.
Herald added a reviewer: espindola.

Also swap the parameter position to make it consistent with
__builtin_ia32_pdep_si.


https://reviews.llvm.org/D48147

Files:
  lld/ELF/Arch/Hexagon.cpp


Index: lld/ELF/Arch/Hexagon.cpp
===================================================================
--- lld/ELF/Arch/Hexagon.cpp
+++ lld/ELF/Arch/Hexagon.cpp
@@ -35,19 +35,27 @@
 // Support V60 only at the moment.
 uint32_t Hexagon::calcEFlags() const { return 0x60; }
 
-static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
-  uint32_t Result = 0;
-  size_t Off = 0;
+// This function scatter Val's bits as instructed by Mask.
+// Here is an example:
+//
+//  Val:    abcd efgh ijkl mnop
+//  Mask:   1110 0001 1111 0001
+//  Result: hij0 000k lmno 000p
+//
+// Some CPUs support this operation as a single instruction.
+// For exapmle, Intel BMI2 extension has this operation as PDEP.
+static inline uint32_t scatter(uint32_t Val, uint32_t Mask) {
+  uint32_t Res = 0;
+  uint32_t Off = 0;
 
-  for (size_t Bit = 0; Bit != 32; ++Bit) {
-    uint32_t ValBit = (Data >> Off) & 1;
-    uint32_t MaskBit = (Mask >> Bit) & 1;
-    if (MaskBit) {
-      Result |= (ValBit << Bit);
-      ++Off;
-    }
-  }
-  return Result;
+  // We want to take the advantage of the fact that Mask is a constant.
+  // Without "#pragma unroll", clang emits a loop that always iterates
+  // 32 times, which is much more expensive than branchless code.
+#pragma unroll
+  for (uint32_t I = 0; I < 32; ++I)
+    if (Mask & (1 << I))
+      Res |= !!(Val & (1 << Off++)) << I;
+  return Res;
 }
 
 RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
@@ -67,7 +75,7 @@
   case R_HEX_NONE:
     break;
   case R_HEX_B22_PCREL:
-    or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
+    or32le(Loc, scatter(Val >> 2, 0x1ff3ffe));
     break;
   default:
     error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48147.151234.patch
Type: text/x-patch
Size: 1713 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180613/79c7a9dd/attachment.bin>


More information about the llvm-commits mailing list