31 #define DEBUG_TYPE "globaldce" 33 STATISTIC(NumAliases ,
"Number of global aliases removed");
34 STATISTIC(NumFunctions,
"Number of functions removed");
35 STATISTIC(NumIFuncs,
"Number of indirect functions removed");
36 STATISTIC(NumVariables,
"Number of global variables removed");
39 class GlobalDCELegacyPass :
public ModulePass {
49 bool runOnModule(
Module &M)
override {
61 auto PA = Impl.run(M, DummyMAM);
62 return !PA.areAllPreserved();
72 "Dead Global Elimination",
false,
false)
76 return new GlobalDCELegacyPass();
82 for (
auto &
I : Entry) {
83 if (isa<DbgInfoIntrinsic>(
I))
85 if (
auto *RI = dyn_cast<ReturnInst>(&
I))
86 return !RI->getReturnValue();
94 void GlobalDCEPass::ComputeDependencies(
Value *V,
96 if (
auto *
I = dyn_cast<Instruction>(V)) {
97 Function *Parent =
I->getParent()->getParent();
99 }
else if (
auto *GV = dyn_cast<GlobalValue>(V)) {
101 }
else if (
auto *CE = dyn_cast<Constant>(V)) {
103 auto Where = ConstantDependenciesCache.find(CE);
104 if (Where != ConstantDependenciesCache.end()) {
105 auto const &K = Where->second;
106 Deps.
insert(K.begin(), K.end());
109 for (
User *CEUser : CE->users())
110 ComputeDependencies(CEUser, LocalDeps);
116 void GlobalDCEPass::UpdateGVDependencies(
GlobalValue &GV) {
119 ComputeDependencies(
User, Deps);
122 GVDependencies[GVU].insert(&GV);
129 auto const Ret = AliveGlobals.insert(&GV);
136 for (
auto &&CM :
make_range(ComdatMembers.equal_range(
C)))
137 MarkLive(*CM.second, Updates);
143 bool Changed =
false;
159 ComdatMembers.insert(std::make_pair(
C, &
F));
162 ComdatMembers.insert(std::make_pair(
C, &GV));
164 if (
Comdat *
C = GA.getComdat())
165 ComdatMembers.insert(std::make_pair(
C, &GA));
169 Changed |= RemoveUnusedGlobalValue(GO);
173 if (!GO.isDeclaration())
174 if (!GO.isDiscardableIfUnused())
177 UpdateGVDependencies(GO);
182 Changed |= RemoveUnusedGlobalValue(GA);
184 if (!GA.isDiscardableIfUnused())
187 UpdateGVDependencies(GA);
192 Changed |= RemoveUnusedGlobalValue(GIF);
194 if (!GIF.isDiscardableIfUnused())
197 UpdateGVDependencies(GIF);
204 while (!NewLiveGVs.empty()) {
206 for (
auto *GVD : GVDependencies[LGV])
207 MarkLive(*GVD, &NewLiveGVs);
215 std::vector<GlobalVariable *> DeadGlobalVars;
217 if (!AliveGlobals.count(&GV)) {
218 DeadGlobalVars.push_back(&GV);
219 if (GV.hasInitializer()) {
221 GV.setInitializer(
nullptr);
228 std::vector<Function *> DeadFunctions;
230 if (!AliveGlobals.count(&
F)) {
231 DeadFunctions.push_back(&
F);
232 if (!
F.isDeclaration())
237 std::vector<GlobalAlias*> DeadAliases;
239 if (!AliveGlobals.count(&GA)) {
240 DeadAliases.push_back(&GA);
241 GA.setAliasee(
nullptr);
245 std::vector<GlobalIFunc*> DeadIFuncs;
247 if (!AliveGlobals.count(&GIF)) {
248 DeadIFuncs.push_back(&GIF);
249 GIF.setResolver(
nullptr);
254 auto EraseUnusedGlobalValue = [&](
GlobalValue *GV) {
255 RemoveUnusedGlobalValue(*GV);
260 NumFunctions += DeadFunctions.size();
262 EraseUnusedGlobalValue(
F);
264 NumVariables += DeadGlobalVars.size();
266 EraseUnusedGlobalValue(GV);
268 NumAliases += DeadAliases.size();
270 EraseUnusedGlobalValue(GA);
272 NumIFuncs += DeadIFuncs.size();
274 EraseUnusedGlobalValue(GIF);
277 AliveGlobals.clear();
278 ConstantDependenciesCache.clear();
279 GVDependencies.clear();
280 ComdatMembers.clear();
293 bool GlobalDCEPass::RemoveUnusedGlobalValue(
GlobalValue &GV) {
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
void push_back(const T &Elt)
void initializeGlobalDCELegacyPassPass(PassRegistry &)
STATISTIC(NumFunctions, "Total number of functions")
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
INITIALIZE_PASS(GlobalDCELegacyPass, "globaldce", "Dead Global Elimination", false, false) ModulePass *llvm
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
Pass to remove unused function declarations.
ModulePass * createGlobalDCEPass()
createGlobalDCEPass - This transform is designed to eliminate unreachable internal globals (functions...
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
const BasicBlock & getEntryBlock() const
A set of analyses that are preserved following a run of a transformation pass.
LLVM Basic Block Representation.
This is an important base class in LLVM.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
static bool isEmptyFunction(Function *F)
Returns true if F is effectively empty.
const Comdat * getComdat() const
iterator_range< user_iterator > users()
void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
void destroyConstant()
Called if some element of this constant is no longer valid.
LLVM Value Representation.
A container for analyses that lazily runs them and caches their results.
bool optimizeGlobalCtorsList(Module &M, function_ref< bool(Function *)> ShouldRemove)
Call "ShouldRemove" for every entry in M's global_ctor list and remove the entries for which it retur...
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)