[llvm] [Instructions] cache computed shufflevector properties (PR #115536)
Princeton Ferro via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 16 09:46:38 PST 2024
https://github.com/Prince781 updated https://github.com/llvm/llvm-project/pull/115536
>From 18ac1aa386b4ae9ea5222c551668ef1ccf477f55 Mon Sep 17 00:00:00 2001
From: Princeton Ferro <pferro at nvidia.com>
Date: Fri, 8 Nov 2024 11:04:37 -0800
Subject: [PATCH] [Instructions] cache computed shufflevector properties
Cache computed properties of a shufflevector mask.
---
llvm/include/llvm/IR/Instructions.h | 85 ++++++++++++++++++++++++++---
llvm/lib/IR/Instructions.cpp | 39 +++++++++----
2 files changed, 103 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 8eea659a00caf3..369b4d4cdc107f 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -1859,6 +1859,39 @@ class ShuffleVectorInst : public Instruction {
SmallVector<int, 4> ShuffleMask;
Constant *ShuffleMaskForBitcode;
+ struct ShuffleProperties {
+ bool isSingleSource : 1;
+ bool isSingleSource_set : 1;
+ bool isIdentityMask : 1;
+ bool isIdentityMask_set : 1;
+ bool isIdentityWithPadding : 1;
+ bool isIdentityWithPadding_set : 1;
+ bool isIdentityWithExtract : 1;
+ bool isIdentityWithExtract_set : 1;
+ bool isConcat : 1;
+ bool isConcat_set : 1;
+ bool isSelect : 1;
+ bool isSelect_set : 1;
+ bool isReverse : 1;
+ bool isReverse_set : 1;
+ bool isZeroEltSplat : 1;
+ bool isZeroEltSplat_set : 1;
+ bool isTranspose : 1;
+ bool isTranspose_set : 1;
+
+ void unset() {
+ isSingleSource_set = false;
+ isIdentityMask_set = false;
+ isIdentityWithPadding_set = false;
+ isIdentityWithExtract_set = false;
+ isConcat_set = false;
+ isSelect_set = false;
+ isReverse_set = false;
+ isZeroEltSplat_set = false;
+ isTranspose_set = false;
+ }
+ };
+ mutable ShuffleProperties CachedShuffleProperties = {};
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
@@ -1970,8 +2003,13 @@ class ShuffleVectorInst : public Instruction {
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
/// TODO: Optionally allow length-changing shuffles.
bool isSingleSource() const {
- return !changesLength() &&
- isSingleSourceMask(ShuffleMask, ShuffleMask.size());
+ if (CachedShuffleProperties.isSingleSource_set)
+ return CachedShuffleProperties.isSingleSource;
+
+ CachedShuffleProperties.isSingleSource_set = true;
+ return CachedShuffleProperties.isSingleSource =
+ !changesLength() &&
+ isSingleSourceMask(ShuffleMask, ShuffleMask.size());
}
/// Return true if this shuffle mask chooses elements from exactly one source
@@ -1998,12 +2036,18 @@ class ShuffleVectorInst : public Instruction {
/// from its input vectors.
/// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
bool isIdentity() const {
+ if (CachedShuffleProperties.isIdentityMask_set)
+ return CachedShuffleProperties.isIdentityMask;
+
+ CachedShuffleProperties.isIdentityMask_set = true;
// Not possible to express a shuffle mask for a scalable vector for this
// case.
if (isa<ScalableVectorType>(getType()))
- return false;
+ return CachedShuffleProperties.isIdentityMask = false;
- return !changesLength() && isIdentityMask(ShuffleMask, ShuffleMask.size());
+ return CachedShuffleProperties.isIdentityMask =
+ !changesLength() &&
+ isIdentityMask(ShuffleMask, ShuffleMask.size());
}
/// Return true if this shuffle lengthens exactly one source vector with
@@ -2044,7 +2088,13 @@ class ShuffleVectorInst : public Instruction {
/// In that case, the shuffle is better classified as an identity shuffle.
/// TODO: Optionally allow length-changing shuffles.
bool isSelect() const {
- return !changesLength() && isSelectMask(ShuffleMask, ShuffleMask.size());
+ if (CachedShuffleProperties.isSelect_set)
+ return CachedShuffleProperties.isSelect;
+
+ CachedShuffleProperties.isSelect_set = true;
+ return CachedShuffleProperties.isSelect =
+ !changesLength() &&
+ isSelectMask(ShuffleMask, ShuffleMask.size());
}
/// Return true if this shuffle mask swaps the order of elements from exactly
@@ -2065,7 +2115,13 @@ class ShuffleVectorInst : public Instruction {
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
/// TODO: Optionally allow length-changing shuffles.
bool isReverse() const {
- return !changesLength() && isReverseMask(ShuffleMask, ShuffleMask.size());
+ if (CachedShuffleProperties.isReverse_set)
+ return CachedShuffleProperties.isReverse;
+
+ CachedShuffleProperties.isReverse_set = true;
+ return CachedShuffleProperties.isReverse =
+ !changesLength() &&
+ isReverseMask(ShuffleMask, ShuffleMask.size());
}
/// Return true if this shuffle mask chooses all elements with the same value
@@ -2088,8 +2144,13 @@ class ShuffleVectorInst : public Instruction {
/// TODO: Optionally allow length-changing shuffles.
/// TODO: Optionally allow splats from other elements.
bool isZeroEltSplat() const {
- return !changesLength() &&
- isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
+ if (CachedShuffleProperties.isZeroEltSplat_set)
+ return CachedShuffleProperties.isZeroEltSplat;
+
+ CachedShuffleProperties.isZeroEltSplat_set = true;
+ return CachedShuffleProperties.isZeroEltSplat =
+ !changesLength() &&
+ isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
}
/// Return true if this shuffle mask is a transpose mask.
@@ -2138,7 +2199,13 @@ class ShuffleVectorInst : public Instruction {
/// exact specification.
/// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
bool isTranspose() const {
- return !changesLength() && isTransposeMask(ShuffleMask, ShuffleMask.size());
+ if (CachedShuffleProperties.isTranspose_set)
+ return CachedShuffleProperties.isTranspose;
+
+ CachedShuffleProperties.isTranspose_set = true;
+ return CachedShuffleProperties.isTranspose =
+ !changesLength() &&
+ isTransposeMask(ShuffleMask, ShuffleMask.size());
}
/// Return true if this shuffle mask is a splice mask, concatenating the two
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 5b89a27126150a..65d1abd1ae5b6a 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1812,6 +1812,7 @@ void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
}
void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
+ CachedShuffleProperties.unset();
ShuffleMask.assign(Mask.begin(), Mask.end());
ShuffleMaskForBitcode = convertShuffleMaskForBitcode(Mask, getType());
}
@@ -2102,63 +2103,77 @@ bool ShuffleVectorInst::isInsertSubvectorMask(ArrayRef<int> Mask,
}
bool ShuffleVectorInst::isIdentityWithPadding() const {
+ if (CachedShuffleProperties.isIdentityWithPadding_set)
+ return CachedShuffleProperties.isIdentityWithPadding;
+
+ CachedShuffleProperties.isIdentityWithPadding_set = true;
// FIXME: Not currently possible to express a shuffle mask for a scalable
// vector for this case.
if (isa<ScalableVectorType>(getType()))
- return false;
+ return CachedShuffleProperties.isIdentityWithPadding = false;
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
if (NumMaskElts <= NumOpElts)
- return false;
+ return CachedShuffleProperties.isIdentityWithPadding = false;
// The first part of the mask must choose elements from exactly 1 source op.
ArrayRef<int> Mask = getShuffleMask();
if (!isIdentityMaskImpl(Mask, NumOpElts))
- return false;
+ return CachedShuffleProperties.isIdentityWithPadding = false;
// All extending must be with undef elements.
for (int i = NumOpElts; i < NumMaskElts; ++i)
if (Mask[i] != -1)
- return false;
+ return CachedShuffleProperties.isIdentityWithPadding = false;
- return true;
+ return CachedShuffleProperties.isIdentityWithPadding = true;
}
bool ShuffleVectorInst::isIdentityWithExtract() const {
+ if (CachedShuffleProperties.isIdentityWithExtract_set)
+ return CachedShuffleProperties.isIdentityWithExtract;
+
+ CachedShuffleProperties.isIdentityWithExtract_set = true;
// FIXME: Not currently possible to express a shuffle mask for a scalable
// vector for this case.
if (isa<ScalableVectorType>(getType()))
- return false;
+ return CachedShuffleProperties.isIdentityWithExtract = false;
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
if (NumMaskElts >= NumOpElts)
- return false;
+ return CachedShuffleProperties.isIdentityWithExtract = false;
- return isIdentityMaskImpl(getShuffleMask(), NumOpElts);
+ return CachedShuffleProperties.isIdentityWithExtract =
+ isIdentityMaskImpl(getShuffleMask(), NumOpElts);
}
bool ShuffleVectorInst::isConcat() const {
+ if (CachedShuffleProperties.isConcat_set)
+ return CachedShuffleProperties.isConcat;
+
+ CachedShuffleProperties.isConcat_set = true;
// Vector concatenation is differentiated from identity with padding.
if (isa<UndefValue>(Op<0>()) || isa<UndefValue>(Op<1>()))
- return false;
+ return CachedShuffleProperties.isConcat = false;
// FIXME: Not currently possible to express a shuffle mask for a scalable
// vector for this case.
if (isa<ScalableVectorType>(getType()))
- return false;
+ return CachedShuffleProperties.isConcat = false;
int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
if (NumMaskElts != NumOpElts * 2)
- return false;
+ return CachedShuffleProperties.isConcat = false;
// Use the mask length rather than the operands' vector lengths here. We
// already know that the shuffle returns a vector twice as long as the inputs,
// and neither of the inputs are undef vectors. If the mask picks consecutive
// elements from both inputs, then this is a concatenation of the inputs.
- return isIdentityMaskImpl(getShuffleMask(), NumMaskElts);
+ return CachedShuffleProperties.isConcat =
+ isIdentityMaskImpl(getShuffleMask(), NumMaskElts);
}
static bool isReplicationMaskWithParams(ArrayRef<int> Mask,
More information about the llvm-commits
mailing list