27 #include <unordered_map>
30 #define DEBUG_TYPE "globaldce"
32 STATISTIC(NumAliases ,
"Number of global aliases removed");
33 STATISTIC(NumFunctions,
"Number of functions removed");
34 STATISTIC(NumVariables,
"Number of global variables removed");
46 bool runOnModule(
Module &M)
override;
51 std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
56 void MarkUsedGlobalsAsNeeded(
Constant *
C);
65 if (Entry.
size() != 1 || !isa<ReturnInst>(Entry.
front()))
73 "Dead Global Elimination",
false,
false)
77 bool GlobalDCE::runOnModule(
Module &M) {
86 ComdatMembers.insert(std::make_pair(C, &
F));
88 if (
Comdat *C = GV.getComdat())
89 ComdatMembers.insert(std::make_pair(C, &GV));
91 if (
Comdat *C = GA.getComdat())
92 ComdatMembers.insert(std::make_pair(C, &GA));
96 Changed |= RemoveUnusedGlobalValue(*
I);
98 if (!
I->isDeclaration() && !
I->hasAvailableExternallyLinkage()) {
99 if (!
I->isDiscardableIfUnused())
106 Changed |= RemoveUnusedGlobalValue(*
I);
109 if (!
I->isDeclaration() && !
I->hasAvailableExternallyLinkage()) {
110 if (!
I->isDiscardableIfUnused())
117 Changed |= RemoveUnusedGlobalValue(*
I);
119 if (!
I->isDiscardableIfUnused()) {
129 std::vector<GlobalVariable*> DeadGlobalVars;
132 if (!AliveGlobals.count(
I)) {
133 DeadGlobalVars.push_back(
I);
134 if (
I->hasInitializer()) {
136 I->setInitializer(
nullptr);
143 std::vector<Function*> DeadFunctions;
145 if (!AliveGlobals.count(
I)) {
146 DeadFunctions.push_back(
I);
147 if (!
I->isDeclaration())
152 std::vector<GlobalAlias*> DeadAliases;
155 if (!AliveGlobals.count(
I)) {
156 DeadAliases.push_back(
I);
157 I->setAliasee(
nullptr);
160 if (!DeadFunctions.empty()) {
163 for (
unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
164 RemoveUnusedGlobalValue(*DeadFunctions[i]);
165 M.getFunctionList().erase(DeadFunctions[i]);
167 NumFunctions += DeadFunctions.size();
171 if (!DeadGlobalVars.empty()) {
172 for (
unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
173 RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
174 M.getGlobalList().erase(DeadGlobalVars[i]);
176 NumVariables += DeadGlobalVars.size();
181 if (!DeadAliases.empty()) {
182 for (
unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
183 RemoveUnusedGlobalValue(*DeadAliases[i]);
184 M.getAliasList().erase(DeadAliases[i]);
186 NumAliases += DeadAliases.size();
191 AliveGlobals.clear();
192 SeenConstants.clear();
193 ComdatMembers.clear();
202 if (!AliveGlobals.insert(G).second)
206 for (
auto &&CM :
make_range(ComdatMembers.equal_range(C)))
207 GlobalIsNeeded(CM.second);
213 if (GV->hasInitializer())
214 MarkUsedGlobalsAsNeeded(GV->getInitializer());
215 }
else if (
GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
217 MarkUsedGlobalsAsNeeded(GA->getAliasee());
239 else if (
Constant *C = dyn_cast<Constant>(*U))
240 MarkUsedGlobalsAsNeeded(C);
244 void GlobalDCE::MarkUsedGlobalsAsNeeded(
Constant *C) {
246 return GlobalIsNeeded(GV);
253 if (Op && SeenConstants.insert(Op).second)
254 MarkUsedGlobalsAsNeeded(Op);
264 bool GlobalDCE::RemoveUnusedGlobalValue(
GlobalValue &GV) {
ReturnInst - Return a value (possibly void), from a function.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Constant * getPrologueData() const
STATISTIC(NumFunctions,"Total number of functions")
A Module instance is used to store all the information related to an LLVM module. ...
bool hasPrologueData() const
const Instruction & front() const
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
A Use represents the edge between a Value definition and its users.
INITIALIZE_PASS(GlobalDCE,"globaldce","Dead Global Elimination", false, false) ModulePass *llvm
ModulePass * createGlobalDCEPass()
createGlobalDCEPass - This transform is designed to eliminate unreachable internal globals (functions...
LLVM Basic Block Representation.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool hasPersonalityFn() const
Get the personality function associated with this function.
bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
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...
Module.h This file contains the declarations for the Module class.
static bool isEmptyFunction(Function *F)
Returns true if F contains only a single "ret" instruction.
const BasicBlock & getEntryBlock() const
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void initializeGlobalDCEPass(PassRegistry &)
Constant * getPersonalityFn() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
bool hasPrefixData() const
void destroyConstant()
Called if some element of this constant is no longer valid.
Constant * getPrefixData() const
void removeDeadConstantUsers() const
removeDeadConstantUsers - If there are any dead constant users dangling off of this constant...
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 ret...