[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