Index: cfe/trunk/lib/CodeGen/CGExpr.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -1538,8 +1538,6 @@ Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (BaseInfo.getMayAlias()) - TBAAInfo = CGM.getTBAAMayAliasAccessInfo(); CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); if (EmitScalarRangeCheck(Load, Ty, Loc)) { @@ -1622,8 +1620,6 @@ Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); } - if (BaseInfo.getMayAlias()) - TBAAInfo = CGM.getTBAAMayAliasAccessInfo(); CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); } @@ -2170,10 +2166,7 @@ TBAAAccessInfo *PointeeTBAAInfo) { llvm::LoadInst *Load = Builder.CreateLoad(RefLVal.getAddress(), RefLVal.isVolatile()); - TBAAAccessInfo RefTBAAInfo = RefLVal.getTBAAInfo(); - if (RefLVal.getBaseInfo().getMayAlias()) - RefTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); - CGM.DecorateInstructionWithTBAA(Load, RefTBAAInfo); + CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo()); CharUnits Align = getNaturalTypeAlignment(RefLVal.getType()->getPointeeType(), PointeeBaseInfo, PointeeTBAAInfo, @@ -2356,11 +2349,10 @@ LValue CapLVal = EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD), CapturedStmtInfo->getContextValue()); - bool MayAlias = CapLVal.getBaseInfo().getMayAlias(); return MakeAddrLValue( Address(CapLVal.getPointer(), getContext().getDeclAlign(VD)), - CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl, MayAlias), - CGM.getTBAAAccessInfo(CapLVal.getType())); + CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl), + CapLVal.getTBAAInfo()); } assert(isa(CurCodeDecl)); @@ -2504,7 +2496,7 @@ ? emitAddrOfRealComponent(LV.getAddress(), LV.getType()) : emitAddrOfImagComponent(LV.getAddress(), LV.getType())); LValue ElemLV = MakeAddrLValue(Component, T, LV.getBaseInfo(), - CGM.getTBAAAccessInfo(T)); + CGM.getTBAAInfoForSubobject(LV, T)); ElemLV.getQuals().addQualifiers(LV.getQuals()); return ElemLV; } @@ -3242,18 +3234,18 @@ Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true, SignedIndices, E->getExprLoc()); return MakeAddrLValue(Addr, EltType, LV.getBaseInfo(), - CGM.getTBAAAccessInfo(EltType)); + CGM.getTBAAInfoForSubobject(LV, EltType)); } - LValueBaseInfo BaseInfo; - TBAAAccessInfo TBAAInfo; + LValueBaseInfo EltBaseInfo; + TBAAAccessInfo EltTBAAInfo; Address Addr = Address::invalid(); if (const VariableArrayType *vla = getContext().getAsVariableArrayType(E->getType())) { // The base must be a pointer, which is not an aggregate. Emit // it. It needs to be emitted first in case it's what captures // the VLA bounds. - Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo); + Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo); auto *Idx = EmitIdxAfterBase(/*Promote*/true); // The element count here is the total number of non-VLA elements. @@ -3277,7 +3269,7 @@ // Indexing over an interface, as in "NSString *P; P[4];" // Emit the base pointer. - Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo); + Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo); auto *Idx = EmitIdxAfterBase(/*Promote*/true); CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT); @@ -3324,18 +3316,18 @@ *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices, E->getExprLoc()); - BaseInfo = ArrayLV.getBaseInfo(); - TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + EltBaseInfo = ArrayLV.getBaseInfo(); + EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType()); } else { // The base must be a pointer; emit it with an estimate of its alignment. - Addr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo); + Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo); auto *Idx = EmitIdxAfterBase(/*Promote*/true); Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices, E->getExprLoc()); } - LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo, TBAAInfo); + LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo); if (getLangOpts().ObjC1 && getLangOpts().getGC() != LangOptions::NonGC) { @@ -3374,9 +3366,12 @@ return CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(ElTy)); } - LValueBaseInfo TypeInfo; - CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeInfo); - BaseInfo.mergeForCast(TypeInfo); + LValueBaseInfo TypeBaseInfo; + TBAAAccessInfo TypeTBAAInfo; + CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeBaseInfo, + &TypeTBAAInfo); + BaseInfo.mergeForCast(TypeBaseInfo); + TBAAInfo = CGF.CGM.mergeTBAAInfoForCast(TBAAInfo, TypeTBAAInfo); return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress()), Align); } return CGF.EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo); @@ -3522,7 +3517,7 @@ ResultExprTy, !getLangOpts().isSignedOverflowDefined(), /*SignedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); - TBAAInfo = CGM.getTBAAAccessInfo(ResultExprTy); + TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy); } else { Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy, ResultExprTy, @@ -3712,7 +3707,7 @@ QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); // TODO: Support TBAA for bit fields. - LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), false); + LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource()); return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo, TBAAAccessInfo()); } @@ -3723,16 +3718,14 @@ QualType FieldType = field->getType(); const RecordDecl *rec = field->getParent(); AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource(); - LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource), false); + LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource)); TBAAAccessInfo FieldTBAAInfo; - if (BaseInfo.getMayAlias() || rec->hasAttr() || - FieldType->isVectorType()) { - FieldBaseInfo.setMayAlias(true); - FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + if (base.getTBAAInfo().isMayAlias() || + rec->hasAttr() || FieldType->isVectorType()) { + FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo(); } else if (rec->isUnion()) { // TODO: Support TBAA for unions. - FieldBaseInfo.setMayAlias(true); - FieldTBAAInfo = CGM.getTBAAMayAliasAccessInfo(); + FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo(); } else { // If no base type been assigned for the base access, then try to generate // one for this base lvalue. @@ -3818,13 +3811,14 @@ llvm::Type *llvmType = ConvertTypeForMem(FieldType); V = Builder.CreateElementBitCast(V, llvmType, Field->getName()); - // TODO: access-path TBAA? + // TODO: Generate TBAA information that describes this access as a structure + // member access and not just an access to an object of the field's type. This + // should be similar to what we do in EmitLValueForField(). LValueBaseInfo BaseInfo = Base.getBaseInfo(); - LValueBaseInfo FieldBaseInfo( - getFieldAlignmentSource(BaseInfo.getAlignmentSource()), - BaseInfo.getMayAlias()); + AlignmentSource FieldAlignSource = BaseInfo.getAlignmentSource(); + LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(FieldAlignSource)); return MakeAddrLValue(V, FieldType, FieldBaseInfo, - CGM.getTBAAAccessInfo(FieldType)); + CGM.getTBAAInfoForSubobject(Base, FieldType)); } LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){ @@ -3937,11 +3931,10 @@ AlignmentSource alignSource = std::max(lhs->getBaseInfo().getAlignmentSource(), rhs->getBaseInfo().getAlignmentSource()); - bool MayAlias = lhs->getBaseInfo().getMayAlias() || - rhs->getBaseInfo().getMayAlias(); - return MakeAddrLValue(result, expr->getType(), - LValueBaseInfo(alignSource, MayAlias), - CGM.getTBAAAccessInfo(expr->getType())); + TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForConditionalOperator( + lhs->getTBAAInfo(), rhs->getTBAAInfo()); + return MakeAddrLValue(result, expr->getType(), LValueBaseInfo(alignSource), + TBAAInfo); } else { assert((lhs || rhs) && "both operands of glvalue conditional are throw-expressions?"); @@ -4039,8 +4032,11 @@ This, DerivedClassDecl, E->path_begin(), E->path_end(), /*NullCheckValue=*/false, E->getExprLoc()); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. return MakeAddrLValue(Base, E->getType(), LV.getBaseInfo(), - CGM.getTBAAAccessInfo(E->getType())); + CGM.getTBAAInfoForSubobject(LV, E->getType())); } case CK_ToUnion: return EmitAggExprToLValue(E); @@ -4068,7 +4064,7 @@ CFITCK_DerivedCast, E->getLocStart()); return MakeAddrLValue(Derived, E->getType(), LV.getBaseInfo(), - CGM.getTBAAAccessInfo(E->getType())); + CGM.getTBAAInfoForSubobject(LV, E->getType())); } case CK_LValueBitCast: { // This must be a reinterpret_cast (or c-style equivalent). @@ -4085,14 +4081,14 @@ CFITCK_UnrelatedCast, E->getLocStart()); return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(), - CGM.getTBAAAccessInfo(E->getType())); + CGM.getTBAAInfoForSubobject(LV, E->getType())); } case CK_ObjCObjectLValueCast: { LValue LV = EmitLValue(E->getSubExpr()); Address V = Builder.CreateElementBitCast(LV.getAddress(), ConvertType(E->getType())); return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(), - CGM.getTBAAAccessInfo(E->getType())); + CGM.getTBAAInfoForSubobject(LV, E->getType())); } case CK_ZeroToOCLQueue: llvm_unreachable("NULL to OpenCL queue lvalue cast is not valid"); Index: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp +++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp @@ -110,7 +110,7 @@ llvm::Type::getIntNTy(CGF.getLLVMContext(), Info->StorageSize)); return LValue::MakeBitfield(Addr, *Info, IvarTy, - LValueBaseInfo(AlignmentSource::Decl, false), + LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); } Index: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp @@ -993,7 +993,7 @@ CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(), CGF.ConvertTypeForMem(SharedType)), SharedType, SharedAddresses[N].first.getBaseInfo(), - CGF.CGM.getTBAAAccessInfo(SharedType)); + CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType)); if (CGF.getContext().getAsArrayType(PrivateVD->getType())) { emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD); } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) { @@ -1046,7 +1046,7 @@ CGF.Builder.CreateElementBitCast(BaseLV.getAddress(), CGF.ConvertTypeForMem(ElTy)), BaseLV.getType(), BaseLV.getBaseInfo(), - CGF.CGM.getTBAAAccessInfo(BaseLV.getType())); + CGF.CGM.getTBAAInfoForSubobject(BaseLV, BaseLV.getType())); } static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, @@ -4084,9 +4084,8 @@ SharedRefLValue = CGF.MakeAddrLValue( Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)), SharedRefLValue.getType(), - LValueBaseInfo(AlignmentSource::Decl, - SharedRefLValue.getBaseInfo().getMayAlias()), - CGF.CGM.getTBAAAccessInfo(SharedRefLValue.getType())); + LValueBaseInfo(AlignmentSource::Decl), + SharedRefLValue.getTBAAInfo()); QualType Type = OriginalVD->getType(); if (Type->isArrayType()) { // Initialize firstprivate array. Index: cfe/trunk/lib/CodeGen/CGValue.h =================================================================== --- cfe/trunk/lib/CodeGen/CGValue.h +++ cfe/trunk/lib/CodeGen/CGValue.h @@ -149,20 +149,15 @@ class LValueBaseInfo { AlignmentSource AlignSource; - bool MayAlias; public: - explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type, - bool Alias = false) - : AlignSource(Source), MayAlias(Alias) {} + explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type) + : AlignSource(Source) {} AlignmentSource getAlignmentSource() const { return AlignSource; } void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; } - bool getMayAlias() const { return MayAlias; } - void setMayAlias(bool Alias) { MayAlias = Alias; } void mergeForCast(const LValueBaseInfo &Info) { setAlignmentSource(Info.getAlignmentSource()); - setMayAlias(getMayAlias() || Info.getMayAlias()); } }; @@ -426,8 +421,7 @@ R.LVType = GlobalReg; R.V = Reg.getPointer(); R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), - LValueBaseInfo(AlignmentSource::Decl, false), - TBAAAccessInfo()); + LValueBaseInfo(AlignmentSource::Decl), TBAAAccessInfo()); return R; } Index: cfe/trunk/lib/CodeGen/CodeGenFunction.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h @@ -1919,8 +1919,7 @@ LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source = AlignmentSource::Type) { - return LValue::MakeAddr(Addr, T, getContext(), - LValueBaseInfo(Source, false), + return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); } @@ -1932,8 +1931,7 @@ LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source = AlignmentSource::Type) { return LValue::MakeAddr(Address(V, Alignment), T, getContext(), - LValueBaseInfo(Source, false), - CGM.getTBAAAccessInfo(T)); + LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); } LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, @@ -3092,8 +3090,7 @@ SourceLocation Loc, AlignmentSource Source = AlignmentSource::Type, bool isNontemporal = false) { - return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, - LValueBaseInfo(Source, false), + return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source), CGM.getTBAAAccessInfo(Ty), isNontemporal); } @@ -3115,7 +3112,7 @@ bool Volatile, QualType Ty, AlignmentSource Source = AlignmentSource::Type, bool isInit = false, bool isNontemporal = false) { - EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source, false), + EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source), CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); } Index: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp @@ -137,13 +137,13 @@ if (auto TT = T->getAs()) { if (auto Align = TT->getDecl()->getMaxAlignment()) { if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, false); + *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType); return getContext().toCharUnitsFromBits(Align); } } if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::Type, false); + *BaseInfo = LValueBaseInfo(AlignmentSource::Type); CharUnits Alignment; if (T->isIncompleteType()) { Index: cfe/trunk/lib/CodeGen/CodeGenModule.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.h +++ cfe/trunk/lib/CodeGen/CodeGenModule.h @@ -673,15 +673,24 @@ /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access. llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info); - /// getTBAAMayAliasAccessInfo - Get TBAA information that represents - /// may-alias accesses. - TBAAAccessInfo getTBAAMayAliasAccessInfo(); - /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of /// type casts. TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo); + /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the + /// purposes of conditional operator. + TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB); + + /// getTBAAInfoForSubobject - Get TBAA information for an access with a given + /// base lvalue. + TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) { + if (Base.getTBAAInfo().isMayAlias()) + return TBAAAccessInfo::getMayAliasInfo(); + return getTBAAAccessInfo(AccessType); + } + bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); bool isPaddedAtomicType(QualType type); Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -606,17 +606,19 @@ return TBAA->getAccessTagInfo(Info); } -TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() { +TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { if (!TBAA) return TBAAAccessInfo(); - return TBAA->getMayAliasAccessInfo(); + return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo); } -TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, - TBAAAccessInfo TargetInfo) { +TBAAAccessInfo +CodeGenModule::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB) { if (!TBAA) return TBAAAccessInfo(); - return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo); + return TBAA->mergeTBAAInfoForConditionalOperator(InfoA, InfoB); } void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst, Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.h =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTBAA.h +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h @@ -32,11 +32,22 @@ namespace CodeGen { class CGRecordLayout; +// TBAAAccessKind - A kind of TBAA memory access descriptor. +enum class TBAAAccessKind : unsigned { + Ordinary, + MayAlias, +}; + // TBAAAccessInfo - Describes a memory access in terms of TBAA. struct TBAAAccessInfo { + TBAAAccessInfo(TBAAAccessKind Kind, llvm::MDNode *BaseType, + llvm::MDNode *AccessType, uint64_t Offset) + : Kind(Kind), BaseType(BaseType), AccessType(AccessType), Offset(Offset) + {} + TBAAAccessInfo(llvm::MDNode *BaseType, llvm::MDNode *AccessType, uint64_t Offset) - : BaseType(BaseType), AccessType(AccessType), Offset(Offset) + : TBAAAccessInfo(TBAAAccessKind::Ordinary, BaseType, AccessType, Offset) {} explicit TBAAAccessInfo(llvm::MDNode *AccessType) @@ -47,12 +58,31 @@ : TBAAAccessInfo(/* AccessType= */ nullptr) {} + static TBAAAccessInfo getMayAliasInfo() { + return TBAAAccessInfo(TBAAAccessKind::MayAlias, /* BaseType= */ nullptr, + /* AccessType= */ nullptr, /* Offset= */ 0); + } + + bool isMayAlias() const { return Kind == TBAAAccessKind::MayAlias; } + bool operator==(const TBAAAccessInfo &Other) const { - return BaseType == Other.BaseType && + return Kind == Other.Kind && + BaseType == Other.BaseType && AccessType == Other.AccessType && Offset == Other.Offset; } + bool operator!=(const TBAAAccessInfo &Other) const { + return !(*this == Other); + } + + explicit operator bool() const { + return *this != TBAAAccessInfo(); + } + + /// Kind - The kind of the access descriptor. + TBAAAccessKind Kind; + /// 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. @@ -139,14 +169,15 @@ /// getAccessTagInfo - Get TBAA tag for a given memory access. llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info); - /// getMayAliasAccessInfo - Get TBAA information that represents may-alias - /// accesses. - TBAAAccessInfo getMayAliasAccessInfo(); - /// mergeTBAAInfoForCast - Get merged TBAA information for the purpose of /// type casts. TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo); + + /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the + /// purpose of conditional operator. + TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB); }; } // end namespace CodeGen @@ -156,30 +187,34 @@ template<> struct DenseMapInfo { static clang::CodeGen::TBAAAccessInfo getEmptyKey() { + unsigned UnsignedKey = DenseMapInfo::getEmptyKey(); return clang::CodeGen::TBAAAccessInfo( + static_cast(UnsignedKey), DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey()); } static clang::CodeGen::TBAAAccessInfo getTombstoneKey() { + unsigned UnsignedKey = DenseMapInfo::getTombstoneKey(); return clang::CodeGen::TBAAAccessInfo( + static_cast(UnsignedKey), DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey()); } static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) { - return DenseMapInfo::getHashValue(Val.BaseType) ^ + auto KindValue = static_cast(Val.Kind); + return DenseMapInfo::getHashValue(KindValue) ^ + DenseMapInfo::getHashValue(Val.BaseType) ^ DenseMapInfo::getHashValue(Val.AccessType) ^ DenseMapInfo::getHashValue(Val.Offset); } 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; + return LHS == RHS; } }; Index: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp +++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp @@ -88,6 +88,25 @@ return false; } +/// Check if the given type is a valid base type to be used in access tags. +static bool isValidBaseType(QualType QTy) { + if (QTy->isReferenceType()) + return false; + if (const RecordType *TTy = QTy->getAs()) { + const RecordDecl *RD = TTy->getDecl()->getDefinition(); + // Incomplete types are not valid base access types. + if (!RD) + return false; + if (RD->hasFlexibleArrayMember()) + return false; + // RD can be struct, union, class, interface or enum. + // For now, we only handle struct and class. + if (RD->isStruct() || RD->isClass()) + return true; + } + return false; +} + llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) @@ -98,8 +117,16 @@ if (TypeHasMayAlias(QTy)) return getChar(); - const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); + // We need this function to not fall back to returning the "omnipotent char" + // type node for aggregate and union types. Otherwise, any dereference of an + // aggregate will result into the may-alias access descriptor, meaning all + // subsequent accesses to direct and indirect members of that aggregate will + // be considered may-alias too. + // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function. + if (isValidBaseType(QTy)) + return getBaseTypeInfo(QTy); + const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); if (llvm::MDNode *N = MetadataCache[Ty]) return N; @@ -232,20 +259,6 @@ return StructMetadataCache[Ty] = nullptr; } -/// 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()) - return false; - // RD can be struct, union, class, interface or enum. - // For now, we only handle struct and class. - if (RD->isStruct() || RD->isClass()) - return true; - } - return false; -} - llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) { if (!isValidBaseType(QTy)) return nullptr; @@ -288,6 +301,9 @@ } llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) { + if (Info.isMayAlias()) + Info = TBAAAccessInfo(getChar()); + if (!Info.AccessType) return nullptr; @@ -306,14 +322,27 @@ Info.Offset); } -TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() { - return TBAAAccessInfo(getChar()); -} - TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo) { - TBAAAccessInfo MayAliasInfo = getMayAliasAccessInfo(); - if (SourceInfo == MayAliasInfo || TargetInfo == MayAliasInfo) - return MayAliasInfo; + if (SourceInfo.isMayAlias() || TargetInfo.isMayAlias()) + return TBAAAccessInfo::getMayAliasInfo(); return TargetInfo; } + +TBAAAccessInfo +CodeGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB) { + if (InfoA == InfoB) + return InfoA; + + if (!InfoA || !InfoB) + return TBAAAccessInfo(); + + if (InfoA.isMayAlias() || InfoB.isMayAlias()) + return TBAAAccessInfo::getMayAliasInfo(); + + // TODO: Implement the rest of the logic here. For example, two accesses + // with same final access types result in an access to an object of that final + // access type regardless of their base types. + return TBAAAccessInfo::getMayAliasInfo(); +}