kosarev created this revision. kosarev added a project: clang. The information about access and type sizes is necessary for producing TBAA metadata in the new size-aware format. With this patch, https://reviews.llvm.org/D39955 and https://reviews.llvm.org/D39956 in place we should be able to change CodeGenTBAA::createScalarTypeNode() and CodeGenTBAA::getBaseTypeInfo() to generate metadata in the new format under the -new-struct-path-tbaa command-line option. For now, this new information remains unused.
Repository: rL LLVM https://reviews.llvm.org/D40176 Files: lib/CodeGen/CGClass.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenTBAA.cpp lib/CodeGen/CodeGenTBAA.h
Index: lib/CodeGen/CodeGenTBAA.h =================================================================== --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -36,40 +36,53 @@ enum class TBAAAccessKind : unsigned { Ordinary, MayAlias, + Incomplete, }; // TBAAAccessInfo - Describes a memory access in terms of TBAA. struct TBAAAccessInfo { TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, - llvm::MDNode *AccessType, uint64_t Offset) - : Kind(Kind), BaseType(BaseType), AccessType(AccessType), Offset(Offset) + llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size) + : Kind(Kind), BaseType(BaseType), AccessType(AccessType), + Offset(Offset), Size(Size) {} TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, - uint64_t Offset) - : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, Offset) + uint64_t Offset, uint64_t Size) + : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, + Offset, Size) {} - explicit TBAAAccessInfo(llvm::MDNode *AccessType) - : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0) + explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) + : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size) {} TBAAAccessInfo() - : TBAAAccessInfo(/* AccessType= */ nullptr) + : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0) {} static TBAAAccessInfo getMayAliasInfo() { - return TBAAAccessInfo(TBAAAccessKind::MayAlias, /* BaseType= */ nullptr, - /* AccessType= */ nullptr, /* Offset= */ 0); + return TBAAAccessInfo(TBAAAccessKind::MayAlias, + /* BaseType= */ nullptr, /* AccessType= */ nullptr, + /* Offset= */ 0, /* Size= */ 0); } bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } + static TBAAAccessInfo getIncompleteInfo() { + return TBAAAccessInfo(TBAAAccessKind::Incomplete, + /* BaseType= */ nullptr, /* AccessType= */ nullptr, + /* Offset= */ 0, /* Size= */ 0); + } + + bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } + bool operator==(const TBAAAccessInfo &Other) const { return Kind == Other.Kind && BaseType == Other.BaseType && AccessType == Other.AccessType && - Offset == Other.Offset; + Offset == Other.Offset && + Size == Other.Size; } bool operator!=(const TBAAAccessInfo &Other) const { @@ -95,12 +108,16 @@ /// Offset - The byte offset of the final access within the base one. Must be /// zero if the base access type is not specified. uint64_t Offset; + + /// Size - The size of access, in bytes. + uint64_t Size; }; /// CodeGenTBAA - This class organizes the cross-module state that is used /// while lowering AST types to LLVM types. class CodeGenTBAA { ASTContext &Context; + llvm::Module &Module; const CodeGenOptions &CodeGenOpts; const LangOptions &Features; MangleContext &MContext; @@ -138,25 +155,23 @@ SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, bool MayAlias); - /// A wrapper function to create a scalar type. For struct-path aware TBAA, - /// the scalar type has the same format as the struct type: name, offset, - /// pointer to another node in the type DAG. - llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent); + /// createScalarTypeNode - A wrapper function to create metadata nodes + /// describing scalar types. + llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, + uint64_t Size); public: - CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext, - const CodeGenOptions &CGO, - const LangOptions &Features, - MangleContext &MContext); + CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, + const LangOptions &Features, MangleContext &MContext); ~CodeGenTBAA(); /// getTypeInfo - Get metadata used to describe accesses to objects of the /// given type. llvm::MDNode *getTypeInfo(QualType QTy); /// getVTablePtrAccessInfo - Get the TBAA information that describes an /// access to a virtual table pointer. - TBAAAccessInfo getVTablePtrAccessInfo(); + TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of /// the given type. @@ -192,6 +207,7 @@ static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), DenseMapInfo<MDNode *>::getEmptyKey(), DenseMapInfo<MDNode *>::getEmptyKey(), + DenseMapInfo<uint64_t>::getEmptyKey(), DenseMapInfo<uint64_t>::getEmptyKey()); } @@ -201,15 +217,17 @@ static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), DenseMapInfo<MDNode *>::getTombstoneKey(), DenseMapInfo<MDNode *>::getTombstoneKey(), + DenseMapInfo<uint64_t>::getTombstoneKey(), DenseMapInfo<uint64_t>::getTombstoneKey()); } static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { auto KindValue = static_cast<unsigned>(Val.Kind); return DenseMapInfo<unsigned>::getHashValue(KindValue) ^ DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^ DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^ - DenseMapInfo<uint64_t>::getHashValue(Val.Offset); + DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^ + DenseMapInfo<uint64_t>::getHashValue(Val.Size); } static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -25,16 +25,17 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" #include "llvm/IR/Type.h" using namespace clang; using namespace CodeGen; -CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext, +CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext) - : Context(Ctx), CodeGenOpts(CGO), Features(Features), MContext(MContext), - MDHelper(VMContext), Root(nullptr), Char(nullptr) { -} + : Context(Ctx), Module(M), CodeGenOpts(CGO), Features(Features), + MContext(MContext), MDHelper(M.getContext()), Root(nullptr), Char(nullptr) +{} CodeGenTBAA::~CodeGenTBAA() { } @@ -56,8 +57,10 @@ // For both scalar TBAA and struct-path aware TBAA, the scalar type has the // same format: name, parent node, and offset. -llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name, - llvm::MDNode *Parent) { +llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name, + llvm::MDNode *Parent, + uint64_t Size) { + (void)Size; // TODO: Support generation of size-aware type nodes. return MDHelper.createTBAAScalarTypeNode(Name, Parent); } @@ -67,7 +70,7 @@ // these special powers only cover user-accessible memory, and doesn't // include things like vtables. if (!Char) - Char = createTBAAScalarType("omnipotent char", getRoot()); + Char = createScalarTypeNode("omnipotent char", getRoot(), /* Size= */ 1); return Char; } @@ -130,6 +133,8 @@ if (llvm::MDNode *N = MetadataCache[Ty]) return N; + uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); + // Handle builtin types. if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) { switch (BTy->getKind()) { @@ -161,7 +166,7 @@ // "underlying types". default: return MetadataCache[Ty] = - createTBAAScalarType(BTy->getName(Features), getChar()); + createScalarTypeNode(BTy->getName(Features), getChar(), Size); } } @@ -175,8 +180,8 @@ // TODO: Implement C++'s type "similarity" and consider dis-"similar" // pointers distinct. if (Ty->isPointerType() || Ty->isReferenceType()) - return MetadataCache[Ty] = createTBAAScalarType("any pointer", - getChar()); + return MetadataCache[Ty] = createScalarTypeNode("any pointer", + getChar(), Size); // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. @@ -191,15 +196,18 @@ SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); MContext.mangleTypeName(QualType(ETy, 0), Out); - return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar()); + return MetadataCache[Ty] = createScalarTypeNode(OutName, getChar(), Size); } // For now, handle any other kind of type conservatively. return MetadataCache[Ty] = getChar(); } -TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() { - return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot())); +TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) { + llvm::DataLayout DL(&Module); + unsigned Size = DL.getPointerTypeSize(VTablePtrType); + return TBAAAccessInfo(createScalarTypeNode("vtable pointer", getRoot(), Size), + Size); } bool @@ -239,7 +247,7 @@ uint64_t Offset = BaseOffset; uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy); - llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType)); + llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size)); Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); return true; } @@ -269,19 +277,20 @@ if (const RecordType *TTy = QTy->getAs<RecordType>()) { const RecordDecl *RD = TTy->getDecl()->getDefinition(); - const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); - SmallVector <std::pair<llvm::MDNode*, uint64_t>, 4> Fields; - unsigned idx = 0; - for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e; ++i, ++idx) { - QualType FieldQTy = i->getType(); - llvm::MDNode *FieldNode = isValidBaseType(FieldQTy) ? + SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields; + for (FieldDecl *Field : RD->fields()) { + QualType FieldQTy = Field->getType(); + llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ? getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy); - if (!FieldNode) + if (!TypeNode) return BaseTypeMetadataCache[Ty] = nullptr; - Fields.push_back(std::make_pair( - FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth())); + + uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex()); + uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity(); + uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity(); + Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, + TypeNode)); } SmallString<256> OutName; @@ -292,23 +301,32 @@ } else { OutName = RD->getName(); } + + // TODO: Support size-aware type nodes and create one here for the + // given aggregate type. + // Create the struct type node with a vector of pairs (offset, type). + SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes; + for (const auto &Field : Fields) + OffsetsAndTypes.push_back(std::make_pair(Field.TBAA, Field.Offset)); return BaseTypeMetadataCache[Ty] = - MDHelper.createTBAAStructTypeNode(OutName, Fields); + MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes); } return BaseTypeMetadataCache[Ty] = nullptr; } llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) { + assert(!Info.isIncomplete() && "Access to an object of an incomplete type!"); + if (Info.isMayAlias()) - Info = TBAAAccessInfo(getChar()); + Info = TBAAAccessInfo(getChar(), Info.Size); if (!Info.AccessType) return nullptr; if (!CodeGenOpts.StructPathTBAA) - Info = TBAAAccessInfo(Info.AccessType); + Info = TBAAAccessInfo(Info.AccessType, Info.Size); llvm::MDNode *&N = AccessTagMetadataCache[Info]; if (N) Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -664,7 +664,7 @@ /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an /// access to a virtual table pointer. - TBAAAccessInfo getTBAAVTablePtrAccessInfo(); + TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType); llvm::MDNode *getTBAAStructInfo(QualType QTy); Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -136,7 +136,7 @@ // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. if (LangOpts.Sanitize.has(SanitizerKind::Thread) || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) - TBAA.reset(new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(), + TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); // If debug info or coverage generation is enabled, create the CGDebugInfo @@ -579,13 +579,20 @@ } TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { - return TBAAAccessInfo(getTBAATypeInfo(AccessType)); + // Pointee values may have incomplete types, but they shall never be + // dereferenced. + if (AccessType->isIncompleteType()) + return TBAAAccessInfo::getIncompleteInfo(); + + uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity(); + return TBAAAccessInfo(getTBAATypeInfo(AccessType), Size); } -TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo() { +TBAAAccessInfo +CodeGenModule::getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType) { if (!TBAA) return TBAAAccessInfo(); - return TBAA->getVTablePtrAccessInfo(); + return TBAA->getVTablePtrAccessInfo(VTablePtrType); } llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -2423,7 +2423,8 @@ VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy); llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); - CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAVTablePtrAccessInfo()); + TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy); + CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); if (CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCodeGenOpts().StrictVTablePointers) CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass); @@ -2517,7 +2518,8 @@ const CXXRecordDecl *RD) { Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); - CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAVTablePtrAccessInfo()); + TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); + CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); if (CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCodeGenOpts().StrictVTablePointers)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits