@@ -187,80 +187,125 @@ Value *lowerObjectSizeCall(
187
187
const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed,
188
188
SmallVectorImpl<Instruction *> *InsertedInstructions = nullptr );
189
189
190
- using SizeOffsetType = std::pair<APInt, APInt>;
190
+ // / SizeOffsetType - A base template class for the object size visitors. Used
191
+ // / here as a self-documenting way to handle the values rather than using a
192
+ // / \p std::pair.
193
+ template <typename T, class C > class SizeOffsetType {
194
+ public:
195
+ T Size ;
196
+ T Offset;
197
+
198
+ SizeOffsetType () = default ;
199
+ SizeOffsetType (T Size , T Offset) : Size (Size ), Offset(Offset) {}
200
+
201
+ bool knownSize () const { return C::known (Size ); }
202
+ bool knownOffset () const { return C::known (Offset); }
203
+ bool anyKnown () const { return knownSize () || knownOffset (); }
204
+ bool bothKnown () const { return knownSize () && knownOffset (); }
205
+
206
+ bool operator ==(const SizeOffsetType<T, C> &RHS) const {
207
+ return Size == RHS.Size && Offset == RHS.Offset ;
208
+ }
209
+ bool operator !=(const SizeOffsetType<T, C> &RHS) const {
210
+ return !(*this == RHS);
211
+ }
212
+ };
213
+
214
+ // / SizeOffsetAPInt - Used by \p ObjectSizeOffsetVisitor, which works with
215
+ // / \p APInts.
216
+ class SizeOffsetAPInt : public SizeOffsetType <APInt, SizeOffsetAPInt> {
217
+ friend class SizeOffsetType ;
218
+ static bool known (APInt V) { return V.getBitWidth () > 1 ; }
219
+
220
+ public:
221
+ SizeOffsetAPInt () = default ;
222
+ SizeOffsetAPInt (APInt Size , APInt Offset) : SizeOffsetType(Size , Offset) {}
223
+ };
191
224
192
225
// / Evaluate the size and offset of an object pointed to by a Value*
193
226
// / statically. Fails if size or offset are not known at compile time.
194
227
class ObjectSizeOffsetVisitor
195
- : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType > {
228
+ : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetAPInt > {
196
229
const DataLayout &DL;
197
230
const TargetLibraryInfo *TLI;
198
231
ObjectSizeOpts Options;
199
232
unsigned IntTyBits;
200
233
APInt Zero;
201
- SmallDenseMap<Instruction *, SizeOffsetType , 8 > SeenInsts;
234
+ SmallDenseMap<Instruction *, SizeOffsetAPInt , 8 > SeenInsts;
202
235
unsigned InstructionsVisited;
203
236
204
237
APInt align (APInt Size , MaybeAlign Align);
205
238
206
- SizeOffsetType unknown () {
207
- return std::make_pair (APInt (), APInt ());
208
- }
239
+ static SizeOffsetAPInt unknown () { return SizeOffsetAPInt (); }
209
240
210
241
public:
211
242
ObjectSizeOffsetVisitor (const DataLayout &DL, const TargetLibraryInfo *TLI,
212
243
LLVMContext &Context, ObjectSizeOpts Options = {});
213
244
214
- SizeOffsetType compute (Value *V);
215
-
216
- static bool knownSize (const SizeOffsetType &SizeOffset) {
217
- return SizeOffset.first .getBitWidth () > 1 ;
218
- }
219
-
220
- static bool knownOffset (const SizeOffsetType &SizeOffset) {
221
- return SizeOffset.second .getBitWidth () > 1 ;
222
- }
223
-
224
- static bool bothKnown (const SizeOffsetType &SizeOffset) {
225
- return knownSize (SizeOffset) && knownOffset (SizeOffset);
226
- }
245
+ SizeOffsetAPInt compute (Value *V);
227
246
228
247
// These are "private", except they can't actually be made private. Only
229
248
// compute() should be used by external users.
230
- SizeOffsetType visitAllocaInst (AllocaInst &I);
231
- SizeOffsetType visitArgument (Argument &A);
232
- SizeOffsetType visitCallBase (CallBase &CB);
233
- SizeOffsetType visitConstantPointerNull (ConstantPointerNull&);
234
- SizeOffsetType visitExtractElementInst (ExtractElementInst &I);
235
- SizeOffsetType visitExtractValueInst (ExtractValueInst &I);
236
- SizeOffsetType visitGlobalAlias (GlobalAlias &GA);
237
- SizeOffsetType visitGlobalVariable (GlobalVariable &GV);
238
- SizeOffsetType visitIntToPtrInst (IntToPtrInst&);
239
- SizeOffsetType visitLoadInst (LoadInst &I);
240
- SizeOffsetType visitPHINode (PHINode&);
241
- SizeOffsetType visitSelectInst (SelectInst &I);
242
- SizeOffsetType visitUndefValue (UndefValue&);
243
- SizeOffsetType visitInstruction (Instruction &I);
249
+ SizeOffsetAPInt visitAllocaInst (AllocaInst &I);
250
+ SizeOffsetAPInt visitArgument (Argument &A);
251
+ SizeOffsetAPInt visitCallBase (CallBase &CB);
252
+ SizeOffsetAPInt visitConstantPointerNull (ConstantPointerNull &);
253
+ SizeOffsetAPInt visitExtractElementInst (ExtractElementInst &I);
254
+ SizeOffsetAPInt visitExtractValueInst (ExtractValueInst &I);
255
+ SizeOffsetAPInt visitGlobalAlias (GlobalAlias &GA);
256
+ SizeOffsetAPInt visitGlobalVariable (GlobalVariable &GV);
257
+ SizeOffsetAPInt visitIntToPtrInst (IntToPtrInst &);
258
+ SizeOffsetAPInt visitLoadInst (LoadInst &I);
259
+ SizeOffsetAPInt visitPHINode (PHINode &);
260
+ SizeOffsetAPInt visitSelectInst (SelectInst &I);
261
+ SizeOffsetAPInt visitUndefValue (UndefValue &);
262
+ SizeOffsetAPInt visitInstruction (Instruction &I);
244
263
245
264
private:
246
- SizeOffsetType findLoadSizeOffset (
265
+ SizeOffsetAPInt findLoadSizeOffset (
247
266
LoadInst &LoadFrom, BasicBlock &BB, BasicBlock::iterator From,
248
- SmallDenseMap<BasicBlock *, SizeOffsetType , 8 > &VisitedBlocks,
267
+ SmallDenseMap<BasicBlock *, SizeOffsetAPInt , 8 > &VisitedBlocks,
249
268
unsigned &ScannedInstCount);
250
- SizeOffsetType combineSizeOffset (SizeOffsetType LHS, SizeOffsetType RHS);
251
- SizeOffsetType computeImpl (Value *V);
252
- SizeOffsetType computeValue (Value *V);
269
+ SizeOffsetAPInt combineSizeOffset (SizeOffsetAPInt LHS, SizeOffsetAPInt RHS);
270
+ SizeOffsetAPInt computeImpl (Value *V);
271
+ SizeOffsetAPInt computeValue (Value *V);
253
272
bool CheckedZextOrTrunc (APInt &I);
254
273
};
255
274
256
- using SizeOffsetEvalType = std::pair<Value *, Value *>;
275
+ // / SizeOffsetValue - Used by \p ObjectSizeOffsetEvaluator, which works with
276
+ // / \p Values.
277
+ class SizeOffsetWeakTrackingVH ;
278
+ class SizeOffsetValue : public SizeOffsetType <Value *, SizeOffsetValue> {
279
+ friend class SizeOffsetType ;
280
+ static bool known (Value *V) { return V != nullptr ; }
281
+
282
+ public:
283
+ SizeOffsetValue () : SizeOffsetType(nullptr , nullptr ) {}
284
+ SizeOffsetValue (Value *Size , Value *Offset) : SizeOffsetType(Size , Offset) {}
285
+ SizeOffsetValue (const SizeOffsetWeakTrackingVH &SOT);
286
+ };
287
+
288
+ // / SizeOffsetWeakTrackingVH - Used by \p ObjectSizeOffsetEvaluator in a
289
+ // / \p DenseMap.
290
+ class SizeOffsetWeakTrackingVH
291
+ : public SizeOffsetType<WeakTrackingVH, SizeOffsetWeakTrackingVH> {
292
+ friend class SizeOffsetType ;
293
+ static bool known (WeakTrackingVH V) { return V.pointsToAliveValue (); }
294
+
295
+ public:
296
+ SizeOffsetWeakTrackingVH () : SizeOffsetType(nullptr , nullptr ) {}
297
+ SizeOffsetWeakTrackingVH (Value *Size , Value *Offset)
298
+ : SizeOffsetType(Size , Offset) {}
299
+ SizeOffsetWeakTrackingVH (const SizeOffsetValue &SOV)
300
+ : SizeOffsetType(SOV.Size , SOV.Offset) {}
301
+ };
257
302
258
303
// / Evaluate the size and offset of an object pointed to by a Value*.
259
304
// / May create code to compute the result at run-time.
260
305
class ObjectSizeOffsetEvaluator
261
- : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType > {
306
+ : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetValue > {
262
307
using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
263
- using WeakEvalType = std::pair<WeakTrackingVH, WeakTrackingVH> ;
308
+ using WeakEvalType = SizeOffsetWeakTrackingVH ;
264
309
using CacheMapTy = DenseMap<const Value *, WeakEvalType>;
265
310
using PtrSetTy = SmallPtrSet<const Value *, 8 >;
266
311
@@ -275,45 +320,27 @@ class ObjectSizeOffsetEvaluator
275
320
ObjectSizeOpts EvalOpts;
276
321
SmallPtrSet<Instruction *, 8 > InsertedInstructions;
277
322
278
- SizeOffsetEvalType compute_ (Value *V);
323
+ SizeOffsetValue compute_ (Value *V);
279
324
280
325
public:
281
- static SizeOffsetEvalType unknown () {
282
- return std::make_pair (nullptr , nullptr );
283
- }
284
-
285
326
ObjectSizeOffsetEvaluator (const DataLayout &DL, const TargetLibraryInfo *TLI,
286
327
LLVMContext &Context, ObjectSizeOpts EvalOpts = {});
287
328
288
- SizeOffsetEvalType compute (Value *V);
289
-
290
- bool knownSize (SizeOffsetEvalType SizeOffset) {
291
- return SizeOffset.first ;
292
- }
293
-
294
- bool knownOffset (SizeOffsetEvalType SizeOffset) {
295
- return SizeOffset.second ;
296
- }
297
-
298
- bool anyKnown (SizeOffsetEvalType SizeOffset) {
299
- return knownSize (SizeOffset) || knownOffset (SizeOffset);
300
- }
329
+ static SizeOffsetValue unknown () { return SizeOffsetValue (); }
301
330
302
- bool bothKnown (SizeOffsetEvalType SizeOffset) {
303
- return knownSize (SizeOffset) && knownOffset (SizeOffset);
304
- }
331
+ SizeOffsetValue compute (Value *V);
305
332
306
333
// The individual instruction visitors should be treated as private.
307
- SizeOffsetEvalType visitAllocaInst (AllocaInst &I);
308
- SizeOffsetEvalType visitCallBase (CallBase &CB);
309
- SizeOffsetEvalType visitExtractElementInst (ExtractElementInst &I);
310
- SizeOffsetEvalType visitExtractValueInst (ExtractValueInst &I);
311
- SizeOffsetEvalType visitGEPOperator (GEPOperator &GEP);
312
- SizeOffsetEvalType visitIntToPtrInst (IntToPtrInst&);
313
- SizeOffsetEvalType visitLoadInst (LoadInst &I);
314
- SizeOffsetEvalType visitPHINode (PHINode &PHI);
315
- SizeOffsetEvalType visitSelectInst (SelectInst &I);
316
- SizeOffsetEvalType visitInstruction (Instruction &I);
334
+ SizeOffsetValue visitAllocaInst (AllocaInst &I);
335
+ SizeOffsetValue visitCallBase (CallBase &CB);
336
+ SizeOffsetValue visitExtractElementInst (ExtractElementInst &I);
337
+ SizeOffsetValue visitExtractValueInst (ExtractValueInst &I);
338
+ SizeOffsetValue visitGEPOperator (GEPOperator &GEP);
339
+ SizeOffsetValue visitIntToPtrInst (IntToPtrInst &);
340
+ SizeOffsetValue visitLoadInst (LoadInst &I);
341
+ SizeOffsetValue visitPHINode (PHINode &PHI);
342
+ SizeOffsetValue visitSelectInst (SelectInst &I);
343
+ SizeOffsetValue visitInstruction (Instruction &I);
317
344
};
318
345
319
346
} // end namespace llvm
0 commit comments