xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CodeGenTBAA.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
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