From c009a3ec0a4e77e9537fede7652c6b663d1fc6e3 Mon Sep 17 00:00:00 2001 From: rth Date: Wed, 1 Jul 2009 23:21:17 +0000 Subject: [PATCH] PR bootstrap/40347 * function.c (reposition_prologue_and_epilogue_notes): If epilogue contained no insns, reposition note before last insn. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149158 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/function.c | 38 +++++++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 801851b..eecd91b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2009-07-01 Richard Henderson + PR bootstrap/40347 + * function.c (reposition_prologue_and_epilogue_notes): If epilogue + contained no insns, reposition note before last insn. + +2009-07-01 Richard Henderson + PR debug/40431 * dwarf2out.c (def_cfa_1): Revert 2009-06-11 change for DW_CFA_def_cfa_offset and DW_CFA_def_cfa. diff --git a/gcc/function.c b/gcc/function.c index a0c45de..63fe835 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -5283,15 +5283,12 @@ reposition_prologue_and_epilogue_notes (void) { #if defined (HAVE_prologue) || defined (HAVE_epilogue) \ || defined (HAVE_sibcall_epilogue) - rtx insn, last, note; - basic_block bb; - /* Since the hash table is created on demand, the fact that it is non-null is a signal that it is non-empty. */ if (prologue_insn_hash != NULL) { size_t len = htab_elements (prologue_insn_hash); - last = 0, note = 0; + rtx insn, last = NULL, note = NULL; /* Scan from the beginning until we reach the last prologue insn. */ /* ??? While we do have the CFG intact, there are two problems: @@ -5342,12 +5339,10 @@ reposition_prologue_and_epilogue_notes (void) FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) { - last = 0, note = 0; - bb = e->src; + rtx insn, first = NULL, note = NULL; + basic_block bb = e->src; - /* Scan from the beginning until we reach the first epilogue insn. - Take the cue for whether this is a plain or sibcall epilogue - from the kind of note we find first. */ + /* Scan from the beginning until we reach the first epilogue insn. */ FOR_BB_INSNS (bb, insn) { if (NOTE_P (insn)) @@ -5355,20 +5350,33 @@ reposition_prologue_and_epilogue_notes (void) if (NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG) { note = insn; - if (last) + if (first != NULL) break; } } - else if (contains (insn, epilogue_insn_hash)) + else if (first == NULL && contains (insn, epilogue_insn_hash)) { - last = insn; + first = insn; if (note != NULL) break; } } - - if (last && note && PREV_INSN (last) != note) - reorder_insns (note, note, PREV_INSN (last)); + + if (note) + { + /* If the function has a single basic block, and no real + epilogue insns (e.g. sibcall with no cleanup), the + epilogue note can get scheduled before the prologue + note. If we have frame related prologue insns, having + them scanned during the epilogue will result in a crash. + In this case re-order the epilogue note to just before + the last insn in the block. */ + if (first == NULL) + first = BB_END (bb); + + if (PREV_INSN (first) != note) + reorder_insns (note, note, PREV_INSN (first)); + } } } #endif /* HAVE_prologue or HAVE_epilogue */ -- 2.7.4