r319012 - [CodeGen] Collect information about sizes of accesses and access types for TBAA
Ivan A. Kosarev via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 27 01:39:29 PST 2017
Author: kosarev
Date: Mon Nov 27 01:39:29 2017
New Revision: 319012
URL: http://llvm.org/viewvc/llvm-project?rev=319012&view=rev
Log:
[CodeGen] Collect information about sizes of accesses and access types for TBAA
The information about access and type sizes is necessary for
producing TBAA metadata in the new size-aware format. With this
patch, D39955 and D39956 in place we should be able to change
CodeGenTBAA::createScalarTypeNode() and
CodeGenTBAA::getBaseTypeInfo() to generate metadata in the new
format under the -new-struct-path-tbaa command-line option. For
now, this new information remains unused.
Differential Revision: https://reviews.llvm.org/D40176
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
cfe/trunk/lib/CodeGen/CodeGenTBAA.h
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=319012&r1=319011&r2=319012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Mon Nov 27 01:39:29 2017
@@ -2423,7 +2423,8 @@ void CodeGenFunction::InitializeVTablePo
VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
- CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAVTablePtrAccessInfo());
+ TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy);
+ CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
CGM.getCodeGenOpts().StrictVTablePointers)
CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass);
@@ -2517,7 +2518,8 @@ llvm::Value *CodeGenFunction::GetVTableP
const CXXRecordDecl *RD) {
Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy);
llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable");
- CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAVTablePtrAccessInfo());
+ TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy);
+ CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
CGM.getCodeGenOpts().StrictVTablePointers)
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=319012&r1=319011&r2=319012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Nov 27 01:39:29 2017
@@ -136,7 +136,7 @@ CodeGenModule::CodeGenModule(ASTContext
// Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
if (LangOpts.Sanitize.has(SanitizerKind::Thread) ||
(!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
- TBAA.reset(new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
+ TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(),
getCXXABI().getMangleContext()));
// If debug info or coverage generation is enabled, create the CGDebugInfo
@@ -579,13 +579,20 @@ llvm::MDNode *CodeGenModule::getTBAAType
}
TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) {
- return TBAAAccessInfo(getTBAATypeInfo(AccessType));
+ // Pointee values may have incomplete types, but they shall never be
+ // dereferenced.
+ if (AccessType->isIncompleteType())
+ return TBAAAccessInfo::getIncompleteInfo();
+
+ uint64_t Size = Context.getTypeSizeInChars(AccessType).getQuantity();
+ return TBAAAccessInfo(getTBAATypeInfo(AccessType), Size);
}
-TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo() {
+TBAAAccessInfo
+CodeGenModule::getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType) {
if (!TBAA)
return TBAAAccessInfo();
- return TBAA->getVTablePtrAccessInfo();
+ return TBAA->getVTablePtrAccessInfo(VTablePtrType);
}
llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) {
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=319012&r1=319011&r2=319012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Nov 27 01:39:29 2017
@@ -664,7 +664,7 @@ public:
/// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an
/// access to a virtual table pointer.
- TBAAAccessInfo getTBAAVTablePtrAccessInfo();
+ TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType);
llvm::MDNode *getTBAAStructInfo(QualType QTy);
Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp?rev=319012&r1=319011&r2=319012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp Mon Nov 27 01:39:29 2017
@@ -25,16 +25,18 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
using namespace clang;
using namespace CodeGen;
-CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext,
+CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M,
const CodeGenOptions &CGO,
const LangOptions &Features, MangleContext &MContext)
- : Context(Ctx), CodeGenOpts(CGO), Features(Features), MContext(MContext),
- MDHelper(VMContext), Root(nullptr), Char(nullptr) {
-}
+ : Context(Ctx), Module(M), CodeGenOpts(CGO),
+ Features(Features), MContext(MContext), MDHelper(M.getContext()),
+ Root(nullptr), Char(nullptr)
+{}
CodeGenTBAA::~CodeGenTBAA() {
}
@@ -54,10 +56,10 @@ llvm::MDNode *CodeGenTBAA::getRoot() {
return Root;
}
-// For both scalar TBAA and struct-path aware TBAA, the scalar type has the
-// same format: name, parent node, and offset.
-llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name,
- llvm::MDNode *Parent) {
+llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
+ llvm::MDNode *Parent,
+ uint64_t Size) {
+ (void)Size; // TODO: Support generation of size-aware type nodes.
return MDHelper.createTBAAScalarTypeNode(Name, Parent);
}
@@ -67,7 +69,7 @@ llvm::MDNode *CodeGenTBAA::getChar() {
// these special powers only cover user-accessible memory, and doesn't
// include things like vtables.
if (!Char)
- Char = createTBAAScalarType("omnipotent char", getRoot());
+ Char = createScalarTypeNode("omnipotent char", getRoot(), /* Size= */ 1);
return Char;
}
@@ -108,6 +110,8 @@ static bool isValidBaseType(QualType QTy
}
llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
+ uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
+
// Handle builtin types.
if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
switch (BTy->getKind()) {
@@ -138,7 +142,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHe
// treating wchar_t, char16_t, and char32_t as distinct from their
// "underlying types".
default:
- return createTBAAScalarType(BTy->getName(Features), getChar());
+ return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
}
}
@@ -152,7 +156,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHe
// TODO: Implement C++'s type "similarity" and consider dis-"similar"
// pointers distinct.
if (Ty->isPointerType() || Ty->isReferenceType())
- return createTBAAScalarType("any pointer", getChar());
+ return createScalarTypeNode("any pointer", getChar(), Size);
// Enum types are distinct types. In C++ they have "underlying types",
// however they aren't related for TBAA.
@@ -167,7 +171,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHe
SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
MContext.mangleTypeName(QualType(ETy, 0), Out);
- return createTBAAScalarType(OutName, getChar());
+ return createScalarTypeNode(OutName, getChar(), Size);
}
// For now, handle any other kind of type conservatively.
@@ -204,8 +208,11 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(Q
return MetadataCache[Ty] = TypeNode;
}
-TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() {
- return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot()));
+TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) {
+ llvm::DataLayout DL(&Module);
+ unsigned Size = DL.getPointerTypeSize(VTablePtrType);
+ return TBAAAccessInfo(createScalarTypeNode("vtable pointer", getRoot(), Size),
+ Size);
}
bool
@@ -245,7 +252,7 @@ CodeGenTBAA::CollectFields(uint64_t Base
uint64_t Offset = BaseOffset;
uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy);
- llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType));
+ llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size));
Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
return true;
}
@@ -268,19 +275,20 @@ CodeGenTBAA::getTBAAStructInfo(QualType
llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
if (auto *TTy = dyn_cast<RecordType>(Ty)) {
const RecordDecl *RD = TTy->getDecl()->getDefinition();
-
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- SmallVector <std::pair<llvm::MDNode*, uint64_t>, 4> Fields;
- unsigned idx = 0;
- for (RecordDecl::field_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i, ++idx) {
- QualType FieldQTy = i->getType();
- llvm::MDNode *FieldNode = isValidBaseType(FieldQTy) ?
+ SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields;
+ for (FieldDecl *Field : RD->fields()) {
+ QualType FieldQTy = Field->getType();
+ llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ?
getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
- if (!FieldNode)
+ if (!TypeNode)
return BaseTypeMetadataCache[Ty] = nullptr;
- Fields.push_back(std::make_pair(
- FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth()));
+
+ uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex());
+ uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
+ uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity();
+ Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
+ TypeNode));
}
SmallString<256> OutName;
@@ -291,8 +299,15 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeIn
} else {
OutName = RD->getName();
}
+
+ // TODO: Support size-aware type nodes and create one here for the
+ // given aggregate type.
+
// Create the struct type node with a vector of pairs (offset, type).
- return MDHelper.createTBAAStructTypeNode(OutName, Fields);
+ SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes;
+ for (const auto &Field : Fields)
+ OffsetsAndTypes.push_back(std::make_pair(Field.TBAA, Field.Offset));
+ return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
}
return nullptr;
@@ -314,14 +329,16 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeIn
}
llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
+ assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
+
if (Info.isMayAlias())
- Info = TBAAAccessInfo(getChar());
+ Info = TBAAAccessInfo(getChar(), Info.Size);
if (!Info.AccessType)
return nullptr;
if (!CodeGenOpts.StructPathTBAA)
- Info = TBAAAccessInfo(Info.AccessType);
+ Info = TBAAAccessInfo(Info.AccessType, Info.Size);
llvm::MDNode *&N = AccessTagMetadataCache[Info];
if (N)
Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.h?rev=319012&r1=319011&r2=319012&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTBAA.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h Mon Nov 27 01:39:29 2017
@@ -36,40 +36,53 @@ class CGRecordLayout;
enum class TBAAAccessKind : unsigned {
Ordinary,
MayAlias,
+ Incomplete,
};
// TBAAAccessInfo - Describes a memory access in terms of TBAA.
struct TBAAAccessInfo {
TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType,
- llvm::MDNode *AccessType, uint64_t Offset)
- : Kind(Kind), BaseType(BaseType), AccessType(AccessType), Offset(Offset)
+ llvm::MDNode *AccessType, uint64_t Offset, uint64_t Size)
+ : Kind(Kind), BaseType(BaseType), AccessType(AccessType),
+ Offset(Offset), Size(Size)
{}
TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType,
- uint64_t Offset)
- : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, Offset)
+ uint64_t Offset, uint64_t Size)
+ : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType,
+ Offset, Size)
{}
- explicit TBAAAccessInfo(llvm::MDNode *AccessType)
- : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0)
+ explicit TBAAAccessInfo(llvm::MDNode *AccessType, uint64_t Size)
+ : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0, Size)
{}
TBAAAccessInfo()
- : TBAAAccessInfo(/* AccessType= */ nullptr)
+ : TBAAAccessInfo(/* AccessType= */ nullptr, /* Size= */ 0)
{}
static TBAAAccessInfo getMayAliasInfo() {
- return TBAAAccessInfo(TBAAAccessKind::MayAlias, /* BaseType= */ nullptr,
- /* AccessType= */ nullptr, /* Offset= */ 0);
+ return TBAAAccessInfo(TBAAAccessKind::MayAlias,
+ /* BaseType= */ nullptr, /* AccessType= */ nullptr,
+ /* Offset= */ 0, /* Size= */ 0);
}
bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; }
+ static TBAAAccessInfo getIncompleteInfo() {
+ return TBAAAccessInfo(TBAAAccessKind::Incomplete,
+ /* BaseType= */ nullptr, /* AccessType= */ nullptr,
+ /* Offset= */ 0, /* Size= */ 0);
+ }
+
+ bool isIncomplete() const { return Kind == TBAAAccessKind::Incomplete; }
+
bool operator==(const TBAAAccessInfo &Other) const {
return Kind == Other.Kind &&
BaseType == Other.BaseType &&
AccessType == Other.AccessType &&
- Offset == Other.Offset;
+ Offset == Other.Offset &&
+ Size == Other.Size;
}
bool operator!=(const TBAAAccessInfo &Other) const {
@@ -95,12 +108,16 @@ struct TBAAAccessInfo {
/// Offset - The byte offset of the final access within the base one. Must be
/// zero if the base access type is not specified.
uint64_t Offset;
+
+ /// Size - The size of access, in bytes.
+ uint64_t Size;
};
/// CodeGenTBAA - This class organizes the cross-module state that is used
/// while lowering AST types to LLVM types.
class CodeGenTBAA {
ASTContext &Context;
+ llvm::Module &Module;
const CodeGenOptions &CodeGenOpts;
const LangOptions &Features;
MangleContext &MContext;
@@ -138,10 +155,10 @@ class CodeGenTBAA {
SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields,
bool MayAlias);
- /// A wrapper function to create a scalar type. For struct-path aware TBAA,
- /// the scalar type has the same format as the struct type: name, offset,
- /// pointer to another node in the type DAG.
- llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent);
+ /// createScalarTypeNode - A wrapper function to create a metadata node
+ /// describing a scalar type.
+ llvm::MDNode *createScalarTypeNode(StringRef Name, llvm::MDNode *Parent,
+ uint64_t Size);
/// getTypeInfoHelper - An internal helper function to generate metadata used
/// to describe accesses to objects of the given type.
@@ -152,10 +169,8 @@ class CodeGenTBAA {
llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
public:
- CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
- const CodeGenOptions &CGO,
- const LangOptions &Features,
- MangleContext &MContext);
+ CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, const CodeGenOptions &CGO,
+ const LangOptions &Features, MangleContext &MContext);
~CodeGenTBAA();
/// getTypeInfo - Get metadata used to describe accesses to objects of the
@@ -164,7 +179,7 @@ public:
/// getVTablePtrAccessInfo - Get the TBAA information that describes an
/// access to a virtual table pointer.
- TBAAAccessInfo getVTablePtrAccessInfo();
+ TBAAAccessInfo getVTablePtrAccessInfo(llvm::Type *VTablePtrType);
/// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of
/// the given type.
@@ -200,6 +215,7 @@ template<> struct DenseMapInfo<clang::Co
static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
DenseMapInfo<MDNode *>::getEmptyKey(),
DenseMapInfo<MDNode *>::getEmptyKey(),
+ DenseMapInfo<uint64_t>::getEmptyKey(),
DenseMapInfo<uint64_t>::getEmptyKey());
}
@@ -209,6 +225,7 @@ template<> struct DenseMapInfo<clang::Co
static_cast<clang::CodeGen::TBAAAccessKind>(UnsignedKey),
DenseMapInfo<MDNode *>::getTombstoneKey(),
DenseMapInfo<MDNode *>::getTombstoneKey(),
+ DenseMapInfo<uint64_t>::getTombstoneKey(),
DenseMapInfo<uint64_t>::getTombstoneKey());
}
@@ -217,7 +234,8 @@ template<> struct DenseMapInfo<clang::Co
return DenseMapInfo<unsigned>::getHashValue(KindValue) ^
DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^
DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^
- DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
+ DenseMapInfo<uint64_t>::getHashValue(Val.Offset) ^
+ DenseMapInfo<uint64_t>::getHashValue(Val.Size);
}
static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS,
More information about the cfe-commits
mailing list