diff options
author | Ivan A. Kosarev <ikosarev@accesssoftek.com> | 2017-11-27 09:39:29 +0000 |
---|---|---|
committer | Ivan A. Kosarev <ikosarev@accesssoftek.com> | 2017-11-27 09:39:29 +0000 |
commit | 4e50e707bfd9aedb6cfda45b4a36089bd2086717 (patch) | |
tree | 273983365df3faa2184c3206f2e8963e6812c916 /clang/lib/CodeGen/CodeGenTBAA.cpp | |
parent | b833bf6ae14f55272c642a5d5200fabb9f29bf69 (diff) | |
download | llvm-4e50e707bfd9aedb6cfda45b4a36089bd2086717.zip llvm-4e50e707bfd9aedb6cfda45b4a36089bd2086717.tar.gz llvm-4e50e707bfd9aedb6cfda45b4a36089bd2086717.tar.bz2 |
[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
llvm-svn: 319012
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.cpp | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index ea66adb..2bc4b8a 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -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::getTypeInfoHelper(const Type *Ty) { // 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::getTypeInfoHelper(const Type *Ty) { // 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::getTypeInfoHelper(const Type *Ty) { 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(QualType QTy) { 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 BaseOffset, 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 QTy) { 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::getBaseTypeInfoHelper(const Type *Ty) { } 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::getBaseTypeInfo(QualType QTy) { } 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) |