[llvm-dev] DebugInfo: Global variable expression management

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] DebugInfo: Global variable expression management

Alberto Barbaro via llvm-dev
Hi Folks,

Looking into some other issues, I came across a couple of oddities with regard to debug info for global variables (PR39900 and PR39899).

But a broader question I was wondering if it was anyone's radar (it's not something I'll be pushing on myself in the near future, but just wanted to see if the idea was already out there, etc):

Why are there DIGlobalVariableExpressions that are both attached as !dbg metadata on llvm::GlobalVariables, and in the globals() list of a DICompileUnit? I would've thought, ideally, a DIGlobalVariableExpression would be mutually exclusively in one place or the other - the only ones in the globals() list of a DICompileUnit would be the constant values, that have no place elsewhere. When the storage for a global is optimized away, it'd be possible to find its DICompileUnit from the scope of the DIGlobalVariable referenced by the DIGlobalVariableExpression given by the !dbg on said GlobalVariable & attach the constant DIGlobalVariableExpression there, perhaps?

Is that a thing folks haev already thought of/planned?

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] DebugInfo: Global variable expression management

Alberto Barbaro via llvm-dev


> On Dec 5, 2018, at 3:58 PM, David Blaikie <[hidden email]> wrote:
>
> Hi Folks,
>
> Looking into some other issues, I came across a couple of oddities with regard to debug info for global variables (PR39900 and PR39899).
>
> But a broader question I was wondering if it was anyone's radar (it's not something I'll be pushing on myself in the near future, but just wanted to see if the idea was already out there, etc):
>
> Why are there DIGlobalVariableExpressions that are both attached as !dbg metadata on llvm::GlobalVariables, and in the globals() list of a DICompileUnit? I would've thought, ideally, a DIGlobalVariableExpression would be mutually exclusively in one place or the other - the only ones in the globals() list of a DICompileUnit would be the constant values, that have no place elsewhere. When the storage for a global is optimized away, it'd be possible to find its DICompileUnit from the scope of the DIGlobalVariable referenced by the DIGlobalVariableExpression given by the !dbg on said GlobalVariable & attach the constant DIGlobalVariableExpression there, perhaps?


This duality was something that I originally planned to clean up, but it turned out to be more complicated than worth the effort.

A couple of constraints are:
- LLVM IR may refer to Metadata, but not vice versa
- llvm::GlobalVariables thus need a !dbg attachment to be bound to a DIGlobalVariableExpression
- An optimized-away global constant needs to live somewhere, hence the DICompileUnit's globals: field.

You are right in that debug variables don't need to be in both places at the same time, but then we need to teach optimization passes that delete a constant llvm::GlobalVariable to update a DICompileUnit's globals: field. That is messy and may subtly break some assumptions that I haven't thought about yet. Outside of DIBuilder we get through the entire compiler without modifying any MDNodes. That said, DICompileUnit is distinct so calling replaceGlobals() on it is probably safe.

What would the primary benefit of making this change be?

-- adrian
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] DebugInfo: Global variable expression management

Alberto Barbaro via llvm-dev


On Wed, Dec 5, 2018 at 4:14 PM Adrian Prantl <[hidden email]> wrote:


> On Dec 5, 2018, at 3:58 PM, David Blaikie <[hidden email]> wrote:
>
> Hi Folks,
>
> Looking into some other issues, I came across a couple of oddities with regard to debug info for global variables (PR39900 and PR39899).
>
> But a broader question I was wondering if it was anyone's radar (it's not something I'll be pushing on myself in the near future, but just wanted to see if the idea was already out there, etc):
>
> Why are there DIGlobalVariableExpressions that are both attached as !dbg metadata on llvm::GlobalVariables, and in the globals() list of a DICompileUnit? I would've thought, ideally, a DIGlobalVariableExpression would be mutually exclusively in one place or the other - the only ones in the globals() list of a DICompileUnit would be the constant values, that have no place elsewhere. When the storage for a global is optimized away, it'd be possible to find its DICompileUnit from the scope of the DIGlobalVariable referenced by the DIGlobalVariableExpression given by the !dbg on said GlobalVariable & attach the constant DIGlobalVariableExpression there, perhaps?


This duality was something that I originally planned to clean up, but it turned out to be more complicated than worth the effort.

A couple of constraints are:
- LLVM IR may refer to Metadata, but not vice versa
- llvm::GlobalVariables thus need a !dbg attachment to be bound to a DIGlobalVariableExpression
- An optimized-away global constant needs to live somewhere, hence the DICompileUnit's globals: field.

You are right in that debug variables don't need to be in both places at the same time, but then we need to teach optimization passes that delete a constant llvm::GlobalVariable to update a DICompileUnit's globals: field.

Fair, I suppose today if an optimization pass deletes a GlobalVariable, the result is that the debug info still describes the global variable - but without any value. (this is inconsistent, though technically better, than we do with functions - which, if totally deleted, aren't emitted at all - but they track through inlining more than a global variable does, so it's not a perfect comparison) - whereas if we avoided having them in the globals() list, we'd /have/ to update that list, even in cases where the optimization didn't have anything useful to say about the value of the global (eg: "hey, this global has lots of different values throughout its lifetime, but none of them are used, I'm going to delete it" - today, it just deletes it and the debug info is correct. But with this change, it'd have to go wire in a null description to ensure the variable wasn't lost entirely)


 
That is messy and may subtly break some assumptions that I haven't thought about yet. Outside of DIBuilder we get through the entire compiler without modifying any MDNodes.

I guess we only create new ones when it comes to creating complicated dwarf location descriptions/expressions as optimizations change local variables around? So not modification in that case?
 
That said, DICompileUnit is distinct so calling replaceGlobals() on it is probably safe.

What would the primary benefit of making this change be?

Oh, just noticed as an aside while I was filing the aforementioned bugs - struck me as weird that they were connected in two places is all. No major thing I can think of.

- Dave 

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] DebugInfo: Global variable expression management

Alberto Barbaro via llvm-dev


On Dec 5, 2018, at 4:20 PM, David Blaikie <[hidden email]> wrote:


Fair, I suppose today if an optimization pass deletes a GlobalVariable, the result is that the debug info still describes the global variable - but without any value. (this is inconsistent, though technically better, than we do with functions - which, if totally deleted, aren't emitted at all - but they track through inlining more than a global variable does, so it's not a perfect comparison) - whereas if we avoided having them in the globals() list, we'd /have/ to update that list, even in cases where the optimization didn't have anything useful to say about the value of the global (eg: "hey, this global has lots of different values throughout its lifetime, but none of them are used, I'm going to delete it" - today, it just deletes it and the debug info is correct. But with this change, it'd have to go wire in a null description to ensure the variable wasn't lost entirely)


 
That is messy and may subtly break some assumptions that I haven't thought about yet. Outside of DIBuilder we get through the entire compiler without modifying any MDNodes.

I guess we only create new ones when it comes to creating complicated dwarf location descriptions/expressions as optimizations change local variables around? So not modification in that case?

Correct. The most common thing we do in the optimizer is to create a new, uniqued, more complex DIExpression and emit a new call @llvm.dbg.value to tie that DIExpression to a DILocalVariable in the instruction stream.

 
That said, DICompileUnit is distinct so calling replaceGlobals() on it is probably safe.

What would the primary benefit of making this change be?

Oh, just noticed as an aside while I was filing the aforementioned bugs - struck me as weird that they were connected in two places is all. No major thing I can think of.

That's fair.

-- adrian

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] DebugInfo: Global variable expression management

Alberto Barbaro via llvm-dev
Thanks for explaining the context - sounds plausible, but has some sharp edges/tradeoffs if anyone does decide to try their hand at it - good to know!

On Wed, Dec 5, 2018 at 4:25 PM Adrian Prantl <[hidden email]> wrote:

On Dec 5, 2018, at 4:20 PM, David Blaikie <[hidden email]> wrote:


Fair, I suppose today if an optimization pass deletes a GlobalVariable, the result is that the debug info still describes the global variable - but without any value. (this is inconsistent, though technically better, than we do with functions - which, if totally deleted, aren't emitted at all - but they track through inlining more than a global variable does, so it's not a perfect comparison) - whereas if we avoided having them in the globals() list, we'd /have/ to update that list, even in cases where the optimization didn't have anything useful to say about the value of the global (eg: "hey, this global has lots of different values throughout its lifetime, but none of them are used, I'm going to delete it" - today, it just deletes it and the debug info is correct. But with this change, it'd have to go wire in a null description to ensure the variable wasn't lost entirely)


 
That is messy and may subtly break some assumptions that I haven't thought about yet. Outside of DIBuilder we get through the entire compiler without modifying any MDNodes.

I guess we only create new ones when it comes to creating complicated dwarf location descriptions/expressions as optimizations change local variables around? So not modification in that case?

Correct. The most common thing we do in the optimizer is to create a new, uniqued, more complex DIExpression and emit a new call @llvm.dbg.value to tie that DIExpression to a DILocalVariable in the instruction stream.

 
That said, DICompileUnit is distinct so calling replaceGlobals() on it is probably safe.

What would the primary benefit of making this change be?

Oh, just noticed as an aside while I was filing the aforementioned bugs - struck me as weird that they were connected in two places is all. No major thing I can think of.

That's fair.

-- adrian

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev