[x86] Switch my usage of VariadicFunction to a "normal" variadic
authorChandler Carruth <chandlerc@gmail.com>
Mon, 16 Feb 2015 09:59:48 +0000 (09:59 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Mon, 16 Feb 2015 09:59:48 +0000 (09:59 +0000)
template now that we can use them.

This is, of course, horribly ugly because of the required recursive
formulation. Suggestions for making it less ugly welcome.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229367 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp

index 14fc3345125235ceeeeb966a7a09b288cea27e71..5c4f06325839fe7e1b69798ddab2fca1cae80567 100644 (file)
@@ -7361,37 +7361,33 @@ is128BitLaneRepeatedShuffleMask(MVT VT, ArrayRef<int> Mask,
   return true;
 }
 
   return true;
 }
 
-// Hide this symbol with an anonymous namespace instead of 'static' so that MSVC
-// 2013 will allow us to use it as a non-type template parameter.
-namespace {
-
-/// \brief Implementation of the \c isShuffleEquivalent variadic functor.
-///
-/// See its documentation for details.
-bool isShuffleEquivalentImpl(SDValue V1, SDValue V2, ArrayRef<int> Mask,
-                             ArrayRef<const int *> Args) {
-  if (Mask.size() != Args.size())
-    return false;
-
-  // If the values are build vectors, we can look through them to find
-  // equivalent inputs that make the shuffles equivalent.
-  auto *BV1 = dyn_cast<BuildVectorSDNode>(V1);
-  auto *BV2 = dyn_cast<BuildVectorSDNode>(V2);
-
-  for (int i = 0, e = Mask.size(); i < e; ++i) {
-    assert(*Args[i] >= 0 && "Arguments must be positive integers!");
-    if (Mask[i] != -1 && Mask[i] != *Args[i]) {
-      auto *MaskBV = Mask[i] < e ? BV1 : BV2;
-      auto *ArgsBV = *Args[i] < e ? BV1 : BV2;
-      if (!MaskBV || !ArgsBV ||
-          MaskBV->getOperand(Mask[i] % e) != ArgsBV->getOperand(*Args[i] % e))
-        return false;
-    }
+/// \brief Base case helper for testing a single mask element.
+static bool isShuffleEquivalentImpl(SDValue V1, SDValue V2,
+                                    BuildVectorSDNode *BV1,
+                                    BuildVectorSDNode *BV2, ArrayRef<int> Mask,
+                                    int i, int Arg) {
+  int Size = Mask.size();
+  if (Mask[i] != -1 && Mask[i] != Arg) {
+    auto *MaskBV = Mask[i] < Size ? BV1 : BV2;
+    auto *ArgsBV = Arg < Size ? BV1 : BV2;
+    if (!MaskBV || !ArgsBV ||
+        MaskBV->getOperand(Mask[i] % Size) != ArgsBV->getOperand(Arg % Size))
+      return false;
   }
   return true;
 }
 
   }
   return true;
 }
 
-} // namespace
+/// \brief Recursive helper to peel off and test each mask element.
+template <typename... Ts>
+static bool isShuffleEquivalentImpl(SDValue V1, SDValue V2,
+                                    BuildVectorSDNode *BV1,
+                                    BuildVectorSDNode *BV2, ArrayRef<int> Mask,
+                                    int i, int Arg, Ts... Args) {
+  if (!isShuffleEquivalentImpl(V1, V2, BV1, BV2, Mask, i, Arg))
+    return false;
+
+  return isShuffleEquivalentImpl(V1, V2, BV1, BV2, Mask, i + 1, Args...);
+}
 
 /// \brief Checks whether a shuffle mask is equivalent to an explicit list of
 /// arguments.
 
 /// \brief Checks whether a shuffle mask is equivalent to an explicit list of
 /// arguments.
@@ -7403,9 +7399,20 @@ bool isShuffleEquivalentImpl(SDValue V1, SDValue V2, ArrayRef<int> Mask,
 /// It returns true if the mask is exactly as wide as the argument list, and
 /// each element of the mask is either -1 (signifying undef) or the value given
 /// in the argument.
 /// It returns true if the mask is exactly as wide as the argument list, and
 /// each element of the mask is either -1 (signifying undef) or the value given
 /// in the argument.
-static const VariadicFunction3<bool, SDValue, SDValue, ArrayRef<int>, int,
-                               isShuffleEquivalentImpl> isShuffleEquivalent =
-    {};
+template <typename... Ts>
+static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef<int> Mask,
+                                Ts... Args) {
+  if (Mask.size() != sizeof...(Args))
+    return false;
+
+  // If the values are build vectors, we can look through them to find
+  // equivalent inputs that make the shuffles equivalent.
+  auto *BV1 = dyn_cast<BuildVectorSDNode>(V1);
+  auto *BV2 = dyn_cast<BuildVectorSDNode>(V2);
+
+  // Recursively peel off arguments and test them against the mask.
+  return isShuffleEquivalentImpl(V1, V2, BV1, BV2, Mask, 0, Args...);
+}
 
 /// \brief Get a 4-lane 8-bit shuffle immediate for a mask.
 ///
 
 /// \brief Get a 4-lane 8-bit shuffle immediate for a mask.
 ///