================ @@ -187,80 +187,147 @@ Value *lowerObjectSizeCall( const TargetLibraryInfo *TLI, AAResults *AA, bool MustSucceed, SmallVectorImpl<Instruction *> *InsertedInstructions = nullptr); -using SizeOffsetType = std::pair<APInt, APInt>; +/// SizeOffsetType - A base template class for the object size visitors. Used +/// here as a self-documenting way to handle the values rather than using a +/// \p std::pair. +template <typename T> struct SizeOffsetType { + T Size; + T Offset; + + bool knownSize() const; + bool knownOffset() const; + bool anyKnown() const; + bool bothKnown() const; +}; + +/// SizeOffsetType<APInt> - Used by \p ObjectSizeOffsetVisitor, which works +/// with \p APInts. +template <> struct SizeOffsetType<APInt> { + APInt Size; + APInt Offset; + + SizeOffsetType() = default; + SizeOffsetType(APInt Size, APInt Offset) : Size(Size), Offset(Offset) {} + + bool knownSize() const { return Size.getBitWidth() > 1; } + bool knownOffset() const { return Offset.getBitWidth() > 1; } + bool anyKnown() const { return knownSize() || knownOffset(); } + bool bothKnown() const { return knownSize() && knownOffset(); } + + bool operator==(const SizeOffsetType<APInt> &RHS) { + return Size == RHS.Size && Offset == RHS.Offset; + } + bool operator!=(const SizeOffsetType<APInt> &RHS) { return !(*this == RHS); } +}; +using SizeOffsetAPInt = SizeOffsetType<APInt>; /// Evaluate the size and offset of an object pointed to by a Value* /// statically. Fails if size or offset are not known at compile time. class ObjectSizeOffsetVisitor - : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> { + : public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetAPInt> { const DataLayout &DL; const TargetLibraryInfo *TLI; ObjectSizeOpts Options; unsigned IntTyBits; APInt Zero; - SmallDenseMap<Instruction *, SizeOffsetType, 8> SeenInsts; + SmallDenseMap<Instruction *, SizeOffsetAPInt, 8> SeenInsts; unsigned InstructionsVisited; APInt align(APInt Size, MaybeAlign Align); - SizeOffsetType unknown() { - return std::make_pair(APInt(), APInt()); - } + static SizeOffsetAPInt unknown; public: ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI, LLVMContext &Context, ObjectSizeOpts Options = {}); - SizeOffsetType compute(Value *V); - - static bool knownSize(const SizeOffsetType &SizeOffset) { - return SizeOffset.first.getBitWidth() > 1; - } - - static bool knownOffset(const SizeOffsetType &SizeOffset) { - return SizeOffset.second.getBitWidth() > 1; - } - - static bool bothKnown(const SizeOffsetType &SizeOffset) { - return knownSize(SizeOffset) && knownOffset(SizeOffset); - } + SizeOffsetAPInt compute(Value *V); // These are "private", except they can't actually be made private. Only // compute() should be used by external users. - SizeOffsetType visitAllocaInst(AllocaInst &I); - SizeOffsetType visitArgument(Argument &A); - SizeOffsetType visitCallBase(CallBase &CB); - SizeOffsetType visitConstantPointerNull(ConstantPointerNull&); - SizeOffsetType visitExtractElementInst(ExtractElementInst &I); - SizeOffsetType visitExtractValueInst(ExtractValueInst &I); - SizeOffsetType visitGlobalAlias(GlobalAlias &GA); - SizeOffsetType visitGlobalVariable(GlobalVariable &GV); - SizeOffsetType visitIntToPtrInst(IntToPtrInst&); - SizeOffsetType visitLoadInst(LoadInst &I); - SizeOffsetType visitPHINode(PHINode&); - SizeOffsetType visitSelectInst(SelectInst &I); - SizeOffsetType visitUndefValue(UndefValue&); - SizeOffsetType visitInstruction(Instruction &I); + SizeOffsetAPInt visitAllocaInst(AllocaInst &I); + SizeOffsetAPInt visitArgument(Argument &A); + SizeOffsetAPInt visitCallBase(CallBase &CB); + SizeOffsetAPInt visitConstantPointerNull(ConstantPointerNull &); + SizeOffsetAPInt visitExtractElementInst(ExtractElementInst &I); + SizeOffsetAPInt visitExtractValueInst(ExtractValueInst &I); + SizeOffsetAPInt visitGlobalAlias(GlobalAlias &GA); + SizeOffsetAPInt visitGlobalVariable(GlobalVariable &GV); + SizeOffsetAPInt visitIntToPtrInst(IntToPtrInst &); + SizeOffsetAPInt visitLoadInst(LoadInst &I); + SizeOffsetAPInt visitPHINode(PHINode &); + SizeOffsetAPInt visitSelectInst(SelectInst &I); + SizeOffsetAPInt visitUndefValue(UndefValue &); + SizeOffsetAPInt visitInstruction(Instruction &I); private: - SizeOffsetType findLoadSizeOffset( + SizeOffsetAPInt findLoadSizeOffset( LoadInst &LoadFrom, BasicBlock &BB, BasicBlock::iterator From, - SmallDenseMap<BasicBlock *, SizeOffsetType, 8> &VisitedBlocks, + SmallDenseMap<BasicBlock *, SizeOffsetAPInt, 8> &VisitedBlocks, unsigned &ScannedInstCount); - SizeOffsetType combineSizeOffset(SizeOffsetType LHS, SizeOffsetType RHS); - SizeOffsetType computeImpl(Value *V); - SizeOffsetType computeValue(Value *V); + SizeOffsetAPInt combineSizeOffset(SizeOffsetAPInt LHS, SizeOffsetAPInt RHS); + SizeOffsetAPInt computeImpl(Value *V); + SizeOffsetAPInt computeValue(Value *V); bool CheckedZextOrTrunc(APInt &I); }; -using SizeOffsetEvalType = std::pair<Value *, Value *>; +template <> struct SizeOffsetType<WeakTrackingVH>; + +/// SizeOffsetType<Value *> - Used by \p ObjectSizeOffsetEvaluator, which works +/// with \p Values. +template <> struct SizeOffsetType<Value *> { + Value *Size; + Value *Offset; + + SizeOffsetType() = default; + SizeOffsetType(Value *Size, Value *Offset) : Size(Size), Offset(Offset) {} + SizeOffsetType(SizeOffsetType<WeakTrackingVH> &SOT); ---------------- jdoerfert wrote:
I'm confused, where is this defined? https://github.com/llvm/llvm-project/pull/76882 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits