Nagurne, James via llvm-dev
2021-Jun-02 21:14 UTC
[llvm-dev] DBG_VALUE placement in post-RA scheduling
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>
Jeremy Morse via llvm-dev
2021-Jun-03 12:18 UTC
[llvm-dev] DBG_VALUE placement in post-RA scheduling
Hi James, On Wed, Jun 2, 2021 at 10:14 PM Nagurne, James via llvm-dev <llvm-dev at lists.llvm.org> wrote:> 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.Unfortunately this is expected, even though it's highly undesirable. Because DBG_VALUE instructions specify both the program position where a variable is assigned a location, and the register location too, correctly placing DBG_VALUEs after scheduling becomes extremely difficult. If we prioritise placing them near the position they were before scheduling we would often get the register location wrong. If we focused on the register location always being correct, we would then often get the program position wrong, re-ordering assignments. I believe the current solution gets position/register-location wrong occasionally, but not especially often. Shameless plug: my instruction-referencing rewrite of variable locations [0] would make this easier, as the concern about register locations is separated, and we would only need to think about where in the program to place DBG_INSTR_REF instructions after scheduling. It's back in the landing-patches [1] phase and might be production ready for llvm 14, but possibly not for VLIW machines, it's been a long time since I've gone near them.> 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.This sounds fixable -- all register uses in DBG_VALUE / DBG_VALUE_LIST instructions should have the "IsDebug" flag set on them, which should allow the verifier to distinguish between "the code is broken" and "the debug-info is faulty", the latter being non-fatal. I've no familiarity with instruction bundles, but I'd guess the "IsDebug" flag can be propagated to their uses, or otherwise interpreted when checking their validity. [0] https://lists.llvm.org/pipermail/llvm-dev/2020-February/139440.html [1] https://reviews.llvm.org/D86812 -- Thanks, Jeremy