~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/CodeGen/CalcSpillWeights.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
//===------------------------ CalcSpillWeights.cpp ------------------------===//
 
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
#define DEBUG_TYPE "calcspillweights"
 
11
 
 
12
#include "llvm/Function.h"
 
13
#include "llvm/ADT/SmallSet.h"
 
14
#include "llvm/CodeGen/CalcSpillWeights.h"
 
15
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
 
16
#include "llvm/CodeGen/MachineFunction.h"
 
17
#include "llvm/CodeGen/MachineLoopInfo.h"
 
18
#include "llvm/CodeGen/MachineRegisterInfo.h"
 
19
#include "llvm/CodeGen/SlotIndexes.h"
 
20
#include "llvm/Support/Debug.h"
 
21
#include "llvm/Support/raw_ostream.h"
 
22
#include "llvm/Target/TargetInstrInfo.h"
 
23
#include "llvm/Target/TargetMachine.h"
 
24
#include "llvm/Target/TargetRegisterInfo.h"
 
25
using namespace llvm;
 
26
 
 
27
char CalculateSpillWeights::ID = 0;
 
28
static RegisterPass<CalculateSpillWeights> X("calcspillweights",
 
29
                                             "Calculate spill weights");
 
30
 
 
31
void CalculateSpillWeights::getAnalysisUsage(AnalysisUsage &au) const {
 
32
  au.addRequired<LiveIntervals>();
 
33
  au.addRequired<MachineLoopInfo>();
 
34
  au.setPreservesAll();
 
35
  MachineFunctionPass::getAnalysisUsage(au);
 
36
}
 
37
 
 
38
bool CalculateSpillWeights::runOnMachineFunction(MachineFunction &fn) {
 
39
 
 
40
  DEBUG(dbgs() << "********** Compute Spill Weights **********\n"
 
41
               << "********** Function: "
 
42
               << fn.getFunction()->getName() << '\n');
 
43
 
 
44
  LiveIntervals *lis = &getAnalysis<LiveIntervals>();
 
45
  MachineLoopInfo *loopInfo = &getAnalysis<MachineLoopInfo>();
 
46
  const TargetInstrInfo *tii = fn.getTarget().getInstrInfo();
 
47
  MachineRegisterInfo *mri = &fn.getRegInfo();
 
48
 
 
49
  SmallSet<unsigned, 4> processed;
 
50
  for (MachineFunction::iterator mbbi = fn.begin(), mbbe = fn.end();
 
51
       mbbi != mbbe; ++mbbi) {
 
52
    MachineBasicBlock* mbb = mbbi;
 
53
    SlotIndex mbbEnd = lis->getMBBEndIdx(mbb);
 
54
    MachineLoop* loop = loopInfo->getLoopFor(mbb);
 
55
    unsigned loopDepth = loop ? loop->getLoopDepth() : 0;
 
56
    bool isExiting = loop ? loop->isLoopExiting(mbb) : false;
 
57
 
 
58
    for (MachineBasicBlock::const_iterator mii = mbb->begin(), mie = mbb->end();
 
59
         mii != mie; ++mii) {
 
60
      const MachineInstr *mi = mii;
 
61
      if (tii->isIdentityCopy(*mi) || mi->isImplicitDef() || mi->isDebugValue())
 
62
        continue;
 
63
 
 
64
      for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) {
 
65
        const MachineOperand &mopi = mi->getOperand(i);
 
66
        if (!mopi.isReg() || mopi.getReg() == 0)
 
67
          continue;
 
68
        unsigned reg = mopi.getReg();
 
69
        if (!TargetRegisterInfo::isVirtualRegister(mopi.getReg()))
 
70
          continue;
 
71
        // Multiple uses of reg by the same instruction. It should not
 
72
        // contribute to spill weight again.
 
73
        if (!processed.insert(reg))
 
74
          continue;
 
75
 
 
76
        bool hasDef = mopi.isDef();
 
77
        bool hasUse = !hasDef;
 
78
        for (unsigned j = i+1; j != e; ++j) {
 
79
          const MachineOperand &mopj = mi->getOperand(j);
 
80
          if (!mopj.isReg() || mopj.getReg() != reg)
 
81
            continue;
 
82
          hasDef |= mopj.isDef();
 
83
          hasUse |= mopj.isUse();
 
84
          if (hasDef && hasUse)
 
85
            break;
 
86
        }
 
87
 
 
88
        LiveInterval &regInt = lis->getInterval(reg);
 
89
        float weight = lis->getSpillWeight(hasDef, hasUse, loopDepth);
 
90
        if (hasDef && isExiting) {
 
91
          // Looks like this is a loop count variable update.
 
92
          SlotIndex defIdx = lis->getInstructionIndex(mi).getDefIndex();
 
93
          const LiveRange *dlr =
 
94
            lis->getInterval(reg).getLiveRangeContaining(defIdx);
 
95
          if (dlr->end >= mbbEnd)
 
96
            weight *= 3.0F;
 
97
        }
 
98
        regInt.weight += weight;
 
99
      }
 
100
      processed.clear();
 
101
    }
 
102
  }
 
103
 
 
104
  for (LiveIntervals::iterator I = lis->begin(), E = lis->end(); I != E; ++I) {
 
105
    LiveInterval &li = *I->second;
 
106
    if (TargetRegisterInfo::isVirtualRegister(li.reg)) {
 
107
      // If the live interval length is essentially zero, i.e. in every live
 
108
      // range the use follows def immediately, it doesn't make sense to spill
 
109
      // it and hope it will be easier to allocate for this li.
 
110
      if (isZeroLengthInterval(&li)) {
 
111
        li.weight = HUGE_VALF;
 
112
        continue;
 
113
      }
 
114
 
 
115
      bool isLoad = false;
 
116
      SmallVector<LiveInterval*, 4> spillIs;
 
117
      if (lis->isReMaterializable(li, spillIs, isLoad)) {
 
118
        // If all of the definitions of the interval are re-materializable,
 
119
        // it is a preferred candidate for spilling. If non of the defs are
 
120
        // loads, then it's potentially very cheap to re-materialize.
 
121
        // FIXME: this gets much more complicated once we support non-trivial
 
122
        // re-materialization.
 
123
        if (isLoad)
 
124
          li.weight *= 0.9F;
 
125
        else
 
126
          li.weight *= 0.5F;
 
127
      }
 
128
 
 
129
      // Slightly prefer live interval that has been assigned a preferred reg.
 
130
      std::pair<unsigned, unsigned> Hint = mri->getRegAllocationHint(li.reg);
 
131
      if (Hint.first || Hint.second)
 
132
        li.weight *= 1.01F;
 
133
 
 
134
      lis->normalizeSpillWeight(li);
 
135
    }
 
136
  }
 
137
  
 
138
  return false;
 
139
}
 
140
 
 
141
/// Returns true if the given live interval is zero length.
 
142
bool CalculateSpillWeights::isZeroLengthInterval(LiveInterval *li) const {
 
143
  for (LiveInterval::Ranges::const_iterator
 
144
       i = li->ranges.begin(), e = li->ranges.end(); i != e; ++i)
 
145
    if (i->end.getPrevIndex() > i->start)
 
146
      return false;
 
147
  return true;
 
148
}