Index: cfe/trunk/lib/CodeGen/CGAtomic.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGAtomic.cpp +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp @@ -205,7 +205,7 @@ addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits()); return LValue::MakeAddr(addr, getValueType(), CGF.getContext(), - LVal.getBaseInfo(), LVal.getTBAAAccessType()); + LVal.getBaseInfo(), LVal.getTBAAInfo()); } /// \brief Emits atomic load. @@ -1425,8 +1425,7 @@ // Other decoration. if (IsVolatile) Load->setVolatile(true); - if (LVal.getTBAAAccessType()) - CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAAccessType()); + CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo()); return Load; } @@ -1942,8 +1941,7 @@ // Other decoration. if (IsVolatile) store->setVolatile(true); - if (dest.getTBAAAccessType()) - CGM.DecorateInstructionWithTBAA(store, dest.getTBAAAccessType()); + CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); return; } Index: cfe/trunk/lib/CodeGen/CGClass.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGClass.cpp +++ cfe/trunk/lib/CodeGen/CGClass.cpp @@ -2383,7 +2383,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); @@ -2477,7 +2477,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: cfe/trunk/lib/CodeGen/CGExpr.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -1174,8 +1174,7 @@ llvm::Value *V = LV.getPointer(); Scope.ForceCleanup({&V}); return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(), - getContext(), LV.getBaseInfo(), - LV.getTBAAAccessType()); + getContext(), LV.getBaseInfo(), LV.getTBAAInfo()); } // FIXME: Is it possible to create an ExprWithCleanups that produces a // bitfield lvalue or some other non-simple lvalue? @@ -1514,7 +1513,7 @@ // Atomic operations have to be done on integral types. LValue AtomicLValue = - LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo.AccessType); + LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) { return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal(); } @@ -1525,14 +1524,10 @@ Load->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (TBAAInfo.AccessType) { - bool MayAlias = BaseInfo.getMayAlias(); - llvm::MDNode *TBAA = MayAlias - ? CGM.getTBAAMayAliasTypeInfo() - : CGM.getTBAAStructTagInfo(TBAAInfo); - if (TBAA) - CGM.DecorateInstructionWithTBAA(Load, TBAA, MayAlias); - } + + if (BaseInfo.getMayAlias()) + TBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); if (EmitScalarRangeCheck(Load, Ty, Loc)) { // In order to prevent the optimizer from throwing away the check, don't @@ -1599,7 +1594,7 @@ Value = EmitToMemory(Value, Ty); LValue AtomicLValue = - LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo.AccessType); + LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); if (Ty->isAtomicType() || (!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) { EmitAtomicStore(RValue::get(Value), AtomicLValue, isInit); @@ -1613,14 +1608,10 @@ llvm::ConstantAsMetadata::get(Builder.getInt32(1))); Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (TBAAInfo.AccessType) { - bool MayAlias = BaseInfo.getMayAlias(); - llvm::MDNode *TBAA = MayAlias - ? CGM.getTBAAMayAliasTypeInfo() - : CGM.getTBAAStructTagInfo(TBAAInfo); - if (TBAA) - CGM.DecorateInstructionWithTBAA(Store, TBAA, MayAlias); - } + + if (BaseInfo.getMayAlias()) + TBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); } void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue, @@ -3727,12 +3718,9 @@ // Loading the reference will disable path-aware TBAA. TBAAPath = false; - if (CGM.shouldUseTBAA()) { - llvm::MDNode *tbaa = mayAlias ? CGM.getTBAAMayAliasTypeInfo() : - CGM.getTBAATypeInfo(type); - if (tbaa) - CGM.DecorateInstructionWithTBAA(load, tbaa); - } + TBAAAccessInfo TBAAInfo = mayAlias ? CGM.getTBAAMayAliasAccessInfo() : + CGM.getTBAAAccessInfo(type); + CGM.DecorateInstructionWithTBAA(load, TBAAInfo); mayAlias = false; type = refType->getPointeeType(); @@ -3762,17 +3750,33 @@ LValue LV = MakeAddrLValue(addr, type, FieldBaseInfo); LV.getQuals().addCVRQualifiers(cvr); - if (TBAAPath) { + + // 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.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); + } else if (TBAAPath) { + // 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.getTBAABaseTypeInfo(base.getType()); + assert(!TBAAInfo.Offset && + "Nonzero offset for an access with no base type!"); + } + + // Adjust offset to be relative to the base type. 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. unsigned CharWidth = getContext().getCharWidth(); - TBAAAccessInfo TBAAInfo = mayAlias ? - TBAAAccessInfo(CGM.getTBAAMayAliasTypeInfo()) : - TBAAAccessInfo(base.getTBAAInfo().BaseType, CGM.getTBAATypeInfo(type), - base.getTBAAInfo().Offset + Layout.getFieldOffset( - field->getFieldIndex()) / CharWidth); + if (TBAAInfo.BaseType) + TBAAInfo.Offset += + Layout.getFieldOffset(field->getFieldIndex()) / CharWidth; + + // Update the final access type. + TBAAInfo.AccessType = LV.getTBAAInfo().AccessType; + LV.setTBAAInfo(TBAAInfo); } @@ -3780,12 +3784,6 @@ if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak) LV.getQuals().removeObjCGCAttr(); - // 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.getTBAAAccessType()) - LV.setTBAAAccessType(CGM.getTBAAMayAliasTypeInfo()); - return LV; } Index: cfe/trunk/lib/CodeGen/CGValue.h =================================================================== --- cfe/trunk/lib/CodeGen/CGValue.h +++ cfe/trunk/lib/CodeGen/CGValue.h @@ -232,7 +232,7 @@ private: void Initialize(QualType Type, Qualifiers Quals, CharUnits Alignment, LValueBaseInfo BaseInfo, - llvm::MDNode *TBAAAccessType = nullptr) { + TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); this->Type = Type; @@ -241,7 +241,7 @@ assert(this->Alignment == Alignment.getQuantity() && "Alignment exceeds allowed max!"); this->BaseInfo = BaseInfo; - this->TBAAInfo = TBAAAccessInfo(Type, TBAAAccessType, /* Offset= */ 0); + this->TBAAInfo = TBAAInfo; // Initialize Objective-C flags. this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false; @@ -311,9 +311,6 @@ TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; } void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; } - llvm::MDNode *getTBAAAccessType() const { return TBAAInfo.AccessType; } - void setTBAAAccessType(llvm::MDNode *N) { TBAAInfo.AccessType = N; } - const Qualifiers &getQuals() const { return Quals; } Qualifiers &getQuals() { return Quals; } @@ -370,10 +367,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 *TBAAAccessType = nullptr) { + static LValue MakeAddr(Address address, QualType type, ASTContext &Context, + LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { Qualifiers qs = type.getQualifiers(); qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); @@ -381,7 +376,7 @@ R.LVType = Simple; assert(address.getPointer()->getType()->isPointerTy()); R.V = address.getPointer(); - R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAAccessType); + R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo); return R; } Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1910,14 +1910,14 @@ LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type)) { return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, - CGM.getTBAATypeInfo(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.getTBAATypeInfo(T)); + BaseInfo, CGM.getTBAAAccessInfo(T)); } LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); @@ -3056,7 +3056,14 @@ SourceLocation Loc, LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type), - TBAAAccessInfo TBAAInfo = TBAAAccessInfo(), + 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 @@ -3072,7 +3079,14 @@ bool Volatile, QualType Ty, LValueBaseInfo BaseInfo = LValueBaseInfo(AlignmentSource::Type), - TBAAAccessInfo TBAAInfo = TBAAAccessInfo(), + 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 Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp +++ cfe/trunk/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.getTBAATypeInfo(T)); + CGM.getTBAAAccessInfo(T)); } /// Given a value of type T* that may not be to a complete object, Index: cfe/trunk/lib/CodeGen/CodeGenModule.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.h +++ cfe/trunk/lib/CodeGen/CodeGenModule.h @@ -656,28 +656,36 @@ /// the given type. llvm::MDNode *getTBAATypeInfo(QualType QTy); - llvm::MDNode *getTBAAInfoForVTablePtr(); + /// getTBAAAccessInfo - Get TBAA information that describes an access to + /// an object of the given type. + TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); + + /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an + /// access to a virtual table pointer. + TBAAAccessInfo getTBAAVTablePtrAccessInfo(); + llvm::MDNode *getTBAAStructInfo(QualType QTy); - /// Get path-aware TBAA tag for a given memory access. - llvm::MDNode *getTBAAStructTagInfo(TBAAAccessInfo Info); + /// 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 *getTBAABaseTypeInfo(QualType QTy); + + /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access. + llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info); - /// getTBAAMayAliasTypeInfo - Get TBAA information that represents + /// getTBAAMayAliasAccessInfo - Get TBAA information that represents /// may-alias accesses. - llvm::MDNode *getTBAAMayAliasTypeInfo(); + TBAAAccessInfo getTBAAMayAliasAccessInfo(); 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. + /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag. void DecorateInstructionWithTBAA(llvm::Instruction *Inst, - llvm::MDNode *TBAAInfo, - bool ConvertTypeToTag = true); + TBAAAccessInfo TBAAInfo); /// Adds !invariant.barrier !tag to instruction void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -578,10 +578,14 @@ return TBAA->getTypeInfo(QTy); } -llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() { +TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { + return TBAAAccessInfo(getTBAATypeInfo(AccessType)); +} + +TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo() { if (!TBAA) - return nullptr; - return TBAA->getTBAAInfoForVTablePtr(); + return TBAAAccessInfo(); + return TBAA->getVTablePtrAccessInfo(); } llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { @@ -590,30 +594,28 @@ return TBAA->getTBAAStructInfo(QTy); } -llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(TBAAAccessInfo Info) { +llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) { if (!TBAA) return nullptr; - return TBAA->getTBAAStructTagInfo(Info); + return TBAA->getBaseTypeInfo(QTy); } -llvm::MDNode *CodeGenModule::getTBAAMayAliasTypeInfo() { +llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) { if (!TBAA) return nullptr; - return TBAA->getMayAliasTypeInfo(); + return TBAA->getAccessTagInfo(Info); +} + +TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->getMayAliasAccessInfo(); } -/// 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) { + if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo)) + Inst->setMetadata(llvm::LLVMContext::MD_tbaa, Tag); } void CodeGenModule::DecorateInstructionWithInvariantGroup( Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTBAA.h +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h @@ -32,22 +32,15 @@ namespace CodeGen { 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; -}; - // TBAAAccessInfo - Describes a memory access in terms of TBAA. struct TBAAAccessInfo { - TBAAAccessInfo(QualType BaseType, llvm::MDNode *AccessType, uint64_t Offset) + TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, + uint64_t Offset) : BaseType(BaseType), AccessType(AccessType), Offset(Offset) {} explicit TBAAAccessInfo(llvm::MDNode *AccessType) - : TBAAAccessInfo(/* BaseType= */ QualType(), AccessType, /* Offset= */ 0) + : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0) {} TBAAAccessInfo() @@ -57,7 +50,7 @@ /// 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. - QualType BaseType; + llvm::MDNode *BaseType; /// AccessType - The final access type. May be null if there is no TBAA /// information available about this access. @@ -82,12 +75,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. @@ -127,26 +118,25 @@ /// given type. llvm::MDNode *getTypeInfo(QualType QTy); - /// getTBAAInfoForVTablePtr - Get the TBAA MDNode to be used for a - /// dereference of a vtable pointer. - llvm::MDNode *getTBAAInfoForVTablePtr(); + /// getVTablePtrAccessInfo - Get the TBAA information that describes an + /// access to a virtual table pointer. + TBAAAccessInfo getVTablePtrAccessInfo(); /// getTBAAStructInfo - Get the TBAAStruct MDNode to be used for a memcpy 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 path-aware TBAA tag for a given memory access. - llvm::MDNode *getTBAAStructTagInfo(TBAAAccessInfo Info); + /// 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 *getBaseTypeInfo(QualType QTy); - /// Get the scalar tag MDNode for a given scalar type. - llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode); + /// getAccessTagInfo - Get TBAA tag for a given memory access. + llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); - /// getMayAliasTypeInfo - Get TBAA information that represents may-alias + /// getMayAliasAccessInfo - Get TBAA information that represents may-alias /// accesses. - llvm::MDNode *getMayAliasTypeInfo(); + TBAAAccessInfo getMayAliasAccessInfo(); }; } // end namespace CodeGen @@ -154,31 +144,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: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp @@ -171,8 +171,8 @@ return MetadataCache[Ty] = getChar(); } -llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() { - return createTBAAScalarType("vtable pointer", getRoot()); +TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() { + return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot())); } bool @@ -211,8 +211,8 @@ /* Otherwise, treat whatever it is as a field. */ uint64_t Offset = BaseOffset; uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity(); - llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTypeInfo(QTy); - llvm::MDNode *TBAATag = getTBAAScalarTagInfo(TBAAInfo); + llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy); + llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType)); Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag)); return true; } @@ -232,8 +232,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 isValidBaseType(QualType QTy) { if (const RecordType *TTy = QTy->getAs()) { const RecordDecl *RD = TTy->getDecl()->getDefinition(); if (RD->hasFlexibleArrayMember()) @@ -246,12 +246,12 @@ return false; } -llvm::MDNode * -CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { - const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); - assert(isTBAAPathStruct(QTy)); +llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) { + if (!isValidBaseType(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()) { @@ -263,13 +263,10 @@ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i, ++idx) { QualType FieldQTy = i->getType(); - llvm::MDNode *FieldNode; - if (isTBAAPathStruct(FieldQTy)) - FieldNode = getTBAAStructTypeInfo(FieldQTy); - else - FieldNode = getTypeInfo(FieldQTy); + llvm::MDNode *FieldNode = isValidBaseType(FieldQTy) ? + getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy); if (!FieldNode) - return StructTypeMetadataCache[Ty] = nullptr; + return BaseTypeMetadataCache[Ty] = nullptr; Fields.push_back(std::make_pair( FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth())); } @@ -283,48 +280,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; } -llvm::MDNode *CodeGenTBAA::getTBAAStructTagInfo(TBAAAccessInfo Info) { +llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) { if (!Info.AccessType) return nullptr; if (!CodeGenOpts.StructPathTBAA) - return getTBAAScalarTagInfo(Info.AccessType); + Info = TBAAAccessInfo(Info.AccessType); - const Type *BTy = Context.getCanonicalType(Info.BaseType).getTypePtr(); - TBAAPathTag PathTag = TBAAPathTag(BTy, Info.AccessType, Info.Offset); - if (llvm::MDNode *N = StructTagMetadataCache[PathTag]) + llvm::MDNode *&N = AccessTagMetadataCache[Info]; + if (N) return N; - llvm::MDNode *BNode = nullptr; - if (isTBAAPathStruct(Info.BaseType)) - BNode = getTBAAStructTypeInfo(Info.BaseType); - if (!BNode) - return StructTagMetadataCache[PathTag] = - MDHelper.createTBAAStructTagNode(Info.AccessType, Info.AccessType, - /* Offset= */ 0); - - return StructTagMetadataCache[PathTag] = - MDHelper.createTBAAStructTagNode(BNode, 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); + if (!Info.BaseType) { + Info.BaseType = Info.AccessType; + assert(!Info.Offset && "Nonzero offset for an access with no base type!"); + } + return N = MDHelper.createTBAAStructTagNode(Info.BaseType, Info.AccessType, + Info.Offset); } -llvm::MDNode *CodeGenTBAA::getMayAliasTypeInfo() { - return getChar(); +TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() { + return TBAAAccessInfo(getChar()); }