Skip to content

Commit 6a332ad

Browse files
committed
[Instructions] cache computed shufflevector properties
Cache computed properties of a shufflevector mask.
1 parent 58ca707 commit 6a332ad

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
@@ -1848,6 +1848,39 @@ class ShuffleVectorInst : public Instruction {
18481848

18491849
SmallVector<int, 4> ShuffleMask;
18501850
Constant *ShuffleMaskForBitcode;
1851+
struct ShuffleProperties {
1852+
bool isSingleSource : 1;
1853+
bool isSingleSource_set : 1;
1854+
bool isIdentityMask : 1;
1855+
bool isIdentityMask_set : 1;
1856+
bool isIdentityWithPadding : 1;
1857+
bool isIdentityWithPadding_set : 1;
1858+
bool isIdentityWithExtract : 1;
1859+
bool isIdentityWithExtract_set : 1;
1860+
bool isConcat : 1;
1861+
bool isConcat_set : 1;
1862+
bool isSelect : 1;
1863+
bool isSelect_set : 1;
1864+
bool isReverse : 1;
1865+
bool isReverse_set : 1;
1866+
bool isZeroEltSplat : 1;
1867+
bool isZeroEltSplat_set : 1;
1868+
bool isTranspose : 1;
1869+
bool isTranspose_set : 1;
1870+
1871+
void unset() {
1872+
isSingleSource_set = false;
1873+
isIdentityMask_set = false;
1874+
isIdentityWithPadding_set = false;
1875+
isIdentityWithExtract_set = false;
1876+
isConcat_set = false;
1877+
isSelect_set = false;
1878+
isReverse_set = false;
1879+
isZeroEltSplat_set = false;
1880+
isTranspose_set = false;
1881+
}
1882+
};
1883+
mutable ShuffleProperties CachedShuffleProperties = {};
18511884

18521885
protected:
18531886
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -1959,8 +1992,13 @@ class ShuffleVectorInst : public Instruction {
19591992
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
19601993
/// TODO: Optionally allow length-changing shuffles.
19611994
bool isSingleSource() const {
1962-
return !changesLength() &&
1963-
isSingleSourceMask(ShuffleMask, ShuffleMask.size());
1995+
if (CachedShuffleProperties.isSingleSource_set)
1996+
return CachedShuffleProperties.isSingleSource;
1997+
1998+
CachedShuffleProperties.isSingleSource_set = true;
1999+
return CachedShuffleProperties.isSingleSource =
2000+
!changesLength() &&
2001+
isSingleSourceMask(ShuffleMask, ShuffleMask.size());
19642002
}
19652003

19662004
/// Return true if this shuffle mask chooses elements from exactly one source
@@ -1987,12 +2025,18 @@ class ShuffleVectorInst : public Instruction {
19872025
/// from its input vectors.
19882026
/// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
19892027
bool isIdentity() const {
2028+
if (CachedShuffleProperties.isIdentityMask_set)
2029+
return CachedShuffleProperties.isIdentityMask;
2030+
2031+
CachedShuffleProperties.isIdentityMask_set = true;
19902032
// Not possible to express a shuffle mask for a scalable vector for this
19912033
// case.
19922034
if (isa<ScalableVectorType>(getType()))
1993-
return false;
2035+
return CachedShuffleProperties.isIdentityMask = false;
19942036

1995-
return !changesLength() && isIdentityMask(ShuffleMask, ShuffleMask.size());
2037+
return CachedShuffleProperties.isIdentityMask =
2038+
!changesLength() &&
2039+
isIdentityMask(ShuffleMask, ShuffleMask.size());
19962040
}
19972041

19982042
/// Return true if this shuffle lengthens exactly one source vector with
@@ -2033,7 +2077,13 @@ class ShuffleVectorInst : public Instruction {
20332077
/// In that case, the shuffle is better classified as an identity shuffle.
20342078
/// TODO: Optionally allow length-changing shuffles.
20352079
bool isSelect() const {
2036-
return !changesLength() && isSelectMask(ShuffleMask, ShuffleMask.size());
2080+
if (CachedShuffleProperties.isSelect_set)
2081+
return CachedShuffleProperties.isSelect;
2082+
2083+
CachedShuffleProperties.isSelect_set = true;
2084+
return CachedShuffleProperties.isSelect =
2085+
!changesLength() &&
2086+
isSelectMask(ShuffleMask, ShuffleMask.size());
20372087
}
20382088

20392089
/// Return true if this shuffle mask swaps the order of elements from exactly
@@ -2054,7 +2104,13 @@ class ShuffleVectorInst : public Instruction {
20542104
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
20552105
/// TODO: Optionally allow length-changing shuffles.
20562106
bool isReverse() const {
2057-
return !changesLength() && isReverseMask(ShuffleMask, ShuffleMask.size());
2107+
if (CachedShuffleProperties.isReverse_set)
2108+
return CachedShuffleProperties.isReverse;
2109+
2110+
CachedShuffleProperties.isReverse_set = true;
2111+
return CachedShuffleProperties.isReverse =
2112+
!changesLength() &&
2113+
isReverseMask(ShuffleMask, ShuffleMask.size());
20582114
}
20592115

20602116
/// Return true if this shuffle mask chooses all elements with the same value
@@ -2077,8 +2133,13 @@ class ShuffleVectorInst : public Instruction {
20772133
/// TODO: Optionally allow length-changing shuffles.
20782134
/// TODO: Optionally allow splats from other elements.
20792135
bool isZeroEltSplat() const {
2080-
return !changesLength() &&
2081-
isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
2136+
if (CachedShuffleProperties.isZeroEltSplat_set)
2137+
return CachedShuffleProperties.isZeroEltSplat;
2138+
2139+
CachedShuffleProperties.isZeroEltSplat_set = true;
2140+
return CachedShuffleProperties.isZeroEltSplat =
2141+
!changesLength() &&
2142+
isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
20822143
}
20832144

20842145
/// Return true if this shuffle mask is a transpose mask.
@@ -2127,7 +2188,13 @@ class ShuffleVectorInst : public Instruction {
21272188
/// exact specification.
21282189
/// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
21292190
bool isTranspose() const {
2130-
return !changesLength() && isTransposeMask(ShuffleMask, ShuffleMask.size());
2191+
if (CachedShuffleProperties.isTranspose_set)
2192+
return CachedShuffleProperties.isTranspose;
2193+
2194+
CachedShuffleProperties.isTranspose_set = true;
2195+
return CachedShuffleProperties.isTranspose =
2196+
!changesLength() &&
2197+
isTransposeMask(ShuffleMask, ShuffleMask.size());
21312198
}
21322199

21332200
/// 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
@@ -1811,6 +1811,7 @@ void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
18111811
}
18121812

18131813
void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
1814+
CachedShuffleProperties.unset();
18141815
ShuffleMask.assign(Mask.begin(), Mask.end());
18151816
ShuffleMaskForBitcode = convertShuffleMaskForBitcode(Mask, getType());
18161817
}
@@ -2101,63 +2102,77 @@ bool ShuffleVectorInst::isInsertSubvectorMask(ArrayRef<int> Mask,
21012102
}
21022103

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

21092114
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21102115
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21112116
if (NumMaskElts <= NumOpElts)
2112-
return false;
2117+
return CachedShuffleProperties.isIdentityWithPadding = false;
21132118

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

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

2124-
return true;
2129+
return CachedShuffleProperties.isIdentityWithPadding = true;
21252130
}
21262131

21272132
bool ShuffleVectorInst::isIdentityWithExtract() const {
2133+
if (CachedShuffleProperties.isIdentityWithExtract_set)
2134+
return CachedShuffleProperties.isIdentityWithExtract;
2135+
2136+
CachedShuffleProperties.isIdentityWithExtract_set = true;
21282137
// FIXME: Not currently possible to express a shuffle mask for a scalable
21292138
// vector for this case.
21302139
if (isa<ScalableVectorType>(getType()))
2131-
return false;
2140+
return CachedShuffleProperties.isIdentityWithExtract = false;
21322141

21332142
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21342143
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21352144
if (NumMaskElts >= NumOpElts)
2136-
return false;
2145+
return CachedShuffleProperties.isIdentityWithExtract = false;
21372146

2138-
return isIdentityMaskImpl(getShuffleMask(), NumOpElts);
2147+
return CachedShuffleProperties.isIdentityWithExtract =
2148+
isIdentityMaskImpl(getShuffleMask(), NumOpElts);
21392149
}
21402150

21412151
bool ShuffleVectorInst::isConcat() const {
2152+
if (CachedShuffleProperties.isConcat_set)
2153+
return CachedShuffleProperties.isConcat;
2154+
2155+
CachedShuffleProperties.isConcat_set = true;
21422156
// Vector concatenation is differentiated from identity with padding.
21432157
if (isa<UndefValue>(Op<0>()) || isa<UndefValue>(Op<1>()))
2144-
return false;
2158+
return CachedShuffleProperties.isConcat = false;
21452159

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

21512165
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21522166
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21532167
if (NumMaskElts != NumOpElts * 2)
2154-
return false;
2168+
return CachedShuffleProperties.isConcat = false;
21552169

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

21632178
static bool isReplicationMaskWithParams(ArrayRef<int> Mask,

0 commit comments

Comments
 (0)