//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
//===----------------------------------------------------------------------===//
//
// This transform is designed to eliminate unreachable internal globals from the
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "globaldce"
#include "llvm/Transforms/IPO.h"
#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
#include <set>
using namespace llvm;
-namespace {
- Statistic<> NumFunctions("globaldce","Number of functions removed");
- Statistic<> NumVariables("globaldce","Number of global variables removed");
+STATISTIC(NumFunctions, "Number of functions removed");
+STATISTIC(NumVariables, "Number of global variables removed");
- struct GlobalDCE : public ModulePass {
+namespace {
+ struct VISIBILITY_HIDDEN GlobalDCE : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ GlobalDCE() : ModulePass((intptr_t)&ID) {}
+
// run - Do the GlobalDCE pass on the specified module, optionally updating
// the specified callgraph to reflect the changes.
//
bool SafeToDestroyConstant(Constant* C);
bool RemoveUnusedGlobalValue(GlobalValue &GV);
};
- RegisterOpt<GlobalDCE> X("globaldce", "Dead Global Elimination");
}
+char GlobalDCE::ID = 0;
+static RegisterPass<GlobalDCE> X("globaldce", "Dead Global Elimination");
+
ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); }
bool GlobalDCE::runOnModule(Module &M) {
Changed |= RemoveUnusedGlobalValue(*I);
// Functions with external linkage are needed if they have a body
if ((!I->hasInternalLinkage() && !I->hasLinkOnceLinkage()) &&
- !I->isExternal())
+ !I->isDeclaration())
GlobalIsNeeded(I);
}
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) {
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I) {
Changed |= RemoveUnusedGlobalValue(*I);
// Externally visible & appending globals are needed, if they have an
// initializer.
if ((!I->hasInternalLinkage() && !I->hasLinkOnceLinkage()) &&
- !I->isExternal())
+ !I->isDeclaration())
GlobalIsNeeded(I);
}
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I != E; ++I) {
+ // Aliases are always needed even if they are not used.
+ MarkUsedGlobalsAsNeeded(I->getAliasee());
+ }
+
// Now that all globals which are needed are in the AliveGlobals set, we loop
// through the program, deleting those which are not alive.
//
// The first pass is to drop initializers of global variables which are dead.
std::vector<GlobalVariable*> DeadGlobalVars; // Keep track of dead globals
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
if (!AliveGlobals.count(I)) {
DeadGlobalVars.push_back(I); // Keep track of dead globals
I->setInitializer(0);
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!AliveGlobals.count(I)) {
DeadFunctions.push_back(I); // Keep track of dead globals
- if (!I->isExternal())
+ if (!I->isDeclaration())
I->deleteBody();
}
NumVariables += DeadGlobalVars.size();
Changed = true;
}
-
+
// Make sure that all memory is released
AliveGlobals.clear();
return Changed;
// referenced by the initializer to the alive set.
if (GV->hasInitializer())
MarkUsedGlobalsAsNeeded(GV->getInitializer());
- } else {
+ } else if (!isa<GlobalAlias>(G)) {
// Otherwise this must be a function object. We have to scan the body of
// the function looking for constants and global values which are used as
// operands. Any operands of these types must be processed to ensure that
if (GlobalValue *GV = dyn_cast<GlobalValue>(*U))
GlobalIsNeeded(GV);
else if (Constant *C = dyn_cast<Constant>(*U))
- MarkUsedGlobalsAsNeeded(C);
+ MarkUsedGlobalsAsNeeded(C);
}
}
GV.removeDeadConstantUsers();
return GV.use_empty();
}
-
+
// SafeToDestroyConstant - It is safe to destroy a constant iff it is only used
// by constants itself. Note that constants cannot be cyclic, so this test is
// pretty easy to implement recursively.