@@ -1848,6 +1848,39 @@ class ShuffleVectorInst : public Instruction {
1848
1848
1849
1849
SmallVector<int , 4 > ShuffleMask;
1850
1850
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 = {};
1851
1884
1852
1885
protected:
1853
1886
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -1959,8 +1992,13 @@ class ShuffleVectorInst : public Instruction {
1959
1992
// / Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
1960
1993
// / TODO: Optionally allow length-changing shuffles.
1961
1994
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 ());
1964
2002
}
1965
2003
1966
2004
// / Return true if this shuffle mask chooses elements from exactly one source
@@ -1987,12 +2025,18 @@ class ShuffleVectorInst : public Instruction {
1987
2025
// / from its input vectors.
1988
2026
// / Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
1989
2027
bool isIdentity () const {
2028
+ if (CachedShuffleProperties.isIdentityMask_set )
2029
+ return CachedShuffleProperties.isIdentityMask ;
2030
+
2031
+ CachedShuffleProperties.isIdentityMask_set = true ;
1990
2032
// Not possible to express a shuffle mask for a scalable vector for this
1991
2033
// case.
1992
2034
if (isa<ScalableVectorType>(getType ()))
1993
- return false ;
2035
+ return CachedShuffleProperties. isIdentityMask = false ;
1994
2036
1995
- return !changesLength () && isIdentityMask (ShuffleMask, ShuffleMask.size ());
2037
+ return CachedShuffleProperties.isIdentityMask =
2038
+ !changesLength () &&
2039
+ isIdentityMask (ShuffleMask, ShuffleMask.size ());
1996
2040
}
1997
2041
1998
2042
// / Return true if this shuffle lengthens exactly one source vector with
@@ -2033,7 +2077,13 @@ class ShuffleVectorInst : public Instruction {
2033
2077
// / In that case, the shuffle is better classified as an identity shuffle.
2034
2078
// / TODO: Optionally allow length-changing shuffles.
2035
2079
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 ());
2037
2087
}
2038
2088
2039
2089
// / Return true if this shuffle mask swaps the order of elements from exactly
@@ -2054,7 +2104,13 @@ class ShuffleVectorInst : public Instruction {
2054
2104
// / Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
2055
2105
// / TODO: Optionally allow length-changing shuffles.
2056
2106
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 ());
2058
2114
}
2059
2115
2060
2116
// / Return true if this shuffle mask chooses all elements with the same value
@@ -2077,8 +2133,13 @@ class ShuffleVectorInst : public Instruction {
2077
2133
// / TODO: Optionally allow length-changing shuffles.
2078
2134
// / TODO: Optionally allow splats from other elements.
2079
2135
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 ());
2082
2143
}
2083
2144
2084
2145
// / Return true if this shuffle mask is a transpose mask.
@@ -2127,7 +2188,13 @@ class ShuffleVectorInst : public Instruction {
2127
2188
// / exact specification.
2128
2189
// / Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
2129
2190
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 ());
2131
2198
}
2132
2199
2133
2200
// / Return true if this shuffle mask is a splice mask, concatenating the two
0 commit comments