Struct-path aware TBAA: uniformize scalar tag and path tag.

For struct-path aware TBAA, we used to use scalar type node as the scalar tag,
which has an incompatible format with the struct path tag. We now use the same
format: base type, access type and offset.

We also uniformize the scalar type node and the struct type node: name, a list
of pairs (offset + pointer to MDNode). For scalar type, we have a single pair.
These are to make implementaiton of aliasing rules easier.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179335 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index fe0d070..4d72dc1 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1175,7 +1175,7 @@
   if (TBAAInfo) {
     llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
                                                       TBAAOffset);
-    CGM.DecorateInstruction(Load, TBAAPath);
+    CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/);
   }
 
   if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) ||
@@ -1289,7 +1289,7 @@
   if (TBAAInfo) {
     llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
                                                       TBAAOffset);
-    CGM.DecorateInstruction(Store, TBAAPath);
+    CGM.DecorateInstruction(Store, TBAAPath, false/*ConvertTypeToTag*/);
   }
 }
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index e8e3d1a..4126bea 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -242,9 +242,18 @@
   return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O);
 }
 
+/// 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 CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
-                                        llvm::MDNode *TBAAInfo) {
-  Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
+                                        llvm::MDNode *TBAAInfo,
+                                        bool ConvertTypeToTag) {
+  if (ConvertTypeToTag && TBAA && CodeGenOpts.StructPathTBAA)
+    Inst->setMetadata(llvm::LLVMContext::MD_tbaa,
+                      TBAA->getTBAAScalarTagInfo(TBAAInfo));
+  else
+    Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
 }
 
 bool CodeGenModule::isTargetDarwin() const {
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 6bc4456..f8b0971 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -519,8 +519,13 @@
   bool isPaddedAtomicType(QualType type);
   bool isPaddedAtomicType(const AtomicType *type);
 
-  static void DecorateInstruction(llvm::Instruction *Inst,
-                                  llvm::MDNode *TBAAInfo);
+  /// 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 DecorateInstruction(llvm::Instruction *Inst,
+                           llvm::MDNode *TBAAInfo,
+                           bool ConvertTypeToTag = true);
 
   /// getSize - Emit the given number of characters as a value of type size_t.
   llvm::ConstantInt *getSize(CharUnits numChars);
diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
index 7e4d34a..bb1ebda 100644
--- a/lib/CodeGen/CodeGenTBAA.cpp
+++ b/lib/CodeGen/CodeGenTBAA.cpp
@@ -50,13 +50,25 @@
   return Root;
 }
 
+// For struct-path aware TBAA, the scalar type has the same format as
+// the struct type: name, offset, pointer to another node in the type DAG.
+// For scalar TBAA, the scalar type is the same as the scalar tag:
+// name and a parent pointer.
+llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name,
+                                                llvm::MDNode *Parent) {
+  if (CodeGenOpts.StructPathTBAA)
+    return MDHelper.createTBAAScalarTypeNode(Name, 0, Parent);
+  else
+    return MDHelper.createTBAANode(Name, Parent);
+}
+
 llvm::MDNode *CodeGenTBAA::getChar() {
   // Define the root of the tree for user-accessible memory. C and C++
   // give special powers to char and certain similar types. However,
   // these special powers only cover user-accessible memory, and doesn't
   // include things like vtables.
   if (!Char)
-    Char = MDHelper.createTBAANode("omnipotent char", getRoot());
+    Char = createTBAAScalarType("omnipotent char", getRoot());
 
   return Char;
 }
@@ -124,7 +136,7 @@
     // "underlying types".
     default:
       return MetadataCache[Ty] =
-        MDHelper.createTBAANode(BTy->getName(Features), getChar());
+        createTBAAScalarType(BTy->getName(Features), getChar());
     }
   }
 
@@ -132,8 +144,8 @@
   // TODO: Implement C++'s type "similarity" and consider dis-"similar"
   // pointers distinct.
   if (Ty->isPointerType())
-    return MetadataCache[Ty] = MDHelper.createTBAANode("any pointer",
-                                                       getChar());
+    return MetadataCache[Ty] = createTBAAScalarType("any pointer",
+                                                    getChar());
 
   // Enum types are distinct types. In C++ they have "underlying types",
   // however they aren't related for TBAA.
@@ -160,7 +172,7 @@
     llvm::raw_svector_ostream Out(OutName);
     MContext.mangleCXXRTTIName(QualType(ETy, 0), Out);
     Out.flush();
-    return MetadataCache[Ty] = MDHelper.createTBAANode(OutName, getChar());
+    return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar());
   }
 
   // For now, handle any other kind of type conservatively.
@@ -168,7 +180,7 @@
 }
 
 llvm::MDNode *CodeGenTBAA::getTBAAInfoForVTablePtr() {
-  return MDHelper.createTBAANode("vtable pointer", getRoot());
+  return createTBAAScalarType("vtable pointer", getRoot());
 }
 
 bool
@@ -252,10 +264,6 @@
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     SmallVector <std::pair<uint64_t, llvm::MDNode*>, 4> Fields;
-    // To reduce the size of MDNode for a given struct type, we only output
-    // once for all the fields with the same scalar types.
-    // Offsets for scalar fields in the type DAG are not used.
-    llvm::SmallSet <llvm::MDNode*, 4> ScalarFieldTypes;
     unsigned idx = 0;
     for (RecordDecl::field_iterator i = RD->field_begin(),
          e = RD->field_end(); i != e; ++i, ++idx) {
@@ -263,13 +271,8 @@
       llvm::MDNode *FieldNode;
       if (isTBAAPathStruct(FieldQTy))
         FieldNode = getTBAAStructTypeInfo(FieldQTy);
-      else {
+      else
         FieldNode = getTBAAInfo(FieldQTy);
-        // Ignore this field if the type already exists.
-        if (ScalarFieldTypes.count(FieldNode))
-          continue;
-        ScalarFieldTypes.insert(FieldNode);
-       }
       if (!FieldNode)
         return StructTypeMetadataCache[Ty] = NULL;
       Fields.push_back(std::make_pair(
@@ -305,8 +308,18 @@
   if (isTBAAPathStruct(BaseQTy))
     BNode  = getTBAAStructTypeInfo(BaseQTy);
   if (!BNode)
-    return StructTagMetadataCache[PathTag] = AccessNode;
+    return StructTagMetadataCache[PathTag] =
+       MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0);
 
   return StructTagMetadataCache[PathTag] =
     MDHelper.createTBAAStructTagNode(BNode, AccessNode, Offset);
 }
+
+llvm::MDNode *
+CodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) {
+  if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode])
+    return N;
+
+  return ScalarTagMetadataCache[AccessNode] =
+    MDHelper.createTBAAStructTagNode(AccessNode, AccessNode, 0);
+}
diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h
index 9ddc3aa..f0c9e06 100644
--- a/lib/CodeGen/CodeGenTBAA.h
+++ b/lib/CodeGen/CodeGenTBAA.h
@@ -61,6 +61,8 @@
   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.
@@ -84,6 +86,11 @@
                      SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields,
                      bool MayAlias);
 
+  /// A wrapper function to create a scalar type. For struct-path aware TBAA,
+  /// the scalar type has the same format as the struct type: name, offset,
+  /// pointer to another node in the type DAG.
+  llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent);
+
 public:
   CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
               const CodeGenOptions &CGO,
@@ -105,10 +112,13 @@
 
   /// Get the MDNode in the type DAG for given struct type QType.
   llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
-  /// Get the tag MDNode for a given base type, the actual sclar access MDNode
+  /// Get the tag MDNode for a given base type, the actual scalar access MDNode
   /// and offset into the base type.
   llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
                                      llvm::MDNode *AccessNode, uint64_t Offset);
+
+  /// Get the sclar tag MDNode for a given scalar type.
+  llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);
 };
 
 }  // end namespace CodeGen