Skip to content
IndVarSimplify.cpp 39.8 KiB
Newer Older
//===- IndVarSimplify.cpp - Induction Variable Elimination ----------------===//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
// This transformation analyzes and transforms the induction variables (and
// computations derived from them) into simpler forms suitable for subsequent
// analysis and transformation.
//
// This transformation makes the following changes to each loop with an
// identifiable induction variable:
//   1. All loops are transformed to have a SINGLE canonical induction variable
//      which starts at zero and steps by one.
//   2. The canonical induction variable is guaranteed to be the first PHI node
//      in the loop header block.
//   3. The canonical induction variable is guaranteed to be in a wide enough
//      type so that IV expressions need not be (directly) zero-extended or
//      sign-extended.
//   4. Any pointer arithmetic recurrences are raised to use array subscripts.
//
// If the trip count of a loop is computable, this pass also makes the following
// changes:
//   1. The exit condition for the loop is canonicalized to compare the
//      induction value against the exit value.  This turns loops like:
//        'for (i = 7; i*i < 1000; ++i)' into 'for (i = 0; i != 25; ++i)'
//   2. Any use outside of the loop of an expression derived from the indvar
//      is changed to compute the derived value outside of the loop, eliminating
//      the dependence on the exit value of the induction variable.  If the only
//      purpose of the loop is to compute the exit value of some derived
//      expression, this transformation will make the loop dead.
//
// This transformation should be followed by strength reduction after all of the
// desired loop transformations have been performed.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/BasicBlock.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/LLVMContext.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/IVUsers.h"
#include "llvm/Analysis/ScalarEvolutionExpander.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Reid Spencer's avatar
Reid Spencer committed
#include "llvm/ADT/SmallVector.h"
Reid Spencer's avatar
Reid Spencer committed
#include "llvm/ADT/Statistic.h"
STATISTIC(NumRemoved , "Number of aux indvars removed");
STATISTIC(NumInserted, "Number of canonical indvars added");
STATISTIC(NumReplaced, "Number of exit values replaced");
STATISTIC(NumLFTR    , "Number of loop exit tests replaced");
Chris Lattner's avatar
Chris Lattner committed

  class IndVarSimplify : public LoopPass {
    LoopInfo        *LI;
    ScalarEvolution *SE;
Chris Lattner's avatar
Chris Lattner committed
  public:
Dan Gohman's avatar
Dan Gohman committed
    static char ID; // Pass identification, replacement for typeid
    IndVarSimplify() : LoopPass(&ID) {}
Dan Gohman's avatar
Dan Gohman committed
    virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
Dan Gohman's avatar
Dan Gohman committed
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<DominatorTree>();
      AU.addRequired<LoopInfo>();
      AU.addRequired<ScalarEvolution>();
      AU.addRequiredID(LoopSimplifyID);
      AU.addRequiredID(LCSSAID);
      AU.addRequired<IVUsers>();
      AU.addPreserved<ScalarEvolution>();
      AU.addPreservedID(LoopSimplifyID);
      AU.addPreservedID(LCSSAID);
      AU.addPreserved<IVUsers>();
      AU.setPreservesCFG();
    }
Chris Lattner's avatar
Chris Lattner committed

    void EliminateIVRemainders();
    void RewriteNonIntegerIVs(Loop *L);

Dan Gohman's avatar
Dan Gohman committed
    ICmpInst *LinearFunctionTestReplace(Loop *L, const SCEV *BackedgeTakenCount,
                                   BasicBlock *ExitingBlock,
                                   BranchInst *BI,
    void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
    void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter);
    void SinkUnusedInvariants(Loop *L);

    void HandleFloatingPointIV(Loop *L, PHINode *PH);
Chris Lattner's avatar
Chris Lattner committed
  };
INITIALIZE_PASS(IndVarSimplify, "indvars",
                "Canonicalize Induction Variables", false, false);
Pass *llvm::createIndVarSimplifyPass() {
Chris Lattner's avatar
Chris Lattner committed
  return new IndVarSimplify();
/// LinearFunctionTestReplace - This method rewrites the exit condition of the
/// loop to be a canonical != comparison against the incremented loop induction
/// variable.  This pass is able to rewrite the exit tests of any loop where the
/// SCEV analysis can determine a loop-invariant trip count of the loop, which
/// is actually a much broader range than just linear tests.
ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
Dan Gohman's avatar
Dan Gohman committed
                                   const SCEV *BackedgeTakenCount,
                                   BasicBlock *ExitingBlock,
                                   BranchInst *BI,
  // Special case: If the backedge-taken count is a UDiv, it's very likely a
  // UDiv that ScalarEvolution produced in order to compute a precise
  // expression, rather than a UDiv from the user's code. If we can't find a
  // UDiv in the code with some simple searching, assume the former and forego
  // rewriting the loop.
  if (isa<SCEVUDivExpr>(BackedgeTakenCount)) {
    ICmpInst *OrigCond = dyn_cast<ICmpInst>(BI->getCondition());
    if (!OrigCond) return 0;
    const SCEV *R = SE->getSCEV(OrigCond->getOperand(1));
    R = SE->getMinusSCEV(R, SE->getConstant(R->getType(), 1));
    if (R != BackedgeTakenCount) {
      const SCEV *L = SE->getSCEV(OrigCond->getOperand(0));
      L = SE->getMinusSCEV(L, SE->getConstant(L->getType(), 1));
  // If the exiting block is not the same as the backedge block, we must compare
  // against the preincremented value, otherwise we prefer to compare against
  // the post-incremented value.
Dan Gohman's avatar
Dan Gohman committed
  const SCEV *RHS = BackedgeTakenCount;
  if (ExitingBlock == L->getLoopLatch()) {
    // Add one to the "backedge-taken" count to get the trip count.
    // If this addition may overflow, we have to be more pessimistic and
    // cast the induction variable before doing the add.
    const SCEV *Zero = SE->getConstant(BackedgeTakenCount->getType(), 0);
Dan Gohman's avatar
Dan Gohman committed
    const SCEV *N =
      SE->getAddExpr(BackedgeTakenCount,
                     SE->getConstant(BackedgeTakenCount->getType(), 1));
    if ((isa<SCEVConstant>(N) && !N->isZero()) ||
        SE->isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, N, Zero)) {
      // No overflow. Cast the sum.
      RHS = SE->getTruncateOrZeroExtend(N, IndVar->getType());
    } else {
      // Potential overflow. Cast before doing the add.
      RHS = SE->getTruncateOrZeroExtend(BackedgeTakenCount,
                                        IndVar->getType());
      RHS = SE->getAddExpr(RHS,
                           SE->getConstant(IndVar->getType(), 1));
    // The BackedgeTaken expression contains the number of times that the
    // backedge branches to the loop header.  This is one less than the
    // number of times the loop executes, so use the incremented indvar.
    CmpIndVar = IndVar->getIncomingValueForBlock(ExitingBlock);
  } else {
    // We have to use the preincremented value...
    RHS = SE->getTruncateOrZeroExtend(BackedgeTakenCount,
                                      IndVar->getType());
  // Expand the code for the iteration count.
  assert(RHS->isLoopInvariant(L) &&
         "Computed iteration count is not loop invariant!");
  Value *ExitCnt = Rewriter.expandCodeFor(RHS, IndVar->getType(), BI);
Reid Spencer's avatar
Reid Spencer committed
  // Insert a new icmp_ne or icmp_eq instruction before the branch.
  ICmpInst::Predicate Opcode;
  if (L->contains(BI->getSuccessor(0)))
Reid Spencer's avatar
Reid Spencer committed
    Opcode = ICmpInst::ICMP_NE;
Loading
Loading full blame...