[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
llvm-svn: 314977
diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index c03e06d..54966dd 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -205,7 +205,7 @@
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 @@
// 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 @@
// Other decoration.
if (IsVolatile)
store->setVolatile(true);
- if (dest.getTBAAAccessType())
- CGM.DecorateInstructionWithTBAA(store, dest.getTBAAAccessType());
+ CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo());
return;
}
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 75a0fd4..e86c8dc 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2383,7 +2383,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);
@@ -2477,7 +2477,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)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 74ad9dc..1bb57b6 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1174,8 +1174,7 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 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 @@
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/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index c0348e4..33575c9 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -232,7 +232,7 @@
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 @@
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 @@
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 @@
// 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 @@
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/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 233396f..df8211f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -171,7 +171,7 @@
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/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 50c8ebf..1abad71 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1910,14 +1910,14 @@
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 @@
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 @@
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/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index a16f350..86153cc 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -578,10 +578,14 @@
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 @@
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);
}
-/// 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.
+TBAAAccessInfo CodeGenModule::getTBAAMayAliasAccessInfo() {
+ if (!TBAA)
+ return TBAAAccessInfo();
+ return TBAA->getMayAliasAccessInfo();
+}
+
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/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 33b6229..8b2fc8d 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -656,28 +656,36 @@
/// 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);
- /// getTBAAMayAliasTypeInfo - Get TBAA information that represents
+ /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access.
+ llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info);
+
+ /// 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/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 0d40748..49a49c1 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -171,8 +171,8 @@
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 @@
/* 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 @@
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())
@@ -246,12 +246,12 @@
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>()) {
@@ -263,13 +263,10 @@
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 @@
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);
+ 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;
-
- return ScalarTagMetadataCache[AccessNode] =
- MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0);
-}
-
-llvm::MDNode *CodeGenTBAA::getMayAliasTypeInfo() {
- return getChar();
+TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() {
+ return TBAAAccessInfo(getChar());
}
diff --git a/clang/lib/CodeGen/CodeGenTBAA.h b/clang/lib/CodeGen/CodeGenTBAA.h
index 2b2c2d4..75f3295 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.h
+++ b/clang/lib/CodeGen/CodeGenTBAA.h
@@ -32,22 +32,15 @@
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 @@
/// 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 @@
/// 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.
@@ -127,26 +118,25 @@
/// 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);
+ /// 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 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);
-
- /// 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 @@
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;
}
};