diff options
| author | Andrew Trick <atrick@apple.com> | 2011-12-09 06:19:40 +0000 | 
|---|---|---|
| committer | Andrew Trick <atrick@apple.com> | 2011-12-09 06:19:40 +0000 | 
| commit | d04d152998a56e3ab266dec7296f72694d34f0c5 (patch) | |
| tree | 68cc962be087ff117a4f5c674daac02c9d7a5992 /llvm/lib/Transforms/Scalar | |
| parent | 5895fa79d62e5b769a64d7668fbc43594479fb82 (diff) | |
| download | bcm5719-llvm-d04d152998a56e3ab266dec7296f72694d34f0c5.tar.gz bcm5719-llvm-d04d152998a56e3ab266dec7296f72694d34f0c5.zip | |
Add -unroll-runtime for unrolling loops with run-time trip counts.
Patch by Brendon Cahoon!
This extends the existing LoopUnroll and LoopUnrollPass. Brendon
measured no regressions in the llvm test suite with -unroll-runtime
enabled. This implementation works by using the existing loop
unrolling code to unroll the loop by a power-of-two (default 8). It
generates an if-then-else sequence of code prior to the loop to
execute the extra iterations before entering the unrolled loop.
llvm-svn: 146245
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp | 35 | 
1 files changed, 28 insertions, 7 deletions
| diff --git a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp index f3fdd4f3c51..22dbfe326c6 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -40,6 +40,10 @@ UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,    cl::desc("Allows loops to be partially unrolled until "             "-unroll-threshold loop size is reached.")); +static cl::opt<bool> +UnrollRuntime("unroll-runtime", cl::ZeroOrMore, cl::init(false), cl::Hidden, +  cl::desc("Unroll loops with run-time trip counts")); +  namespace {    class LoopUnroll : public LoopPass {    public: @@ -63,6 +67,10 @@ namespace {      // explicit -unroll-threshold).      static const unsigned OptSizeUnrollThreshold = 50; +    // Default unroll count for loops with run-time trip count if +    // -unroll-count is not set +    static const unsigned UnrollRuntimeCount = 8; +      unsigned CurrentCount;      unsigned CurrentThreshold;      bool     CurrentAllowPartial; @@ -151,8 +159,13 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {      TripCount = SE->getSmallConstantTripCount(L, LatchBlock);      TripMultiple = SE->getSmallConstantTripMultiple(L, LatchBlock);    } -  // Automatically select an unroll count. +  // Use a default unroll-count if the user doesn't specify a value +  // and the trip count is a run-time value.  The default is different +  // for run-time or compile-time trip count loops.    unsigned Count = CurrentCount; +  if (UnrollRuntime && CurrentCount == 0 && TripCount == 0) +    Count = UnrollRuntimeCount; +    if (Count == 0) {      // Conservative heuristic: if we know the trip count, see if we can      // completely unroll (subject to the threshold, checked below); otherwise @@ -177,15 +190,23 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {      if (TripCount != 1 && Size > Threshold) {        DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count              << " because size: " << Size << ">" << Threshold << "\n"); -      if (!CurrentAllowPartial) { +      if (!CurrentAllowPartial && !(UnrollRuntime && TripCount == 0)) {          DEBUG(dbgs() << "  will not try to unroll partially because "                << "-unroll-allow-partial not given\n");          return false;        } -      // Reduce unroll count to be modulo of TripCount for partial unrolling -      Count = Threshold / LoopSize; -      while (Count != 0 && TripCount%Count != 0) { -        Count--; +      if (TripCount) { +        // Reduce unroll count to be modulo of TripCount for partial unrolling +        Count = CurrentThreshold / LoopSize; +        while (Count != 0 && TripCount%Count != 0) +          Count--; +      } +      else if (UnrollRuntime) { +        // Reduce unroll count to be a lower power-of-two value +        while (Count != 0 && Size > CurrentThreshold) { +          Count >>= 1; +          Size = LoopSize*Count; +        }        }        if (Count < 2) {          DEBUG(dbgs() << "  could not unroll partially\n"); @@ -196,7 +217,7 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {    }    // Unroll the loop. -  if (!UnrollLoop(L, Count, TripCount, TripMultiple, LI, &LPM)) +  if (!UnrollLoop(L, Count, TripCount, UnrollRuntime, TripMultiple, LI, &LPM))      return false;    return true; | 

