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"
39 : Context(Ctx), CGTypes(CGTypes), Module(M), CodeGenOpts(CGO),
47llvm::MDNode *CodeGenTBAA::getRoot() {
53 if (Features.CPlusPlus)
54 Root = MDHelper.createTBAARoot(
"Simple C++ TBAA");
56 Root = MDHelper.createTBAARoot(
"Simple C/C++ TBAA");
62llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
65 if (CodeGenOpts.NewStructPathTBAA) {
66 llvm::Metadata *Id = MDHelper.createString(Name);
67 return MDHelper.createTBAATypeNode(Parent, Size, Id);
69 return MDHelper.createTBAAScalarTypeNode(Name, Parent);
72llvm::MDNode *CodeGenTBAA::getChar() {
78 Char = createScalarTypeNode(
"omnipotent char", getRoot(), 1);
83llvm::MDNode *CodeGenTBAA::getAnyPtr(
unsigned PtrDepth) {
84 assert(PtrDepth >= 1 &&
"Pointer must have some depth");
103 if (AnyPtrs.size() < PtrDepth) {
104 AnyPtrs.reserve(PtrDepth);
105 auto Size = Module.getDataLayout().getPointerSize();
108 AnyPtrs.push_back(createScalarTypeNode(
"any pointer", getChar(), Size));
110 for (
size_t Idx = AnyPtrs.size(); Idx < PtrDepth; ++Idx) {
111 auto Name = (
"any p" + llvm::Twine(Idx + 1) +
" pointer").str();
112 AnyPtrs.push_back(createScalarTypeNode(Name, AnyPtrs[Idx - 1], Size));
116 return AnyPtrs[PtrDepth - 1];
122 if (TD->hasAttr<MayAliasAttr>())
129 if (TT->getDecl()->hasAttr<MayAliasAttr>())
147 if (!RD->isCompleteDefinition())
149 if (RD->hasFlexibleArrayMember())
153 if (RD->isStruct() || RD->isClass())
159llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(
const Type *Ty) {
160 uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
163 if (
const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
164 switch (BTy->getKind()) {
170 case BuiltinType::Char_U:
171 case BuiltinType::Char_S:
172 case BuiltinType::UChar:
173 case BuiltinType::SChar:
177 case BuiltinType::UShort:
179 case BuiltinType::UInt:
181 case BuiltinType::ULong:
183 case BuiltinType::ULongLong:
185 case BuiltinType::UInt128:
188 case BuiltinType::UShortFract:
190 case BuiltinType::UFract:
192 case BuiltinType::ULongFract:
195 case BuiltinType::SatUShortFract:
197 case BuiltinType::SatUFract:
199 case BuiltinType::SatULongFract:
202 case BuiltinType::UShortAccum:
204 case BuiltinType::UAccum:
206 case BuiltinType::ULongAccum:
209 case BuiltinType::SatUShortAccum:
211 case BuiltinType::SatUAccum:
213 case BuiltinType::SatULongAccum:
220 return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
247 if (!CodeGenOpts.PointerTBAA)
265 unsigned PtrDepth = 0;
276 return getAnyPtr(PtrDepth);
286 SmallString<256> TyName;
288 llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty);
291 ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0))
300 return getAnyPtr(PtrDepth);
313 if (!RT->getDecl()->getDeclName())
314 return getAnyPtr(PtrDepth);
317 llvm::raw_svector_ostream TyOut(TyName);
318 MangleCtx->mangleCanonicalTypeName(QualType(Ty, 0), TyOut);
321 SmallString<256> OutName(
"p");
322 OutName += std::to_string(PtrDepth);
325 return createScalarTypeNode(OutName, getAnyPtr(PtrDepth), Size);
329 if (CodeGenOpts.NewStructPathTBAA && Ty->
isArrayType())
333 if (
const auto *MTy = dyn_cast<MatrixType>(Ty)) {
335 "only ConstantMatrixType should reach CodeGen");
341 if (
const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
342 const EnumDecl *ED = ETy->getDecl()->getDefinitionOrSelf();
343 if (!Features.CPlusPlus)
353 SmallString<256> OutName;
354 llvm::raw_svector_ostream
Out(OutName);
355 CGTypes.getCXXABI().getMangleContext().mangleCanonicalTypeName(
356 QualType(ETy, 0), Out);
357 return createScalarTypeNode(OutName, getChar(), Size);
360 if (
const auto *EIT = dyn_cast<BitIntType>(Ty)) {
361 SmallString<256> OutName;
362 llvm::raw_svector_ostream
Out(OutName);
365 Out <<
"_BitInt(" << EIT->getNumBits() <<
')';
366 return createScalarTypeNode(OutName, getChar(), Size);
376 if (!Features.Sanitize.has(SanitizerKind::Type) &&
377 (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing))
393 return getValidBaseTypeInfo(QTy);
395 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
396 if (llvm::MDNode *N = MetadataCache[Ty])
402 llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
403 return MetadataCache[Ty] = TypeNode;
415 uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
420 const llvm::DataLayout &DL = Module.getDataLayout();
421 unsigned Size = DL.getPointerTypeSize(VTablePtrType);
422 return TBAAAccessInfo(createScalarTypeNode(
"vtable pointer", getRoot(), Size),
427CodeGenTBAA::CollectFields(uint64_t BaseOffset,
435 if (TTy->isUnionType()) {
436 uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
437 llvm::MDNode *TBAAType = getChar();
440 llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag));
449 if (!
Decl->bases().empty())
457 i != e; ++i, ++idx) {
466 if ((*i)->isBitField()) {
471 bool IsBE = Context.getTargetInfo().isBigEndian();
478 llvm::divideCeil(CurrentBitFieldSize, Context.getCharWidth());
479 llvm::MDNode *TBAAType = getChar();
480 llvm::MDNode *TBAATag =
483 llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
488 if (!CollectFields(Offset, FieldQTy, Fields,
497 uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
500 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
506 if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
509 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
511 if (llvm::MDNode *N = StructMetadataCache[Ty])
516 return MDHelper.createTBAAStructNode(Fields);
519 return StructMetadataCache[Ty] =
nullptr;
522llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(
const Type *Ty) {
523 if (
auto *TTy = dyn_cast<RecordType>(Ty)) {
526 using TBAAStructField = llvm::MDBuilder::TBAAStructField;
528 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
532 if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
542 ? getValidBaseTypeInfo(BaseQTy)
548 Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
550 llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
558 [](
const TBAAStructField &A,
const TBAAStructField &B) {
559 return A.Offset < B.Offset;
562 for (FieldDecl *Field : RD->
fields()) {
563 if (
Field->isZeroSize(Context) ||
Field->isUnnamedBitField())
565 QualType FieldQTy =
Field->getType();
567 ? getValidBaseTypeInfo(FieldQTy)
573 uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
574 uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity();
575 Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
579 SmallString<256> OutName;
580 if (Features.CPlusPlus) {
582 llvm::raw_svector_ostream
Out(OutName);
583 CGTypes.getCXXABI().getMangleContext().mangleCanonicalTypeName(
584 QualType(Ty, 0), Out);
589 if (CodeGenOpts.NewStructPathTBAA) {
590 llvm::MDNode *Parent = getChar();
591 uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
592 llvm::Metadata *Id = MDHelper.createString(OutName);
593 return MDHelper.createTBAATypeNode(Parent, Size, Id, Fields);
597 SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes;
598 for (
const auto &Field : Fields)
599 OffsetsAndTypes.push_back(std::make_pair(
Field.Type,
Field.Offset));
600 return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
606llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) {
609 const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
612 auto I = BaseTypeMetadataCache.find(Ty);
613 if (I != BaseTypeMetadataCache.end())
618 llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
619 [[maybe_unused]]
auto inserted = BaseTypeMetadataCache.insert({Ty, TypeNode});
620 assert(inserted.second &&
"BaseType metadata was already inserted");
630 assert(!Info.
isIncomplete() &&
"Access to an object of an incomplete type!");
638 if (!CodeGenOpts.StructPathTBAA)
641 llvm::MDNode *&N = AccessTagMetadataCache[Info];
647 assert(!Info.
Offset &&
"Nonzero offset for an access with no base type!");
649 if (CodeGenOpts.NewStructPathTBAA) {
670 if (!InfoA || !InfoB)
685 if (DestInfo == SrcInfo)
688 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.
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...
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.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
The JSON file list parser is used to communicate input to InstallAPI.
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