Skip to content

Commit bfa9cb1

Browse files
committed
[Instructions] cache computed shufflevector properties
- Cache computed properties of a shufflevector mask. - Merge several shuffle mask property analyses into a single analysis and introduce ShuffleMaskAttrs. - Compute the properties on shufflevector construction.
1 parent 8eb5baf commit bfa9cb1

File tree

2 files changed

+203
-120
lines changed

2 files changed

+203
-120
lines changed

llvm/include/llvm/IR/Instructions.h

Lines changed: 94 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,76 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
18831883

18841884
constexpr int PoisonMaskElem = -1;
18851885

1886+
/// Attributes of a shufflevector mask.
1887+
struct ShuffleMaskAttrs {
1888+
/// If the shuffle chooses elements from exactly one source vector without
1889+
/// changing the length of that vector.
1890+
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
1891+
/// TODO: Optionally allow length-changing shuffles.
1892+
bool SingleSource : 1;
1893+
1894+
/// If the shuffle chooses elements from exactly one source vector without
1895+
/// lane crossings and does not change the number of elements from its input
1896+
/// vectors.
1897+
/// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
1898+
bool Identity : 1;
1899+
1900+
/// If the shuffle lengthens exactly one source vector with undefs in the
1901+
/// high elements.
1902+
bool IdentityWithPadding : 1;
1903+
1904+
/// If the shuffle extracts the first N elements of exactly one source
1905+
/// vector.
1906+
bool IdentityWithExtract : 1;
1907+
1908+
/// If the shuffle concatenates the two source vectors. This is false if either
1909+
/// input is undefined. In that case, the shuffle is better classified as an
1910+
/// identity with padding operation.
1911+
bool Concat : 1;
1912+
1913+
/// If the shuffle swaps the order of elements from exactly one source vector.
1914+
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
1915+
/// TODO: Optionally allow length-changing shuffles.
1916+
bool Reverse : 1;
1917+
1918+
/// If all elements of the shuffle are the same value as the first element of
1919+
/// exactly one source vector without changing the length of that vector.
1920+
/// Example: shufflevector <4 x n> A, <4 x n> B, <undef,0,undef,0>
1921+
/// TODO: Optionally allow length-changing shuffles.
1922+
/// TODO: Optionally allow splats from other elements.
1923+
bool ZeroEltSplat : 1;
1924+
1925+
/// Return true if this shuffle chooses elements from its source vectors
1926+
/// without lane crossings and all operands have the same number of elements.
1927+
/// In other words, this shuffle is equivalent to a vector select with a
1928+
/// constant condition operand.
1929+
/// Example: shufflevector <4 x n> A, <4 x n> B, <undef,1,6,3>
1930+
/// This returns false if the mask does not choose from both input vectors.
1931+
/// In that case, the shuffle is better classified as an identity shuffle.
1932+
/// TODO: Optionally allow length-changing shuffles.
1933+
bool Select : 1;
1934+
1935+
/// If the shuffle transposes the elements of its inputs without changing the
1936+
/// length of the vectors. This operation may also be known as a merge or
1937+
/// interleave. See the description for isTransposeMask() for the exact
1938+
/// specification.
1939+
/// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
1940+
bool Transpose : 1;
1941+
1942+
/// If the shuffle splices two inputs without changing the length of the
1943+
/// vectors. This operation concatenates the two inputs together and then
1944+
/// extracts an original width vector starting from the splice index.
1945+
/// Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
1946+
bool Splice : 1;
1947+
1948+
/// The starting index of the splice.
1949+
/// Example: 1, from the previous example
1950+
int SpliceIndex;
1951+
};
1952+
1953+
static_assert(sizeof(ShuffleMaskAttrs) <= sizeof(uint64_t),
1954+
"ShuffleMaskAttrs is too large!");
1955+
18861956
/// This instruction constructs a fixed permutation of two
18871957
/// input vectors.
18881958
///
@@ -1898,6 +1968,7 @@ class ShuffleVectorInst : public Instruction {
18981968

18991969
SmallVector<int, 4> ShuffleMask;
19001970
Constant *ShuffleMaskForBitcode;
1971+
ShuffleMaskAttrs MaskAttrs;
19011972

19021973
protected:
19031974
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -1924,6 +1995,12 @@ class ShuffleVectorInst : public Instruction {
19241995
/// of the instruction.
19251996
void commute();
19261997

1998+
// Analyze mask of fixed vector. NumOpElts is number of known elements in
1999+
// operand1/operand2. Scalable is set if any operands are scalable vectors.
2000+
// HasUndefOp is set if there are any undef operands.
2001+
static ShuffleMaskAttrs analyzeMask(ArrayRef<int> Mask, int NumOpElts,
2002+
bool Scalable, bool HasUndefOp);
2003+
19272004
/// Return true if a shufflevector instruction can be
19282005
/// formed with the specified operands.
19292006
static bool isValidOperands(const Value *V1, const Value *V2,
@@ -2004,13 +2081,8 @@ class ShuffleVectorInst : public Instruction {
20042081
return isSingleSourceMask(MaskAsInts, NumSrcElts);
20052082
}
20062083

2007-
/// Return true if this shuffle chooses elements from exactly one source
2008-
/// vector without changing the length of that vector.
2009-
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
2010-
/// TODO: Optionally allow length-changing shuffles.
20112084
bool isSingleSource() const {
2012-
return !changesLength() &&
2013-
isSingleSourceMask(ShuffleMask, ShuffleMask.size());
2085+
return MaskAttrs.SingleSource;
20142086
}
20152087

20162088
/// Return true if this shuffle mask chooses elements from exactly one source
@@ -2032,31 +2104,21 @@ class ShuffleVectorInst : public Instruction {
20322104
return isIdentityMask(MaskAsInts, NumSrcElts);
20332105
}
20342106

2035-
/// Return true if this shuffle chooses elements from exactly one source
2036-
/// vector without lane crossings and does not change the number of elements
2037-
/// from its input vectors.
2038-
/// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
20392107
bool isIdentity() const {
2040-
// Not possible to express a shuffle mask for a scalable vector for this
2041-
// case.
2042-
if (isa<ScalableVectorType>(getType()))
2043-
return false;
2044-
2045-
return !changesLength() && isIdentityMask(ShuffleMask, ShuffleMask.size());
2108+
return MaskAttrs.Identity;
20462109
}
20472110

2048-
/// Return true if this shuffle lengthens exactly one source vector with
2049-
/// undefs in the high elements.
2050-
bool isIdentityWithPadding() const;
2111+
bool isIdentityWithPadding() const {
2112+
return MaskAttrs.IdentityWithPadding;
2113+
}
20512114

2052-
/// Return true if this shuffle extracts the first N elements of exactly one
2053-
/// source vector.
2054-
bool isIdentityWithExtract() const;
2115+
bool isIdentityWithExtract() const {
2116+
return MaskAttrs.IdentityWithExtract;
2117+
}
20552118

2056-
/// Return true if this shuffle concatenates its 2 source vectors. This
2057-
/// returns false if either input is undefined. In that case, the shuffle is
2058-
/// is better classified as an identity with padding operation.
2059-
bool isConcat() const;
2119+
bool isConcat() const {
2120+
return MaskAttrs.Concat;
2121+
}
20602122

20612123
/// Return true if this shuffle mask chooses elements from its source vectors
20622124
/// without lane crossings. A shuffle using this mask would be
@@ -2074,16 +2136,8 @@ class ShuffleVectorInst : public Instruction {
20742136
return isSelectMask(MaskAsInts, NumSrcElts);
20752137
}
20762138

2077-
/// Return true if this shuffle chooses elements from its source vectors
2078-
/// without lane crossings and all operands have the same number of elements.
2079-
/// In other words, this shuffle is equivalent to a vector select with a
2080-
/// constant condition operand.
2081-
/// Example: shufflevector <4 x n> A, <4 x n> B, <undef,1,6,3>
2082-
/// This returns false if the mask does not choose from both input vectors.
2083-
/// In that case, the shuffle is better classified as an identity shuffle.
2084-
/// TODO: Optionally allow length-changing shuffles.
20852139
bool isSelect() const {
2086-
return !changesLength() && isSelectMask(ShuffleMask, ShuffleMask.size());
2140+
return MaskAttrs.Select;
20872141
}
20882142

20892143
/// Return true if this shuffle mask swaps the order of elements from exactly
@@ -2099,12 +2153,8 @@ class ShuffleVectorInst : public Instruction {
20992153
return isReverseMask(MaskAsInts, NumSrcElts);
21002154
}
21012155

2102-
/// Return true if this shuffle swaps the order of elements from exactly
2103-
/// one source vector.
2104-
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
2105-
/// TODO: Optionally allow length-changing shuffles.
21062156
bool isReverse() const {
2107-
return !changesLength() && isReverseMask(ShuffleMask, ShuffleMask.size());
2157+
return MaskAttrs.Reverse;
21082158
}
21092159

21102160
/// Return true if this shuffle mask chooses all elements with the same value
@@ -2120,15 +2170,8 @@ class ShuffleVectorInst : public Instruction {
21202170
return isZeroEltSplatMask(MaskAsInts, NumSrcElts);
21212171
}
21222172

2123-
/// Return true if all elements of this shuffle are the same value as the
2124-
/// first element of exactly one source vector without changing the length
2125-
/// of that vector.
2126-
/// Example: shufflevector <4 x n> A, <4 x n> B, <undef,0,undef,0>
2127-
/// TODO: Optionally allow length-changing shuffles.
2128-
/// TODO: Optionally allow splats from other elements.
21292173
bool isZeroEltSplat() const {
2130-
return !changesLength() &&
2131-
isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
2174+
return MaskAttrs.ZeroEltSplat;
21322175
}
21332176

21342177
/// Return true if this shuffle mask is a transpose mask.
@@ -2171,13 +2214,8 @@ class ShuffleVectorInst : public Instruction {
21712214
return isTransposeMask(MaskAsInts, NumSrcElts);
21722215
}
21732216

2174-
/// Return true if this shuffle transposes the elements of its inputs without
2175-
/// changing the length of the vectors. This operation may also be known as a
2176-
/// merge or interleave. See the description for isTransposeMask() for the
2177-
/// exact specification.
2178-
/// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
21792217
bool isTranspose() const {
2180-
return !changesLength() && isTransposeMask(ShuffleMask, ShuffleMask.size());
2218+
return MaskAttrs.Transpose;
21812219
}
21822220

21832221
/// Return true if this shuffle mask is a splice mask, concatenating the two
@@ -2194,13 +2232,9 @@ class ShuffleVectorInst : public Instruction {
21942232
return isSpliceMask(MaskAsInts, NumSrcElts, Index);
21952233
}
21962234

2197-
/// Return true if this shuffle splices two inputs without changing the length
2198-
/// of the vectors. This operation concatenates the two inputs together and
2199-
/// then extracts an original width vector starting from the splice index.
2200-
/// Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
22012235
bool isSplice(int &Index) const {
2202-
return !changesLength() &&
2203-
isSpliceMask(ShuffleMask, ShuffleMask.size(), Index);
2236+
Index = MaskAttrs.SpliceIndex;
2237+
return MaskAttrs.Splice;
22042238
}
22052239

22062240
/// Return true if this shuffle mask is an extract subvector mask.

0 commit comments

Comments
 (0)