Skip to content

Commit 3201274

Browse files
committed
[VPlan] Handle scalarized values in VPTransformState.
This patch adds plumbing to handle scalarized values directly in VPTransformState. Reviewed By: gilr Differential Revision: https://reviews.llvm.org/D92282
1 parent 05d5125 commit 3201274

File tree

3 files changed

+64
-23
lines changed

3 files changed

+64
-23
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7718,9 +7718,15 @@ void LoopVectorizationPlanner::executePlan(InnerLoopVectorizer &ILV,
77187718

77197719
assert(BestVF.hasValue() && "Vectorization Factor is missing");
77207720

7721-
VPTransformState State{*BestVF, BestUF, LI,
7722-
DT, ILV.Builder, ILV.VectorLoopValueMap,
7723-
&ILV, CallbackILV};
7721+
VPTransformState State{*BestVF,
7722+
BestUF,
7723+
OrigLoop,
7724+
LI,
7725+
DT,
7726+
ILV.Builder,
7727+
ILV.VectorLoopValueMap,
7728+
&ILV,
7729+
CallbackILV};
77247730
State.CFG.PrevBB = ILV.createVectorizedLoopSkeleton();
77257731
State.TripCount = ILV.getOrCreateTripCount(nullptr);
77267732
State.CanonicalIV = ILV.Induction;

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,27 @@ VPBasicBlock::iterator VPBasicBlock::getFirstNonPhi() {
216216
return It;
217217
}
218218

219+
Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
220+
if (!Def->getDef() && OrigLoop->isLoopInvariant(Def->getLiveInIRValue()))
221+
return Def->getLiveInIRValue();
222+
223+
if (hasScalarValue(Def, Instance))
224+
return Data.PerPartScalars[Def][Instance.Part][Instance.Lane];
225+
226+
if (hasVectorValue(Def, Instance.Part)) {
227+
assert(Data.PerPartOutput.count(Def));
228+
auto *VecPart = Data.PerPartOutput[Def][Instance.Part];
229+
if (!VecPart->getType()->isVectorTy()) {
230+
assert(Instance.Lane == 0 && "cannot get lane > 0 for scalar");
231+
return VecPart;
232+
}
233+
// TODO: Cache created scalar values.
234+
return Builder.CreateExtractElement(VecPart,
235+
Builder.getInt32(Instance.Lane));
236+
}
237+
return Callback.getOrCreateScalarValue(VPValue2Value[Def], Instance);
238+
}
239+
219240
BasicBlock *
220241
VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
221242
// BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,12 @@ struct VPCallback {
246246
/// VPTransformState holds information passed down when "executing" a VPlan,
247247
/// needed for generating the output IR.
248248
struct VPTransformState {
249-
VPTransformState(ElementCount VF, unsigned UF, LoopInfo *LI,
249+
VPTransformState(ElementCount VF, unsigned UF, Loop *OrigLoop, LoopInfo *LI,
250250
DominatorTree *DT, IRBuilder<> &Builder,
251251
VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV,
252252
VPCallback &Callback)
253-
: VF(VF), UF(UF), Instance(), LI(LI), DT(DT), Builder(Builder),
254-
ValueMap(ValueMap), ILV(ILV), Callback(Callback) {}
253+
: VF(VF), UF(UF), Instance(), OrigLoop(OrigLoop), LI(LI), DT(DT),
254+
Builder(Builder), ValueMap(ValueMap), ILV(ILV), Callback(Callback) {}
255255

256256
/// The chosen Vectorization and Unroll Factors of the loop being vectorized.
257257
ElementCount VF;
@@ -269,6 +269,9 @@ struct VPTransformState {
269269
typedef SmallVector<Value *, 2> PerPartValuesTy;
270270

271271
DenseMap<VPValue *, PerPartValuesTy> PerPartOutput;
272+
273+
using ScalarsPerPartValuesTy = SmallVector<SmallVector<Value *, 4>, 2>;
274+
DenseMap<VPValue *, ScalarsPerPartValuesTy> PerPartScalars;
272275
} Data;
273276

274277
/// Get the generated Value for a given VPValue and a given Part. Note that
@@ -285,24 +288,21 @@ struct VPTransformState {
285288
}
286289

287290
/// Get the generated Value for a given VPValue and given Part and Lane.
288-
Value *get(VPValue *Def, const VPIteration &Instance) {
289-
// If the Def is managed directly by VPTransformState, extract the lane from
290-
// the relevant part. Note that currently only VPInstructions and external
291-
// defs are managed by VPTransformState. Other Defs are still created by ILV
292-
// and managed in its ValueMap. For those this method currently just
293-
// delegates the call to ILV below.
294-
if (Data.PerPartOutput.count(Def)) {
295-
auto *VecPart = Data.PerPartOutput[Def][Instance.Part];
296-
if (!VecPart->getType()->isVectorTy()) {
297-
assert(Instance.Lane == 0 && "cannot get lane > 0 for scalar");
298-
return VecPart;
299-
}
300-
// TODO: Cache created scalar values.
301-
return Builder.CreateExtractElement(VecPart,
302-
Builder.getInt32(Instance.Lane));
303-
}
291+
Value *get(VPValue *Def, const VPIteration &Instance);
304292

305-
return Callback.getOrCreateScalarValue(VPValue2Value[Def], Instance);
293+
bool hasVectorValue(VPValue *Def, unsigned Part) {
294+
auto I = Data.PerPartOutput.find(Def);
295+
return I != Data.PerPartOutput.end() && Part < I->second.size() &&
296+
I->second[Part];
297+
}
298+
299+
bool hasScalarValue(VPValue *Def, VPIteration Instance) {
300+
auto I = Data.PerPartScalars.find(Def);
301+
if (I == Data.PerPartScalars.end())
302+
return false;
303+
return Instance.Part < I->second.size() &&
304+
Instance.Lane < I->second[Instance.Part].size() &&
305+
I->second[Instance.Part][Instance.Lane];
306306
}
307307

308308
/// Set the generated Value for a given VPValue and a given Part.
@@ -315,6 +315,17 @@ struct VPTransformState {
315315
}
316316
void set(VPValue *Def, Value *IRDef, Value *V, unsigned Part);
317317

318+
void set(VPValue *Def, Value *V, const VPIteration &Instance) {
319+
auto Iter = Data.PerPartScalars.insert({Def, {}});
320+
auto &PerPartVec = Iter.first->second;
321+
while (PerPartVec.size() <= Instance.Part)
322+
PerPartVec.emplace_back();
323+
auto &Scalars = PerPartVec[Instance.Part];
324+
while (Scalars.size() <= Instance.Lane)
325+
Scalars.push_back(nullptr);
326+
Scalars[Instance.Lane] = V;
327+
}
328+
318329
/// Hold state information used when constructing the CFG of the output IR,
319330
/// traversing the VPBasicBlocks and generating corresponding IR BasicBlocks.
320331
struct CFGState {
@@ -340,6 +351,9 @@ struct VPTransformState {
340351
CFGState() = default;
341352
} CFG;
342353

354+
/// Hold a pointer to the original loop.
355+
Loop *OrigLoop;
356+
343357
/// Hold a pointer to LoopInfo to register new basic blocks in the loop.
344358
LoopInfo *LI;
345359

0 commit comments

Comments
 (0)