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

Nagurne, James via llvm-dev
Wed, 02 Jun 2021 21:14:51 -0000

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.

Regards,
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>