Skip to content

Commit

Permalink
[AST] Store the OwnedTagDecl as a trailing object in ElaboratedType.
Browse files Browse the repository at this point in the history
The TagDecl *OwnedTagDecl in ElaboratedType is quite commonly
null (at least when parsing all of Boost, it is non-null for only about 600
of the 66k ElaboratedType). Therefore we can save a pointer in the
common case by storing it as a trailing object, and storing a bit in the
bit-fields of Type indicating when the pointer is null.

Reviewed By: rjmccall

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

llvm-svn: 339862
  • Loading branch information
riccibruno committed Aug 16, 2018
1 parent 08672ec commit d6bd598
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 20 deletions.
58 changes: 40 additions & 18 deletions clang/include/clang/AST/Type.h
Expand Up @@ -45,6 +45,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -1573,6 +1574,16 @@ class Type : public ExtQualsTypeCommonBase {

enum { NumTypeWithKeywordBits = 8 };

class ElaboratedTypeBitfields {
friend class ElaboratedType;

unsigned : NumTypeBits;
unsigned : NumTypeWithKeywordBits;

/// Whether the ElaboratedType has a trailing OwnedTagDecl.
unsigned HasOwnedTagDecl : 1;
};

class VectorTypeBitfields {
friend class VectorType;
friend class DependentVectorType;
Expand Down Expand Up @@ -1686,6 +1697,7 @@ class Type : public ExtQualsTypeCommonBase {
ObjCObjectTypeBitfields ObjCObjectTypeBits;
ReferenceTypeBitfields ReferenceTypeBits;
TypeWithKeywordBitfields TypeWithKeywordBits;
ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
Expand All @@ -1711,6 +1723,8 @@ class Type : public ExtQualsTypeCommonBase {
"ReferenceTypeBitfields is larger than 8 bytes!");
static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
"TypeWithKeywordBitfields is larger than 8 bytes!");
static_assert(sizeof(ElaboratedTypeBitfields) <= 8,
"ElaboratedTypeBitfields is larger than 8 bytes!");
static_assert(sizeof(VectorTypeBitfields) <= 8,
"VectorTypeBitfields is larger than 8 bytes!");
static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8,
Expand Down Expand Up @@ -5028,35 +5042,42 @@ class TypeWithKeyword : public Type {
/// source code, including tag keywords and any nested-name-specifiers.
/// The type itself is always "sugar", used to express what was written
/// in the source code but containing no additional semantic information.
class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
class ElaboratedType final
: public TypeWithKeyword,
public llvm::FoldingSetNode,
private llvm::TrailingObjects<ElaboratedType, TagDecl *> {
friend class ASTContext; // ASTContext creates these
friend TrailingObjects;

/// The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;

/// The type that this qualified name refers to.
QualType NamedType;

/// The (re)declaration of this tag type owned by this occurrence, or nullptr
/// if none.
TagDecl *OwnedTagDecl;
/// The (re)declaration of this tag type owned by this occurrence is stored
/// as a trailing object if there is one. Use getOwnedTagDecl to obtain
/// it, or obtain a null pointer if there is none.

ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
: TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->isDependentType(),
NamedType->isInstantiationDependentType(),
NamedType->isVariablyModifiedType(),
NamedType->containsUnexpandedParameterPack()),
NNS(NNS), NamedType(NamedType), OwnedTagDecl(OwnedTagDecl) {
: TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->isDependentType(),
NamedType->isInstantiationDependentType(),
NamedType->isVariablyModifiedType(),
NamedType->containsUnexpandedParameterPack()),
NNS(NNS), NamedType(NamedType) {
ElaboratedTypeBits.HasOwnedTagDecl = false;
if (OwnedTagDecl) {
ElaboratedTypeBits.HasOwnedTagDecl = true;
*getTrailingObjects<TagDecl *>() = OwnedTagDecl;
}
assert(!(Keyword == ETK_None && NNS == nullptr) &&
"ElaboratedType cannot have elaborated type keyword "
"and name qualifier both null.");
}

public:
~ElaboratedType();

/// Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }

Expand All @@ -5070,11 +5091,14 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
bool isSugared() const { return true; }

/// Return the (re)declaration of this type owned by this occurrence of this
/// type, or nullptr if none.
TagDecl *getOwnedTagDecl() const { return OwnedTagDecl; }
/// type, or nullptr if there is none.
TagDecl *getOwnedTagDecl() const {
return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects<TagDecl *>()
: nullptr;
}

void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getKeyword(), NNS, NamedType, OwnedTagDecl);
Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl());
}

static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
Expand All @@ -5086,9 +5110,7 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
ID.AddPointer(OwnedTagDecl);
}

static bool classof(const Type *T) {
return T->getTypeClass() == Elaborated;
}
static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
};

/// Represents a qualified type name for which the type name is
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/AST/ASTContext.cpp
Expand Up @@ -4136,8 +4136,10 @@ QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
(void)CheckT;
}

T = new (*this, TypeAlignment)
ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
void *Mem = Allocate(ElaboratedType::totalSizeToAlloc<TagDecl *>(!!OwnedTagDecl),
TypeAlignment);
T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);

Types.push_back(T);
ElaboratedTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
Expand Down

0 comments on commit d6bd598

Please sign in to comment.