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 <aph@xxxxxxxxxx> * 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;