1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[VPlan][NFC] Introduce constructors for VPIteration

This patch adds constructors to VPIteration as a cleaner way of
initialising the struct and replaces existing constructions of
the form:

  {Part, Lane}

with

  VPIteration(Part, Lane)

I have also added a default constructor, which is used by VPlan.cpp
when deciding whether to replicate a block or not.

This refactoring will be required in a later patch that adds more
members and functions to VPIteration.

Differential Revision: https://reviews.llvm.org/D95676
This commit is contained in:
David Sherwood 2021-01-29 11:46:41 +00:00
parent a49cc783f7
commit 9ead40bd43
3 changed files with 32 additions and 23 deletions

View File

@ -2140,7 +2140,8 @@ void InnerLoopVectorizer::recordVectorLoopValueForInductionCast(
// induction update chain itself.
Instruction *CastInst = *Casts.begin();
if (Lane < UINT_MAX)
VectorLoopValueMap.setScalarValue(CastInst, {Part, Lane}, VectorLoopVal);
VectorLoopValueMap.setScalarValue(CastInst, VPIteration(Part, Lane),
VectorLoopVal);
else
VectorLoopValueMap.setVectorValue(CastInst, Part, VectorLoopVal);
}
@ -2360,7 +2361,7 @@ void InnerLoopVectorizer::buildScalarSteps(Value *ScalarIV, Value *Step,
"scalable");
auto *Mul = addFastMathFlag(Builder.CreateBinOp(MulOp, StartIdx, Step));
auto *Add = addFastMathFlag(Builder.CreateBinOp(AddOp, ScalarIV, Mul));
VectorLoopValueMap.setScalarValue(EntryVal, {Part, Lane}, Add);
VectorLoopValueMap.setScalarValue(EntryVal, VPIteration(Part, Lane), Add);
recordVectorLoopValueForInductionCast(ID, EntryVal, Add, Part, Lane);
}
}
@ -2384,7 +2385,8 @@ Value *InnerLoopVectorizer::getOrCreateVectorValue(Value *V, unsigned Part) {
// instead. If it has been scalarized, and we actually need the value in
// vector form, we will construct the vector values on demand.
if (VectorLoopValueMap.hasAnyScalarValue(V)) {
Value *ScalarValue = VectorLoopValueMap.getScalarValue(V, {Part, 0});
Value *ScalarValue =
VectorLoopValueMap.getScalarValue(V, VPIteration(Part, 0));
// If we've scalarized a value, that value should be an instruction.
auto *I = cast<Instruction>(V);
@ -2406,7 +2408,7 @@ Value *InnerLoopVectorizer::getOrCreateVectorValue(Value *V, unsigned Part) {
assert((!VF.isScalable() || LastLane == 0) &&
"Scalable vectorization can't lead to any scalarized values.");
auto *LastInst = cast<Instruction>(
VectorLoopValueMap.getScalarValue(V, {Part, LastLane}));
VectorLoopValueMap.getScalarValue(V, VPIteration(Part, LastLane)));
// Set the insert point after the last scalarized instruction. This ensures
// the insertelement sequence will directly follow the scalar definitions.
@ -2430,7 +2432,7 @@ Value *InnerLoopVectorizer::getOrCreateVectorValue(Value *V, unsigned Part) {
Value *Poison = PoisonValue::get(VectorType::get(V->getType(), VF));
VectorLoopValueMap.setVectorValue(V, Part, Poison);
for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
packScalarIntoVectorValue(V, {Part, Lane});
packScalarIntoVectorValue(V, VPIteration(Part, Lane));
VectorValue = VectorLoopValueMap.getVectorValue(V, Part);
}
Builder.restoreIP(OldIP);
@ -2573,7 +2575,7 @@ void InnerLoopVectorizer::vectorizeInterleaveGroup(
Index += (VF.getKnownMinValue() - 1) * Group->getFactor();
for (unsigned Part = 0; Part < UF; Part++) {
Value *AddrPart = State.get(Addr, {Part, 0});
Value *AddrPart = State.get(Addr, VPIteration(Part, 0));
setDebugLocFromInst(Builder, AddrPart);
// Notice current instruction could be any index. Need to adjust the address
@ -2825,7 +2827,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(
// We don't want to update the value in the map as it might be used in
// another expression. So don't call resetVectorValue(StoredVal).
}
auto *VecPtr = CreateVecPtr(Part, State.get(Addr, {0, 0}));
auto *VecPtr = CreateVecPtr(Part, State.get(Addr, VPIteration(0, 0)));
if (isMaskRequired)
NewSI = Builder.CreateMaskedStore(StoredVal, VecPtr, Alignment,
BlockInMaskParts[Part]);
@ -2849,7 +2851,7 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(
nullptr, "wide.masked.gather");
addMetadata(NewLI, LI);
} else {
auto *VecPtr = CreateVecPtr(Part, State.get(Addr, {0, 0}));
auto *VecPtr = CreateVecPtr(Part, State.get(Addr, VPIteration(0, 0)));
if (isMaskRequired)
NewLI = Builder.CreateMaskedLoad(
VecPtr, Alignment, BlockInMaskParts[Part], PoisonValue::get(DataTy),
@ -2877,7 +2879,7 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr, VPUser &User,
// llvm.experimental.noalias.scope.decl intrinsics must only be duplicated for
// the first lane and part.
if (isa<NoAliasScopeDeclInst>(Instr))
if (Instance.Lane != 0 || Instance.Part != 0)
if (!Instance.isFirstIteration())
return;
setDebugLocFromInst(Builder, Instr);
@ -4405,7 +4407,7 @@ void InnerLoopVectorizer::fixLCSSAPHIs() {
// extracted from the vectorized loop.
Builder.SetInsertPoint(LoopMiddleBlock->getTerminator());
Value *lastIncomingValue =
getOrCreateScalarValue(IncomingValue, { UF - 1, LastLane });
getOrCreateScalarValue(IncomingValue, VPIteration(UF - 1, LastLane));
LCSSAPhi.addIncoming(lastIncomingValue, LoopMiddleBlock);
}
}
@ -4551,8 +4553,9 @@ void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
for (unsigned Part = 0; Part < UF; ++Part) {
// The pointer operand of the new GEP. If it's loop-invariant, we
// won't broadcast it.
auto *Ptr = IsPtrLoopInvariant ? State.get(Operands.getOperand(0), {0, 0})
: State.get(Operands.getOperand(0), Part);
auto *Ptr = IsPtrLoopInvariant
? State.get(Operands.getOperand(0), VPIteration(0, 0))
: State.get(Operands.getOperand(0), Part);
// Collect all the indices for the new GEP. If any index is
// loop-invariant, we won't broadcast it.
@ -4560,7 +4563,7 @@ void InnerLoopVectorizer::widenGEP(GetElementPtrInst *GEP, VPValue *VPDef,
for (unsigned I = 1, E = Operands.getNumOperands(); I < E; I++) {
VPValue *Operand = Operands.getOperand(I);
if (IsIndexLoopInvariant[I - 1])
Indices.push_back(State.get(Operand, {0, 0}));
Indices.push_back(State.get(Operand, VPIteration(0, 0)));
else
Indices.push_back(State.get(Operand, Part));
}
@ -4699,7 +4702,8 @@ void InnerLoopVectorizer::widenPHIInstruction(Instruction *PN,
Value *SclrGep =
emitTransformedIndex(Builder, GlobalIdx, PSE.getSE(), DL, II);
SclrGep->setName("next.gep");
VectorLoopValueMap.setScalarValue(P, {Part, Lane}, SclrGep);
VectorLoopValueMap.setScalarValue(P, VPIteration(Part, Lane),
SclrGep);
}
}
return;
@ -4916,7 +4920,7 @@ void InnerLoopVectorizer::widenCallInstruction(CallInst &I, VPValue *Def,
if (!UseVectorIntrinsic || !hasVectorInstrinsicScalarOpd(ID, I.index()))
Arg = State.get(I.value(), Part);
else
Arg = State.get(I.value(), {0, 0});
Arg = State.get(I.value(), VPIteration(0, 0));
Args.push_back(Arg);
}
@ -4961,8 +4965,9 @@ void InnerLoopVectorizer::widenSelectInstruction(SelectInst &I, VPValue *VPDef,
// loop. This means that we can't just use the original 'cond' value.
// We have to take the 'vectorized' value and pick the first lane.
// Instcombine will make this a no-op.
auto *InvarCond =
InvariantCond ? State.get(Operands.getOperand(0), {0, 0}) : nullptr;
auto *InvarCond = InvariantCond
? State.get(Operands.getOperand(0), VPIteration(0, 0))
: nullptr;
for (unsigned Part = 0; Part < UF; ++Part) {
Value *Cond =
@ -9102,8 +9107,9 @@ void VPReplicateRecipe::execute(VPTransformState &State) {
"Can't scalarize a scalable vector");
for (unsigned Part = 0; Part < State.UF; ++Part)
for (unsigned Lane = 0; Lane < EndLane; ++Lane)
State.ILV->scalarizeInstruction(getUnderlyingInstr(), *this, {Part, Lane},
IsPredicated, State);
State.ILV->scalarizeInstruction(getUnderlyingInstr(), *this,
VPIteration(Part, Lane), IsPredicated,
State);
}
void VPBranchOnMaskRecipe::execute(VPTransformState &State) {

View File

@ -286,8 +286,7 @@ VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
}
void VPBasicBlock::execute(VPTransformState *State) {
bool Replica = State->Instance &&
!(State->Instance->Part == 0 && State->Instance->Lane == 0);
bool Replica = State->Instance && !State->Instance->isFirstIteration();
VPBasicBlock *PrevVPBB = State->CFG.PrevVPBB;
VPBlockBase *SingleHPred = nullptr;
BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible.
@ -401,7 +400,7 @@ void VPRegionBlock::execute(VPTransformState *State) {
assert(!State->Instance && "Replicating a Region with non-null instance.");
// Enter replicating mode.
State->Instance = {0, 0};
State->Instance = VPIteration(0, 0);
for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part) {
State->Instance->Part = Part;
@ -497,7 +496,7 @@ void VPInstruction::generateInstruction(VPTransformState &State,
}
case VPInstruction::ActiveLaneMask: {
// Get first lane of vector induction variable.
Value *VIVElem0 = State.get(getOperand(0), {Part, 0});
Value *VIVElem0 = State.get(getOperand(0), VPIteration(Part, 0));
// Get the original loop tripcount.
Value *ScalarTC = State.TripCount;

View File

@ -97,6 +97,10 @@ struct VPIteration {
/// in [0..VF)
unsigned Lane;
VPIteration(unsigned Part, unsigned Lane) : Part(Part), Lane(Lane) {}
bool isFirstIteration() const { return Part == 0 && Lane == 0; }
};
/// This is a helper struct for maintaining vectorization state. It's used for