1 | //===-- CodeGenTBAA.cpp - TBAA information for LLVM CodeGen ---------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This is the code that manages TBAA information and defines the TBAA policy |
10 | // for the optimizer to use. Relevant standards text includes: |
11 | // |
12 | // C99 6.5p7 |
13 | // C++ [basic.lval] (p10 in n3126, p15 in some earlier versions) |
14 | // |
15 | //===----------------------------------------------------------------------===// |
16 | |
17 | #include "CodeGenTBAA.h" |
18 | #include "CGRecordLayout.h" |
19 | #include "CodeGenTypes.h" |
20 | #include "clang/AST/ASTContext.h" |
21 | #include "clang/AST/Attr.h" |
22 | #include "clang/AST/Mangle.h" |
23 | #include "clang/AST/RecordLayout.h" |
24 | #include "clang/Basic/CodeGenOptions.h" |
25 | #include "clang/Basic/TargetInfo.h" |
26 | #include "llvm/ADT/SmallSet.h" |
27 | #include "llvm/IR/Constants.h" |
28 | #include "llvm/IR/LLVMContext.h" |
29 | #include "llvm/IR/Metadata.h" |
30 | #include "llvm/IR/Module.h" |
31 | #include "llvm/IR/Type.h" |
32 | #include "llvm/Support/Debug.h" |
33 | using namespace clang; |
34 | using namespace CodeGen; |
35 | |
36 | CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, |
37 | llvm::Module &M, const CodeGenOptions &CGO, |
38 | const LangOptions &Features, MangleContext &MContext) |
39 | : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO), |
40 | Features(Features), MContext(MContext), MDHelper(M.getContext()), |
41 | Root(nullptr), Char(nullptr) {} |
42 | |
43 | CodeGenTBAA::~CodeGenTBAA() { |
44 | } |
45 | |
46 | llvm::MDNode *CodeGenTBAA::getRoot() { |
47 | // Define the root of the tree. This identifies the tree, so that |
48 | // if our LLVM IR is linked with LLVM IR from a different front-end |
49 | // (or a different version of this front-end), their TBAA trees will |
50 | // remain distinct, and the optimizer will treat them conservatively. |
51 | if (!Root) { |
52 | if (Features.CPlusPlus) |
53 | Root = MDHelper.createTBAARoot(Name: "Simple C++ TBAA" ); |
54 | else |
55 | Root = MDHelper.createTBAARoot(Name: "Simple C/C++ TBAA" ); |
56 | } |
57 | |
58 | return Root; |
59 | } |
60 | |
61 | llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name, |
62 | llvm::MDNode *Parent, |
63 | uint64_t Size) { |
64 | if (CodeGenOpts.NewStructPathTBAA) { |
65 | llvm::Metadata *Id = MDHelper.createString(Str: Name); |
66 | return MDHelper.createTBAATypeNode(Parent, Size, Id); |
67 | } |
68 | return MDHelper.createTBAAScalarTypeNode(Name, Parent); |
69 | } |
70 | |
71 | llvm::MDNode *CodeGenTBAA::getChar() { |
72 | // Define the root of the tree for user-accessible memory. C and C++ |
73 | // give special powers to char and certain similar types. However, |
74 | // these special powers only cover user-accessible memory, and doesn't |
75 | // include things like vtables. |
76 | if (!Char) |
77 | Char = createScalarTypeNode(Name: "omnipotent char" , Parent: getRoot(), /* Size= */ 1); |
78 | |
79 | return Char; |
80 | } |
81 | |
82 | static bool TypeHasMayAlias(QualType QTy) { |
83 | // Tagged types have declarations, and therefore may have attributes. |
84 | if (auto *TD = QTy->getAsTagDecl()) |
85 | if (TD->hasAttr<MayAliasAttr>()) |
86 | return true; |
87 | |
88 | // Also look for may_alias as a declaration attribute on a typedef. |
89 | // FIXME: We should follow GCC and model may_alias as a type attribute |
90 | // rather than as a declaration attribute. |
91 | while (auto *TT = QTy->getAs<TypedefType>()) { |
92 | if (TT->getDecl()->hasAttr<MayAliasAttr>()) |
93 | return true; |
94 | QTy = TT->desugar(); |
95 | } |
96 | return false; |
97 | } |
98 | |
99 | /// Check if the given type is a valid base type to be used in access tags. |
100 | static bool isValidBaseType(QualType QTy) { |
101 | if (const RecordType *TTy = QTy->getAs<RecordType>()) { |
102 | const RecordDecl *RD = TTy->getDecl()->getDefinition(); |
103 | // Incomplete types are not valid base access types. |
104 | if (!RD) |
105 | return false; |
106 | if (RD->hasFlexibleArrayMember()) |
107 | return false; |
108 | // RD can be struct, union, class, interface or enum. |
109 | // For now, we only handle struct and class. |
110 | if (RD->isStruct() || RD->isClass()) |
111 | return true; |
112 | } |
113 | return false; |
114 | } |
115 | |
116 | llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { |
117 | uint64_t Size = Context.getTypeSizeInChars(T: Ty).getQuantity(); |
118 | |
119 | // Handle builtin types. |
120 | if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Val: Ty)) { |
121 | switch (BTy->getKind()) { |
122 | // Character types are special and can alias anything. |
123 | // In C++, this technically only includes "char" and "unsigned char", |
124 | // and not "signed char". In C, it includes all three. For now, |
125 | // the risk of exploiting this detail in C++ seems likely to outweigh |
126 | // the benefit. |
127 | case BuiltinType::Char_U: |
128 | case BuiltinType::Char_S: |
129 | case BuiltinType::UChar: |
130 | case BuiltinType::SChar: |
131 | return getChar(); |
132 | |
133 | // Unsigned types can alias their corresponding signed types. |
134 | case BuiltinType::UShort: |
135 | return getTypeInfo(QTy: Context.ShortTy); |
136 | case BuiltinType::UInt: |
137 | return getTypeInfo(QTy: Context.IntTy); |
138 | case BuiltinType::ULong: |
139 | return getTypeInfo(QTy: Context.LongTy); |
140 | case BuiltinType::ULongLong: |
141 | return getTypeInfo(QTy: Context.LongLongTy); |
142 | case BuiltinType::UInt128: |
143 | return getTypeInfo(QTy: Context.Int128Ty); |
144 | |
145 | case BuiltinType::UShortFract: |
146 | return getTypeInfo(QTy: Context.ShortFractTy); |
147 | case BuiltinType::UFract: |
148 | return getTypeInfo(QTy: Context.FractTy); |
149 | case BuiltinType::ULongFract: |
150 | return getTypeInfo(QTy: Context.LongFractTy); |
151 | |
152 | case BuiltinType::SatUShortFract: |
153 | return getTypeInfo(QTy: Context.SatShortFractTy); |
154 | case BuiltinType::SatUFract: |
155 | return getTypeInfo(QTy: Context.SatFractTy); |
156 | case BuiltinType::SatULongFract: |
157 | return getTypeInfo(QTy: Context.SatLongFractTy); |
158 | |
159 | case BuiltinType::UShortAccum: |
160 | return getTypeInfo(QTy: Context.ShortAccumTy); |
161 | case BuiltinType::UAccum: |
162 | return getTypeInfo(QTy: Context.AccumTy); |
163 | case BuiltinType::ULongAccum: |
164 | return getTypeInfo(QTy: Context.LongAccumTy); |
165 | |
166 | case BuiltinType::SatUShortAccum: |
167 | return getTypeInfo(QTy: Context.SatShortAccumTy); |
168 | case BuiltinType::SatUAccum: |
169 | return getTypeInfo(QTy: Context.SatAccumTy); |
170 | case BuiltinType::SatULongAccum: |
171 | return getTypeInfo(QTy: Context.SatLongAccumTy); |
172 | |
173 | // Treat all other builtin types as distinct types. This includes |
174 | // treating wchar_t, char16_t, and char32_t as distinct from their |
175 | // "underlying types". |
176 | default: |
177 | return createScalarTypeNode(Name: BTy->getName(Policy: Features), Parent: getChar(), Size); |
178 | } |
179 | } |
180 | |
181 | // C++1z [basic.lval]p10: "If a program attempts to access the stored value of |
182 | // an object through a glvalue of other than one of the following types the |
183 | // behavior is undefined: [...] a char, unsigned char, or std::byte type." |
184 | if (Ty->isStdByteType()) |
185 | return getChar(); |
186 | |
187 | // Handle pointers and references. |
188 | // TODO: Implement C++'s type "similarity" and consider dis-"similar" |
189 | // pointers distinct. |
190 | if (Ty->isPointerType() || Ty->isReferenceType()) |
191 | return createScalarTypeNode(Name: "any pointer" , Parent: getChar(), Size); |
192 | |
193 | // Accesses to arrays are accesses to objects of their element types. |
194 | if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType()) |
195 | return getTypeInfo(QTy: cast<ArrayType>(Val: Ty)->getElementType()); |
196 | |
197 | // Enum types are distinct types. In C++ they have "underlying types", |
198 | // however they aren't related for TBAA. |
199 | if (const EnumType *ETy = dyn_cast<EnumType>(Val: Ty)) { |
200 | if (!Features.CPlusPlus) |
201 | return getTypeInfo(QTy: ETy->getDecl()->getIntegerType()); |
202 | |
203 | // In C++ mode, types have linkage, so we can rely on the ODR and |
204 | // on their mangled names, if they're external. |
205 | // TODO: Is there a way to get a program-wide unique name for a |
206 | // decl with local linkage or no linkage? |
207 | if (!ETy->getDecl()->isExternallyVisible()) |
208 | return getChar(); |
209 | |
210 | SmallString<256> OutName; |
211 | llvm::raw_svector_ostream Out(OutName); |
212 | MContext.mangleCanonicalTypeName(T: QualType(ETy, 0), Out); |
213 | return createScalarTypeNode(Name: OutName, Parent: getChar(), Size); |
214 | } |
215 | |
216 | if (const auto *EIT = dyn_cast<BitIntType>(Val: Ty)) { |
217 | SmallString<256> OutName; |
218 | llvm::raw_svector_ostream Out(OutName); |
219 | // Don't specify signed/unsigned since integer types can alias despite sign |
220 | // differences. |
221 | Out << "_BitInt(" << EIT->getNumBits() << ')'; |
222 | return createScalarTypeNode(Name: OutName, Parent: getChar(), Size); |
223 | } |
224 | |
225 | // For now, handle any other kind of type conservatively. |
226 | return getChar(); |
227 | } |
228 | |
229 | llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { |
230 | // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. |
231 | if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) |
232 | return nullptr; |
233 | |
234 | // If the type has the may_alias attribute (even on a typedef), it is |
235 | // effectively in the general char alias class. |
236 | if (TypeHasMayAlias(QTy)) |
237 | return getChar(); |
238 | |
239 | // We need this function to not fall back to returning the "omnipotent char" |
240 | // type node for aggregate and union types. Otherwise, any dereference of an |
241 | // aggregate will result into the may-alias access descriptor, meaning all |
242 | // subsequent accesses to direct and indirect members of that aggregate will |
243 | // be considered may-alias too. |
244 | // TODO: Combine getTypeInfo() and getValidBaseTypeInfo() into a single |
245 | // function. |
246 | if (isValidBaseType(QTy)) |
247 | return getValidBaseTypeInfo(QTy); |
248 | |
249 | const Type *Ty = Context.getCanonicalType(T: QTy).getTypePtr(); |
250 | if (llvm::MDNode *N = MetadataCache[Ty]) |
251 | return N; |
252 | |
253 | // Note that the following helper call is allowed to add new nodes to the |
254 | // cache, which invalidates all its previously obtained iterators. So we |
255 | // first generate the node for the type and then add that node to the cache. |
256 | llvm::MDNode *TypeNode = getTypeInfoHelper(Ty); |
257 | return MetadataCache[Ty] = TypeNode; |
258 | } |
259 | |
260 | TBAAAccessInfo CodeGenTBAA::getAccessInfo(QualType AccessType) { |
261 | // Pointee values may have incomplete types, but they shall never be |
262 | // dereferenced. |
263 | if (AccessType->isIncompleteType()) |
264 | return TBAAAccessInfo::getIncompleteInfo(); |
265 | |
266 | if (TypeHasMayAlias(QTy: AccessType)) |
267 | return TBAAAccessInfo::getMayAliasInfo(); |
268 | |
269 | uint64_t Size = Context.getTypeSizeInChars(T: AccessType).getQuantity(); |
270 | return TBAAAccessInfo(getTypeInfo(QTy: AccessType), Size); |
271 | } |
272 | |
273 | TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) { |
274 | llvm::DataLayout DL(&Module); |
275 | unsigned Size = DL.getPointerTypeSize(Ty: VTablePtrType); |
276 | return TBAAAccessInfo(createScalarTypeNode(Name: "vtable pointer" , Parent: getRoot(), Size), |
277 | Size); |
278 | } |
279 | |
280 | bool |
281 | CodeGenTBAA::CollectFields(uint64_t BaseOffset, |
282 | QualType QTy, |
283 | SmallVectorImpl<llvm::MDBuilder::TBAAStructField> & |
284 | Fields, |
285 | bool MayAlias) { |
286 | /* Things not handled yet include: C++ base classes, bitfields, */ |
287 | |
288 | if (const RecordType *TTy = QTy->getAs<RecordType>()) { |
289 | if (TTy->isUnionType()) { |
290 | uint64_t Size = Context.getTypeSizeInChars(T: QTy).getQuantity(); |
291 | llvm::MDNode *TBAAType = getChar(); |
292 | llvm::MDNode *TBAATag = getAccessTagInfo(Info: TBAAAccessInfo(TBAAType, Size)); |
293 | Fields.push_back( |
294 | Elt: llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag)); |
295 | return true; |
296 | } |
297 | const RecordDecl *RD = TTy->getDecl()->getDefinition(); |
298 | if (RD->hasFlexibleArrayMember()) |
299 | return false; |
300 | |
301 | // TODO: Handle C++ base classes. |
302 | if (const CXXRecordDecl *Decl = dyn_cast<CXXRecordDecl>(Val: RD)) |
303 | if (Decl->bases_begin() != Decl->bases_end()) |
304 | return false; |
305 | |
306 | const ASTRecordLayout &Layout = Context.getASTRecordLayout(D: RD); |
307 | const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD); |
308 | |
309 | unsigned idx = 0; |
310 | for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); |
311 | i != e; ++i, ++idx) { |
312 | if ((*i)->isZeroSize(Ctx: Context)) |
313 | continue; |
314 | |
315 | uint64_t Offset = |
316 | BaseOffset + Layout.getFieldOffset(FieldNo: idx) / Context.getCharWidth(); |
317 | |
318 | // Create a single field for consecutive named bitfields using char as |
319 | // base type. |
320 | if ((*i)->isBitField()) { |
321 | const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(FD: *i); |
322 | // For big endian targets the first bitfield in the consecutive run is |
323 | // at the most-significant end; see CGRecordLowering::setBitFieldInfo |
324 | // for more information. |
325 | bool IsBE = Context.getTargetInfo().isBigEndian(); |
326 | bool IsFirst = IsBE ? Info.StorageSize - (Info.Offset + Info.Size) == 0 |
327 | : Info.Offset == 0; |
328 | if (!IsFirst) |
329 | continue; |
330 | unsigned CurrentBitFieldSize = Info.StorageSize; |
331 | uint64_t Size = |
332 | llvm::divideCeil(Numerator: CurrentBitFieldSize, Denominator: Context.getCharWidth()); |
333 | llvm::MDNode *TBAAType = getChar(); |
334 | llvm::MDNode *TBAATag = |
335 | getAccessTagInfo(Info: TBAAAccessInfo(TBAAType, Size)); |
336 | Fields.push_back( |
337 | Elt: llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); |
338 | continue; |
339 | } |
340 | |
341 | QualType FieldQTy = i->getType(); |
342 | if (!CollectFields(BaseOffset: Offset, QTy: FieldQTy, Fields, |
343 | MayAlias: MayAlias || TypeHasMayAlias(QTy: FieldQTy))) |
344 | return false; |
345 | } |
346 | return true; |
347 | } |
348 | |
349 | /* Otherwise, treat whatever it is as a field. */ |
350 | uint64_t Offset = BaseOffset; |
351 | uint64_t Size = Context.getTypeSizeInChars(T: QTy).getQuantity(); |
352 | llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy); |
353 | llvm::MDNode *TBAATag = getAccessTagInfo(Info: TBAAAccessInfo(TBAAType, Size)); |
354 | Fields.push_back(Elt: llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); |
355 | return true; |
356 | } |
357 | |
358 | llvm::MDNode * |
359 | CodeGenTBAA::getTBAAStructInfo(QualType QTy) { |
360 | if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) |
361 | return nullptr; |
362 | |
363 | const Type *Ty = Context.getCanonicalType(T: QTy).getTypePtr(); |
364 | |
365 | if (llvm::MDNode *N = StructMetadataCache[Ty]) |
366 | return N; |
367 | |
368 | SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields; |
369 | if (CollectFields(BaseOffset: 0, QTy, Fields, MayAlias: TypeHasMayAlias(QTy))) |
370 | return MDHelper.createTBAAStructNode(Fields); |
371 | |
372 | // For now, handle any other kind of type conservatively. |
373 | return StructMetadataCache[Ty] = nullptr; |
374 | } |
375 | |
376 | llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) { |
377 | if (auto *TTy = dyn_cast<RecordType>(Val: Ty)) { |
378 | const RecordDecl *RD = TTy->getDecl()->getDefinition(); |
379 | const ASTRecordLayout &Layout = Context.getASTRecordLayout(D: RD); |
380 | using TBAAStructField = llvm::MDBuilder::TBAAStructField; |
381 | SmallVector<TBAAStructField, 4> Fields; |
382 | if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD)) { |
383 | // Handle C++ base classes. Non-virtual bases can treated a kind of |
384 | // field. Virtual bases are more complex and omitted, but avoid an |
385 | // incomplete view for NewStructPathTBAA. |
386 | if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0) |
387 | return nullptr; |
388 | for (const CXXBaseSpecifier &B : CXXRD->bases()) { |
389 | if (B.isVirtual()) |
390 | continue; |
391 | QualType BaseQTy = B.getType(); |
392 | const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl(); |
393 | if (BaseRD->isEmpty()) |
394 | continue; |
395 | llvm::MDNode *TypeNode = isValidBaseType(QTy: BaseQTy) |
396 | ? getValidBaseTypeInfo(QTy: BaseQTy) |
397 | : getTypeInfo(QTy: BaseQTy); |
398 | if (!TypeNode) |
399 | return nullptr; |
400 | uint64_t Offset = Layout.getBaseClassOffset(Base: BaseRD).getQuantity(); |
401 | uint64_t Size = |
402 | Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity(); |
403 | Fields.push_back( |
404 | Elt: llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode)); |
405 | } |
406 | // The order in which base class subobjects are allocated is unspecified, |
407 | // so may differ from declaration order. In particular, Itanium ABI will |
408 | // allocate a primary base first. |
409 | // Since we exclude empty subobjects, the objects are not overlapping and |
410 | // their offsets are unique. |
411 | llvm::sort(C&: Fields, |
412 | Comp: [](const TBAAStructField &A, const TBAAStructField &B) { |
413 | return A.Offset < B.Offset; |
414 | }); |
415 | } |
416 | for (FieldDecl *Field : RD->fields()) { |
417 | if (Field->isZeroSize(Ctx: Context) || Field->isUnnamedBitField()) |
418 | continue; |
419 | QualType FieldQTy = Field->getType(); |
420 | llvm::MDNode *TypeNode = isValidBaseType(QTy: FieldQTy) |
421 | ? getValidBaseTypeInfo(QTy: FieldQTy) |
422 | : getTypeInfo(QTy: FieldQTy); |
423 | if (!TypeNode) |
424 | return nullptr; |
425 | |
426 | uint64_t BitOffset = Layout.getFieldOffset(FieldNo: Field->getFieldIndex()); |
427 | uint64_t Offset = Context.toCharUnitsFromBits(BitSize: BitOffset).getQuantity(); |
428 | uint64_t Size = Context.getTypeSizeInChars(T: FieldQTy).getQuantity(); |
429 | Fields.push_back(Elt: llvm::MDBuilder::TBAAStructField(Offset, Size, |
430 | TypeNode)); |
431 | } |
432 | |
433 | SmallString<256> OutName; |
434 | if (Features.CPlusPlus) { |
435 | // Don't use the mangler for C code. |
436 | llvm::raw_svector_ostream Out(OutName); |
437 | MContext.mangleCanonicalTypeName(T: QualType(Ty, 0), Out); |
438 | } else { |
439 | OutName = RD->getName(); |
440 | } |
441 | |
442 | if (CodeGenOpts.NewStructPathTBAA) { |
443 | llvm::MDNode *Parent = getChar(); |
444 | uint64_t Size = Context.getTypeSizeInChars(T: Ty).getQuantity(); |
445 | llvm::Metadata *Id = MDHelper.createString(Str: OutName); |
446 | return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields); |
447 | } |
448 | |
449 | // Create the struct type node with a vector of pairs (offset, type). |
450 | SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes; |
451 | for (const auto &Field : Fields) |
452 | OffsetsAndTypes.push_back(Elt: std::make_pair(x: Field.Type, y: Field.Offset)); |
453 | return MDHelper.createTBAAStructTypeNode(Name: OutName, Fields: OffsetsAndTypes); |
454 | } |
455 | |
456 | return nullptr; |
457 | } |
458 | |
459 | llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) { |
460 | assert(isValidBaseType(QTy) && "Must be a valid base type" ); |
461 | |
462 | const Type *Ty = Context.getCanonicalType(T: QTy).getTypePtr(); |
463 | |
464 | // nullptr is a valid value in the cache, so use find rather than [] |
465 | auto I = BaseTypeMetadataCache.find(Val: Ty); |
466 | if (I != BaseTypeMetadataCache.end()) |
467 | return I->second; |
468 | |
469 | // First calculate the metadata, before recomputing the insertion point, as |
470 | // the helper can recursively call us. |
471 | llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty); |
472 | LLVM_ATTRIBUTE_UNUSED auto inserted = |
473 | BaseTypeMetadataCache.insert(KV: {Ty, TypeNode}); |
474 | assert(inserted.second && "BaseType metadata was already inserted" ); |
475 | |
476 | return TypeNode; |
477 | } |
478 | |
479 | llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) { |
480 | return isValidBaseType(QTy) ? getValidBaseTypeInfo(QTy) : nullptr; |
481 | } |
482 | |
483 | llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) { |
484 | assert(!Info.isIncomplete() && "Access to an object of an incomplete type!" ); |
485 | |
486 | if (Info.isMayAlias()) |
487 | Info = TBAAAccessInfo(getChar(), Info.Size); |
488 | |
489 | if (!Info.AccessType) |
490 | return nullptr; |
491 | |
492 | if (!CodeGenOpts.StructPathTBAA) |
493 | Info = TBAAAccessInfo(Info.AccessType, Info.Size); |
494 | |
495 | llvm::MDNode *&N = AccessTagMetadataCache[Info]; |
496 | if (N) |
497 | return N; |
498 | |
499 | if (!Info.BaseType) { |
500 | Info.BaseType = Info.AccessType; |
501 | assert(!Info.Offset && "Nonzero offset for an access with no base type!" ); |
502 | } |
503 | if (CodeGenOpts.NewStructPathTBAA) { |
504 | return N = MDHelper.createTBAAAccessTag(BaseType: Info.BaseType, AccessType: Info.AccessType, |
505 | Offset: Info.Offset, Size: Info.Size); |
506 | } |
507 | return N = MDHelper.createTBAAStructTagNode(BaseType: Info.BaseType, AccessType: Info.AccessType, |
508 | Offset: Info.Offset); |
509 | } |
510 | |
511 | TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, |
512 | TBAAAccessInfo TargetInfo) { |
513 | if (SourceInfo.isMayAlias() || TargetInfo.isMayAlias()) |
514 | return TBAAAccessInfo::getMayAliasInfo(); |
515 | return TargetInfo; |
516 | } |
517 | |
518 | TBAAAccessInfo |
519 | CodeGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, |
520 | TBAAAccessInfo InfoB) { |
521 | if (InfoA == InfoB) |
522 | return InfoA; |
523 | |
524 | if (!InfoA || !InfoB) |
525 | return TBAAAccessInfo(); |
526 | |
527 | if (InfoA.isMayAlias() || InfoB.isMayAlias()) |
528 | return TBAAAccessInfo::getMayAliasInfo(); |
529 | |
530 | // TODO: Implement the rest of the logic here. For example, two accesses |
531 | // with same final access types result in an access to an object of that final |
532 | // access type regardless of their base types. |
533 | return TBAAAccessInfo::getMayAliasInfo(); |
534 | } |
535 | |
536 | TBAAAccessInfo |
537 | CodeGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, |
538 | TBAAAccessInfo SrcInfo) { |
539 | if (DestInfo == SrcInfo) |
540 | return DestInfo; |
541 | |
542 | if (!DestInfo || !SrcInfo) |
543 | return TBAAAccessInfo(); |
544 | |
545 | if (DestInfo.isMayAlias() || SrcInfo.isMayAlias()) |
546 | return TBAAAccessInfo::getMayAliasInfo(); |
547 | |
548 | // TODO: Implement the rest of the logic here. For example, two accesses |
549 | // with same final access types result in an access to an object of that final |
550 | // access type regardless of their base types. |
551 | return TBAAAccessInfo::getMayAliasInfo(); |
552 | } |
553 | |