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 | 22695fcec3b206eec0e04c52a089c8b4c520d24b (patch) | |
tree | 07972f1110fb073ede511d9e524d54e5663777e7 /clang/lib/CodeGen/CodeGenTBAA.cpp | |
parent | 3852b3e1891939f4cc008025494b07894a408707 (diff) | |
download | bcm5719-llvm-22695fcec3b206eec0e04c52a089c8b4c520d24b.tar.gz bcm5719-llvm-22695fcec3b206eec0e04c52a089c8b4c520d24b.zip |
Add basic support for adding !tbaa.struct metadata on llvm.memcpy calls for
struct assignment.
llvm-svn: 164853
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenTBAA.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index bab60afbb7f..d9004a02ae2 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/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; +} |