[llvm] VPlan: factor out VPUtils into its own file (NFC) (PR #105857)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 23 09:59:00 PDT 2024
https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/105857
None
>From f26eb4146f91ee2c6333052baac781f443452eb5 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Fri, 23 Aug 2024 17:36:00 +0100
Subject: [PATCH] VPlan: factor out VPUtils into its own file (NFC)
---
llvm/lib/Transforms/Vectorize/CMakeLists.txt | 1 +
.../Transforms/Vectorize/LoopVectorize.cpp | 1 +
llvm/lib/Transforms/Vectorize/VPUtils.cpp | 62 +++++++++++++++++++
llvm/lib/Transforms/Vectorize/VPUtils.h | 50 +++++++++++++++
llvm/lib/Transforms/Vectorize/VPlan.cpp | 48 +-------------
llvm/lib/Transforms/Vectorize/VPlan.h | 38 ------------
.../lib/Transforms/Vectorize/VPlanRecipes.cpp | 1 +
.../Transforms/Vectorize/VPlanTransforms.cpp | 1 +
8 files changed, 117 insertions(+), 85 deletions(-)
create mode 100644 llvm/lib/Transforms/Vectorize/VPUtils.cpp
create mode 100644 llvm/lib/Transforms/Vectorize/VPUtils.h
diff --git a/llvm/lib/Transforms/Vectorize/CMakeLists.txt b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
index 4caec07c5ac437..95a02e218e57fc 100644
--- a/llvm/lib/Transforms/Vectorize/CMakeLists.txt
+++ b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
@@ -13,6 +13,7 @@ add_llvm_component_library(LLVMVectorize
VPlanSLP.cpp
VPlanTransforms.cpp
VPlanVerifier.cpp
+ VPUtils.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index f3fb888f20cbbd..88237fbe7c8f11 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -56,6 +56,7 @@
#include "llvm/Transforms/Vectorize/LoopVectorize.h"
#include "LoopVectorizationPlanner.h"
#include "VPRecipeBuilder.h"
+#include "VPUtils.h"
#include "VPlan.h"
#include "VPlanAnalysis.h"
#include "VPlanHCFGBuilder.h"
diff --git a/llvm/lib/Transforms/Vectorize/VPUtils.cpp b/llvm/lib/Transforms/Vectorize/VPUtils.cpp
new file mode 100644
index 00000000000000..300d73a9ca9cdc
--- /dev/null
+++ b/llvm/lib/Transforms/Vectorize/VPUtils.cpp
@@ -0,0 +1,62 @@
+//===- VPUtils.cpp - VPlan-related utilities ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VPUtils.h"
+#include "VPlanPatternMatch.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+
+using namespace llvm;
+
+bool vputils::onlyFirstLaneUsed(const VPValue *Def) {
+ return all_of(Def->users(),
+ [Def](const VPUser *U) { return U->onlyFirstLaneUsed(Def); });
+}
+
+bool vputils::onlyFirstPartUsed(const VPValue *Def) {
+ return all_of(Def->users(),
+ [Def](const VPUser *U) { return U->onlyFirstPartUsed(Def); });
+}
+
+VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
+ ScalarEvolution &SE) {
+ if (auto *Expanded = Plan.getSCEVExpansion(Expr))
+ return Expanded;
+ VPValue *Expanded = nullptr;
+ if (auto *E = dyn_cast<SCEVConstant>(Expr))
+ Expanded = Plan.getOrAddLiveIn(E->getValue());
+ else if (auto *E = dyn_cast<SCEVUnknown>(Expr))
+ Expanded = Plan.getOrAddLiveIn(E->getValue());
+ else {
+ Expanded = new VPExpandSCEVRecipe(Expr, SE);
+ Plan.getPreheader()->appendRecipe(Expanded->getDefiningRecipe());
+ }
+ Plan.addSCEVExpansion(Expr, Expanded);
+ return Expanded;
+}
+
+bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) {
+ if (isa<VPActiveLaneMaskPHIRecipe>(V))
+ return true;
+
+ auto IsWideCanonicalIV = [](VPValue *A) {
+ return isa<VPWidenCanonicalIVRecipe>(A) ||
+ (isa<VPWidenIntOrFpInductionRecipe>(A) &&
+ cast<VPWidenIntOrFpInductionRecipe>(A)->isCanonical());
+ };
+
+ VPValue *A, *B;
+ using namespace VPlanPatternMatch;
+
+ if (match(V, m_ActiveLaneMask(m_VPValue(A), m_VPValue(B))))
+ return B == Plan.getTripCount() &&
+ (match(A, m_ScalarIVSteps(m_CanonicalIV(), m_SpecificInt(1))) ||
+ IsWideCanonicalIV(A));
+
+ return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) &&
+ IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount();
+}
diff --git a/llvm/lib/Transforms/Vectorize/VPUtils.h b/llvm/lib/Transforms/Vectorize/VPUtils.h
new file mode 100644
index 00000000000000..ec9af027034c8a
--- /dev/null
+++ b/llvm/lib/Transforms/Vectorize/VPUtils.h
@@ -0,0 +1,50 @@
+//===- VPUtils.h - Miscellanous VPlan-related utilities ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_VPUTILS_H
+#define LLVM_TRANSFORMS_VECTORIZE_VPUTILS_H
+
+#include "VPlan.h"
+
+namespace llvm::vputils {
+/// Returns true if only the first lane of \p Def is used.
+bool onlyFirstLaneUsed(const VPValue *Def);
+
+/// Returns true if only the first part of \p Def is used.
+bool onlyFirstPartUsed(const VPValue *Def);
+
+/// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
+/// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
+/// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
+/// pre-header already contains a recipe expanding \p Expr, return it. If not,
+/// create a new one.
+VPValue *getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
+ ScalarEvolution &SE);
+
+/// Returns true if \p VPV is uniform after vectorization.
+inline bool isUniformAfterVectorization(const VPValue *VPV) {
+ // A value defined outside the vector region must be uniform after
+ // vectorization inside a vector region.
+ if (VPV->isDefinedOutsideVectorRegions())
+ return true;
+ const VPRecipeBase *Def = VPV->getDefiningRecipe();
+ assert(Def && "Must have definition for value defined inside vector region");
+ if (auto *Rep = dyn_cast<VPReplicateRecipe>(Def))
+ return Rep->isUniform();
+ if (auto *GEP = dyn_cast<VPWidenGEPRecipe>(Def))
+ return all_of(GEP->operands(), isUniformAfterVectorization);
+ if (auto *VPI = dyn_cast<VPInstruction>(Def))
+ return VPI->isSingleScalar() || VPI->isVectorToScalar();
+ return false;
+}
+
+/// Return true if \p V is a header mask in \p Plan.
+bool isHeaderMask(const VPValue *V, VPlan &Plan);
+} // end namespace llvm::vputils
+
+#endif
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index f487b1de1e5b37..6ab0a95f502195 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -18,6 +18,7 @@
#include "VPlan.h"
#include "LoopVectorizationPlanner.h"
+#include "VPUtils.h"
#include "VPlanCFG.h"
#include "VPlanDominatorTree.h"
#include "VPlanPatternMatch.h"
@@ -1602,53 +1603,6 @@ std::string VPSlotTracker::getOrCreateName(const VPValue *V) const {
return "<badref>";
}
-bool vputils::onlyFirstLaneUsed(const VPValue *Def) {
- return all_of(Def->users(),
- [Def](const VPUser *U) { return U->onlyFirstLaneUsed(Def); });
-}
-
-bool vputils::onlyFirstPartUsed(const VPValue *Def) {
- return all_of(Def->users(),
- [Def](const VPUser *U) { return U->onlyFirstPartUsed(Def); });
-}
-
-VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
- ScalarEvolution &SE) {
- if (auto *Expanded = Plan.getSCEVExpansion(Expr))
- return Expanded;
- VPValue *Expanded = nullptr;
- if (auto *E = dyn_cast<SCEVConstant>(Expr))
- Expanded = Plan.getOrAddLiveIn(E->getValue());
- else if (auto *E = dyn_cast<SCEVUnknown>(Expr))
- Expanded = Plan.getOrAddLiveIn(E->getValue());
- else {
- Expanded = new VPExpandSCEVRecipe(Expr, SE);
- Plan.getPreheader()->appendRecipe(Expanded->getDefiningRecipe());
- }
- Plan.addSCEVExpansion(Expr, Expanded);
- return Expanded;
-}
-
-bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) {
- if (isa<VPActiveLaneMaskPHIRecipe>(V))
- return true;
-
- auto IsWideCanonicalIV = [](VPValue *A) {
- return isa<VPWidenCanonicalIVRecipe>(A) ||
- (isa<VPWidenIntOrFpInductionRecipe>(A) &&
- cast<VPWidenIntOrFpInductionRecipe>(A)->isCanonical());
- };
-
- VPValue *A, *B;
- if (match(V, m_ActiveLaneMask(m_VPValue(A), m_VPValue(B))))
- return B == Plan.getTripCount() &&
- (match(A, m_ScalarIVSteps(m_CanonicalIV(), m_SpecificInt(1))) ||
- IsWideCanonicalIV(A));
-
- return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) &&
- IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount();
-}
-
bool LoopVectorizationPlanner::getDecisionAndClampRange(
const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
assert(!Range.isEmpty() && "Trying to test an empty VF range.");
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 36a1aa08654d5b..e7ea5cb23b90d3 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -3803,44 +3803,6 @@ class VPlanSlp {
/// Return true if all visited instruction can be combined.
bool isCompletelySLP() const { return CompletelySLP; }
};
-
-namespace vputils {
-
-/// Returns true if only the first lane of \p Def is used.
-bool onlyFirstLaneUsed(const VPValue *Def);
-
-/// Returns true if only the first part of \p Def is used.
-bool onlyFirstPartUsed(const VPValue *Def);
-
-/// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
-/// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
-/// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
-/// pre-header already contains a recipe expanding \p Expr, return it. If not,
-/// create a new one.
-VPValue *getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
- ScalarEvolution &SE);
-
-/// Returns true if \p VPV is uniform after vectorization.
-inline bool isUniformAfterVectorization(const VPValue *VPV) {
- // A value defined outside the vector region must be uniform after
- // vectorization inside a vector region.
- if (VPV->isDefinedOutsideVectorRegions())
- return true;
- const VPRecipeBase *Def = VPV->getDefiningRecipe();
- assert(Def && "Must have definition for value defined inside vector region");
- if (auto Rep = dyn_cast<VPReplicateRecipe>(Def))
- return Rep->isUniform();
- if (auto *GEP = dyn_cast<VPWidenGEPRecipe>(Def))
- return all_of(GEP->operands(), isUniformAfterVectorization);
- if (auto *VPI = dyn_cast<VPInstruction>(Def))
- return VPI->isSingleScalar() || VPI->isVectorToScalar();
- return false;
-}
-
-/// Return true if \p V is a header mask in \p Plan.
-bool isHeaderMask(const VPValue *V, VPlan &Plan);
-} // end namespace vputils
-
} // end namespace llvm
#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index fe1325f4163004..86d73b913f50a3 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -11,6 +11,7 @@
///
//===----------------------------------------------------------------------===//
+#include "VPUtils.h"
#include "VPlan.h"
#include "VPlanAnalysis.h"
#include "llvm/ADT/STLExtras.h"
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 8deded031dc391..f3b2a79f3b43dd 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -13,6 +13,7 @@
#include "VPlanTransforms.h"
#include "VPRecipeBuilder.h"
+#include "VPUtils.h"
#include "VPlanAnalysis.h"
#include "VPlanCFG.h"
#include "VPlanDominatorTree.h"
More information about the llvm-commits
mailing list