[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