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