/// A collection of metadata nodes that might be associated with a
/// memory access used by the alias-analysis infrastructure.
struct AAMDNodes {
- explicit AAMDNodes(MDNode *T = nullptr, MDNode *S = nullptr,
- MDNode *N = nullptr)
- : TBAA(T), Scope(S), NoAlias(N) {}
+ explicit AAMDNodes() = default;
+ explicit AAMDNodes(MDNode *T, MDNode *TS, MDNode *S, MDNode *N)
+ : TBAA(T), TBAAStruct(TS), Scope(S), NoAlias(N) {}
bool operator==(const AAMDNodes &A) const {
- return TBAA == A.TBAA && Scope == A.Scope && NoAlias == A.NoAlias;
+ return TBAA == A.TBAA && TBAAStruct == A.TBAAStruct && Scope == A.Scope &&
+ NoAlias == A.NoAlias;
}
bool operator!=(const AAMDNodes &A) const { return !(*this == A); }
- explicit operator bool() const { return TBAA || Scope || NoAlias; }
+ explicit operator bool() const {
+ return TBAA || TBAAStruct || Scope || NoAlias;
+ }
/// The tag for type-based alias analysis.
- MDNode *TBAA;
+ MDNode *TBAA = nullptr;
+
+ /// The tag for type-based alias analysis (tbaa struct).
+ MDNode *TBAAStruct = nullptr;
/// The tag for alias scope specification (used with noalias).
- MDNode *Scope;
+ MDNode *Scope = nullptr;
/// The tag specifying the noalias scope.
- MDNode *NoAlias;
+ MDNode *NoAlias = nullptr;
/// Given two sets of AAMDNodes that apply to the same pointer,
/// give the best AAMDNodes that are compatible with both (i.e. a set of
AAMDNodes intersect(const AAMDNodes &Other) {
AAMDNodes Result;
Result.TBAA = Other.TBAA == TBAA ? TBAA : nullptr;
+ Result.TBAAStruct = Other.TBAAStruct == TBAAStruct ? TBAAStruct : nullptr;
Result.Scope = Other.Scope == Scope ? Scope : nullptr;
Result.NoAlias = Other.NoAlias == NoAlias ? NoAlias : nullptr;
return Result;
struct DenseMapInfo<AAMDNodes> {
static inline AAMDNodes getEmptyKey() {
return AAMDNodes(DenseMapInfo<MDNode *>::getEmptyKey(),
- nullptr, nullptr);
+ nullptr, nullptr, nullptr);
}
static inline AAMDNodes getTombstoneKey() {
return AAMDNodes(DenseMapInfo<MDNode *>::getTombstoneKey(),
- nullptr, nullptr);
+ nullptr, nullptr, nullptr);
}
static unsigned getHashValue(const AAMDNodes &Val) {
return DenseMapInfo<MDNode *>::getHashValue(Val.TBAA) ^
+ DenseMapInfo<MDNode *>::getHashValue(Val.TBAAStruct) ^
DenseMapInfo<MDNode *>::getHashValue(Val.Scope) ^
DenseMapInfo<MDNode *>::getHashValue(Val.NoAlias);
}
}
void Instruction::getAAMetadata(AAMDNodes &N, bool Merge) const {
- if (Merge)
+ if (Merge) {
N.TBAA =
MDNode::getMostGenericTBAA(N.TBAA, getMetadata(LLVMContext::MD_tbaa));
- else
- N.TBAA = getMetadata(LLVMContext::MD_tbaa);
-
- if (Merge)
+ N.TBAAStruct = nullptr;
N.Scope = MDNode::getMostGenericAliasScope(
N.Scope, getMetadata(LLVMContext::MD_alias_scope));
- else
- N.Scope = getMetadata(LLVMContext::MD_alias_scope);
-
- if (Merge)
N.NoAlias =
MDNode::intersect(N.NoAlias, getMetadata(LLVMContext::MD_noalias));
- else
+ } else {
+ N.TBAA = getMetadata(LLVMContext::MD_tbaa);
+ N.TBAAStruct = getMetadata(LLVMContext::MD_tbaa_struct);
+ N.Scope = getMetadata(LLVMContext::MD_alias_scope);
N.NoAlias = getMetadata(LLVMContext::MD_noalias);
+ }
}
static const MDNode *createAccessTag(const MDNode *AccessType) {