bricci created this revision.
bricci added reviewers: arphaman, bkramer, rsmith.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D49302

Files:
  include/clang/AST/CXXInheritance.h
  lib/AST/CXXInheritance.cpp

Index: lib/AST/CXXInheritance.cpp
===================================================================
--- lib/AST/CXXInheritance.cpp
+++ lib/AST/CXXInheritance.cpp
@@ -40,7 +40,7 @@
   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());
 
@@ -63,8 +63,8 @@
 /// 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.
@@ -217,30 +217,31 @@
     
     // 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;
       Element.Base = &BaseSpec;
       Element.Class = Record;
       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.
Index: include/clang/AST/CXXInheritance.h
===================================================================
--- include/clang/AST/CXXInheritance.h
+++ include/clang/AST/CXXInheritance.h
@@ -127,16 +127,34 @@
   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
@@ -152,20 +170,7 @@
   /// 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,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to