[Bug c/36303] New: location list incomplete for spilled registers
gcaprino at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu May 22 16:32:00 GMT 2008
Location list created for the following test case is incomplete for parameter
"p1":
cc1 -v -dD fs.c -dA -m64 -mcmodel=small -gdwarf-2 -O2 -fno-omit-frame-pointer
-quiet
typedef struct s2 {
unsigned short f1;
unsigned short length;
char data[64];
} s2;
int func(s2 *p1, const char *p2)
{
if (((_LogEffectiveLevel(57)) >= (3))) {
_Log("abc",
(__FUNCTION__+((__FUNCTION__[(sizeof("FSS") - 1)] == '_') ?
(sizeof("FSS") - 1) + 1 : (sizeof("FSS") - 1))),
237 ,
(p1)->f1,
(p1)->length,
*((unsigned int *)(&(p1)->data[0])),
*((unsigned int *)(&(p1)->data[4])),
*((unsigned int *)(&(p1)->data[8])),
*((unsigned int *)(&(p1)->data[12])),
*((unsigned int *)(&(p1)->data[16])),
*((unsigned int *)(&(p1)->data[20])),
*((unsigned int *)(&(p1)->data[24])),
*((unsigned int *)(&(p1)->data[28])),
*((unsigned long *)(&(p1)->data[32])),
*((unsigned long *)(&(p1)->data[40])),
*((unsigned long *)(&(p1)->data[48])),
*((unsigned long *)(&(p1)->data[56])), p2);
}
return 0;
}
The generated assembly shows the following:
.uleb128 0xb # (DIE (0xb2) DW_TAG_formal_parameter)
.ascii "p1\0" # DW_AT_name
.byte 0x1 # DW_AT_decl_file (fs.c)
.byte 0x8 # DW_AT_decl_line
.long 0xea # DW_AT_type
.long .LLST1 # DW_AT_location
.LLST1:
.quad .LVL0-.Ltext0 # Location list begin address (*.LLST1)
.quad .LVL1-.Ltext0 # Location list end address (*.LLST1)
.value 0x1 # Location expression size
.byte 0x55 # DW_OP_reg5
.quad .LVL1-.Ltext0 # Location list begin address (*.LLST1)
.quad .LVL2-.Ltext0 # Location list end address (*.LLST1)
.value 0x1 # Location expression size
.byte 0x5b # DW_OP_reg11
.quad .LVL4-.Ltext0 # Location list begin address (*.LLST1)
.quad .LVL5-.Ltext0 # Location list end address (*.LLST1)
.value 0x1 # Location expression size
.byte 0x5b # DW_OP_reg11
.quad 0x0 # Location list terminator begin (*.LLST1)
.quad 0x0 # Location list terminator end (*.LLST1)
This does not cover instructions between .LVL2 and .LVL4.
Looking at the assembly, you see that R11 is being saved to the stack across
the call to _LogEffectiveLevel() and then reloaded *before* .LVL4:
# fs.c:10
.LM4:
movq %r11, -48(%rbp)
.LVL2:
call _LogEffectiveLevel
.LVL3:
cmpl $2, %eax
movq -48(%rbp), %r11
jle .L2
# basic block 3
# fs.c:11
.LM5:
movl 28(%r11), %ecx
.LVL4:
movq 60(%r11), %rax
movq 52(%r11), %rdx
So when gdb is stopped at line fs.c:11 it reports that p1's <value is optimized
out>.
I debugged var-tracking.c, and it does not look like it is tracking duplicate
locations, such as when a register is saved and restored from the stack.
It's also possible that one of the previous passes does not give enough
information to var-tracking.c about the variable being saved/restored.
I can see the following in the var tracking output:
(insn:TI 7 102 107 2 fs.c:10 (set (reg:SI 5 di)
(const_int 57 [0x39])) 47 {*movsi_1} (nil))
(note 107 7 83 2 ( p1 (expr_list:REG_DEP_TRUE (reg/v/f:DI 40 r11 [orig:75 p1 ]
[75])
(const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION)
....
(insn 78 90 108 2 fs.c:10 (set (mem/c:DI (plus:DI (reg/f:DI 6 bp)
(const_int -48 [0xffffffffffffffd0])) [10 S8 A8])
(reg:DI 40 r11)) 89 {*movdi_1_rex64} (expr_list:REG_DEAD (reg:DI 40
r11)
(nil)))
(note 108 78 9 2 ( p1 (nil)) NOTE_INSN_VAR_LOCATION)
....
(insn 79 11 12 2 fs.c:10 (set (reg:DI 40 r11)
(mem/c:DI (plus:DI (reg/f:DI 6 bp)
(const_int -48 [0xffffffffffffffd0])) [10 S8 A8])) 89
{*movdi_1_rex64} (nil))
It seems that when r11 is saved in insn 78 and reloaded in insn 79 it is not
marked as containing "p1".
Unfortunately I don't have enough knowledge to continue debugging gcc to be
sure it's var-tracking.c or someone else's fault.
This happens with gcc 4.2.3 and gcc 4.3.0.
It does not happen with -O1, or if I remove even a single parameter from the
call to _LogEffectiveLevel().
However we observe a lot of <value optimized out> messages in other parts of
our code, and most of the time I tracked it to incomplete info in the location
list.
I hope this is enough information. Let me know if you need more.
Thanks,
Giampiero Caprino
--
Summary: location list incomplete for spilled registers
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: gcaprino at gmail dot com
GCC host triplet: host-i686-pc-linux-gnu
GCC target triplet: x86_64-linux
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36303
More information about the Gcc-bugs
mailing list