You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SIL debug info expression (SIL DIExpression) is a powerful method to connect SSA
3544
+
value with the source variable in an indirect fashion. Di-expression in SIL
3545
+
uses a stack based execution model to evaluate the expression and apply on
3546
+
the associated (SIL) SSA value before connecting it with the debug variable.
3547
+
For instance, given the following SIL code::
3548
+
3549
+
debug_value %a : $*Int, name "x", expr op_deref
3550
+
3551
+
It means: "You can get the value of source variable 'x' by *dereferencing*
3552
+
SSA value ``%a``". The ``op_deref`` is a SIL DIExpression operator that represents
3553
+
"dereference". If there are multiple SIL DIExpression operators (or arguments), they
3554
+
are evaluated from left to right::
3555
+
3556
+
debug_value %b : $**Int, name "y", expr op_deref:op_deref
3557
+
3558
+
In the snippet above, two ``op_deref`` operators will be applied on SSA value
3559
+
``%b`` sequentially.
3560
+
3561
+
Note that normally when the SSA value has an address type, there will be a ``op_deref``
3562
+
in the SIL DIExpression. Because there is no pointer in Swift so you always need to
3563
+
dereference an address-type SSA value to get the value of a source variable.
3564
+
However, if the SSA value is a ``alloc_stack``, the ``debug_value`` is used to indicate
3565
+
the *declaration* of a source variable. Or, you can say, used to specify the location
3566
+
(memory address) of the source variable. Therefore, we don't need to add a ``op_deref``
3567
+
in this case::
3568
+
3569
+
%a = alloc_stack $Int, ...
3570
+
debug_value %a : $*Int, name "my_var"
3571
+
3572
+
3573
+
The ``op_fragment`` operator is used to specify the SSA value of a specific
3574
+
field in an aggregate-type source variable. This SIL DIExpression operator takes
3575
+
a field declaration -- which references the desired sub-field in source variable
3576
+
-- as its argument. Here is an example::
3551
3577
3552
3578
struct MyStruct {
3553
3579
var x: Int
@@ -3556,23 +3582,13 @@ like AST nodes or strings. Here is an example::
3556
3582
...
3557
3583
debug_value %1 : $Int, var, (name "the_struct", loc "file.swift":8:7), type $MyStruct, expr op_fragment:#MyStruct.y, loc "file.swift":9:4
3558
3584
3559
-
In the snippet above, source variable "the_struct" has an aggregate type ``$MyStruct`` and we use di-expression with ``op_fragment`` operator to associate ``%1`` to the ``y`` member variable inside "the_struct". Note that the extra source location directive follows rigt after ``name "the_struct"`` indicate that "the_struct" was originally declared in line 8, but not until line 9, the current ``debug_value`` instruction's source location, does member ``y`` got updated with SSA value ``%1``.
This indicates that the value of a declaration with address-only type
3571
-
has changed value to the specified operand. The declaration in
3572
-
question is identified by the SILLocation attached to the
3573
-
debug_value_addr instruction.
3585
+
In the snippet above, source variable "the_struct" has an aggregate type ``$MyStruct`` and we use a SIL DIExpression with ``op_fragment`` operator to associate ``%1`` to the ``y`` member variable (via the ``#MyStruct.y`` directive) inside "the_struct".
3586
+
Note that the extra source location directive follows rigt after ``name "the_struct"`` indicate that "the_struct" was originally declared in line 8, but not until line 9 -- the current ``debug_value`` instruction's source location -- does member ``y`` got updated with SSA value ``%1``.
3574
3587
3575
-
Note that this instruction can be replaced by ``debug_value`` + di-expression operator that is equivalent to LLVM's ``DW_OP_deref``.
3588
+
It is worth noting that a SIL DIExpression is similar to
3589
+
`!DIExpression <https://www.llvm.org/docs/LangRef.html#diexpression>`_ in LLVM debug
3590
+
info metadata. While LLVM represents ``!DIExpression`` are a list of 64-bit integers,
3591
+
SIL DIExpression can have elements with various types, like AST nodes or strings.
0 commit comments