Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Transforms/IPO/ConstantMerge.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 | afa8332a0e37 |
comparison
equal
deleted
inserted
replaced
76:9e74acfe8c42 | 80:67baa08a3894 |
---|---|
15 // Algorithm: ConstantMerge is designed to build up a map of available constants | 15 // Algorithm: ConstantMerge is designed to build up a map of available constants |
16 // and eliminate duplicates when it is initialized. | 16 // and eliminate duplicates when it is initialized. |
17 // | 17 // |
18 //===----------------------------------------------------------------------===// | 18 //===----------------------------------------------------------------------===// |
19 | 19 |
20 #define DEBUG_TYPE "constmerge" | |
21 #include "llvm/Transforms/IPO.h" | 20 #include "llvm/Transforms/IPO.h" |
22 #include "llvm/ADT/DenseMap.h" | 21 #include "llvm/ADT/DenseMap.h" |
23 #include "llvm/ADT/PointerIntPair.h" | 22 #include "llvm/ADT/PointerIntPair.h" |
24 #include "llvm/ADT/SmallPtrSet.h" | 23 #include "llvm/ADT/SmallPtrSet.h" |
25 #include "llvm/ADT/Statistic.h" | 24 #include "llvm/ADT/Statistic.h" |
29 #include "llvm/IR/Module.h" | 28 #include "llvm/IR/Module.h" |
30 #include "llvm/IR/Operator.h" | 29 #include "llvm/IR/Operator.h" |
31 #include "llvm/Pass.h" | 30 #include "llvm/Pass.h" |
32 using namespace llvm; | 31 using namespace llvm; |
33 | 32 |
33 #define DEBUG_TYPE "constmerge" | |
34 | |
34 STATISTIC(NumMerged, "Number of global constants merged"); | 35 STATISTIC(NumMerged, "Number of global constants merged"); |
35 | 36 |
36 namespace { | 37 namespace { |
37 struct ConstantMerge : public ModulePass { | 38 struct ConstantMerge : public ModulePass { |
38 static char ID; // Pass identification, replacement for typeid | 39 static char ID; // Pass identification, replacement for typeid |
40 initializeConstantMergePass(*PassRegistry::getPassRegistry()); | 41 initializeConstantMergePass(*PassRegistry::getPassRegistry()); |
41 } | 42 } |
42 | 43 |
43 // For this pass, process all of the globals in the module, eliminating | 44 // For this pass, process all of the globals in the module, eliminating |
44 // duplicate constants. | 45 // duplicate constants. |
45 bool runOnModule(Module &M); | 46 bool runOnModule(Module &M) override; |
46 | 47 |
47 // Return true iff we can determine the alignment of this global variable. | 48 // Return true iff we can determine the alignment of this global variable. |
48 bool hasKnownAlignment(GlobalVariable *GV) const; | 49 bool hasKnownAlignment(GlobalVariable *GV) const; |
49 | 50 |
50 // Return the alignment of the global, including converting the default | 51 // Return the alignment of the global, including converting the default |
51 // alignment to a concrete value. | 52 // alignment to a concrete value. |
52 unsigned getAlignment(GlobalVariable *GV) const; | 53 unsigned getAlignment(GlobalVariable *GV) const; |
53 | 54 |
54 const DataLayout *TD; | 55 const DataLayout *DL; |
55 }; | 56 }; |
56 } | 57 } |
57 | 58 |
58 char ConstantMerge::ID = 0; | 59 char ConstantMerge::ID = 0; |
59 INITIALIZE_PASS(ConstantMerge, "constmerge", | 60 INITIALIZE_PASS(ConstantMerge, "constmerge", |
63 | 64 |
64 | 65 |
65 | 66 |
66 /// Find values that are marked as llvm.used. | 67 /// Find values that are marked as llvm.used. |
67 static void FindUsedValues(GlobalVariable *LLVMUsed, | 68 static void FindUsedValues(GlobalVariable *LLVMUsed, |
68 SmallPtrSet<const GlobalValue*, 8> &UsedValues) { | 69 SmallPtrSetImpl<const GlobalValue*> &UsedValues) { |
69 if (LLVMUsed == 0) return; | 70 if (!LLVMUsed) return; |
70 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); | 71 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); |
71 | 72 |
72 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) { | 73 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) { |
73 Value *Operand = Inits->getOperand(i)->stripPointerCastsNoFollowAliases(); | 74 Value *Operand = Inits->getOperand(i)->stripPointerCastsNoFollowAliases(); |
74 GlobalValue *GV = cast<GlobalValue>(Operand); | 75 GlobalValue *GV = cast<GlobalValue>(Operand); |
75 UsedValues.insert(GV); | 76 UsedValues.insert(GV); |
76 } | 77 } |
77 } | 78 } |
78 | 79 |
79 // True if A is better than B. | 80 // True if A is better than B. |
80 static bool IsBetterCannonical(const GlobalVariable &A, | 81 static bool IsBetterCanonical(const GlobalVariable &A, |
81 const GlobalVariable &B) { | 82 const GlobalVariable &B) { |
82 if (!A.hasLocalLinkage() && B.hasLocalLinkage()) | 83 if (!A.hasLocalLinkage() && B.hasLocalLinkage()) |
83 return true; | 84 return true; |
84 | 85 |
85 if (A.hasLocalLinkage() && !B.hasLocalLinkage()) | 86 if (A.hasLocalLinkage() && !B.hasLocalLinkage()) |
86 return false; | 87 return false; |
87 | 88 |
88 return A.hasUnnamedAddr(); | 89 return A.hasUnnamedAddr(); |
89 } | 90 } |
90 | 91 |
91 bool ConstantMerge::hasKnownAlignment(GlobalVariable *GV) const { | 92 bool ConstantMerge::hasKnownAlignment(GlobalVariable *GV) const { |
92 return TD || GV->getAlignment() != 0; | 93 return DL || GV->getAlignment() != 0; |
93 } | 94 } |
94 | 95 |
95 unsigned ConstantMerge::getAlignment(GlobalVariable *GV) const { | 96 unsigned ConstantMerge::getAlignment(GlobalVariable *GV) const { |
96 unsigned Align = GV->getAlignment(); | 97 unsigned Align = GV->getAlignment(); |
97 if (Align) | 98 if (Align) |
98 return Align; | 99 return Align; |
99 if (TD) | 100 if (DL) |
100 return TD->getPreferredAlignment(GV); | 101 return DL->getPreferredAlignment(GV); |
101 return 0; | 102 return 0; |
102 } | 103 } |
103 | 104 |
104 bool ConstantMerge::runOnModule(Module &M) { | 105 bool ConstantMerge::runOnModule(Module &M) { |
105 TD = getAnalysisIfAvailable<DataLayout>(); | 106 DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); |
107 DL = DLP ? &DLP->getDataLayout() : nullptr; | |
106 | 108 |
107 // Find all the globals that are marked "used". These cannot be merged. | 109 // Find all the globals that are marked "used". These cannot be merged. |
108 SmallPtrSet<const GlobalValue*, 8> UsedGlobals; | 110 SmallPtrSet<const GlobalValue*, 8> UsedGlobals; |
109 FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals); | 111 FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals); |
110 FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals); | 112 FindUsedValues(M.getGlobalVariable("llvm.compiler.used"), UsedGlobals); |
158 GlobalVariable *&Slot = CMap[Pair]; | 160 GlobalVariable *&Slot = CMap[Pair]; |
159 | 161 |
160 // If this is the first constant we find or if the old one is local, | 162 // If this is the first constant we find or if the old one is local, |
161 // replace with the current one. If the current is externally visible | 163 // replace with the current one. If the current is externally visible |
162 // it cannot be replace, but can be the canonical constant we merge with. | 164 // it cannot be replace, but can be the canonical constant we merge with. |
163 if (Slot == 0 || IsBetterCannonical(*GV, *Slot)) | 165 if (!Slot || IsBetterCanonical(*GV, *Slot)) |
164 Slot = GV; | 166 Slot = GV; |
165 } | 167 } |
166 | 168 |
167 // Second: identify all globals that can be merged together, filling in | 169 // Second: identify all globals that can be merged together, filling in |
168 // the Replacements vector. We cannot do the replacement in this pass | 170 // the Replacements vector. We cannot do the replacement in this pass |