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