Preface
The debug_value_addr instruction has been used to associate a pointer-type (SIL) SSA value with a debug variable. It is nearly identical to debug_value in terms of functionality, except that one can only use pointer-type SSA values in debug_value_addr (along with few other exceptions like poison can not be used in debug_value_addr ). With help from the newly-introduced SIL debug info expression (pull request), we are planning to merge the functionality of debug_value_addr into debug_value and deprecate the former instruction. This can make the debug ecosystem in SIL cleaner and adopt more generic solution on expressing debug values.
Changes
We’re planning to replace the following debug_value_addr :
debug_value_addr %a : $*T, name "my_var"
with this:
debug_value %a : $*T, name "my_var", expr op_deref
The op_deref di-expression operator here indicates that “my_var” source variable is associated with the dereference of SSA value %a . This is identical to the DW_OP_deref operator in DWARF standard.
Deprecation roadmap
The migration to debug_value is planning to be done in three phases (patches).
- First, we bring up the
op_derefoperator. Including its in-memory / textual SIL (including SILParser and SILPrinter) and IRGen support. SILGen will not leverage the feature at this point. - Second, we modify
SILBuilder::createDebugValueAddrto generatedebug_valuew/op_derefinstructions instead ofdebug_value_addrinstructions. The aforementioned SILBuilder method is currently the only way swift compiler is using to generatedebug_value_addr. At the same time, for every places in the swift compiler that inspect thedebug_value_addrinstruction (e.g.visitDebugValueAddrInstcallback andisa<DebugValueAddrInst>predicates), we need to duplicate their logics fordebug_value+op_derefcompound. This steps include updating all the test cases. - Finally, we remove every usages of
DebugValueAddrInst.
You might find the second phase being too bulky. An alternative procedure will be: First, we duplicate the logics of every debug_value_addr for debug_value + op_deref without changing SILBuilder::createDebugValueAddr . Then in phase three, we flip the switch of SILBuilder::createDebugValueAddr and update the test cases and remove all DebugValueAddrInst usages at the same time. The reason I don’t prefer this way in the first place is because all the changes we made in phase two will be completely untested. Because no input is able to trigger those program path.
I'm happy to hear the comments on this ![]()