Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Transforms/IPO/GlobalDCE.cpp @ 80:67baa08a3894
update to LLVM 3.6
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 25 Sep 2014 16:56:18 +0900 |
parents | 54457678186b |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
76:9e74acfe8c42 | 80:67baa08a3894 |
---|---|
13 // deletes whatever is left over. This allows it to delete recursive chunks of | 13 // deletes whatever is left over. This allows it to delete recursive chunks of |
14 // the program which are unreachable. | 14 // the program which are unreachable. |
15 // | 15 // |
16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
17 | 17 |
18 #define DEBUG_TYPE "globaldce" | |
19 #include "llvm/Transforms/IPO.h" | 18 #include "llvm/Transforms/IPO.h" |
20 #include "llvm/ADT/SmallPtrSet.h" | 19 #include "llvm/ADT/SmallPtrSet.h" |
21 #include "llvm/ADT/Statistic.h" | 20 #include "llvm/ADT/Statistic.h" |
22 #include "llvm/IR/Constants.h" | 21 #include "llvm/IR/Constants.h" |
22 #include "llvm/IR/Instructions.h" | |
23 #include "llvm/IR/Module.h" | 23 #include "llvm/IR/Module.h" |
24 #include "llvm/Transforms/Utils/CtorUtils.h" | |
25 #include "llvm/Transforms/Utils/GlobalStatus.h" | |
24 #include "llvm/Pass.h" | 26 #include "llvm/Pass.h" |
25 using namespace llvm; | 27 using namespace llvm; |
28 | |
29 #define DEBUG_TYPE "globaldce" | |
26 | 30 |
27 STATISTIC(NumAliases , "Number of global aliases removed"); | 31 STATISTIC(NumAliases , "Number of global aliases removed"); |
28 STATISTIC(NumFunctions, "Number of functions removed"); | 32 STATISTIC(NumFunctions, "Number of functions removed"); |
29 STATISTIC(NumVariables, "Number of global variables removed"); | 33 STATISTIC(NumVariables, "Number of global variables removed"); |
30 | 34 |
36 } | 40 } |
37 | 41 |
38 // run - Do the GlobalDCE pass on the specified module, optionally updating | 42 // run - Do the GlobalDCE pass on the specified module, optionally updating |
39 // the specified callgraph to reflect the changes. | 43 // the specified callgraph to reflect the changes. |
40 // | 44 // |
41 bool runOnModule(Module &M); | 45 bool runOnModule(Module &M) override; |
42 | 46 |
43 private: | 47 private: |
44 SmallPtrSet<GlobalValue*, 32> AliveGlobals; | 48 SmallPtrSet<GlobalValue*, 32> AliveGlobals; |
45 SmallPtrSet<Constant *, 8> SeenConstants; | 49 SmallPtrSet<Constant *, 8> SeenConstants; |
46 | 50 |
51 | 55 |
52 bool RemoveUnusedGlobalValue(GlobalValue &GV); | 56 bool RemoveUnusedGlobalValue(GlobalValue &GV); |
53 }; | 57 }; |
54 } | 58 } |
55 | 59 |
60 /// Returns true if F contains only a single "ret" instruction. | |
61 static bool isEmptyFunction(Function *F) { | |
62 BasicBlock &Entry = F->getEntryBlock(); | |
63 if (Entry.size() != 1 || !isa<ReturnInst>(Entry.front())) | |
64 return false; | |
65 ReturnInst &RI = cast<ReturnInst>(Entry.front()); | |
66 return RI.getReturnValue() == nullptr; | |
67 } | |
68 | |
56 char GlobalDCE::ID = 0; | 69 char GlobalDCE::ID = 0; |
57 INITIALIZE_PASS(GlobalDCE, "globaldce", | 70 INITIALIZE_PASS(GlobalDCE, "globaldce", |
58 "Dead Global Elimination", false, false) | 71 "Dead Global Elimination", false, false) |
59 | 72 |
60 ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); } | 73 ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); } |
61 | 74 |
62 bool GlobalDCE::runOnModule(Module &M) { | 75 bool GlobalDCE::runOnModule(Module &M) { |
63 bool Changed = false; | 76 bool Changed = false; |
64 | 77 |
78 // Remove empty functions from the global ctors list. | |
79 Changed |= optimizeGlobalCtorsList(M, isEmptyFunction); | |
80 | |
81 typedef std::multimap<const Comdat *, GlobalValue *> ComdatGVPairsTy; | |
82 ComdatGVPairsTy ComdatGVPairs; | |
83 | |
65 // Loop over the module, adding globals which are obviously necessary. | 84 // Loop over the module, adding globals which are obviously necessary. |
66 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { | 85 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { |
67 Changed |= RemoveUnusedGlobalValue(*I); | 86 Changed |= RemoveUnusedGlobalValue(*I); |
68 // Functions with external linkage are needed if they have a body | 87 // Functions with external linkage are needed if they have a body |
69 if (!I->isDiscardableIfUnused() && | 88 if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) { |
70 !I->isDeclaration() && !I->hasAvailableExternallyLinkage()) | 89 if (!I->isDiscardableIfUnused()) |
71 GlobalIsNeeded(I); | 90 GlobalIsNeeded(I); |
91 else if (const Comdat *C = I->getComdat()) | |
92 ComdatGVPairs.insert(std::make_pair(C, I)); | |
93 } | |
72 } | 94 } |
73 | 95 |
74 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); | 96 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); |
75 I != E; ++I) { | 97 I != E; ++I) { |
76 Changed |= RemoveUnusedGlobalValue(*I); | 98 Changed |= RemoveUnusedGlobalValue(*I); |
77 // Externally visible & appending globals are needed, if they have an | 99 // Externally visible & appending globals are needed, if they have an |
78 // initializer. | 100 // initializer. |
79 if (!I->isDiscardableIfUnused() && | 101 if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) { |
80 !I->isDeclaration() && !I->hasAvailableExternallyLinkage()) | 102 if (!I->isDiscardableIfUnused()) |
81 GlobalIsNeeded(I); | 103 GlobalIsNeeded(I); |
104 else if (const Comdat *C = I->getComdat()) | |
105 ComdatGVPairs.insert(std::make_pair(C, I)); | |
106 } | |
82 } | 107 } |
83 | 108 |
84 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); | 109 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); |
85 I != E; ++I) { | 110 I != E; ++I) { |
86 Changed |= RemoveUnusedGlobalValue(*I); | 111 Changed |= RemoveUnusedGlobalValue(*I); |
87 // Externally visible aliases are needed. | 112 // Externally visible aliases are needed. |
88 if (!I->isDiscardableIfUnused()) | 113 if (!I->isDiscardableIfUnused()) { |
89 GlobalIsNeeded(I); | 114 GlobalIsNeeded(I); |
115 } else if (const Comdat *C = I->getComdat()) { | |
116 ComdatGVPairs.insert(std::make_pair(C, I)); | |
117 } | |
118 } | |
119 | |
120 for (ComdatGVPairsTy::iterator I = ComdatGVPairs.begin(), | |
121 E = ComdatGVPairs.end(); | |
122 I != E;) { | |
123 ComdatGVPairsTy::iterator UB = ComdatGVPairs.upper_bound(I->first); | |
124 bool CanDiscard = std::all_of(I, UB, [](ComdatGVPairsTy::value_type Pair) { | |
125 return Pair.second->isDiscardableIfUnused(); | |
126 }); | |
127 if (!CanDiscard) { | |
128 std::for_each(I, UB, [this](ComdatGVPairsTy::value_type Pair) { | |
129 GlobalIsNeeded(Pair.second); | |
130 }); | |
131 } | |
132 I = UB; | |
90 } | 133 } |
91 | 134 |
92 // Now that all globals which are needed are in the AliveGlobals set, we loop | 135 // Now that all globals which are needed are in the AliveGlobals set, we loop |
93 // through the program, deleting those which are not alive. | 136 // through the program, deleting those which are not alive. |
94 // | 137 // |
97 std::vector<GlobalVariable*> DeadGlobalVars; // Keep track of dead globals | 140 std::vector<GlobalVariable*> DeadGlobalVars; // Keep track of dead globals |
98 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); | 141 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); |
99 I != E; ++I) | 142 I != E; ++I) |
100 if (!AliveGlobals.count(I)) { | 143 if (!AliveGlobals.count(I)) { |
101 DeadGlobalVars.push_back(I); // Keep track of dead globals | 144 DeadGlobalVars.push_back(I); // Keep track of dead globals |
102 I->setInitializer(0); | 145 if (I->hasInitializer()) { |
146 Constant *Init = I->getInitializer(); | |
147 I->setInitializer(nullptr); | |
148 if (isSafeToDestroyConstant(Init)) | |
149 Init->destroyConstant(); | |
150 } | |
103 } | 151 } |
104 | 152 |
105 // The second pass drops the bodies of functions which are dead... | 153 // The second pass drops the bodies of functions which are dead... |
106 std::vector<Function*> DeadFunctions; | 154 std::vector<Function*> DeadFunctions; |
107 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) | 155 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) |
115 std::vector<GlobalAlias*> DeadAliases; | 163 std::vector<GlobalAlias*> DeadAliases; |
116 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; | 164 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; |
117 ++I) | 165 ++I) |
118 if (!AliveGlobals.count(I)) { | 166 if (!AliveGlobals.count(I)) { |
119 DeadAliases.push_back(I); | 167 DeadAliases.push_back(I); |
120 I->setAliasee(0); | 168 I->setAliasee(nullptr); |
121 } | 169 } |
122 | 170 |
123 if (!DeadFunctions.empty()) { | 171 if (!DeadFunctions.empty()) { |
124 // Now that all interferences have been dropped, delete the actual objects | 172 // Now that all interferences have been dropped, delete the actual objects |
125 // themselves. | 173 // themselves. |