aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2009-07-01 16:21:17 -0700
committerRichard Henderson <rth@gcc.gnu.org>2009-07-01 16:21:17 -0700
commit997704f18b252a1063f514a716fbf6b636f62620 (patch)
tree2863da00a857ad078f33c3cdf9b6b6552c38c036 /gcc/function.c
parent9f2af3cef8463e296639cfaa5811c38b2dabeae5 (diff)
downloadgcc-997704f18b252a1063f514a716fbf6b636f62620.zip
gcc-997704f18b252a1063f514a716fbf6b636f62620.tar.gz
gcc-997704f18b252a1063f514a716fbf6b636f62620.tar.bz2
re PR bootstrap/40347 (i386-darwin ICEs while building libgcc during stage2)
PR bootstrap/40347 * function.c (reposition_prologue_and_epilogue_notes): If epilogue contained no insns, reposition note before last insn. From-SVN: r149158
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c38
1 files changed, 23 insertions, 15 deletions
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 */