|  | //===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- C++ -*-===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This is the code that manages TBAA information and defines the TBAA policy | 
|  | // for the optimizer to use. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H | 
|  | #define LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H | 
|  |  | 
|  | #include "clang/AST/Type.h" | 
|  | #include "clang/Basic/LLVM.h" | 
|  | #include "llvm/ADT/DenseMap.h" | 
|  | #include "llvm/IR/MDBuilder.h" | 
|  | #include "llvm/IR/Metadata.h" | 
|  |  | 
|  | namespace clang { | 
|  | class ASTContext; | 
|  | class CodeGenOptions; | 
|  | class LangOptions; | 
|  | class MangleContext; | 
|  | class QualType; | 
|  | class Type; | 
|  |  | 
|  | namespace CodeGen { | 
|  | class CGRecordLayout; | 
|  |  | 
|  | // TBAAAccessKind - A kind of TBAA memory access descriptor. | 
|  | 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, uint64_t Size) | 
|  | : Kind(Kind), BaseType(BaseType), AccessType(AccessType), | 
|  | Offset(Offset), Size(Size) | 
|  | {} | 
|  |  | 
|  | TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, | 
|  | uint64_t Offset, uint64_t Size) | 
|  | : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, | 
|  | Offset, Size) | 
|  | {} | 
|  |  | 
|  | explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) | 
|  | : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size) | 
|  | {} | 
|  |  | 
|  | TBAAAccessInfo() | 
|  | : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0) | 
|  | {} | 
|  |  | 
|  | static TBAAAccessInfo getMayAliasInfo() { | 
|  | 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 && | 
|  | Size == Other.Size; | 
|  | } | 
|  |  | 
|  | bool operator!=(const TBAAAccessInfo &Other) const { | 
|  | return !(*this == Other); | 
|  | } | 
|  |  | 
|  | explicit operator bool() const { | 
|  | return *this != TBAAAccessInfo(); | 
|  | } | 
|  |  | 
|  | /// Kind - The kind of the access descriptor. | 
|  | TBAAAccessKind Kind; | 
|  |  | 
|  | /// BaseType - The base/leading access type. May be null if this access | 
|  | /// descriptor represents an access that is not considered to be an access | 
|  | /// to an aggregate or union member. | 
|  | llvm::MDNode *BaseType; | 
|  |  | 
|  | /// AccessType - The final access type. May be null if there is no TBAA | 
|  | /// information available about this access. | 
|  | llvm::MDNode *AccessType; | 
|  |  | 
|  | /// 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; | 
|  |  | 
|  | // MDHelper - Helper for creating metadata. | 
|  | llvm::MDBuilder MDHelper; | 
|  |  | 
|  | /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing | 
|  | /// them. | 
|  | llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; | 
|  | /// This maps clang::Types to a base access type in the type DAG. | 
|  | llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache; | 
|  | /// This maps TBAA access descriptors to tag nodes. | 
|  | llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache; | 
|  |  | 
|  | /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing | 
|  | /// them for struct assignments. | 
|  | llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache; | 
|  |  | 
|  | llvm::MDNode *Root; | 
|  | llvm::MDNode *Char; | 
|  |  | 
|  | /// getRoot - This is the mdnode for the root of the metadata type graph | 
|  | /// for this translation unit. | 
|  | llvm::MDNode *getRoot(); | 
|  |  | 
|  | /// getChar - This is the mdnode for "char", which is special, and any types | 
|  | /// considered to be equivalent to it. | 
|  | llvm::MDNode *getChar(); | 
|  |  | 
|  | /// CollectFields - Collect information about the fields of a type for | 
|  | /// !tbaa.struct metadata formation. Return false for an unsupported type. | 
|  | bool CollectFields(uint64_t BaseOffset, | 
|  | QualType Ty, | 
|  | SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, | 
|  | bool MayAlias); | 
|  |  | 
|  | /// createScalarTypeNode - A wrapper function to create a metadata node | 
|  | /// describing a scalar type. | 
|  | llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, | 
|  | uint64_t Size); | 
|  |  | 
|  | /// getTypeInfoHelper - An internal helper function to generate metadata used | 
|  | /// to describe accesses to objects of the given type. | 
|  | llvm::MDNode *getTypeInfoHelper(const Type *Ty); | 
|  |  | 
|  | /// getBaseTypeInfoHelper - An internal helper function to generate metadata | 
|  | /// used to describe accesses to objects of the given base type. | 
|  | llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); | 
|  |  | 
|  | public: | 
|  | 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); | 
|  |  | 
|  | /// getAccessInfo - Get TBAA information that describes an access to | 
|  | /// an object of the given type. | 
|  | TBAAAccessInfo getAccessInfo(QualType AccessType); | 
|  |  | 
|  | /// getVTablePtrAccessInfo - Get the TBAA information that describes an | 
|  | /// access to a virtual table pointer. | 
|  | TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); | 
|  |  | 
|  | /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of | 
|  | /// the given type. | 
|  | llvm::MDNode *getTBAAStructInfo(QualType QTy); | 
|  |  | 
|  | /// getBaseTypeInfo - Get metadata that describes the given base access type. | 
|  | /// Return null if the type is not suitable for use in TBAA access tags. | 
|  | llvm::MDNode *getBaseTypeInfo(QualType QTy); | 
|  |  | 
|  | /// getAccessTagInfo - Get TBAA tag for a given memory access. | 
|  | llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); | 
|  |  | 
|  | /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of | 
|  | /// type casts. | 
|  | TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, | 
|  | TBAAAccessInfo TargetInfo); | 
|  |  | 
|  | /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the | 
|  | /// purpose of conditional operator. | 
|  | TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, | 
|  | TBAAAccessInfo InfoB); | 
|  |  | 
|  | /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the | 
|  | /// purpose of memory transfer calls. | 
|  | TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, | 
|  | TBAAAccessInfo SrcInfo); | 
|  | }; | 
|  |  | 
|  | }  // end namespace CodeGen | 
|  | }  // end namespace clang | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> { | 
|  | static clang::CodeGen::TBAAAccessInfo getEmptyKey() { | 
|  | unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey(); | 
|  | return clang::CodeGen::TBAAAccessInfo( | 
|  | static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), | 
|  | DenseMapInfo<MDNode *>::getEmptyKey(), | 
|  | DenseMapInfo<MDNode *>::getEmptyKey(), | 
|  | DenseMapInfo<uint64_t>::getEmptyKey(), | 
|  | DenseMapInfo<uint64_t>::getEmptyKey()); | 
|  | } | 
|  |  | 
|  | static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { | 
|  | unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey(); | 
|  | return clang::CodeGen::TBAAAccessInfo( | 
|  | 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.Size); | 
|  | } | 
|  |  | 
|  | static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, | 
|  | const clang::CodeGen::TBAAAccessInfo &RHS) { | 
|  | return LHS == RHS; | 
|  | } | 
|  | }; | 
|  |  | 
|  | }  // end namespace llvm | 
|  |  | 
|  | #endif |