From: Douglas Gregor Date: Thu, 8 Apr 2010 15:52:03 +0000 (+0000) Subject: Eliminate excessive PCH deserialization caused by the search for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1e201b4a9d4880c3f90ab77e8a308140f003c7da;p=clang Eliminate excessive PCH deserialization caused by the search for __cxxabiv1::__fundamental_type_info in every translation unit. Previously, we would perform name lookup for __cxxabiv1::__fundamental_type_info at the end of IRGen for a each translation unit, to determine whether it was present. If so, we we produce type information for all of the fundamental types. However, this name lookup causes PCH deserialization of a significant part of the translation unit, which has a woeful impact on performance. With this change, we now look at each record type after we've generated its vtable to see if it is __cxxabiv1::__fundamental_type_info. If so, we generate type info for all of the fundamental types. This works because __cxxabiv1::__fundamental_type_info should always have a key function (typically the virtual destructor), that will be defined once in the support library. The fundamental type information will end up there. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100772 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 1caec97fc3..4e24bd26aa 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -791,35 +791,6 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) { return RTTIBuilder(*this).BuildTypeInfo(Ty); } -// Try to find the magic class __cxxabiv1::__fundamental_type_info. If -// exists and has a destructor, we will emit the typeinfo for the fundamental -// types. This is the same behaviour as GCC. -static CXXRecordDecl *FindMagicClass(ASTContext &AC) { - const IdentifierInfo &NamespaceII = AC.Idents.get("__cxxabiv1"); - DeclarationName NamespaceDN = AC.DeclarationNames.getIdentifier(&NamespaceII); - TranslationUnitDecl *TUD = AC.getTranslationUnitDecl(); - DeclContext::lookup_result NamespaceLookup = TUD->lookup(NamespaceDN); - if (NamespaceLookup.first == NamespaceLookup.second) - return NULL; - const NamespaceDecl *Namespace = - dyn_cast(*NamespaceLookup.first); - if (!Namespace) - return NULL; - - const IdentifierInfo &ClassII = AC.Idents.get("__fundamental_type_info"); - DeclarationName ClassDN = AC.DeclarationNames.getIdentifier(&ClassII); - DeclContext::lookup_const_result ClassLookup = Namespace->lookup(ClassDN); - if (ClassLookup.first == ClassLookup.second) - return NULL; - CXXRecordDecl *Class = dyn_cast(*ClassLookup.first); - - if (Class->hasDefinition() && Class->isDynamicClass() && - Class->getDestructor(AC)) - return Class; - - return NULL; -} - void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) { QualType PointerType = Context.getPointerType(Type); QualType PointerTypeConst = Context.getPointerType(Type.withConst()); @@ -829,12 +800,6 @@ void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) { } void CodeGenModule::EmitFundamentalRTTIDescriptors() { - CXXRecordDecl *RD = FindMagicClass(getContext()); - if (!RD) - return; - - getVTables().GenerateClassData(getVtableLinkage(RD), RD); - QualType FundamentalTypes[] = { Context.VoidTy, Context.Char32Ty, Context.Char16Ty, Context.UnsignedLongLongTy, Context.LongLongTy, Context.WCharTy, diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index fc6d1a8e37..e23289a01a 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3121,6 +3121,18 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, EmitVTableDefinition(VTable, Linkage, RD); GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); + + // If this is the magic class __cxxabiv1::__fundamental_type_info, + // we will emit the typeinfo for the fundamental types. This is the + // same behaviour as GCC. + const DeclContext *DC = RD->getDeclContext(); + if (RD->getIdentifier() && + RD->getIdentifier()->isStr("__fundamental_type_info") && + isa(DC) && + cast(DC)->getIdentifier() && + cast(DC)->getIdentifier()->isStr("__cxxabiv1") && + DC->getParent()->isTranslationUnit()) + CGM.EmitFundamentalRTTIDescriptors(); } void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) { diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index a2ad31e85a..1cb7089210 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -78,7 +78,6 @@ void CodeGenModule::createObjCRuntime() { } void CodeGenModule::Release() { - EmitFundamentalRTTIDescriptors(); EmitDeferred(); EmitCXXGlobalInitFunc(); EmitCXXGlobalDtorFunc(); diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp index 473f48db67..6826321cd5 100644 --- a/test/CodeGenCXX/rtti-fundamental.cpp +++ b/test/CodeGenCXX/rtti-fundamental.cpp @@ -8,8 +8,10 @@ std::type_info foo() { namespace __cxxabiv1 { struct __fundamental_type_info { - virtual ~__fundamental_type_info() {} + virtual ~__fundamental_type_info(); }; + + __fundamental_type_info::~__fundamental_type_info() { } } // CHECK: @_ZTIv = weak_odr constant