[PATCH] Fix -mno-accumulate-outgoing-args -fasynchronous-unwind-tables (PR rtl-optimization/36419, take 2)
H.J. Lu
hjl.tools@gmail.com
Mon Jul 28 19:35:00 GMT 2008
On Mon, Jul 28, 2008 at 7:15 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Sun, Jul 27, 2008 at 02:08:54PM -0700, H.J. Lu wrote:
>> On Sun, Jul 27, 2008 at 1:03 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>
>> and here is the insn:
>>
>> (insn/f 91 90 92 x.ii:6 (parallel [
>> (set (reg/f:SI 7 sp)
>> (plus:SI (reg/f:SI 7 sp)
>> (const_int -184 [0xffffffffffffff48])))
>> (clobber (reg:CC 17 flags))
>> (clobber (mem:BLK (scratch) [0 A8]))
>> ]) 890 {pro_epilogue_adjust_stack_1}
>> (expr_list:REG_FRAME_RELATED_EXPR (sequence [
>> (set/f (reg/f:SI 7 sp)
>> (plus:SI (reg/f:SI 7 sp)
>> (const_int -152 [0xffffffffffffff68])))
>> (set (reg/f:SI 7 sp)
>> (plus:SI (reg/f:SI 7 sp)
>> (const_int -32 [0xffffffffffffffe0])))
>> ])
>> (expr_list:REG_UNUSED (reg:CC 17 flags)
>> (nil))))
>>
>> As you can see, since RTX_FRAME_RELATED_P (insn) is true,
>> dwarf2out_stack_adjust is never called on it. We have
>>
>> (gdb) p cfa
>> $1 = {offset = 0, base_offset = 0, reg = 2, indirect = 0}
>> (gdb) p cfa_store
>> $2 = {offset = 0, base_offset = 0, reg = 7, indirect = 0}
>>
>> It comes from function foo in g++.dg/torture/stackalign/unwind-2.C
>> on stack branch. It failed with -O1, -O2, -O3 before we added the
>> fix.
>
> From unwind info POV, the above insn is equivalent to
>
> (insn/f 91 90 92 x.ii:6 (parallel [
> (set (reg/f:SI 7 sp)
> (plus:SI (reg/f:SI 7 sp)
> (const_int -152 [0xffffffffffffff68])))
> (clobber (reg:CC 17 flags))
> (clobber (mem:BLK (scratch) [0 A8]))
> ]) 890 {pro_epilogue_adjust_stack_1}
>
> (insn 92 91 93 x.ii:6 (parallel [
> (set (reg/f:SI 7 sp)
> (plus:SI (reg/f:SI 7 sp)
> (const_int -32 [0xffffffffffffffe0])))
> (clobber (reg:CC 17 flags))
> ])
>
> except that no DW_CFA_advance_loc* in between them will be needed.
> Just disable stack adjustment combining and dwarf2out_stack_adjust
> will be called on the second insn. Does stackalign/unwind-2.C
> fail at -O1+ if you unconditionally return 0 from
> gate_handle_stack_adjustments? If not, where is cfa_store updated?
>
CSA turns
00000000 <_Z3foov>:
0: 8d 4c 24 04 lea 0x4(%esp),%ecx
4: 83 e4 c0 and $0xffffffc0,%esp
7: ff 71 fc pushl -0x4(%ecx)
a: 55 push %ebp
b: 89 e5 mov %esp,%ebp
d: 81 ec 98 00 00 00 sub $0x98,%esp
13: 89 8c 24 88 00 00 00 mov %ecx,0x88(%esp)
1a: 89 9c 24 8c 00 00 00 mov %ebx,0x8c(%esp)
21: 89 b4 24 90 00 00 00 mov %esi,0x90(%esp)
28: 89 bc 24 94 00 00 00 mov %edi,0x94(%esp)
2f: c7 45 88 04 00 00 00 movl $0x4,-0x78(%ebp)
36: 83 ec 20 sub $0x20,%esp
into
d: 81 ec b8 00 00 00 sub $0xb8,%esp
13: 89 8c 24 a8 00 00 00 mov %ecx,0xa8(%esp)
1a: 89 9c 24 ac 00 00 00 mov %ebx,0xac(%esp)
21: 89 b4 24 b0 00 00 00 mov %esi,0xb0(%esp)
28: 89 bc 24 b4 00 00 00 mov %edi,0xb4(%esp)
2f: c7 45 88 04 00 00 00 movl $0x4,-0x78(%ebp)
Since
(insn 92 91 93 x.ii:6 (parallel [
(set (reg/f:SI 7 sp)
(plus:SI (reg/f:SI 7 sp)
(const_int -32 [0xffffffffffffffe0])))
(clobber (reg:CC 17 flags))
])
is after saving ebx, esi and edi onto stack, our testcase doesn't fail.
We could factor out
if (offset != 0)
{
if (cfa.reg == STACK_POINTER_REGNUM)
cfa.offset += offset;
if (cfa_store.reg == STACK_POINTER_REGNUM)
cfa_store.offset += offset;
#ifndef STACK_GROWS_DOWNWARD
offset = -offset;
#endif
args_size += offset;
if (args_size < 0)
args_size = 0;
def_cfa_1 (label, &cfa);
if (flag_asynchronous_unwind_tables)
dwarf2out_args_size (label, args_size);
}
into a function and call it from dwarf2out_frame_debug_expr
and dwarf2out_stack_adjust.
--
H.J.
More information about the Gcc-patches
mailing list