xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/CodeGenTBAA.h (revision 5deeebd8c6ca991269e72902a7a62cada57947f6)
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