From c64aa1bff66eaa08d18f0704502ac0b45610f218 Mon Sep 17 00:00:00 2001 From: "Ivan A. Kosarev" Date: Thu, 5 Oct 2017 10:47:51 +0000 Subject: [PATCH] [CodeGen] Unify generation of scalar and struct-path TBAA tags This patch makes it possible to produce access tags in a uniform manner regardless whether the resulting tag will be a scalar or a struct-path one. getAccessTagInfo() now takes care of the actual translation of access descriptors to tags and can handle all kinds of accesses. Facilities that specific to scalar accesses are eliminated. Some more details: * DecorateInstructionWithTBAA() is not responsible for conversion of types to access tags anymore. Instead, it takes an access descriptor (TBAAAccessInfo) and generates corresponding access tag from it. * getTBAAInfoForVTablePtr() reworked to getTBAAVTablePtrAccessInfo() that now returns the virtual-pointer access descriptor and not the virtual-point type metadata. * Added function getTBAAMayAliasAccessInfo() that returns the descriptor for may-alias accesses. * getTBAAStructTagInfo() renamed to getTBAAAccessTagInfo() as now it is the only way to generate access tag by a given access descriptor. It is capable of producing both scalar and struct-path tags, depending on options and availability of the base access type. getTBAAScalarTagInfo() and its cache ScalarTagMetadataCache are eliminated. * Now that we do not need to care about whether the resulting access tag should be a scalar or struct-path one, getTBAAStructTypeInfo() is renamed to getBaseTypeInfo(). * Added function getTBAAAccessInfo() that constructs access descriptor by a given QualType access type. This is part of D37826 reworked to be a separate patch to simplify review. Differential Revision: https://reviews.llvm.org/D38503 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314977 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGAtomic.cpp | 8 ++-- lib/CodeGen/CGClass.cpp | 4 +- lib/CodeGen/CGExpr.cpp | 78 ++++++++++++++++---------------- lib/CodeGen/CGValue.h | 15 +++---- lib/CodeGen/CodeGenFunction.cpp | 2 +- lib/CodeGen/CodeGenFunction.h | 22 +++++++-- lib/CodeGen/CodeGenModule.cpp | 38 ++++++++-------- lib/CodeGen/CodeGenModule.h | 30 ++++++++----- lib/CodeGen/CodeGenTBAA.cpp | 75 ++++++++++++------------------- lib/CodeGen/CodeGenTBAA.h | 80 +++++++++++++++------------------ 10 files changed, 169 insertions(+), 183 deletions(-) diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp index c03e06d571..54966dd6a1 100644 --- a/lib/CodeGen/CGAtomic.cpp +++ b/lib/CodeGen/CGAtomic.cpp @@ -205,7 +205,7 @@ namespace { 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 @@ llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, // 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 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, // Other decoration. if (IsVolatile) store->setVolatile(true); - if (dest.getTBAAAccessType()) - CGM.DecorateInstructionWithTBAA(store, dest.getTBAAAccessType()); + CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); return; } diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 75a0fd43e8..e86c8dcc8a 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -2383,7 +2383,7 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { 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 @@ llvm::Value *CodeGenFunction::GetVTablePtr(Address This, 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) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 74ad9dcf46..1bb57b6e2b 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1174,8 +1174,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { 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 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, // 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 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, 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 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, 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 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, 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 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, // 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 CodeGenFunction::EmitLValueForField(LValue base, 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 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, 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; } diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index c0348e4d2e..33575c97da 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -232,7 +232,7 @@ class LValue { 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 @@ private: 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 @@ public: 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 @@ public: // 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 @@ public: 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; } diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 233396fc91..df8211f8d7 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -171,7 +171,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.getTBAATypeInfo(T)); + CGM.getTBAAAccessInfo(T)); } /// Given a value of type T* that may not be to a complete object, diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 50c8ebf7a5..1abad71ed4 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1910,14 +1910,14 @@ public: 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 @@ public: 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 @@ public: 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 diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index a16f350f9d..86153cc7d9 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -578,10 +578,14 @@ llvm::MDNode *CodeGenModule::getTBAATypeInfo(QualType QTy) { 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 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) { 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( diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 33b622972d..8b2fc8d2a8 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -656,28 +656,36 @@ public: /// 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, diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index 0d40748c45..49a49c1f5d 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -171,8 +171,8 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) { 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 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, /* 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 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) { 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 @@ static bool isTBAAPathStruct(QualType QTy) { 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 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { 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 @@ CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) { 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()); } diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h index 2b2c2d4b09..75f32950d5 100644 --- a/lib/CodeGen/CodeGenTBAA.h +++ b/lib/CodeGen/CodeGenTBAA.h @@ -32,22 +32,15 @@ namespace clang { 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 @@ struct TBAAAccessInfo { /// 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 @@ class CodeGenTBAA { /// 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 @@ public: /// 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 @@ public: 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; } }; -- 2.40.0