diff options
author | Dan Gohman <gohman@apple.com> | 2012-09-28 21:58:29 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2012-09-28 21:58:29 +0000 |
commit | b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9b (patch) | |
tree | 229206e36c039731daa063a9a194205dc31f904b /lib/CodeGen | |
parent | 72ab27732ea7a42d756a1e79727f86fbe391b42b (diff) |
Add basic support for adding !tbaa.struct metadata on llvm.memcpy calls for
struct assignment.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164853 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.cpp | 57 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.h | 15 |
5 files changed, 86 insertions, 1 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 48b21d2f85..c9ffc19a8b 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -1362,11 +1362,17 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr, } } } + + // Determine the metadata to describe the position of any padding in this + // memcpy, as well as the TBAA tags for the members of the struct, in case + // the optimizer wishes to expand it in to scalar memory operations. + llvm::MDNode *TBAAStructTag = CGM.getTBAAStructInfo(Ty); Builder.CreateMemCpy(DestPtr, SrcPtr, llvm::ConstantInt::get(IntPtrTy, TypeInfo.first.getQuantity()), - alignment.getQuantity(), isVolatile); + alignment.getQuantity(), isVolatile, + /*TBAATag=*/0, TBAAStructTag); } void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value *loc, diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 0a33e809b3..164031a503 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -202,6 +202,12 @@ llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() { return TBAA->getTBAAInfoForVTablePtr(); } +llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { + if (!TBAA) + return 0; + return TBAA->getTBAAStructInfo(QTy); +} + void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo) { Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 6e81693f7f..3b5e1425bd 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -461,6 +461,7 @@ public: llvm::MDNode *getTBAAInfo(QualType QTy); llvm::MDNode *getTBAAInfoForVTablePtr(); + llvm::MDNode *getTBAAStructInfo(QualType QTy); bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index bab60afbb7..d9004a02ae 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -17,6 +17,7 @@ #include "CodeGenTBAA.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h" #include "clang/AST/Mangle.h" #include "clang/Frontend/CodeGenOptions.h" #include "llvm/LLVMContext.h" @@ -167,3 +168,59 @@ CodeGenTBAA::getTBAAInfo(QualType QTy) { llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { return MDHelper.createTBAANode("vtable pointer", getRoot()); } + +bool +CodeGenTBAA::CollectFields(uint64_t BaseOffset, + QualType QTy, + SmallVectorImpl<llvm::MDBuilder::TBAAStructField> & + Fields, + bool MayAlias) { + /* Things not handled yet include: C++ base classes, bitfields, */ + + if (const RecordType *TTy = QTy->getAs<RecordType>()) { + const RecordDecl *RD = TTy->getDecl()->getDefinition(); + if (RD->hasFlexibleArrayMember()) + return false; + + // TODO: Handle C++ base classes. + if (const CXXRecordDecl *Decl = dyn_cast<CXXRecordDecl>(RD)) + if (Decl->bases_begin() != Decl->bases_end()) + return false; + + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + + unsigned idx = 0; + for (RecordDecl::field_iterator i = RD->field_begin(), + e = RD->field_end(); i != e; ++i, ++idx) { + uint64_t Offset = BaseOffset + + Layout.getFieldOffset(idx) / Context.getCharWidth(); + QualType FieldQTy = i->getType(); + if (!CollectFields(Offset, FieldQTy, Fields, + MayAlias || TypeHasMayAlias(FieldQTy))) + return false; + } + return true; + } + + /* Otherwise, treat whatever it is as a field. */ + uint64_t Offset = BaseOffset; + uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); + llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTBAAInfo(QTy); + Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAAInfo)); + return true; +} + +llvm::MDNode * +CodeGenTBAA::getTBAAStructInfo(QualType QTy) { + const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); + + if (llvm::MDNode *N = StructMetadataCache[Ty]) + return N; + + SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields; + if (CollectFields(0, QTy, Fields, TypeHasMayAlias(QTy))) + return MDHelper.createTBAAStructNode(Fields); + + // For now, handle any other kind of type conservatively. + return StructMetadataCache[Ty] = NULL; +} diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h index c17a5cf03c..eedb996f3e 100644 --- a/lib/CodeGen/CodeGenTBAA.h +++ b/lib/CodeGen/CodeGenTBAA.h @@ -49,6 +49,10 @@ class CodeGenTBAA { /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them. llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache; + /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing + /// them for struct assignments. + llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache; + llvm::MDNode *Root; llvm::MDNode *Char; @@ -60,6 +64,13 @@ class CodeGenTBAA { /// considered to be equivalent to it. llvm::MDNode *getChar(); + /// CollectFields - Collect information about the fields of a type for + /// !tbaa.struct metadata formation. Return false for an unsupported type. + bool CollectFields(uint64_t BaseOffset, + QualType Ty, + SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields, + bool MayAlias); + public: CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext, const CodeGenOptions &CGO, @@ -74,6 +85,10 @@ public: /// getTBAAInfoForVTablePtr - Get the TBAA MDNode to be used for a /// dereference of a vtable pointer. llvm::MDNode *getTBAAInfoForVTablePtr(); + + /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy of + /// the given type. + llvm::MDNode *getTBAAStructInfo(QualType QTy); }; } // end namespace CodeGen |