Index: lib/CodeGen/CGAtomic.cpp =================================================================== --- lib/CodeGen/CGAtomic.cpp +++ lib/CodeGen/CGAtomic.cpp @@ -98,7 +98,6 @@ LVal = LValue::MakeBitfield(Address(Addr, lvalue.getAlignment()), BFI, lvalue.getType(), lvalue.getBaseInfo()); - LVal.setTBAAInfo(lvalue.getTBAAInfo()); AtomicTy = C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned); if (AtomicTy.isNull()) { llvm::APInt Size( @@ -205,7 +204,7 @@ addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits()); return LValue::MakeAddr(addr, getValueType(), CGF.getContext(), - LVal.getBaseInfo(), LVal.getTBAAInfo()); + LVal.getBaseInfo()); } /// \brief Emits atomic load. @@ -1425,8 +1424,7 @@ // Other decoration. if (IsVolatile) Load->setVolatile(true); - if (LVal.getTBAAInfo()) - CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo()); + CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getBaseInfo().getTBAAInfo()); return Load; } @@ -1692,8 +1690,6 @@ DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), AtomicLVal.getBaseInfo()); } - UpdateLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); - DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); UpRVal = CGF.EmitLoadOfLValue(UpdateLVal, SourceLocation()); } // Store new value in the corresponding memory area @@ -1789,7 +1785,6 @@ DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), AtomicLVal.getBaseInfo()); } - DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); // Store new value in the corresponding memory area assert(UpdateRVal.isScalar()); CGF.EmitStoreThroughLValue(UpdateRVal, DesiredLVal); @@ -1942,8 +1937,7 @@ // Other decoration. if (IsVolatile) store->setVolatile(true); - if (dest.getTBAAInfo()) - CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); + CGM.DecorateInstructionWithTBAA(store, dest.getBaseInfo().getTBAAInfo()); return; } Index: lib/CodeGen/CGBlocks.cpp =================================================================== --- lib/CodeGen/CGBlocks.cpp +++ lib/CodeGen/CGBlocks.cpp @@ -918,7 +918,8 @@ // FIXME: Pass a specific location for the expr init so that the store is // attributed to a reasonable location - otherwise it may be attributed to // locations of subexpressions in the initialization. - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(type)); EmitExprAsInit(&l2r, &BlockFieldPseudoVar, MakeAddrLValue(blockField, type, BaseInfo), /*captured by init*/ false); 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 @@ -411,15 +411,17 @@ // ref-counting operations. Therefore we have no need to emit either a // dynamic initialization or a cleanup and we can just return the address // of the temporary. - if (Var->hasInitializer()) - return MakeAddrLValue(Object, M->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + if (Var->hasInitializer()) { + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(M->getType())); + return MakeAddrLValue(Object, M->getType(), BaseInfo); + } Var->setInitializer(CGM.EmitNullConstant(E->getType())); } - LValue RefTempDst = MakeAddrLValue(Object, M->getType(), - LValueBaseInfo(AlignmentSource::Decl, - false)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(M->getType())); + LValue RefTempDst = MakeAddrLValue(Object, M->getType(), BaseInfo); switch (getEvaluationKind(E->getType())) { default: llvm_unreachable("expected scalar or aggregate expression"); @@ -506,8 +508,9 @@ break; case SubobjectAdjustment::FieldAdjustment: { - LValue LV = MakeAddrLValue(Object, E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType())); + LValue LV = MakeAddrLValue(Object, E->getType(), BaseInfo); LV = EmitLValueForField(LV, Adjustment.Field); assert(LV.isSimple() && "materialized temporary field is not a simple lvalue"); @@ -524,8 +527,9 @@ } } - return MakeAddrLValue(Object, M->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(M->getType())); + return MakeAddrLValue(Object, M->getType(), BaseInfo); } RValue @@ -941,7 +945,7 @@ CharUnits Align = getNaturalPointeeTypeAlignment(E->getType(), &ExpInfo); if (BaseInfo) - BaseInfo->mergeForCast(ExpInfo); + BaseInfo->mergeForCast(ExpInfo, CGM); Addr = Address(Addr.getPointer(), Align); } @@ -1161,8 +1165,7 @@ llvm::Value *V = LV.getPointer(); Scope.ForceCleanup({&V}); return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(), - getContext(), LV.getBaseInfo(), - LV.getTBAAInfo()); + getContext(), LV.getBaseInfo()); } // FIXME: Is it possible to create an ExprWithCleanups that produces a // bitfield lvalue or some other non-simple lvalue? @@ -1362,8 +1365,6 @@ SourceLocation Loc) { return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), lvalue.getType(), Loc, lvalue.getBaseInfo(), - lvalue.getTBAAInfo(), - lvalue.getTBAABaseType(), lvalue.getTBAAOffset(), lvalue.isNontemporal()); } @@ -1471,12 +1472,8 @@ } 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, bool isNontemporal) { if (!CGM.getCodeGenOpts().PreserveVec3Type) { // For better performance, handle vector loads differently. @@ -1504,8 +1501,7 @@ } // Atomic operations have to be done on integral types. - LValue AtomicLValue = - LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); + LValue AtomicLValue = LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo); if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) { return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal(); } @@ -1516,14 +1512,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, BaseInfo.getTBAAInfo()); if (EmitScalarRangeCheck(Load, Ty, Loc)) { // In order to prevent the optimizer from throwing away the check, don't @@ -1563,11 +1553,7 @@ 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) { - + bool isInit, bool isNontemporal) { if (!CGM.getCodeGenOpts().PreserveVec3Type) { // Handle vectors differently to get better performance. if (Ty->isVectorType()) { @@ -1592,8 +1578,7 @@ Value = EmitToMemory(Value, Ty); - LValue AtomicLValue = - LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo); + LValue AtomicLValue = LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo); if (Ty->isAtomicType() || (!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) { EmitAtomicStore(RValue::get(Value), AtomicLValue, isInit); @@ -1607,22 +1592,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, BaseInfo.getTBAAInfo()); } 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()); + isInit, lvalue.isNontemporal()); } /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this @@ -2152,7 +2130,8 @@ llvm::Type *RealVarTy, SourceLocation Loc) { Addr = CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc); Addr = CGF.Builder.CreateElementBitCast(Addr, RealVarTy); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGF.CGM.getTBAAAccessInfo(T)); return CGF.MakeAddrLValue(Addr, T, BaseInfo); } @@ -2210,7 +2189,8 @@ if (auto RefTy = VD->getType()->getAs()) { LV = CGF.EmitLoadOfReferenceLValue(Addr, RefTy); } else { - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGF.CGM.getTBAAAccessInfo(T)); LV = CGF.MakeAddrLValue(Addr, T, BaseInfo); } setObjCGCLValueClass(CGF.getContext(), E, LV); @@ -2245,7 +2225,8 @@ const Expr *E, const FunctionDecl *FD) { llvm::Value *V = EmitFunctionDeclPointer(CGF.CGM, FD); CharUnits Alignment = CGF.getContext().getDeclAlign(FD); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGF.CGM.getTBAAAccessInfo(E->getType())); return CGF.MakeAddrLValue(V, E->getType(), Alignment, BaseInfo); } @@ -2313,7 +2294,8 @@ // Should we be using the alignment of the constant pointer we emitted? CharUnits Alignment = getNaturalTypeAlignment(E->getType(), nullptr, /*pointee*/ true); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(T)); return MakeAddrLValue(Address(Val, Alignment), T, BaseInfo); } @@ -2332,15 +2314,17 @@ 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)); + CapLVal.getType(), + LValueBaseInfo(AlignmentSource::Decl, + CapLVal.getBaseInfo().getTBAAInfo())); } assert(isa(CurCodeDecl)); Address addr = GetAddrOfBlockDecl(VD, VD->hasAttr()); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(T)); return MakeAddrLValue(addr, T, BaseInfo); } } @@ -2355,8 +2339,8 @@ if (ND->hasAttr()) { const auto *VD = cast(ND); ConstantAddress Aliasee = CGM.GetWeakRefReference(VD); - return MakeAddrLValue(Aliasee, T, - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, CGM.getTBAAAccessInfo(T)); + return MakeAddrLValue(Aliasee, T, BaseInfo); } if (const auto *VD = dyn_cast(ND)) { @@ -2402,7 +2386,7 @@ if (auto RefTy = VD->getType()->getAs()) { LV = EmitLoadOfReferenceLValue(addr, RefTy); } else { - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, CGM.getTBAAAccessInfo(T)); LV = MakeAddrLValue(addr, T, BaseInfo); } @@ -2501,15 +2485,17 @@ } LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) { + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType())); return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E), - E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + E->getType(), BaseInfo); } LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) { + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType())); return MakeAddrLValue(CGM.GetAddrOfConstantStringFromObjCEncode(E), - E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + E->getType(), BaseInfo); } LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) { @@ -2521,7 +2507,8 @@ StringRef NameItems[] = { PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName}; std::string GVName = llvm::join(NameItems, NameItems + 2, "."); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType())); if (auto *BD = dyn_cast(CurCodeDecl)) { std::string Name = SL->getString(); if (!Name.empty()) { @@ -3212,7 +3199,11 @@ QualType EltType = LV.getType()->castAs()->getElementType(); Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true, SignedIndices, E->getExprLoc()); - return MakeAddrLValue(Addr, EltType, LV.getBaseInfo()); + TBAAAccessInfo TBAAInfo = LV.getBaseInfo().getTBAAInfo(); + if (!CGM.isTBAAMayAliasAccessInfo(TBAAInfo)) + TBAAInfo = CGM.getTBAAAccessInfo(EltType); + LValueBaseInfo BaseInfo(LV.getBaseInfo().getAlignmentSource(), TBAAInfo); + return MakeAddrLValue(Addr, EltType, BaseInfo); } LValueBaseInfo BaseInfo; @@ -3303,9 +3294,12 @@ SignedIndices, E->getExprLoc()); } - LValue LV = MakeAddrLValue(Addr, E->getType(), BaseInfo); - - // TODO: Preserve/extend path TBAA metadata? + // TODO: Propagate TBAA information of the base value. + TBAAAccessInfo TBAAInfo = BaseInfo.getTBAAInfo(); + if (!CGM.isTBAAMayAliasAccessInfo(TBAAInfo)) + TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + LValueBaseInfo EltBaseInfo(BaseInfo.getAlignmentSource(), TBAAInfo); + LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo); if (getLangOpts().ObjC1 && getLangOpts().getGC() != LangOptions::NonGC) { @@ -3345,7 +3339,7 @@ } LValueBaseInfo TypeInfo; CharUnits Align = CGF.getNaturalTypeAlignment(ElTy, &TypeInfo); - BaseInfo.mergeForCast(TypeInfo); + BaseInfo.mergeForCast(TypeInfo, CGF.CGM); return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress()), Align); } return CGF.EmitPointerWithAlignment(Base, &BaseInfo); @@ -3534,8 +3528,9 @@ // Store the vector to memory (because LValue wants an address). Address VecMem = CreateMemTemp(E->getBase()->getType()); Builder.CreateStore(Vec, VecMem); - Base = MakeAddrLValue(VecMem, E->getBase()->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getBase()->getType())); + Base = MakeAddrLValue(VecMem, E->getBase()->getType(), BaseInfo); } QualType type = @@ -3661,15 +3656,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { LValueBaseInfo BaseInfo = base.getBaseInfo(); - AlignmentSource fieldAlignSource = - getFieldAlignmentSource(BaseInfo.getAlignmentSource()); - LValueBaseInfo FieldBaseInfo(fieldAlignSource, BaseInfo.getMayAlias()); - - QualType type = field->getType(); - const RecordDecl *rec = field->getParent(); - if (rec->isUnion() || rec->hasAttr() || type->isVectorType()) - FieldBaseInfo.setMayAlias(true); - bool mayAlias = FieldBaseInfo.getMayAlias(); if (field->isBitField()) { const CGRecordLayout &RL = @@ -3689,18 +3675,53 @@ QualType fieldType = field->getType().withCVRQualifiers(base.getVRQualifiers()); + // TODO: Support TBAA for bit fields. + LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource(), + CGM.getTBAAMayAliasAccessInfo()); return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo); } + // Fields of may-alias structs are may-alias themselves. + // FIXME: this should get propagated down through anonymous structs + // and unions. + QualType type = field->getType(); + const RecordDecl *rec = field->getParent(); + LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource()); + if (CGM.isTBAAMayAliasAccessInfo(BaseInfo.getTBAAInfo()) || + rec->hasAttr() || type->isVectorType()) { + FieldBaseInfo.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); + } else if(rec->isUnion()) { + // TODO: Support TBAA for unions. + FieldBaseInfo.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo()); + } else { + // If no base type been assigned for the base access, then try to generate + // one for this base lvalue. + TBAAAccessInfo TBAAInfo = BaseInfo.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. + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(field->getParent()); + unsigned ByteSizeInBits = getContext().getCharWidth(); + if (TBAAInfo.BaseType) + TBAAInfo.Offset += + Layout.getFieldOffset(field->getFieldIndex()) / ByteSizeInBits; + + // Update the final access type. + TBAAInfo.AccessType = CGM.getTBAATypeMetadata(type); + + FieldBaseInfo.setTBAAInfo(TBAAInfo); + } + Address addr = base.getAddress(); unsigned cvr = base.getVRQualifiers(); - bool TBAAPath = CGM.getCodeGenOpts().StructPathTBAA; if (rec->isUnion()) { // For unions, there is no pointer adjustment. assert(!type->isReferenceType() && "union has reference member"); - // TODO: handle path-aware TBAA for union. - TBAAPath = false; - const auto FieldType = field->getType(); if (CGM.getCodeGenOpts().StrictVTablePointers && hasAnyVptr(FieldType, getContext())) @@ -3716,25 +3737,11 @@ if (const ReferenceType *refType = type->getAs()) { llvm::LoadInst *load = Builder.CreateLoad(addr, "ref"); if (cvr & Qualifiers::Volatile) load->setVolatile(true); + CGM.DecorateInstructionWithTBAA(load, FieldBaseInfo.getTBAAInfo()); - // 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); - } - - mayAlias = false; type = refType->getPointeeType(); - CharUnits alignment = getNaturalTypeAlignment(type, &FieldBaseInfo, /*pointee*/ true); - FieldBaseInfo.setMayAlias(false); addr = Address(load, alignment); // Qualifiers on the struct don't apply to the referencee, and @@ -3757,27 +3764,11 @@ LValue LV = MakeAddrLValue(addr, type, FieldBaseInfo); LV.getQuals().addCVRQualifiers(cvr); - 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()); - } // __weak attribute on a field is ignored. 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.getTBAAInfo()) - LV.setTBAAInfo(CGM.getTBAAInfo(getContext().CharTy)); - return LV; } @@ -3795,16 +3786,17 @@ llvm::Type *llvmType = ConvertTypeForMem(FieldType); V = Builder.CreateElementBitCast(V, llvmType, Field->getName()); - // TODO: access-path TBAA? + // TODO: Propagate TBAA information of the base value. LValueBaseInfo BaseInfo = Base.getBaseInfo(); LValueBaseInfo FieldBaseInfo( getFieldAlignmentSource(BaseInfo.getAlignmentSource()), - BaseInfo.getMayAlias()); + TBAAAccessInfo(CGM.getTBAAAccessInfo(FieldType))); return MakeAddrLValue(V, FieldType, FieldBaseInfo); } LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){ - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType())); if (E->isFileScope()) { ConstantAddress GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E); return MakeAddrLValue(GlobalPtr, E->getType(), BaseInfo); @@ -3914,10 +3906,11 @@ AlignmentSource alignSource = std::max(lhs->getBaseInfo().getAlignmentSource(), rhs->getBaseInfo().getAlignmentSource()); - bool MayAlias = lhs->getBaseInfo().getMayAlias() || - rhs->getBaseInfo().getMayAlias(); + TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForConditionalOperator( + lhs->getBaseInfo().getTBAAInfo(), + rhs->getBaseInfo().getTBAAInfo()); return MakeAddrLValue(result, expr->getType(), - LValueBaseInfo(alignSource, MayAlias)); + LValueBaseInfo(alignSource, TBAAInfo)); } else { assert((lhs || rhs) && "both operands of glvalue conditional are throw-expressions?"); @@ -4253,7 +4246,8 @@ if (!RV.isScalar()) return MakeAddrLValue(RV.getAggregateAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); assert(E->getCallReturnType(getContext())->isReferenceType() && "Can't have a scalar return unless the return type is a " @@ -4273,7 +4267,8 @@ AggValueSlot Slot = CreateAggTemp(E->getType()); EmitCXXConstructExpr(E, Slot); return MakeAddrLValue(Slot.getAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); } LValue @@ -4288,7 +4283,8 @@ LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) { return MakeAddrLValue(EmitCXXUuidofExpr(E), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); } LValue @@ -4298,7 +4294,8 @@ EmitAggExpr(E->getSubExpr(), Slot); EmitCXXTemporary(E->getTemporary(), E->getType(), Slot.getAddress()); return MakeAddrLValue(Slot.getAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); } LValue @@ -4306,7 +4303,8 @@ AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue"); EmitLambdaExpr(E, Slot); return MakeAddrLValue(Slot.getAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); } LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) { @@ -4314,7 +4312,8 @@ if (!RV.isScalar()) return MakeAddrLValue(RV.getAggregateAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); assert(E->getMethodDecl()->getReturnType()->isReferenceType() && "Can't have a scalar return unless the return type is a " @@ -4327,7 +4326,8 @@ Address V = CGM.getObjCRuntime().GetAddrOfSelector(*this, E->getSelector()); return MakeAddrLValue(V, E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); } llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface, @@ -4371,7 +4371,8 @@ // Can only get l-value for message expression returning aggregate type RValue RV = EmitAnyExprToTemp(E); return MakeAddrLValue(RV.getAggregateAddress(), E->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(E->getType()))); } RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee, @@ -4575,7 +4576,8 @@ QualType type, SourceLocation loc) { LValue lvalue = MakeAddrLValue(addr, type, - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(type))); switch (getEvaluationKind(type)) { case TEK_Complex: return RValue::getComplex(EmitLoadOfComplex(lvalue, loc)); @@ -4630,7 +4632,8 @@ if (ov == resultExpr && ov->isRValue() && !forLValue && CodeGenFunction::hasAggregateEvaluationKind(ov->getType())) { CGF.EmitAggExpr(ov->getSourceExpr(), slot); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGF.CGM.getTBAAAccessInfo(ov->getType())); LValue LV = CGF.MakeAddrLValue(slot.getAddress(), ov->getType(), BaseInfo); opaqueData = OVMA::bind(CGF, ov, LV); @@ -4680,3 +4683,10 @@ LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) { return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV; } + +void LValueBaseInfo::mergeForCast(const LValueBaseInfo &TargetTypeInfo, + CodeGenModule &CGM) { + setAlignmentSource(TargetTypeInfo.getAlignmentSource()); + setTBAAInfo(CGM.mergeTBAAInfoForCast(getTBAAInfo(), + TargetTypeInfo.getTBAAInfo())); +} 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/CGObjC.cpp =================================================================== --- lib/CodeGen/CGObjC.cpp +++ lib/CodeGen/CGObjC.cpp @@ -162,19 +162,21 @@ const Expr *Rhs = ALE->getElement(i); LValue LV = MakeAddrLValue( Builder.CreateConstArrayGEP(Objects, i, getPointerSize()), - ElementType, LValueBaseInfo(AlignmentSource::Decl, false)); + ElementType, LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(ElementType))); llvm::Value *value = EmitScalarExpr(Rhs); EmitStoreThroughLValue(RValue::get(value), LV, true); if (TrackNeededObjects) { NeededObjects.push_back(value); } - } else { + } else { // Emit the key and store it to the appropriate array slot. const Expr *Key = DLE->getKeyValueElement(i).Key; LValue KeyLV = MakeAddrLValue( Builder.CreateConstArrayGEP(Keys, i, getPointerSize()), - ElementType, LValueBaseInfo(AlignmentSource::Decl, false)); + ElementType, LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(ElementType))); llvm::Value *keyValue = EmitScalarExpr(Key); EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true); @@ -182,7 +184,8 @@ const Expr *Value = DLE->getKeyValueElement(i).Value; LValue ValueLV = MakeAddrLValue( Builder.CreateConstArrayGEP(Objects, i, getPointerSize()), - ElementType, LValueBaseInfo(AlignmentSource::Decl, false)); + ElementType, LValueBaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(ElementType))); llvm::Value *valueValue = EmitScalarExpr(Value); EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true); if (TrackNeededObjects) { Index: lib/CodeGen/CGObjCRuntime.cpp =================================================================== --- lib/CodeGen/CGObjCRuntime.cpp +++ 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)); } namespace { Index: lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -1140,9 +1140,10 @@ LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue( CodeGenFunction &CGF) { - return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()), - getThreadIDVariable()->getType(), - LValueBaseInfo(AlignmentSource::Decl, false)); + QualType T = getThreadIDVariable()->getType(); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, CGF.CGM.getTBAAAccessInfo(T)); + return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()), T, + BaseInfo); } CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM) @@ -4083,7 +4084,7 @@ Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)), SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl, - SharedRefLValue.getBaseInfo().getMayAlias())); + SharedRefLValue.getBaseInfo().getTBAAInfo())); QualType Type = OriginalVD->getType(); if (Type->isArrayType()) { // Initialize firstprivate array. Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -376,11 +376,14 @@ continue; } - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); - LValue ArgLVal = - CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), BaseInfo); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(Args[Cnt]->getType())); + LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), + BaseInfo); if (FD->hasCapturedVLAType()) { if (FO.UIntPtrCastRequired) { + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(FD->getType())); ArgLVal = CGF.MakeAddrLValue(castValueFromUintptr(CGF, FD->getType(), Args[Cnt]->getName(), ArgLVal), @@ -481,20 +484,23 @@ llvm::Function *WrapperF = emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, WrapperCGF.CXXThisValue, WrapperFO); - LValueBaseInfo BaseInfo(AlignmentSource::Decl, false); llvm::SmallVector CallArgs; for (const auto *Arg : Args) { llvm::Value *CallArg; auto I = LocalAddrs.find(Arg); if (I != LocalAddrs.end()) { - LValue LV = - WrapperCGF.MakeAddrLValue(I->second.second, Arg->getType(), BaseInfo); + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(Arg->getType())); + LValue LV = WrapperCGF.MakeAddrLValue(I->second.second, Arg->getType(), + BaseInfo); CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation()); } else { auto EI = VLASizes.find(Arg); if (EI != VLASizes.end()) CallArg = EI->second.second; else { + LValueBaseInfo BaseInfo(AlignmentSource::Decl, + CGM.getTBAAAccessInfo(Arg->getType())); LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg), Arg->getType(), BaseInfo); CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation()); 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; @@ -30,6 +31,7 @@ namespace CodeGen { class AggValueSlot; struct CGBitFieldInfo; + class CodeGenModule; /// RValue - This trivial value class is used to represent the result of an /// expression that is evaluated. It can be one of three things: either a @@ -148,21 +150,18 @@ class LValueBaseInfo { AlignmentSource AlignSource; - bool MayAlias; + TBAAAccessInfo TBAAInfo; public: explicit LValueBaseInfo(AlignmentSource Source = AlignmentSource::Type, - bool Alias = false) - : AlignSource(Source), MayAlias(Alias) {} + TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) + : AlignSource(Source), TBAAInfo(TBAAInfo) {} AlignmentSource getAlignmentSource() const { return AlignSource; } void setAlignmentSource(AlignmentSource Source) { AlignSource = Source; } - bool getMayAlias() const { return MayAlias; } - void setMayAlias(bool Alias) { MayAlias = Alias; } + TBAAAccessInfo getTBAAInfo() const { return TBAAInfo; } + void setTBAAInfo(TBAAAccessInfo Info) { TBAAInfo = Info; } - void mergeForCast(const LValueBaseInfo &Info) { - setAlignmentSource(Info.getAlignmentSource()); - setMayAlias(getMayAlias() || Info.getMayAlias()); - } + void mergeForCast(const LValueBaseInfo &TargetTypeInfo, CodeGenModule &CGM); }; /// LValue - This represents an lvalue references. Because C/C++ allow @@ -227,18 +226,9 @@ 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; - private: void Initialize(QualType Type, Qualifiers Quals, - CharUnits Alignment, LValueBaseInfo BaseInfo, - llvm::MDNode *TBAAInfo = nullptr) { + CharUnits Alignment, LValueBaseInfo BaseInfo) { assert((!Alignment.isZero() || Type->isIncompleteType()) && "initializing l-value with zero alignment!"); this->Type = Type; @@ -254,11 +244,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,19 +299,10 @@ 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; } - const Qualifiers &getQuals() const { return Quals; } Qualifiers &getQuals() { return Quals; } @@ -383,10 +359,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) { Qualifiers qs = type.getQualifiers(); qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); @@ -394,7 +368,7 @@ R.LVType = Simple; assert(address.getPointer()->getType()->isPointerTy()); R.V = address.getPointer(); - R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAInfo); + R.Initialize(type, qs, address.getAlignment(), BaseInfo); return R; } @@ -443,7 +417,7 @@ R.LVType = GlobalReg; R.V = Reg.getPointer(); R.Initialize(type, type.getQualifiers(), Reg.getAlignment(), - LValueBaseInfo(AlignmentSource::Decl, false)); + LValueBaseInfo(AlignmentSource::Decl)); return R; } Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -1905,18 +1905,23 @@ // Helpers //===--------------------------------------------------------------------===// - LValue MakeAddrLValue(Address Addr, QualType T, - LValueBaseInfo BaseInfo = - LValueBaseInfo(AlignmentSource::Type)) { - return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, - CGM.getTBAAInfo(T)); + LValue MakeAddrLValue(Address Addr, QualType T) { + LValueBaseInfo BaseInfo(AlignmentSource::Type, CGM.getTBAAAccessInfo(T)); + return LValue::MakeAddr(Addr, T, getContext(), BaseInfo); + } + + LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo) { + return LValue::MakeAddr(Addr, T, getContext(), BaseInfo); + } + + LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment) { + LValueBaseInfo BaseInfo(AlignmentSource::Type, CGM.getTBAAAccessInfo(T)); + return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo); } 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)); + LValueBaseInfo BaseInfo) { + return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo); } LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); @@ -3043,12 +3048,13 @@ /// care to appropriately convert from the memory representation to /// the LLVM value representation. llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, - SourceLocation Loc, - LValueBaseInfo BaseInfo = - LValueBaseInfo(AlignmentSource::Type), - llvm::MDNode *TBAAInfo = nullptr, - QualType TBAABaseTy = QualType(), - uint64_t TBAAOffset = 0, + SourceLocation Loc) { + LValueBaseInfo BaseInfo(AlignmentSource::Type, CGM.getTBAAAccessInfo(Ty)); + return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, BaseInfo); + } + + llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, + SourceLocation Loc, LValueBaseInfo BaseInfo, bool isNontemporal = false); /// EmitLoadOfScalar - Load a scalar value from an address, taking @@ -3061,12 +3067,14 @@ /// care to appropriately convert from the memory representation to /// the LLVM value representation. void EmitStoreOfScalar(llvm::Value *Value, Address Addr, - 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 Volatile, QualType Ty) { + LValueBaseInfo BaseInfo(AlignmentSource::Type, CGM.getTBAAAccessInfo(Ty)); + EmitStoreOfScalar(Value, Addr, Volatile, Ty, BaseInfo); + } + + void EmitStoreOfScalar(llvm::Value *Value, Address Addr, + bool Volatile, QualType Ty, LValueBaseInfo BaseInfo, + 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 @@ -132,13 +132,15 @@ if (auto TT = T->getAs()) { if (auto Align = TT->getDecl()->getMaxAlignment()) { if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, false); + *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType, + CGM.getTBAAAccessInfo(T)); return getContext().toCharUnitsFromBits(Align); } } if (BaseInfo) - *BaseInfo = LValueBaseInfo(AlignmentSource::Type, false); + *BaseInfo = LValueBaseInfo(AlignmentSource::Type, + CGM.getTBAAAccessInfo(T)); CharUnits Alignment; if (T->isIncompleteType()) { @@ -170,8 +172,7 @@ LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { LValueBaseInfo BaseInfo; CharUnits Alignment = getNaturalTypeAlignment(T, &BaseInfo); - return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo, - CGM.getTBAAInfo(T)); + return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo); } /// 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" @@ -652,25 +653,56 @@ 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(); + + /// isTBAAMayAliasAccessInfo - Test for the may-alias TBAA access descriptor. + bool isTBAAMayAliasAccessInfo(TBAAAccessInfo Info); + + /// getTBAAAccessInfo - Get TBAA information that describes an accesses to + /// an object of the given type. + TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); + + /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes 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); + + /// 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,74 @@ 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); +} + +TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->getTBAAMayAliasAccessInfo(); } -llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(QualType BaseTy, - llvm::MDNode *AccessN, - uint64_t O) { +bool CodeGenModule::isTBAAMayAliasAccessInfo(TBAAAccessInfo Info) { + if (!TBAA) + return false; + return TBAA->isTBAAMayAliasAccessInfo(Info); +} + +TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) { + return TBAAAccessInfo(getTBAATypeMetadata(AccessType)); +} + +TBAAAccessInfo CodeGenModule::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->mergeTBAAInfoForCast(SourceInfo, TargetInfo); +} + +TBAAAccessInfo +CodeGenModule::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB) { + if (!TBAA) + return TBAAAccessInfo(); + return TBAA->mergeTBAAInfoForConditionalOperator(InfoA, InfoB); +} + +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,45 @@ 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) + {} + + explicit TBAAAccessInfo(llvm::MDNode *AccessType) + : TBAAAccessInfo(/* BaseType= */ nullptr, AccessType, /* Offset= */ 0) + {} + + TBAAAccessInfo() + : TBAAAccessInfo(/* AccessType= */ nullptr) + {} + + bool operator==(const TBAAAccessInfo &Other) const { + return BaseType == Other.BaseType && + AccessType == Other.AccessType && + Offset == Other.Offset; + } + + bool operator!=(const TBAAAccessInfo &Other) const { + return !(*this == Other); + } + + /// 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 +84,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 +123,42 @@ 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(); + + /// isTBAAMayAliasAccessInfo - Test for the may-alias TBAA access descriptor. + bool isTBAAMayAliasAccessInfo(TBAAAccessInfo Info); + + /// 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); + + /// getTBAAStructMetadata - Get "tbaa.struct" metadata used to describe + /// accesses to aggregates and unions. + llvm::MDNode *getTBAAStructMetadata(QualType QTy); }; } // end namespace CodeGen @@ -123,32 +166,30 @@ 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 && - LHS.Offset == RHS.Offset; + static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS, + const clang::CodeGen::TBAAAccessInfo &RHS) { + return LHS == RHS; } }; Index: lib/CodeGen/CodeGenTBAA.cpp =================================================================== --- lib/CodeGen/CodeGenTBAA.cpp +++ lib/CodeGen/CodeGenTBAA.cpp @@ -88,19 +88,46 @@ return false; } -llvm::MDNode * -CodeGenTBAA::getTBAAInfo(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(); + // TODO: We should never request TBAA information for incomplete types. + // Fix related code and enable the assert. + // assert(RD && "Requested TBAA information for an incomplete type!"); + 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::getTypeMetadata(QualType QTy) { // At -O0 or relaxed aliasing, TBAA is not emitted for regular types. if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing) return nullptr; + // In some cases, such as dereferencing a structure member, the final access + // type may well itself be an aggregate. Since it is possible to dereference + // a member of that aggregate, this function shall be able to generate + // descriptors for any object types, including aggregate ones, without + // falling back to returning the "omnipotent char" type node. + // TODO: Combine getTypeMetadata() and getTBAABaseTypeMetadata() into a + // single function. + if (isValidTBAABaseType(QTy)) + return getTBAABaseTypeMetadata(QTy); + // If the type has the may_alias attribute (even on a typedef), it is // effectively in the general char alias class. if (TypeHasMayAlias(QTy)) return getChar(); const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); - if (llvm::MDNode *N = MetadataCache[Ty]) return N; @@ -120,15 +147,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 @@ -145,10 +172,10 @@ if (Ty->isStdByteType()) return MetadataCache[Ty] = getChar(); - // Handle pointers. + // Handle pointers and references. // TODO: Implement C++'s type "similarity" and consider dis-"similar" // pointers distinct. - if (Ty->isPointerType()) + if (Ty->isPointerType() || Ty->isReferenceType()) return MetadataCache[Ty] = createTBAAScalarType("any pointer", getChar()); @@ -172,8 +199,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 +239,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,26 +259,12 @@ return StructMetadataCache[Ty] = nullptr; } -/// Check if the given type can be handled by path-aware TBAA. -static bool isTBAAPathStruct(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::getTBAABaseTypeMetadata(QualType QTy) { + if (!isValidTBAABaseType(QTy)) + return nullptr; -llvm::MDNode * -CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { const Type *Ty = Context.getCanonicalType(QTy).getTypePtr(); - assert(isTBAAPathStruct(QTy)); - - if (llvm::MDNode *N = StructTypeMetadataCache[Ty]) + if (llvm::MDNode *N = BaseTypeMetadataCache[Ty]) return N; if (const RecordType *TTy = QTy->getAs()) { @@ -265,12 +277,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 +296,56 @@ 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]) + llvm::MDNode *&N = AccessTagMetadataCache[Info]; + if (N) 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 N = 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; +TBAAAccessInfo CodeGenTBAA::getTBAAMayAliasAccessInfo() { + return TBAAAccessInfo(getChar()); +} + +bool CodeGenTBAA::isTBAAMayAliasAccessInfo(TBAAAccessInfo Info) { + return Info == getTBAAMayAliasAccessInfo(); +} + +TBAAAccessInfo CodeGenTBAA::mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, + TBAAAccessInfo TargetInfo) { + TBAAAccessInfo MayAliasInfo = getTBAAMayAliasAccessInfo(); + if (SourceInfo == MayAliasInfo || TargetInfo == MayAliasInfo) + return MayAliasInfo; + return TargetInfo; +} - return ScalarTagMetadataCache[AccessNode] = - MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0); +TBAAAccessInfo +CodeGenTBAA::mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, + TBAAAccessInfo InfoB) { + if (InfoA == InfoB) + return InfoA; + TBAAAccessInfo MayAliasInfo = getTBAAMayAliasAccessInfo(); + if (InfoA == MayAliasInfo || InfoB == MayAliasInfo) + return MayAliasInfo; + // TODO: Implement the rest of the logic. + return TBAAAccessInfo(); } Index: test/CodeGen/tbaa-reference.cpp =================================================================== --- test/CodeGen/tbaa-reference.cpp +++ test/CodeGen/tbaa-reference.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s +// +// Check that we generate correct TBAA information for reference accesses. + +struct S; + +struct B { + S &s; + B(S &s) : s(s) {} + void bar(); +}; + +void foo(S &s) { + B b(s); + b.bar(); +} + +// CHECK-LABEL: _Z3fooR1S +// CHECK: store %struct.S* {{.*}}, %struct.S** {{.*}}, !tbaa [[TAG_pointer:!.*]] +// +// CHECK-DAG: [[TAG_pointer]] = !{[[TYPE_pointer:!.*]], [[TYPE_pointer]], i64 0} +// CHECK-DAG: [[TYPE_pointer]] = !{!"any pointer", [[TYPE_char:!.*]], i64 0} +// CHECK-DAG: [[TYPE_char]] = !{!"omnipotent char", {{!.*}}, i64 0}