~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/CodeGen/ProcessImplicitDefs.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
//===---------------------- ProcessImplicitDefs.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 "processimplicitdefs"
 
11
 
 
12
#include "llvm/CodeGen/ProcessImplicitDefs.h"
 
13
 
 
14
#include "llvm/ADT/DepthFirstIterator.h"
 
15
#include "llvm/ADT/SmallSet.h"
 
16
#include "llvm/Analysis/AliasAnalysis.h"
 
17
#include "llvm/CodeGen/LiveVariables.h"
 
18
#include "llvm/CodeGen/MachineInstr.h"
 
19
#include "llvm/CodeGen/MachineRegisterInfo.h"
 
20
#include "llvm/CodeGen/Passes.h"
 
21
#include "llvm/Support/Debug.h"
 
22
#include "llvm/Target/TargetInstrInfo.h"
 
23
#include "llvm/Target/TargetRegisterInfo.h"
 
24
 
 
25
 
 
26
using namespace llvm;
 
27
 
 
28
char ProcessImplicitDefs::ID = 0;
 
29
static RegisterPass<ProcessImplicitDefs> X("processimpdefs",
 
30
                                           "Process Implicit Definitions.");
 
31
 
 
32
void ProcessImplicitDefs::getAnalysisUsage(AnalysisUsage &AU) const {
 
33
  AU.setPreservesCFG();
 
34
  AU.addPreserved<AliasAnalysis>();
 
35
  AU.addPreserved<LiveVariables>();
 
36
  AU.addRequired<LiveVariables>();
 
37
  AU.addPreservedID(MachineLoopInfoID);
 
38
  AU.addPreservedID(MachineDominatorsID);
 
39
  AU.addPreservedID(TwoAddressInstructionPassID);
 
40
  AU.addPreservedID(PHIEliminationID);
 
41
  MachineFunctionPass::getAnalysisUsage(AU);
 
42
}
 
43
 
 
44
bool ProcessImplicitDefs::CanTurnIntoImplicitDef(MachineInstr *MI,
 
45
                                                 unsigned Reg, unsigned OpIdx,
 
46
                                                 const TargetInstrInfo *tii_) {
 
47
  unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
 
48
  if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
 
49
      Reg == SrcReg)
 
50
    return true;
 
51
 
 
52
  if (OpIdx == 2 && MI->isSubregToReg())
 
53
    return true;
 
54
  if (OpIdx == 1 && MI->isExtractSubreg())
 
55
    return true;
 
56
  return false;
 
57
}
 
58
 
 
59
/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure
 
60
/// there is one implicit_def for each use. Add isUndef marker to
 
61
/// implicit_def defs and their uses.
 
62
bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) {
 
63
 
 
64
  DEBUG(dbgs() << "********** PROCESS IMPLICIT DEFS **********\n"
 
65
               << "********** Function: "
 
66
               << ((Value*)fn.getFunction())->getName() << '\n');
 
67
 
 
68
  bool Changed = false;
 
69
 
 
70
  const TargetInstrInfo *tii_ = fn.getTarget().getInstrInfo();
 
71
  const TargetRegisterInfo *tri_ = fn.getTarget().getRegisterInfo();
 
72
  MachineRegisterInfo *mri_ = &fn.getRegInfo();
 
73
 
 
74
  LiveVariables *lv_ = &getAnalysis<LiveVariables>();
 
75
 
 
76
  SmallSet<unsigned, 8> ImpDefRegs;
 
77
  SmallVector<MachineInstr*, 8> ImpDefMIs;
 
78
  SmallVector<MachineInstr*, 4> RUses;
 
79
  SmallPtrSet<MachineBasicBlock*,16> Visited;
 
80
  SmallPtrSet<MachineInstr*, 8> ModInsts;
 
81
 
 
82
  MachineBasicBlock *Entry = fn.begin();
 
83
  for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
 
84
         DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
 
85
       DFI != E; ++DFI) {
 
86
    MachineBasicBlock *MBB = *DFI;
 
87
    for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
 
88
         I != E; ) {
 
89
      MachineInstr *MI = &*I;
 
90
      ++I;
 
91
      if (MI->isImplicitDef()) {
 
92
        unsigned Reg = MI->getOperand(0).getReg();
 
93
        ImpDefRegs.insert(Reg);
 
94
        if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
 
95
          for (const unsigned *SS = tri_->getSubRegisters(Reg); *SS; ++SS)
 
96
            ImpDefRegs.insert(*SS);
 
97
        }
 
98
        ImpDefMIs.push_back(MI);
 
99
        continue;
 
100
      }
 
101
 
 
102
      if (MI->isInsertSubreg()) {
 
103
        MachineOperand &MO = MI->getOperand(2);
 
104
        if (ImpDefRegs.count(MO.getReg())) {
 
105
          // %reg1032<def> = INSERT_SUBREG %reg1032, undef, 2
 
106
          // This is an identity copy, eliminate it now.
 
107
          if (MO.isKill()) {
 
108
            LiveVariables::VarInfo& vi = lv_->getVarInfo(MO.getReg());
 
109
            vi.removeKill(MI);
 
110
          }
 
111
          MI->eraseFromParent();
 
112
          Changed = true;
 
113
          continue;
 
114
        }
 
115
      }
 
116
 
 
117
      bool ChangedToImpDef = false;
 
118
      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
 
119
        MachineOperand& MO = MI->getOperand(i);
 
120
        if (!MO.isReg() || !MO.isUse() || MO.isUndef())
 
121
          continue;
 
122
        unsigned Reg = MO.getReg();
 
123
        if (!Reg)
 
124
          continue;
 
125
        if (!ImpDefRegs.count(Reg))
 
126
          continue;
 
127
        // Use is a copy, just turn it into an implicit_def.
 
128
        if (CanTurnIntoImplicitDef(MI, Reg, i, tii_)) {
 
129
          bool isKill = MO.isKill();
 
130
          MI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF));
 
131
          for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
 
132
            MI->RemoveOperand(j);
 
133
          if (isKill) {
 
134
            ImpDefRegs.erase(Reg);
 
135
            LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg);
 
136
            vi.removeKill(MI);
 
137
          }
 
138
          ChangedToImpDef = true;
 
139
          Changed = true;
 
140
          break;
 
141
        }
 
142
 
 
143
        Changed = true;
 
144
        MO.setIsUndef();
 
145
        if (MO.isKill() || MI->isRegTiedToDefOperand(i)) {
 
146
          // Make sure other uses of 
 
147
          for (unsigned j = i+1; j != e; ++j) {
 
148
            MachineOperand &MOJ = MI->getOperand(j);
 
149
            if (MOJ.isReg() && MOJ.isUse() && MOJ.getReg() == Reg)
 
150
              MOJ.setIsUndef();
 
151
          }
 
152
          ImpDefRegs.erase(Reg);
 
153
        }
 
154
      }
 
155
 
 
156
      if (ChangedToImpDef) {
 
157
        // Backtrack to process this new implicit_def.
 
158
        --I;
 
159
      } else {
 
160
        for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
 
161
          MachineOperand& MO = MI->getOperand(i);
 
162
          if (!MO.isReg() || !MO.isDef())
 
163
            continue;
 
164
          ImpDefRegs.erase(MO.getReg());
 
165
        }
 
166
      }
 
167
    }
 
168
 
 
169
    // Any outstanding liveout implicit_def's?
 
170
    for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) {
 
171
      MachineInstr *MI = ImpDefMIs[i];
 
172
      unsigned Reg = MI->getOperand(0).getReg();
 
173
      if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
 
174
          !ImpDefRegs.count(Reg)) {
 
175
        // Delete all "local" implicit_def's. That include those which define
 
176
        // physical registers since they cannot be liveout.
 
177
        MI->eraseFromParent();
 
178
        Changed = true;
 
179
        continue;
 
180
      }
 
181
 
 
182
      // If there are multiple defs of the same register and at least one
 
183
      // is not an implicit_def, do not insert implicit_def's before the
 
184
      // uses.
 
185
      bool Skip = false;
 
186
      SmallVector<MachineInstr*, 4> DeadImpDefs;
 
187
      for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg),
 
188
             DE = mri_->def_end(); DI != DE; ++DI) {
 
189
        MachineInstr *DeadImpDef = &*DI;
 
190
        if (!DeadImpDef->isImplicitDef()) {
 
191
          Skip = true;
 
192
          break;
 
193
        }
 
194
        DeadImpDefs.push_back(DeadImpDef);
 
195
      }
 
196
      if (Skip)
 
197
        continue;
 
198
 
 
199
      // The only implicit_def which we want to keep are those that are live
 
200
      // out of its block.
 
201
      for (unsigned j = 0, ee = DeadImpDefs.size(); j != ee; ++j)
 
202
        DeadImpDefs[j]->eraseFromParent();
 
203
      Changed = true;
 
204
 
 
205
      // Process each use instruction once.
 
206
      for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
 
207
             UE = mri_->use_end(); UI != UE; ++UI) {
 
208
        if (UI.getOperand().isUndef())
 
209
          continue;
 
210
        MachineInstr *RMI = &*UI;
 
211
        if (ModInsts.insert(RMI))
 
212
          RUses.push_back(RMI);
 
213
      }
 
214
 
 
215
      for (unsigned i = 0, e = RUses.size(); i != e; ++i) {
 
216
        MachineInstr *RMI = RUses[i];
 
217
 
 
218
        // Turn a copy use into an implicit_def.
 
219
        unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
 
220
        if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
 
221
            Reg == SrcReg) {
 
222
          RMI->setDesc(tii_->get(TargetOpcode::IMPLICIT_DEF));
 
223
 
 
224
          bool isKill = false;
 
225
          SmallVector<unsigned, 4> Ops;
 
226
          for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) {
 
227
            MachineOperand &RRMO = RMI->getOperand(j);
 
228
            if (RRMO.isReg() && RRMO.getReg() == Reg) {
 
229
              Ops.push_back(j);
 
230
              if (RRMO.isKill())
 
231
                isKill = true;
 
232
            }
 
233
          }
 
234
          // Leave the other operands along.
 
235
          for (unsigned j = 0, ee = Ops.size(); j != ee; ++j) {
 
236
            unsigned OpIdx = Ops[j];
 
237
            RMI->RemoveOperand(OpIdx-j);
 
238
          }
 
239
 
 
240
          // Update LiveVariables varinfo if the instruction is a kill.
 
241
          if (isKill) {
 
242
            LiveVariables::VarInfo& vi = lv_->getVarInfo(Reg);
 
243
            vi.removeKill(RMI);
 
244
          }
 
245
          continue;
 
246
        }
 
247
 
 
248
        // Replace Reg with a new vreg that's marked implicit.
 
249
        const TargetRegisterClass* RC = mri_->getRegClass(Reg);
 
250
        unsigned NewVReg = mri_->createVirtualRegister(RC);
 
251
        bool isKill = true;
 
252
        for (unsigned j = 0, ee = RMI->getNumOperands(); j != ee; ++j) {
 
253
          MachineOperand &RRMO = RMI->getOperand(j);
 
254
          if (RRMO.isReg() && RRMO.getReg() == Reg) {
 
255
            RRMO.setReg(NewVReg);
 
256
            RRMO.setIsUndef();
 
257
            if (isKill) {
 
258
              // Only the first operand of NewVReg is marked kill.
 
259
              RRMO.setIsKill();
 
260
              isKill = false;
 
261
            }
 
262
          }
 
263
        }
 
264
      }
 
265
      RUses.clear();
 
266
      ModInsts.clear();
 
267
    }
 
268
    ImpDefRegs.clear();
 
269
    ImpDefMIs.clear();
 
270
  }
 
271
 
 
272
  return Changed;
 
273
}
 
274