diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-04-21 22:22:01 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-04-21 22:22:01 +0000 | 
| commit | dc7cc350889acf51bd1aa9a6b0165f0b7dde6912 (patch) | |
| tree | 92b768779816cded76081062aa519bba9752e622 /llvm/lib/Transforms | |
| parent | be8bb804c5529128efb3fe60c401ff46ed96fb2d (diff) | |
| download | bcm5719-llvm-dc7cc350889acf51bd1aa9a6b0165f0b7dde6912.tar.gz bcm5719-llvm-dc7cc350889acf51bd1aa9a6b0165f0b7dde6912.zip | |
Implement a fixme.  The helps loops that have induction variables of different
types in them.  Instead of creating an induction variable for all types, it
creates a single induction variable and casts to the other sizes.  This generates
this code:
no_exit:                ; preds = %entry, %no_exit
        %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=4]
***     %j.0.0 = cast uint %indvar to short             ; <short> [#uses=1]
        %indvar = cast uint %indvar to int              ; <int> [#uses=1]
        %tmp.7 = getelementptr short* %P, uint %indvar          ; <short*> [#uses=1]
        store short %j.0.0, short* %tmp.7
        %inc.0 = add int %indvar, 1             ; <int> [#uses=2]
        %tmp.2 = setlt int %inc.0, %N           ; <bool> [#uses=1]
        %indvar.next = add uint %indvar, 1              ; <uint> [#uses=1]
        br bool %tmp.2, label %no_exit, label %loopexit
instead of:
no_exit:                ; preds = %entry, %no_exit
        %indvar = phi ushort [ %indvar.next, %no_exit ], [ 0, %entry ]          ; <ushort> [#uses=2]
***     %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]            ; <uint> [#uses=3]
        %indvar = cast uint %indvar to int              ; <int> [#uses=1]
        %indvar = cast ushort %indvar to short          ; <short> [#uses=1]
        %tmp.7 = getelementptr short* %P, uint %indvar          ; <short*> [#uses=1]
        store short %indvar, short* %tmp.7
        %inc.0 = add int %indvar, 1             ; <int> [#uses=2]
        %tmp.2 = setlt int %inc.0, %N           ; <bool> [#uses=1]
        %indvar.next = add uint %indvar, 1
***     %indvar.next = add ushort %indvar, 1
        br bool %tmp.2, label %no_exit, label %loopexit
This is an improvement in register pressure, but probably doesn't happen that
often.
The more important fix will be to get rid of the redundant add.
llvm-svn: 13101
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 37 | 
1 files changed, 20 insertions, 17 deletions
| diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index d375dcf4a91..b69e0a181e8 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -390,10 +390,8 @@ void IndVarSimplify::runOnLoop(Loop *L) {    // Compute the type of the largest recurrence expression.    //    const Type *LargestType = IndVars[0].first->getType(); -  bool DifferingSizes = false;    for (unsigned i = 1, e = IndVars.size(); i != e; ++i) {      const Type *Ty = IndVars[i].first->getType(); -    DifferingSizes |= Ty->getPrimitiveSize() != LargestType->getPrimitiveSize();      if (Ty->getPrimitiveSize() > LargestType->getPrimitiveSize())        LargestType = Ty;    } @@ -411,30 +409,35 @@ void IndVarSimplify::runOnLoop(Loop *L) {    if (!isa<SCEVCouldNotCompute>(IterationCount))      LinearFunctionTestReplace(L, IterationCount, Rewriter); -#if 0 -  // If there were induction variables of other sizes, cast the primary -  // induction variable to the right size for them, avoiding the need for the -  // code evaluation methods to insert induction variables of different sizes. -  // FIXME! -  if (DifferingSizes) { -    std::map<unsigned, Value*> InsertedSizes; -    for (unsigned i = 0, e = IndVars.size(); i != e; ++i) { -    }     -  } -#endif -    // Now that we have a canonical induction variable, we can rewrite any    // recurrences in terms of the induction variable.  Start with the auxillary    // induction variables, and recursively rewrite any of their uses.    BasicBlock::iterator InsertPt = Header->begin();    while (isa<PHINode>(InsertPt)) ++InsertPt; +  // If there were induction variables of other sizes, cast the primary +  // induction variable to the right size for them, avoiding the need for the +  // code evaluation methods to insert induction variables of different sizes. +  std::map<unsigned, Value*> InsertedSizes; +  InsertedSizes[LargestType->getPrimitiveSize()] = IndVar;    while (!IndVars.empty()) {      PHINode *PN = IndVars.back().first; -    Value *NewVal = Rewriter.ExpandCodeFor(IndVars.back().second, InsertPt, -                                           PN->getType()); + +    const Type *Ty = PN->getType()->getUnsignedVersion(); +    Value *&IV = InsertedSizes[Ty->getPrimitiveSize()]; +    if (IV == 0) { +      // Insert a new cast instruction, which will hold this recurrence. +      std::string Name = PN->getName(); +      PN->setName(""); +      IV = new CastInst(IndVar, Ty, Name, InsertPt); +    } + +    Value *V = IV; +    if (PN->getType() != Ty) +      V = new CastInst(V, PN->getType(), V->getName(), InsertPt); +      // Replace the old PHI Node with the inserted computation. -    PN->replaceAllUsesWith(NewVal); +    PN->replaceAllUsesWith(V);      DeadInsts.insert(PN);      IndVars.pop_back();      ++NumRemoved; | 

