Skip to content

Commit f44a8bd

Browse files
committed
[VPlan] Introduce cannotHoistOrSinkRecipe
Factor out common code to determine legality of hoisting and sinking. In the case of the additonal use-sites, functional changes, if any, would amount to esoteric bugs being fixed.
1 parent 8a232dc commit f44a8bd

File tree

2 files changed

+26
-27
lines changed

2 files changed

+26
-27
lines changed

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ bool VPRecipeBase::mayWriteToMemory() const {
7070
return cast<VPWidenIntrinsicRecipe>(this)->mayWriteToMemory();
7171
case VPCanonicalIVPHISC:
7272
case VPBranchOnMaskSC:
73+
case VPDerivedIVSC:
7374
case VPFirstOrderRecurrencePHISC:
7475
case VPReductionPHISC:
7576
case VPScalarIVStepsSC:
@@ -86,6 +87,7 @@ bool VPRecipeBase::mayWriteToMemory() const {
8687
case VPWidenLoadEVLSC:
8788
case VPWidenLoadSC:
8889
case VPWidenPHISC:
90+
case VPWidenPointerInductionSC:
8991
case VPWidenSC:
9092
case VPWidenSelectSC: {
9193
const Instruction *I =
@@ -119,6 +121,7 @@ bool VPRecipeBase::mayReadFromMemory() const {
119121
case VPWidenIntrinsicSC:
120122
return cast<VPWidenIntrinsicRecipe>(this)->mayReadFromMemory();
121123
case VPBranchOnMaskSC:
124+
case VPDerivedIVSC:
122125
case VPFirstOrderRecurrencePHISC:
123126
case VPPredInstPHISC:
124127
case VPScalarIVStepsSC:
@@ -134,6 +137,7 @@ bool VPRecipeBase::mayReadFromMemory() const {
134137
case VPWidenGEPSC:
135138
case VPWidenIntOrFpInductionSC:
136139
case VPWidenPHISC:
140+
case VPWidenPointerInductionSC:
137141
case VPWidenSC:
138142
case VPWidenSelectSC: {
139143
const Instruction *I =

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,24 @@ bool VPlanTransforms::tryToConvertVPInstructionsToVPRecipes(
130130
return true;
131131
}
132132

133+
/// Return true if we do not know how to (mechanically) hoist or sink \p R out
134+
/// of a loop region.
135+
static bool cannotHoistOrSinkRecipe(const VPRecipeBase &R) {
136+
// Assumes don't alias anything or throw; as long as they're guaranteed to
137+
// execute, they're safe to hoist.
138+
if (match(&R, m_Intrinsic<Intrinsic::assume>()))
139+
return false;
140+
141+
// TODO: Relax checks in the future, e.g. we could also hoist reads, if their
142+
// memory location is not modified in the vector loop.
143+
if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
144+
return true;
145+
146+
// Allocas cannot be hoisted.
147+
auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
148+
return RepR && RepR->getOpcode() == Instruction::Alloca;
149+
}
150+
133151
static bool sinkScalarOperands(VPlan &Plan) {
134152
auto Iter = vp_depth_first_deep(Plan.getEntry());
135153
bool Changed = false;
@@ -1789,7 +1807,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
17891807
VPDT.properlyDominates(Previous, SinkCandidate))
17901808
return true;
17911809

1792-
if (SinkCandidate->mayHaveSideEffects())
1810+
if (cannotHoistOrSinkRecipe(*SinkCandidate))
17931811
return false;
17941812

17951813
WorkList.push_back(SinkCandidate);
@@ -1829,7 +1847,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
18291847
static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18301848
VPRecipeBase *Previous,
18311849
VPDominatorTree &VPDT) {
1832-
if (Previous->mayHaveSideEffects() || Previous->mayReadFromMemory())
1850+
if (cannotHoistOrSinkRecipe(*Previous))
18331851
return false;
18341852

18351853
// Collect recipes that need hoisting.
@@ -1876,11 +1894,6 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18761894
return nullptr;
18771895
return HoistCandidate;
18781896
};
1879-
auto CanHoist = [&](VPRecipeBase *HoistCandidate) {
1880-
// Avoid hoisting candidates with side-effects, as we do not yet analyze
1881-
// associated dependencies.
1882-
return !HoistCandidate->mayHaveSideEffects();
1883-
};
18841897

18851898
if (!NeedsHoisting(Previous->getVPSingleValue()))
18861899
return true;
@@ -1892,7 +1905,7 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18921905
VPRecipeBase *Current = HoistCandidates[I];
18931906
assert(Current->getNumDefinedValues() == 1 &&
18941907
"only recipes with a single defined value expected");
1895-
if (!CanHoist(Current))
1908+
if (cannotHoistOrSinkRecipe(*Current))
18961909
return false;
18971910

18981911
for (VPValue *Op : Current->operands()) {
@@ -2121,24 +2134,6 @@ void VPlanTransforms::cse(VPlan &Plan) {
21212134
static void licm(VPlan &Plan) {
21222135
VPBasicBlock *Preheader = Plan.getVectorPreheader();
21232136

2124-
// Return true if we do not know how to (mechanically) hoist a given recipe
2125-
// out of a loop region.
2126-
auto CannotHoistRecipe = [](VPRecipeBase &R) {
2127-
// Assumes don't alias anything or throw; as long as they're guaranteed to
2128-
// execute, they're safe to hoist.
2129-
if (match(&R, m_Intrinsic<Intrinsic::assume>()))
2130-
return false;
2131-
2132-
// TODO: Relax checks in the future, e.g. we could also hoist reads, if
2133-
// their memory location is not modified in the vector loop.
2134-
if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
2135-
return true;
2136-
2137-
// Allocas cannot be hoisted.
2138-
auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
2139-
return RepR && RepR->getOpcode() == Instruction::Alloca;
2140-
};
2141-
21422137
// Hoist any loop invariant recipes from the vector loop region to the
21432138
// preheader. Preform a shallow traversal of the vector loop region, to
21442139
// exclude recipes in replicate regions. Since the top-level blocks in the
@@ -2150,7 +2145,7 @@ static void licm(VPlan &Plan) {
21502145
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
21512146
vp_depth_first_shallow(LoopRegion->getEntry()))) {
21522147
for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
2153-
if (CannotHoistRecipe(R))
2148+
if (cannotHoistOrSinkRecipe(R))
21542149
continue;
21552150
if (any_of(R.operands(), [](VPValue *Op) {
21562151
return !Op->isDefinedOutsideLoopRegions();

0 commit comments

Comments
 (0)