Skip to content

Commit 1398559

Browse files
authored
Merge 038664c into 8a5f153
2 parents 8a5f153 + 038664c commit 1398559

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -132,59 +132,65 @@ bool VPlanTransforms::tryToConvertVPInstructionsToVPRecipes(
132132

133133
static bool sinkScalarOperands(VPlan &Plan) {
134134
auto Iter = vp_depth_first_deep(Plan.getEntry());
135+
bool ScalarVFOnly = Plan.hasScalarVFOnly();
135136
bool Changed = false;
137+
138+
auto IsValidSinkCandidate = [ScalarVFOnly](VPBasicBlock *SinkTo,
139+
VPSingleDefRecipe *Candidate) {
140+
// We only know how to duplicate VPReplicateRecipes and
141+
// VPScalarIVStepsRecipes for now.
142+
if (!isa<VPReplicateRecipe, VPScalarIVStepsRecipe>(Candidate))
143+
return false;
144+
145+
if (Candidate->getParent() == SinkTo || Candidate->mayHaveSideEffects() ||
146+
Candidate->mayReadOrWriteMemory())
147+
return false;
148+
149+
if (auto *RepR = dyn_cast<VPReplicateRecipe>(Candidate))
150+
if (!ScalarVFOnly && RepR->isSingleScalar())
151+
return false;
152+
153+
return true;
154+
};
155+
136156
// First, collect the operands of all recipes in replicate blocks as seeds for
137157
// sinking.
138158
SetVector<std::pair<VPBasicBlock *, VPSingleDefRecipe *>> WorkList;
139159
for (VPRegionBlock *VPR : VPBlockUtils::blocksOnly<VPRegionBlock>(Iter)) {
140160
VPBasicBlock *EntryVPBB = VPR->getEntryBasicBlock();
141161
if (!VPR->isReplicator() || EntryVPBB->getSuccessors().size() != 2)
142162
continue;
143-
VPBasicBlock *VPBB = dyn_cast<VPBasicBlock>(EntryVPBB->getSuccessors()[0]);
144-
if (!VPBB || VPBB->getSingleSuccessor() != VPR->getExitingBasicBlock())
163+
VPBasicBlock *VPBB = cast<VPBasicBlock>(EntryVPBB->getSuccessors().front());
164+
if (VPBB->getSingleSuccessor() != VPR->getExitingBasicBlock())
145165
continue;
146166
for (auto &Recipe : *VPBB) {
147-
for (VPValue *Op : Recipe.operands())
167+
for (VPValue *Op : Recipe.operands()) {
148168
if (auto *Def =
149169
dyn_cast_or_null<VPSingleDefRecipe>(Op->getDefiningRecipe()))
150-
WorkList.insert({VPBB, Def});
170+
if (IsValidSinkCandidate(VPBB, Def))
171+
WorkList.insert({VPBB, Def});
172+
}
151173
}
152174
}
153175

154-
bool ScalarVFOnly = Plan.hasScalarVFOnly();
155176
// Try to sink each replicate or scalar IV steps recipe in the worklist.
156177
for (unsigned I = 0; I != WorkList.size(); ++I) {
157178
VPBasicBlock *SinkTo;
158179
VPSingleDefRecipe *SinkCandidate;
159180
std::tie(SinkTo, SinkCandidate) = WorkList[I];
160-
if (SinkCandidate->getParent() == SinkTo ||
161-
SinkCandidate->mayHaveSideEffects() ||
162-
SinkCandidate->mayReadOrWriteMemory())
163-
continue;
164-
if (auto *RepR = dyn_cast<VPReplicateRecipe>(SinkCandidate)) {
165-
if (!ScalarVFOnly && RepR->isSingleScalar())
166-
continue;
167-
} else if (!isa<VPScalarIVStepsRecipe>(SinkCandidate))
168-
continue;
169181

170-
bool NeedsDuplicating = false;
171182
// All recipe users of the sink candidate must be in the same block SinkTo
172-
// or all users outside of SinkTo must be uniform-after-vectorization (
173-
// i.e., only first lane is used) . In the latter case, we need to duplicate
174-
// SinkCandidate.
175-
auto CanSinkWithUser = [SinkTo, &NeedsDuplicating,
176-
SinkCandidate](VPUser *U) {
177-
auto *UI = cast<VPRecipeBase>(U);
178-
if (UI->getParent() == SinkTo)
179-
return true;
180-
NeedsDuplicating = UI->onlyFirstLaneUsed(SinkCandidate);
181-
// We only know how to duplicate VPReplicateRecipes and
182-
// VPScalarIVStepsRecipes for now.
183-
return NeedsDuplicating &&
184-
isa<VPReplicateRecipe, VPScalarIVStepsRecipe>(SinkCandidate);
185-
};
186-
if (!all_of(SinkCandidate->users(), CanSinkWithUser))
183+
// or all users outside of SinkTo must have only their first lane used. In
184+
// the latter case, we need to duplicate SinkCandidate.
185+
auto UsersOutsideSinkTo =
186+
make_filter_range(SinkCandidate->users(), [SinkTo](VPUser *U) {
187+
return cast<VPRecipeBase>(U)->getParent() != SinkTo;
188+
});
189+
if (any_of(UsersOutsideSinkTo, [SinkCandidate](VPUser *U) {
190+
return !U->onlyFirstLaneUsed(SinkCandidate);
191+
}))
187192
continue;
193+
bool NeedsDuplicating = !UsersOutsideSinkTo.empty();
188194

189195
if (NeedsDuplicating) {
190196
if (ScalarVFOnly)
@@ -211,7 +217,8 @@ static bool sinkScalarOperands(VPlan &Plan) {
211217
for (VPValue *Op : SinkCandidate->operands())
212218
if (auto *Def =
213219
dyn_cast_or_null<VPSingleDefRecipe>(Op->getDefiningRecipe()))
214-
WorkList.insert({SinkTo, Def});
220+
if (IsValidSinkCandidate(SinkTo, Def))
221+
WorkList.insert({SinkTo, Def});
215222
Changed = true;
216223
}
217224
return Changed;

0 commit comments

Comments
 (0)