]> granicus.if.org Git - clang/commitdiff
Refine generation of TBAA information in clang
authorIvan A. Kosarev <ikosarev@accesssoftek.com>
Fri, 6 Oct 2017 08:17:48 +0000 (08:17 +0000)
committerIvan A. Kosarev <ikosarev@accesssoftek.com>
Fri, 6 Oct 2017 08:17:48 +0000 (08:17 +0000)
This patch is an attempt to clarify and simplify generation and
propagation of TBAA information. The idea is to pack all values
that describe a memory access, namely, base type, access type and
offset, into a single structure. This is supposed to make further
changes, such as adding support for unions and array members,
easier to prepare and review.

DecorateInstructionWithTBAA() is no more responsible for
converting types to tags. These implicit conversions not only
complicate reading the code, but also suggest assigning scalar
access tags while we generally prefer full-size struct-path tags.

TBAAPathTag is replaced with TBAAAccessInfo; the latter is now
the type of the keys of the cache map that translates access
descriptors to metadata nodes.

Fixed a bug with writing to a wrong map in
getTBAABaseTypeMetadata() (former getTBAAStructTypeInfo()).

We now check for valid base access types every time we
dereference a field. The original code only checks the top-level
base type. See isValidBaseType() / isTBAAPathStruct() calls.

Some entities have been renamed to sound more adequate and less
confusing/misleading in presence of path-aware TBAA information.

Now we do not lookup twice for the same cache entry in
getAccessTagInfo().

Refined relevant comments and descriptions.

Differential Revision: https://reviews.llvm.org/D37826

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315048 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGAtomic.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGValue.h
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/CodeGenTBAA.cpp
lib/CodeGen/CodeGenTBAA.h
test/CodeGen/tbaa-for-vptr.cpp

index 030c944ffeb1ea60d2d9fbe09af055654e3ec828..54966dd6a1554e1ee07d3a1af59ccd9dd2a235df 100644 (file)
@@ -205,7 +205,7 @@ namespace {
         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 @@ llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO,
   // Other decoration.
   if (IsVolatile)
     Load->setVolatile(true);
-  TBAAAccessInfo TBAAInfo(LVal.getTBAAAccessType());
-  CGF.CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
+  CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo());
   return Load;
 }
 
@@ -1942,8 +1941,7 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
     // Other decoration.
     if (IsVolatile)
       store->setVolatile(true);
-    TBAAAccessInfo TBAAInfo(dest.getTBAAAccessType());
-    CGM.DecorateInstructionWithTBAA(store, TBAAInfo);
+    CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo());
     return;
   }
 
index 076034ff51c99a2053f5aa3992924940dd7d8494..1bb57b6e2bb55880fbb221b9e66b65b3e7d1ccc0 100644 (file)
@@ -1174,8 +1174,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
       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 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
 
   // 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,11 +1524,10 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
         Load->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
     Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
   }
-  if (TBAAInfo.AccessType) {
-    if (BaseInfo.getMayAlias())
-      TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
-    CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
-  }
+
+  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
@@ -1596,7 +1594,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
   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);
@@ -1610,11 +1608,10 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
                           llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
     Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
   }
-  if (TBAAInfo.AccessType) {
-    if (BaseInfo.getMayAlias())
-      TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
-    CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
-  }
+
+  if (BaseInfo.getMayAlias())
+    TBAAInfo = CGM.getTBAAMayAliasAccessInfo();
+  CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
 }
 
 void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
@@ -3753,17 +3750,33 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
 
   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 ?
-      CGM.getTBAAMayAliasAccessInfo() :
-      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);
   }
 
@@ -3771,12 +3784,6 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
   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.setTBAAInfo(CGM.getTBAAMayAliasAccessInfo());
-
   return LV;
 }
 
index c0348e4d2ead9b9f2705cd9f4a5c9e8fe4f5a111..33575c97da99122cb76e183f6c443230588734bf 100644 (file)
@@ -232,7 +232,7 @@ class LValue {
 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 @@ private:
     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 @@ public:
   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 @@ public:
   // 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 @@ public:
     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;
   }
 
index 233396fc916b2228e8c16121274aaab918180009..df8211f8d7ad9a394b498d701f7a682e949d9ddb 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.getTBAATypeInfo(T));
+                          CGM.getTBAAAccessInfo(T));
 }
 
 /// Given a value of type T* that may not be to a complete object,
index 8cee6b64d46fcf75b8ea039335a4a9dffe5a91da..68be87fc5f05a7c47b928b46e2c86eb8298ec1a9 100644 (file)
@@ -1914,14 +1914,14 @@ public:
                         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);
@@ -3060,7 +3060,14 @@ public:
                                 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
@@ -3076,7 +3083,14 @@ public:
                          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
index 895bd5d5794a678e9494c295de236014422cde62..86153cc7d929ad20c565ced4924d451fffa193f7 100644 (file)
@@ -594,6 +594,12 @@ llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) {
   return TBAA->getTBAAStructInfo(QTy);
 }
 
+llvm::MDNode *CodeGenModule::getTBAABaseTypeInfo(QualType QTy) {
+  if (!TBAA)
+    return nullptr;
+  return TBAA->getBaseTypeInfo(QTy);
+}
+
 llvm::MDNode *CodeGenModule::getTBAAAccessTagInfo(TBAAAccessInfo Info) {
   if (!TBAA)
     return nullptr;
index 50e23d55c4a996481c770530f8a98d098eccc4ad..c1a31c9f3d6934b8a196c803800e82027900d0c0 100644 (file)
@@ -666,6 +666,10 @@ public:
 
   llvm::MDNode *getTBAAStructInfo(QualType QTy);
 
+  /// getTBAABaseTypeInfo - 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);
 
index 3f0f942ea9931f755996781cdce54b1c48715e5e..49a49c1f5d705efc26c20046f38ebf5cc5a525c3 100644 (file)
@@ -234,8 +234,6 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
 
 /// Check if the given type is a valid base type to be used in access tags.
 static bool isValidBaseType(QualType QTy) {
-  if (QTy == QualType())
-    return false;
   if (const RecordType *TTy = QTy->getAs<RecordType>()) {
     const RecordDecl *RD = TTy->getDecl()->getDefinition();
     if (RD->hasFlexibleArrayMember())
@@ -249,10 +247,11 @@ static bool isValidBaseType(QualType QTy) {
 }
 
 llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
-  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  assert(isValidBaseType(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>()) {
@@ -267,7 +266,7 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
       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()));
     }
@@ -281,11 +280,11 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
       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::getAccessTagInfo(TBAAAccessInfo Info) {
@@ -295,23 +294,16 @@ llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
   if (!CodeGenOpts.StructPathTBAA)
     Info = TBAAAccessInfo(Info.AccessType);
 
-  const Type *BTy = nullptr;
-  if (Info.BaseType != QualType())
-    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 (isValidBaseType(Info.BaseType))
-    BNode = getBaseTypeInfo(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);
 }
 
 TBAAAccessInfo CodeGenTBAA::getMayAliasAccessInfo() {
index 198c2005db9016c408461a97714cad8dca945179..8fc0c72fcbcce734e1bf6ffbdf3eeb00012c1293 100644 (file)
@@ -32,22 +32,15 @@ namespace clang {
 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 @@ struct 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.
@@ -82,10 +75,10 @@ class CodeGenTBAA {
   /// 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 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.
@@ -133,8 +126,9 @@ public:
   /// the given type.
   llvm::MDNode *getTBAAStructInfo(QualType QTy);
 
-  /// getBaseTypeInfo - Get metadata node for a given base access type.
-  llvm::MDNode *getBaseTypeInfo(QualType QType);
+  /// getBaseTypeInfo - 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);
 
   /// getAccessTagInfo - Get TBAA tag for a given memory access.
   llvm::MDNode *getAccessTagInfo(TBAAAccessInfo Info);
@@ -149,31 +143,31 @@ public:
 
 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;
   }
 };
index 7b8ae2099e470b6395c4551b7fef203060b169d9..6136874cbfcb752c85189643d9d80012c37f5bc8 100644 (file)
@@ -23,12 +23,12 @@ void CallFoo(A *a, int (A::*fp)() const) {
 }
 
 // CHECK-LABEL: @_Z7CallFoo
-// CHECK: %{{.*}} = load {{.*}} !tbaa ![[NUM:[0-9]+]]
+// CHECK: %{{.*}} = load i32 (%struct.A*)**, {{.*}} !tbaa ![[NUM:[0-9]+]]
 // CHECK: br i1
-// CHECK: load {{.*}}, !tbaa ![[NUM]]
+// CHECK: load i8*, {{.*}}, !tbaa ![[NUM]]
 //
 // CHECK-LABEL: @_ZN1AC2Ev
-// CHECK: store {{.*}} !tbaa ![[NUM]]
+// CHECK: store i32 (...)** {{.*}}, !tbaa ![[NUM]]
 //
 // CHECK: [[NUM]] = !{[[TYPE:!.*]], [[TYPE]], i64 0}
 // CHECK: [[TYPE]] = !{!"vtable pointer", !{{.*}}