~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Transforms/IPO/GlobalDCE.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
//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
 
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 transform is designed to eliminate unreachable internal globals from the
 
11
// program.  It uses an aggressive algorithm, searching out globals that are
 
12
// known to be alive.  After it finds all of the globals which are needed, it
 
13
// deletes whatever is left over.  This allows it to delete recursive chunks of
 
14
// the program which are unreachable.
 
15
//
 
16
//===----------------------------------------------------------------------===//
 
17
 
 
18
#define DEBUG_TYPE "globaldce"
 
19
#include "llvm/Transforms/IPO.h"
 
20
#include "llvm/Constants.h"
 
21
#include "llvm/Module.h"
 
22
#include "llvm/Pass.h"
 
23
#include "llvm/ADT/SmallPtrSet.h"
 
24
#include "llvm/ADT/Statistic.h"
 
25
using namespace llvm;
 
26
 
 
27
STATISTIC(NumAliases  , "Number of global aliases removed");
 
28
STATISTIC(NumFunctions, "Number of functions removed");
 
29
STATISTIC(NumVariables, "Number of global variables removed");
 
30
 
 
31
namespace {
 
32
  struct GlobalDCE : public ModulePass {
 
33
    static char ID; // Pass identification, replacement for typeid
 
34
    GlobalDCE() : ModulePass(&ID) {}
 
35
 
 
36
    // run - Do the GlobalDCE pass on the specified module, optionally updating
 
37
    // the specified callgraph to reflect the changes.
 
38
    //
 
39
    bool runOnModule(Module &M);
 
40
 
 
41
  private:
 
42
    SmallPtrSet<GlobalValue*, 32> AliveGlobals;
 
43
 
 
44
    /// GlobalIsNeeded - mark the specific global value as needed, and
 
45
    /// recursively mark anything that it uses as also needed.
 
46
    void GlobalIsNeeded(GlobalValue *GV);
 
47
    void MarkUsedGlobalsAsNeeded(Constant *C);
 
48
 
 
49
    bool RemoveUnusedGlobalValue(GlobalValue &GV);
 
50
  };
 
51
}
 
52
 
 
53
char GlobalDCE::ID = 0;
 
54
static RegisterPass<GlobalDCE> X("globaldce", "Dead Global Elimination");
 
55
 
 
56
ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); }
 
57
 
 
58
bool GlobalDCE::runOnModule(Module &M) {
 
59
  bool Changed = false;
 
60
  
 
61
  // Loop over the module, adding globals which are obviously necessary.
 
62
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
 
63
    Changed |= RemoveUnusedGlobalValue(*I);
 
64
    // Functions with external linkage are needed if they have a body
 
65
    if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage() &&
 
66
        !I->isDeclaration() && !I->hasAvailableExternallyLinkage())
 
67
      GlobalIsNeeded(I);
 
68
  }
 
69
 
 
70
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
 
71
       I != E; ++I) {
 
72
    Changed |= RemoveUnusedGlobalValue(*I);
 
73
    // Externally visible & appending globals are needed, if they have an
 
74
    // initializer.
 
75
    if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage() &&
 
76
        !I->isDeclaration() && !I->hasAvailableExternallyLinkage())
 
77
      GlobalIsNeeded(I);
 
78
  }
 
79
 
 
80
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
 
81
       I != E; ++I) {
 
82
    Changed |= RemoveUnusedGlobalValue(*I);
 
83
    // Externally visible aliases are needed.
 
84
    if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage())
 
85
      GlobalIsNeeded(I);
 
86
  }
 
87
 
 
88
  // Now that all globals which are needed are in the AliveGlobals set, we loop
 
89
  // through the program, deleting those which are not alive.
 
90
  //
 
91
 
 
92
  // The first pass is to drop initializers of global variables which are dead.
 
93
  std::vector<GlobalVariable*> DeadGlobalVars;   // Keep track of dead globals
 
94
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
 
95
       I != E; ++I)
 
96
    if (!AliveGlobals.count(I)) {
 
97
      DeadGlobalVars.push_back(I);         // Keep track of dead globals
 
98
      I->setInitializer(0);
 
99
    }
 
100
 
 
101
  // The second pass drops the bodies of functions which are dead...
 
102
  std::vector<Function*> DeadFunctions;
 
103
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
 
104
    if (!AliveGlobals.count(I)) {
 
105
      DeadFunctions.push_back(I);         // Keep track of dead globals
 
106
      if (!I->isDeclaration())
 
107
        I->deleteBody();
 
108
    }
 
109
 
 
110
  // The third pass drops targets of aliases which are dead...
 
111
  std::vector<GlobalAlias*> DeadAliases;
 
112
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
 
113
       ++I)
 
114
    if (!AliveGlobals.count(I)) {
 
115
      DeadAliases.push_back(I);
 
116
      I->setAliasee(0);
 
117
    }
 
118
 
 
119
  if (!DeadFunctions.empty()) {
 
120
    // Now that all interferences have been dropped, delete the actual objects
 
121
    // themselves.
 
122
    for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
 
123
      RemoveUnusedGlobalValue(*DeadFunctions[i]);
 
124
      M.getFunctionList().erase(DeadFunctions[i]);
 
125
    }
 
126
    NumFunctions += DeadFunctions.size();
 
127
    Changed = true;
 
128
  }
 
129
 
 
130
  if (!DeadGlobalVars.empty()) {
 
131
    for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
 
132
      RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
 
133
      M.getGlobalList().erase(DeadGlobalVars[i]);
 
134
    }
 
135
    NumVariables += DeadGlobalVars.size();
 
136
    Changed = true;
 
137
  }
 
138
 
 
139
  // Now delete any dead aliases.
 
140
  if (!DeadAliases.empty()) {
 
141
    for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
 
142
      RemoveUnusedGlobalValue(*DeadAliases[i]);
 
143
      M.getAliasList().erase(DeadAliases[i]);
 
144
    }
 
145
    NumAliases += DeadAliases.size();
 
146
    Changed = true;
 
147
  }
 
148
 
 
149
  // Make sure that all memory is released
 
150
  AliveGlobals.clear();
 
151
 
 
152
  return Changed;
 
153
}
 
154
 
 
155
/// GlobalIsNeeded - the specific global value as needed, and
 
156
/// recursively mark anything that it uses as also needed.
 
157
void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
 
158
  // If the global is already in the set, no need to reprocess it.
 
159
  if (!AliveGlobals.insert(G))
 
160
    return;
 
161
  
 
162
  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G)) {
 
163
    // If this is a global variable, we must make sure to add any global values
 
164
    // referenced by the initializer to the alive set.
 
165
    if (GV->hasInitializer())
 
166
      MarkUsedGlobalsAsNeeded(GV->getInitializer());
 
167
  } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
 
168
    // The target of a global alias is needed.
 
169
    MarkUsedGlobalsAsNeeded(GA->getAliasee());
 
170
  } else {
 
171
    // Otherwise this must be a function object.  We have to scan the body of
 
172
    // the function looking for constants and global values which are used as
 
173
    // operands.  Any operands of these types must be processed to ensure that
 
174
    // any globals used will be marked as needed.
 
175
    Function *F = cast<Function>(G);
 
176
 
 
177
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
 
178
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
 
179
        for (User::op_iterator U = I->op_begin(), E = I->op_end(); U != E; ++U)
 
180
          if (GlobalValue *GV = dyn_cast<GlobalValue>(*U))
 
181
            GlobalIsNeeded(GV);
 
182
          else if (Constant *C = dyn_cast<Constant>(*U))
 
183
            MarkUsedGlobalsAsNeeded(C);
 
184
  }
 
185
}
 
186
 
 
187
void GlobalDCE::MarkUsedGlobalsAsNeeded(Constant *C) {
 
188
  if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
 
189
    return GlobalIsNeeded(GV);
 
190
  
 
191
  // Loop over all of the operands of the constant, adding any globals they
 
192
  // use to the list of needed globals.
 
193
  for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I)
 
194
    if (Constant *OpC = dyn_cast<Constant>(*I))
 
195
      MarkUsedGlobalsAsNeeded(OpC);
 
196
}
 
197
 
 
198
// RemoveUnusedGlobalValue - Loop over all of the uses of the specified
 
199
// GlobalValue, looking for the constant pointer ref that may be pointing to it.
 
200
// If found, check to see if the constant pointer ref is safe to destroy, and if
 
201
// so, nuke it.  This will reduce the reference count on the global value, which
 
202
// might make it deader.
 
203
//
 
204
bool GlobalDCE::RemoveUnusedGlobalValue(GlobalValue &GV) {
 
205
  if (GV.use_empty()) return false;
 
206
  GV.removeDeadConstantUsers();
 
207
  return GV.use_empty();
 
208
}