[llvm] r193926 - LoopVectorize: Remove quadratic behavior the local CSE.

Nadav Rotem nrotem at apple.com
Sat Nov 2 10:40:22 PDT 2013


Thanks Ben!  We can further improve the compile time by checking for redundancy while creating the shuffles and insert/extract elements. This will prevent the linear scan on the basic block.
 

On Nov 2, 2013, at 6:39 AM, Benjamin Kramer <benny.kra at googlemail.com> wrote:

> Author: d0k
> Date: Sat Nov  2 08:39:00 2013
> New Revision: 193926
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=193926&view=rev
> Log:
> LoopVectorize: Remove quadratic behavior the local CSE.
> 
> Doing this with a hash map doesn't change behavior and avoids calling
> isIdenticalTo O(n^2) times. This should probably eventually move into a utility
> class shared with EarlyCSE and the limited CSE in the SLPVectorizer.
> 
> Modified:
>    llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> 
> Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=193926&r1=193925&r2=193926&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
> +++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Sat Nov  2 08:39:00 2013
> @@ -48,6 +48,7 @@
> #include "llvm/Transforms/Vectorize.h"
> #include "llvm/ADT/DenseMap.h"
> #include "llvm/ADT/EquivalenceClasses.h"
> +#include "llvm/ADT/Hashing.h"
> #include "llvm/ADT/MapVector.h"
> #include "llvm/ADT/SetVector.h"
> #include "llvm/ADT/SmallPtrSet.h"
> @@ -2055,38 +2056,51 @@ Value *createMinMaxOp(IRBuilder<> &Build
>   return Select;
> }
> 
> +namespace {
> +struct CSEDenseMapInfo {
> +  static bool canHandle(Instruction *I) {
> +    return isa<InsertElementInst>(I) || isa<ExtractElementInst>(I) ||
> +           isa<ShuffleVectorInst>(I) || isa<GetElementPtrInst>(I);
> +  }
> +  static inline Instruction *getEmptyKey() {
> +    return DenseMapInfo<Instruction *>::getEmptyKey();
> +  }
> +  static inline Instruction *getTombstoneKey() {
> +    return DenseMapInfo<Instruction *>::getTombstoneKey();
> +  }
> +  static unsigned getHashValue(Instruction *I) {
> +    assert(canHandle(I) && "Unknown instruction!");
> +    return hash_combine(I->getOpcode(), hash_combine_range(I->value_op_begin(),
> +                                                           I->value_op_end()));
> +  }
> +  static bool isEqual(Instruction *LHS, Instruction *RHS) {
> +    if (LHS == getEmptyKey() || RHS == getEmptyKey() ||
> +        LHS == getTombstoneKey() || RHS == getTombstoneKey())
> +      return LHS == RHS;
> +    return LHS->isIdenticalTo(RHS);
> +  }
> +};
> +}
> +
> ///\brief Perform cse of induction variable instructions.
> static void cse(BasicBlock *BB) {
>   // Perform simple cse.
> -  SmallPtrSet<Instruction*, 16> Visited;
> -  SmallVector<Instruction*, 16> ToRemove;
> -  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
> -      Instruction *In = I;
> +  SmallDenseMap<Instruction *, Instruction *, 4, CSEDenseMapInfo> CSEMap;
> +  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
> +    Instruction *In = I++;
> 
> -      if (!isa<InsertElementInst>(In) && !isa<ExtractElementInst>(In) &&
> -          !isa<ShuffleVectorInst>(In) && !isa<GetElementPtrInst>(In))
> -        continue;
> +    if (!CSEDenseMapInfo::canHandle(In))
> +      continue;
> 
> -      // Check if we can replace this instruction with any of the
> -      // visited instructions.
> -      for (SmallPtrSet<Instruction*, 16>::iterator v = Visited.begin(),
> -           ve = Visited.end(); v != ve; ++v) {
> -        if (In->isIdenticalTo(*v)) {
> -          In->replaceAllUsesWith(*v);
> -          ToRemove.push_back(In);
> -          In = 0;
> -          break;
> -        }
> -      }
> -      if (In)
> -        Visited.insert(In);
> +    // Check if we can replace this instruction with any of the
> +    // visited instructions.
> +    if (Instruction *V = CSEMap.lookup(In)) {
> +      In->replaceAllUsesWith(V);
> +      In->eraseFromParent();
> +      continue;
> +    }
> 
> -  }
> -  // Erase all of the instructions that we RAUWed.
> -  for (SmallVectorImpl<Instruction *>::iterator v = ToRemove.begin(),
> -       ve = ToRemove.end(); v != ve; ++v) {
> -    assert((*v)->getNumUses() == 0 && "Can't remove instructions with uses");
> -    (*v)->eraseFromParent();
> +    CSEMap[In] = In;
>   }
> }
> 
> 
> 
> _______________________________________________
> 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