1*0b57cec5SDimitry Andric //===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This is the code that manages TBAA information and defines the TBAA policy 10*0b57cec5SDimitry Andric // for the optimizer to use. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H 15*0b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric #include "clang/AST/Type.h" 18*0b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 21*0b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric namespace clang { 24*0b57cec5SDimitry Andric class ASTContext; 25*0b57cec5SDimitry Andric class CodeGenOptions; 26*0b57cec5SDimitry Andric class LangOptions; 27*0b57cec5SDimitry Andric class MangleContext; 28*0b57cec5SDimitry Andric class QualType; 29*0b57cec5SDimitry Andric class Type; 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric namespace CodeGen { 32*0b57cec5SDimitry Andric class CGRecordLayout; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric // TBAAAccessKind - A kind of TBAA memory access descriptor. 35*0b57cec5SDimitry Andric enum class TBAAAccessKind : unsigned { 36*0b57cec5SDimitry Andric Ordinary, 37*0b57cec5SDimitry Andric MayAlias, 38*0b57cec5SDimitry Andric Incomplete, 39*0b57cec5SDimitry Andric }; 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric // TBAAAccessInfo - Describes a memory access in terms of TBAA. 42*0b57cec5SDimitry Andric struct TBAAAccessInfo { 43*0b57cec5SDimitry Andric TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, 44*0b57cec5SDimitry Andric llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size) 45*0b57cec5SDimitry Andric : Kind(Kind), BaseType(BaseType), AccessType(AccessType), 46*0b57cec5SDimitry Andric Offset(Offset), Size(Size) 47*0b57cec5SDimitry Andric {} 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, 50*0b57cec5SDimitry Andric uint64_t Offset, uint64_t Size) 51*0b57cec5SDimitry Andric : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, 52*0b57cec5SDimitry Andric Offset, Size) 53*0b57cec5SDimitry Andric {} 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) 56*0b57cec5SDimitry Andric : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size) 57*0b57cec5SDimitry Andric {} 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric TBAAAccessInfo() 60*0b57cec5SDimitry Andric : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0) 61*0b57cec5SDimitry Andric {} 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric static TBAAAccessInfo getMayAliasInfo() { 64*0b57cec5SDimitry Andric return TBAAAccessInfo(TBAAAccessKind::MayAlias, 65*0b57cec5SDimitry Andric /* BaseType= */ nullptr, /* AccessType= */ nullptr, 66*0b57cec5SDimitry Andric /* Offset= */ 0, /* Size= */ 0); 67*0b57cec5SDimitry Andric } 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric static TBAAAccessInfo getIncompleteInfo() { 72*0b57cec5SDimitry Andric return TBAAAccessInfo(TBAAAccessKind::Incomplete, 73*0b57cec5SDimitry Andric /* BaseType= */ nullptr, /* AccessType= */ nullptr, 74*0b57cec5SDimitry Andric /* Offset= */ 0, /* Size= */ 0); 75*0b57cec5SDimitry Andric } 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric bool operator==(const TBAAAccessInfo &Other) const { 80*0b57cec5SDimitry Andric return Kind == Other.Kind && 81*0b57cec5SDimitry Andric BaseType == Other.BaseType && 82*0b57cec5SDimitry Andric AccessType == Other.AccessType && 83*0b57cec5SDimitry Andric Offset == Other.Offset && 84*0b57cec5SDimitry Andric Size == Other.Size; 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric bool operator!=(const TBAAAccessInfo &Other) const { 88*0b57cec5SDimitry Andric return !(*this == Other); 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric explicit operator bool() const { 92*0b57cec5SDimitry Andric return *this != TBAAAccessInfo(); 93*0b57cec5SDimitry Andric } 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric /// Kind - The kind of the access descriptor. 96*0b57cec5SDimitry Andric TBAAAccessKind Kind; 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric /// BaseType - The base/leading access type. May be null if this access 99*0b57cec5SDimitry Andric /// descriptor represents an access that is not considered to be an access 100*0b57cec5SDimitry Andric /// to an aggregate or union member. 101*0b57cec5SDimitry Andric llvm::MDNode *BaseType; 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric /// AccessType - The final access type. May be null if there is no TBAA 104*0b57cec5SDimitry Andric /// information available about this access. 105*0b57cec5SDimitry Andric llvm::MDNode *AccessType; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric /// Offset - The byte offset of the final access within the base one. Must be 108*0b57cec5SDimitry Andric /// zero if the base access type is not specified. 109*0b57cec5SDimitry Andric uint64_t Offset; 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric /// Size - The size of access, in bytes. 112*0b57cec5SDimitry Andric uint64_t Size; 113*0b57cec5SDimitry Andric }; 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric /// CodeGenTBAA - This class organizes the cross-module state that is used 116*0b57cec5SDimitry Andric /// while lowering AST types to LLVM types. 117*0b57cec5SDimitry Andric class CodeGenTBAA { 118*0b57cec5SDimitry Andric ASTContext &Context; 119*0b57cec5SDimitry Andric llvm::Module &Module; 120*0b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts; 121*0b57cec5SDimitry Andric const LangOptions &Features; 122*0b57cec5SDimitry Andric MangleContext &MContext; 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric // MDHelper - Helper for creating metadata. 125*0b57cec5SDimitry Andric llvm::MDBuilder MDHelper; 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing 128*0b57cec5SDimitry Andric /// them. 129*0b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; 130*0b57cec5SDimitry Andric /// This maps clang::Types to a base access type in the type DAG. 131*0b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache; 132*0b57cec5SDimitry Andric /// This maps TBAA access descriptors to tag nodes. 133*0b57cec5SDimitry Andric llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache; 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing 136*0b57cec5SDimitry Andric /// them for struct assignments. 137*0b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache; 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric llvm::MDNode *Root; 140*0b57cec5SDimitry Andric llvm::MDNode *Char; 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric /// getRoot - This is the mdnode for the root of the metadata type graph 143*0b57cec5SDimitry Andric /// for this translation unit. 144*0b57cec5SDimitry Andric llvm::MDNode *getRoot(); 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric /// getChar - This is the mdnode for "char", which is special, and any types 147*0b57cec5SDimitry Andric /// considered to be equivalent to it. 148*0b57cec5SDimitry Andric llvm::MDNode *getChar(); 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric /// CollectFields - Collect information about the fields of a type for 151*0b57cec5SDimitry Andric /// !tbaa.struct metadata formation. Return false for an unsupported type. 152*0b57cec5SDimitry Andric bool CollectFields(uint64_t BaseOffset, 153*0b57cec5SDimitry Andric QualType Ty, 154*0b57cec5SDimitry Andric SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, 155*0b57cec5SDimitry Andric bool MayAlias); 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric /// createScalarTypeNode - A wrapper function to create a metadata node 158*0b57cec5SDimitry Andric /// describing a scalar type. 159*0b57cec5SDimitry Andric llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, 160*0b57cec5SDimitry Andric uint64_t Size); 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric /// getTypeInfoHelper - An internal helper function to generate metadata used 163*0b57cec5SDimitry Andric /// to describe accesses to objects of the given type. 164*0b57cec5SDimitry Andric llvm::MDNode *getTypeInfoHelper(const Type *Ty); 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric /// getBaseTypeInfoHelper - An internal helper function to generate metadata 167*0b57cec5SDimitry Andric /// used to describe accesses to objects of the given base type. 168*0b57cec5SDimitry Andric llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric public: 171*0b57cec5SDimitry Andric CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, 172*0b57cec5SDimitry Andric const LangOptions &Features, MangleContext &MContext); 173*0b57cec5SDimitry Andric ~CodeGenTBAA(); 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric /// getTypeInfo - Get metadata used to describe accesses to objects of the 176*0b57cec5SDimitry Andric /// given type. 177*0b57cec5SDimitry Andric llvm::MDNode *getTypeInfo(QualType QTy); 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric /// getAccessInfo - Get TBAA information that describes an access to 180*0b57cec5SDimitry Andric /// an object of the given type. 181*0b57cec5SDimitry Andric TBAAAccessInfo getAccessInfo(QualType AccessType); 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric /// getVTablePtrAccessInfo - Get the TBAA information that describes an 184*0b57cec5SDimitry Andric /// access to a virtual table pointer. 185*0b57cec5SDimitry Andric TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of 188*0b57cec5SDimitry Andric /// the given type. 189*0b57cec5SDimitry Andric llvm::MDNode *getTBAAStructInfo(QualType QTy); 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric /// getBaseTypeInfo - Get metadata that describes the given base access type. 192*0b57cec5SDimitry Andric /// Return null if the type is not suitable for use in TBAA access tags. 193*0b57cec5SDimitry Andric llvm::MDNode *getBaseTypeInfo(QualType QTy); 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric /// getAccessTagInfo - Get TBAA tag for a given memory access. 196*0b57cec5SDimitry Andric llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of 199*0b57cec5SDimitry Andric /// type casts. 200*0b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, 201*0b57cec5SDimitry Andric TBAAAccessInfo TargetInfo); 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the 204*0b57cec5SDimitry Andric /// purpose of conditional operator. 205*0b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, 206*0b57cec5SDimitry Andric TBAAAccessInfo InfoB); 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the 209*0b57cec5SDimitry Andric /// purpose of memory transfer calls. 210*0b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, 211*0b57cec5SDimitry Andric TBAAAccessInfo SrcInfo); 212*0b57cec5SDimitry Andric }; 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andric } // end namespace CodeGen 215*0b57cec5SDimitry Andric } // end namespace clang 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric namespace llvm { 218*0b57cec5SDimitry Andric 219*0b57cec5SDimitry Andric template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> { 220*0b57cec5SDimitry Andric static clang::CodeGen::TBAAAccessInfo getEmptyKey() { 221*0b57cec5SDimitry Andric unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey(); 222*0b57cec5SDimitry Andric return clang::CodeGen::TBAAAccessInfo( 223*0b57cec5SDimitry Andric static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), 224*0b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getEmptyKey(), 225*0b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getEmptyKey(), 226*0b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getEmptyKey(), 227*0b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getEmptyKey()); 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { 231*0b57cec5SDimitry Andric unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey(); 232*0b57cec5SDimitry Andric return clang::CodeGen::TBAAAccessInfo( 233*0b57cec5SDimitry Andric static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), 234*0b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getTombstoneKey(), 235*0b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getTombstoneKey(), 236*0b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getTombstoneKey(), 237*0b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getTombstoneKey()); 238*0b57cec5SDimitry Andric } 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { 241*0b57cec5SDimitry Andric auto KindValue = static_cast<unsigned>(Val.Kind); 242*0b57cec5SDimitry Andric return DenseMapInfo<unsigned>::getHashValue(KindValue) ^ 243*0b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^ 244*0b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^ 245*0b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^ 246*0b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getHashValue(Val.Size); 247*0b57cec5SDimitry Andric } 248*0b57cec5SDimitry Andric 249*0b57cec5SDimitry Andric static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, 250*0b57cec5SDimitry Andric const clang::CodeGen::TBAAAccessInfo &RHS) { 251*0b57cec5SDimitry Andric return LHS == RHS; 252*0b57cec5SDimitry Andric } 253*0b57cec5SDimitry Andric }; 254*0b57cec5SDimitry Andric 255*0b57cec5SDimitry Andric } // end namespace llvm 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric #endif 258