Skip to content

Commit

Permalink
[AST] Various micro-optimizations in CXXInheritance
Browse files Browse the repository at this point in the history
1. Pack std::pair<bool, unsigned> in CXXBasePaths::ClassSubobjects.
2. Use a SmallPtrSet instead of a SmallDenseSet for CXXBasePaths::VisitedDependentRecords.
3. Reorder some members of CXXBasePaths to save 8 bytes.
4. Use a SmallSetVector instead of a SetVector in CXXBasePaths::ComputeDeclsFound to avoid some allocations.

This speeds up an -fsyntax-only on all of Boost by approx 0.15%,
mainly by speeding up CXXBasePaths::lookupInBases by
approx 10%. No functional changes.

Patch by Bruno Ricci!

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

llvm-svn: 337607
  • Loading branch information
d0k committed Jul 20, 2018
1 parent 31d5284 commit 1b2bc60
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 28 deletions.
41 changes: 23 additions & 18 deletions clang/include/clang/AST/CXXInheritance.h
Expand Up @@ -125,18 +125,36 @@ class CXXBasePaths {
/// Paths - The actual set of paths that can be taken from the
/// derived class to the same base class.
std::list<CXXBasePath> Paths;

/// ClassSubobjects - Records the class subobjects for each class
/// type that we've seen. The first element in the pair says
/// type that we've seen. The first element IsVirtBase says
/// whether we found a path to a virtual base for that class type,
/// while the element contains the number of non-virtual base
/// while NumberOfNonVirtBases contains the number of non-virtual base
/// class subobjects for that class type. The key of the map is
/// the cv-unqualified canonical type of the base class subobject.
llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
struct IsVirtBaseAndNumberNonVirtBases {
unsigned IsVirtBase : 1;
unsigned NumberOfNonVirtBases : 31;
};
llvm::SmallDenseMap<QualType, IsVirtBaseAndNumberNonVirtBases, 8>
ClassSubobjects;

/// VisitedDependentRecords - Records the dependent records that have been
/// already visited.
llvm::SmallDenseSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedDependentRecords;

/// DetectedVirtual - The base class that is virtual.
const RecordType *DetectedVirtual = nullptr;

/// ScratchPath - A BasePath that is used by Sema::lookupInBases
/// to help build the set of paths.
CXXBasePath ScratchPath;

/// Array of the declarations that have been found. This
/// array is constructed only if needed, e.g., to iterate over the
/// results within LookupResult.
std::unique_ptr<NamedDecl *[]> DeclsFound;
unsigned NumDeclsFound = 0;

/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
/// ambiguous paths while it is looking for a path from a derived
Expand All @@ -152,20 +170,7 @@ class CXXBasePaths {
/// if it finds a path that goes across a virtual base. The virtual class
/// is also recorded.
bool DetectVirtual;

/// ScratchPath - A BasePath that is used by Sema::lookupInBases
/// to help build the set of paths.
CXXBasePath ScratchPath;

/// DetectedVirtual - The base class that is virtual.
const RecordType *DetectedVirtual = nullptr;

/// Array of the declarations that have been found. This
/// array is constructed only if needed, e.g., to iterate over the
/// results within LookupResult.
std::unique_ptr<NamedDecl *[]> DeclsFound;
unsigned NumDeclsFound = 0;

void ComputeDeclsFound();

bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
Expand Down
20 changes: 10 additions & 10 deletions clang/lib/AST/CXXInheritance.cpp
Expand Up @@ -40,7 +40,7 @@ void CXXBasePaths::ComputeDeclsFound() {
assert(NumDeclsFound == 0 && !DeclsFound &&
"Already computed the set of declarations");

llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8>> Decls;
llvm::SmallSetVector<NamedDecl *, 8> Decls;
for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path)
Decls.insert(Path->Decls.front());

Expand All @@ -63,8 +63,8 @@ CXXBasePaths::decl_range CXXBasePaths::found_decls() {
/// an unqualified, canonical class type.
bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
BaseType = BaseType.getUnqualifiedType();
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
IsVirtBaseAndNumberNonVirtBases Subobjects = ClassSubobjects[BaseType];
return Subobjects.NumberOfNonVirtBases + (Subobjects.IsVirtBase ? 1 : 0) > 1;
}

/// clear - Clear out all prior path information.
Expand Down Expand Up @@ -217,21 +217,21 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,

// Determine whether we need to visit this base class at all,
// updating the count of subobjects appropriately.
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
IsVirtBaseAndNumberNonVirtBases &Subobjects = ClassSubobjects[BaseType];
bool VisitBase = true;
bool SetVirtual = false;
if (BaseSpec.isVirtual()) {
VisitBase = !Subobjects.first;
Subobjects.first = true;
VisitBase = !Subobjects.IsVirtBase;
Subobjects.IsVirtBase = true;
if (isDetectingVirtual() && DetectedVirtual == nullptr) {
// If this is the first virtual we find, remember it. If it turns out
// there is no base path here, we'll reset it later.
DetectedVirtual = BaseType->getAs<RecordType>();
SetVirtual = true;
}
} else
++Subobjects.second;

} else {
++Subobjects.NumberOfNonVirtBases;
}
if (isRecordingPaths()) {
// Add this base specifier to the current path.
CXXBasePathElement Element;
Expand All @@ -240,7 +240,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
if (BaseSpec.isVirtual())
Element.SubobjectNumber = 0;
else
Element.SubobjectNumber = Subobjects.second;
Element.SubobjectNumber = Subobjects.NumberOfNonVirtBases;
ScratchPath.push_back(Element);

// Calculate the "top-down" access to this base class.
Expand Down

0 comments on commit 1b2bc60

Please sign in to comment.