[llvm-dev] DBG_VALUE placement in post-RA scheduling

Nagurne, James via llvm-dev llvm-dev at lists.llvm.org
Wed Jun 2 14:14:51 PDT 2021

I'm having an issue in a downstream target that I'm trying to track down and characterize involving a custom scheduling pass similar to Hexagon's VLIW scheduler, and am looking for any tips on what I should be looking for.

Consider the following instructions taking place in program order in a MachineBasicBlock

  1.  $r1 = unrelated_instruction
  2.  DBG_VALUE $r0, $noreg, !"variable_name"
  3.  use $r0
  4.  ...

During the creation of the schedule DAG, ScheduleDAGInstrs::buildSchedGraph populates a list of MachineInstr pairs. Each pair is a debug instruction and the instruction immediately preceding it (again, before scheduling). Therefore, in the above case, the list has a single member, the pair <2, 1> because the DBG_VALUE 2) has an immediate predecessor of 1).

Scheduling then occurs. Because there is no edge between 1) and 3), I believe that the algorithm can legally schedule 3) before 1).

Finally, placeDebugValues is called. This function takes each pair created in the above step and splices the DEBUG_VALUE into the block so that it immediately succeeds the instruction it succeeded prior to scheduling. This leaves us with the new scheduled order:

  1.  use $r0
  2.  $r1 = unrelated_instruction
  3.  DBG_VALUE $r0, $noreg, !"variable_name"
  4.  ...

I can't imagine that this is expected. The knowledge that the use of $0 in the new 1) is 'variable_name' is lost. Furthermore, we now have a strange liveness problem in that the DBG_VALUE is apparently killing $r0, which sounds logically incorrect.

To add one more level of specifics, the error I'm getting stems from the above plus the register kill fixup step that happens after each basic block is scheduled. Both the use of $r0 and the DBG_VALUE are added to a VLIW bundle, which inherits register behaviors from the contained instructions:

BUNDLE implicit $r0
  use $r0
BUNDLE implicit $r0
  DBG_VALUE $r0, $noreg, !"variable_name"

After the fixup step, both bundles are marked as kills of $r0, I believe as a consequence of the fact that the fixup step skips debug instructions at the top level, but not at the bundle level. This triggers the MachineVerifier to complain that the bundle containing the DBG_VALUE is using an undefined register because the prior bundle killed it.

J.B. Nagurne
Code Generation
Texas Instruments
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210602/c970f5d5/attachment.html>

More information about the llvm-dev mailing list