Home | History | Annotate | Download | only in Scalar
      1 //===-- LoopUnroll.cpp - Loop unroller pass -------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This pass implements a simple loop unroller.  It works best when loops have
     11 // been canonicalized by the -indvars pass, allowing it to determine the trip
     12 // counts of loops easily.
     13 //===----------------------------------------------------------------------===//
     14 
     15 #define DEBUG_TYPE "loop-unroll"
     16 #include "llvm/IntrinsicInst.h"
     17 #include "llvm/Transforms/Scalar.h"
     18 #include "llvm/Analysis/LoopPass.h"
     19 #include "llvm/Analysis/CodeMetrics.h"
     20 #include "llvm/Analysis/ScalarEvolution.h"
     21 #include "llvm/Support/CommandLine.h"
     22 #include "llvm/Support/Debug.h"
     23 #include "llvm/Support/raw_ostream.h"
     24 #include "llvm/Transforms/Utils/UnrollLoop.h"
     25 #include "llvm/Target/TargetData.h"
     26 #include <climits>
     27 
     28 using namespace llvm;
     29 
     30 static cl::opt<unsigned>
     31 UnrollThreshold("unroll-threshold", cl::init(150), cl::Hidden,
     32   cl::desc("The cut-off point for automatic loop unrolling"));
     33 
     34 static cl::opt<unsigned>
     35 UnrollCount("unroll-count", cl::init(0), cl::Hidden,
     36   cl::desc("Use this unroll count for all loops, for testing purposes"));
     37 
     38 static cl::opt<bool>
     39 UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,
     40   cl::desc("Allows loops to be partially unrolled until "
     41            "-unroll-threshold loop size is reached."));
     42 
     43 // Temporary flag to be removed in 3.0
     44 static cl::opt<bool>
     45 NoSCEVUnroll("disable-unroll-scev", cl::init(false), cl::Hidden,
     46   cl::desc("Use ScalarEvolution to analyze loop trip counts for unrolling"));
     47 
     48 namespace {
     49   class LoopUnroll : public LoopPass {
     50   public:
     51     static char ID; // Pass ID, replacement for typeid
     52     LoopUnroll(int T = -1, int C = -1,  int P = -1) : LoopPass(ID) {
     53       CurrentThreshold = (T == -1) ? UnrollThreshold : unsigned(T);
     54       CurrentCount = (C == -1) ? UnrollCount : unsigned(C);
     55       CurrentAllowPartial = (P == -1) ? UnrollAllowPartial : (bool)P;
     56 
     57       UserThreshold = (T != -1) || (UnrollThreshold.getNumOccurrences() > 0);
     58 
     59       initializeLoopUnrollPass(*PassRegistry::getPassRegistry());
     60     }
     61 
     62     /// A magic value for use with the Threshold parameter to indicate
     63     /// that the loop unroll should be performed regardless of how much
     64     /// code expansion would result.
     65     static const unsigned NoThreshold = UINT_MAX;
     66 
     67     // Threshold to use when optsize is specified (and there is no
     68     // explicit -unroll-threshold).
     69     static const unsigned OptSizeUnrollThreshold = 50;
     70 
     71     unsigned CurrentCount;
     72     unsigned CurrentThreshold;
     73     bool     CurrentAllowPartial;
     74     bool     UserThreshold;        // CurrentThreshold is user-specified.
     75 
     76     bool runOnLoop(Loop *L, LPPassManager &LPM);
     77 
     78     /// This transformation requires natural loop information & requires that
     79     /// loop preheaders be inserted into the CFG...
     80     ///
     81     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     82       AU.addRequired<LoopInfo>();
     83       AU.addPreserved<LoopInfo>();
     84       AU.addRequiredID(LoopSimplifyID);
     85       AU.addPreservedID(LoopSimplifyID);
     86       AU.addRequiredID(LCSSAID);
     87       AU.addPreservedID(LCSSAID);
     88       AU.addRequired<ScalarEvolution>();
     89       AU.addPreserved<ScalarEvolution>();
     90       // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
     91       // If loop unroll does not preserve dom info then LCSSA pass on next
     92       // loop will receive invalid dom info.
     93       // For now, recreate dom info, if loop is unrolled.
     94       AU.addPreserved<DominatorTree>();
     95     }
     96   };
     97 }
     98 
     99 char LoopUnroll::ID = 0;
    100 INITIALIZE_PASS_BEGIN(LoopUnroll, "loop-unroll", "Unroll loops", false, false)
    101 INITIALIZE_PASS_DEPENDENCY(LoopInfo)
    102 INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
    103 INITIALIZE_PASS_DEPENDENCY(LCSSA)
    104 INITIALIZE_PASS_END(LoopUnroll, "loop-unroll", "Unroll loops", false, false)
    105 
    106 Pass *llvm::createLoopUnrollPass(int Threshold, int Count, int AllowPartial) {
    107   return new LoopUnroll(Threshold, Count, AllowPartial);
    108 }
    109 
    110 /// ApproximateLoopSize - Approximate the size of the loop.
    111 static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
    112                                     const TargetData *TD) {
    113   CodeMetrics Metrics;
    114   for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
    115        I != E; ++I)
    116     Metrics.analyzeBasicBlock(*I, TD);
    117   NumCalls = Metrics.NumInlineCandidates;
    118 
    119   unsigned LoopSize = Metrics.NumInsts;
    120 
    121   // Don't allow an estimate of size zero.  This would allows unrolling of loops
    122   // with huge iteration counts, which is a compile time problem even if it's
    123   // not a problem for code quality.
    124   if (LoopSize == 0) LoopSize = 1;
    125 
    126   return LoopSize;
    127 }
    128 
    129 bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
    130   LoopInfo *LI = &getAnalysis<LoopInfo>();
    131   ScalarEvolution *SE = &getAnalysis<ScalarEvolution>();
    132 
    133   BasicBlock *Header = L->getHeader();
    134   DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()
    135         << "] Loop %" << Header->getName() << "\n");
    136   (void)Header;
    137 
    138   // Determine the current unrolling threshold.  While this is normally set
    139   // from UnrollThreshold, it is overridden to a smaller value if the current
    140   // function is marked as optimize-for-size, and the unroll threshold was
    141   // not user specified.
    142   unsigned Threshold = CurrentThreshold;
    143   if (!UserThreshold &&
    144       Header->getParent()->hasFnAttr(Attribute::OptimizeForSize))
    145     Threshold = OptSizeUnrollThreshold;
    146 
    147   // Find trip count and trip multiple if count is not available
    148   unsigned TripCount = 0;
    149   unsigned TripMultiple = 1;
    150   if (!NoSCEVUnroll) {
    151     // Find "latch trip count". UnrollLoop assumes that control cannot exit
    152     // via the loop latch on any iteration prior to TripCount. The loop may exit
    153     // early via an earlier branch.
    154     BasicBlock *LatchBlock = L->getLoopLatch();
    155     if (LatchBlock) {
    156       TripCount = SE->getSmallConstantTripCount(L, LatchBlock);
    157       TripMultiple = SE->getSmallConstantTripMultiple(L, LatchBlock);
    158     }
    159   }
    160   else {
    161     TripCount = L->getSmallConstantTripCount();
    162     if (TripCount == 0)
    163       TripMultiple = L->getSmallConstantTripMultiple();
    164   }
    165   // Automatically select an unroll count.
    166   unsigned Count = CurrentCount;
    167   if (Count == 0) {
    168     // Conservative heuristic: if we know the trip count, see if we can
    169     // completely unroll (subject to the threshold, checked below); otherwise
    170     // try to find greatest modulo of the trip count which is still under
    171     // threshold value.
    172     if (TripCount == 0)
    173       return false;
    174     Count = TripCount;
    175   }
    176 
    177   // Enforce the threshold.
    178   if (Threshold != NoThreshold) {
    179     const TargetData *TD = getAnalysisIfAvailable<TargetData>();
    180     unsigned NumInlineCandidates;
    181     unsigned LoopSize = ApproximateLoopSize(L, NumInlineCandidates, TD);
    182     DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
    183     if (NumInlineCandidates != 0) {
    184       DEBUG(dbgs() << "  Not unrolling loop with inlinable calls.\n");
    185       return false;
    186     }
    187     uint64_t Size = (uint64_t)LoopSize*Count;
    188     if (TripCount != 1 && Size > Threshold) {
    189       DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count
    190             << " because size: " << Size << ">" << Threshold << "\n");
    191       if (!CurrentAllowPartial) {
    192         DEBUG(dbgs() << "  will not try to unroll partially because "
    193               << "-unroll-allow-partial not given\n");
    194         return false;
    195       }
    196       // Reduce unroll count to be modulo of TripCount for partial unrolling
    197       Count = Threshold / LoopSize;
    198       while (Count != 0 && TripCount%Count != 0) {
    199         Count--;
    200       }
    201       if (Count < 2) {
    202         DEBUG(dbgs() << "  could not unroll partially\n");
    203         return false;
    204       }
    205       DEBUG(dbgs() << "  partially unrolling with count: " << Count << "\n");
    206     }
    207   }
    208 
    209   // Unroll the loop.
    210   if (!UnrollLoop(L, Count, TripCount, TripMultiple, LI, &LPM))
    211     return false;
    212 
    213   return true;
    214 }
    215