-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[LangRef] Clarify definition of fragments and debug intrinsics #82019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -130,6 +130,40 @@ debugging information influences optimization passes then it will be reported | |||||
| as a failure. See :doc:`TestingGuide` for more information on LLVM test | ||||||
| infrastructure and how to run various tests. | ||||||
|
|
||||||
| .. _variables_and_variable_fragments: | ||||||
|
|
||||||
| Variables and Variable Fragments | ||||||
| ================================ | ||||||
|
|
||||||
| Source language variables (or just "variables") are represented by `local | ||||||
| variable <LangRef.html#dilocalvariable>`_ and `global variable | ||||||
| <LangRef.html#diglobalvariable>`_ metadata nodes. | ||||||
|
|
||||||
| When variables are not allocated to contiguous memory or to a single LLVM value | ||||||
| the metadata must record enough information to describe each "piece" or | ||||||
|
||||||
| "fragment" of the source variable. Each fragment is a contiguous span of bits | ||||||
| of the variable it is a part of. | ||||||
|
|
||||||
| This is achieved by encoding fragment information at the end of the | ||||||
| ``DIExpression`` with the ``DW_OP_LLVM_fragment`` operation, whose operands are | ||||||
| the bit offset of the fragment relative to the start of the variable, and the | ||||||
| fragment size in bits. | ||||||
|
|
||||||
| .. note:: | ||||||
|
|
||||||
| The ``DW_OP_LLVM_fragment`` operation acts only to encode the fragment | ||||||
| information, and does not have an effect on the semantics of the expression. | ||||||
|
|
||||||
| A debug intrinsic which refers to a ``DIExpression`` ending with a fragment | ||||||
| operation provides information about the fragment of the variable it refers to, | ||||||
| rather than the whole variable. | ||||||
|
|
||||||
| An equivalence relation over the set of all variables and variable fragments | ||||||
| called "spatially overlapping" is defined in order to describe when intrinsics | ||||||
| terminate the effects of other intrinsics. A variable spatially overlaps with | ||||||
| itself and all fragments of itself. Fragments additionally spatially overlap | ||||||
| with other fragments sharing one common bit of the same variable. | ||||||
|
|
||||||
| .. _format: | ||||||
|
|
||||||
| Debugging information format | ||||||
|
|
@@ -180,7 +214,9 @@ track source local variables through optimization and code generation. | |||||
|
|
||||||
| .. code-block:: llvm | ||||||
|
|
||||||
| void @llvm.dbg.declare(metadata, metadata, metadata) | ||||||
| void @llvm.dbg.declare(metadata <type> <value>, | ||||||
| metadata <!DILocalVariable>, | ||||||
| metadata <!DIExpression>) | ||||||
|
|
||||||
| This intrinsic provides information about a local element (e.g., variable). | ||||||
| The first argument is metadata holding the address of variable, typically a | ||||||
|
|
@@ -221,7 +257,9 @@ agree on the memory location. | |||||
|
|
||||||
| .. code-block:: llvm | ||||||
|
|
||||||
| void @llvm.dbg.value(metadata, metadata, metadata) | ||||||
| void @llvm.dbg.value(metadata <<type> <value>|!DIArgList>, | ||||||
| metadata <!DILocalVariable>, | ||||||
| metadata <!DIExpression>) | ||||||
|
|
||||||
| This intrinsic provides information when a user source variable is set to a new | ||||||
| value. The first argument is the new value (wrapped as metadata). The second | ||||||
|
|
@@ -243,12 +281,12 @@ the complex expression derives the direct value. | |||||
|
|
||||||
| .. code-block:: llvm | ||||||
|
|
||||||
| void @llvm.dbg.assign(Value *Value, | ||||||
| DIExpression *ValueExpression, | ||||||
| DILocalVariable *Variable, | ||||||
| DIAssignID *ID, | ||||||
| Value *Address, | ||||||
| DIExpression *AddressExpression) | ||||||
| void @llvm.dbg.assign(metadata <<type> <value>|!DIArgList>, | ||||||
| metadata <!DIExpression>, | ||||||
| metadata <!DILocalVariable>, | ||||||
| metadata <!DIAssignID>, | ||||||
| metadata <type> <value>, | ||||||
| metadata <!DIExpression>) | ||||||
|
|
||||||
| This intrinsic marks the position in IR where a source assignment occurred. It | ||||||
| encodes the value of the variable. It references the store, if any, that | ||||||
|
|
@@ -259,13 +297,6 @@ argument is a ``DIAssignID`` used to reference a store. The fifth is the | |||||
| destination of the store (wrapped as metadata), and the sixth is a `complex | ||||||
| expression <LangRef.html#diexpression>`_ that modifies it. | ||||||
|
|
||||||
| The formal LLVM-IR signature is: | ||||||
|
|
||||||
| .. code-block:: llvm | ||||||
|
|
||||||
| void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata) | ||||||
|
|
||||||
|
|
||||||
| See :doc:`AssignmentTracking` for more info. | ||||||
|
|
||||||
| Object lifetimes and scoping | ||||||
|
|
@@ -417,8 +448,9 @@ values through compilation, when objects are promoted to SSA values an | |||||
| ``llvm.dbg.value`` intrinsic is created for each assignment, recording the | ||||||
| variable's new location. Compared with the ``llvm.dbg.declare`` intrinsic: | ||||||
|
|
||||||
| * A dbg.value terminates the effect of any preceding dbg.values for (any | ||||||
| overlapping fragments of) the specified variable. | ||||||
| * A dbg.value terminates the effect of any preceding dbg.values for any | ||||||
|
||||||
| spatially overlapping variables or fragments of the specified variable or | ||||||
|
||||||
| spatially overlapping variables or fragments of the specified variable or | |
| spatially overlapping llvm.dbg.values of the specified variable or |
Perhaps this - I think given the definition of spatial overlaps, it should be clear that it applies to both fragment and non-fragment variable definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, it might be good to add a note here, and to make the term "spatially overlapping" be a link back to the definition, but the intention was to define "spatial overlap" such that this could just talk in terms of the universe of all variables and fragments and by definition still be restricted to the way LLVM currently works. In other words, a dbg.value for "x" cannot spatially overlap with a dbg.value for "y" by definition, so the wording here does not need to repeat that restriction.
Edit: at least it doesn't need to repeat it "normatively"; if a note helps the reader understand I'm happy to include one!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add "and constants"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just imo, but I think we could skip mentioning constants, on the basis that the sentence as written isn't exclusive (it doesn't specify that only variables are represented by these classes), and I don't believe(?) that we use fragments for constants since we should always have a single whole definition for them, so the following text would only concern variables. No complaints from me about adding a mention of constants here, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the terminology gets a bit fuzzy, because "constants" can mean different things in different source languages anyway, right?
I didn't audit every other mention of "variable" in the document, but I imagine this same ambiguity comes up elsewhere, so it would be ideal to get a consistent definition to point back at. DWARF seems to call these "data objects" and says:
Maybe we can just adopt "data object" here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the interest of not bike-shedding this patch forever, I'll avoid commenting too much more (it already looks "good enough" to me!), but I think using "data object" outside of the DWARF context may just be adding confusion. Personally I feel like "Variable" is a good term, since the information here explicitly applies to just "variables" and not really to constants, but ultimately I put my vote for either "variables" or "variables and constants".