Skip to content

Commit deec9e7

Browse files
committed
[VPlan] Move VPTransformState::get() to VPlan.cpp (NFC).
The last dependency of code defined in LoopVectorize.cpp has been removed a while ago. Move VPTransformState::get() to VPlan.cpp where other members are also defined.
1 parent 8cacabe commit deec9e7

File tree

2 files changed

+93
-92
lines changed

2 files changed

+93
-92
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -9830,98 +9830,6 @@ static ScalarEpilogueLowering getScalarEpilogueLowering(
98309830
return CM_ScalarEpilogueAllowed;
98319831
}
98329832

9833-
Value *VPTransformState::get(VPValue *Def, unsigned Part) {
9834-
// If Values have been set for this Def return the one relevant for \p Part.
9835-
if (hasVectorValue(Def, Part))
9836-
return Data.PerPartOutput[Def][Part];
9837-
9838-
auto GetBroadcastInstrs = [this, Def](Value *V) {
9839-
bool SafeToHoist = Def->isDefinedOutsideVectorRegions();
9840-
if (VF.isScalar())
9841-
return V;
9842-
// Place the code for broadcasting invariant variables in the new preheader.
9843-
IRBuilder<>::InsertPointGuard Guard(Builder);
9844-
if (SafeToHoist) {
9845-
BasicBlock *LoopVectorPreHeader = CFG.VPBB2IRBB[cast<VPBasicBlock>(
9846-
Plan->getVectorLoopRegion()->getSinglePredecessor())];
9847-
if (LoopVectorPreHeader)
9848-
Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
9849-
}
9850-
9851-
// Place the code for broadcasting invariant variables in the new preheader.
9852-
// Broadcast the scalar into all locations in the vector.
9853-
Value *Shuf = Builder.CreateVectorSplat(VF, V, "broadcast");
9854-
9855-
return Shuf;
9856-
};
9857-
9858-
if (!hasScalarValue(Def, {Part, 0})) {
9859-
assert(Def->isLiveIn() && "expected a live-in");
9860-
if (Part != 0)
9861-
return get(Def, 0);
9862-
Value *IRV = Def->getLiveInIRValue();
9863-
Value *B = GetBroadcastInstrs(IRV);
9864-
set(Def, B, Part);
9865-
return B;
9866-
}
9867-
9868-
Value *ScalarValue = get(Def, {Part, 0});
9869-
// If we aren't vectorizing, we can just copy the scalar map values over
9870-
// to the vector map.
9871-
if (VF.isScalar()) {
9872-
set(Def, ScalarValue, Part);
9873-
return ScalarValue;
9874-
}
9875-
9876-
bool IsUniform = vputils::isUniformAfterVectorization(Def);
9877-
9878-
unsigned LastLane = IsUniform ? 0 : VF.getKnownMinValue() - 1;
9879-
// Check if there is a scalar value for the selected lane.
9880-
if (!hasScalarValue(Def, {Part, LastLane})) {
9881-
// At the moment, VPWidenIntOrFpInductionRecipes, VPScalarIVStepsRecipes and
9882-
// VPExpandSCEVRecipes can also be uniform.
9883-
assert((isa<VPWidenIntOrFpInductionRecipe>(Def->getDefiningRecipe()) ||
9884-
isa<VPScalarIVStepsRecipe>(Def->getDefiningRecipe()) ||
9885-
isa<VPExpandSCEVRecipe>(Def->getDefiningRecipe())) &&
9886-
"unexpected recipe found to be invariant");
9887-
IsUniform = true;
9888-
LastLane = 0;
9889-
}
9890-
9891-
auto *LastInst = cast<Instruction>(get(Def, {Part, LastLane}));
9892-
// Set the insert point after the last scalarized instruction or after the
9893-
// last PHI, if LastInst is a PHI. This ensures the insertelement sequence
9894-
// will directly follow the scalar definitions.
9895-
auto OldIP = Builder.saveIP();
9896-
auto NewIP =
9897-
isa<PHINode>(LastInst)
9898-
? BasicBlock::iterator(LastInst->getParent()->getFirstNonPHI())
9899-
: std::next(BasicBlock::iterator(LastInst));
9900-
Builder.SetInsertPoint(&*NewIP);
9901-
9902-
// However, if we are vectorizing, we need to construct the vector values.
9903-
// If the value is known to be uniform after vectorization, we can just
9904-
// broadcast the scalar value corresponding to lane zero for each unroll
9905-
// iteration. Otherwise, we construct the vector values using
9906-
// insertelement instructions. Since the resulting vectors are stored in
9907-
// State, we will only generate the insertelements once.
9908-
Value *VectorValue = nullptr;
9909-
if (IsUniform) {
9910-
VectorValue = GetBroadcastInstrs(ScalarValue);
9911-
set(Def, VectorValue, Part);
9912-
} else {
9913-
// Initialize packing with insertelements to start from undef.
9914-
assert(!VF.isScalable() && "VF is assumed to be non scalable.");
9915-
Value *Undef = PoisonValue::get(VectorType::get(LastInst->getType(), VF));
9916-
set(Def, Undef, Part);
9917-
for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
9918-
packScalarIntoVectorValue(Def, {Part, Lane});
9919-
VectorValue = get(Def, Part);
9920-
}
9921-
Builder.restoreIP(OldIP);
9922-
return VectorValue;
9923-
}
9924-
99259833
// Process the loop in the VPlan-native vectorization path. This path builds
99269834
// VPlan upfront in the vectorization pipeline, which allows to apply
99279835
// VPlan-to-VPlan transformations from the very beginning without modifying the

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,99 @@ Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
234234
// set(Def, Extract, Instance);
235235
return Extract;
236236
}
237+
238+
Value *VPTransformState::get(VPValue *Def, unsigned Part) {
239+
// If Values have been set for this Def return the one relevant for \p Part.
240+
if (hasVectorValue(Def, Part))
241+
return Data.PerPartOutput[Def][Part];
242+
243+
auto GetBroadcastInstrs = [this, Def](Value *V) {
244+
bool SafeToHoist = Def->isDefinedOutsideVectorRegions();
245+
if (VF.isScalar())
246+
return V;
247+
// Place the code for broadcasting invariant variables in the new preheader.
248+
IRBuilder<>::InsertPointGuard Guard(Builder);
249+
if (SafeToHoist) {
250+
BasicBlock *LoopVectorPreHeader = CFG.VPBB2IRBB[cast<VPBasicBlock>(
251+
Plan->getVectorLoopRegion()->getSinglePredecessor())];
252+
if (LoopVectorPreHeader)
253+
Builder.SetInsertPoint(LoopVectorPreHeader->getTerminator());
254+
}
255+
256+
// Place the code for broadcasting invariant variables in the new preheader.
257+
// Broadcast the scalar into all locations in the vector.
258+
Value *Shuf = Builder.CreateVectorSplat(VF, V, "broadcast");
259+
260+
return Shuf;
261+
};
262+
263+
if (!hasScalarValue(Def, {Part, 0})) {
264+
assert(Def->isLiveIn() && "expected a live-in");
265+
if (Part != 0)
266+
return get(Def, 0);
267+
Value *IRV = Def->getLiveInIRValue();
268+
Value *B = GetBroadcastInstrs(IRV);
269+
set(Def, B, Part);
270+
return B;
271+
}
272+
273+
Value *ScalarValue = get(Def, {Part, 0});
274+
// If we aren't vectorizing, we can just copy the scalar map values over
275+
// to the vector map.
276+
if (VF.isScalar()) {
277+
set(Def, ScalarValue, Part);
278+
return ScalarValue;
279+
}
280+
281+
bool IsUniform = vputils::isUniformAfterVectorization(Def);
282+
283+
unsigned LastLane = IsUniform ? 0 : VF.getKnownMinValue() - 1;
284+
// Check if there is a scalar value for the selected lane.
285+
if (!hasScalarValue(Def, {Part, LastLane})) {
286+
// At the moment, VPWidenIntOrFpInductionRecipes, VPScalarIVStepsRecipes and
287+
// VPExpandSCEVRecipes can also be uniform.
288+
assert((isa<VPWidenIntOrFpInductionRecipe>(Def->getDefiningRecipe()) ||
289+
isa<VPScalarIVStepsRecipe>(Def->getDefiningRecipe()) ||
290+
isa<VPExpandSCEVRecipe>(Def->getDefiningRecipe())) &&
291+
"unexpected recipe found to be invariant");
292+
IsUniform = true;
293+
LastLane = 0;
294+
}
295+
296+
auto *LastInst = cast<Instruction>(get(Def, {Part, LastLane}));
297+
// Set the insert point after the last scalarized instruction or after the
298+
// last PHI, if LastInst is a PHI. This ensures the insertelement sequence
299+
// will directly follow the scalar definitions.
300+
auto OldIP = Builder.saveIP();
301+
auto NewIP =
302+
isa<PHINode>(LastInst)
303+
? BasicBlock::iterator(LastInst->getParent()->getFirstNonPHI())
304+
: std::next(BasicBlock::iterator(LastInst));
305+
Builder.SetInsertPoint(&*NewIP);
306+
307+
// However, if we are vectorizing, we need to construct the vector values.
308+
// If the value is known to be uniform after vectorization, we can just
309+
// broadcast the scalar value corresponding to lane zero for each unroll
310+
// iteration. Otherwise, we construct the vector values using
311+
// insertelement instructions. Since the resulting vectors are stored in
312+
// State, we will only generate the insertelements once.
313+
Value *VectorValue = nullptr;
314+
if (IsUniform) {
315+
VectorValue = GetBroadcastInstrs(ScalarValue);
316+
set(Def, VectorValue, Part);
317+
} else {
318+
// Initialize packing with insertelements to start from undef.
319+
assert(!VF.isScalable() && "VF is assumed to be non scalable.");
320+
Value *Undef = PoisonValue::get(VectorType::get(LastInst->getType(), VF));
321+
set(Def, Undef, Part);
322+
for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
323+
packScalarIntoVectorValue(Def, {Part, Lane});
324+
VectorValue = get(Def, Part);
325+
}
326+
Builder.restoreIP(OldIP);
327+
return VectorValue;
328+
}
329+
237330
BasicBlock *VPTransformState::CFGState::getPreheaderBBFor(VPRecipeBase *R) {
238331
VPRegionBlock *LoopRegion = R->getParent()->getEnclosingLoopRegion();
239332
return VPBB2IRBB[LoopRegion->getPreheaderVPBB()];

0 commit comments

Comments
 (0)