Skip to content

Commit 18ac1aa

Browse files
committed
[Instructions] cache computed shufflevector properties
Cache computed properties of a shufflevector mask.
1 parent 15ca799 commit 18ac1aa

File tree

2 files changed

+103
-21
lines changed

2 files changed

+103
-21
lines changed

llvm/include/llvm/IR/Instructions.h

Lines changed: 76 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,39 @@ class ShuffleVectorInst : public Instruction {
18591859

18601860
SmallVector<int, 4> ShuffleMask;
18611861
Constant *ShuffleMaskForBitcode;
1862+
struct ShuffleProperties {
1863+
bool isSingleSource : 1;
1864+
bool isSingleSource_set : 1;
1865+
bool isIdentityMask : 1;
1866+
bool isIdentityMask_set : 1;
1867+
bool isIdentityWithPadding : 1;
1868+
bool isIdentityWithPadding_set : 1;
1869+
bool isIdentityWithExtract : 1;
1870+
bool isIdentityWithExtract_set : 1;
1871+
bool isConcat : 1;
1872+
bool isConcat_set : 1;
1873+
bool isSelect : 1;
1874+
bool isSelect_set : 1;
1875+
bool isReverse : 1;
1876+
bool isReverse_set : 1;
1877+
bool isZeroEltSplat : 1;
1878+
bool isZeroEltSplat_set : 1;
1879+
bool isTranspose : 1;
1880+
bool isTranspose_set : 1;
1881+
1882+
void unset() {
1883+
isSingleSource_set = false;
1884+
isIdentityMask_set = false;
1885+
isIdentityWithPadding_set = false;
1886+
isIdentityWithExtract_set = false;
1887+
isConcat_set = false;
1888+
isSelect_set = false;
1889+
isReverse_set = false;
1890+
isZeroEltSplat_set = false;
1891+
isTranspose_set = false;
1892+
}
1893+
};
1894+
mutable ShuffleProperties CachedShuffleProperties = {};
18621895

18631896
protected:
18641897
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -1970,8 +2003,13 @@ class ShuffleVectorInst : public Instruction {
19702003
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
19712004
/// TODO: Optionally allow length-changing shuffles.
19722005
bool isSingleSource() const {
1973-
return !changesLength() &&
1974-
isSingleSourceMask(ShuffleMask, ShuffleMask.size());
2006+
if (CachedShuffleProperties.isSingleSource_set)
2007+
return CachedShuffleProperties.isSingleSource;
2008+
2009+
CachedShuffleProperties.isSingleSource_set = true;
2010+
return CachedShuffleProperties.isSingleSource =
2011+
!changesLength() &&
2012+
isSingleSourceMask(ShuffleMask, ShuffleMask.size());
19752013
}
19762014

19772015
/// Return true if this shuffle mask chooses elements from exactly one source
@@ -1998,12 +2036,18 @@ class ShuffleVectorInst : public Instruction {
19982036
/// from its input vectors.
19992037
/// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
20002038
bool isIdentity() const {
2039+
if (CachedShuffleProperties.isIdentityMask_set)
2040+
return CachedShuffleProperties.isIdentityMask;
2041+
2042+
CachedShuffleProperties.isIdentityMask_set = true;
20012043
// Not possible to express a shuffle mask for a scalable vector for this
20022044
// case.
20032045
if (isa<ScalableVectorType>(getType()))
2004-
return false;
2046+
return CachedShuffleProperties.isIdentityMask = false;
20052047

2006-
return !changesLength() && isIdentityMask(ShuffleMask, ShuffleMask.size());
2048+
return CachedShuffleProperties.isIdentityMask =
2049+
!changesLength() &&
2050+
isIdentityMask(ShuffleMask, ShuffleMask.size());
20072051
}
20082052

20092053
/// Return true if this shuffle lengthens exactly one source vector with
@@ -2044,7 +2088,13 @@ class ShuffleVectorInst : public Instruction {
20442088
/// In that case, the shuffle is better classified as an identity shuffle.
20452089
/// TODO: Optionally allow length-changing shuffles.
20462090
bool isSelect() const {
2047-
return !changesLength() && isSelectMask(ShuffleMask, ShuffleMask.size());
2091+
if (CachedShuffleProperties.isSelect_set)
2092+
return CachedShuffleProperties.isSelect;
2093+
2094+
CachedShuffleProperties.isSelect_set = true;
2095+
return CachedShuffleProperties.isSelect =
2096+
!changesLength() &&
2097+
isSelectMask(ShuffleMask, ShuffleMask.size());
20482098
}
20492099

20502100
/// Return true if this shuffle mask swaps the order of elements from exactly
@@ -2065,7 +2115,13 @@ class ShuffleVectorInst : public Instruction {
20652115
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
20662116
/// TODO: Optionally allow length-changing shuffles.
20672117
bool isReverse() const {
2068-
return !changesLength() && isReverseMask(ShuffleMask, ShuffleMask.size());
2118+
if (CachedShuffleProperties.isReverse_set)
2119+
return CachedShuffleProperties.isReverse;
2120+
2121+
CachedShuffleProperties.isReverse_set = true;
2122+
return CachedShuffleProperties.isReverse =
2123+
!changesLength() &&
2124+
isReverseMask(ShuffleMask, ShuffleMask.size());
20692125
}
20702126

20712127
/// Return true if this shuffle mask chooses all elements with the same value
@@ -2088,8 +2144,13 @@ class ShuffleVectorInst : public Instruction {
20882144
/// TODO: Optionally allow length-changing shuffles.
20892145
/// TODO: Optionally allow splats from other elements.
20902146
bool isZeroEltSplat() const {
2091-
return !changesLength() &&
2092-
isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
2147+
if (CachedShuffleProperties.isZeroEltSplat_set)
2148+
return CachedShuffleProperties.isZeroEltSplat;
2149+
2150+
CachedShuffleProperties.isZeroEltSplat_set = true;
2151+
return CachedShuffleProperties.isZeroEltSplat =
2152+
!changesLength() &&
2153+
isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
20932154
}
20942155

20952156
/// Return true if this shuffle mask is a transpose mask.
@@ -2138,7 +2199,13 @@ class ShuffleVectorInst : public Instruction {
21382199
/// exact specification.
21392200
/// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
21402201
bool isTranspose() const {
2141-
return !changesLength() && isTransposeMask(ShuffleMask, ShuffleMask.size());
2202+
if (CachedShuffleProperties.isTranspose_set)
2203+
return CachedShuffleProperties.isTranspose;
2204+
2205+
CachedShuffleProperties.isTranspose_set = true;
2206+
return CachedShuffleProperties.isTranspose =
2207+
!changesLength() &&
2208+
isTransposeMask(ShuffleMask, ShuffleMask.size());
21422209
}
21432210

21442211
/// Return true if this shuffle mask is a splice mask, concatenating the two

llvm/lib/IR/Instructions.cpp

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,7 @@ void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
18121812
}
18131813

18141814
void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
1815+
CachedShuffleProperties.unset();
18151816
ShuffleMask.assign(Mask.begin(), Mask.end());
18161817
ShuffleMaskForBitcode = convertShuffleMaskForBitcode(Mask, getType());
18171818
}
@@ -2102,63 +2103,77 @@ bool ShuffleVectorInst::isInsertSubvectorMask(ArrayRef<int> Mask,
21022103
}
21032104

21042105
bool ShuffleVectorInst::isIdentityWithPadding() const {
2106+
if (CachedShuffleProperties.isIdentityWithPadding_set)
2107+
return CachedShuffleProperties.isIdentityWithPadding;
2108+
2109+
CachedShuffleProperties.isIdentityWithPadding_set = true;
21052110
// FIXME: Not currently possible to express a shuffle mask for a scalable
21062111
// vector for this case.
21072112
if (isa<ScalableVectorType>(getType()))
2108-
return false;
2113+
return CachedShuffleProperties.isIdentityWithPadding = false;
21092114

21102115
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21112116
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21122117
if (NumMaskElts <= NumOpElts)
2113-
return false;
2118+
return CachedShuffleProperties.isIdentityWithPadding = false;
21142119

21152120
// The first part of the mask must choose elements from exactly 1 source op.
21162121
ArrayRef<int> Mask = getShuffleMask();
21172122
if (!isIdentityMaskImpl(Mask, NumOpElts))
2118-
return false;
2123+
return CachedShuffleProperties.isIdentityWithPadding = false;
21192124

21202125
// All extending must be with undef elements.
21212126
for (int i = NumOpElts; i < NumMaskElts; ++i)
21222127
if (Mask[i] != -1)
2123-
return false;
2128+
return CachedShuffleProperties.isIdentityWithPadding = false;
21242129

2125-
return true;
2130+
return CachedShuffleProperties.isIdentityWithPadding = true;
21262131
}
21272132

21282133
bool ShuffleVectorInst::isIdentityWithExtract() const {
2134+
if (CachedShuffleProperties.isIdentityWithExtract_set)
2135+
return CachedShuffleProperties.isIdentityWithExtract;
2136+
2137+
CachedShuffleProperties.isIdentityWithExtract_set = true;
21292138
// FIXME: Not currently possible to express a shuffle mask for a scalable
21302139
// vector for this case.
21312140
if (isa<ScalableVectorType>(getType()))
2132-
return false;
2141+
return CachedShuffleProperties.isIdentityWithExtract = false;
21332142

21342143
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21352144
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21362145
if (NumMaskElts >= NumOpElts)
2137-
return false;
2146+
return CachedShuffleProperties.isIdentityWithExtract = false;
21382147

2139-
return isIdentityMaskImpl(getShuffleMask(), NumOpElts);
2148+
return CachedShuffleProperties.isIdentityWithExtract =
2149+
isIdentityMaskImpl(getShuffleMask(), NumOpElts);
21402150
}
21412151

21422152
bool ShuffleVectorInst::isConcat() const {
2153+
if (CachedShuffleProperties.isConcat_set)
2154+
return CachedShuffleProperties.isConcat;
2155+
2156+
CachedShuffleProperties.isConcat_set = true;
21432157
// Vector concatenation is differentiated from identity with padding.
21442158
if (isa<UndefValue>(Op<0>()) || isa<UndefValue>(Op<1>()))
2145-
return false;
2159+
return CachedShuffleProperties.isConcat = false;
21462160

21472161
// FIXME: Not currently possible to express a shuffle mask for a scalable
21482162
// vector for this case.
21492163
if (isa<ScalableVectorType>(getType()))
2150-
return false;
2164+
return CachedShuffleProperties.isConcat = false;
21512165

21522166
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21532167
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21542168
if (NumMaskElts != NumOpElts * 2)
2155-
return false;
2169+
return CachedShuffleProperties.isConcat = false;
21562170

21572171
// Use the mask length rather than the operands' vector lengths here. We
21582172
// already know that the shuffle returns a vector twice as long as the inputs,
21592173
// and neither of the inputs are undef vectors. If the mask picks consecutive
21602174
// elements from both inputs, then this is a concatenation of the inputs.
2161-
return isIdentityMaskImpl(getShuffleMask(), NumMaskElts);
2175+
return CachedShuffleProperties.isConcat =
2176+
isIdentityMaskImpl(getShuffleMask(), NumMaskElts);
21622177
}
21632178

21642179
static bool isReplicationMaskWithParams(ArrayRef<int> Mask,

0 commit comments

Comments
 (0)