llvm.org GIT mirror llvm / 713cab0
Optimize more linkonce_odr values during LTO. When a linkonce_odr value that is on the dso list is not unnamed_addr we can still look to see if anything is actually using its address. If not, it is safe to hide it. This patch implements that by moving GlobalStatus to Transforms/Utils and using it in Internalize. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193090 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
7 changed file(s) with 296 addition(s) and 215 deletion(s). Raw diff Collapse all Expand all
0 //===- GlobalStatus.h - Compute status info for globals ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
10 #define LLVM_TRANSFORMS_UTILS_GLOBALSTATUS_H
11
12 #include "llvm/IR/Instructions.h"
13
14 namespace llvm {
15 class Value;
16 class Function;
17
18 /// It is safe to destroy a constant iff it is only used by constants itself.
19 /// Note that constants cannot be cyclic, so this test is pretty easy to
20 /// implement recursively.
21 ///
22 bool isSafeToDestroyConstant(const Constant *C);
23
24 /// As we analyze each global, keep track of some information about it. If we
25 /// find out that the address of the global is taken, none of this info will be
26 /// accurate.
27 struct GlobalStatus {
28 /// True if the global's address is used in a comparison.
29 bool IsCompared;
30
31 /// True if the global is ever loaded. If the global isn't ever loaded it
32 /// can be deleted.
33 bool IsLoaded;
34
35 /// Keep track of what stores to the global look like.
36 enum StoredType {
37 /// There is no store to this global. It can thus be marked constant.
38 NotStored,
39
40 /// This global is stored to, but the only thing stored is the constant it
41 /// was initialized with. This is only tracked for scalar globals.
42 InitializerStored,
43
44 /// This global is stored to, but only its initializer and one other value
45 /// is ever stored to it. If this global isStoredOnce, we track the value
46 /// stored to it in StoredOnceValue below. This is only tracked for scalar
47 /// globals.
48 StoredOnce,
49
50 /// This global is stored to by multiple values or something else that we
51 /// cannot track.
52 Stored
53 } StoredType;
54
55 /// If only one value (besides the initializer constant) is ever stored to
56 /// this global, keep track of what value it is.
57 Value *StoredOnceValue;
58
59 /// These start out null/false. When the first accessing function is noticed,
60 /// it is recorded. When a second different accessing function is noticed,
61 /// HasMultipleAccessingFunctions is set to true.
62 const Function *AccessingFunction;
63 bool HasMultipleAccessingFunctions;
64
65 /// Set to true if this global has a user that is not an instruction (e.g. a
66 /// constant expr or GV initializer).
67 bool HasNonInstructionUser;
68
69 /// Set to the strongest atomic ordering requirement.
70 AtomicOrdering Ordering;
71
72 /// Look at all uses of the global and fill in the GlobalStatus structure. If
73 /// the global has its address taken, return true to indicate we can't do
74 /// anything with it.
75 static bool analyzeGlobal(const Value *V, GlobalStatus &GS);
76
77 GlobalStatus();
78 };
79 }
80
81 #endif
3737 #include "llvm/Support/MathExtras.h"
3838 #include "llvm/Support/raw_ostream.h"
3939 #include "llvm/Target/TargetLibraryInfo.h"
40 #include "llvm/Transforms/Utils/GlobalStatus.h"
4041 #include "llvm/Transforms/Utils/ModuleUtils.h"
4142 #include
4243 using namespace llvm;
5960 STATISTIC(NumCXXDtorsRemoved, "Number of global C++ destructors removed");
6061
6162 namespace {
62 struct GlobalStatus;
6363 struct GlobalOpt : public ModulePass {
6464 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
6565 AU.addRequired();
9898
9999 namespace {
100100
101 /// As we analyze each global, keep track of some information about it. If we
102 /// find out that the address of the global is taken, none of this info will be
103 /// accurate.
104 struct GlobalStatus {
105 /// True if the global's address is used in a comparison.
106 bool IsCompared;
107
108 /// True if the global is ever loaded. If the global isn't ever loaded it can
109 /// be deleted.
110 bool IsLoaded;
111
112 /// Keep track of what stores to the global look like.
113 ///
114 enum StoredType {
115 /// There is no store to this global. It can thus be marked constant.
116 NotStored,
117
118 /// This global is stored to, but the only thing stored is the constant it
119 /// was initialized with. This is only tracked for scalar globals.
120 InitializerStored,
121
122 /// This global is stored to, but only its initializer and one other value
123 /// is ever stored to it. If this global StoredOnce, we track the value
124 /// stored to it in StoredOnceValue below. This is only tracked for scalar
125 /// globals.
126 StoredOnce,
127
128 /// This global is stored to by multiple values or something else that we
129 /// cannot track.
130 Stored
131 } StoredType;
132
133 /// StoredOnceValue - If only one value (besides the initializer constant) is
134 /// ever stored to this global, keep track of what value it is.
135 Value *StoredOnceValue;
136
137 /// AccessingFunction/HasMultipleAccessingFunctions - These start out
138 /// null/false. When the first accessing function is noticed, it is recorded.
139 /// When a second different accessing function is noticed,
140 /// HasMultipleAccessingFunctions is set to true.
141 const Function *AccessingFunction;
142 bool HasMultipleAccessingFunctions;
143
144 /// HasNonInstructionUser - Set to true if this global has a user that is not
145 /// an instruction (e.g. a constant expr or GV initializer).
146 bool HasNonInstructionUser;
147
148 /// AtomicOrdering - Set to the strongest atomic ordering requirement.
149 AtomicOrdering Ordering;
150
151 GlobalStatus() : IsCompared(false), IsLoaded(false), StoredType(NotStored),
152 StoredOnceValue(0), AccessingFunction(0),
153 HasMultipleAccessingFunctions(false),
154 HasNonInstructionUser(false), Ordering(NotAtomic) {}
155 };
156
157 }
158
159 /// StrongerOrdering - Return the stronger of the two ordering. If the two
160 /// orderings are acquire and release, then return AcquireRelease.
161 ///
162 static AtomicOrdering StrongerOrdering(AtomicOrdering X, AtomicOrdering Y) {
163 if (X == Acquire && Y == Release) return AcquireRelease;
164 if (Y == Acquire && X == Release) return AcquireRelease;
165 return (AtomicOrdering)std::max(X, Y);
166 }
167
168 /// It is safe to destroy a constant iff it is only used by constants itself.
169 /// Note that constants cannot be cyclic, so this test is pretty easy to
170 /// implement recursively.
171 ///
172 static bool isSafeToDestroyConstant(const Constant *C) {
173 if (isa(C))
174 return false;
175
176 for (Value::const_use_iterator UI = C->use_begin(), E = C->use_end(); UI != E;
177 ++UI)
178 if (const Constant *CU = dyn_cast(*UI)) {
179 if (!isSafeToDestroyConstant(CU))
180 return false;
181 } else
182 return false;
183 return true;
184 }
185
186 static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
187 SmallPtrSet &PHIUsers) {
188 for (Value::const_use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;
189 ++UI) {
190 const User *U = *UI;
191 if (const ConstantExpr *CE = dyn_cast(U)) {
192 GS.HasNonInstructionUser = true;
193
194 // If the result of the constantexpr isn't pointer type, then we won't
195 // know to expect it in various places. Just reject early.
196 if (!isa(CE->getType())) return true;
197
198 if (analyzeGlobalAux(CE, GS, PHIUsers))
199 return true;
200 } else if (const Instruction *I = dyn_cast(U)) {
201 if (!GS.HasMultipleAccessingFunctions) {
202 const Function *F = I->getParent()->getParent();
203 if (GS.AccessingFunction == 0)
204 GS.AccessingFunction = F;
205 else if (GS.AccessingFunction != F)
206 GS.HasMultipleAccessingFunctions = true;
207 }
208 if (const LoadInst *LI = dyn_cast(I)) {
209 GS.IsLoaded = true;
210 // Don't hack on volatile loads.
211 if (LI->isVolatile()) return true;
212 GS.Ordering = StrongerOrdering(GS.Ordering, LI->getOrdering());
213 } else if (const StoreInst *SI = dyn_cast(I)) {
214 // Don't allow a store OF the address, only stores TO the address.
215 if (SI->getOperand(0) == V) return true;
216
217 // Don't hack on volatile stores.
218 if (SI->isVolatile()) return true;
219
220 GS.Ordering = StrongerOrdering(GS.Ordering, SI->getOrdering());
221
222 // If this is a direct store to the global (i.e., the global is a scalar
223 // value, not an aggregate), keep more specific information about
224 // stores.
225 if (GS.StoredType != GlobalStatus::Stored) {
226 if (const GlobalVariable *GV = dyn_cast(
227 SI->getOperand(1))) {
228 Value *StoredVal = SI->getOperand(0);
229
230 if (Constant *C = dyn_cast(StoredVal)) {
231 if (C->isThreadDependent()) {
232 // The stored value changes between threads; don't track it.
233 return true;
234 }
235 }
236
237 if (StoredVal == GV->getInitializer()) {
238 if (GS.StoredType < GlobalStatus::InitializerStored)
239 GS.StoredType = GlobalStatus::InitializerStored;
240 } else if (isa(StoredVal) &&
241 cast(StoredVal)->getOperand(0) == GV) {
242 if (GS.StoredType < GlobalStatus::InitializerStored)
243 GS.StoredType = GlobalStatus::InitializerStored;
244 } else if (GS.StoredType < GlobalStatus::StoredOnce) {
245 GS.StoredType = GlobalStatus::StoredOnce;
246 GS.StoredOnceValue = StoredVal;
247 } else if (GS.StoredType == GlobalStatus::StoredOnce &&
248 GS.StoredOnceValue == StoredVal) {
249 // noop.
250 } else {
251 GS.StoredType = GlobalStatus::Stored;
252 }
253 } else {
254 GS.StoredType = GlobalStatus::Stored;
255 }
256 }
257 } else if (isa(I)) {
258 if (analyzeGlobalAux(I, GS, PHIUsers))
259 return true;
260 } else if (isa(I)) {
261 if (analyzeGlobalAux(I, GS, PHIUsers))
262 return true;
263 } else if (isa(I)) {
264 if (analyzeGlobalAux(I, GS, PHIUsers))
265 return true;
266 } else if (const PHINode *PN = dyn_cast(I)) {
267 // PHI nodes we can check just like select or GEP instructions, but we
268 // have to be careful about infinite recursion.
269 if (PHIUsers.insert(PN)) // Not already visited.
270 if (analyzeGlobalAux(I, GS, PHIUsers))
271 return true;
272 } else if (isa(I)) {
273 GS.IsCompared = true;
274 } else if (const MemTransferInst *MTI = dyn_cast(I)) {
275 if (MTI->isVolatile()) return true;
276 if (MTI->getArgOperand(0) == V)
277 GS.StoredType = GlobalStatus::Stored;
278 if (MTI->getArgOperand(1) == V)
279 GS.IsLoaded = true;
280 } else if (const MemSetInst *MSI = dyn_cast(I)) {
281 assert(MSI->getArgOperand(0) == V && "Memset only takes one pointer!");
282 if (MSI->isVolatile()) return true;
283 GS.StoredType = GlobalStatus::Stored;
284 } else {
285 return true; // Any other non-load instruction might take address!
286 }
287 } else if (const Constant *C = dyn_cast(U)) {
288 GS.HasNonInstructionUser = true;
289 // We might have a dead and dangling constant hanging off of here.
290 if (!isSafeToDestroyConstant(C))
291 return true;
292 } else {
293 GS.HasNonInstructionUser = true;
294 // Otherwise must be some other user.
295 return true;
296 }
297 }
298
299 return false;
300 }
301
302 /// Look at all uses of the global and fill in the GlobalStatus
303 /// structure. If the global has its address taken, return true to indicate we
304 /// can't do anything with it.
305 ///
306 static bool analyzeGlobal(const Value *V, GlobalStatus &GS) {
307 SmallPtrSet PHIUsers;
308 return analyzeGlobalAux(V, GS, PHIUsers);
101
102
309103 }
310104
311105 /// isLeakCheckerRoot - Is this global variable possibly used by a leak checker
19261720
19271721 GlobalStatus GS;
19281722
1929 if (analyzeGlobal(GV, GS))
1723 if (GlobalStatus::analyzeGlobal(GV, GS))
19301724 return false;
19311725
19321726 if (!GS.IsCompared && !GV->hasUnnamedAddr()) {
99 // This pass loops over all of the functions and variables in the input module.
1010 // If the function or variable is not in the list of external names given to
1111 // the pass it is marked as internal.
12 //
13 // This transformation would not be legal or profitable in a regular
14 // compilation, but it gets extra information from the linker about what is safe
15 // or profitable.
16 //
17 // As an example of a normally illegal transformation: Internalizing a function
18 // with external linkage. Only if we are told it is only used from within this
19 // module, it is safe to do it.
20 //
21 // On the profitability side: It is always legal to internalize a linkonce_odr
22 // whose address is not used. Doing so normally would introduce code bloat, but
23 // if we are told by the linker that the only use of this would be for a
24 // DSO symbol table, it is profitable to hide it.
1225 //
1326 //===----------------------------------------------------------------------===//
1427
2235 #include "llvm/Support/CommandLine.h"
2336 #include "llvm/Support/Debug.h"
2437 #include "llvm/Support/raw_ostream.h"
38 #include "llvm/Transforms/Utils/GlobalStatus.h"
2539 #include "llvm/Transforms/Utils/ModuleUtils.h"
2640 #include
2741 #include
141155 if (GV.hasUnnamedAddr())
142156 return true;
143157
144 // FIXME: Check if the address is used.
145 return false;
158 GlobalStatus GS;
159 if (GlobalStatus::analyzeGlobal(&GV, GS))
160 return false;
161
162 return !GS.IsCompared;
146163 }
147164
148165 bool InternalizePass::runOnModule(Module &M) {
77 CmpInstAnalysis.cpp
88 CodeExtractor.cpp
99 DemoteRegToStack.cpp
10 GlobalStatus.cpp
1011 InlineFunction.cpp
1112 InstructionNamer.cpp
1213 IntegerDivision.cpp
0 //===-- GlobalStatus.cpp - Compute status info for globals -----------------==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/SmallPtrSet.h"
10 #include "llvm/IR/BasicBlock.h"
11 #include "llvm/IR/GlobalVariable.h"
12 #include "llvm/IR/IntrinsicInst.h"
13 #include "llvm/Transforms/Utils/GlobalStatus.h"
14
15 using namespace llvm;
16
17 /// Return the stronger of the two ordering. If the two orderings are acquire
18 /// and release, then return AcquireRelease.
19 ///
20 static AtomicOrdering strongerOrdering(AtomicOrdering X, AtomicOrdering Y) {
21 if (X == Acquire && Y == Release)
22 return AcquireRelease;
23 if (Y == Acquire && X == Release)
24 return AcquireRelease;
25 return (AtomicOrdering)std::max(X, Y);
26 }
27
28 /// It is safe to destroy a constant iff it is only used by constants itself.
29 /// Note that constants cannot be cyclic, so this test is pretty easy to
30 /// implement recursively.
31 ///
32 bool llvm::isSafeToDestroyConstant(const Constant *C) {
33 if (isa(C))
34 return false;
35
36 for (Value::const_use_iterator UI = C->use_begin(), E = C->use_end(); UI != E;
37 ++UI)
38 if (const Constant *CU = dyn_cast(*UI)) {
39 if (!isSafeToDestroyConstant(CU))
40 return false;
41 } else
42 return false;
43 return true;
44 }
45
46 static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
47 SmallPtrSet &PhiUsers) {
48 for (Value::const_use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;
49 ++UI) {
50 const User *U = *UI;
51 if (const ConstantExpr *CE = dyn_cast(U)) {
52 GS.HasNonInstructionUser = true;
53
54 // If the result of the constantexpr isn't pointer type, then we won't
55 // know to expect it in various places. Just reject early.
56 if (!isa(CE->getType()))
57 return true;
58
59 if (analyzeGlobalAux(CE, GS, PhiUsers))
60 return true;
61 } else if (const Instruction *I = dyn_cast(U)) {
62 if (!GS.HasMultipleAccessingFunctions) {
63 const Function *F = I->getParent()->getParent();
64 if (GS.AccessingFunction == 0)
65 GS.AccessingFunction = F;
66 else if (GS.AccessingFunction != F)
67 GS.HasMultipleAccessingFunctions = true;
68 }
69 if (const LoadInst *LI = dyn_cast(I)) {
70 GS.IsLoaded = true;
71 // Don't hack on volatile loads.
72 if (LI->isVolatile())
73 return true;
74 GS.Ordering = strongerOrdering(GS.Ordering, LI->getOrdering());
75 } else if (const StoreInst *SI = dyn_cast(I)) {
76 // Don't allow a store OF the address, only stores TO the address.
77 if (SI->getOperand(0) == V)
78 return true;
79
80 // Don't hack on volatile stores.
81 if (SI->isVolatile())
82 return true;
83
84 GS.Ordering = strongerOrdering(GS.Ordering, SI->getOrdering());
85
86 // If this is a direct store to the global (i.e., the global is a scalar
87 // value, not an aggregate), keep more specific information about
88 // stores.
89 if (GS.StoredType != GlobalStatus::Stored) {
90 if (const GlobalVariable *GV =
91 dyn_cast(SI->getOperand(1))) {
92 Value *StoredVal = SI->getOperand(0);
93
94 if (Constant *C = dyn_cast(StoredVal)) {
95 if (C->isThreadDependent()) {
96 // The stored value changes between threads; don't track it.
97 return true;
98 }
99 }
100
101 if (StoredVal == GV->getInitializer()) {
102 if (GS.StoredType < GlobalStatus::InitializerStored)
103 GS.StoredType = GlobalStatus::InitializerStored;
104 } else if (isa(StoredVal) &&
105 cast(StoredVal)->getOperand(0) == GV) {
106 if (GS.StoredType < GlobalStatus::InitializerStored)
107 GS.StoredType = GlobalStatus::InitializerStored;
108 } else if (GS.StoredType < GlobalStatus::StoredOnce) {
109 GS.StoredType = GlobalStatus::StoredOnce;
110 GS.StoredOnceValue = StoredVal;
111 } else if (GS.StoredType == GlobalStatus::StoredOnce &&
112 GS.StoredOnceValue == StoredVal) {
113 // noop.
114 } else {
115 GS.StoredType = GlobalStatus::Stored;
116 }
117 } else {
118 GS.StoredType = GlobalStatus::Stored;
119 }
120 }
121 } else if (isa(I)) {
122 if (analyzeGlobalAux(I, GS, PhiUsers))
123 return true;
124 } else if (isa(I)) {
125 if (analyzeGlobalAux(I, GS, PhiUsers))
126 return true;
127 } else if (isa(I)) {
128 if (analyzeGlobalAux(I, GS, PhiUsers))
129 return true;
130 } else if (const PHINode *PN = dyn_cast(I)) {
131 // PHI nodes we can check just like select or GEP instructions, but we
132 // have to be careful about infinite recursion.
133 if (PhiUsers.insert(PN)) // Not already visited.
134 if (analyzeGlobalAux(I, GS, PhiUsers))
135 return true;
136 } else if (isa(I)) {
137 GS.IsCompared = true;
138 } else if (const MemTransferInst *MTI = dyn_cast(I)) {
139 if (MTI->isVolatile())
140 return true;
141 if (MTI->getArgOperand(0) == V)
142 GS.StoredType = GlobalStatus::Stored;
143 if (MTI->getArgOperand(1) == V)
144 GS.IsLoaded = true;
145 } else if (const MemSetInst *MSI = dyn_cast(I)) {
146 assert(MSI->getArgOperand(0) == V && "Memset only takes one pointer!");
147 if (MSI->isVolatile())
148 return true;
149 GS.StoredType = GlobalStatus::Stored;
150 } else {
151 return true; // Any other non-load instruction might take address!
152 }
153 } else if (const Constant *C = dyn_cast(U)) {
154 GS.HasNonInstructionUser = true;
155 // We might have a dead and dangling constant hanging off of here.
156 if (!isSafeToDestroyConstant(C))
157 return true;
158 } else {
159 GS.HasNonInstructionUser = true;
160 // Otherwise must be some other user.
161 return true;
162 }
163 }
164
165 return false;
166 }
167
168 bool GlobalStatus::analyzeGlobal(const Value *V, GlobalStatus &GS) {
169 SmallPtrSet PhiUsers;
170 return analyzeGlobalAux(V, GS, PhiUsers);
171 }
172
173 GlobalStatus::GlobalStatus()
174 : IsCompared(false), IsLoaded(false), StoredType(NotStored),
175 StoredOnceValue(0), AccessingFunction(0),
176 HasMultipleAccessingFunctions(false), HasNonInstructionUser(false),
177 Ordering(NotAtomic) {}
2828 ; RUN: llvm-nm %t | FileCheck %s -check-prefix=ZED1_AND_ZED2
2929 ; ZED1_AND_ZED2: V zed1
3030 @zed1 = linkonce_odr global i32 42
31 define i32* @get_zed1() {
32 ret i32* @zed1
33 }
3134
3235 ; ZED1_AND_ZED2: d zed2
3336 @zed2 = linkonce_odr unnamed_addr global i32 42
1414
1515 ; Put zed1 and zed2 in the symbol table. If the address is not relevant, we
1616 ; internalize them.
17 ; RUN: opt < %s -internalize -internalize-dso-list zed1,zed2 -S | FileCheck --check-prefix=ZED1_AND_ZED2 %s
17 ; RUN: opt < %s -internalize -internalize-dso-list zed1,zed2,zed3 -S | FileCheck --check-prefix=ZEDS %s
1818
1919 ; ALL: @i = internal global
2020 ; FOO_AND_J: @i = internal global
2828 ; FOO_J_AND_BAR: @j = global
2929 @j = global i32 0
3030
31 ; ZED1_AND_ZED2: @zed1 = linkonce_odr global i32 42
31 ; ZEDS: @zed1 = internal global i32 42
3232 @zed1 = linkonce_odr global i32 42
3333
34 ; ZED1_AND_ZED2: @zed2 = internal unnamed_addr global i32 42
34 ; ZEDS: @zed2 = internal unnamed_addr global i32 42
3535 @zed2 = linkonce_odr unnamed_addr global i32 42
36
37 ; ZEDS: @zed3 = linkonce_odr global i32 42
38 @zed3 = linkonce_odr global i32 42
39 define i32* @get_zed3() {
40 ret i32* @zed3
41 }
3642
3743 ; ALL: define internal void @main() {
3844 ; FOO_AND_J: define internal void @main() {