~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/InlineCost.h"
 
20
#include "llvm/Support/CommandLine.h"
 
21
#include "llvm/Support/Debug.h"
 
22
#include "llvm/Support/raw_ostream.h"
 
23
#include "llvm/Transforms/Utils/UnrollLoop.h"
 
24
#include <climits>
 
25
 
 
26
using namespace llvm;
 
27
 
 
28
static cl::opt<unsigned>
 
29
UnrollThreshold("unroll-threshold", cl::init(100), cl::Hidden,
 
30
  cl::desc("The cut-off point for automatic loop unrolling"));
 
31
 
 
32
static cl::opt<unsigned>
 
33
UnrollCount("unroll-count", cl::init(0), cl::Hidden,
 
34
  cl::desc("Use this unroll count for all loops, for testing purposes"));
 
35
 
 
36
static cl::opt<bool>
 
37
UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden,
 
38
  cl::desc("Allows loops to be partially unrolled until "
 
39
           "-unroll-threshold loop size is reached."));
 
40
 
 
41
namespace {
 
42
  class LoopUnroll : public LoopPass {
 
43
  public:
 
44
    static char ID; // Pass ID, replacement for typeid
 
45
    LoopUnroll() : LoopPass(&ID) {}
 
46
 
 
47
    /// A magic value for use with the Threshold parameter to indicate
 
48
    /// that the loop unroll should be performed regardless of how much
 
49
    /// code expansion would result.
 
50
    static const unsigned NoThreshold = UINT_MAX;
 
51
 
 
52
    bool runOnLoop(Loop *L, LPPassManager &LPM);
 
53
 
 
54
    /// This transformation requires natural loop information & requires that
 
55
    /// loop preheaders be inserted into the CFG...
 
56
    ///
 
57
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
 
58
      AU.addRequiredID(LoopSimplifyID);
 
59
      AU.addRequiredID(LCSSAID);
 
60
      AU.addRequired<LoopInfo>();
 
61
      AU.addPreservedID(LCSSAID);
 
62
      AU.addPreserved<LoopInfo>();
 
63
      // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
 
64
      // If loop unroll does not preserve dom info then LCSSA pass on next
 
65
      // loop will receive invalid dom info.
 
66
      // For now, recreate dom info, if loop is unrolled.
 
67
      AU.addPreserved<DominatorTree>();
 
68
      AU.addPreserved<DominanceFrontier>();
 
69
    }
 
70
  };
 
71
}
 
72
 
 
73
char LoopUnroll::ID = 0;
 
74
static RegisterPass<LoopUnroll> X("loop-unroll", "Unroll loops");
 
75
 
 
76
Pass *llvm::createLoopUnrollPass() { return new LoopUnroll(); }
 
77
 
 
78
/// ApproximateLoopSize - Approximate the size of the loop.
 
79
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) {
 
80
  CodeMetrics Metrics;
 
81
  for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
 
82
       I != E; ++I)
 
83
    Metrics.analyzeBasicBlock(*I);
 
84
  NumCalls = Metrics.NumCalls;
 
85
  return Metrics.NumInsts;
 
86
}
 
87
 
 
88
bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
 
89
  assert(L->isLCSSAForm());
 
90
  LoopInfo *LI = &getAnalysis<LoopInfo>();
 
91
 
 
92
  BasicBlock *Header = L->getHeader();
 
93
  DEBUG(dbgs() << "Loop Unroll: F[" << Header->getParent()->getName()
 
94
        << "] Loop %" << Header->getName() << "\n");
 
95
  (void)Header;
 
96
 
 
97
  // Find trip count
 
98
  unsigned TripCount = L->getSmallConstantTripCount();
 
99
  unsigned Count = UnrollCount;
 
100
 
 
101
  // Automatically select an unroll count.
 
102
  if (Count == 0) {
 
103
    // Conservative heuristic: if we know the trip count, see if we can
 
104
    // completely unroll (subject to the threshold, checked below); otherwise
 
105
    // try to find greatest modulo of the trip count which is still under
 
106
    // threshold value.
 
107
    if (TripCount == 0)
 
108
      return false;
 
109
    Count = TripCount;
 
110
  }
 
111
 
 
112
  // Enforce the threshold.
 
113
  if (UnrollThreshold != NoThreshold) {
 
114
    unsigned NumCalls;
 
115
    unsigned LoopSize = ApproximateLoopSize(L, NumCalls);
 
116
    DEBUG(dbgs() << "  Loop Size = " << LoopSize << "\n");
 
117
    if (NumCalls != 0) {
 
118
      DEBUG(dbgs() << "  Not unrolling loop with function calls.\n");
 
119
      return false;
 
120
    }
 
121
    uint64_t Size = (uint64_t)LoopSize*Count;
 
122
    if (TripCount != 1 && Size > UnrollThreshold) {
 
123
      DEBUG(dbgs() << "  Too large to fully unroll with count: " << Count
 
124
            << " because size: " << Size << ">" << UnrollThreshold << "\n");
 
125
      if (!UnrollAllowPartial) {
 
126
        DEBUG(dbgs() << "  will not try to unroll partially because "
 
127
              << "-unroll-allow-partial not given\n");
 
128
        return false;
 
129
      }
 
130
      // Reduce unroll count to be modulo of TripCount for partial unrolling
 
131
      Count = UnrollThreshold / LoopSize;
 
132
      while (Count != 0 && TripCount%Count != 0) {
 
133
        Count--;
 
134
      }
 
135
      if (Count < 2) {
 
136
        DEBUG(dbgs() << "  could not unroll partially\n");
 
137
        return false;
 
138
      }
 
139
      DEBUG(dbgs() << "  partially unrolling with count: " << Count << "\n");
 
140
    }
 
141
  }
 
142
 
 
143
  // Unroll the loop.
 
144
  Function *F = L->getHeader()->getParent();
 
145
  if (!UnrollLoop(L, Count, LI, &LPM))
 
146
    return false;
 
147
 
 
148
  // FIXME: Reconstruct dom info, because it is not preserved properly.
 
149
  DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
 
150
  if (DT) {
 
151
    DT->runOnFunction(*F);
 
152
    DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>();
 
153
    if (DF)
 
154
      DF->runOnFunction(*F);
 
155
  }
 
156
  return true;
 
157
}