diff mbox

Initial shrink-wrapping patch

Message ID 4E8C7ED0.3090705@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt Oct. 5, 2011, 3:59 p.m. UTC
On 10/05/11 17:13, Richard Guenther wrote:
> On Wed, Oct 5, 2011 at 12:29 AM, Richard Henderson <rth@redhat.com> wrote:
>> On 10/04/2011 03:10 PM, Bernd Schmidt wrote:
>>>       * doc/invoke.texi (-fshrink-wrap): Document.
>>>       * opts.c (default_options_table): Add it.
>>>       * common.opt (fshrink-wrap): Add.
>>>       * function.c (emit_return_into_block): Remove useless declaration.
>>>       (record_hard_reg_uses_1, record_hard_reg_uses, frame_required_for_rtx,
>>>       requires_stack_frame_p, gen_return_pattern): New static functions.
>>>       (emit_return_into_block): New arg simple_p.  All callers changed.
>>>       Use gen_return_pattern.
>>>       (thread_prologue_and_epilogue_insns): Implement shrink-wrapping.
>>>       * config/i386/i386.md (return): Expand into a simple_return.
>>>       (simple_return): New expander):
>>>       (simple_return_internal, simple_return_internal_long,
>>>       simple_return_pop_internal_long, simple_return_indirect_internal):
>>>       Renamed from return_internal, return_internal_long,
>>>       return_pop_internal_long and return_indirect_internal; changed to use
>>>       simple_return.
>>>       * config/i386/i386.c (ix86_expand_epilogue): Adjust to expand
>>>       simple returns.
>>>       (ix86_pad_returns): Likewise.
>>>       * function.h (struct rtl_data): Add member shrink_wrapped.
>>>       * cfgcleanup.c (outgoing_edges_match): If shrink-wrapped, edges that
>>>       are not jumps or sibcalls can't be compared.
>>>
>>>       * gcc.target/i386/sw-1.c: New test.
>>
>> Ok.
>>
>> As a followup, I think this option needs to be disabled for profiling
>> and profile_after_prologue.  Should be a mere matter of frobbing the
>> options at startup.
> 
> This breaks bootstrap on x86_64-linux.
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50621

Caused by the x86_64 expand_epilogue not generating REG_CFA_RESTORE
notes, and in another case by queuing but not emitting them.

Bootstrapping the following now. Ok? (Alternatively, could keep the
redzone logic, but make it depend on !flag_shrink_wrap).


Bernd
* config/i386/i386.c (ix86_add_cfa_restore_note): Lose CFA_OFFSET
	argument.  All callers changed.  Always emit a note.
	(ix86_expand_epilogue): Ensure queued cfa_adjust notes are attached
	to an insn.

Comments

Richard Henderson Oct. 5, 2011, 4:21 p.m. UTC | #1
On 10/05/2011 08:59 AM, Bernd Schmidt wrote:
> Bootstrapping the following now. Ok? (Alternatively, could keep the
> redzone logic, but make it depend on !flag_shrink_wrap).

It's a good space-saving optimization, that redzone logic.  We
should be able to keep it based on crtl->shrink_wrapped; that
does appear to get set before we actually emit the epilogue.


r~
Bernd Schmidt Oct. 6, 2011, 6:03 p.m. UTC | #2
HJ found some more maybe_record_trace_start failures. In one case I
debugged, we have

(insn/f 31 0 32 (parallel [
            (set (reg/f:DI 7 sp)
                (plus:DI (reg/f:DI 7 sp)
                    (const_int 8 [0x8])))
            (clobber (reg:CC 17 flags))
            (clobber (mem:BLK (scratch) [0 A8]))
        ]) -1
     (expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
            (plus:DI (reg/f:DI 7 sp)
                (const_int 8 [0x8])))
        (nil)))

The insn pattern is later changed by csa to adjust by 24, and the note
is left untouched; that seems to be triggering the problem.

Richard, is there a reason to use REG_CFA_ADJUST_CFA rather than
REG_CFA_DEF_CFA? If no, I'll just try to fix i386.c not to emit the former.


Bernd
Richard Henderson Oct. 6, 2011, 6:13 p.m. UTC | #3
On 10/06/2011 11:03 AM, Bernd Schmidt wrote:
> HJ found some more maybe_record_trace_start failures. In one case I
> debugged, we have
> 
> (insn/f 31 0 32 (parallel [
>             (set (reg/f:DI 7 sp)
>                 (plus:DI (reg/f:DI 7 sp)
>                     (const_int 8 [0x8])))
>             (clobber (reg:CC 17 flags))
>             (clobber (mem:BLK (scratch) [0 A8]))
>         ]) -1
>      (expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
>             (plus:DI (reg/f:DI 7 sp)
>                 (const_int 8 [0x8])))
>         (nil)))
> 
> The insn pattern is later changed by csa to adjust by 24, and the note
> is left untouched; that seems to be triggering the problem.

Hmm.  That seems a bit odd, considering this function probably does not
use alloca (no frame pointer), and uses accumulated outgoing arguments
(x86_64 never uses no-accumulate-outgoing-args, afaik).

> Richard, is there a reason to use REG_CFA_ADJUST_CFA rather than
> REG_CFA_DEF_CFA? If no, I'll just try to fix i386.c not to emit the former.

Not that I can think of.  But if that change makes any difference at all,
that's almost certainly another bug.

What PR are you looking at here?


r~
Bernd Schmidt Oct. 6, 2011, 6:15 p.m. UTC | #4
On 10/06/11 20:13, Richard Henderson wrote:
> What PR are you looking at here?

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50632

Testcase is gcc.dg/pr50132.c.


Bernd
diff mbox

Patch

Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 179553)
+++ gcc/config/i386/i386.c	(working copy)
@@ -9126,17 +9126,11 @@  ix86_emit_save_sse_regs_using_mov (HOST_
 static GTY(()) rtx queued_cfa_restores;
 
 /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
-   manipulation insn.  The value is on the stack at CFA - CFA_OFFSET.
-   Don't add the note if the previously saved value will be left untouched
-   within stack red-zone till return, as unwinders can find the same value
-   in the register and on the stack.  */
+   manipulation insn.  */
 
 static void
-ix86_add_cfa_restore_note (rtx insn, rtx reg, HOST_WIDE_INT cfa_offset)
+ix86_add_cfa_restore_note (rtx insn, rtx reg)
 {
-  if (cfa_offset <= cfun->machine->fs.red_zone_offset)
-    return;
-
   if (insn)
     {
       add_reg_note (insn, REG_CFA_RESTORE, reg);
@@ -10298,7 +10292,7 @@  ix86_emit_restore_reg_using_pop (rtx reg
   struct machine_function *m = cfun->machine;
   rtx insn = emit_insn (gen_pop (reg));
 
-  ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
+  ix86_add_cfa_restore_note (insn, reg);
   m->fs.sp_offset -= UNITS_PER_WORD;
 
   if (m->fs.cfa_reg == crtl->drap_reg
@@ -10383,8 +10377,7 @@  ix86_emit_leave (void)
       add_reg_note (insn, REG_CFA_DEF_CFA,
 		    plus_constant (stack_pointer_rtx, m->fs.sp_offset));
       RTX_FRAME_RELATED_P (insn) = 1;
-      ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
-				 m->fs.fp_offset);
+      ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx);
     }
 }
 
@@ -10421,7 +10414,7 @@  ix86_emit_restore_regs_using_mov (HOST_W
 	    m->fs.drap_valid = true;
 	  }
 	else
-	  ix86_add_cfa_restore_note (NULL_RTX, reg, cfa_offset);
+	  ix86_add_cfa_restore_note (NULL_RTX, reg);
 
 	cfa_offset -= UNITS_PER_WORD;
       }
@@ -10446,7 +10439,7 @@  ix86_emit_restore_sse_regs_using_mov (HO
 	set_mem_align (mem, 128);
 	emit_move_insn (reg, mem);
 
-	ix86_add_cfa_restore_note (NULL_RTX, reg, cfa_offset);
+	ix86_add_cfa_restore_note (NULL_RTX, reg);
 
 	cfa_offset -= 16;
       }
@@ -10738,6 +10731,8 @@  ix86_expand_epilogue (int style)
 				 GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
 				 style, true);
     }
+  else
+    ix86_add_queued_cfa_restore_notes (get_last_insn ());
 
   /* Sibcall epilogues don't want a return instruction.  */
   if (style == 0)