On i386 we replace (add sp -4) with (push reg).  This generates faster
and smaller code.

However, we are not copying RTX_FRAME_RELATED_P from the old
instructions to the new, and so we are not emitting unwind information
for the stack pointer adjustment.  The breaks stack traces on gcj, and
I suspect it breaks a bunch of stuff elsewhere too.

This very crude patch sets RTX_FRAME_RELATED_P on every one of the new
instructions if any of the old instructions had RTX_FRAME_RELATED_P
set.  It seems to do the trick, but I suspect there must be a more
subtle way to do it.

Can anyone suggest a neater way to do this?

Without this patch, for
java.lang.Throwable.Throwable(java.lang.String) we get

00a326a8 <java.lang.Throwable.Throwable(java.lang.String)>:
  a326a8:       56                      push   %esi
  a326a9:       53                      push   %ebx
  a326aa:       50                      push   %eax  <=== ** This is the insn 
generated by peephole **
  a326ab:       e8 00 00 00 00          call   a326b0 
<java.lang.Throwable.Throwable(java.lang.String)+0x8>
  a326b0:       5b                      pop    %ebx

00058f08 0000001c 0003252c FDE cie=000269e0 pc=00a328f8..00a3292e               
            
  Augmentation data:     00 00 00 00                                            
            
                                                                                
            
  DW_CFA_advance_loc: 1 to 00a328f9                                             
            
  DW_CFA_def_cfa_offset: 8                                                      
            
  DW_CFA_advance_loc: 1 to 00a328fa                                             
            
  DW_CFA_def_cfa_offset: 12                                                     
            
  DW_CFA_offset: r3 at cfa-12                                                   
            
  DW_CFA_offset: r6 at cfa-8                                                    
            
  DW_CFA_nop                                                                    
            
                                                                 
after the patch, we get
                                                                 
0005946c 00000020 000328e4 FDE cie=00026b8c pc=00a326a8..00a326de
  Augmentation data:     00 00 00 00

  DW_CFA_advance_loc: 1 to 00a326a9
  DW_CFA_def_cfa_offset: 8
  DW_CFA_advance_loc: 1 to 00a326aa
  DW_CFA_def_cfa_offset: 12
  DW_CFA_advance_loc: 1 to 00a326ab
  DW_CFA_def_cfa_offset: 16
  DW_CFA_offset: r0 at cfa-16
  DW_CFA_offset: r3 at cfa-12
  DW_CFA_offset: r6 at cfa-8

Here's a trivial test case:

public class Hello {

     public static void main(String[] args) {
        System.out.println("Hello, World!");
        new Throwable().printStackTrace();
     }
}

 $ ~/gcc/install/bin/gcj Hello.java --main=Hello -g
 $ LD_LIBRARY_PATH=~/gcc/install/lib ./a.out
Hello, World!
java.lang.Throwable
   at Hello.main (Hello.java:5)

Andrew.


2005-12-19  Andrew Haley  <[EMAIL PROTECTED]>

        * recog.c (peephole2_optimize): Copy RTX_FRAME_RELATED_P from old
        instructions to new instructions.

Index: recog.c
===================================================================
--- recog.c     (revision 108424)
+++ recog.c     (working copy)
@@ -3107,6 +3107,7 @@
              int match_len;
              rtx note;
              bool was_call = false;
+             bool frame_related = false;
 
              /* Record this insn.  */
              if (--peep2_current < 0)
@@ -3122,6 +3123,14 @@
              try = peephole2_insns (PATTERN (insn), insn, &match_len);
              if (try != NULL)
                {
+                 {
+                   rtx old_insn = insn;
+                   for (i = 0; i <= match_len; ++i)
+                     {
+                       frame_related |= RTX_FRAME_RELATED_P (old_insn);
+                       old_insn = NEXT_INSN (old_insn);
+                     }             
+                 }
                  /* If we are splitting a CALL_INSN, look for the CALL_INSN
                     in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
                     cfg-related call notes.  */
@@ -3179,6 +3188,16 @@
                      break;
                    }
 
+                 if (frame_related)
+                   {
+                     rtx new_insn = try;
+                     while (new_insn != NULL_RTX)
+                       {                        
+                         RTX_FRAME_RELATED_P (new_insn) = true;
+                         new_insn = NEXT_INSN (new_insn);
+                       }                         
+                   }
+
                  i = match_len + peep2_current;
                  if (i >= MAX_INSNS_PER_PEEP2 + 1)
                    i -= MAX_INSNS_PER_PEEP2 + 1;

Reply via email to