[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