[cfe-commits] r150752 - in /cfe/trunk: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
Chad Rosier
mcrosier at apple.com
Thu Feb 16 16:19:24 PST 2012
*begins thinking of very _mean_ words to say to Eric if and when the compile-time regressions come* ;)
Chad
On Feb 16, 2012, at 2:54 PM, Eric Christopher wrote:
> Author: echristo
> Date: Thu Feb 16 16:54:45 2012
> New Revision: 150752
>
> URL: http://llvm.org/viewvc/llvm-project?rev=150752&view=rev
> Log:
> Reapply r150631:
>
> "Add a completed/incomplete type difference. This allows us to have
> partial types for contexts and forward decls while allowing us to
> complete types later on for debug purposes.
>
> This piggy-backs on the metadata replacement and rauw changes
> for temporary nodes and takes advantage of the incremental
> support I added in earlier. This allows us to, if we decide,
> to limit adding methods and variables to structures in order
> to limit the amount of debug information output into a .o file.
>
> The caching is a bit complicated though so any thoughts on
> untangling that are welcome."
>
> with a fix:
>
> - Remove all RAUW during type construction by adding stub versions
> of types that we later complete.
>
> and some TODOs:
>
> - Add an RAUW cache for forward declared types so that we can replace
> them at the end of compilation.
> - Remove the code that updates on completed types because we no
> longer need to have that happen. We emit incomplete types on
> purpose and only want to know when we want to complete them.
>
> Modified:
> cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
> cfe/trunk/lib/CodeGen/CGDebugInfo.h
> cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=150752&r1=150751&r2=150752&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Feb 16 16:54:45 2012
> @@ -524,11 +524,8 @@
>
> if (const RecordDecl *RD = dyn_cast<RecordDecl>(Context)) {
> if (!RD->isDependentType()) {
> - llvm::DIDescriptor FDContext =
> - createContextChain(cast<Decl>(RD->getDeclContext()));
> - llvm::DIType Ty = createRecordFwdDecl(RD, FDContext);
> -
> - RegionMap[Context] = llvm::WeakVH(Ty);
> + llvm::DIType Ty = getOrCreateLimitedType(CGM.getContext().getTypeDeclType(RD),
> + getOrCreateMainFile());
> return llvm::DIDescriptor(Ty);
> }
> }
> @@ -557,7 +554,9 @@
> RecordDecl *RD = RTy->getDecl();
> llvm::DIDescriptor FDContext =
> getContextDescriptor(cast<Decl>(RD->getDeclContext()));
> - return createRecordFwdDecl(RD, FDContext);
> + llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext);
> + TypeCache[PointeeTy.getAsOpaquePtr()] = RetTy;
> + return RetTy;
> }
> return getOrCreateType(PointeeTy, Unit);
>
> @@ -654,10 +653,11 @@
> // declared.
> unsigned Line = getLineNumber(Ty->getDecl()->getLocation());
> const TypedefNameDecl *TyDecl = Ty->getDecl();
> +
> llvm::DIDescriptor TypedefContext =
> getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext()));
> -
> - return
> +
> + return
> DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);
> }
>
> @@ -1133,8 +1133,6 @@
>
> // Get overall information about the record type for the debug info.
> llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
> - unsigned Line = getLineNumber(RD->getLocation());
> - StringRef RDName = RD->getName();
>
> // Records and classes and unions can all be recursive. To handle them, we
> // first generate a debug descriptor for the struct as a forward declaration.
> @@ -1143,28 +1141,21 @@
> // may refer to the forward decl if the struct is recursive) and replace all
> // uses of the forward declaration with the final definition.
>
> - llvm::DIDescriptor RDContext;
> - if (CGM.getCodeGenOpts().LimitDebugInfo)
> - RDContext = createContextChain(cast<Decl>(RD->getDeclContext()));
> - else
> - RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));
> -
> - // If this is just a forward declaration, construct an appropriately
> - // marked node and just return it.
> - if (!RD->getDefinition())
> - return createRecordFwdDecl(RD, RDContext);
> -
> - llvm::DIType FwdDecl = DBuilder.createTemporaryType(DefUnit);
> + llvm::DIType FwdDecl = getOrCreateLimitedType(QualType(Ty, 0), DefUnit);
>
> + if (FwdDecl.isForwardDecl())
> + return FwdDecl;
> +
> llvm::MDNode *MN = FwdDecl;
> llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
> - // Otherwise, insert it into the TypeCache so that recursive uses will find
> - // it.
> - TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
> +
> // Push the struct on region stack.
> LexicalBlockStack.push_back(FwdDeclNode);
> RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
>
> + // Add this to the completed types cache since we're completing it.
> + CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
> +
> // Convert all the elements.
> SmallVector<llvm::Value *, 16> EltTys;
>
> @@ -1196,50 +1187,20 @@
> if (RI != RegionMap.end())
> RegionMap.erase(RI);
>
> - uint64_t Size = CGM.getContext().getTypeSize(Ty);
> - uint64_t Align = CGM.getContext().getTypeAlign(Ty);
> llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
> - llvm::MDNode *RealDecl = NULL;
> -
> + // FIXME: Magic numbers ahoy! These should be changed when we
> + // get some enums in llvm/Analysis/DebugInfo.h to refer to
> + // them.
> if (RD->isUnion())
> - RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line,
> - Size, Align, 0, Elements);
> + MN->replaceOperandWith(10, Elements);
> else if (CXXDecl) {
> - RDName = getClassName(RD);
> - // A class's primary base or the class itself contains the vtable.
> - llvm::MDNode *ContainingType = NULL;
> - const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
> - if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
> - // Seek non virtual primary base root.
> - while (1) {
> - const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
> - const CXXRecordDecl *PBT = BRL.getPrimaryBase();
> - if (PBT && !BRL.isPrimaryBaseVirtual())
> - PBase = PBT;
> - else
> - break;
> - }
> - ContainingType =
> - getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit);
> - }
> - else if (CXXDecl->isDynamicClass())
> - ContainingType = FwdDecl;
> -
> - // FIXME: This could be a struct type giving a default visibility different
> - // than C++ class type, but needs llvm metadata changes first.
> - RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,
> - Size, Align, 0, 0, llvm::DIType(),
> - Elements, ContainingType,
> - TParamsArray);
> + MN->replaceOperandWith(10, Elements);
> + MN->replaceOperandWith(13, TParamsArray);
> } else
> - RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
> - Size, Align, 0, Elements);
> + MN->replaceOperandWith(10, Elements);
>
> - // Now that we have a real decl for the struct, replace anything using the
> - // old decl with the new one. This will recursively update the debug info.
> - llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl);
> - RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
> - return llvm::DIType(RealDecl);
> + RegionMap[Ty->getDecl()] = llvm::WeakVH(MN);
> + return llvm::DIType(MN);
> }
>
> /// CreateType - get objective-c object type.
> @@ -1274,22 +1235,28 @@
> }
> ID = Def;
>
> - // To handle a recursive interface, we first generate a debug descriptor
> - // for the struct as a forward declaration. Then (if it is a definition)
> - // we go through and get debug info for all of its members. Finally, we
> - // create a descriptor for the complete type (which may refer to the
> - // forward decl if the struct is recursive) and replace all uses of the
> - // forward declaration with the final definition.
> - llvm::DIType FwdDecl = DBuilder.createTemporaryType(DefUnit);
> + // Bit size, align and offset of the type.
> + uint64_t Size = CGM.getContext().getTypeSize(Ty);
> + uint64_t Align = CGM.getContext().getTypeAlign(Ty);
>
> - llvm::MDNode *MN = FwdDecl;
> - llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
> + unsigned Flags = 0;
> + if (ID->getImplementation())
> + Flags |= llvm::DIDescriptor::FlagObjcClassComplete;
> +
> + llvm::DIType RealDecl =
> + DBuilder.createStructType(Unit, ID->getName(), DefUnit,
> + Line, Size, Align, Flags,
> + llvm::DIArray(), RuntimeLang);
> +
> // Otherwise, insert it into the TypeCache so that recursive uses will find
> // it.
> - TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
> + TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RealDecl;
> // Push the struct on region stack.
> + llvm::MDNode *MN = RealDecl;
> + llvm::TrackingVH<llvm::MDNode> FwdDeclNode = MN;
> +
> LexicalBlockStack.push_back(FwdDeclNode);
> - RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
> + RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
>
> // Convert all the elements.
> SmallVector<llvm::Value *, 16> EltTys;
> @@ -1302,7 +1269,7 @@
> return llvm::DIType();
>
> llvm::DIType InhTag =
> - DBuilder.createInheritance(FwdDecl, SClassTy, 0, 0);
> + DBuilder.createInheritance(RealDecl, SClassTy, 0, 0);
> EltTys.push_back(InhTag);
> }
>
> @@ -1381,31 +1348,9 @@
> }
>
> llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
> -
> + RealDecl->replaceOperandWith(10, Elements);
> +
> LexicalBlockStack.pop_back();
> - llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator RI =
> - RegionMap.find(Ty->getDecl());
> - if (RI != RegionMap.end())
> - RegionMap.erase(RI);
> -
> - // Bit size, align and offset of the type.
> - uint64_t Size = CGM.getContext().getTypeSize(Ty);
> - uint64_t Align = CGM.getContext().getTypeAlign(Ty);
> -
> - unsigned Flags = 0;
> - if (ID->getImplementation())
> - Flags |= llvm::DIDescriptor::FlagObjcClassComplete;
> -
> - llvm::DIType RealDecl =
> - DBuilder.createStructType(Unit, ID->getName(), DefUnit,
> - Line, Size, Align, Flags,
> - Elements, RuntimeLang);
> -
> - // Now that we have a real decl for the struct, replace anything using the
> - // old decl with the new one. This will recursively update the debug info.
> - llvm::DIType(FwdDeclNode).replaceAllUsesWith(RealDecl);
> - RegionMap[ID] = llvm::WeakVH(RealDecl);
> -
> return RealDecl;
> }
>
> @@ -1637,6 +1582,26 @@
> return llvm::DIType();
> }
>
> +/// getCompletedTypeOrNull - Get the type from the cache or return null if it
> +/// doesn't exist.
> +llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
> +
> + // Unwrap the type as needed for debug information.
> + Ty = UnwrapTypeForDebugInfo(Ty);
> +
> + // Check for existing entry.
> + llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
> + CompletedTypeCache.find(Ty.getAsOpaquePtr());
> + if (it != CompletedTypeCache.end()) {
> + // Verify that the debug info still exists.
> + if (&*it->second)
> + return llvm::DIType(cast<llvm::MDNode>(it->second));
> + }
> +
> + return llvm::DIType();
> +}
> +
> +
> /// getOrCreateType - Get the type from the cache or create a new
> /// one if necessary.
> llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
> @@ -1646,14 +1611,18 @@
> // Unwrap the type as needed for debug information.
> Ty = UnwrapTypeForDebugInfo(Ty);
>
> - llvm::DIType T = getTypeOrNull(Ty);
> + llvm::DIType T = getCompletedTypeOrNull(Ty);
> +
> if (T.Verify()) return T;
>
> // Otherwise create the type.
> llvm::DIType Res = CreateTypeNode(Ty, Unit);
> -
> +
> // And update the type cache.
> - TypeCache[Ty.getAsOpaquePtr()] = Res;
> + TypeCache[Ty.getAsOpaquePtr()] = Res;
> +
> + if (!Res.isForwardDecl())
> + CompletedTypeCache[Ty.getAsOpaquePtr()] = Res;
> return Res;
> }
>
> @@ -1737,6 +1706,123 @@
> return llvm::DIType();
> }
>
> +/// getOrCreateLimitedType - Get the type from the cache or create a new
> +/// limited type if necessary.
> +llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty,
> + llvm::DIFile Unit) {
> + if (Ty.isNull())
> + return llvm::DIType();
> +
> + // Unwrap the type as needed for debug information.
> + Ty = UnwrapTypeForDebugInfo(Ty);
> +
> + llvm::DIType T = getTypeOrNull(Ty);
> +
> + // We may have cached a forward decl when we could have created
> + // a non-forward decl. Go ahead and create a non-forward decl
> + // now.
> + if (T.Verify() && !T.isForwardDecl()) return T;
> +
> + // Otherwise create the type.
> + llvm::DIType Res = CreateLimitedTypeNode(Ty, Unit);
> +
> + // And update the type cache.
> + TypeCache[Ty.getAsOpaquePtr()] = Res;
> + return Res;
> +}
> +
> +// TODO: Currently used for context chains when limiting debug info.
> +llvm::DIType CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
> + RecordDecl *RD = Ty->getDecl();
> +
> + // Get overall information about the record type for the debug info.
> + llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
> + unsigned Line = getLineNumber(RD->getLocation());
> + StringRef RDName = RD->getName();
> +
> + llvm::DIDescriptor RDContext;
> + if (CGM.getCodeGenOpts().LimitDebugInfo)
> + RDContext = createContextChain(cast<Decl>(RD->getDeclContext()));
> + else
> + RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));
> +
> + // If this is just a forward declaration, construct an appropriately
> + // marked node and just return it.
> + if (!RD->getDefinition()) {
> + llvm::DIType RTy = createRecordFwdDecl(RD, RDContext);
> + TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RTy;
> + return RTy;
> + }
> +
> + uint64_t Size = CGM.getContext().getTypeSize(Ty);
> + uint64_t Align = CGM.getContext().getTypeAlign(Ty);
> + const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
> + llvm::MDNode *RealDecl = NULL;
> +
> + if (RD->isUnion())
> + RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line,
> + Size, Align, 0, llvm::DIArray());
> + else if (CXXDecl) {
> + RDName = getClassName(RD);
> +
> + // FIXME: This could be a struct type giving a default visibility different
> + // than C++ class type, but needs llvm metadata changes first.
> + RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,
> + Size, Align, 0, 0, llvm::DIType(),
> + llvm::DIArray(), NULL,
> + llvm::DIArray());
> + } else
> + RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
> + Size, Align, 0, llvm::DIArray());
> +
> + RegionMap[Ty->getDecl()] = llvm::WeakVH(RealDecl);
> + TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = llvm::DIType(RealDecl);
> +
> + if (CXXDecl) {
> + // A class's primary base or the class itself contains the vtable.
> + llvm::MDNode *ContainingType = NULL;
> + const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
> + if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
> + // Seek non virtual primary base root.
> + while (1) {
> + const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
> + const CXXRecordDecl *PBT = BRL.getPrimaryBase();
> + if (PBT && !BRL.isPrimaryBaseVirtual())
> + PBase = PBT;
> + else
> + break;
> + }
> + ContainingType =
> + getOrCreateType(QualType(PBase->getTypeForDecl(), 0), DefUnit);
> + }
> + else if (CXXDecl->isDynamicClass())
> + ContainingType = RealDecl;
> +
> + RealDecl->replaceOperandWith(9, ContainingType);
> + }
> + return llvm::DIType(RealDecl);
> +}
> +
> +/// CreateLimitedTypeNode - Create a new debug type node, but only forward
> +/// declare composite types that haven't been processed yet.
> +llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) {
> +
> + // Work out details of type.
> + switch (Ty->getTypeClass()) {
> +#define TYPE(Class, Base)
> +#define ABSTRACT_TYPE(Class, Base)
> +#define NON_CANONICAL_TYPE(Class, Base)
> +#define DEPENDENT_TYPE(Class, Base) case Type::Class:
> + #include "clang/AST/TypeNodes.def"
> + llvm_unreachable("Dependent types cannot show up in debug information");
> +
> + case Type::Record:
> + return CreateLimitedType(cast<RecordType>(Ty));
> + default:
> + return CreateTypeNode(Ty, Unit);
> + }
> +}
> +
> /// CreateMemberType - Create new member and increase Offset by FType's size.
> llvm::DIType CGDebugInfo::CreateMemberType(llvm::DIFile Unit, QualType FType,
> StringRef Name,
>
> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=150752&r1=150751&r2=150752&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Thu Feb 16 16:54:45 2012
> @@ -53,6 +53,9 @@
> /// TypeCache - Cache of previously constructed Types.
> llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
>
> + /// CompleteTypeCache - Cache of previously constructed complete RecordTypes.
> + llvm::DenseMap<void *, llvm::WeakVH> CompletedTypeCache;
> +
> bool BlockLiteralGenericSet;
> llvm::DIType BlockLiteralGeneric;
>
> @@ -84,6 +87,7 @@
> llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
> llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
> llvm::DIType CreateType(const RecordType *Ty);
> + llvm::DIType CreateLimitedType(const RecordType *Ty);
> llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
> llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
> llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
> @@ -94,6 +98,7 @@
> llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
> llvm::DIType CreateEnumType(const EnumDecl *ED);
> llvm::DIType getTypeOrNull(const QualType);
> + llvm::DIType getCompletedTypeOrNull(const QualType);
> llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
> llvm::DIFile F);
> llvm::DIType getOrCreateFunctionType(const Decl *D, QualType FnType,
> @@ -257,9 +262,17 @@
> /// necessary.
> llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);
>
> + /// getOrCreateLimitedType - Get the type from the cache or create a new
> + /// partial type if necessary.
> + llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F);
> +
> /// CreateTypeNode - Create type metadata for a source language type.
> llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
>
> + /// CreateLimitedTypeNode - Create type metadata for a source language
> + /// type, but only partial types for records.
> + llvm::DIType CreateLimitedTypeNode(QualType Ty, llvm::DIFile F);
> +
> /// CreateMemberType - Create new member and increase Offset by FType's size.
> llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,
> StringRef Name, uint64_t *Offset);
>
> Modified: cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp?rev=150752&r1=150751&r2=150752&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp Thu Feb 16 16:54:45 2012
> @@ -19,6 +19,6 @@
>
> Test t;
>
> -// CHECK: metadata !"data", metadata !7, i32 13, i64 32, i64 32, i32 0, i32 0
> +// CHECK: metadata !"data", metadata !7, i32 14, i64 32, i64 32, i32 0, i32 0
> // CHECK: metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !5} ; [ DW_TAG_pointer_type ]
> // CHECK-NOT: metadata !"data", metadata !7, i32 13, i64 0, i64 0, i32 0, i32 4,
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list