diff options
| author | Chris Lattner <sabre@nondot.org> | 2010-12-27 00:03:23 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2010-12-27 00:03:23 +0000 | 
| commit | b9fe685b9a6361c4f9e3cb5a87921f45e191cf60 (patch) | |
| tree | 76510819faedbdbf8e77d276afae6091d3e757e4 /llvm/lib/Transforms | |
| parent | 29e14edc8da9f9687f858db045931daa16c40ecb (diff) | |
| download | bcm5719-llvm-b9fe685b9a6361c4f9e3cb5a87921f45e191cf60.tar.gz bcm5719-llvm-b9fe685b9a6361c4f9e3cb5a87921f45e191cf60.zip | |
have loop-idiom nuke instructions that feed stores that get removed.
llvm-svn: 122574
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 51 | 
1 files changed, 45 insertions, 6 deletions
| diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index a5e2b2dba17..f8748efecea 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -20,6 +20,7 @@  #include "llvm/Analysis/ScalarEvolutionExpander.h"  #include "llvm/Analysis/ValueTracking.h"  #include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Utils/Local.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/IRBuilder.h"  #include "llvm/Support/raw_ostream.h" @@ -77,6 +78,40 @@ INITIALIZE_PASS_END(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms",  Pass *llvm::createLoopIdiomPass() { return new LoopIdiomRecognize(); } +/// DeleteDeadInstruction - Delete this instruction.  Before we do, go through +/// and zero out all the operands of this instruction.  If any of them become +/// dead, delete them and the computation tree that feeds them. +/// +static void DeleteDeadInstruction(Instruction *I, ScalarEvolution &SE) { +  SmallVector<Instruction*, 32> NowDeadInsts; +   +  NowDeadInsts.push_back(I); +   +  // Before we touch this instruction, remove it from SE! +  do { +    Instruction *DeadInst = NowDeadInsts.pop_back_val(); +     +    // This instruction is dead, zap it, in stages.  Start by removing it from +    // SCEV. +    SE.forgetValue(DeadInst); +     +    for (unsigned op = 0, e = DeadInst->getNumOperands(); op != e; ++op) { +      Value *Op = DeadInst->getOperand(op); +      DeadInst->setOperand(op, 0); +       +      // If this operand just became dead, add it to the NowDeadInsts list. +      if (!Op->use_empty()) continue; +       +      if (Instruction *OpI = dyn_cast<Instruction>(Op)) +        if (isInstructionTriviallyDead(OpI)) +          NowDeadInsts.push_back(OpI); +    } +     +    DeadInst->eraseFromParent(); +     +  } while (!NowDeadInsts.empty()); +} +  bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {    CurLoop = L; @@ -106,8 +141,13 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L, LPPassManager &LPM) {      StoreInst *SI = dyn_cast<StoreInst>(I++);      if (SI == 0 || SI->isVolatile()) continue; -     -    MadeChange |= processLoopStore(SI, BECount); +    WeakVH InstPtr; +    if (processLoopStore(SI, BECount)) { +      // If processing the store invalidated our iterator, start over from the +      // head of the loop. +      if (InstPtr == 0) +        I = BB->begin(); +    }    }    return MadeChange; @@ -205,10 +245,9 @@ processLoopStoreOfSplatValue(StoreInst *SI, unsigned StoreSize,    DEBUG(dbgs() << "  Formed memset: " << *NewCall << "\n"                 << "    from store to: " << *Ev << " at: " << *SI << "\n"); -  // Okay, the memset has been formed.  Zap the original store. -  // FIXME: We want to recursively delete dead instructions, but we have to -  // update SCEV. -  SI->eraseFromParent();   +  // Okay, the memset has been formed.  Zap the original store and anything that +  // feeds into it. +  DeleteDeadInstruction(SI, *SE);    return true;  } | 

