1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H |
15 | #define LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H |
16 | |
17 | #include "clang/AST/Type.h" |
18 | #include "clang/Basic/LLVM.h" |
19 | #include "llvm/ADT/DenseMap.h" |
20 | #include "llvm/IR/MDBuilder.h" |
21 | #include "llvm/IR/Metadata.h" |
22 | |
23 | namespace clang { |
24 | class ASTContext; |
25 | class CodeGenOptions; |
26 | class LangOptions; |
27 | class MangleContext; |
28 | class QualType; |
29 | class Type; |
30 | |
31 | namespace CodeGen { |
32 | class CGRecordLayout; |
33 | |
34 | |
35 | enum class TBAAAccessKind : unsigned { |
36 | Ordinary, |
37 | MayAlias, |
38 | Incomplete, |
39 | }; |
40 | |
41 | |
42 | struct TBAAAccessInfo { |
43 | TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, |
44 | llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size) |
45 | : Kind(Kind), BaseType(BaseType), AccessType(AccessType), |
46 | Offset(Offset), Size(Size) |
47 | {} |
48 | |
49 | TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, |
50 | uint64_t Offset, uint64_t Size) |
51 | : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, |
52 | Offset, Size) |
53 | {} |
54 | |
55 | explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size) |
56 | : TBAAAccessInfo( nullptr, AccessType, 0, Size) |
57 | {} |
58 | |
59 | TBAAAccessInfo() |
60 | : TBAAAccessInfo( nullptr, 0) |
61 | {} |
62 | |
63 | static TBAAAccessInfo getMayAliasInfo() { |
64 | return TBAAAccessInfo(TBAAAccessKind::MayAlias, |
65 | nullptr, nullptr, |
66 | 0, 0); |
67 | } |
68 | |
69 | bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } |
70 | |
71 | static TBAAAccessInfo getIncompleteInfo() { |
72 | return TBAAAccessInfo(TBAAAccessKind::Incomplete, |
73 | nullptr, nullptr, |
74 | 0, 0); |
75 | } |
76 | |
77 | bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; } |
78 | |
79 | bool operator==(const TBAAAccessInfo &Other) const { |
80 | return Kind == Other.Kind && |
81 | BaseType == Other.BaseType && |
82 | AccessType == Other.AccessType && |
83 | Offset == Other.Offset && |
84 | Size == Other.Size; |
85 | } |
86 | |
87 | bool operator!=(const TBAAAccessInfo &Other) const { |
88 | return !(*this == Other); |
89 | } |
90 | |
91 | explicit operator bool() const { |
92 | return *this != TBAAAccessInfo(); |
93 | } |
94 | |
95 | |
96 | TBAAAccessKind Kind; |
97 | |
98 | |
99 | |
100 | |
101 | llvm::MDNode *BaseType; |
102 | |
103 | |
104 | |
105 | llvm::MDNode *AccessType; |
106 | |
107 | |
108 | |
109 | uint64_t Offset; |
110 | |
111 | |
112 | uint64_t Size; |
113 | }; |
114 | |
115 | |
116 | |
117 | class CodeGenTBAA { |
118 | ASTContext &Context; |
119 | llvm::Module &Module; |
120 | const CodeGenOptions &CodeGenOpts; |
121 | const LangOptions &Features; |
122 | MangleContext &MContext; |
123 | |
124 | |
125 | llvm::MDBuilder MDHelper; |
126 | |
127 | |
128 | |
129 | llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; |
130 | |
131 | llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache; |
132 | |
133 | llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache; |
134 | |
135 | |
136 | |
137 | llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache; |
138 | |
139 | llvm::MDNode *Root; |
140 | llvm::MDNode *Char; |
141 | |
142 | |
143 | |
144 | llvm::MDNode *getRoot(); |
145 | |
146 | |
147 | |
148 | llvm::MDNode *getChar(); |
149 | |
150 | |
151 | |
152 | bool CollectFields(uint64_t BaseOffset, |
153 | QualType Ty, |
154 | SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, |
155 | bool MayAlias); |
156 | |
157 | |
158 | |
159 | llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent, |
160 | uint64_t Size); |
161 | |
162 | |
163 | |
164 | llvm::MDNode *getTypeInfoHelper(const Type *Ty); |
165 | |
166 | |
167 | |
168 | llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty); |
169 | |
170 | public: |
171 | CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO, |
172 | const LangOptions &Features, MangleContext &MContext); |
173 | ~CodeGenTBAA(); |
174 | |
175 | |
176 | |
177 | llvm::MDNode *getTypeInfo(QualType QTy); |
178 | |
179 | |
180 | |
181 | TBAAAccessInfo getAccessInfo(QualType AccessType); |
182 | |
183 | |
184 | |
185 | TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType); |
186 | |
187 | |
188 | |
189 | llvm::MDNode *getTBAAStructInfo(QualType QTy); |
190 | |
191 | |
192 | |
193 | llvm::MDNode *getBaseTypeInfo(QualType QTy); |
194 | |
195 | |
196 | llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); |
197 | |
198 | |
199 | |
200 | TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, |
201 | TBAAAccessInfo TargetInfo); |
202 | |
203 | |
204 | |
205 | TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, |
206 | TBAAAccessInfo InfoB); |
207 | |
208 | |
209 | |
210 | TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, |
211 | TBAAAccessInfo SrcInfo); |
212 | }; |
213 | |
214 | } |
215 | } |
216 | |
217 | namespace llvm { |
218 | |
219 | template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> { |
220 | static clang::CodeGen::TBAAAccessInfo getEmptyKey() { |
221 | unsigned UnsignedKey = DenseMapInfo<unsigned>::getEmptyKey(); |
222 | return clang::CodeGen::TBAAAccessInfo( |
223 | static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), |
224 | DenseMapInfo<MDNode *>::getEmptyKey(), |
225 | DenseMapInfo<MDNode *>::getEmptyKey(), |
226 | DenseMapInfo<uint64_t>::getEmptyKey(), |
227 | DenseMapInfo<uint64_t>::getEmptyKey()); |
228 | } |
229 | |
230 | static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { |
231 | unsigned UnsignedKey = DenseMapInfo<unsigned>::getTombstoneKey(); |
232 | return clang::CodeGen::TBAAAccessInfo( |
233 | static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey), |
234 | DenseMapInfo<MDNode *>::getTombstoneKey(), |
235 | DenseMapInfo<MDNode *>::getTombstoneKey(), |
236 | DenseMapInfo<uint64_t>::getTombstoneKey(), |
237 | DenseMapInfo<uint64_t>::getTombstoneKey()); |
238 | } |
239 | |
240 | static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { |
241 | auto KindValue = static_cast<unsigned>(Val.Kind); |
242 | return DenseMapInfo<unsigned>::getHashValue(KindValue) ^ |
243 | DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^ |
244 | DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^ |
245 | DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^ |
246 | DenseMapInfo<uint64_t>::getHashValue(Val.Size); |
247 | } |
248 | |
249 | static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, |
250 | const clang::CodeGen::TBAAAccessInfo &RHS) { |
251 | return LHS == RHS; |
252 | } |
253 | }; |
254 | |
255 | } |
256 | |
257 | #endif |
258 | |