From: Chandler Carruth Date: Mon, 16 Feb 2015 09:59:48 +0000 (+0000) Subject: [x86] Switch my usage of VariadicFunction to a "normal" variadic X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8b1a5559e93b66785e75da44f62fc8c16219659c;p=oota-llvm.git [x86] Switch my usage of VariadicFunction to a "normal" variadic 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 --- diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 14fc3345125..5c4f0632583 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -7361,37 +7361,33 @@ is128BitLaneRepeatedShuffleMask(MVT VT, ArrayRef Mask, 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 Mask, - ArrayRef 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(V1); - auto *BV2 = dyn_cast(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 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; } -} // namespace +/// \brief Recursive helper to peel off and test each mask element. +template +static bool isShuffleEquivalentImpl(SDValue V1, SDValue V2, + BuildVectorSDNode *BV1, + BuildVectorSDNode *BV2, ArrayRef 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. @@ -7403,9 +7399,20 @@ bool isShuffleEquivalentImpl(SDValue V1, SDValue V2, ArrayRef 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. -static const VariadicFunction3, int, - isShuffleEquivalentImpl> isShuffleEquivalent = - {}; +template +static bool isShuffleEquivalent(SDValue V1, SDValue V2, ArrayRef 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(V1); + auto *BV2 = dyn_cast(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. ///