Mercurial > hg > CbC > CbC_llvm
comparison lib/Transforms/IPO/ConstantMerge.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children | c2174574ed3a |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
17 // | 17 // |
18 //===----------------------------------------------------------------------===// | 18 //===----------------------------------------------------------------------===// |
19 | 19 |
20 #include "llvm/Transforms/IPO/ConstantMerge.h" | 20 #include "llvm/Transforms/IPO/ConstantMerge.h" |
21 #include "llvm/ADT/DenseMap.h" | 21 #include "llvm/ADT/DenseMap.h" |
22 #include "llvm/ADT/PointerIntPair.h" | |
23 #include "llvm/ADT/SmallPtrSet.h" | 22 #include "llvm/ADT/SmallPtrSet.h" |
23 #include "llvm/ADT/SmallVector.h" | |
24 #include "llvm/ADT/Statistic.h" | 24 #include "llvm/ADT/Statistic.h" |
25 #include "llvm/IR/Constants.h" | 25 #include "llvm/IR/Constants.h" |
26 #include "llvm/IR/DataLayout.h" | 26 #include "llvm/IR/DataLayout.h" |
27 #include "llvm/IR/DerivedTypes.h" | 27 #include "llvm/IR/DerivedTypes.h" |
28 #include "llvm/IR/GlobalValue.h" | |
29 #include "llvm/IR/GlobalVariable.h" | |
30 #include "llvm/IR/LLVMContext.h" | |
28 #include "llvm/IR/Module.h" | 31 #include "llvm/IR/Module.h" |
29 #include "llvm/IR/Operator.h" | |
30 #include "llvm/Pass.h" | 32 #include "llvm/Pass.h" |
33 #include "llvm/Support/Casting.h" | |
31 #include "llvm/Transforms/IPO.h" | 34 #include "llvm/Transforms/IPO.h" |
35 #include <algorithm> | |
36 #include <cassert> | |
37 #include <utility> | |
38 | |
32 using namespace llvm; | 39 using namespace llvm; |
33 | 40 |
34 #define DEBUG_TYPE "constmerge" | 41 #define DEBUG_TYPE "constmerge" |
35 | 42 |
36 STATISTIC(NumMerged, "Number of global constants merged"); | 43 STATISTIC(NumMerged, "Number of global constants merged"); |
58 return false; | 65 return false; |
59 | 66 |
60 return A.hasGlobalUnnamedAddr(); | 67 return A.hasGlobalUnnamedAddr(); |
61 } | 68 } |
62 | 69 |
70 static bool hasMetadataOtherThanDebugLoc(const GlobalVariable *GV) { | |
71 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; | |
72 GV->getAllMetadata(MDs); | |
73 for (const auto &V : MDs) | |
74 if (V.first != LLVMContext::MD_dbg) | |
75 return true; | |
76 return false; | |
77 } | |
78 | |
79 static void copyDebugLocMetadata(const GlobalVariable *From, | |
80 GlobalVariable *To) { | |
81 SmallVector<DIGlobalVariableExpression *, 1> MDs; | |
82 From->getDebugInfo(MDs); | |
83 for (auto MD : MDs) | |
84 To->addDebugInfo(MD); | |
85 } | |
86 | |
63 static unsigned getAlignment(GlobalVariable *GV) { | 87 static unsigned getAlignment(GlobalVariable *GV) { |
64 unsigned Align = GV->getAlignment(); | 88 unsigned Align = GV->getAlignment(); |
65 if (Align) | 89 if (Align) |
66 return Align; | 90 return Align; |
67 return GV->getParent()->getDataLayout().getPreferredAlignment(GV); | 91 return GV->getParent()->getDataLayout().getPreferredAlignment(GV); |
83 | 107 |
84 // Iterate constant merging while we are still making progress. Merging two | 108 // Iterate constant merging while we are still making progress. Merging two |
85 // constants together may allow us to merge other constants together if the | 109 // constants together may allow us to merge other constants together if the |
86 // second level constants have initializers which point to the globals that | 110 // second level constants have initializers which point to the globals that |
87 // were just merged. | 111 // were just merged. |
88 while (1) { | 112 while (true) { |
89 | |
90 // First: Find the canonical constants others will be merged with. | 113 // First: Find the canonical constants others will be merged with. |
91 for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); | 114 for (Module::global_iterator GVI = M.global_begin(), E = M.global_end(); |
92 GVI != E; ) { | 115 GVI != E; ) { |
93 GlobalVariable *GV = &*GVI++; | 116 GlobalVariable *GV = &*GVI++; |
94 | 117 |
109 // This transformation is legal for weak ODR globals in the sense it | 132 // This transformation is legal for weak ODR globals in the sense it |
110 // doesn't change semantics, but we really don't want to perform it | 133 // doesn't change semantics, but we really don't want to perform it |
111 // anyway; it's likely to pessimize code generation, and some tools | 134 // anyway; it's likely to pessimize code generation, and some tools |
112 // (like the Darwin linker in cases involving CFString) don't expect it. | 135 // (like the Darwin linker in cases involving CFString) don't expect it. |
113 if (GV->isWeakForLinker()) | 136 if (GV->isWeakForLinker()) |
137 continue; | |
138 | |
139 // Don't touch globals with metadata other then !dbg. | |
140 if (hasMetadataOtherThanDebugLoc(GV)) | |
114 continue; | 141 continue; |
115 | 142 |
116 Constant *Init = GV->getInitializer(); | 143 Constant *Init = GV->getInitializer(); |
117 | 144 |
118 // Check to see if the initializer is already known. | 145 // Check to see if the initializer is already known. |
151 | 178 |
152 if (!Slot || Slot == GV) | 179 if (!Slot || Slot == GV) |
153 continue; | 180 continue; |
154 | 181 |
155 if (!Slot->hasGlobalUnnamedAddr() && !GV->hasGlobalUnnamedAddr()) | 182 if (!Slot->hasGlobalUnnamedAddr() && !GV->hasGlobalUnnamedAddr()) |
183 continue; | |
184 | |
185 if (hasMetadataOtherThanDebugLoc(GV)) | |
156 continue; | 186 continue; |
157 | 187 |
158 if (!GV->hasGlobalUnnamedAddr()) | 188 if (!GV->hasGlobalUnnamedAddr()) |
159 Slot->setUnnamedAddr(GlobalValue::UnnamedAddr::None); | 189 Slot->setUnnamedAddr(GlobalValue::UnnamedAddr::None); |
160 | 190 |
176 Replacements[i].second->setAlignment( | 206 Replacements[i].second->setAlignment( |
177 std::max(getAlignment(Replacements[i].first), | 207 std::max(getAlignment(Replacements[i].first), |
178 getAlignment(Replacements[i].second))); | 208 getAlignment(Replacements[i].second))); |
179 } | 209 } |
180 | 210 |
211 copyDebugLocMetadata(Replacements[i].first, Replacements[i].second); | |
212 | |
181 // Eliminate any uses of the dead global. | 213 // Eliminate any uses of the dead global. |
182 Replacements[i].first->replaceAllUsesWith(Replacements[i].second); | 214 Replacements[i].first->replaceAllUsesWith(Replacements[i].second); |
183 | 215 |
184 // Delete the global value from the module. | 216 // Delete the global value from the module. |
185 assert(Replacements[i].first->hasLocalLinkage() && | 217 assert(Replacements[i].first->hasLocalLinkage() && |
197 return PreservedAnalyses::all(); | 229 return PreservedAnalyses::all(); |
198 return PreservedAnalyses::none(); | 230 return PreservedAnalyses::none(); |
199 } | 231 } |
200 | 232 |
201 namespace { | 233 namespace { |
234 | |
202 struct ConstantMergeLegacyPass : public ModulePass { | 235 struct ConstantMergeLegacyPass : public ModulePass { |
203 static char ID; // Pass identification, replacement for typeid | 236 static char ID; // Pass identification, replacement for typeid |
237 | |
204 ConstantMergeLegacyPass() : ModulePass(ID) { | 238 ConstantMergeLegacyPass() : ModulePass(ID) { |
205 initializeConstantMergeLegacyPassPass(*PassRegistry::getPassRegistry()); | 239 initializeConstantMergeLegacyPassPass(*PassRegistry::getPassRegistry()); |
206 } | 240 } |
207 | 241 |
208 // For this pass, process all of the globals in the module, eliminating | 242 // For this pass, process all of the globals in the module, eliminating |
209 // duplicate constants. | 243 // duplicate constants. |
210 bool runOnModule(Module &M) { | 244 bool runOnModule(Module &M) override { |
211 if (skipModule(M)) | 245 if (skipModule(M)) |
212 return false; | 246 return false; |
213 return mergeConstants(M); | 247 return mergeConstants(M); |
214 } | 248 } |
215 }; | 249 }; |
216 } | 250 |
251 } // end anonymous namespace | |
217 | 252 |
218 char ConstantMergeLegacyPass::ID = 0; | 253 char ConstantMergeLegacyPass::ID = 0; |
254 | |
219 INITIALIZE_PASS(ConstantMergeLegacyPass, "constmerge", | 255 INITIALIZE_PASS(ConstantMergeLegacyPass, "constmerge", |
220 "Merge Duplicate Global Constants", false, false) | 256 "Merge Duplicate Global Constants", false, false) |
221 | 257 |
222 ModulePass *llvm::createConstantMergePass() { | 258 ModulePass *llvm::createConstantMergePass() { |
223 return new ConstantMergeLegacyPass(); | 259 return new ConstantMergeLegacyPass(); |