r318752 - [CodeGen] Generate TBAA type descriptors in a more reliable manner

Ivan A. Kosarev via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 21 03:18:07 PST 2017


Author: kosarev
Date: Tue Nov 21 03:18:06 2017
New Revision: 318752

URL: http://llvm.org/viewvc/llvm-project?rev=318752&view=rev
Log:
[CodeGen] Generate TBAA type descriptors in a more reliable manner

This patch introduces a couple of helper functions that make it
possible to handle the caching logic in a single place.

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

Modified:
    cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
    cfe/trunk/lib/CodeGen/CodeGenTBAA.h

Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp?rev=318752&r1=318751&r2=318752&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTBAA.cpp Tue Nov 21 03:18:06 2017
@@ -107,29 +107,7 @@ static bool isValidBaseType(QualType QTy
   return false;
 }
 
-llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
-  // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
-  if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
-    return nullptr;
-
-  // If the type has the may_alias attribute (even on a typedef), it is
-  // effectively in the general char alias class.
-  if (TypeHasMayAlias(QTy))
-    return getChar();
-
-  // We need this function to not fall back to returning the "omnipotent char"
-  // type node for aggregate and union types. Otherwise, any dereference of an
-  // aggregate will result into the may-alias access descriptor, meaning all
-  // subsequent accesses to direct and indirect members of that aggregate will
-  // be considered may-alias too.
-  // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function.
-  if (isValidBaseType(QTy))
-    return getBaseTypeInfo(QTy);
-
-  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  if (llvm::MDNode *N = MetadataCache[Ty])
-    return N;
-
+llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
   // Handle builtin types.
   if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
     switch (BTy->getKind()) {
@@ -160,8 +138,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(Q
     // treating wchar_t, char16_t, and char32_t as distinct from their
     // "underlying types".
     default:
-      return MetadataCache[Ty] =
-        createTBAAScalarType(BTy->getName(Features), getChar());
+      return createTBAAScalarType(BTy->getName(Features), getChar());
     }
   }
 
@@ -169,14 +146,13 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(Q
   // an object through a glvalue of other than one of the following types the
   // behavior is undefined: [...] a char, unsigned char, or std::byte type."
   if (Ty->isStdByteType())
-    return MetadataCache[Ty] = getChar();
+    return getChar();
 
   // Handle pointers and references.
   // TODO: Implement C++'s type "similarity" and consider dis-"similar"
   // pointers distinct.
   if (Ty->isPointerType() || Ty->isReferenceType())
-    return MetadataCache[Ty] = createTBAAScalarType("any pointer",
-                                                    getChar());
+    return createTBAAScalarType("any pointer", getChar());
 
   // Enum types are distinct types. In C++ they have "underlying types",
   // however they aren't related for TBAA.
@@ -186,16 +162,46 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(Q
     // TODO: Is there a way to get a program-wide unique name for a
     // decl with local linkage or no linkage?
     if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())
-      return MetadataCache[Ty] = getChar();
+      return getChar();
 
     SmallString<256> OutName;
     llvm::raw_svector_ostream Out(OutName);
     MContext.mangleTypeName(QualType(ETy, 0), Out);
-    return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar());
+    return createTBAAScalarType(OutName, getChar());
   }
 
   // For now, handle any other kind of type conservatively.
-  return MetadataCache[Ty] = getChar();
+  return getChar();
+}
+
+llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
+  // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
+  if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
+    return nullptr;
+
+  // If the type has the may_alias attribute (even on a typedef), it is
+  // effectively in the general char alias class.
+  if (TypeHasMayAlias(QTy))
+    return getChar();
+
+  // We need this function to not fall back to returning the "omnipotent char"
+  // type node for aggregate and union types. Otherwise, any dereference of an
+  // aggregate will result into the may-alias access descriptor, meaning all
+  // subsequent accesses to direct and indirect members of that aggregate will
+  // be considered may-alias too.
+  // TODO: Combine getTypeInfo() and getBaseTypeInfo() into a single function.
+  if (isValidBaseType(QTy))
+    return getBaseTypeInfo(QTy);
+
+  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
+  if (llvm::MDNode *N = MetadataCache[Ty])
+    return N;
+
+  // Note that the following helper call is allowed to add new nodes to the
+  // cache, which invalidates all its previously obtained iterators. So we
+  // first generate the node for the type and then add that node to the cache.
+  llvm::MDNode *TypeNode = getTypeInfoHelper(Ty);
+  return MetadataCache[Ty] = TypeNode;
 }
 
 TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() {
@@ -259,15 +265,8 @@ CodeGenTBAA::getTBAAStructInfo(QualType
   return StructMetadataCache[Ty] = nullptr;
 }
 
-llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
-  if (!isValidBaseType(QTy))
-    return nullptr;
-
-  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-  if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
-    return N;
-
-  if (const RecordType *TTy = QTy->getAs<RecordType>()) {
+llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
+  if (auto *TTy = dyn_cast<RecordType>(Ty)) {
     const RecordDecl *RD = TTy->getDecl()->getDefinition();
 
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
@@ -293,11 +292,25 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeIn
       OutName = RD->getName();
     }
     // Create the struct type node with a vector of pairs (offset, type).
-    return BaseTypeMetadataCache[Ty] =
-      MDHelper.createTBAAStructTypeNode(OutName, Fields);
+    return MDHelper.createTBAAStructTypeNode(OutName, Fields);
   }
 
-  return BaseTypeMetadataCache[Ty] = nullptr;
+  return nullptr;
+}
+
+llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
+  if (!isValidBaseType(QTy))
+    return nullptr;
+
+  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
+  if (llvm::MDNode *N = BaseTypeMetadataCache[Ty])
+    return N;
+
+  // Note that the following helper call is allowed to add new nodes to the
+  // cache, which invalidates all its previously obtained iterators. So we
+  // first generate the node for the type and then add that node to the cache.
+  llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
+  return BaseTypeMetadataCache[Ty] = TypeNode;
 }
 
 llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {

Modified: cfe/trunk/lib/CodeGen/CodeGenTBAA.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTBAA.h?rev=318752&r1=318751&r2=318752&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTBAA.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTBAA.h Tue Nov 21 03:18:06 2017
@@ -143,6 +143,14 @@ class CodeGenTBAA {
   /// pointer to another node in the type DAG.
   llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent);
 
+  /// getTypeInfoHelper - An internal helper function to generate metadata used
+  /// to describe accesses to objects of the given type.
+  llvm::MDNode *getTypeInfoHelper(const Type *Ty);
+
+  /// getBaseTypeInfoHelper - An internal helper function to generate metadata
+  /// used to describe accesses to objects of the given base type.
+  llvm::MDNode *getBaseTypeInfoHelper(const Type *Ty);
+
 public:
   CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
               const CodeGenOptions &CGO,




More information about the cfe-commits mailing list