13d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman//===--- CodeGenTypes.cpp - TBAA information for LLVM CodeGen -------------===// 23d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// 33d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// The LLVM Compiler Infrastructure 43d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// 53d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// This file is distributed under the University of Illinois Open Source 63d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// License. See LICENSE.TXT for details. 73d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// 83d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman//===----------------------------------------------------------------------===// 93d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// 10565cc44bea707ff3865fbeb731e4790dd9874786Dan Gohman// This is the code that manages TBAA information and defines the TBAA policy 11565cc44bea707ff3865fbeb731e4790dd9874786Dan Gohman// for the optimizer to use. Relevant standards text includes: 12780658af93b996bb58f333905d458b6462262afbDan Gohman// 13780658af93b996bb58f333905d458b6462262afbDan Gohman// C99 6.5p7 14780658af93b996bb58f333905d458b6462262afbDan Gohman// C++ [basic.lval] (p10 in n3126, p15 in some earlier versions) 153d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman// 163d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman//===----------------------------------------------------------------------===// 173d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 183d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman#include "CodeGenTBAA.h" 193d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman#include "clang/AST/ASTContext.h" 202fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h" 2114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne#include "clang/AST/Mangle.h" 222fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/RecordLayout.h" 23c9fe6056e4ce8ffad1ef439fca3318a5faf1c075Kostya Serebryany#include "clang/Frontend/CodeGenOptions.h" 24b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren#include "llvm/ADT/SmallSet.h" 253b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Constants.h" 263b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/LLVMContext.h" 273b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Metadata.h" 283b844ba7d5be205a9b4f5f0b0d1b7978977f4b8cChandler Carruth#include "llvm/IR/Type.h" 293d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohmanusing namespace clang; 303d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohmanusing namespace CodeGen; 313d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 323d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan GohmanCodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext, 33c9fe6056e4ce8ffad1ef439fca3318a5faf1c075Kostya Serebryany const CodeGenOptions &CGO, 340b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman const LangOptions &Features, MangleContext &MContext) 35facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer : Context(Ctx), CodeGenOpts(CGO), Features(Features), MContext(MContext), 362d7cb069fe101da3971a07900ff583380bcac184Duncan Sands MDHelper(VMContext), Root(0), Char(0) { 373d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman} 383d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 393d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan GohmanCodeGenTBAA::~CodeGenTBAA() { 403d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman} 413d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 42224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohmanllvm::MDNode *CodeGenTBAA::getRoot() { 43224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // Define the root of the tree. This identifies the tree, so that 44224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // if our LLVM IR is linked with LLVM IR from a different front-end 45224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // (or a different version of this front-end), their TBAA trees will 46224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // remain distinct, and the optimizer will treat them conservatively. 47224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman if (!Root) 4860c77079d4767133a587c1c9390f2f5fd43fba9fDuncan Sands Root = MDHelper.createTBAARoot("Simple C/C++ TBAA"); 49224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman 50224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman return Root; 51224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman} 52224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman 53ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren// For struct-path aware TBAA, the scalar type has the same format as 54ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren// the struct type: name, offset, pointer to another node in the type DAG. 55ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren// For scalar TBAA, the scalar type is the same as the scalar tag: 56ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren// name and a parent pointer. 57ca835180412eb4382fe4cc97e9374489b9ad3946Manman Renllvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name, 58ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren llvm::MDNode *Parent) { 59ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren if (CodeGenOpts.StructPathTBAA) 6050be9041fcca4d77c09f120e720d75be703b6ea0Manman Ren return MDHelper.createTBAAScalarTypeNode(Name, Parent); 61ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren else 62ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return MDHelper.createTBAANode(Name, Parent); 63ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren} 64ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren 65224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohmanllvm::MDNode *CodeGenTBAA::getChar() { 66224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // Define the root of the tree for user-accessible memory. C and C++ 67224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // give special powers to char and certain similar types. However, 68224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // these special powers only cover user-accessible memory, and doesn't 69224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman // include things like vtables. 70224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman if (!Char) 71ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren Char = createTBAAScalarType("omnipotent char", getRoot()); 72224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman 73224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman return Char; 74224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman} 75224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman 762ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohmanstatic bool TypeHasMayAlias(QualType QTy) { 772ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman // Tagged types have declarations, and therefore may have attributes. 782ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman if (const TagType *TTy = dyn_cast<TagType>(QTy)) 792ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman return TTy->getDecl()->hasAttr<MayAliasAttr>(); 802ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman 812ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman // Typedef types have declarations, and therefore may have attributes. 822ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman if (const TypedefType *TTy = dyn_cast<TypedefType>(QTy)) { 832ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman if (TTy->getDecl()->hasAttr<MayAliasAttr>()) 842ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman return true; 852ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman // Also, their underlying types may have relevant attributes. 862ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman return TypeHasMayAlias(TTy->desugar()); 872ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman } 882ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman 892ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman return false; 902ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman} 912ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman 923d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohmanllvm::MDNode * 933d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan GohmanCodeGenTBAA::getTBAAInfo(QualType QTy) { 94c9fe6056e4ce8ffad1ef439fca3318a5faf1c075Kostya Serebryany // At -O0 TBAA is not emitted for regular types. 95c9fe6056e4ce8ffad1ef439fca3318a5faf1c075Kostya Serebryany if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) 96c9fe6056e4ce8ffad1ef439fca3318a5faf1c075Kostya Serebryany return NULL; 97c9fe6056e4ce8ffad1ef439fca3318a5faf1c075Kostya Serebryany 982ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman // If the type has the may_alias attribute (even on a typedef), it is 992ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman // effectively in the general char alias class. 1002ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman if (TypeHasMayAlias(QTy)) 1012ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman return getChar(); 1022ea7e73361c11f061e00caa8d9e71e84e6dd8554Dan Gohman 103f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); 1043d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 1053d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman if (llvm::MDNode *N = MetadataCache[Ty]) 1063d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman return N; 1073d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 108565cc44bea707ff3865fbeb731e4790dd9874786Dan Gohman // Handle builtin types. 1099af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) { 1103d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman switch (BTy->getKind()) { 1118562348b3d0de524342c1e36ff3cd83f7490bba2Dan Gohman // Character types are special and can alias anything. 1128562348b3d0de524342c1e36ff3cd83f7490bba2Dan Gohman // In C++, this technically only includes "char" and "unsigned char", 1138562348b3d0de524342c1e36ff3cd83f7490bba2Dan Gohman // and not "signed char". In C, it includes all three. For now, 1140a53198149d26a908bd89ca945ee3f12b4acc949Dan Gohman // the risk of exploiting this detail in C++ seems likely to outweigh 1158562348b3d0de524342c1e36ff3cd83f7490bba2Dan Gohman // the benefit. 1163d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman case BuiltinType::Char_U: 1173d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman case BuiltinType::Char_S: 1183d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman case BuiltinType::UChar: 1193d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman case BuiltinType::SChar: 120224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman return getChar(); 1219af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman 1229af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman // Unsigned types can alias their corresponding signed types. 1239af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman case BuiltinType::UShort: 1249af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman return getTBAAInfo(Context.ShortTy); 1259af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman case BuiltinType::UInt: 1269af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman return getTBAAInfo(Context.IntTy); 1279af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman case BuiltinType::ULong: 1289af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman return getTBAAInfo(Context.LongTy); 1299af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman case BuiltinType::ULongLong: 1309af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman return getTBAAInfo(Context.LongLongTy); 1319af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman case BuiltinType::UInt128: 1329af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman return getTBAAInfo(Context.Int128Ty); 1339af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman 1342f8c21d880e64fa13372ce978009b65a49f0040fDan Gohman // Treat all other builtin types as distinct types. This includes 1352f8c21d880e64fa13372ce978009b65a49f0040fDan Gohman // treating wchar_t, char16_t, and char32_t as distinct from their 1362f8c21d880e64fa13372ce978009b65a49f0040fDan Gohman // "underlying types". 1373d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman default: 1383d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman return MetadataCache[Ty] = 139ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren createTBAAScalarType(BTy->getName(Features), getChar()); 1403d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman } 1413d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman } 1423d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman 143565cc44bea707ff3865fbeb731e4790dd9874786Dan Gohman // Handle pointers. 144dc491118b3ad2b35f047df611107b8a069176ce5Dan Gohman // TODO: Implement C++'s type "similarity" and consider dis-"similar" 145dc491118b3ad2b35f047df611107b8a069176ce5Dan Gohman // pointers distinct. 146c1028f45ea061455b144ab42d0311aba5838c29cDan Gohman if (Ty->isPointerType()) 147ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return MetadataCache[Ty] = createTBAAScalarType("any pointer", 148ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren getChar()); 149c1028f45ea061455b144ab42d0311aba5838c29cDan Gohman 1500b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // Enum types are distinct types. In C++ they have "underlying types", 1510b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // however they aren't related for TBAA. 1520b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { 1530b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // In C++ mode, types have linkage, so we can rely on the ODR and 1540b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // on their mangled names, if they're external. 1550b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // TODO: Is there a way to get a program-wide unique name for a 1560b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // decl with local linkage or no linkage? 1571847c718fe61f8e99d77c60ab77c9bf2ad4d77aaEli Friedman if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible()) 158224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman return MetadataCache[Ty] = getChar(); 1590b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman 1600b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // TODO: This is using the RTTI name. Is there a better way to get 1610b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman // a unique string for a type? 162f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> OutName; 163f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola llvm::raw_svector_ostream Out(OutName); 164f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola MContext.mangleCXXRTTIName(QualType(ETy, 0), Out); 165f0be979bddb8baa28e77693a3dc931e487b2a9f2Rafael Espindola Out.flush(); 166ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar()); 1670b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman } 1680b5c4fc2ae3b503c2b1f354bf52b718aa50a6aeeDan Gohman 1699af2f83863eb27840a4eb17abefec906c078d8eaDan Gohman // For now, handle any other kind of type conservatively. 170224d75972a836b06e2ca708d1eafdac6f762c487Dan Gohman return MetadataCache[Ty] = getChar(); 1713d5aff5d3036b0ff09d114857cd2276134b3d8c9Dan Gohman} 1728cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany 1738cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryanyllvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { 174ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return createTBAAScalarType("vtable pointer", getRoot()); 1758cb4a070d491ddd671b049110cc8d0accb08b905Kostya Serebryany} 176b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 177b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohmanbool 178b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan GohmanCodeGenTBAA::CollectFields(uint64_t BaseOffset, 179b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman QualType QTy, 180b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman SmallVectorImpl<llvm::MDBuilder::TBAAStructField> & 181b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman Fields, 182b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman bool MayAlias) { 183b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman /* Things not handled yet include: C++ base classes, bitfields, */ 184b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 185b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (const RecordType *TTy = QTy->getAs<RecordType>()) { 186b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman const RecordDecl *RD = TTy->getDecl()->getDefinition(); 187b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (RD->hasFlexibleArrayMember()) 188b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return false; 189b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 190b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman // TODO: Handle C++ base classes. 191b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (const CXXRecordDecl *Decl = dyn_cast<CXXRecordDecl>(RD)) 192b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (Decl->bases_begin() != Decl->bases_end()) 193b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return false; 194b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 195b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 196b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 197b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman unsigned idx = 0; 198b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman for (RecordDecl::field_iterator i = RD->field_begin(), 199b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman e = RD->field_end(); i != e; ++i, ++idx) { 200b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman uint64_t Offset = BaseOffset + 201b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman Layout.getFieldOffset(idx) / Context.getCharWidth(); 202b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman QualType FieldQTy = i->getType(); 203b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (!CollectFields(Offset, FieldQTy, Fields, 204b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman MayAlias || TypeHasMayAlias(FieldQTy))) 205b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return false; 206b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman } 207b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return true; 208b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman } 209b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 210b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman /* Otherwise, treat whatever it is as a field. */ 211b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman uint64_t Offset = BaseOffset; 212b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); 213b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTBAAInfo(QTy); 214c7f2bfb4a2dcda757619356a28cb633711a6548cManman Ren llvm::MDNode *TBAATag = CodeGenOpts.StructPathTBAA ? 215c7f2bfb4a2dcda757619356a28cb633711a6548cManman Ren getTBAAScalarTagInfo(TBAAInfo) : TBAAInfo; 216c7f2bfb4a2dcda757619356a28cb633711a6548cManman Ren Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); 217b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return true; 218b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman} 219b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 220b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohmanllvm::MDNode * 221b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan GohmanCodeGenTBAA::getTBAAStructInfo(QualType QTy) { 222b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); 223b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 224b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (llvm::MDNode *N = StructMetadataCache[Ty]) 225b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return N; 226b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 227b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields; 228b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman if (CollectFields(0, QTy, Fields, TypeHasMayAlias(QTy))) 229b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return MDHelper.createTBAAStructNode(Fields); 230b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman 231b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman // For now, handle any other kind of type conservatively. 232b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman return StructMetadataCache[Ty] = NULL; 233b22c7dc707cf3770ff3b5e5f11f11fd0aaa06d9bDan Gohman} 234b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 235b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren/// Check if the given type can be handled by path-aware TBAA. 236b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Renstatic bool isTBAAPathStruct(QualType QTy) { 237b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (const RecordType *TTy = QTy->getAs<RecordType>()) { 238b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren const RecordDecl *RD = TTy->getDecl()->getDefinition(); 239c7d77b25a37acad689ae5c318fdf80fde92983f0Manman Ren if (RD->hasFlexibleArrayMember()) 240c7d77b25a37acad689ae5c318fdf80fde92983f0Manman Ren return false; 241b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren // RD can be struct, union, class, interface or enum. 242c7d77b25a37acad689ae5c318fdf80fde92983f0Manman Ren // For now, we only handle struct and class. 243c7d77b25a37acad689ae5c318fdf80fde92983f0Manman Ren if (RD->isStruct() || RD->isClass()) 244b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return true; 245b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren } 246b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return false; 247b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren} 248b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 249b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Renllvm::MDNode * 250b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman RenCodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { 251b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); 252b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren assert(isTBAAPathStruct(QTy)); 253b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 254b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (llvm::MDNode *N = StructTypeMetadataCache[Ty]) 255b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return N; 256b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 257b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (const RecordType *TTy = QTy->getAs<RecordType>()) { 258b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren const RecordDecl *RD = TTy->getDecl()->getDefinition(); 259b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 260b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 26150be9041fcca4d77c09f120e720d75be703b6ea0Manman Ren SmallVector <std::pair<llvm::MDNode*, uint64_t>, 4> Fields; 262b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren unsigned idx = 0; 263b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren for (RecordDecl::field_iterator i = RD->field_begin(), 264b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren e = RD->field_end(); i != e; ++i, ++idx) { 265b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren QualType FieldQTy = i->getType(); 266b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren llvm::MDNode *FieldNode; 267b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (isTBAAPathStruct(FieldQTy)) 268b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren FieldNode = getTBAAStructTypeInfo(FieldQTy); 269ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren else 270b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren FieldNode = getTBAAInfo(FieldQTy); 271b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (!FieldNode) 272b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return StructTypeMetadataCache[Ty] = NULL; 273b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren Fields.push_back(std::make_pair( 27450be9041fcca4d77c09f120e720d75be703b6ea0Manman Ren FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth())); 275b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren } 276b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 277b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren // TODO: This is using the RTTI name. Is there a better way to get 278b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren // a unique string for a type? 279b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren SmallString<256> OutName; 280b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren llvm::raw_svector_ostream Out(OutName); 281b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren MContext.mangleCXXRTTIName(QualType(Ty, 0), Out); 282b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren Out.flush(); 283b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren // Create the struct type node with a vector of pairs (offset, type). 284b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return StructTypeMetadataCache[Ty] = 285b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren MDHelper.createTBAAStructTypeNode(OutName, Fields); 286b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren } 287b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 288b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return StructMetadataCache[Ty] = NULL; 289b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren} 290b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 291b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Renllvm::MDNode * 292b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman RenCodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode, 293b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren uint64_t Offset) { 294b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (!CodeGenOpts.StructPathTBAA) 295b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return AccessNode; 296b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 297b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr(); 298b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset); 299b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (llvm::MDNode *N = StructTagMetadataCache[PathTag]) 300b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return N; 301b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 302b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren llvm::MDNode *BNode = 0; 303b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (isTBAAPathStruct(BaseQTy)) 304b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren BNode = getTBAAStructTypeInfo(BaseQTy); 305b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren if (!BNode) 306ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return StructTagMetadataCache[PathTag] = 307ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); 308b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren 309b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren return StructTagMetadataCache[PathTag] = 310b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset); 311b37a73d5c6a0c8bb1f6e363d3b53980e4fa0ceadManman Ren} 312ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren 313ca835180412eb4382fe4cc97e9374489b9ad3946Manman Renllvm::MDNode * 314ca835180412eb4382fe4cc97e9374489b9ad3946Manman RenCodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) { 315ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode]) 316ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return N; 317ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren 318ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren return ScalarTagMetadataCache[AccessNode] = 319ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); 320ca835180412eb4382fe4cc97e9374489b9ad3946Manman Ren} 321