[PATCH] D16440: [ThinLTO] Link in only necessary DICompileUnit operands

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 26 09:47:09 PST 2016

On Tue, Jan 26, 2016 at 9:09 AM, David Blaikie <dblaikie at gmail.com> wrote:

> On Tue, Jan 26, 2016 at 8:53 AM, Teresa Johnson via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>> tejohnson added a comment.
>> > !78 = !DICompositeType(tag: DW_TAG_class_type, name:
>> "XMLPlatformUtils", scope: !17, file: !16, line: 104, size: 8, align: 8,
>> elements: !79, identifier: "_ZTSN11xercesc_2_516XMLPlatformUtilsE")
>> >  ...
>> >  !93 = !DISubprogram(name: "Initialize", linkageName:
>> "_ZN11xercesc_2_516XMLPlatformUtils10InitializeEPKcS2_PNS_12PanicHandlerEPNS_13MemoryManagerE",
>> scope: !"_ZTSN11xercesc_2_516XMLPlatformUtilsE", file: !16, line: 204,
>> type: !94, isLocal: false, isDefinition: false, scopeLine: 204, flags:
>> DIFlagPublic | DIFlagPrototyped, isOptimized: true)
>> Correction, the DISubprogram that references the composite type (and was
>> pulled in due to an import) is:
>> !103 = distinct !DISubprogram(name: "alignPointerForNewBlockAllocation",
>> linkageName:
>> "_ZN11xercesc_2_516XMLPlatformUtils33alignPointerForNewBlockAllocationEm",
>> scope: !"_ZTSN11xercesc_2_516XMLPlatformUtilsE", file: !104, line: 851,
>> type: !105, isLocal: false, isDefinition: true, scopeLine: 852, flags:
>> DIFlagPrototyped, isOptimized: true, declaration: !107, variables: !108)
>> > Why aren't these correlated by the metadata ID instead? I.e. !93
>> instead of !"_ZTSN11xercesc_2_516XMLPlatformUtilsE" in the DISubprogram
>> scope? Then no TypeIdentifierMap would be needed.
>> >
>> > In any case, I added some handling for this, so that we detect and map
>> in retained types onto the new DICompileUnit if they correspond to a
>> DISubprogram that is being mapped in. However, I just hit another similar
>> issue. In this case, the retained type DICompositeType identifier is the
>> base type of a DIDerivedType needed by a DISubprogram that was mapped in.
>> E.g.:
>> >
>> > !3 = !DICompositeType(tag: DW_TAG_enumeration_type, name:
>> "PanicReasons", scope: !"_ZTSN11xercesc_2_512PanicHandlerE", file: !4,
>> line: 116, size: 32, align: 32, elements: !5, identifier:
>> "_ZTSN11xercesc_2_512PanicHandler12PanicReasonsE")
>> >  ...
>> >  !107 = !DIDerivedType(tag: DW_TAG_const_type, baseType:
>> !"_ZTSN11xercesc_2_512PanicHandler12PanicReasonsE")
>> >
>> > where the DIDerivedType is the DISubroutineType for a DISubprogram that
>> was mapped in. I'll need to extend my handling a bit to get this case. Same
>> question here though, why doesn't it just use "baseType: !3"?
>> It turns out the second problem was caused by the fix for the first. The
>> subprogram that referenced the DIDerivedType !107 was only mapped in
>> because it is in the list of elements for the DICompositeType !78 that was
>> the scope for the function needed due to importing. So the set of what
>> debug metadata needs to be imported keeps exploding as the problem is
>> addressed.
>> Is there any way to avoid this? Does the complete DICompositeType !78
>> need to be recreated in the importing module? It isn't clear to me which
>> debug type metadata needs to be fully recreated in the importing module, I
>> know the original premise behind this patch was that it was sufficient for
>> it to exist in the original module. But getOrCreateSubprogramDIE wants to
>> get the ContextDIE for the subprogram.
> Subprogram DIEs will need the right context for the DWARF to be
> correct/valid, so some amount of DWARF is going to need to be cloned into
> any module where the subprogram/function is emitted (even if it is only
> emitted inline)
> Essentially, the minimal DWARF you would need for a subprogram that might
> be a member of a type would be:
> Declaration of outer type
>   Declaration of member function
> Definition of member function (referencing the declaration)
> So you still need to clone the metadata declaration to match the
> definition, and the scope chains of both declaration and definition (but I
> don't think we put the definition inside any scopes if it's an implicit
> definition of a member (that's vague wording, I can be more specific)), but
> you can avoid importing lots of stuff if you demote any definitions of user
> defined types (structs, classes, enums, etc) to declarations.

Thanks, this is helpful.

Just talked to David Blaikie offline, he pointed me to the composite type
declarations being marked with "flags: DIFlagFwdDecl" instead of having an
element list. He pointed out that I need to follow the scope chains of the
imported Subprogram definition and declaration all the way up but can make
them declarations instead of importing all the member elements. And ditto
for the types hanging off the imported subprogram.

Will work on that.


> So long as the types stick around as definitions somewhere.
> The DWARF produced here will look similar to other things we produce with
> -fno-standalone-debug (this is the default on non-Apple platforms) - types
> in DWARF that are only a declaration and have arbitrary subsets of members,
> but there will be an authoritative definition somewhere in the LTO'd
> program (wherever the types were drawn from). This shouldn't hit the
> problematic cases Apple has on their platform that necessitated them
> turning to -fstandalone-debug. It probably won't even hit the LLDB bugs
> that are exposed by -fno-standalone-debug either (because the debug info
> will be standalone in the destination module before we import anything, so
> we won't create the weird situations that LLDB fails on)
> - David

Teresa Johnson |  Software Engineer |  tejohnson at google.com |  408-460-2413
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160126/f5f3bbf1/attachment.html>

More information about the llvm-commits mailing list