addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits());
return LValue::MakeAddr(addr, getValueType(), CGF.getContext(),
- LVal.getBaseInfo(), LVal.getTBAAInfo());
+ LVal.getBaseInfo(), LVal.getTBAAAccessType());
}
/// \brief Emits atomic load.
// Other decoration.
if (IsVolatile)
Load->setVolatile(true);
- CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo());
+ if (LVal.getTBAAAccessType())
+ CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAAccessType());
return Load;
}
// Other decoration.
if (IsVolatile)
store->setVolatile(true);
- CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo());
+ if (dest.getTBAAAccessType())
+ CGM.DecorateInstructionWithTBAA(store, dest.getTBAAAccessType());
return;
}
VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
- CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAVTablePtrAccessInfo());
+ CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAInfoForVTablePtr());
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.getTBAAVTablePtrAccessInfo());
+ CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAInfoForVTablePtr());
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.getTBAAInfo());
+ getContext(), LV.getBaseInfo(),
+ LV.getTBAAAccessType());
}
// 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);
+ LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo.AccessType);
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 (BaseInfo.getMayAlias())
- TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
- CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
+ if (TBAAInfo.AccessType) {
+ bool MayAlias = BaseInfo.getMayAlias();
+ llvm::MDNode *TBAA = MayAlias
+ ? CGM.getTBAAMayAliasTypeInfo()
+ : CGM.getTBAAStructTagInfo(TBAAInfo);
+ if (TBAA)
+ CGM.DecorateInstructionWithTBAA(Load, TBAA, MayAlias);
+ }
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);
+ LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo.AccessType);
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 (BaseInfo.getMayAlias())
- TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
- CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
+ if (TBAAInfo.AccessType) {
+ bool MayAlias = BaseInfo.getMayAlias();
+ llvm::MDNode *TBAA = MayAlias
+ ? CGM.getTBAAMayAliasTypeInfo()
+ : CGM.getTBAAStructTagInfo(TBAAInfo);
+ if (TBAA)
+ CGM.DecorateInstructionWithTBAA(Store, TBAA, MayAlias);
+ }
}
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
// Loading the reference will disable path-aware TBAA.
TBAAPath = false;
- TBAAAccessInfo TBAAInfo = mayAlias ? CGM.getTBAAMayAliasAccessInfo() :
- CGM.getTBAAAccessInfo(type);
- CGM.DecorateInstructionWithTBAA(load, TBAAInfo);
+ if (CGM.shouldUseTBAA()) {
+ llvm::MDNode *tbaa = mayAlias ? CGM.getTBAAMayAliasTypeInfo() :
+ CGM.getTBAATypeInfo(type);
+ if (tbaa)
+ CGM.DecorateInstructionWithTBAA(load, tbaa);
+ }
mayAlias = false;
type = refType->getPointeeType();
LValue LV = MakeAddrLValue(addr, type, FieldBaseInfo);
LV.getQuals().addCVRQualifiers(cvr);
-
- // 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.
+ 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.
unsigned CharWidth = getContext().getCharWidth();
- if (TBAAInfo.BaseType)
- TBAAInfo.Offset +=
- Layout.getFieldOffset(field->getFieldIndex()) / CharWidth;
-
- // Update the final access type.
- TBAAInfo.AccessType = LV.getTBAAInfo().AccessType;
-
+ TBAAAccessInfo TBAAInfo = mayAlias ?
+ TBAAAccessInfo(CGM.getTBAAMayAliasTypeInfo()) :
+ TBAAAccessInfo(base.getTBAAInfo().BaseType, CGM.getTBAATypeInfo(type),
+ base.getTBAAInfo().Offset + Layout.getFieldOffset(
+ field->getFieldIndex()) / CharWidth);
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,
- TBAAAccessInfo TBAAInfo = TBAAAccessInfo()) {
+ llvm::MDNode *TBAAAccessType = nullptr) {
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 = TBAAInfo;
+ this->TBAAInfo = TBAAAccessInfo(Type, TBAAAccessType, /* Offset= */ 0);
// 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, TBAAAccessInfo TBAAInfo) {
+ static LValue MakeAddr(Address address, QualType type,
+ ASTContext &Context,
+ LValueBaseInfo BaseInfo,
+ llvm::MDNode *TBAAAccessType = nullptr) {
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, TBAAInfo);
+ R.Initialize(type, qs, address.getAlignment(), BaseInfo, TBAAAccessType);
return R;
}
LValueBaseInfo BaseInfo;
CharUnits Alignment = getNaturalTypeAlignment(T, &BaseInfo);
return LValue::MakeAddr(Address(V, Alignment), T, getContext(), BaseInfo,
- CGM.getTBAAAccessInfo(T));
+ CGM.getTBAATypeInfo(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.getTBAAAccessInfo(T));
+ CGM.getTBAATypeInfo(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.getTBAAAccessInfo(T));
+ BaseInfo, CGM.getTBAATypeInfo(T));
}
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
SourceLocation Loc,
LValueBaseInfo BaseInfo =
LValueBaseInfo(AlignmentSource::Type),
- 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,
+ TBAAAccessInfo TBAAInfo = TBAAAccessInfo(),
bool isNontemporal = false);
/// EmitLoadOfScalar - Load a scalar value from an address, taking
bool Volatile, QualType Ty,
LValueBaseInfo BaseInfo =
LValueBaseInfo(AlignmentSource::Type),
- 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,
+ TBAAAccessInfo TBAAInfo = TBAAAccessInfo(),
bool isInit = false, bool isNontemporal = false);
/// EmitStoreOfScalar - Store a scalar value to an address, taking
return TBAA->getTypeInfo(QTy);
}
-TBAAAccessInfo CodeGenModule::getTBAAAccessInfo(QualType AccessType) {
- return TBAAAccessInfo(getTBAATypeInfo(AccessType));
-}
-
-TBAAAccessInfo CodeGenModule::getTBAAVTablePtrAccessInfo() {
+llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() {
if (!TBAA)
- return TBAAAccessInfo();
- return TBAA->getVTablePtrAccessInfo();
+ return nullptr;
+ return TBAA->getTBAAInfoForVTablePtr();
}
llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) {
return TBAA->getTBAAStructInfo(QTy);
}
-llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) {
+llvm::MDNode *CodeGenModule::getTBAAStructTagInfo(TBAAAccessInfo Info) {
if (!TBAA)
return nullptr;
- return TBAA->getBaseTypeInfo(QTy);
+ return TBAA->getTBAAStructTagInfo(Info);
}
-llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
+llvm::MDNode *CodeGenModule::getTBAAMayAliasTypeInfo() {
if (!TBAA)
return nullptr;
- return TBAA->getAccessTagInfo(Info);
-}
-
-TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() {
- if (!TBAA)
- return TBAAAccessInfo();
- return TBAA->getMayAliasAccessInfo();
+ return TBAA->getMayAliasTypeInfo();
}
+/// 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,
- TBAAAccessInfo TBAAInfo) {
- if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo))
- Inst->setMetadata(llvm::LLVMContext::MD_tbaa, Tag);
+ 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);
}
void CodeGenModule::DecorateInstructionWithInvariantGroup(
/// the given type.
llvm::MDNode *getTBAATypeInfo(QualType QTy);
- /// 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 *getTBAAInfoForVTablePtr();
llvm::MDNode *getTBAAStructInfo(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 *getTBAABaseTypeInfo(QualType QTy);
-
- /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access.
- llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info);
+ /// Get path-aware TBAA tag for a given memory access.
+ llvm::MDNode *getTBAAStructTagInfo(TBAAAccessInfo Info);
- /// getTBAAMayAliasAccessInfo - Get TBAA information that represents
+ /// getTBAAMayAliasTypeInfo - Get TBAA information that represents
/// may-alias accesses.
- TBAAAccessInfo getTBAAMayAliasAccessInfo();
+ llvm::MDNode *getTBAAMayAliasTypeInfo();
bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
bool isPaddedAtomicType(QualType type);
bool isPaddedAtomicType(const AtomicType *type);
- /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
+ /// 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.
void DecorateInstructionWithTBAA(llvm::Instruction *Inst,
- TBAAAccessInfo TBAAInfo);
+ llvm::MDNode *TBAAInfo,
+ bool ConvertTypeToTag = true);
/// Adds !invariant.barrier !tag to instruction
void DecorateInstructionWithInvariantGroup(llvm::Instruction *I,
return MetadataCache[Ty] = getChar();
}
-TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() {
- return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot()));
+llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() {
+ return 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 *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy);
- llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType));
+ llvm::MDNode *TBAAInfo = MayAlias ? getChar() : getTypeInfo(QTy);
+ llvm::MDNode *TBAATag = getTBAAScalarTagInfo(TBAAInfo);
Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
return true;
}
return StructMetadataCache[Ty] = nullptr;
}
-/// Check if the given type is a valid base type to be used in access tags.
-static bool isValidBaseType(QualType QTy) {
+/// Check if the given type can be handled by path-aware TBAA.
+static bool isTBAAPathStruct(QualType QTy) {
if (const RecordType *TTy = QTy->getAs<RecordType>()) {
const RecordDecl *RD = TTy->getDecl()->getDefinition();
if (RD->hasFlexibleArrayMember())
return false;
}
-llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
- if (!isValidBaseType(QTy))
- return nullptr;
-
+llvm::MDNode *
+CodeGenTBAA::getTBAAStructTypeInfo(QualType QTy) {
const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
- if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
+ assert(isTBAAPathStruct(QTy));
+
+ if (llvm::MDNode *N = StructTypeMetadataCache[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 = isValidBaseType(FieldQTy) ?
- getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
+ llvm::MDNode *FieldNode;
+ if (isTBAAPathStruct(FieldQTy))
+ FieldNode = getTBAAStructTypeInfo(FieldQTy);
+ else
+ FieldNode = getTypeInfo(FieldQTy);
if (!FieldNode)
- return BaseTypeMetadataCache[Ty] = nullptr;
+ return StructTypeMetadataCache[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 BaseTypeMetadataCache[Ty] =
+ return StructTypeMetadataCache[Ty] =
MDHelper.createTBAAStructTypeNode(OutName, Fields);
}
- return BaseTypeMetadataCache[Ty] = nullptr;
+ return StructMetadataCache[Ty] = nullptr;
}
-llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
+llvm::MDNode *CodeGenTBAA::getTBAAStructTagInfo(TBAAAccessInfo Info) {
if (!Info.AccessType)
return nullptr;
if (!CodeGenOpts.StructPathTBAA)
- Info = TBAAAccessInfo(Info.AccessType);
+ return getTBAAScalarTagInfo(Info.AccessType);
- llvm::MDNode *&N = AccessTagMetadataCache[Info];
- if (N)
+ const Type *BTy = Context.getCanonicalType(Info.BaseType).getTypePtr();
+ TBAAPathTag PathTag = TBAAPathTag(BTy, Info.AccessType, Info.Offset);
+ if (llvm::MDNode *N = StructTagMetadataCache[PathTag])
return N;
- 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 *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);
}
-TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() {
- return TBAAAccessInfo(getChar());
+llvm::MDNode *CodeGenTBAA::getMayAliasTypeInfo() {
+ return 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(llvm::MDNode *BaseType, llvm::MDNode *AccessType,
- uint64_t Offset)
+ TBAAAccessInfo(QualType 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(/* BaseType= */ QualType(), 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.
- llvm::MDNode *BaseType;
+ QualType 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 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;
+ /// 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;
/// StructMetadataCache - This maps clang::Types to llvm::MDNodes describing
/// them for struct assignments.
/// given type.
llvm::MDNode *getTypeInfo(QualType QTy);
- /// getVTablePtrAccessInfo - Get the TBAA information that describes an
- /// access to a virtual table pointer.
- TBAAAccessInfo getVTablePtrAccessInfo();
+ /// 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
/// the given type.
llvm::MDNode *getTBAAStructInfo(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 *getBaseTypeInfo(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);
- /// getAccessTagInfo - Get TBAA tag for a given memory access.
- llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);
+ /// Get the scalar tag MDNode for a given scalar type.
+ llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);
- /// getMayAliasAccessInfo - Get TBAA information that represents may-alias
+ /// getMayAliasTypeInfo - Get TBAA information that represents may-alias
/// accesses.
- TBAAAccessInfo getMayAliasAccessInfo();
+ llvm::MDNode *getMayAliasTypeInfo();
};
} // end namespace CodeGen
namespace llvm {
-template<> struct DenseMapInfo<clang::CodeGen::TBAAAccessInfo> {
- static clang::CodeGen::TBAAAccessInfo getEmptyKey() {
- return clang::CodeGen::TBAAAccessInfo(
- DenseMapInfo<MDNode *>::getEmptyKey(),
- DenseMapInfo<MDNode *>::getEmptyKey(),
+template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
+ static clang::CodeGen::TBAAPathTag getEmptyKey() {
+ return clang::CodeGen::TBAAPathTag(
+ DenseMapInfo<const clang::Type *>::getEmptyKey(),
+ DenseMapInfo<const MDNode *>::getEmptyKey(),
DenseMapInfo<uint64_t>::getEmptyKey());
}
- static clang::CodeGen::TBAAAccessInfo getTombstoneKey() {
- return clang::CodeGen::TBAAAccessInfo(
- DenseMapInfo<MDNode *>::getTombstoneKey(),
- DenseMapInfo<MDNode *>::getTombstoneKey(),
+ static clang::CodeGen::TBAAPathTag getTombstoneKey() {
+ return clang::CodeGen::TBAAPathTag(
+ DenseMapInfo<const clang::Type *>::getTombstoneKey(),
+ DenseMapInfo<const MDNode *>::getTombstoneKey(),
DenseMapInfo<uint64_t>::getTombstoneKey());
}
- static unsigned getHashValue(const clang::CodeGen::TBAAAccessInfo &Val) {
- return DenseMapInfo<MDNode *>::getHashValue(Val.BaseType) ^
- DenseMapInfo<MDNode *>::getHashValue(Val.AccessType) ^
+ static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
+ return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
+ DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
}
- static bool isEqual(const clang::CodeGen::TBAAAccessInfo &LHS,
- const clang::CodeGen::TBAAAccessInfo &RHS) {
- return LHS.BaseType == RHS.BaseType &&
- LHS.AccessType == RHS.AccessType &&
+ 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;
}
};