29#include "llvm/IR/LLVMContext.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/IR/Module.h"
32#include "llvm/IR/Type.h"
33#include "llvm/Support/Debug.h"
40 : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
48llvm::MDNode *CodeGenTBAA::getRoot() {
54 if (Features.CPlusPlus)
55 Root = MDHelper.createTBAARoot(
"Simple C++ TBAA");
57 Root = MDHelper.createTBAARoot(
"Simple C/C++ TBAA");
63llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
66 if (CodeGenOpts.NewStructPathTBAA) {
67 llvm::Metadata *Id = MDHelper.createString(Name);
68 return MDHelper.createTBAATypeNode(Parent, Size, Id);
70 return MDHelper.createTBAAScalarTypeNode(Name, Parent);
79 Char = createScalarTypeNode(
"omnipotent char", getRoot(), 1);
84llvm::MDNode *CodeGenTBAA::getAnyPtr(
unsigned PtrDepth) {
85 assert(PtrDepth >= 1 &&
"Pointer must have some depth");
104 if (AnyPtrs.size() < PtrDepth) {
105 AnyPtrs.reserve(PtrDepth);
106 auto Size =
Module.getDataLayout().getPointerSize();
109 AnyPtrs.push_back(createScalarTypeNode(
"any pointer",
getChar(), Size));
111 for (
size_t Idx = AnyPtrs.size(); Idx < PtrDepth; ++Idx) {
112 auto Name = (
"any p" + llvm::Twine(Idx + 1) +
" pointer").str();
113 AnyPtrs.push_back(createScalarTypeNode(Name, AnyPtrs[Idx - 1], Size));
117 return AnyPtrs[PtrDepth - 1];
123 if (TD->hasAttr<MayAliasAttr>())
130 if (TT->getDecl()->hasAttr<MayAliasAttr>())
148 if (!RD->isCompleteDefinition())
150 if (RD->hasFlexibleArrayMember())
154 if (RD->isStruct() || RD->isClass())
160llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(
const Type *Ty) {
161 uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
164 if (
const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
165 switch (BTy->getKind()) {
171 case BuiltinType::Char_U:
172 case BuiltinType::Char_S:
173 case BuiltinType::UChar:
174 case BuiltinType::SChar:
178 case BuiltinType::UShort:
180 case BuiltinType::UInt:
182 case BuiltinType::ULong:
184 case BuiltinType::ULongLong:
186 case BuiltinType::UInt128:
189 case BuiltinType::UShortFract:
191 case BuiltinType::UFract:
193 case BuiltinType::ULongFract:
196 case BuiltinType::SatUShortFract:
198 case BuiltinType::SatUFract:
200 case BuiltinType::SatULongFract:
203 case BuiltinType::UShortAccum:
205 case BuiltinType::UAccum:
207 case BuiltinType::ULongAccum:
210 case BuiltinType::SatUShortAccum:
212 case BuiltinType::SatUAccum:
214 case BuiltinType::SatULongAccum:
221 return createScalarTypeNode(BTy->getName(Features),
getChar(), Size);
248 if (!CodeGenOpts.PointerTBAA)
266 unsigned PtrDepth = 0;
277 return getAnyPtr(PtrDepth);
287 SmallString<256> TyName;
289 llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
292 ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
301 return getAnyPtr(PtrDepth);
314 if (!RT->getDecl()->getDeclName())
315 return getAnyPtr(PtrDepth);
318 llvm::raw_svector_ostream TyOut(TyName);
319 MangleCtx->mangleCanonicalTypeName(QualType(Ty, 0), TyOut);
322 SmallString<256> OutName(
"p");
323 OutName += std::to_string(PtrDepth);
326 return createScalarTypeNode(OutName, getAnyPtr(PtrDepth), Size);
330 if (CodeGenOpts.NewStructPathTBAA && Ty->
isArrayType())
334 if (
const auto *MTy = dyn_cast<MatrixType>(Ty)) {
336 "only ConstantMatrixType should reach CodeGen");
342 if (
const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
343 const EnumDecl *ED = ETy->getDecl()->getDefinitionOrSelf();
344 if (!Features.CPlusPlus)
354 SmallString<256> OutName;
355 llvm::raw_svector_ostream
Out(OutName);
356 CGTypes.getCXXABI().getMangleContext().mangleCanonicalTypeName(
357 QualType(ETy, 0), Out);
358 return createScalarTypeNode(OutName,
getChar(), Size);
361 if (
const auto *EIT = dyn_cast<BitIntType>(Ty)) {
362 SmallString<256> OutName;
363 llvm::raw_svector_ostream
Out(OutName);
366 Out <<
"_BitInt(" << EIT->getNumBits() <<
')';
367 return createScalarTypeNode(OutName,
getChar(), Size);
377 if (!Features.Sanitize.has(SanitizerKind::Type) &&
378 (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing))
394 return getValidBaseTypeInfo(QTy);
396 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
397 if (llvm::MDNode *N = MetadataCache[Ty])
403 llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
404 return MetadataCache[Ty] = TypeNode;
416 uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
421 const llvm::DataLayout &DL = Module.getDataLayout();
422 unsigned Size = DL.getPointerTypeSize(VTablePtrType);
423 return TBAAAccessInfo(createScalarTypeNode(
"vtable pointer", getRoot(), Size),
428CodeGenTBAA::CollectFields(uint64_t BaseOffset,
436 if (TTy->isUnionType()) {
437 uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
438 llvm::MDNode *TBAAType =
getChar();
441 llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag));
450 if (!
Decl->bases().empty())
458 i != e; ++i, ++idx) {
467 if ((*i)->isBitField()) {
472 bool IsBE = Context.getTargetInfo().isBigEndian();
479 llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth());
480 llvm::MDNode *TBAAType =
getChar();
481 llvm::MDNode *TBAATag =
484 llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
489 if (!CollectFields(Offset, FieldQTy, Fields,
498 uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
501 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
507 if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
510 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
512 if (llvm::MDNode *N = StructMetadataCache[Ty])
517 return MDHelper.createTBAAStructNode(Fields);
520 return StructMetadataCache[Ty] =
nullptr;
523llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(
const Type *Ty) {
524 if (
auto *TTy = dyn_cast<RecordType>(Ty)) {
527 using TBAAStructField = llvm::MDBuilder::TBAAStructField;
529 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
533 if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
543 ? getValidBaseTypeInfo(BaseQTy)
549 Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
551 llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
559 [](
const TBAAStructField &A,
const TBAAStructField &B) {
560 return A.Offset < B.Offset;
563 for (FieldDecl *Field : RD->
fields()) {
564 if (
Field->isZeroSize(Context) ||
Field->isUnnamedBitField())
566 QualType FieldQTy =
Field->getType();
568 ? getValidBaseTypeInfo(FieldQTy)
574 uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
575 uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity();
576 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
580 SmallString<256> OutName;
581 if (Features.CPlusPlus) {
583 llvm::raw_svector_ostream
Out(OutName);
584 CGTypes.getCXXABI().getMangleContext().mangleCanonicalTypeName(
585 QualType(Ty, 0), Out);
590 if (CodeGenOpts.NewStructPathTBAA) {
591 llvm::MDNode *Parent =
getChar();
592 uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
593 llvm::Metadata *Id = MDHelper.createString(OutName);
594 return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields);
598 SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes;
599 for (
const auto &Field : Fields)
600 OffsetsAndTypes.push_back(std::make_pair(
Field.Type,
Field.Offset));
601 return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
607llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) {
610 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
613 auto I = BaseTypeMetadataCache.find(Ty);
614 if (I != BaseTypeMetadataCache.end())
619 llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
620 [[maybe_unused]]
auto inserted = BaseTypeMetadataCache.insert({Ty, TypeNode});
621 assert(inserted.second &&
"BaseType metadata was already inserted");
631 assert(!Info.
isIncomplete() &&
"Access to an object of an incomplete type!");
639 if (!CodeGenOpts.StructPathTBAA)
642 llvm::MDNode *&N = AccessTagMetadataCache[Info];
648 assert(!Info.
Offset &&
"Nonzero offset for an access with no base type!");
650 if (CodeGenOpts.NewStructPathTBAA) {
671 if (!InfoA || !InfoB)
686 if (DestInfo == SrcInfo)
689 if (!DestInfo || !SrcInfo)
Defines the clang::ASTContext interface.
static bool TypeHasMayAlias(QualType QTy)
static bool isValidBaseType(QualType QTy)
Check if the given type is a valid base type to be used in access tags.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents a base class of a C++ class.
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
llvm::MDNode * getBaseTypeInfo(QualType QTy)
getBaseTypeInfo - Get metadata that describes the given base access type.
llvm::MDNode * getTypeInfo(QualType QTy)
getTypeInfo - Get metadata used to describe accesses to objects of the given type.
TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType)
getVTablePtrAccessInfo - Get the TBAA information that describes an access to a virtual table pointer...
TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, TBAAAccessInfo SrcInfo)
mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the purpose of memory transfer calls...
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo)
mergeTBAAInfoForCast - Get merged TBAA information for the purpose of type casts.
llvm::MDNode * getChar()
getChar - This is the mdnode for "char", which is special, and any types considered to be equivalent ...
TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, TBAAAccessInfo InfoB)
mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the purpose of conditional oper...
llvm::MDNode * getAccessTagInfo(TBAAAccessInfo Info)
getAccessTagInfo - Get TBAA tag for a given memory access.
llvm::MDNode * getTBAAStructInfo(QualType QTy)
getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of the given type.
CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features)
TBAAAccessInfo getAccessInfo(QualType AccessType)
getAccessInfo - Get TBAA information that describes an access to an object of the given type.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
Decl - This represents one declaration (or definition), e.g.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Describes a module or submodule.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool isExternallyVisible() const
A (possibly-)qualified type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
Exposes information about the current target.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isStdByteType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs<specific type>'.
Defines the clang::TargetInfo interface.
bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD)
Return true iff the field is "empty", that is, either a zero-width bit-field or an isEmptyRecordForLa...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)
Structure with information about how a bitfield should be accessed.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
llvm::MDNode * AccessType
AccessType - The final access type.
uint64_t Offset
Offset - The byte offset of the final access within the base one.
static TBAAAccessInfo getMayAliasInfo()
uint64_t Size
Size - The size of access, in bytes.
static TBAAAccessInfo getIncompleteInfo()
llvm::MDNode * BaseType
BaseType - The base/leading access type.
bool isIncomplete() const