diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-10-11 23:06:50 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-10-11 23:06:50 +0000 | 
| commit | 9776f7259bf66ca7184d80f9ec09117ea2b0fcd5 (patch) | |
| tree | c18d9c3a893a1a8c8dbe979e56f5708dd8246f7a /llvm/lib/Transforms | |
| parent | 13128ab8fb24933a6a2c91e707116556d530d07d (diff) | |
| download | bcm5719-llvm-9776f7259bf66ca7184d80f9ec09117ea2b0fcd5.tar.gz bcm5719-llvm-9776f7259bf66ca7184d80f9ec09117ea2b0fcd5.zip | |
Handle a common case more carefully.  In particular, instead of transforming
pointer recurrences into expressions from this:
  %P_addr.0.i.0 = phi sbyte* [ getelementptr ([8 x sbyte]* %.str_1, int 0, int 0), %entry ], [ %inc.0.i, %no_exit.i ]
  %inc.0.i = getelementptr sbyte* %P_addr.0.i.0, int 1            ; <sbyte*> [#uses=2]
into this:
  %inc.0.i = getelementptr sbyte* getelementptr ([8 x sbyte]* %.str_1, int 0, int 0), int %inc.0.i.rec
Actually create something nice, like this:
  %inc.0.i = getelementptr [8 x sbyte]* %.str_1, int 0, int %inc.0.i.rec
llvm-svn: 16924
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 37 | 
1 files changed, 33 insertions, 4 deletions
| diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 72ad30c0672..3398b376abf 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -45,6 +45,7 @@  #include "llvm/Analysis/ScalarEvolutionExpressions.h"  #include "llvm/Analysis/LoopInfo.h"  #include "llvm/Support/CFG.h" +#include "llvm/Support/GetElementPtrTypeIterator.h"  #include "llvm/Transforms/Utils/Local.h"  #include "llvm/Support/CommandLine.h"  #include "llvm/ADT/Statistic.h" @@ -135,9 +136,9 @@ namespace {                  while (isa<PHINode>(It)) ++It;                  if (It != BasicBlock::iterator(CI)) {                    // Splice the cast immediately after the operand in question. -                  I->getParent()->getInstList().splice(It, -                                                       CI->getParent()->getInstList(), -                                                       CI); +                  BasicBlock::InstListType &InstList = +                    I->getParent()->getInstList(); +                  InstList.splice(It, InstList, CI);                  }                  return CI;                } @@ -345,7 +346,7 @@ DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts) {          if (Instruction *U = dyn_cast<Instruction>(I->getOperand(i)))            Insts.insert(U);        SE->deleteInstructionFromRecords(I); -      I->getParent()->getInstList().erase(I); +      I->eraseFromParent();        Changed = true;      }    } @@ -387,6 +388,34 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN,        // Update the GEP to use the new recurrence we just inserted.        GEPI->setOperand(1, NewAdd); +      // If the incoming value is a constant expr GEP, try peeling out the array +      // 0 index if possible to make things simpler. +      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GEPI->getOperand(0))) +        if (CE->getOpcode() == Instruction::GetElementPtr) { +          unsigned NumOps = CE->getNumOperands(); +          assert(NumOps > 1 && "CE folding didn't work!"); +          if (CE->getOperand(NumOps-1)->isNullValue()) { +            // Check to make sure the last index really is an array index. +            gep_type_iterator GTI = gep_type_begin(GEPI); +            for (unsigned i = 1, e = GEPI->getNumOperands()-1; +                 i != e; ++i, ++GTI) +              /*empty*/; +            if (isa<SequentialType>(*GTI)) { +              // Pull the last index out of the constant expr GEP. +              std::vector<Value*> CEIdxs(CE->op_begin()+1, CE->op_end()-1); +              Constant *NCE = ConstantExpr::getGetElementPtr(CE->getOperand(0), +                                                             CEIdxs); +              GetElementPtrInst *NGEPI = +                new GetElementPtrInst(NCE, Constant::getNullValue(Type::IntTy), +                                      NewAdd, GEPI->getName(), GEPI); +              GEPI->replaceAllUsesWith(NGEPI); +              GEPI->eraseFromParent(); +              GEPI = NGEPI; +            } +          } +        } + +        // Finally, if there are any other users of the PHI node, we must        // insert a new GEP instruction that uses the pre-incremented version        // of the induction amount. | 

