Author: Teresa Johnson Date: 2020-11-24T12:06:24-08:00 New Revision: 0768b0576a938b6a4832884384fcb02cd2f74e09
URL: https://github.com/llvm/llvm-project/commit/0768b0576a938b6a4832884384fcb02cd2f74e09 DIFF: https://github.com/llvm/llvm-project/commit/0768b0576a938b6a4832884384fcb02cd2f74e09.diff LOG: Avoid redundant work when computing vtable vcall visibility Add a Visited set to avoid repeatedly processing the same base classes in complex class hierarchies. This cut down the compile time of one source file from >12min to ~1min. Differential Revision: https://reviews.llvm.org/D91676 Added: Modified: clang/lib/CodeGen/CGVTables.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/CodeGen/MicrosoftCXXABI.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 65b3b0c5f53d..75afc860cc47 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -1294,8 +1294,16 @@ bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) { return !HasLTOVisibilityPublicStd(RD); } -llvm::GlobalObject::VCallVisibility -CodeGenModule::GetVCallVisibilityLevel(const CXXRecordDecl *RD) { +llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel( + const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) { + // If we have already visited this RD (which means this is a recursive call + // since the initial call should have an empty Visited set), return the max + // visibility. The recursive calls below compute the min between the result + // of the recursive call and the current TypeVis, so returning the max here + // ensures that it will have no effect on the current TypeVis. + if (!Visited.insert(RD).second) + return llvm::GlobalObject::VCallVisibilityTranslationUnit; + LinkageInfo LV = RD->getLinkageAndVisibility(); llvm::GlobalObject::VCallVisibility TypeVis; if (!isExternallyVisible(LV.getLinkage())) @@ -1307,13 +1315,15 @@ CodeGenModule::GetVCallVisibilityLevel(const CXXRecordDecl *RD) { for (auto B : RD->bases()) if (B.getType()->getAsCXXRecordDecl()->isDynamicClass()) - TypeVis = std::min(TypeVis, - GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl())); + TypeVis = std::min( + TypeVis, + GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited)); for (auto B : RD->vbases()) if (B.getType()->getAsCXXRecordDecl()->isDynamicClass()) - TypeVis = std::min(TypeVis, - GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl())); + TypeVis = std::min( + TypeVis, + GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited)); return TypeVis; } @@ -1382,7 +1392,9 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD, if (getCodeGenOpts().VirtualFunctionElimination || getCodeGenOpts().WholeProgramVTables) { - llvm::GlobalObject::VCallVisibility TypeVis = GetVCallVisibilityLevel(RD); + llvm::DenseSet<const CXXRecordDecl *> Visited; + llvm::GlobalObject::VCallVisibility TypeVis = + GetVCallVisibilityLevel(RD, Visited); if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic) VTable->setVCallVisibilityMetadata(TypeVis); } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 7d812b6658dc..c59570598b0d 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1333,8 +1333,11 @@ class CodeGenModule : public CodeGenTypeCache { /// a virtual function call could be made which ends up being dispatched to a /// member function of this class. This scope can be wider than the visibility /// of the class itself when the class has a more-visible dynamic base class. + /// The client should pass in an empty Visited set, which is used to prevent + /// redundant recursive processing. llvm::GlobalObject::VCallVisibility - GetVCallVisibilityLevel(const CXXRecordDecl *RD); + GetVCallVisibilityLevel(const CXXRecordDecl *RD, + llvm::DenseSet<const CXXRecordDecl *> &Visited); /// Emit type metadata for the given vtable using the given layout. void EmitVTableTypeMetadata(const CXXRecordDecl *RD, diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 8046b7afce57..c16c72dc93d5 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1649,8 +1649,9 @@ void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info, // TODO: Should VirtualFunctionElimination also be supported here? // See similar handling in CodeGenModule::EmitVTableTypeMetadata. if (CGM.getCodeGenOpts().WholeProgramVTables) { + llvm::DenseSet<const CXXRecordDecl *> Visited; llvm::GlobalObject::VCallVisibility TypeVis = - CGM.GetVCallVisibilityLevel(RD); + CGM.GetVCallVisibilityLevel(RD, Visited); if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic) VTable->setVCallVisibilityMetadata(TypeVis); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits