This is an archive of the discontinued LLVM Phabricator instance.

[DebugInfo][ScheduleDAGInstrs] Prevent scheduler from reordering DBG_VALUE instructions through their clobbering MIs
Needs ReviewPublic

Authored by andrew.zhogin on May 25 2018, 5:21 AM.

Details

Summary

Currently, ScheduleDAGInstrs have simple algorithm for re-insertion of DBG_VALUE instructions. DBG_VALUEs are attached to the nearest top MI and will be re-inserted bottom from this MI after scheduling. But is is a problem for some cases like:
r0 = Instr0 ...
r1 = Instr1 ...
r2 = Instr2 ...
DBG_VALUE var0 => r0
DBG_VALUE var1 => r1
DBG_VALUE var2 => r2

DBG_VALUEs are attached to Instr2, but the scheduler may reorder Instr0 and Instr1 after Instr2:
r2 = Instr2 ...
DBG_VALUE var0 => r0 >>> Start of var0 debug-loc liverange.
DBG_VALUE var1 => r1 >>> Start of var1 debug-loc liverange.
DBG_VALUE var2 => r2
r0 = Instr0 ... >>> End of var0 debug-loc liverange (because of r0 clobbering def).
r1 = Instr1 ... >>> End of var1 debug-loc liverange (because of r1 clobbering def).

So, the re-inserted DBG_VALUEs for var0 (register r0) and var1 (register r1) will be placed before actual def instruction for their corresponding registers. Providing cutted debug-loc liveranges for such variables.

This patch adds reattachment of DBG_VALUE to the nearest clobbering MI (other DBG_VALUE with the same variable or clobbering register def of any mayStore instruction).
Constant-defined DBG_VALUES will not be reattached.

Diff Detail

Event Timeline

andrew.zhogin created this revision.May 25 2018, 5:21 AM

Is this only an issue with AArch64, or is this more generic? Have you seen how this applies to other targets (say X86)?

lib/CodeGen/ScheduleDAGInstrs.cpp
76–78

Is there value in keeping this hidden under a flag? What is the risk of just doing this by default?

699

Name is a bit misleading -- isDescribedByReg sounds like it should return a bool. This might be better named as getRegDescriptor or regDescriptor instead. Then you can describe this as returning the register number.

701

I must be missing something, but why is this assertion required here?

718–720

Is this a formatting error, is there something else missing here to catch the case where reg1 != 0 && reg2 == 0?

721–722

Looks weird, maybe should be:

} else {

instead?

815–817

s/Registered/Track/ ?

also:

s/index/indices/ ?

835

How about using emplace instead?

Is this only an issue with AArch64, or is this more generic? Have you seen how this applies to other targets (say X86)?

I have reproduced it for AArch64, but it is generic problem and may occur for any target. And cut debug-loc liveranges for some variables (with >=O1 optimizations).

Is this only an issue with AArch64, or is this more generic? Have you seen how this applies to other targets (say X86)?

I have reproduced it for AArch64, but it is generic problem and may occur for any target. And cut debug-loc liveranges for some variables (with >=O1 optimizations).

Okay, so will this break any of the other target tests? Can the test be made more generic alongside any existing debug info tests in codegen?

Is this only an issue with AArch64, or is this more generic? Have you seen how this applies to other targets (say X86)?

I have reproduced it for AArch64, but it is generic problem and may occur for any target. And cut debug-loc liveranges for some variables (with >=O1 optimizations).

Okay, so will this break any of the other target tests? Can the test be made more generic alongside any existing debug info tests in codegen?

For sure, I did check-all runs. Existing tests are fine with the patch (most use -O0 compilation).
I will try to make the test more generic.

vsk added a subscriber: vsk.May 25 2018, 1:10 PM

Small fixes according to the review comments.

bjope added a subscriber: bjope.May 27 2018, 2:43 AM
andrew.zhogin marked 7 inline comments as done.May 27 2018, 12:05 PM
andrew.zhogin added inline comments.
lib/CodeGen/ScheduleDAGInstrs.cpp
76–78

I use this flag in test to verify that the problem exists with "-enable-dbg-value-reattach=false", but not with "-enable-dbg-value-reattach=true".
This flag is enabled by default.

701

Just to verify correct DBG_VALUE instruction. This code was taken from DbgValueHistoryCalculator.

718–720

Formatting error fixed.

reg1 != 0 && reg2 == 0

It means "not clobbering", handled by final "return false;".

andrew.zhogin marked 3 inline comments as done.

Added x86_64 test.

Code without this patch have DEBUG_VALUES moved before corresponding move instructions (after post-ra MI scheduler):

	movl	%edi, %ebx
.Ltmp1:
	#DEBUG_VALUE: foo:returnValue <- 0.000000e+00
	#DEBUG_VALUE: foo:s <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $r14d
	#DEBUG_VALUE: foo:c <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $ebp
	#DEBUG_VALUE: foo:i <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $ebx
	#DEBUG_VALUE: foo:s <- $r14d       >>> %r14d debug value here
	#DEBUG_VALUE: foo:c <- $ebp         >>> %ebp debug value here
	#DEBUG_VALUE: foo:i <- $ebx
	movl	%esi, %ebp                             <<< %ebp def here
.Ltmp2:
	.loc	1 20 5 prologue_end     # ./dbg-values-reattach.cpp:20:5
	movl	$.L.str, %edi
	xorl	%eax, %eax
	movl	%edx, %r14d                          <<< %r14d def here

Code with this patch have correct order for move and debug value instructions:

	movl	%edi, %ebx
.Ltmp1:
	#DEBUG_VALUE: foo:i <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $ebx
	#DEBUG_VALUE: foo:i <- $ebx
	#DEBUG_VALUE: foo:returnValue <- 0.000000e+00
	movl	%esi, %ebp
.Ltmp2:
	#DEBUG_VALUE: foo:c <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $ebp
	#DEBUG_VALUE: foo:c <- $ebp
	.loc	1 20 5 prologue_end     # ./dbg-values-reattach.cpp:20:5
	movl	$.L.str, %edi
	xorl	%eax, %eax
	movl	%edx, %r14d
.Ltmp3:
	#DEBUG_VALUE: foo:s <- [DW_OP_plus_uconst 1, DW_OP_stack_value] $r14d
	#DEBUG_VALUE: foo:s <- $r14d