[PATCH] Extend SLPVectorizer for cases where insertelement instructions must be rescheduled
Nadav Rotem
nrotem at apple.com
Fri Mar 21 14:20:02 PDT 2014
Hi Arch,
It looks like you uploaded the wrong patch.
Thanks,
Nadav
On Mar 21, 2014, at 2:05 PM, Arch D. Robison <arch.robison at intel.com> wrote:
> Hi #llvm,
>
> The patch extends SLPVectorizer to handle cases where operations building a vector overlap the operations to be vectorized. Motivation arises from compiling Julia tuples, as described [here](https://github.com/JuliaLang/julia/issues/5857#issuecomment-35784676), though the extension is likely useful for other languages too.
>
> Per a suggestion of Arnold Schwaighofer, the patch adapts existing logic for `RdxOps`. The patch changes method `buildTree` to separate two roles of `RdxOps`.
> * The first role is as a list of uses that can be ignored for purposes of legality checking.
> * The second role is as a list of reduction uses.
> The `insertelement` instructions for building a vector act the first role, but not the second. Values used for reductions act both roles.
>
> A new method `movePrematureInserts` reschedules the `insertelement` instructions if the transform happens.
>
> The patch refines a cost estimate to take credit for `extractelement` instructions that will be erased.
>
> The new test checks that vectorization occurs for a case (derived from a Julia example) that previously stumped SLPVecotrizer.
>
>
> http://llvm-reviews.chandlerc.com/D3143
>
> Files:
> lib/Transforms/Vectorize/SLPVectorizer.cpp
>
> Index: lib/Transforms/Vectorize/SLPVectorizer.cpp
> ===================================================================
> --- lib/Transforms/Vectorize/SLPVectorizer.cpp
> +++ lib/Transforms/Vectorize/SLPVectorizer.cpp
> @@ -367,7 +368,7 @@
>
> /// Construct a vectorizable tree that starts at \p Roots and is possibly
> /// used by a reduction of \p RdxOps.
> - void buildTree(ArrayRef<Value *> Roots, ValueSet *RdxOps = 0);
> + void buildTree(ArrayRef<Value *> Roots, bool buildsVector=false, ValueSet *RdxOps = 0);
>
> /// Clear the internal data structures that are created by 'buildTree'.
> void deleteTree() {
> @@ -391,7 +392,7 @@
> int getEntryCost(TreeEntry *E);
>
> /// This is the recursive part of buildTree.
> - void buildTree_rec(ArrayRef<Value *> Roots, unsigned Depth);
> + void buildTree_rec(ArrayRef<Value *> Roots, unsigned Depth, bool buildsVector=false);
>
> /// Vectorize a single entry in the tree.
> Value *vectorizeTree(TreeEntry *E);
> @@ -542,12 +543,12 @@
> IRBuilder<> Builder;
> };
>
> -void BoUpSLP::buildTree(ArrayRef<Value *> Roots, ValueSet *Rdx) {
> +void BoUpSLP::buildTree(ArrayRef<Value *> Roots, bool buildsVector, ValueSet *Rdx) {
> deleteTree();
> RdxOps = Rdx;
> if (!getSameType(Roots))
> return;
> - buildTree_rec(Roots, 0);
> + buildTree_rec(Roots, 0, buildsVector);
>
> // Collect the values that we need to extract from the tree.
> for (int EIdx = 0, EE = VectorizableTree.size(); EIdx < EE; ++EIdx) {
> @@ -589,7 +590,7 @@
> }
>
>
> -void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth) {
> +void BoUpSLP::buildTree_rec(ArrayRef<Value *> VL, unsigned Depth, bool buildsVector ) {
> bool SameTy = getSameType(VL); (void)SameTy;
> assert(SameTy && "Invalid types!");
>
> @@ -712,6 +713,10 @@
> if (RdxOps && RdxOps->count(UI))
> continue;
>
> + // This user is part of building a vector
> + if (buildsVector)
> + continue;
> +
> // Make sure that we can schedule this unknown user.
> BlockNumbering &BN = BlocksNumbers[BB];
> int UserIndex = BN.getIndex(UI);
> @@ -1012,8 +1017,16 @@
> return 0;
> }
> case Instruction::ExtractElement: {
> - if (CanReuseExtract(VL))
> - return 0;
> + if (CanReuseExtract(VL)) {
> + int DeadCost = 0;
> + for (unsigned i = 0, e = VL.size(); i < e; ++i) {
> + ExtractElementInst *E = cast<ExtractElementInst>(VL[i]);
> + if( E->hasOneUse() )
> + // Take credit for instruction that will become dead.
> + DeadCost += TTI->getVectorInstrCost(Instruction::ExtractElement, VecTy, i);
> + }
> + return -DeadCost;
> + }
> return getGatherCost(VecTy);
> }
> case Instruction::ZExt:
> @@ -1948,7 +1961,7 @@
>
> /// \brief Try to vectorize a list of operands.
> /// \returns true if a value was vectorized.
> - bool tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R);
> + bool tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R, bool buildsVector=false);
>
> /// \brief Try to vectorize a chain that may start at the operands of \V;
> bool tryToVectorize(BinaryOperator *V, BoUpSLP &R);
> @@ -2121,7 +2134,7 @@
> return tryToVectorizeList(VL, R);
> }
>
> -bool SLPVectorizer::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R) {
> +bool SLPVectorizer::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R, bool buildsVector) {
> if (VL.size() < 2)
> return false;
>
> @@ -2149,7 +2162,7 @@
>
> bool Changed = false;
>
> - // Keep track of values that were delete by vectorizing in the loop below.
> + // Keep track of values that were deleted by vectorizing in the loop below.
> SmallVector<WeakVH, 8> TrackValues(VL.begin(), VL.end());
>
> for (unsigned i = 0, e = VL.size(); i < e; ++i) {
> @@ -2171,11 +2184,11 @@
> << "\n");
> ArrayRef<Value *> Ops = VL.slice(i, OpsWidth);
>
> - R.buildTree(Ops);
> + R.buildTree(Ops,buildsVector);
> int Cost = R.getTreeCost();
>
> if (Cost < -SLPCostThreshold) {
> - DEBUG(dbgs() << "SLP: Vectorizing pair at cost:" << Cost << ".\n");
> + DEBUG(dbgs() << "SLP: Vectorizing list at cost:" << Cost << ".\n");
> R.vectorizeTree();
>
> // Move to the next bundle.
> @@ -2417,7 +2430,7 @@
>
> for (; i < NumReducedVals - ReduxWidth + 1; i += ReduxWidth) {
> ArrayRef<Value *> ValsToReduce(&ReducedVals[i], ReduxWidth);
> - V.buildTree(ValsToReduce, &ReductionOps);
> + V.buildTree(ValsToReduce, false, &ReductionOps);
>
> // Estimate cost.
> int Cost = V.getTreeCost() + getReductionCost(TTI, ReducedVals[i]);
> @@ -2717,7 +2730,7 @@
> if (!findBuildVector(IE, Ops))
> continue;
>
> - if (tryToVectorizeList(Ops, R)) {
> + if (tryToVectorizeList(Ops, R, true)) {
> Changed = true;
> it = BB->begin();
> e = BB->end();
> <D3143.1.patch>_______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list