@@ -106,6 +106,175 @@ static cl::opt<int> ColdCCRelFreq(
106
106
" entry frequency, for a call site to be considered cold for enabling"
107
107
" coldcc" ));
108
108
109
+ // / Is this global variable possibly used by a leak checker as a root? If so,
110
+ // / we might not really want to eliminate the stores to it.
111
+ static bool isLeakCheckerRoot (GlobalVariable *GV) {
112
+ // A global variable is a root if it is a pointer, or could plausibly contain
113
+ // a pointer. There are two challenges; one is that we could have a struct
114
+ // the has an inner member which is a pointer. We recurse through the type to
115
+ // detect these (up to a point). The other is that we may actually be a union
116
+ // of a pointer and another type, and so our LLVM type is an integer which
117
+ // gets converted into a pointer, or our type is an [i8 x #] with a pointer
118
+ // potentially contained here.
119
+
120
+ if (GV->hasPrivateLinkage ())
121
+ return false ;
122
+
123
+ SmallVector<Type *, 4 > Types;
124
+ Types.push_back (GV->getValueType ());
125
+
126
+ unsigned Limit = 20 ;
127
+ do {
128
+ Type *Ty = Types.pop_back_val ();
129
+ switch (Ty->getTypeID ()) {
130
+ default : break ;
131
+ case Type::PointerTyID:
132
+ return true ;
133
+ case Type::FixedVectorTyID:
134
+ case Type::ScalableVectorTyID:
135
+ if (cast<VectorType>(Ty)->getElementType ()->isPointerTy ())
136
+ return true ;
137
+ break ;
138
+ case Type::ArrayTyID:
139
+ Types.push_back (cast<ArrayType>(Ty)->getElementType ());
140
+ break ;
141
+ case Type::StructTyID: {
142
+ StructType *STy = cast<StructType>(Ty);
143
+ if (STy->isOpaque ()) return true ;
144
+ for (StructType::element_iterator I = STy->element_begin (),
145
+ E = STy->element_end (); I != E; ++I) {
146
+ Type *InnerTy = *I;
147
+ if (isa<PointerType>(InnerTy)) return true ;
148
+ if (isa<StructType>(InnerTy) || isa<ArrayType>(InnerTy) ||
149
+ isa<VectorType>(InnerTy))
150
+ Types.push_back (InnerTy);
151
+ }
152
+ break ;
153
+ }
154
+ }
155
+ if (--Limit == 0 ) return true ;
156
+ } while (!Types.empty ());
157
+ return false ;
158
+ }
159
+
160
+ // / Given a value that is stored to a global but never read, determine whether
161
+ // / it's safe to remove the store and the chain of computation that feeds the
162
+ // / store.
163
+ static bool IsSafeComputationToRemove (
164
+ Value *V, function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
165
+ do {
166
+ if (isa<Constant>(V))
167
+ return true ;
168
+ if (!V->hasOneUse ())
169
+ return false ;
170
+ if (isa<LoadInst>(V) || isa<InvokeInst>(V) || isa<Argument>(V) ||
171
+ isa<GlobalValue>(V))
172
+ return false ;
173
+ if (isAllocationFn (V, GetTLI))
174
+ return true ;
175
+
176
+ Instruction *I = cast<Instruction>(V);
177
+ if (I->mayHaveSideEffects ())
178
+ return false ;
179
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {
180
+ if (!GEP->hasAllConstantIndices ())
181
+ return false ;
182
+ } else if (I->getNumOperands () != 1 ) {
183
+ return false ;
184
+ }
185
+
186
+ V = I->getOperand (0 );
187
+ } while (true );
188
+ }
189
+
190
+ // / This GV is a pointer root. Loop over all users of the global and clean up
191
+ // / any that obviously don't assign the global a value that isn't dynamically
192
+ // / allocated.
193
+ static bool
194
+ CleanupPointerRootUsers (GlobalVariable *GV,
195
+ function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
196
+ // A brief explanation of leak checkers. The goal is to find bugs where
197
+ // pointers are forgotten, causing an accumulating growth in memory
198
+ // usage over time. The common strategy for leak checkers is to explicitly
199
+ // allow the memory pointed to by globals at exit. This is popular because it
200
+ // also solves another problem where the main thread of a C++ program may shut
201
+ // down before other threads that are still expecting to use those globals. To
202
+ // handle that case, we expect the program may create a singleton and never
203
+ // destroy it.
204
+
205
+ bool Changed = false ;
206
+
207
+ // If Dead[n].first is the only use of a malloc result, we can delete its
208
+ // chain of computation and the store to the global in Dead[n].second.
209
+ SmallVector<std::pair<Instruction *, Instruction *>, 32 > Dead;
210
+
211
+ // Constants can't be pointers to dynamically allocated memory.
212
+ for (Value::user_iterator UI = GV->user_begin (), E = GV->user_end ();
213
+ UI != E;) {
214
+ User *U = *UI++;
215
+ if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
216
+ Value *V = SI->getValueOperand ();
217
+ if (isa<Constant>(V)) {
218
+ Changed = true ;
219
+ SI->eraseFromParent ();
220
+ } else if (Instruction *I = dyn_cast<Instruction>(V)) {
221
+ if (I->hasOneUse ())
222
+ Dead.push_back (std::make_pair (I, SI));
223
+ }
224
+ } else if (MemSetInst *MSI = dyn_cast<MemSetInst>(U)) {
225
+ if (isa<Constant>(MSI->getValue ())) {
226
+ Changed = true ;
227
+ MSI->eraseFromParent ();
228
+ } else if (Instruction *I = dyn_cast<Instruction>(MSI->getValue ())) {
229
+ if (I->hasOneUse ())
230
+ Dead.push_back (std::make_pair (I, MSI));
231
+ }
232
+ } else if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(U)) {
233
+ GlobalVariable *MemSrc = dyn_cast<GlobalVariable>(MTI->getSource ());
234
+ if (MemSrc && MemSrc->isConstant ()) {
235
+ Changed = true ;
236
+ MTI->eraseFromParent ();
237
+ } else if (Instruction *I = dyn_cast<Instruction>(MemSrc)) {
238
+ if (I->hasOneUse ())
239
+ Dead.push_back (std::make_pair (I, MTI));
240
+ }
241
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
242
+ if (CE->use_empty ()) {
243
+ CE->destroyConstant ();
244
+ Changed = true ;
245
+ }
246
+ } else if (Constant *C = dyn_cast<Constant>(U)) {
247
+ if (isSafeToDestroyConstant (C)) {
248
+ C->destroyConstant ();
249
+ // This could have invalidated UI, start over from scratch.
250
+ Dead.clear ();
251
+ CleanupPointerRootUsers (GV, GetTLI);
252
+ return true ;
253
+ }
254
+ }
255
+ }
256
+
257
+ for (int i = 0 , e = Dead.size (); i != e; ++i) {
258
+ if (IsSafeComputationToRemove (Dead[i].first , GetTLI)) {
259
+ Dead[i].second ->eraseFromParent ();
260
+ Instruction *I = Dead[i].first ;
261
+ do {
262
+ if (isAllocationFn (I, GetTLI))
263
+ break ;
264
+ Instruction *J = dyn_cast<Instruction>(I->getOperand (0 ));
265
+ if (!J)
266
+ break ;
267
+ I->eraseFromParent ();
268
+ I = J;
269
+ } while (true );
270
+ I->eraseFromParent ();
271
+ Changed = true ;
272
+ }
273
+ }
274
+
275
+ return Changed;
276
+ }
277
+
109
278
// / We just marked GV constant. Loop over all users of the global, cleaning up
110
279
// / the obvious ones. This is largely just a quick scan over the use list to
111
280
// / clean up the easy and obvious cruft. This returns true if it made a change.
@@ -654,8 +823,12 @@ static bool OptimizeAwayTrappingUsesOfLoads(
654
823
// If we nuked all of the loads, then none of the stores are needed either,
655
824
// nor is the global.
656
825
if (AllNonStoreUsesGone) {
657
- Changed = true ;
658
- CleanupConstantGlobalUsers (GV, nullptr , DL, GetTLI);
826
+ if (isLeakCheckerRoot (GV)) {
827
+ Changed |= CleanupPointerRootUsers (GV, GetTLI);
828
+ } else {
829
+ Changed = true ;
830
+ CleanupConstantGlobalUsers (GV, nullptr , DL, GetTLI);
831
+ }
659
832
if (GV->use_empty ()) {
660
833
LLVM_DEBUG (dbgs () << " *** GLOBAL NOW DEAD!\n " );
661
834
Changed = true ;
@@ -1824,10 +1997,15 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
1824
1997
if (!GS.IsLoaded ) {
1825
1998
LLVM_DEBUG (dbgs () << " GLOBAL NEVER LOADED: " << *GV << " \n " );
1826
1999
1827
- // Delete any stores we can find to the global. We may not be able to
1828
- // make it completely dead though.
1829
- Changed =
1830
- CleanupConstantGlobalUsers (GV, GV->getInitializer (), DL, GetTLI);
2000
+ if (isLeakCheckerRoot (GV)) {
2001
+ // Delete any constant stores to the global.
2002
+ Changed = CleanupPointerRootUsers (GV, GetTLI);
2003
+ } else {
2004
+ // Delete any stores we can find to the global. We may not be able to
2005
+ // make it completely dead though.
2006
+ Changed =
2007
+ CleanupConstantGlobalUsers (GV, GV->getInitializer (), DL, GetTLI);
2008
+ }
1831
2009
1832
2010
// If the global is dead now, delete it.
1833
2011
if (GV->use_empty ()) {
0 commit comments