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
Nagurne, James via llvm-dev
2021-Jun-03 16:23 UTC
[llvm-dev] [EXTERNAL] Re: DBG_VALUE placement in post-RA scheduling
> Unfortunately this is expectedIndeed unfortunate, but I understand the reasoning behind it. I've worked with other compilers that attempted to solve the same issue. We ended up making the decision to create hard latencies between the debug instructions and their 'uses', effectively adding the debug into the DAG in a sense. This of course impacts performance, which can be argued to be a greater evil.> my instruction-referencing rewrite of variable locations... might be production ready for llvm 14, but possibly not for VLIW machinesYes, this sounds like it'd require thought/work on each VLIW backend's part. VLIW can mean different things to different targets and is not very well abstracted at this point. I'll keep an eye on this change!> all register uses in DBG_VALUE / DBG_VALUE_LIST instructions should have the "IsDebug" flag set on themIt looks like the main driver for bundle creation, 'finalizeBundle', doesn't care about that flag at all. The function iterates over all register operands and notes only uses and defs, which get added to the BUNDLE instruction. The only flags that it tracks are dead, kill, and undef. If adding 'debug' to the tracked state fixes our issue, I'll see about putting up a quick patch to get feedback. Another option is to ensure that debug instructions do not appear 'in' a bundle. When finalizing a bundle, the mechanism could shift all debug instructions to the top, and then only bundle 'real' instructions that come after. Right now, debug instructions are added to the bundle only because they are in between instructions that have been consciously chosen to be in a bundle together. This solves the issue of having to track the debug flag in finalizeBundle. In any case, thanks much for the response. I have plenty to work off of now. Regards, JB -----Original Message----- From: Jeremy Morse <jeremy.morse.llvm at gmail.com> Sent: Thursday, June 3, 2021 7:18 AM To: Nagurne, James <j-nagurne at ti.com> Cc: llvm-dev at lists.llvm.org Subject: [EXTERNAL] Re: [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