10b57cec5SDimitry Andric //===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This is the code that manages TBAA information and defines the TBAA policy 100b57cec5SDimitry Andric // for the optimizer to use. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H 150b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "clang/AST/Type.h" 180b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 190b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 200b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 210b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace clang { 240b57cec5SDimitry Andric class ASTContext; 250b57cec5SDimitry Andric class CodeGenOptions; 260b57cec5SDimitry Andric class LangOptions; 270b57cec5SDimitry Andric class MangleContext; 280b57cec5SDimitry Andric class QualType; 290b57cec5SDimitry Andric class Type; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace CodeGen { 32*0fca6ea1SDimitry Andric class CodeGenTypes; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // TBAAAccessKind - A kind of TBAA memory access descriptor. 350b57cec5SDimitry Andric enum class TBAAAccessKind : unsigned { 360b57cec5SDimitry Andric Ordinary, 370b57cec5SDimitry Andric MayAlias, 380b57cec5SDimitry Andric Incomplete, 390b57cec5SDimitry Andric }; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric // TBAAAccessInfo - Describes a memory access in terms of TBAA. 420b57cec5SDimitry Andric struct TBAAAccessInfo { 430b57cec5SDimitry Andric TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, 440b57cec5SDimitry Andric llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size) 450b57cec5SDimitry Andric : Kind(Kind), BaseType(BaseType), AccessType(AccessType), 460b57cec5SDimitry Andric Offset(Offset), Size(Size) 470b57cec5SDimitry Andric {} 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, 500b57cec5SDimitry Andric uint64_t Offset, uint64_t Size) 510b57cec5SDimitry Andric : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, 520b57cec5SDimitry Andric Offset, Size) 530b57cec5SDimitry Andric {} 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) 560b57cec5SDimitry Andric : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size) 570b57cec5SDimitry Andric {} 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric TBAAAccessInfo() 600b57cec5SDimitry Andric : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0) 610b57cec5SDimitry Andric {} 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric static TBAAAccessInfo getMayAliasInfo() { 640b57cec5SDimitry Andric return TBAAAccessInfo(TBAAAccessKind::MayAlias, 650b57cec5SDimitry Andric /* BaseType= */ nullptr, /* AccessType= */ nullptr, 660b57cec5SDimitry Andric /* Offset= */ 0, /* Size= */ 0); 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric static TBAAAccessInfo getIncompleteInfo() { 720b57cec5SDimitry Andric return TBAAAccessInfo(TBAAAccessKind::Incomplete, 730b57cec5SDimitry Andric /* BaseType= */ nullptr, /* AccessType= */ nullptr, 740b57cec5SDimitry Andric /* Offset= */ 0, /* Size= */ 0); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric bool operator==(const TBAAAccessInfo &Other) const { 800b57cec5SDimitry Andric return Kind == Other.Kind && 810b57cec5SDimitry Andric BaseType == Other.BaseType && 820b57cec5SDimitry Andric AccessType == Other.AccessType && 830b57cec5SDimitry Andric Offset == Other.Offset && 840b57cec5SDimitry Andric Size == Other.Size; 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric bool operator!=(const TBAAAccessInfo &Other) const { 880b57cec5SDimitry Andric return !(*this == Other); 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric explicit operator bool() const { 920b57cec5SDimitry Andric return *this != TBAAAccessInfo(); 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /// Kind - The kind of the access descriptor. 960b57cec5SDimitry Andric TBAAAccessKind Kind; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric /// BaseType - The base/leading access type. May be null if this access 990b57cec5SDimitry Andric /// descriptor represents an access that is not considered to be an access 1000b57cec5SDimitry Andric /// to an aggregate or union member. 1010b57cec5SDimitry Andric llvm::MDNode *BaseType; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// AccessType - The final access type. May be null if there is no TBAA 1040b57cec5SDimitry Andric /// information available about this access. 1050b57cec5SDimitry Andric llvm::MDNode *AccessType; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// Offset - The byte offset of the final access within the base one. Must be 1080b57cec5SDimitry Andric /// zero if the base access type is not specified. 1090b57cec5SDimitry Andric uint64_t Offset; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric /// Size - The size of access, in bytes. 1120b57cec5SDimitry Andric uint64_t Size; 1130b57cec5SDimitry Andric }; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric /// CodeGenTBAA - This class organizes the cross-module state that is used 1160b57cec5SDimitry Andric /// while lowering AST types to LLVM types. 1170b57cec5SDimitry Andric class CodeGenTBAA { 1180b57cec5SDimitry Andric ASTContext &Context; 119*0fca6ea1SDimitry Andric CodeGenTypes &CGTypes; 1200b57cec5SDimitry Andric llvm::Module &Module; 1210b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts; 1220b57cec5SDimitry Andric const LangOptions &Features; 1230b57cec5SDimitry Andric MangleContext &MContext; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric // MDHelper - Helper for creating metadata. 1260b57cec5SDimitry Andric llvm::MDBuilder MDHelper; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing 1290b57cec5SDimitry Andric /// them. 1300b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; 1310b57cec5SDimitry Andric /// This maps clang::Types to a base access type in the type DAG. 1320b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache; 1330b57cec5SDimitry Andric /// This maps TBAA access descriptors to tag nodes. 1340b57cec5SDimitry Andric llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing 1370b57cec5SDimitry Andric /// them for struct assignments. 1380b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric llvm::MDNode *Root; 1410b57cec5SDimitry Andric llvm::MDNode *Char; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric /// getRoot - This is the mdnode for the root of the metadata type graph 1440b57cec5SDimitry Andric /// for this translation unit. 1450b57cec5SDimitry Andric llvm::MDNode *getRoot(); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric /// getChar - This is the mdnode for "char", which is special, and any types 1480b57cec5SDimitry Andric /// considered to be equivalent to it. 1490b57cec5SDimitry Andric llvm::MDNode *getChar(); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric /// CollectFields - Collect information about the fields of a type for 1520b57cec5SDimitry Andric /// !tbaa.struct metadata formation. Return false for an unsupported type. 1530b57cec5SDimitry Andric bool CollectFields(uint64_t BaseOffset, 1540b57cec5SDimitry Andric QualType Ty, 1550b57cec5SDimitry Andric SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, 1560b57cec5SDimitry Andric bool MayAlias); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// createScalarTypeNode - A wrapper function to create a metadata node 1590b57cec5SDimitry Andric /// describing a scalar type. 1600b57cec5SDimitry Andric llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, 1610b57cec5SDimitry Andric uint64_t Size); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric /// getTypeInfoHelper - An internal helper function to generate metadata used 1640b57cec5SDimitry Andric /// to describe accesses to objects of the given type. 1650b57cec5SDimitry Andric llvm::MDNode *getTypeInfoHelper(const Type *Ty); 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric /// getBaseTypeInfoHelper - An internal helper function to generate metadata 1680b57cec5SDimitry Andric /// used to describe accesses to objects of the given base type. 1690b57cec5SDimitry Andric llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); 1700b57cec5SDimitry Andric 171*0fca6ea1SDimitry Andric /// getValidBaseTypeInfo - Return metadata that describes the given base 172*0fca6ea1SDimitry Andric /// access type. The type must be suitable. 173*0fca6ea1SDimitry Andric llvm::MDNode *getValidBaseTypeInfo(QualType QTy); 174*0fca6ea1SDimitry Andric 1750b57cec5SDimitry Andric public: 176*0fca6ea1SDimitry Andric CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, 177*0fca6ea1SDimitry Andric const CodeGenOptions &CGO, const LangOptions &Features, 178*0fca6ea1SDimitry Andric MangleContext &MContext); 1790b57cec5SDimitry Andric ~CodeGenTBAA(); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric /// getTypeInfo - Get metadata used to describe accesses to objects of the 1820b57cec5SDimitry Andric /// given type. 1830b57cec5SDimitry Andric llvm::MDNode *getTypeInfo(QualType QTy); 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric /// getAccessInfo - Get TBAA information that describes an access to 1860b57cec5SDimitry Andric /// an object of the given type. 1870b57cec5SDimitry Andric TBAAAccessInfo getAccessInfo(QualType AccessType); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// getVTablePtrAccessInfo - Get the TBAA information that describes an 1900b57cec5SDimitry Andric /// access to a virtual table pointer. 1910b57cec5SDimitry Andric TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of 1940b57cec5SDimitry Andric /// the given type. 1950b57cec5SDimitry Andric llvm::MDNode *getTBAAStructInfo(QualType QTy); 1960b57cec5SDimitry Andric 197*0fca6ea1SDimitry Andric /// getBaseTypeInfo - Get metadata that describes the given base access 198*0fca6ea1SDimitry Andric /// type. Return null if the type is not suitable for use in TBAA access 199*0fca6ea1SDimitry Andric /// tags. 2000b57cec5SDimitry Andric llvm::MDNode *getBaseTypeInfo(QualType QTy); 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric /// getAccessTagInfo - Get TBAA tag for a given memory access. 2030b57cec5SDimitry Andric llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of 2060b57cec5SDimitry Andric /// type casts. 2070b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, 2080b57cec5SDimitry Andric TBAAAccessInfo TargetInfo); 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the 2110b57cec5SDimitry Andric /// purpose of conditional operator. 2120b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, 2130b57cec5SDimitry Andric TBAAAccessInfo InfoB); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the 2160b57cec5SDimitry Andric /// purpose of memory transfer calls. 2170b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, 2180b57cec5SDimitry Andric TBAAAccessInfo SrcInfo); 2190b57cec5SDimitry Andric }; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric } // end namespace CodeGen 2220b57cec5SDimitry Andric } // end namespace clang 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric namespace llvm { 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> { 2270b57cec5SDimitry Andric static clang::CodeGen::TBAAAccessInfo getEmptyKey() { 2280b57cec5SDimitry Andric unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey(); 2290b57cec5SDimitry Andric return clang::CodeGen::TBAAAccessInfo( 2300b57cec5SDimitry Andric static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), 2310b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getEmptyKey(), 2320b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getEmptyKey(), 2330b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getEmptyKey(), 2340b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getEmptyKey()); 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { 2380b57cec5SDimitry Andric unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey(); 2390b57cec5SDimitry Andric return clang::CodeGen::TBAAAccessInfo( 2400b57cec5SDimitry Andric static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), 2410b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getTombstoneKey(), 2420b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getTombstoneKey(), 2430b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getTombstoneKey(), 2440b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getTombstoneKey()); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { 2480b57cec5SDimitry Andric auto KindValue = static_cast<unsigned>(Val.Kind); 2490b57cec5SDimitry Andric return DenseMapInfo<unsigned>::getHashValue(KindValue) ^ 2500b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^ 2510b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^ 2520b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^ 2530b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getHashValue(Val.Size); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, 2570b57cec5SDimitry Andric const clang::CodeGen::TBAAAccessInfo &RHS) { 2580b57cec5SDimitry Andric return LHS == RHS; 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric }; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric } // end namespace llvm 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric #endif 265