diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 130 |
1 files changed, 59 insertions, 71 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 25bf69729c70..644372483edd 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -666,19 +666,18 @@ static void inversePermutation(ArrayRef<unsigned> Indices, /// \returns inserting index of InsertElement or InsertValue instruction, /// using Offset as base offset for index. -static Optional<int> getInsertIndex(Value *InsertInst, unsigned Offset) { +static Optional<unsigned> getInsertIndex(Value *InsertInst, + unsigned Offset = 0) { int Index = Offset; if (auto *IE = dyn_cast<InsertElementInst>(InsertInst)) { if (auto *CI = dyn_cast<ConstantInt>(IE->getOperand(2))) { auto *VT = cast<FixedVectorType>(IE->getType()); if (CI->getValue().uge(VT->getNumElements())) - return UndefMaskElem; + return None; Index *= VT->getNumElements(); Index += CI->getZExtValue(); return Index; } - if (isa<UndefValue>(IE->getOperand(2))) - return UndefMaskElem; return None; } @@ -3848,13 +3847,9 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth, // Check that we have a buildvector and not a shuffle of 2 or more // different vectors. ValueSet SourceVectors; - int MinIdx = std::numeric_limits<int>::max(); for (Value *V : VL) { SourceVectors.insert(cast<Instruction>(V)->getOperand(0)); - Optional<int> Idx = *getInsertIndex(V, 0); - if (!Idx || *Idx == UndefMaskElem) - continue; - MinIdx = std::min(MinIdx, *Idx); + assert(getInsertIndex(V) != None && "Non-constant or undef index?"); } if (count_if(VL, [&SourceVectors](Value *V) { @@ -3876,10 +3871,8 @@ void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth, decltype(OrdCompare)> Indices(OrdCompare); for (int I = 0, E = VL.size(); I < E; ++I) { - Optional<int> Idx = *getInsertIndex(VL[I], 0); - if (!Idx || *Idx == UndefMaskElem) - continue; - Indices.emplace(*Idx, I); + unsigned Idx = *getInsertIndex(VL[I]); + Indices.emplace(Idx, I); } OrdersType CurrentOrder(VL.size(), VL.size()); bool IsIdentity = true; @@ -5006,12 +4999,10 @@ InstructionCost BoUpSLP::getEntryCost(const TreeEntry *E, SmallVector<int> PrevMask(NumElts, UndefMaskElem); Mask.swap(PrevMask); for (unsigned I = 0; I < NumScalars; ++I) { - Optional<int> InsertIdx = getInsertIndex(VL[PrevMask[I]], 0); - if (!InsertIdx || *InsertIdx == UndefMaskElem) - continue; - DemandedElts.setBit(*InsertIdx); - IsIdentity &= *InsertIdx - Offset == I; - Mask[*InsertIdx - Offset] = I; + unsigned InsertIdx = *getInsertIndex(VL[PrevMask[I]]); + DemandedElts.setBit(InsertIdx); + IsIdentity &= InsertIdx - Offset == I; + Mask[InsertIdx - Offset] = I; } assert(Offset < NumElts && "Failed to find vector index offset"); @@ -5685,42 +5676,41 @@ InstructionCost BoUpSLP::getTreeCost(ArrayRef<Value *> VectorizedVals) { // to detect it as a final shuffled/identity match. if (auto *VU = dyn_cast_or_null<InsertElementInst>(EU.User)) { if (auto *FTy = dyn_cast<FixedVectorType>(VU->getType())) { - Optional<int> InsertIdx = getInsertIndex(VU, 0); - if (!InsertIdx || *InsertIdx == UndefMaskElem) - continue; - auto *It = find_if(FirstUsers, [VU](Value *V) { - return areTwoInsertFromSameBuildVector(VU, - cast<InsertElementInst>(V)); - }); - int VecId = -1; - if (It == FirstUsers.end()) { - VF.push_back(FTy->getNumElements()); - ShuffleMask.emplace_back(VF.back(), UndefMaskElem); - // Find the insertvector, vectorized in tree, if any. - Value *Base = VU; - while (isa<InsertElementInst>(Base)) { - // Build the mask for the vectorized insertelement instructions. - if (const TreeEntry *E = getTreeEntry(Base)) { - VU = cast<InsertElementInst>(Base); - do { - int Idx = E->findLaneForValue(Base); - ShuffleMask.back()[Idx] = Idx; - Base = cast<InsertElementInst>(Base)->getOperand(0); - } while (E == getTreeEntry(Base)); - break; + Optional<unsigned> InsertIdx = getInsertIndex(VU); + if (InsertIdx) { + auto *It = find_if(FirstUsers, [VU](Value *V) { + return areTwoInsertFromSameBuildVector(VU, + cast<InsertElementInst>(V)); + }); + int VecId = -1; + if (It == FirstUsers.end()) { + VF.push_back(FTy->getNumElements()); + ShuffleMask.emplace_back(VF.back(), UndefMaskElem); + // Find the insertvector, vectorized in tree, if any. + Value *Base = VU; + while (isa<InsertElementInst>(Base)) { + // Build the mask for the vectorized insertelement instructions. + if (const TreeEntry *E = getTreeEntry(Base)) { + VU = cast<InsertElementInst>(Base); + do { + int Idx = E->findLaneForValue(Base); + ShuffleMask.back()[Idx] = Idx; + Base = cast<InsertElementInst>(Base)->getOperand(0); + } while (E == getTreeEntry(Base)); + break; + } + Base = cast<InsertElementInst>(Base)->getOperand(0); } - Base = cast<InsertElementInst>(Base)->getOperand(0); + FirstUsers.push_back(VU); + DemandedElts.push_back(APInt::getZero(VF.back())); + VecId = FirstUsers.size() - 1; + } else { + VecId = std::distance(FirstUsers.begin(), It); } - FirstUsers.push_back(VU); - DemandedElts.push_back(APInt::getZero(VF.back())); - VecId = FirstUsers.size() - 1; - } else { - VecId = std::distance(FirstUsers.begin(), It); + ShuffleMask[VecId][*InsertIdx] = EU.Lane; + DemandedElts[VecId].setBit(*InsertIdx); + continue; } - int Idx = *InsertIdx; - ShuffleMask[VecId][Idx] = EU.Lane; - DemandedElts[VecId].setBit(Idx); - continue; } } @@ -6477,11 +6467,9 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) { Mask.swap(PrevMask); for (unsigned I = 0; I < NumScalars; ++I) { Value *Scalar = E->Scalars[PrevMask[I]]; - Optional<int> InsertIdx = getInsertIndex(Scalar, 0); - if (!InsertIdx || *InsertIdx == UndefMaskElem) - continue; - IsIdentity &= *InsertIdx - Offset == I; - Mask[*InsertIdx - Offset] = I; + unsigned InsertIdx = *getInsertIndex(Scalar); + IsIdentity &= InsertIdx - Offset == I; + Mask[InsertIdx - Offset] = I; } if (!IsIdentity || NumElts != NumScalars) { V = Builder.CreateShuffleVector(V, Mask); @@ -8349,6 +8337,8 @@ void SLPVectorizerPass::collectSeedInstructions(BasicBlock *BB) { bool SLPVectorizerPass::tryToVectorizePair(Value *A, Value *B, BoUpSLP &R) { if (!A || !B) return false; + if (isa<InsertElementInst>(A) || isa<InsertElementInst>(B)) + return false; Value *VL[] = {A, B}; return tryToVectorizeList(VL, R); } @@ -9323,21 +9313,22 @@ static Optional<unsigned> getAggregateSize(Instruction *InsertInst) { } while (true); } -static bool findBuildAggregate_rec(Instruction *LastInsertInst, +static void findBuildAggregate_rec(Instruction *LastInsertInst, TargetTransformInfo *TTI, SmallVectorImpl<Value *> &BuildVectorOpds, SmallVectorImpl<Value *> &InsertElts, unsigned OperandOffset) { do { Value *InsertedOperand = LastInsertInst->getOperand(1); - Optional<int> OperandIndex = getInsertIndex(LastInsertInst, OperandOffset); + Optional<unsigned> OperandIndex = + getInsertIndex(LastInsertInst, OperandOffset); if (!OperandIndex) - return false; + return; if (isa<InsertElementInst>(InsertedOperand) || isa<InsertValueInst>(InsertedOperand)) { - if (!findBuildAggregate_rec(cast<Instruction>(InsertedOperand), TTI, - BuildVectorOpds, InsertElts, *OperandIndex)) - return false; + findBuildAggregate_rec(cast<Instruction>(InsertedOperand), TTI, + BuildVectorOpds, InsertElts, *OperandIndex); + } else { BuildVectorOpds[*OperandIndex] = InsertedOperand; InsertElts[*OperandIndex] = LastInsertInst; @@ -9347,7 +9338,6 @@ static bool findBuildAggregate_rec(Instruction *LastInsertInst, (isa<InsertValueInst>(LastInsertInst) || isa<InsertElementInst>(LastInsertInst)) && LastInsertInst->hasOneUse()); - return true; } /// Recognize construction of vectors like @@ -9382,13 +9372,11 @@ static bool findBuildAggregate(Instruction *LastInsertInst, BuildVectorOpds.resize(*AggregateSize); InsertElts.resize(*AggregateSize); - if (findBuildAggregate_rec(LastInsertInst, TTI, BuildVectorOpds, InsertElts, - 0)) { - llvm::erase_value(BuildVectorOpds, nullptr); - llvm::erase_value(InsertElts, nullptr); - if (BuildVectorOpds.size() >= 2) - return true; - } + findBuildAggregate_rec(LastInsertInst, TTI, BuildVectorOpds, InsertElts, 0); + llvm::erase_value(BuildVectorOpds, nullptr); + llvm::erase_value(InsertElts, nullptr); + if (BuildVectorOpds.size() >= 2) + return true; return false; } |