-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Add target hook for automatic histogram vectorization #128414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Now, each target, depending on the load/store instruction, can indicate whether it is safe to vectorize histogram operations. For example, this allows distinguishing between different pointer address spaces.
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-llvm-analysis Author: None (RonDahan101) ChangesNow, each target, depending on the load/store instruction, can indicate whether it is safe to vectorize histogram operations. For example, this allows distinguishing between different pointer address spaces. Full diff: https://github.com/llvm/llvm-project/pull/128414.diff 4 Files Affected:
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 9048481b49189..94a565a99ab41 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -805,6 +805,9 @@ class TargetTransformInfo {
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const;
/// Return true if the target supports masked gather.
bool isLegalMaskedGather(Type *DataType, Align Alignment) const;
+ /// Return true if the target supports vectorization of histograms.
+ bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) const;
/// Return true if the target forces scalarizing of llvm.masked.gather
/// intrinsics.
bool forceScalarizeMaskedGather(VectorType *Type, Align Alignment) const;
@@ -2028,6 +2031,8 @@ class TargetTransformInfo::Concept {
ElementCount NumElements) const = 0;
virtual bool isLegalMaskedScatter(Type *DataType, Align Alignment) = 0;
virtual bool isLegalMaskedGather(Type *DataType, Align Alignment) = 0;
+ virtual bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) = 0;
virtual bool forceScalarizeMaskedGather(VectorType *DataType,
Align Alignment) = 0;
virtual bool forceScalarizeMaskedScatter(VectorType *DataType,
@@ -2589,6 +2594,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
bool isLegalMaskedGather(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedGather(DataType, Alignment);
}
+ bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) override {
+ return Impl.isLegalForHistogramVectorization(LI, SI);
+ }
bool forceScalarizeMaskedGather(VectorType *DataType,
Align Alignment) override {
return Impl.forceScalarizeMaskedGather(DataType, Alignment);
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index a8d6dd18266bb..de93612ffffda 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -310,6 +310,22 @@ class TargetTransformInfoImplBase {
return false;
}
+ bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) const {
+ // TODO: Currently, when a target wants to use histogram intrinsics, it adds
+ // the
+ // `-enable-histogram-loop-vectorization` flag to Clang.
+ //
+ // Once the histogram option is enabled by default, we will need to update
+ // the default hook to return `false`, and each target that wants automatic
+ // histogram vectorization will need to override it to return `true`.
+ //
+ // Additionally, we will need to deprecate the
+ // `-enable-histogram-loop-vectorization` flag, as it will no longer be
+ // necessary.
+ return true;
+ }
+
bool forceScalarizeMaskedGather(VectorType *DataType, Align Alignment) const {
return false;
}
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 7df7038f6dd47..7a020d55abad2 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -492,6 +492,11 @@ bool TargetTransformInfo::isLegalMaskedGather(Type *DataType,
return TTIImpl->isLegalMaskedGather(DataType, Alignment);
}
+bool TargetTransformInfo::isLegalForHistogramVectorization(
+ const LoadInst *LI, const StoreInst *SI) const {
+ return TTIImpl->isLegalForHistogramVectorization(LI, SI);
+}
+
bool TargetTransformInfo::isLegalAltInstr(
VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
const SmallBitVector &OpcodeMask) const {
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 420cbc5384ce4..4045fd315d5bd 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1193,6 +1193,9 @@ bool LoopVectorizationLegality::canVectorizeIndirectUnsafeDependences() {
if (!LI || !SI)
return false;
+ if (!TTI->isLegalForHistogramVectorization(LI, SI))
+ return false;
+
LLVM_DEBUG(dbgs() << "LV: Checking for a histogram on: " << *SI << "\n");
return findHistogram(LI, SI, TheLoop, LAI->getPSE(), Histograms);
}
|
|
@llvm/pr-subscribers-vectorizers Author: None (RonDahan101) ChangesNow, each target, depending on the load/store instruction, can indicate whether it is safe to vectorize histogram operations. For example, this allows distinguishing between different pointer address spaces. Full diff: https://github.com/llvm/llvm-project/pull/128414.diff 4 Files Affected:
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 9048481b49189..94a565a99ab41 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -805,6 +805,9 @@ class TargetTransformInfo {
bool isLegalMaskedScatter(Type *DataType, Align Alignment) const;
/// Return true if the target supports masked gather.
bool isLegalMaskedGather(Type *DataType, Align Alignment) const;
+ /// Return true if the target supports vectorization of histograms.
+ bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) const;
/// Return true if the target forces scalarizing of llvm.masked.gather
/// intrinsics.
bool forceScalarizeMaskedGather(VectorType *Type, Align Alignment) const;
@@ -2028,6 +2031,8 @@ class TargetTransformInfo::Concept {
ElementCount NumElements) const = 0;
virtual bool isLegalMaskedScatter(Type *DataType, Align Alignment) = 0;
virtual bool isLegalMaskedGather(Type *DataType, Align Alignment) = 0;
+ virtual bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) = 0;
virtual bool forceScalarizeMaskedGather(VectorType *DataType,
Align Alignment) = 0;
virtual bool forceScalarizeMaskedScatter(VectorType *DataType,
@@ -2589,6 +2594,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
bool isLegalMaskedGather(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedGather(DataType, Alignment);
}
+ bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) override {
+ return Impl.isLegalForHistogramVectorization(LI, SI);
+ }
bool forceScalarizeMaskedGather(VectorType *DataType,
Align Alignment) override {
return Impl.forceScalarizeMaskedGather(DataType, Alignment);
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index a8d6dd18266bb..de93612ffffda 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -310,6 +310,22 @@ class TargetTransformInfoImplBase {
return false;
}
+ bool isLegalForHistogramVectorization(const LoadInst *LI,
+ const StoreInst *SI) const {
+ // TODO: Currently, when a target wants to use histogram intrinsics, it adds
+ // the
+ // `-enable-histogram-loop-vectorization` flag to Clang.
+ //
+ // Once the histogram option is enabled by default, we will need to update
+ // the default hook to return `false`, and each target that wants automatic
+ // histogram vectorization will need to override it to return `true`.
+ //
+ // Additionally, we will need to deprecate the
+ // `-enable-histogram-loop-vectorization` flag, as it will no longer be
+ // necessary.
+ return true;
+ }
+
bool forceScalarizeMaskedGather(VectorType *DataType, Align Alignment) const {
return false;
}
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 7df7038f6dd47..7a020d55abad2 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -492,6 +492,11 @@ bool TargetTransformInfo::isLegalMaskedGather(Type *DataType,
return TTIImpl->isLegalMaskedGather(DataType, Alignment);
}
+bool TargetTransformInfo::isLegalForHistogramVectorization(
+ const LoadInst *LI, const StoreInst *SI) const {
+ return TTIImpl->isLegalForHistogramVectorization(LI, SI);
+}
+
bool TargetTransformInfo::isLegalAltInstr(
VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
const SmallBitVector &OpcodeMask) const {
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 420cbc5384ce4..4045fd315d5bd 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1193,6 +1193,9 @@ bool LoopVectorizationLegality::canVectorizeIndirectUnsafeDependences() {
if (!LI || !SI)
return false;
+ if (!TTI->isLegalForHistogramVectorization(LI, SI))
+ return false;
+
LLVM_DEBUG(dbgs() << "LV: Checking for a histogram on: " << *SI << "\n");
return findHistogram(LI, SI, TheLoop, LAI->getPSE(), Histograms);
}
|
| return false; | ||
| } | ||
|
|
||
| bool isLegalForHistogramVectorization(const LoadInst *LI, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if you could add the load and store to the parameters in IntrinsicCostAttributes when asking for the cost of a histogram intrinsic, and return Invalid if the target doesn't support it instead of introducing a new method.
I guess this is a fast way of rejecting something in a different address space though, without going through the rest of the analysis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When investigating your approach, I realized that IntrinsicCostAttributes already contains the GEP pointer, which includes the address space information. By adjusting the cost (or simply marking it as invalid), I can control which histogram operations I'd like to support.
Thank you for the feedback!
I'll go ahead and close the PR.
Now, each target, depending on the load/store instruction, can indicate whether it is safe to vectorize histogram operations.
For example, this allows distinguishing between different pointer address spaces.