17330f729Sjoerg //===-- CodeGenTBAA.cpp - TBAA information for LLVM CodeGen ---------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This is the code that manages TBAA information and defines the TBAA policy
107330f729Sjoerg // for the optimizer to use. Relevant standards text includes:
117330f729Sjoerg //
127330f729Sjoerg // C99 6.5p7
137330f729Sjoerg // C++ [basic.lval] (p10 in n3126, p15 in some earlier versions)
147330f729Sjoerg //
157330f729Sjoerg //===----------------------------------------------------------------------===//
167330f729Sjoerg
177330f729Sjoerg #include "CodeGenTBAA.h"
187330f729Sjoerg #include "clang/AST/ASTContext.h"
197330f729Sjoerg #include "clang/AST/Attr.h"
207330f729Sjoerg #include "clang/AST/Mangle.h"
217330f729Sjoerg #include "clang/AST/RecordLayout.h"
227330f729Sjoerg #include "clang/Basic/CodeGenOptions.h"
237330f729Sjoerg #include "llvm/ADT/SmallSet.h"
247330f729Sjoerg #include "llvm/IR/Constants.h"
257330f729Sjoerg #include "llvm/IR/LLVMContext.h"
267330f729Sjoerg #include "llvm/IR/Metadata.h"
277330f729Sjoerg #include "llvm/IR/Module.h"
287330f729Sjoerg #include "llvm/IR/Type.h"
297330f729Sjoerg using namespace clang;
307330f729Sjoerg using namespace CodeGen;
317330f729Sjoerg
CodeGenTBAA(ASTContext & Ctx,llvm::Module & M,const CodeGenOptions & CGO,const LangOptions & Features,MangleContext & MContext)327330f729Sjoerg CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M,
337330f729Sjoerg const CodeGenOptions &CGO,
347330f729Sjoerg const LangOptions &Features, MangleContext &MContext)
357330f729Sjoerg : Context(Ctx), Module(M), CodeGenOpts(CGO),
367330f729Sjoerg Features(Features), MContext(MContext), MDHelper(M.getContext()),
377330f729Sjoerg Root(nullptr), Char(nullptr)
387330f729Sjoerg {}
397330f729Sjoerg
~CodeGenTBAA()407330f729Sjoerg CodeGenTBAA::~CodeGenTBAA() {
417330f729Sjoerg }
427330f729Sjoerg
getRoot()437330f729Sjoerg llvm::MDNode *CodeGenTBAA::getRoot() {
447330f729Sjoerg // Define the root of the tree. This identifies the tree, so that
457330f729Sjoerg // if our LLVM IR is linked with LLVM IR from a different front-end
467330f729Sjoerg // (or a different version of this front-end), their TBAA trees will
477330f729Sjoerg // remain distinct, and the optimizer will treat them conservatively.
487330f729Sjoerg if (!Root) {
497330f729Sjoerg if (Features.CPlusPlus)
507330f729Sjoerg Root = MDHelper.createTBAARoot("Simple C++ TBAA");
517330f729Sjoerg else
527330f729Sjoerg Root = MDHelper.createTBAARoot("Simple C/C++ TBAA");
537330f729Sjoerg }
547330f729Sjoerg
557330f729Sjoerg return Root;
567330f729Sjoerg }
577330f729Sjoerg
createScalarTypeNode(StringRef Name,llvm::MDNode * Parent,uint64_t Size)587330f729Sjoerg llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
597330f729Sjoerg llvm::MDNode *Parent,
607330f729Sjoerg uint64_t Size) {
617330f729Sjoerg if (CodeGenOpts.NewStructPathTBAA) {
627330f729Sjoerg llvm::Metadata *Id = MDHelper.createString(Name);
637330f729Sjoerg return MDHelper.createTBAATypeNode(Parent, Size, Id);
647330f729Sjoerg }
657330f729Sjoerg return MDHelper.createTBAAScalarTypeNode(Name, Parent);
667330f729Sjoerg }
677330f729Sjoerg
getChar()687330f729Sjoerg llvm::MDNode *CodeGenTBAA::getChar() {
697330f729Sjoerg // Define the root of the tree for user-accessible memory. C and C++
707330f729Sjoerg // give special powers to char and certain similar types. However,
717330f729Sjoerg // these special powers only cover user-accessible memory, and doesn't
727330f729Sjoerg // include things like vtables.
737330f729Sjoerg if (!Char)
747330f729Sjoerg Char = createScalarTypeNode("omnipotent char", getRoot(), /* Size= */ 1);
757330f729Sjoerg
767330f729Sjoerg return Char;
777330f729Sjoerg }
787330f729Sjoerg
TypeHasMayAlias(QualType QTy)797330f729Sjoerg static bool TypeHasMayAlias(QualType QTy) {
807330f729Sjoerg // Tagged types have declarations, and therefore may have attributes.
81*e038c9c4Sjoerg if (auto *TD = QTy->getAsTagDecl())
82*e038c9c4Sjoerg if (TD->hasAttr<MayAliasAttr>())
837330f729Sjoerg return true;
847330f729Sjoerg
85*e038c9c4Sjoerg // Also look for may_alias as a declaration attribute on a typedef.
86*e038c9c4Sjoerg // FIXME: We should follow GCC and model may_alias as a type attribute
87*e038c9c4Sjoerg // rather than as a declaration attribute.
88*e038c9c4Sjoerg while (auto *TT = QTy->getAs<TypedefType>()) {
89*e038c9c4Sjoerg if (TT->getDecl()->hasAttr<MayAliasAttr>())
90*e038c9c4Sjoerg return true;
91*e038c9c4Sjoerg QTy = TT->desugar();
92*e038c9c4Sjoerg }
937330f729Sjoerg return false;
947330f729Sjoerg }
957330f729Sjoerg
967330f729Sjoerg /// Check if the given type is a valid base type to be used in access tags.
isValidBaseType(QualType QTy)977330f729Sjoerg static bool isValidBaseType(QualType QTy) {
987330f729Sjoerg if (QTy->isReferenceType())
997330f729Sjoerg return false;
1007330f729Sjoerg if (const RecordType *TTy = QTy->getAs<RecordType>()) {
1017330f729Sjoerg const RecordDecl *RD = TTy->getDecl()->getDefinition();
1027330f729Sjoerg // Incomplete types are not valid base access types.
1037330f729Sjoerg if (!RD)
1047330f729Sjoerg return false;
1057330f729Sjoerg if (RD->hasFlexibleArrayMember())
1067330f729Sjoerg return false;
1077330f729Sjoerg // RD can be struct, union, class, interface or enum.
1087330f729Sjoerg // For now, we only handle struct and class.
1097330f729Sjoerg if (RD->isStruct() || RD->isClass())
1107330f729Sjoerg return true;
1117330f729Sjoerg }
1127330f729Sjoerg return false;
1137330f729Sjoerg }
1147330f729Sjoerg
getTypeInfoHelper(const Type * Ty)1157330f729Sjoerg llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
1167330f729Sjoerg uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
1177330f729Sjoerg
1187330f729Sjoerg // Handle builtin types.
1197330f729Sjoerg if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
1207330f729Sjoerg switch (BTy->getKind()) {
1217330f729Sjoerg // Character types are special and can alias anything.
1227330f729Sjoerg // In C++, this technically only includes "char" and "unsigned char",
1237330f729Sjoerg // and not "signed char". In C, it includes all three. For now,
1247330f729Sjoerg // the risk of exploiting this detail in C++ seems likely to outweigh
1257330f729Sjoerg // the benefit.
1267330f729Sjoerg case BuiltinType::Char_U:
1277330f729Sjoerg case BuiltinType::Char_S:
1287330f729Sjoerg case BuiltinType::UChar:
1297330f729Sjoerg case BuiltinType::SChar:
1307330f729Sjoerg return getChar();
1317330f729Sjoerg
1327330f729Sjoerg // Unsigned types can alias their corresponding signed types.
1337330f729Sjoerg case BuiltinType::UShort:
1347330f729Sjoerg return getTypeInfo(Context.ShortTy);
1357330f729Sjoerg case BuiltinType::UInt:
1367330f729Sjoerg return getTypeInfo(Context.IntTy);
1377330f729Sjoerg case BuiltinType::ULong:
1387330f729Sjoerg return getTypeInfo(Context.LongTy);
1397330f729Sjoerg case BuiltinType::ULongLong:
1407330f729Sjoerg return getTypeInfo(Context.LongLongTy);
1417330f729Sjoerg case BuiltinType::UInt128:
1427330f729Sjoerg return getTypeInfo(Context.Int128Ty);
1437330f729Sjoerg
144*e038c9c4Sjoerg case BuiltinType::UShortFract:
145*e038c9c4Sjoerg return getTypeInfo(Context.ShortFractTy);
146*e038c9c4Sjoerg case BuiltinType::UFract:
147*e038c9c4Sjoerg return getTypeInfo(Context.FractTy);
148*e038c9c4Sjoerg case BuiltinType::ULongFract:
149*e038c9c4Sjoerg return getTypeInfo(Context.LongFractTy);
150*e038c9c4Sjoerg
151*e038c9c4Sjoerg case BuiltinType::SatUShortFract:
152*e038c9c4Sjoerg return getTypeInfo(Context.SatShortFractTy);
153*e038c9c4Sjoerg case BuiltinType::SatUFract:
154*e038c9c4Sjoerg return getTypeInfo(Context.SatFractTy);
155*e038c9c4Sjoerg case BuiltinType::SatULongFract:
156*e038c9c4Sjoerg return getTypeInfo(Context.SatLongFractTy);
157*e038c9c4Sjoerg
158*e038c9c4Sjoerg case BuiltinType::UShortAccum:
159*e038c9c4Sjoerg return getTypeInfo(Context.ShortAccumTy);
160*e038c9c4Sjoerg case BuiltinType::UAccum:
161*e038c9c4Sjoerg return getTypeInfo(Context.AccumTy);
162*e038c9c4Sjoerg case BuiltinType::ULongAccum:
163*e038c9c4Sjoerg return getTypeInfo(Context.LongAccumTy);
164*e038c9c4Sjoerg
165*e038c9c4Sjoerg case BuiltinType::SatUShortAccum:
166*e038c9c4Sjoerg return getTypeInfo(Context.SatShortAccumTy);
167*e038c9c4Sjoerg case BuiltinType::SatUAccum:
168*e038c9c4Sjoerg return getTypeInfo(Context.SatAccumTy);
169*e038c9c4Sjoerg case BuiltinType::SatULongAccum:
170*e038c9c4Sjoerg return getTypeInfo(Context.SatLongAccumTy);
171*e038c9c4Sjoerg
1727330f729Sjoerg // Treat all other builtin types as distinct types. This includes
1737330f729Sjoerg // treating wchar_t, char16_t, and char32_t as distinct from their
1747330f729Sjoerg // "underlying types".
1757330f729Sjoerg default:
1767330f729Sjoerg return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
1777330f729Sjoerg }
1787330f729Sjoerg }
1797330f729Sjoerg
1807330f729Sjoerg // C++1z [basic.lval]p10: "If a program attempts to access the stored value of
1817330f729Sjoerg // an object through a glvalue of other than one of the following types the
1827330f729Sjoerg // behavior is undefined: [...] a char, unsigned char, or std::byte type."
1837330f729Sjoerg if (Ty->isStdByteType())
1847330f729Sjoerg return getChar();
1857330f729Sjoerg
1867330f729Sjoerg // Handle pointers and references.
1877330f729Sjoerg // TODO: Implement C++'s type "similarity" and consider dis-"similar"
1887330f729Sjoerg // pointers distinct.
1897330f729Sjoerg if (Ty->isPointerType() || Ty->isReferenceType())
1907330f729Sjoerg return createScalarTypeNode("any pointer", getChar(), Size);
1917330f729Sjoerg
1927330f729Sjoerg // Accesses to arrays are accesses to objects of their element types.
1937330f729Sjoerg if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
1947330f729Sjoerg return getTypeInfo(cast<ArrayType>(Ty)->getElementType());
1957330f729Sjoerg
1967330f729Sjoerg // Enum types are distinct types. In C++ they have "underlying types",
1977330f729Sjoerg // however they aren't related for TBAA.
1987330f729Sjoerg if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
1997330f729Sjoerg // In C++ mode, types have linkage, so we can rely on the ODR and
2007330f729Sjoerg // on their mangled names, if they're external.
2017330f729Sjoerg // TODO: Is there a way to get a program-wide unique name for a
2027330f729Sjoerg // decl with local linkage or no linkage?
2037330f729Sjoerg if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())
2047330f729Sjoerg return getChar();
2057330f729Sjoerg
2067330f729Sjoerg SmallString<256> OutName;
2077330f729Sjoerg llvm::raw_svector_ostream Out(OutName);
2087330f729Sjoerg MContext.mangleTypeName(QualType(ETy, 0), Out);
2097330f729Sjoerg return createScalarTypeNode(OutName, getChar(), Size);
2107330f729Sjoerg }
2117330f729Sjoerg
212*e038c9c4Sjoerg if (const auto *EIT = dyn_cast<ExtIntType>(Ty)) {
213*e038c9c4Sjoerg SmallString<256> OutName;
214*e038c9c4Sjoerg llvm::raw_svector_ostream Out(OutName);
215*e038c9c4Sjoerg // Don't specify signed/unsigned since integer types can alias despite sign
216*e038c9c4Sjoerg // differences.
217*e038c9c4Sjoerg Out << "_ExtInt(" << EIT->getNumBits() << ')';
218*e038c9c4Sjoerg return createScalarTypeNode(OutName, getChar(), Size);
219*e038c9c4Sjoerg }
220*e038c9c4Sjoerg
2217330f729Sjoerg // For now, handle any other kind of type conservatively.
2227330f729Sjoerg return getChar();
2237330f729Sjoerg }
2247330f729Sjoerg
getTypeInfo(QualType QTy)2257330f729Sjoerg llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
2267330f729Sjoerg // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
2277330f729Sjoerg if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
2287330f729Sjoerg return nullptr;
2297330f729Sjoerg
2307330f729Sjoerg // If the type has the may_alias attribute (even on a typedef), it is
2317330f729Sjoerg // effectively in the general char alias class.
2327330f729Sjoerg if (TypeHasMayAlias(QTy))
2337330f729Sjoerg return getChar();
2347330f729Sjoerg
2357330f729Sjoerg // We need this function to not fall back to returning the "omnipotent char"
2367330f729Sjoerg // type node for aggregate and union types. Otherwise, any dereference of an
2377330f729Sjoerg // aggregate will result into the may-alias access descriptor, meaning all
2387330f729Sjoerg // subsequent accesses to direct and indirect members of that aggregate will
2397330f729Sjoerg // be considered may-alias too.
2407330f729Sjoerg // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function.
2417330f729Sjoerg if (isValidBaseType(QTy))
2427330f729Sjoerg return getBaseTypeInfo(QTy);
2437330f729Sjoerg
2447330f729Sjoerg const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
2457330f729Sjoerg if (llvm::MDNode *N = MetadataCache[Ty])
2467330f729Sjoerg return N;
2477330f729Sjoerg
2487330f729Sjoerg // Note that the following helper call is allowed to add new nodes to the
2497330f729Sjoerg // cache, which invalidates all its previously obtained iterators. So we
2507330f729Sjoerg // first generate the node for the type and then add that node to the cache.
2517330f729Sjoerg llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
2527330f729Sjoerg return MetadataCache[Ty] = TypeNode;
2537330f729Sjoerg }
2547330f729Sjoerg
getAccessInfo(QualType AccessType)2557330f729Sjoerg TBAAAccessInfo CodeGenTBAA::getAccessInfo(QualType AccessType) {
2567330f729Sjoerg // Pointee values may have incomplete types, but they shall never be
2577330f729Sjoerg // dereferenced.
2587330f729Sjoerg if (AccessType->isIncompleteType())
2597330f729Sjoerg return TBAAAccessInfo::getIncompleteInfo();
2607330f729Sjoerg
2617330f729Sjoerg if (TypeHasMayAlias(AccessType))
2627330f729Sjoerg return TBAAAccessInfo::getMayAliasInfo();
2637330f729Sjoerg
2647330f729Sjoerg uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
2657330f729Sjoerg return TBAAAccessInfo(getTypeInfo(AccessType), Size);
2667330f729Sjoerg }
2677330f729Sjoerg
getVTablePtrAccessInfo(llvm::Type * VTablePtrType)2687330f729Sjoerg TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) {
2697330f729Sjoerg llvm::DataLayout DL(&Module);
2707330f729Sjoerg unsigned Size = DL.getPointerTypeSize(VTablePtrType);
2717330f729Sjoerg return TBAAAccessInfo(createScalarTypeNode("vtable pointer", getRoot(), Size),
2727330f729Sjoerg Size);
2737330f729Sjoerg }
2747330f729Sjoerg
2757330f729Sjoerg bool
CollectFields(uint64_t BaseOffset,QualType QTy,SmallVectorImpl<llvm::MDBuilder::TBAAStructField> & Fields,bool MayAlias)2767330f729Sjoerg CodeGenTBAA::CollectFields(uint64_t BaseOffset,
2777330f729Sjoerg QualType QTy,
2787330f729Sjoerg SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &
2797330f729Sjoerg Fields,
2807330f729Sjoerg bool MayAlias) {
2817330f729Sjoerg /* Things not handled yet include: C++ base classes, bitfields, */
2827330f729Sjoerg
2837330f729Sjoerg if (const RecordType *TTy = QTy->getAs<RecordType>()) {
2847330f729Sjoerg const RecordDecl *RD = TTy->getDecl()->getDefinition();
2857330f729Sjoerg if (RD->hasFlexibleArrayMember())
2867330f729Sjoerg return false;
2877330f729Sjoerg
2887330f729Sjoerg // TODO: Handle C++ base classes.
2897330f729Sjoerg if (const CXXRecordDecl *Decl = dyn_cast<CXXRecordDecl>(RD))
2907330f729Sjoerg if (Decl->bases_begin() != Decl->bases_end())
2917330f729Sjoerg return false;
2927330f729Sjoerg
2937330f729Sjoerg const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
2947330f729Sjoerg
2957330f729Sjoerg unsigned idx = 0;
2967330f729Sjoerg for (RecordDecl::field_iterator i = RD->field_begin(),
2977330f729Sjoerg e = RD->field_end(); i != e; ++i, ++idx) {
2987330f729Sjoerg if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield())
2997330f729Sjoerg continue;
3007330f729Sjoerg uint64_t Offset = BaseOffset +
3017330f729Sjoerg Layout.getFieldOffset(idx) / Context.getCharWidth();
3027330f729Sjoerg QualType FieldQTy = i->getType();
3037330f729Sjoerg if (!CollectFields(Offset, FieldQTy, Fields,
3047330f729Sjoerg MayAlias || TypeHasMayAlias(FieldQTy)))
3057330f729Sjoerg return false;
3067330f729Sjoerg }
3077330f729Sjoerg return true;
3087330f729Sjoerg }
3097330f729Sjoerg
3107330f729Sjoerg /* Otherwise, treat whatever it is as a field. */
3117330f729Sjoerg uint64_t Offset = BaseOffset;
3127330f729Sjoerg uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
3137330f729Sjoerg llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy);
3147330f729Sjoerg llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size));
3157330f729Sjoerg Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
3167330f729Sjoerg return true;
3177330f729Sjoerg }
3187330f729Sjoerg
3197330f729Sjoerg llvm::MDNode *
getTBAAStructInfo(QualType QTy)3207330f729Sjoerg CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
3217330f729Sjoerg const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
3227330f729Sjoerg
3237330f729Sjoerg if (llvm::MDNode *N = StructMetadataCache[Ty])
3247330f729Sjoerg return N;
3257330f729Sjoerg
3267330f729Sjoerg SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields;
3277330f729Sjoerg if (CollectFields(0, QTy, Fields, TypeHasMayAlias(QTy)))
3287330f729Sjoerg return MDHelper.createTBAAStructNode(Fields);
3297330f729Sjoerg
3307330f729Sjoerg // For now, handle any other kind of type conservatively.
3317330f729Sjoerg return StructMetadataCache[Ty] = nullptr;
3327330f729Sjoerg }
3337330f729Sjoerg
getBaseTypeInfoHelper(const Type * Ty)3347330f729Sjoerg llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
3357330f729Sjoerg if (auto *TTy = dyn_cast<RecordType>(Ty)) {
3367330f729Sjoerg const RecordDecl *RD = TTy->getDecl()->getDefinition();
3377330f729Sjoerg const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
3387330f729Sjoerg SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields;
3397330f729Sjoerg for (FieldDecl *Field : RD->fields()) {
3407330f729Sjoerg if (Field->isZeroSize(Context) || Field->isUnnamedBitfield())
3417330f729Sjoerg continue;
3427330f729Sjoerg QualType FieldQTy = Field->getType();
3437330f729Sjoerg llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ?
3447330f729Sjoerg getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
3457330f729Sjoerg if (!TypeNode)
3467330f729Sjoerg return BaseTypeMetadataCache[Ty] = nullptr;
3477330f729Sjoerg
3487330f729Sjoerg uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex());
3497330f729Sjoerg uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
3507330f729Sjoerg uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity();
3517330f729Sjoerg Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
3527330f729Sjoerg TypeNode));
3537330f729Sjoerg }
3547330f729Sjoerg
3557330f729Sjoerg SmallString<256> OutName;
3567330f729Sjoerg if (Features.CPlusPlus) {
3577330f729Sjoerg // Don't use the mangler for C code.
3587330f729Sjoerg llvm::raw_svector_ostream Out(OutName);
3597330f729Sjoerg MContext.mangleTypeName(QualType(Ty, 0), Out);
3607330f729Sjoerg } else {
3617330f729Sjoerg OutName = RD->getName();
3627330f729Sjoerg }
3637330f729Sjoerg
3647330f729Sjoerg if (CodeGenOpts.NewStructPathTBAA) {
3657330f729Sjoerg llvm::MDNode *Parent = getChar();
3667330f729Sjoerg uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
3677330f729Sjoerg llvm::Metadata *Id = MDHelper.createString(OutName);
3687330f729Sjoerg return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields);
3697330f729Sjoerg }
3707330f729Sjoerg
3717330f729Sjoerg // Create the struct type node with a vector of pairs (offset, type).
3727330f729Sjoerg SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes;
3737330f729Sjoerg for (const auto &Field : Fields)
3747330f729Sjoerg OffsetsAndTypes.push_back(std::make_pair(Field.Type, Field.Offset));
3757330f729Sjoerg return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
3767330f729Sjoerg }
3777330f729Sjoerg
3787330f729Sjoerg return nullptr;
3797330f729Sjoerg }
3807330f729Sjoerg
getBaseTypeInfo(QualType QTy)3817330f729Sjoerg llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
3827330f729Sjoerg if (!isValidBaseType(QTy))
3837330f729Sjoerg return nullptr;
3847330f729Sjoerg
3857330f729Sjoerg const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
3867330f729Sjoerg if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
3877330f729Sjoerg return N;
3887330f729Sjoerg
3897330f729Sjoerg // Note that the following helper call is allowed to add new nodes to the
3907330f729Sjoerg // cache, which invalidates all its previously obtained iterators. So we
3917330f729Sjoerg // first generate the node for the type and then add that node to the cache.
3927330f729Sjoerg llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
3937330f729Sjoerg return BaseTypeMetadataCache[Ty] = TypeNode;
3947330f729Sjoerg }
3957330f729Sjoerg
getAccessTagInfo(TBAAAccessInfo Info)3967330f729Sjoerg llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
3977330f729Sjoerg assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
3987330f729Sjoerg
3997330f729Sjoerg if (Info.isMayAlias())
4007330f729Sjoerg Info = TBAAAccessInfo(getChar(), Info.Size);
4017330f729Sjoerg
4027330f729Sjoerg if (!Info.AccessType)
4037330f729Sjoerg return nullptr;
4047330f729Sjoerg
4057330f729Sjoerg if (!CodeGenOpts.StructPathTBAA)
4067330f729Sjoerg Info = TBAAAccessInfo(Info.AccessType, Info.Size);
4077330f729Sjoerg
4087330f729Sjoerg llvm::MDNode *&N = AccessTagMetadataCache[Info];
4097330f729Sjoerg if (N)
4107330f729Sjoerg return N;
4117330f729Sjoerg
4127330f729Sjoerg if (!Info.BaseType) {
4137330f729Sjoerg Info.BaseType = Info.AccessType;
4147330f729Sjoerg assert(!Info.Offset && "Nonzero offset for an access with no base type!");
4157330f729Sjoerg }
4167330f729Sjoerg if (CodeGenOpts.NewStructPathTBAA) {
4177330f729Sjoerg return N = MDHelper.createTBAAAccessTag(Info.BaseType, Info.AccessType,
4187330f729Sjoerg Info.Offset, Info.Size);
4197330f729Sjoerg }
4207330f729Sjoerg return N = MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType,
4217330f729Sjoerg Info.Offset);
4227330f729Sjoerg }
4237330f729Sjoerg
mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,TBAAAccessInfo TargetInfo)4247330f729Sjoerg TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
4257330f729Sjoerg TBAAAccessInfo TargetInfo) {
4267330f729Sjoerg if (SourceInfo.isMayAlias() || TargetInfo.isMayAlias())
4277330f729Sjoerg return TBAAAccessInfo::getMayAliasInfo();
4287330f729Sjoerg return TargetInfo;
4297330f729Sjoerg }
4307330f729Sjoerg
4317330f729Sjoerg TBAAAccessInfo
mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,TBAAAccessInfo InfoB)4327330f729Sjoerg CodeGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
4337330f729Sjoerg TBAAAccessInfo InfoB) {
4347330f729Sjoerg if (InfoA == InfoB)
4357330f729Sjoerg return InfoA;
4367330f729Sjoerg
4377330f729Sjoerg if (!InfoA || !InfoB)
4387330f729Sjoerg return TBAAAccessInfo();
4397330f729Sjoerg
4407330f729Sjoerg if (InfoA.isMayAlias() || InfoB.isMayAlias())
4417330f729Sjoerg return TBAAAccessInfo::getMayAliasInfo();
4427330f729Sjoerg
4437330f729Sjoerg // TODO: Implement the rest of the logic here. For example, two accesses
4447330f729Sjoerg // with same final access types result in an access to an object of that final
4457330f729Sjoerg // access type regardless of their base types.
4467330f729Sjoerg return TBAAAccessInfo::getMayAliasInfo();
4477330f729Sjoerg }
4487330f729Sjoerg
4497330f729Sjoerg TBAAAccessInfo
mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,TBAAAccessInfo SrcInfo)4507330f729Sjoerg CodeGenTBAA::mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
4517330f729Sjoerg TBAAAccessInfo SrcInfo) {
4527330f729Sjoerg if (DestInfo == SrcInfo)
4537330f729Sjoerg return DestInfo;
4547330f729Sjoerg
4557330f729Sjoerg if (!DestInfo || !SrcInfo)
4567330f729Sjoerg return TBAAAccessInfo();
4577330f729Sjoerg
4587330f729Sjoerg if (DestInfo.isMayAlias() || SrcInfo.isMayAlias())
4597330f729Sjoerg return TBAAAccessInfo::getMayAliasInfo();
4607330f729Sjoerg
4617330f729Sjoerg // TODO: Implement the rest of the logic here. For example, two accesses
4627330f729Sjoerg // with same final access types result in an access to an object of that final
4637330f729Sjoerg // access type regardless of their base types.
4647330f729Sjoerg return TBAAAccessInfo::getMayAliasInfo();
4657330f729Sjoerg }
466