[RFC] The debug_value_addr SIL instruction deprecation roadmap

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).

  1. First, we bring up the op_deref operator. Including its in-memory / textual SIL (including SILParser and SILPrinter) and IRGen support. SILGen will not leverage the feature at this point.
  2. Second, we modify SILBuilder::createDebugValueAddr to generate debug_value w/ op_deref instructions instead of debug_value_addr instructions. The aforementioned SILBuilder method is currently the only way swift compiler is using to generate debug_value_addr . At the same time, for every places in the swift compiler that inspect the debug_value_addr instruction (e.g. visitDebugValueAddrInst callback and isa<DebugValueAddrInst> predicates), we need to duplicate their logics for debug_value + op_deref compound. This steps include updating all the test cases.
  3. 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 :slightly_smiling_face:

2 Likes