Index: lib/CodeGen/CGAtomic.cpp =================================================================== --- lib/CodeGen/CGAtomic.cpp +++ lib/CodeGen/CGAtomic.cpp @@ -1425,8 +1425,7 @@ // Other decoration. if (IsVolatile) Load->setVolatile(true); - if (LVal.getTBAAInfo()) - CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo()); + CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo()); return Load; } @@ -1942,8 +1941,7 @@ // Other decoration. if (IsVolatile) store->setVolatile(true); - if (dest.getTBAAInfo()) - CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); + CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); return; } Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -2382,7 +2382,7 @@ VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy); llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); - CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAInfoForVTablePtr()); + CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAVTablePtrAccessInfo()); if (CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCodeGenOpts().StrictVTablePointers) CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass); @@ -2476,7 +2476,7 @@ const CXXRecordDecl *RD) { Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy); llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); - CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAInfoForVTablePtr()); + CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAVTablePtrAccessInfo()); if (CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCodeGenOpts().StrictVTablePointers) Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1362,9 +1362,7 @@ SourceLocation Loc) { return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), lvalue.getType(), Loc, lvalue.getBaseInfo(), - lvalue.getTBAAInfo(), - lvalue.getTBAABaseType(), lvalue.getTBAAOffset(), - lvalue.isNontemporal()); + lvalue.getTBAAInfo(), lvalue.isNontemporal()); } static bool hasBooleanRepresentation(QualType Ty) { @@ -1471,12 +1469,9 @@ } llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, - QualType Ty, - SourceLocation Loc, + QualType Ty, SourceLocation Loc, LValueBaseInfo BaseInfo, - llvm::MDNode *TBAAInfo, - QualType TBAABaseType, - uint64_t TBAAOffset, + TBAAAccessInfo TBAAInfo, bool isNontemporal) { if (!CGM.getCodeGenOpts().PreserveVec3Type) { // For better performance, handle vector loads differently. @@ -1516,14 +1511,8 @@ Load->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (TBAAInfo) { - bool MayAlias = BaseInfo.getMayAlias(); - llvm::MDNode *TBAA = MayAlias - ? CGM.getTBAAInfo(getContext().CharTy) - : CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset); - if (TBAA) - CGM.DecorateInstructionWithTBAA(Load, TBAA, MayAlias); - } + + CGM.DecorateInstructionWithTBAA(Load, TBAAInfo, BaseInfo.getMayAlias()); if (EmitScalarRangeCheck(Load, Ty, Loc)) { // In order to prevent the optimizer from throwing away the check, don't @@ -1563,11 +1552,8 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, - llvm::MDNode *TBAAInfo, - bool isInit, QualType TBAABaseType, - uint64_t TBAAOffset, - bool isNontemporal) { - + TBAAAccessInfo TBAAInfo, + bool isInit, bool isNontemporal) { if (!CGM.getCodeGenOpts().PreserveVec3Type) { // Handle vectors differently to get better performance. if (Ty->isVectorType()) { @@ -1607,22 +1593,15 @@ llvm::ConstantAsMetadata::get(Builder.getInt32(1))); Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (TBAAInfo) { - bool MayAlias = BaseInfo.getMayAlias(); - llvm::MDNode *TBAA = MayAlias - ? CGM.getTBAAInfo(getContext().CharTy) - : CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo, TBAAOffset); - if (TBAA) - CGM.DecorateInstructionWithTBAA(Store, TBAA, MayAlias); - } + + CGM.DecorateInstructionWithTBAA(Store, TBAAInfo, BaseInfo.getMayAlias()); } void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit) { EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), lvalue.getType(), lvalue.getBaseInfo(), - lvalue.getTBAAInfo(), isInit, lvalue.getTBAABaseType(), - lvalue.getTBAAOffset(), lvalue.isNontemporal()); + lvalue.getTBAAInfo(), isInit, lvalue.isNontemporal()); } /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this @@ -3719,15 +3698,9 @@ // Loading the reference will disable path-aware TBAA. TBAAPath = false; - if (CGM.shouldUseTBAA()) { - llvm::MDNode *tbaa; - if (mayAlias) - tbaa = CGM.getTBAAInfo(getContext().CharTy); - else - tbaa = CGM.getTBAAInfo(type); - if (tbaa) - CGM.DecorateInstructionWithTBAA(load, tbaa); - } + if (CGM.shouldUseTBAA()) + CGM.DecorateInstructionWithTBAA(load, CGM.getTBAAAccessInfo(type), + mayAlias); mayAlias = false; type = refType->getPointeeType(); @@ -3760,12 +3733,26 @@ if (TBAAPath) { const ASTRecordLayout &Layout = getContext().getASTRecordLayout(field->getParent()); - // Set the base type to be the base type of the base LValue and - // update offset to be relative to the base type. - LV.setTBAABaseType(mayAlias ? getContext().CharTy : base.getTBAABaseType()); - LV.setTBAAOffset(mayAlias ? 0 : base.getTBAAOffset() + - Layout.getFieldOffset(field->getFieldIndex()) / - getContext().getCharWidth()); + + // If no base type been assigned for the base access, then try to generate + // one for this base lvalue. + TBAAAccessInfo TBAAInfo = base.getTBAAInfo(); + if (!TBAAInfo.BaseType) { + TBAAInfo.BaseType = CGM.getTBAABaseTypeMetadata(base.getType()); + assert(!TBAAInfo.Offset && + "Nonzero offset for an access with no base type!"); + } + + // Adjust offset to be relative to the base type. + unsigned ByteSizeInBits = getContext().getCharWidth(); + if (TBAAInfo.BaseType) + TBAAInfo.Offset += + Layout.getFieldOffset(field->getFieldIndex()) / ByteSizeInBits; + + // Update the final access type. + TBAAInfo.AccessType = LV.getTBAAInfo().AccessType; + + LV.setTBAAInfo(TBAAInfo); } // __weak attribute on a field is ignored. @@ -3775,8 +3762,8 @@ // Fields of may_alias structs act like 'char' for TBAA purposes. // FIXME: this should get propagated down through anonymous structs // and unions. - if (mayAlias && LV.getTBAAInfo()) - LV.setTBAAInfo(CGM.getTBAAInfo(getContext().CharTy)); + if (mayAlias) + LV.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); return LV; } Index: lib/CodeGen/CGExprAgg.cpp =================================================================== --- lib/CodeGen/CGExprAgg.cpp +++ lib/CodeGen/CGExprAgg.cpp @@ -1655,6 +1655,6 @@ // 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. - if (llvm::MDNode *TBAAStructTag = CGM.getTBAAStructInfo(Ty)) + if (llvm::MDNode *TBAAStructTag = CGM.getTBAAStructMetadata(Ty)) Inst->setMetadata(llvm::LLVMContext::MD_tbaa_struct, TBAAStructTag); } Index: lib/CodeGen/CGValue.h =================================================================== --- lib/CodeGen/CGValue.h +++ lib/CodeGen/CGValue.h @@ -20,6 +20,7 @@ #include "llvm/IR/Value.h" #include "llvm/IR/Type.h" #include "Address.h" +#include "CodeGenTBAA.h" namespace llvm { class Constant; @@ -227,18 +228,13 @@ Expr *BaseIvarExp; - /// Used by struct-path-aware TBAA. - QualType TBAABaseType; - /// Offset relative to the base type. - uint64_t TBAAOffset; - - /// TBAAInfo - TBAA information to attach to dereferences of this LValue. - llvm::MDNode *TBAAInfo; + /// TBAAInfo - TBAA information associated with this LValue. + TBAAAccessInfo TBAAInfo; private: void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment, LValueBaseInfo BaseInfo, - llvm::MDNode *TBAAInfo = nullptr) { + TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); this->Type = Type; @@ -247,6 +243,7 @@ assert(this->Alignment == Alignment.getQuantity() && "Alignment exceeds allowed max!"); this->BaseInfo = BaseInfo; + this->TBAAInfo = TBAAInfo; // Initialize Objective-C flags. this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; @@ -254,11 +251,6 @@ this->Nontemporal = false; this->ThreadLocalRef = false; this->BaseIvarExp = nullptr; - - // Initialize fields for TBAA. - this->TBAABaseType = Type; - this->TBAAOffset = 0; - this->TBAAInfo = TBAAInfo; } public: @@ -314,18 +306,12 @@ bool isVolatile() const { return Quals.hasVolatile(); } - + Expr *getBaseIvarExp() const { return BaseIvarExp; } void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } - QualType getTBAABaseType() const { return TBAABaseType; } - void setTBAABaseType(QualType T) { TBAABaseType = T; } - - uint64_t getTBAAOffset() const { return TBAAOffset; } - void setTBAAOffset(uint64_t O) { TBAAOffset = O; } - - llvm::MDNode *getTBAAInfo() const { return TBAAInfo; } - void setTBAAInfo(llvm::MDNode *N) { TBAAInfo = N; } + TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; } + void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; } const Qualifiers &getQuals() const { return Quals; } Qualifiers &getQuals() { return Quals; } @@ -383,10 +369,8 @@ // global register lvalue llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; } - static LValue MakeAddr(Address address, QualType type, - ASTContext &Context, - LValueBaseInfo BaseInfo, - llvm::MDNode *TBAAInfo = nullptr) { + static LValue MakeAddr(Address address, QualType type, ASTContext &Context, + LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { Qualifiers qs = type.getQualifiers(); qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -1900,14 +1900,14 @@ LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type)) { return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, - CGM.getTBAAInfo(T)); + CGM.getTBAAAccessInfo(T)); } LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type)) { return LValue::MakeAddr(Address(V, Alignment), T, getContext(), - BaseInfo, CGM.getTBAAInfo(T)); + BaseInfo, CGM.getTBAAAccessInfo(T)); } LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); @@ -3037,9 +3037,14 @@ SourceLocation Loc, LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type), - llvm::MDNode *TBAAInfo = nullptr, - QualType TBAABaseTy = QualType(), - uint64_t TBAAOffset = 0, + bool isNontemporal = false) { + return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, BaseInfo, + CGM.getTBAAAccessInfo(Ty), isNontemporal); + } + + llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, + SourceLocation Loc, LValueBaseInfo BaseInfo, + TBAAAccessInfo TBAAInfo, bool isNontemporal = false); /// EmitLoadOfScalar - Load a scalar value from an address, taking @@ -3055,9 +3060,15 @@ bool Volatile, QualType Ty, LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type), - llvm::MDNode *TBAAInfo = nullptr, bool isInit = false, - QualType TBAABaseTy = QualType(), - uint64_t TBAAOffset = 0, bool isNontemporal = false); + bool isInit = false, bool isNontemporal = false) { + EmitStoreOfScalar(Value, Addr, Volatile, Ty, BaseInfo, + CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); + } + + void EmitStoreOfScalar(llvm::Value *Value, Address Addr, + bool Volatile, QualType Ty, + LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, + bool isInit = false, bool isNontemporal = false); /// EmitStoreOfScalar - Store a scalar value to an address, taking /// care to appropriately convert from the memory representation to Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -171,7 +171,7 @@ LValueBaseInfo BaseInfo; CharUnits Alignment = getNaturalTypeAlignment(T, &BaseInfo); return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo, - CGM.getTBAAInfo(T)); + CGM.getTBAAAccessInfo(T)); } /// Given a value of type T* that may not be to a complete object, Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H #include "CGVTables.h" +#include "CodeGenTBAA.h" #include "CodeGenTypeCache.h" #include "CodeGenTypes.h" #include "SanitizerMetadata.h" @@ -649,25 +650,43 @@ CtorList &getGlobalCtors() { return GlobalCtors; } CtorList &getGlobalDtors() { return GlobalDtors; } - llvm::MDNode *getTBAAInfo(QualType QTy); - llvm::MDNode *getTBAAInfoForVTablePtr(); - llvm::MDNode *getTBAAStructInfo(QualType QTy); - /// Return the path-aware tag for given base type, access node and offset. - llvm::MDNode *getTBAAStructTagInfo(QualType BaseTy, llvm::MDNode *AccessN, - uint64_t O); + /// getTBAATypeMetadata - Get metadata used to describe accesses to objects + /// of the given type. + llvm::MDNode *getTBAATypeMetadata(QualType QTy); + + /// getTBAABaseTypeMetadata - Get metadata that describes the given base + /// access type. Return null if the type is not suitable for use in TBAA + /// access tags. + llvm::MDNode *getTBAABaseTypeMetadata(QualType QTy); + + /// getTBAAAccessMetadata - Get TBAA metadata for a given access descriptor. + llvm::MDNode *getTBAAAccessMetadata(TBAAAccessInfo TBAAInfo); + + /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an + /// access to a virtual table pointer. + TBAAAccessInfo getTBAAVTablePtrAccessInfo(); + + /// getTBAAMayAliasAccessInfo - Get TBAA information that represents + /// may-alias accesses. + TBAAAccessInfo getTBAAMayAliasAccessInfo(); + + /// getTBAAAccessInfo - Get TBAA information that describes an accesses to + /// an object of the given type. + TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); + + /// getTBAAStructMetadata - Get "tbaa.struct" metadata used to describe + /// accesses to aggregates and unions. + llvm::MDNode *getTBAAStructMetadata(QualType QTy); bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); bool isPaddedAtomicType(QualType type); bool isPaddedAtomicType(const AtomicType *type); - /// Decorate the instruction with a TBAA tag. For scalar TBAA, the tag - /// is the same as the type. For struct-path aware TBAA, the tag - /// is different from the type: base type, access type and offset. - /// When ConvertTypeToTag is true, we create a tag based on the scalar type. + /// Decorate the instruction with a TBAA access tag. void DecorateInstructionWithTBAA(llvm::Instruction *Inst, - llvm::MDNode *TBAAInfo, - bool ConvertTypeToTag = true); + TBAAAccessInfo TBAAInfo, + bool MayAlias = false); /// Adds !invariant.barrier !tag to instruction void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -23,7 +23,6 @@ #include "CGOpenMPRuntimeNVPTX.h" #include "CodeGenFunction.h" #include "CodeGenPGO.h" -#include "CodeGenTBAA.h" #include "ConstantEmitter.h" #include "CoverageMappingGen.h" #include "TargetInfo.h" @@ -574,44 +573,53 @@ Types.RefreshTypeCacheForClass(RD); } -llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) { +llvm::MDNode *CodeGenModule::getTBAATypeMetadata(QualType QTy) { if (!TBAA) return nullptr; - return TBAA->getTBAAInfo(QTy); + return TBAA->getTypeMetadata(QTy); } -llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() { +TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo() { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->getTBAAVTablePtrAccessInfo(); +} + +llvm::MDNode *CodeGenModule::getTBAAStructMetadata(QualType QTy) { if (!TBAA) return nullptr; - return TBAA->getTBAAInfoForVTablePtr(); + return TBAA->getTBAAStructMetadata(QTy); } -llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { +llvm::MDNode *CodeGenModule::getTBAAAccessMetadata(TBAAAccessInfo TBAAInfo) { if (!TBAA) return nullptr; - return TBAA->getTBAAStructInfo(QTy); + return TBAA->getTBAAAccessMetadata(TBAAInfo); } -llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, - llvm::MDNode *AccessN, - uint64_t O) { +TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->getTBAAMayAliasAccessInfo(); +} + +TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { + return TBAAAccessInfo(getTBAATypeMetadata(AccessType)); +} + +llvm::MDNode *CodeGenModule::getTBAABaseTypeMetadata(QualType QTy) { if (!TBAA) return nullptr; - return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O); + return TBAA->getTBAABaseTypeMetadata(QTy); } -/// Decorate the instruction with a TBAA tag. For both scalar TBAA -/// and struct-path aware TBAA, the tag has the same format: -/// base type, access type and offset. -/// When ConvertTypeToTag is true, we create a tag based on the scalar type. void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst, - llvm::MDNode *TBAAInfo, - bool ConvertTypeToTag) { - if (ConvertTypeToTag && TBAA) - Inst->setMetadata(llvm::LLVMContext::MD_tbaa, - TBAA->getTBAAScalarTagInfo(TBAAInfo)); - else - Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo); + TBAAAccessInfo TBAAInfo, + bool MayAlias) { + if (MayAlias) + TBAAInfo = getTBAAMayAliasAccessInfo(); + if (llvm::MDNode *AccessTag = getTBAAAccessMetadata(TBAAInfo)) + Inst->setMetadata(llvm::LLVMContext::MD_tbaa, AccessTag); } void CodeGenModule::DecorateInstructionWithInvariantGroup( Index: lib/CodeGen/CodeGenTBAA.h =================================================================== --- lib/CodeGen/CodeGenTBAA.h +++ lib/CodeGen/CodeGenTBAA.h @@ -30,15 +30,35 @@ class Type; namespace CodeGen { - class CGRecordLayout; +class CGRecordLayout; - struct TBAAPathTag { - TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O) - : BaseT(B), AccessN(A), Offset(O) {} - const Type *BaseT; - const llvm::MDNode *AccessN; - uint64_t Offset; - }; +struct TBAAAccessInfo { + TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, + uint64_t Offset) + : BaseType(BaseType), AccessType(AccessType), Offset(Offset) + {} + + TBAAAccessInfo(llvm::MDNode *AccessType) + : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0) + {} + + TBAAAccessInfo() + : TBAAAccessInfo(/* AccessType= */ nullptr) + {} + + /// BaseType - The base/leading access type. May be null if this access + /// descriptor represents an access that is not considered to be an access + /// to an aggregate or union member. + llvm::MDNode *BaseType; + + /// AccessType - The final access type. May be null if there is no TBAA + /// information available about this access. + llvm::MDNode *AccessType; + + /// 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; +}; /// CodeGenTBAA - This class organizes the cross-module state that is used /// while lowering AST types to LLVM types. @@ -54,12 +74,10 @@ /// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing /// them. llvm::DenseMap MetadataCache; - /// This maps clang::Types to a struct node in the type DAG. - llvm::DenseMap StructTypeMetadataCache; - /// This maps TBAAPathTags to a tag node. - llvm::DenseMap StructTagMetadataCache; - /// This maps a scalar type to a scalar tag node. - llvm::DenseMap ScalarTagMetadataCache; + /// This maps clang::Types to a base access type in the type DAG. + llvm::DenseMap BaseTypeMetadataCache; + /// This maps TBAA access descriptors to tag nodes. + llvm::DenseMap AccessTagMetadataCache; /// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing /// them for struct assignments. @@ -95,27 +113,29 @@ MangleContext &MContext); ~CodeGenTBAA(); - /// getTBAAInfo - Get the TBAA MDNode to be used for a dereference - /// of the given type. - llvm::MDNode *getTBAAInfo(QualType QTy); - - /// 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 + /// getTypeMetadata - Get metadata used to describe accesses to objects of /// the given type. - llvm::MDNode *getTBAAStructInfo(QualType QTy); - - /// Get the MDNode in the type DAG for given struct type QType. - llvm::MDNode *getTBAAStructTypeInfo(QualType QType); - /// Get the tag MDNode for a given base type, the actual scalar access MDNode - /// and offset into the base type. - llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType, - llvm::MDNode *AccessNode, uint64_t Offset); + llvm::MDNode *getTypeMetadata(QualType QTy); - /// Get the scalar tag MDNode for a given scalar type. - llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode); + /// getTBAABaseTypeMetadata - Get metadata that describes the given base + /// access type. Return null if the type is not suitable for use in TBAA + /// access tags. + llvm::MDNode *getTBAABaseTypeMetadata(QualType QTy); + + /// getTBAAAccessMetadata - Get TBAA metadata for a given access descriptor. + llvm::MDNode *getTBAAAccessMetadata(TBAAAccessInfo Info); + + /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an + /// access to a virtual table pointer. + TBAAAccessInfo getTBAAVTablePtrAccessInfo(); + + /// getTBAAMayAliasAccessInfo - Get TBAA information that represents + /// may-alias accesses. + TBAAAccessInfo getTBAAMayAliasAccessInfo(); + + /// getTBAAStructMetadata - Get "tbaa.struct" metadata used to describe + /// accesses to aggregates and unions. + llvm::MDNode *getTBAAStructMetadata(QualType QTy); }; } // end namespace CodeGen @@ -123,31 +143,31 @@ namespace llvm { -template<> struct DenseMapInfo { - static clang::CodeGen::TBAAPathTag getEmptyKey() { - return clang::CodeGen::TBAAPathTag( - DenseMapInfo::getEmptyKey(), - DenseMapInfo::getEmptyKey(), +template<> struct DenseMapInfo { + static clang::CodeGen::TBAAAccessInfo getEmptyKey() { + return clang::CodeGen::TBAAAccessInfo( + DenseMapInfo::getEmptyKey(), + DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey()); } - static clang::CodeGen::TBAAPathTag getTombstoneKey() { - return clang::CodeGen::TBAAPathTag( - DenseMapInfo::getTombstoneKey(), - DenseMapInfo::getTombstoneKey(), + static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { + return clang::CodeGen::TBAAAccessInfo( + DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey()); } - static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) { - return DenseMapInfo::getHashValue(Val.BaseT) ^ - DenseMapInfo::getHashValue(Val.AccessN) ^ + static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { + return DenseMapInfo::getHashValue(Val.BaseType) ^ + DenseMapInfo::getHashValue(Val.AccessType) ^ DenseMapInfo::getHashValue(Val.Offset); } - static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS, - const clang::CodeGen::TBAAPathTag &RHS) { - return LHS.BaseT == RHS.BaseT && - LHS.AccessN == RHS.AccessN && + static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, + const clang::CodeGen::TBAAAccessInfo &RHS) { + return LHS.BaseType == RHS.BaseType && + LHS.AccessType == RHS.AccessType && LHS.Offset == RHS.Offset; } }; Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -88,8 +88,7 @@ return false; } -llvm::MDNode * -CodeGenTBAA::getTBAAInfo(QualType QTy) { +llvm::MDNode *CodeGenTBAA::getTypeMetadata(QualType QTy) { // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) return nullptr; @@ -120,15 +119,15 @@ // Unsigned types can alias their corresponding signed types. case BuiltinType::UShort: - return getTBAAInfo(Context.ShortTy); + return getTypeMetadata(Context.ShortTy); case BuiltinType::UInt: - return getTBAAInfo(Context.IntTy); + return getTypeMetadata(Context.IntTy); case BuiltinType::ULong: - return getTBAAInfo(Context.LongTy); + return getTypeMetadata(Context.LongTy); case BuiltinType::ULongLong: - return getTBAAInfo(Context.LongLongTy); + return getTypeMetadata(Context.LongLongTy); case BuiltinType::UInt128: - return getTBAAInfo(Context.Int128Ty); + return getTypeMetadata(Context.Int128Ty); // Treat all other builtin types as distinct types. This includes // treating wchar_t, char16_t, and char32_t as distinct from their @@ -172,8 +171,8 @@ return MetadataCache[Ty] = getChar(); } -llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { - return createTBAAScalarType("vtable pointer", getRoot()); +TBAAAccessInfo CodeGenTBAA::getTBAAVTablePtrAccessInfo() { + return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot())); } bool @@ -212,14 +211,13 @@ /* 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); - llvm::MDNode *TBAATag = getTBAAScalarTagInfo(TBAAInfo); + llvm::MDNode *AccessType = MayAlias ? getChar() : getTypeMetadata(QTy); + llvm::MDNode *TBAATag = getTBAAAccessMetadata(TBAAAccessInfo(AccessType)); Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); return true; } -llvm::MDNode * -CodeGenTBAA::getTBAAStructInfo(QualType QTy) { +llvm::MDNode *CodeGenTBAA::getTBAAStructMetadata(QualType QTy) { const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); if (llvm::MDNode *N = StructMetadataCache[Ty]) @@ -233,8 +231,8 @@ return StructMetadataCache[Ty] = nullptr; } -/// Check if the given type can be handled by path-aware TBAA. -static bool isTBAAPathStruct(QualType QTy) { +/// Check if the given type is a valid base type to be used in access tags. +static bool isValidTBAABaseType(QualType QTy) { if (const RecordType *TTy = QTy->getAs()) { const RecordDecl *RD = TTy->getDecl()->getDefinition(); if (RD->hasFlexibleArrayMember()) @@ -247,12 +245,12 @@ return false; } -llvm::MDNode * -CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { - const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); - assert(isTBAAPathStruct(QTy)); +llvm::MDNode *CodeGenTBAA::getTBAABaseTypeMetadata(QualType QTy) { + if (!isValidTBAABaseType(QTy)) + return nullptr; - if (llvm::MDNode *N = StructTypeMetadataCache[Ty]) + const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); + if (llvm::MDNode *N = BaseTypeMetadataCache[Ty]) return N; if (const RecordType *TTy = QTy->getAs()) { @@ -265,12 +263,12 @@ e = RD->field_end(); i != e; ++i, ++idx) { QualType FieldQTy = i->getType(); llvm::MDNode *FieldNode; - if (isTBAAPathStruct(FieldQTy)) - FieldNode = getTBAAStructTypeInfo(FieldQTy); + if (isValidTBAABaseType(FieldQTy)) + FieldNode = getTBAABaseTypeMetadata(FieldQTy); else - FieldNode = getTBAAInfo(FieldQTy); + FieldNode = getTypeMetadata(FieldQTy); if (!FieldNode) - return StructTypeMetadataCache[Ty] = nullptr; + return BaseTypeMetadataCache[Ty] = nullptr; Fields.push_back(std::make_pair( FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth())); } @@ -284,46 +282,32 @@ OutName = RD->getName(); } // Create the struct type node with a vector of pairs (offset, type). - return StructTypeMetadataCache[Ty] = + return BaseTypeMetadataCache[Ty] = MDHelper.createTBAAStructTypeNode(OutName, Fields); } - return StructMetadataCache[Ty] = nullptr; + return BaseTypeMetadataCache[Ty] = nullptr; } -/// Return a TBAA tag node for both scalar TBAA and struct-path aware TBAA. -llvm::MDNode * -CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode, - uint64_t Offset) { - if (!AccessNode) +llvm::MDNode *CodeGenTBAA::getTBAAAccessMetadata(TBAAAccessInfo Info) { + if (!Info.AccessType) return nullptr; if (!CodeGenOpts.StructPathTBAA) - return getTBAAScalarTagInfo(AccessNode); + Info = TBAAAccessInfo(Info.AccessType); - const Type *BTy = Context.getCanonicalType(BaseQTy).getTypePtr(); - TBAAPathTag PathTag = TBAAPathTag(BTy, AccessNode, Offset); - if (llvm::MDNode *N = StructTagMetadataCache[PathTag]) + if (llvm::MDNode *N = AccessTagMetadataCache[Info]) return N; - llvm::MDNode *BNode = nullptr; - if (isTBAAPathStruct(BaseQTy)) - BNode = getTBAAStructTypeInfo(BaseQTy); - if (!BNode) - return StructTagMetadataCache[PathTag] = - MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); - - return StructTagMetadataCache[PathTag] = - MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset); + if (!Info.BaseType) { + Info.BaseType = Info.AccessType; + assert(!Info.Offset && "Nonzero offset for an access with no base type!"); + } + return AccessTagMetadataCache[Info] = + MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType, + Info.Offset); } -llvm::MDNode * -CodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) { - if (!AccessNode) - return nullptr; - if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode]) - return N; - - return ScalarTagMetadataCache[AccessNode] = - MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); +TBAAAccessInfo CodeGenTBAA::getTBAAMayAliasAccessInfo() { + return TBAAAccessInfo(getChar()); }