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.
// Other decoration.
if (IsVolatile)
Load->setVolatile(true);
- if (LVal.getTBAAAccessType())
- CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAAccessType());
+ CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo());
return Load;
}
// Other decoration.
if (IsVolatile)
store->setVolatile(true);
- if (dest.getTBAAAccessType())
- CGM.DecorateInstructionWithTBAA(store, dest.getTBAAAccessType());
+ CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo());
return;
}
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);
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)
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?
// 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();
}
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
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);
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,
// 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();
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);
}
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;
}
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;
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;
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; }
// 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));
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;
}
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,
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);
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
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
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) {
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(
/// 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,
return MetadataCache[Ty] = getChar();
}
-llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() {
- return createTBAAScalarType("vtable pointer", getRoot());
+TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() {
+ return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot()));
}
bool
/* 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;
}
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<RecordType>()) {
const RecordDecl *RD = TTy->getDecl()->getDefinition();
if (RD->hasFlexibleArrayMember())
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<RecordType>()) {
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()));
}
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());
}
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()
/// 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.
/// MetadataCache - This maps clang::Types to scalar llvm::MDNodes describing
/// them.
llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
- /// This maps clang::Types to a struct node in the type DAG.
- llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache;
- /// This maps TBAAPathTags to a tag node.
- llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache;
- /// This maps a scalar type to a scalar tag node.
- llvm::DenseMap<const llvm::MDNode *, llvm::MDNode *> ScalarTagMetadataCache;
+ /// This maps clang::Types to a base access type in the type DAG.
+ llvm::DenseMap<const Type *, llvm::MDNode *> BaseTypeMetadataCache;
+ /// This maps TBAA access descriptors to tag nodes.
+ llvm::DenseMap<TBAAAccessInfo, llvm::MDNode *> AccessTagMetadataCache;
/// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
/// them for struct assignments.
/// 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
namespace llvm {
-template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
- static clang::CodeGen::TBAAPathTag getEmptyKey() {
- return clang::CodeGen::TBAAPathTag(
- DenseMapInfo<const clang::Type *>::getEmptyKey(),
- DenseMapInfo<const MDNode *>::getEmptyKey(),
+template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> {
+ static clang::CodeGen::TBAAAccessInfo getEmptyKey() {
+ return clang::CodeGen::TBAAAccessInfo(
+ DenseMapInfo<MDNode *>::getEmptyKey(),
+ DenseMapInfo<MDNode *>::getEmptyKey(),
DenseMapInfo<uint64_t>::getEmptyKey());
}
- static clang::CodeGen::TBAAPathTag getTombstoneKey() {
- return clang::CodeGen::TBAAPathTag(
- DenseMapInfo<const clang::Type *>::getTombstoneKey(),
- DenseMapInfo<const MDNode *>::getTombstoneKey(),
+ static clang::CodeGen::TBAAAccessInfo getTombstoneKey() {
+ return clang::CodeGen::TBAAAccessInfo(
+ DenseMapInfo<MDNode *>::getTombstoneKey(),
+ DenseMapInfo<MDNode *>::getTombstoneKey(),
DenseMapInfo<uint64_t>::getTombstoneKey());
}
- static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
- return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
- DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
+ static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) {
+ return DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^
+ DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^
DenseMapInfo<uint64_t>::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;
}
};