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 QualType; 280b57cec5SDimitry Andric class Type; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric namespace CodeGen { 310fca6ea1SDimitry Andric class CodeGenTypes; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric // TBAAAccessKind - A kind of TBAA memory access descriptor. 340b57cec5SDimitry Andric enum class TBAAAccessKind : unsigned { 350b57cec5SDimitry Andric Ordinary, 360b57cec5SDimitry Andric MayAlias, 370b57cec5SDimitry Andric Incomplete, 380b57cec5SDimitry Andric }; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric // TBAAAccessInfo - Describes a memory access in terms of TBAA. 410b57cec5SDimitry Andric struct TBAAAccessInfo { TBAAAccessInfoTBAAAccessInfo420b57cec5SDimitry Andric TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, 430b57cec5SDimitry Andric llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size) 440b57cec5SDimitry Andric : Kind(Kind), BaseType(BaseType), AccessType(AccessType), 450b57cec5SDimitry Andric Offset(Offset), Size(Size) 460b57cec5SDimitry Andric {} 470b57cec5SDimitry Andric TBAAAccessInfoTBAAAccessInfo480b57cec5SDimitry Andric TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, 490b57cec5SDimitry Andric uint64_t Offset, uint64_t Size) 500b57cec5SDimitry Andric : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, 510b57cec5SDimitry Andric Offset, Size) 520b57cec5SDimitry Andric {} 530b57cec5SDimitry Andric TBAAAccessInfoTBAAAccessInfo540b57cec5SDimitry Andric explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) 550b57cec5SDimitry Andric : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size) 560b57cec5SDimitry Andric {} 570b57cec5SDimitry Andric TBAAAccessInfoTBAAAccessInfo580b57cec5SDimitry Andric TBAAAccessInfo() 590b57cec5SDimitry Andric : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0) 600b57cec5SDimitry Andric {} 610b57cec5SDimitry Andric getMayAliasInfoTBAAAccessInfo620b57cec5SDimitry Andric static TBAAAccessInfo getMayAliasInfo() { 630b57cec5SDimitry Andric return TBAAAccessInfo(TBAAAccessKind::MayAlias, 640b57cec5SDimitry Andric /* BaseType= */ nullptr, /* AccessType= */ nullptr, 650b57cec5SDimitry Andric /* Offset= */ 0, /* Size= */ 0); 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric isMayAliasTBAAAccessInfo680b57cec5SDimitry Andric bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } 690b57cec5SDimitry Andric getIncompleteInfoTBAAAccessInfo700b57cec5SDimitry Andric static TBAAAccessInfo getIncompleteInfo() { 710b57cec5SDimitry Andric return TBAAAccessInfo(TBAAAccessKind::Incomplete, 720b57cec5SDimitry Andric /* BaseType= */ nullptr, /* AccessType= */ nullptr, 730b57cec5SDimitry Andric /* Offset= */ 0, /* Size= */ 0); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric isIncompleteTBAAAccessInfo760b57cec5SDimitry Andric bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric bool operator==(const TBAAAccessInfo &Other) const { 790b57cec5SDimitry Andric return Kind == Other.Kind && 800b57cec5SDimitry Andric BaseType == Other.BaseType && 810b57cec5SDimitry Andric AccessType == Other.AccessType && 820b57cec5SDimitry Andric Offset == Other.Offset && 830b57cec5SDimitry Andric Size == Other.Size; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric bool operator!=(const TBAAAccessInfo &Other) const { 870b57cec5SDimitry Andric return !(*this == Other); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric explicit operator bool() const { 910b57cec5SDimitry Andric return *this != TBAAAccessInfo(); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// Kind - The kind of the access descriptor. 950b57cec5SDimitry Andric TBAAAccessKind Kind; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric /// BaseType - The base/leading access type. May be null if this access 980b57cec5SDimitry Andric /// descriptor represents an access that is not considered to be an access 990b57cec5SDimitry Andric /// to an aggregate or union member. 1000b57cec5SDimitry Andric llvm::MDNode *BaseType; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric /// AccessType - The final access type. May be null if there is no TBAA 1030b57cec5SDimitry Andric /// information available about this access. 1040b57cec5SDimitry Andric llvm::MDNode *AccessType; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric /// Offset - The byte offset of the final access within the base one. Must be 1070b57cec5SDimitry Andric /// zero if the base access type is not specified. 1080b57cec5SDimitry Andric uint64_t Offset; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// Size - The size of access, in bytes. 1110b57cec5SDimitry Andric uint64_t Size; 1120b57cec5SDimitry Andric }; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric /// CodeGenTBAA - This class organizes the cross-module state that is used 1150b57cec5SDimitry Andric /// while lowering AST types to LLVM types. 1160b57cec5SDimitry Andric class CodeGenTBAA { 1170b57cec5SDimitry Andric ASTContext &Context; 1180fca6ea1SDimitry Andric CodeGenTypes &CGTypes; 1190b57cec5SDimitry Andric llvm::Module &Module; 1200b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts; 1210b57cec5SDimitry Andric const LangOptions &Features; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric // MDHelper - Helper for creating metadata. 1240b57cec5SDimitry Andric llvm::MDBuilder MDHelper; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing 1270b57cec5SDimitry Andric /// them. 1280b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; 1290b57cec5SDimitry Andric /// This maps clang::Types to a base access type in the type DAG. 1300b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache; 1310b57cec5SDimitry Andric /// This maps TBAA access descriptors to tag nodes. 1320b57cec5SDimitry Andric llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing 1350b57cec5SDimitry Andric /// them for struct assignments. 1360b57cec5SDimitry Andric llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache; 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric llvm::MDNode *Root; 1390b57cec5SDimitry Andric llvm::MDNode *Char; 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric /// getRoot - This is the mdnode for the root of the metadata type graph 1420b57cec5SDimitry Andric /// for this translation unit. 1430b57cec5SDimitry Andric llvm::MDNode *getRoot(); 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric /// getChar - This is the mdnode for "char", which is special, and any types 1460b57cec5SDimitry Andric /// considered to be equivalent to it. 1470b57cec5SDimitry Andric llvm::MDNode *getChar(); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /// CollectFields - Collect information about the fields of a type for 1500b57cec5SDimitry Andric /// !tbaa.struct metadata formation. Return false for an unsupported type. 1510b57cec5SDimitry Andric bool CollectFields(uint64_t BaseOffset, 1520b57cec5SDimitry Andric QualType Ty, 1530b57cec5SDimitry Andric SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, 1540b57cec5SDimitry Andric bool MayAlias); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric /// createScalarTypeNode - A wrapper function to create a metadata node 1570b57cec5SDimitry Andric /// describing a scalar type. 1580b57cec5SDimitry Andric llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, 1590b57cec5SDimitry Andric uint64_t Size); 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric /// getTypeInfoHelper - An internal helper function to generate metadata used 1620b57cec5SDimitry Andric /// to describe accesses to objects of the given type. 1630b57cec5SDimitry Andric llvm::MDNode *getTypeInfoHelper(const Type *Ty); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric /// getBaseTypeInfoHelper - An internal helper function to generate metadata 1660b57cec5SDimitry Andric /// used to describe accesses to objects of the given base type. 1670b57cec5SDimitry Andric llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); 1680b57cec5SDimitry Andric 1690fca6ea1SDimitry Andric /// getValidBaseTypeInfo - Return metadata that describes the given base 1700fca6ea1SDimitry Andric /// access type. The type must be suitable. 1710fca6ea1SDimitry Andric llvm::MDNode *getValidBaseTypeInfo(QualType QTy); 1720fca6ea1SDimitry Andric 1730b57cec5SDimitry Andric public: 1740fca6ea1SDimitry Andric CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, 175*5deeebd8SDimitry Andric const CodeGenOptions &CGO, const LangOptions &Features); 1760b57cec5SDimitry Andric ~CodeGenTBAA(); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric /// getTypeInfo - Get metadata used to describe accesses to objects of the 1790b57cec5SDimitry Andric /// given type. 1800b57cec5SDimitry Andric llvm::MDNode *getTypeInfo(QualType QTy); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric /// getAccessInfo - Get TBAA information that describes an access to 1830b57cec5SDimitry Andric /// an object of the given type. 1840b57cec5SDimitry Andric TBAAAccessInfo getAccessInfo(QualType AccessType); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric /// getVTablePtrAccessInfo - Get the TBAA information that describes an 1870b57cec5SDimitry Andric /// access to a virtual table pointer. 1880b57cec5SDimitry Andric TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of 1910b57cec5SDimitry Andric /// the given type. 1920b57cec5SDimitry Andric llvm::MDNode *getTBAAStructInfo(QualType QTy); 1930b57cec5SDimitry Andric 1940fca6ea1SDimitry Andric /// getBaseTypeInfo - Get metadata that describes the given base access 1950fca6ea1SDimitry Andric /// type. Return null if the type is not suitable for use in TBAA access 1960fca6ea1SDimitry Andric /// tags. 1970b57cec5SDimitry Andric llvm::MDNode *getBaseTypeInfo(QualType QTy); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// getAccessTagInfo - Get TBAA tag for a given memory access. 2000b57cec5SDimitry Andric llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of 2030b57cec5SDimitry Andric /// type casts. 2040b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, 2050b57cec5SDimitry Andric TBAAAccessInfo TargetInfo); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the 2080b57cec5SDimitry Andric /// purpose of conditional operator. 2090b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, 2100b57cec5SDimitry Andric TBAAAccessInfo InfoB); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the 2130b57cec5SDimitry Andric /// purpose of memory transfer calls. 2140b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, 2150b57cec5SDimitry Andric TBAAAccessInfo SrcInfo); 2160b57cec5SDimitry Andric }; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric } // end namespace CodeGen 2190b57cec5SDimitry Andric } // end namespace clang 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric namespace llvm { 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> { 2240b57cec5SDimitry Andric static clang::CodeGen::TBAAAccessInfo getEmptyKey() { 2250b57cec5SDimitry Andric unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey(); 2260b57cec5SDimitry Andric return clang::CodeGen::TBAAAccessInfo( 2270b57cec5SDimitry Andric static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), 2280b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getEmptyKey(), 2290b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getEmptyKey(), 2300b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getEmptyKey(), 2310b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getEmptyKey()); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { 2350b57cec5SDimitry Andric unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey(); 2360b57cec5SDimitry Andric return clang::CodeGen::TBAAAccessInfo( 2370b57cec5SDimitry Andric static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), 2380b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getTombstoneKey(), 2390b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getTombstoneKey(), 2400b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getTombstoneKey(), 2410b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getTombstoneKey()); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { 2450b57cec5SDimitry Andric auto KindValue = static_cast<unsigned>(Val.Kind); 2460b57cec5SDimitry Andric return DenseMapInfo<unsigned>::getHashValue(KindValue) ^ 2470b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^ 2480b57cec5SDimitry Andric DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^ 2490b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^ 2500b57cec5SDimitry Andric DenseMapInfo<uint64_t>::getHashValue(Val.Size); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, 2540b57cec5SDimitry Andric const clang::CodeGen::TBAAAccessInfo &RHS) { 2550b57cec5SDimitry Andric return LHS == RHS; 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric }; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric } // end namespace llvm 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric #endif 262