Skip to content

Commit 71ede8d

Browse files
authored
VPlan: factor out VPlanUtils into its own file (NFC) (#105857)
1 parent f4e7e5d commit 71ede8d

File tree

8 files changed

+117
-85
lines changed

8 files changed

+117
-85
lines changed

llvm/lib/Transforms/Vectorize/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_llvm_component_library(LLVMVectorize
1313
VPlanSLP.cpp
1414
VPlanTransforms.cpp
1515
VPlanVerifier.cpp
16+
VPlanUtils.cpp
1617

1718
ADDITIONAL_HEADER_DIRS
1819
${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "VPlanHCFGBuilder.h"
6262
#include "VPlanPatternMatch.h"
6363
#include "VPlanTransforms.h"
64+
#include "VPlanUtils.h"
6465
#include "VPlanVerifier.h"
6566
#include "llvm/ADT/APInt.h"
6667
#include "llvm/ADT/ArrayRef.h"

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "VPlanDominatorTree.h"
2323
#include "VPlanPatternMatch.h"
2424
#include "VPlanTransforms.h"
25+
#include "VPlanUtils.h"
2526
#include "llvm/ADT/PostOrderIterator.h"
2627
#include "llvm/ADT/STLExtras.h"
2728
#include "llvm/ADT/SmallVector.h"
@@ -1602,53 +1603,6 @@ std::string VPSlotTracker::getOrCreateName(const VPValue *V) const {
16021603
return "<badref>";
16031604
}
16041605

1605-
bool vputils::onlyFirstLaneUsed(const VPValue *Def) {
1606-
return all_of(Def->users(),
1607-
[Def](const VPUser *U) { return U->onlyFirstLaneUsed(Def); });
1608-
}
1609-
1610-
bool vputils::onlyFirstPartUsed(const VPValue *Def) {
1611-
return all_of(Def->users(),
1612-
[Def](const VPUser *U) { return U->onlyFirstPartUsed(Def); });
1613-
}
1614-
1615-
VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
1616-
ScalarEvolution &SE) {
1617-
if (auto *Expanded = Plan.getSCEVExpansion(Expr))
1618-
return Expanded;
1619-
VPValue *Expanded = nullptr;
1620-
if (auto *E = dyn_cast<SCEVConstant>(Expr))
1621-
Expanded = Plan.getOrAddLiveIn(E->getValue());
1622-
else if (auto *E = dyn_cast<SCEVUnknown>(Expr))
1623-
Expanded = Plan.getOrAddLiveIn(E->getValue());
1624-
else {
1625-
Expanded = new VPExpandSCEVRecipe(Expr, SE);
1626-
Plan.getPreheader()->appendRecipe(Expanded->getDefiningRecipe());
1627-
}
1628-
Plan.addSCEVExpansion(Expr, Expanded);
1629-
return Expanded;
1630-
}
1631-
1632-
bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) {
1633-
if (isa<VPActiveLaneMaskPHIRecipe>(V))
1634-
return true;
1635-
1636-
auto IsWideCanonicalIV = [](VPValue *A) {
1637-
return isa<VPWidenCanonicalIVRecipe>(A) ||
1638-
(isa<VPWidenIntOrFpInductionRecipe>(A) &&
1639-
cast<VPWidenIntOrFpInductionRecipe>(A)->isCanonical());
1640-
};
1641-
1642-
VPValue *A, *B;
1643-
if (match(V, m_ActiveLaneMask(m_VPValue(A), m_VPValue(B))))
1644-
return B == Plan.getTripCount() &&
1645-
(match(A, m_ScalarIVSteps(m_CanonicalIV(), m_SpecificInt(1))) ||
1646-
IsWideCanonicalIV(A));
1647-
1648-
return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) &&
1649-
IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount();
1650-
}
1651-
16521606
bool LoopVectorizationPlanner::getDecisionAndClampRange(
16531607
const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
16541608
assert(!Range.isEmpty() && "Trying to test an empty VF range.");

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3803,44 +3803,6 @@ class VPlanSlp {
38033803
/// Return true if all visited instruction can be combined.
38043804
bool isCompletelySLP() const { return CompletelySLP; }
38053805
};
3806-
3807-
namespace vputils {
3808-
3809-
/// Returns true if only the first lane of \p Def is used.
3810-
bool onlyFirstLaneUsed(const VPValue *Def);
3811-
3812-
/// Returns true if only the first part of \p Def is used.
3813-
bool onlyFirstPartUsed(const VPValue *Def);
3814-
3815-
/// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
3816-
/// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
3817-
/// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
3818-
/// pre-header already contains a recipe expanding \p Expr, return it. If not,
3819-
/// create a new one.
3820-
VPValue *getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
3821-
ScalarEvolution &SE);
3822-
3823-
/// Returns true if \p VPV is uniform after vectorization.
3824-
inline bool isUniformAfterVectorization(const VPValue *VPV) {
3825-
// A value defined outside the vector region must be uniform after
3826-
// vectorization inside a vector region.
3827-
if (VPV->isDefinedOutsideVectorRegions())
3828-
return true;
3829-
const VPRecipeBase *Def = VPV->getDefiningRecipe();
3830-
assert(Def && "Must have definition for value defined inside vector region");
3831-
if (auto Rep = dyn_cast<VPReplicateRecipe>(Def))
3832-
return Rep->isUniform();
3833-
if (auto *GEP = dyn_cast<VPWidenGEPRecipe>(Def))
3834-
return all_of(GEP->operands(), isUniformAfterVectorization);
3835-
if (auto *VPI = dyn_cast<VPInstruction>(Def))
3836-
return VPI->isSingleScalar() || VPI->isVectorToScalar();
3837-
return false;
3838-
}
3839-
3840-
/// Return true if \p V is a header mask in \p Plan.
3841-
bool isHeaderMask(const VPValue *V, VPlan &Plan);
3842-
} // end namespace vputils
3843-
38443806
} // end namespace llvm
38453807

38463808
#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "VPlan.h"
1515
#include "VPlanAnalysis.h"
16+
#include "VPlanUtils.h"
1617
#include "llvm/ADT/STLExtras.h"
1718
#include "llvm/ADT/SmallVector.h"
1819
#include "llvm/ADT/Twine.h"

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "VPlanCFG.h"
1818
#include "VPlanDominatorTree.h"
1919
#include "VPlanPatternMatch.h"
20+
#include "VPlanUtils.h"
2021
#include "llvm/ADT/PostOrderIterator.h"
2122
#include "llvm/ADT/STLExtras.h"
2223
#include "llvm/ADT/SetVector.h"
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===- VPlanUtils.cpp - VPlan-related utilities ---------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "VPlanUtils.h"
10+
#include "VPlanPatternMatch.h"
11+
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
12+
13+
using namespace llvm;
14+
15+
bool vputils::onlyFirstLaneUsed(const VPValue *Def) {
16+
return all_of(Def->users(),
17+
[Def](const VPUser *U) { return U->onlyFirstLaneUsed(Def); });
18+
}
19+
20+
bool vputils::onlyFirstPartUsed(const VPValue *Def) {
21+
return all_of(Def->users(),
22+
[Def](const VPUser *U) { return U->onlyFirstPartUsed(Def); });
23+
}
24+
25+
VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
26+
ScalarEvolution &SE) {
27+
if (auto *Expanded = Plan.getSCEVExpansion(Expr))
28+
return Expanded;
29+
VPValue *Expanded = nullptr;
30+
if (auto *E = dyn_cast<SCEVConstant>(Expr))
31+
Expanded = Plan.getOrAddLiveIn(E->getValue());
32+
else if (auto *E = dyn_cast<SCEVUnknown>(Expr))
33+
Expanded = Plan.getOrAddLiveIn(E->getValue());
34+
else {
35+
Expanded = new VPExpandSCEVRecipe(Expr, SE);
36+
Plan.getPreheader()->appendRecipe(Expanded->getDefiningRecipe());
37+
}
38+
Plan.addSCEVExpansion(Expr, Expanded);
39+
return Expanded;
40+
}
41+
42+
bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) {
43+
if (isa<VPActiveLaneMaskPHIRecipe>(V))
44+
return true;
45+
46+
auto IsWideCanonicalIV = [](VPValue *A) {
47+
return isa<VPWidenCanonicalIVRecipe>(A) ||
48+
(isa<VPWidenIntOrFpInductionRecipe>(A) &&
49+
cast<VPWidenIntOrFpInductionRecipe>(A)->isCanonical());
50+
};
51+
52+
VPValue *A, *B;
53+
using namespace VPlanPatternMatch;
54+
55+
if (match(V, m_ActiveLaneMask(m_VPValue(A), m_VPValue(B))))
56+
return B == Plan.getTripCount() &&
57+
(match(A, m_ScalarIVSteps(m_CanonicalIV(), m_SpecificInt(1))) ||
58+
IsWideCanonicalIV(A));
59+
60+
return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) &&
61+
IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount();
62+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===- VPlanUtils.h - VPlan-related utilities -------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
10+
#define LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
11+
12+
#include "VPlan.h"
13+
14+
namespace llvm::vputils {
15+
/// Returns true if only the first lane of \p Def is used.
16+
bool onlyFirstLaneUsed(const VPValue *Def);
17+
18+
/// Returns true if only the first part of \p Def is used.
19+
bool onlyFirstPartUsed(const VPValue *Def);
20+
21+
/// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
22+
/// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
23+
/// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
24+
/// pre-header already contains a recipe expanding \p Expr, return it. If not,
25+
/// create a new one.
26+
VPValue *getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
27+
ScalarEvolution &SE);
28+
29+
/// Returns true if \p VPV is uniform after vectorization.
30+
inline bool isUniformAfterVectorization(const VPValue *VPV) {
31+
// A value defined outside the vector region must be uniform after
32+
// vectorization inside a vector region.
33+
if (VPV->isDefinedOutsideVectorRegions())
34+
return true;
35+
const VPRecipeBase *Def = VPV->getDefiningRecipe();
36+
assert(Def && "Must have definition for value defined inside vector region");
37+
if (auto *Rep = dyn_cast<VPReplicateRecipe>(Def))
38+
return Rep->isUniform();
39+
if (auto *GEP = dyn_cast<VPWidenGEPRecipe>(Def))
40+
return all_of(GEP->operands(), isUniformAfterVectorization);
41+
if (auto *VPI = dyn_cast<VPInstruction>(Def))
42+
return VPI->isSingleScalar() || VPI->isVectorToScalar();
43+
return false;
44+
}
45+
46+
/// Return true if \p V is a header mask in \p Plan.
47+
bool isHeaderMask(const VPValue *V, VPlan &Plan);
48+
} // end namespace llvm::vputils
49+
50+
#endif

0 commit comments

Comments
 (0)