[llvm-dev] Mapping a retained DILocalVariable back to its Function

William Woodruff via llvm-dev llvm-dev at lists.llvm.org
Thu Apr 30 09:02:47 PDT 2020


Thanks for the quick reply!

Yeah, I think having a mapping is the right way to do this -- I was
just curious if there was some way to walk back up to that `!dbg !XX`
reference that `llvm::Function`s have for their corresponding
`DISubprogram`s without needing the map.

On Thu, Apr 30, 2020 at 11:49 AM David Blaikie <dblaikie at gmail.com> wrote:
>
> I believe the only way to do this is to go forward from llvm::Functions to DISubprograms - so probably your best bet is to walk all the llvm::Functions in your module either searching for the associated DISubprogram, or creating a map from Function to DISubprogram to do lookups on later if you want to do several of these.
>
> On Thu, Apr 30, 2020 at 8:44 AM William Woodruff via llvm-dev <llvm-dev at lists.llvm.org> wrote:
>>
>> Hi all,
>>
>> I'm dealing with LLVM's debug information metadata, and have run into
>> an interesting edge case.
>>
>> Under normal circumstances, every `DILocalVariable` has a `User` in
>> the form of the `llvm.dbg.*` intrinsic that produced it. Knowing this,
>> I can go from `DILocalVariable` to `MetadataAsValue`, grab the users,
>> and end up at the corresponding instruction + function.
>>
>> In some cases, however, LLVM will optimize the IR such that those
>> intrinsics are no longer called, and their corresponding metadata is
>> stashed in the `RetainedNodes` of each `DISubprogram` instead.
>>
>> For example:
>>
>>     ; Function Attrs: nounwind readnone uwtable
>>     define dso_local i32 @foobar(i32) local_unnamed_addr #0 !dbg !13 {
>>       ; no calls to llvm.dbg.* for the locals in this func
>>     }
>>
>> With the corresponding debug nodes:
>>
>>     !13 = distinct !DISubprogram(name: "foobar", scope: !1, file: !1,
>> line: 7, type: !14, isLocal: false, isDefinition: true, scopeLine: 7,
>> flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes:
>> !16)
>>     !14 = !DISubroutineType(types: !15)
>>     !15 = !{!4, !4}
>>     !16 = !{!17, !18}
>>     !17 = !DILocalVariable(name: "x", arg: 1, scope: !13, file: !1,
>> line: 7, type: !4)
>>     ; this one in particular, since it's a non-argument local
>>     !18 = !DILocalVariable(name: "y", scope: !13, file: !1, line: 13, type: !19)
>>
>> I can iterate over these retained local variables as a special case,
>> and would like to map them back to their corresponding IR function
>> (which I don't have direct access to). My plan for doing so was to
>> grab their `DISubprogram` and do a similar `MetadataAsValue -> users`
>> trick to reach the `llvm::Function`,  but this results in an empty
>> use/users list (presumably because the `!dbg !13` isn't recorded as a
>> "use").
>>
>> Any ideas? I'm in a context where the only state I have is the
>> DILocalVariable (as MetadataAsValue, so I have an LLVMContext).
>>
>> Thanks,
>> William
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


More information about the llvm-dev mailing list