X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FGlobalDCE.cpp;h=09f9e7c4f68a6e55ea516bf7ca0be5a1c85cd782;hb=7eb28f3786543f63cb9a4099655e6d456fca71f7;hp=17dcb31859c9251b025de3c00e4836e8409a67c6;hpb=86453c52ba02e743d29c08456e51006500041456;p=oota-llvm.git diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp index 17dcb31859c..09f9e7c4f68 100644 --- a/lib/Transforms/IPO/GlobalDCE.cpp +++ b/lib/Transforms/IPO/GlobalDCE.cpp @@ -2,8 +2,8 @@ // // 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. // //===----------------------------------------------------------------------===// // @@ -21,14 +21,19 @@ #include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/Compiler.h" #include using namespace llvm; +STATISTIC(NumAliases , "Number of global aliases removed"); STATISTIC(NumFunctions, "Number of functions removed"); STATISTIC(NumVariables, "Number of global variables removed"); namespace { - struct GlobalDCE : public ModulePass { + struct VISIBILITY_HIDDEN GlobalDCE : public ModulePass { + static char ID; // Pass identification, replacement for typeid + GlobalDCE() : ModulePass(&ID) {} + // run - Do the GlobalDCE pass on the specified module, optionally updating // the specified callgraph to reflect the changes. // @@ -37,39 +42,49 @@ namespace { private: std::set AliveGlobals; - /// MarkGlobalIsNeeded - the specific global value as needed, and + /// GlobalIsNeeded - mark the specific global value as needed, and /// recursively mark anything that it uses as also needed. void GlobalIsNeeded(GlobalValue *GV); void MarkUsedGlobalsAsNeeded(Constant *C); - bool SafeToDestroyConstant(Constant* C); bool RemoveUnusedGlobalValue(GlobalValue &GV); }; - RegisterPass X("globaldce", "Dead Global Elimination"); } +char GlobalDCE::ID = 0; +static RegisterPass X("globaldce", "Dead Global Elimination"); + ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); } bool GlobalDCE::runOnModule(Module &M) { bool Changed = false; + // Loop over the module, adding globals which are obviously necessary. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { Changed |= RemoveUnusedGlobalValue(*I); // Functions with external linkage are needed if they have a body - if ((!I->hasInternalLinkage() && !I->hasLinkOnceLinkage()) && - !I->isExternal()) + if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage() && + !I->isDeclaration() && !I->hasAvailableExternallyLinkage()) GlobalIsNeeded(I); } - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 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()) + if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage() && + !I->isDeclaration() && !I->hasAvailableExternallyLinkage()) GlobalIsNeeded(I); } + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); + I != E; ++I) { + Changed |= RemoveUnusedGlobalValue(*I); + // Externally visible aliases are needed. + if (!I->hasLocalLinkage() && !I->hasLinkOnceLinkage()) + GlobalIsNeeded(I); + } // Now that all globals which are needed are in the AliveGlobals set, we loop // through the program, deleting those which are not alive. @@ -83,18 +98,26 @@ bool GlobalDCE::runOnModule(Module &M) { I->setInitializer(0); } - // The second pass drops the bodies of functions which are dead... std::vector DeadFunctions; 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(); } + // The third pass drops targets of aliases which are dead... + std::vector DeadAliases; + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; + ++I) + if (!AliveGlobals.count(I)) { + DeadAliases.push_back(I); + I->setAliasee(0); + } + if (!DeadFunctions.empty()) { - // Now that all interreferences have been dropped, delete the actual objects + // Now that all interferences have been dropped, delete the actual objects // themselves. for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) { RemoveUnusedGlobalValue(*DeadFunctions[i]); @@ -113,18 +136,31 @@ bool GlobalDCE::runOnModule(Module &M) { Changed = true; } + // Now delete any dead aliases. + if (!DeadAliases.empty()) { + for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) { + RemoveUnusedGlobalValue(*DeadAliases[i]); + M.getAliasList().erase(DeadAliases[i]); + } + NumAliases += DeadAliases.size(); + Changed = true; + } + // Make sure that all memory is released AliveGlobals.clear(); + + // Remove dead metadata. + Changed |= M.getContext().RemoveDeadMetadata(); return Changed; } -/// MarkGlobalIsNeeded - the specific global value as needed, and +/// GlobalIsNeeded - the specific global value as needed, and /// recursively mark anything that it uses as also needed. void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { - std::set::iterator I = AliveGlobals.lower_bound(G); + std::set::iterator I = AliveGlobals.find(G); // If the global is already in the set, no need to reprocess it. - if (I != AliveGlobals.end() && *I == G) return; + if (I != AliveGlobals.end()) return; // Otherwise insert it now, so we do not infinitely recurse AliveGlobals.insert(I, G); @@ -134,6 +170,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { // referenced by the initializer to the alive set. if (GV->hasInitializer()) MarkUsedGlobalsAsNeeded(GV->getInitializer()); + } else if (GlobalAlias *GA = dyn_cast(G)) { + // The target of a global alias is needed. + MarkUsedGlobalsAsNeeded(GA->getAliasee()); } else { // 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 @@ -175,17 +214,3 @@ bool GlobalDCE::RemoveUnusedGlobalValue(GlobalValue &GV) { 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. -// -bool GlobalDCE::SafeToDestroyConstant(Constant *C) { - for (Value::use_iterator I = C->use_begin(), E = C->use_end(); I != E; ++I) - if (Constant *User = dyn_cast(*I)) { - if (!SafeToDestroyConstant(User)) return false; - } else { - return false; - } - return true; -}