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