summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c64aa1b)
raw | patch | inline | side by side (parent: c64aa1b)
author | Ivan A. Kosarev <ikosarev@accesssoftek.com> | |
Thu, 5 Oct 2017 11:05:43 +0000 (11:05 +0000) | ||
committer | Ivan A. Kosarev <ikosarev@accesssoftek.com> | |
Thu, 5 Oct 2017 11:05:43 +0000 (11:05 +0000) |
D37826 has been mistakenly committed where it should be the patch from D38503.
Differential Revision: https://reviews.llvm.org/D38503
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314978 91177308-0d34-0410-b5e6-96231b3b80d8
Differential Revision: https://reviews.llvm.org/D38503
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314978 91177308-0d34-0410-b5e6-96231b3b80d8
index 54966dd6a1554e1ee07d3a1af59ccd9dd2a235df..c03e06d571e0e8a8640043827f787f4f50404126 100644 (file)
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
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;
}
index e86c8dcc8a626c8b28dcd2fc3cc66cf9d369c1c1..75a0fd43e8b939b6e03ce4ad68e37d80b4570368 100644 (file)
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
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)
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 1bb57b6e2bb55880fbb221b9e66b65b3e7d1ccc0..74ad9dcf463028ff1c3c5f51fff7def6696a1be2 100644 (file)
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
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;
}
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index 33575c97da99122cb76e183f6c443230588734bf..c0348e4d2ead9b9f2705cd9f4a5c9e8fe4f5a111 100644 (file)
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
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;
}
index df8211f8d7ad9a394b498d701f7a682e949d9ddb..233396fc916b2228e8c16121274aaab918180009 100644 (file)
@@ -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.getTBAAAccessInfo(T));
+ CGM.getTBAATypeInfo(T));
}
/// Given a value of type T* that may not be to a complete object,
index 1abad71ed4089689793cb71a7c8390f0bb70d5ef..50c8ebf7a55fd87900c7fa470e4500a64d05091e 100644 (file)
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
index 86153cc7d929ad20c565ced4924d451fffa193f7..a16f350f9d5c311fadd885b9ab4e174e2d5c03ad 100644 (file)
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(
index 8b2fc8d2a8c7e75c0c4666c0dda2ca2f2c63cc40..33b622972d9d81b1a28403116fda28996ae90640 100644 (file)
/// 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,
index 49a49c1f5d705efc26c20046f38ebf5cc5a525c3..0d40748c4567aea3423abff8b23cf61c2c498eb3 100644 (file)
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();
}
index 75f32950d5dce2306c9ec3d211bca2d93b07c477..2b2c2d4b0984af5a3f27128a384cfbc46f32b9ba 100644 (file)
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;
}
};