This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo] Do not extend range for physreg in LiveDebugVariables
ClosedPublic

Authored by bjope on Sep 21 2017, 9:24 AM.

Details

Summary

A DBG_VALUE that is referring to a physical register is
valid up until the next def of the register, or the end
of the basic block that it belongs to.

LiveDebugVariables is computing live intervals (slot index
ranges) for DBG_VALUE instructions, before regalloc, in order
to be able to re-insert DBG_VALUE instructions again after
regalloc. When the DBG_VALUE is mapping a variable to a
physical register we do not need to compute the range. We
should simply re-insert the DBG_VALUE at the start position.

The problem that was found, resulting in this patch, was a
situation when the DBG_VALUE was the last real use of the
physical register. The computeIntervals/extendDef methods
extended the range to cover the whole basic block, even though
the physical register very well could be allocated to some
virtual register inside the basic block. So the extended
range could not be trusted.

This patch is more or less a preparation for https://reviews.llvm.org/D38229,
where the goal is to insert DBG_VALUE after each new definition
of a variable, even if the virtual registers that the variable
was connected to has been coalesced into using the same physical
register (e.g. due to two address instructions). For more info
see https://bugs.llvm.org/show_bug.cgi?id=34545

Event Timeline

bjope created this revision.Sep 21 2017, 9:24 AM
bjope edited the summary of this revision. (Show Details)Sep 25 2017, 4:10 AM
aprantl accepted this revision.Sep 25 2017, 9:08 AM

This seems reasonable, thanks!
Could we make the test check the MIR instead of the debug output?

test/DebugInfo/MIR/X86/live-debug-vars-unused-arg.mir
2

If you really need to check the debug output of the pass (could we check the IR instead?) this needs a REQUIRES: asserts.

This revision is now accepted and ready to land.Sep 25 2017, 9:08 AM
rnk added inline comments.Sep 25 2017, 9:22 AM
test/DebugInfo/MIR/X86/live-debug-vars-unused-arg.mir
152

I think this is testable with dwarfdump. The range for argc should run exactly up until it is clobbered by a0, so the location lists will look like:

DW_TAG_formal_parameter
  DW_AT_location (0xNNN
    0x000 - [[SET_RDI:0x.*]]: RDI)
  DW_AT_name: "argc"
DW_TAG_variable
  DW_AT_location (0xNNN
    [[SET_RDI]] - {{.*}}: RDI)
  DW_AT_name: "a0"
bjope added inline comments.Sep 26 2017, 7:16 AM
test/DebugInfo/MIR/X86/live-debug-vars-unused-arg.mir
2

Well, this patch does not impact the IR/MIR by itself. So in order to have a test case that fails without the patch LiveDebugVariables I need to look at the debug printout (I do not think that it is possible to get the VRM and LDV data structures dumped in the MIR yet?).

I can however prepare a test case that would fail if we land https://reviews.llvm.org/D38229 without landing this patch first.

bjope updated this revision to Diff 116663.Sep 26 2017, 7:19 AM

Added REQUIRES asserts to the test case.
Added a second RUN line to also verify the MIR.

bjope marked an inline comment as done.Sep 26 2017, 7:20 AM
bjope added inline comments.Sep 26 2017, 7:33 AM
test/DebugInfo/MIR/X86/live-debug-vars-unused-arg.mir
152

Sure we could probably use dwarfdump, but I think that would make this test case dependent on the behavior of the later passes emitting the dwarf, as well as dwarfdump. By stopping before livedebugvalues I will limit the test case to verify the behavior of LiveDebugVariables (and inevitably some other RA passes run together with "greedy"). I think it will make the test case more robust if we limit the scope of the test.

If we need to test the whole chain of passes (integration test of several passes), then we should add a test in the debuginfo-tests repo instead. Or what do you think?

live-debug-variables happens so late in the pipeline that in practice checking for dwarfdump output hasn't caused much churn in the testsuite. I would prefer a -filetype=obj -start-before=greedy | llvm-dwarfdump- test over one that checks DEBUG output (which will only be tested by bots that build with assertions enabled).

bjope updated this revision to Diff 116772.Sep 27 2017, 1:39 AM

Narrowed the test case even further by stopping already after virtregrewriter.

bjope added a comment.Sep 27 2017, 2:17 AM

live-debug-variables happens so late in the pipeline that in practice checking for dwarfdump output hasn't caused much churn in the testsuite. I would prefer a -filetype=obj -start-before=greedy | llvm-dwarfdump- test over one that checks DEBUG output (which will only be tested by bots that build with assertions enabled).

This patch is to make sure that the output from the virtregrewriter is correct (i.e. the input to later passes such as LiveDebugValues and DwarfDebug). I want to do the checks as early as possible to catch faults in virtregrewriter without the risk of later passes hiding the fault.
My feeling is that the DBG_VALUE handling in the backend is quite unstable today. I think we need to define what the expectation is from each pass. Unless we start adding test cases to verify how each pass is handling DBG_VALUEs it will become hard to make things better.

One idea is to remove the CHECKDBG checks again in https://reviews.llvm.org/D38229 (and by that loosing some kind if regression tests on how LiveDebugVariables is calculating slot index ranges for physical registers). If D38229 had been pushed before this patch,. then this patch would become a bugfix and I would probably have settled with only adding the CHECKMIR checks.
Or maybe I need to write a class test for LiveDebugVariables.

Okay, let's do this: Split the CHECKDBG test into a separate .test file that has the REQUIRES: asserts and re-uses the same input. This way we get some testing in all configurations and full testing in asserts builds.

bjope added a comment.Sep 27 2017, 9:45 AM

Okay, let's do this: Split the CHECKDBG test into a separate .test file that has the REQUIRES: asserts and re-uses the same input. This way we get some testing in all configurations and full testing in asserts builds.

Good idea. I'll split the test case and then I will land this. Thanks!

This revision was automatically updated to reflect the committed changes.