@@ -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
18521885protected:
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
0 commit comments