summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-09-19 18:32:21 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2001-09-19 18:32:21 +0000
commitf8fd77b7c4a7075421a7552b36403789274ac16a (patch)
tree0ab5d4ace72ef7a97ad21aea402e46a371cca067 /gcc
parentc2c76df5218727dbba0a8e4b3eed4eb01ed14e48 (diff)
downloadgcc-f8fd77b7c4a7075421a7552b36403789274ac16a.tar.gz
* recog.c (peephole2_optimize): Likewise. Handle EH_REGION;
copy over CALL_INSN_FUNCTION_USAGE. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45693 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog2
-rw-r--r--gcc/recog.c63
2 files changed, 65 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7dd1da4ac72..336cf9bc32f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -4,6 +4,8 @@
* emit-rtl.c (try_split): Copy NORETURN, SETJMP, ALWAYS_RETURN
and NON_LOCAL_GOTO notes.
+ * recog.c (peephole2_optimize): Likewise. Handle EH_REGION;
+ copy over CALL_INSN_FUNCTION_USAGE.
2001-09-18 Catherine Moore <clm@redhat.com>
diff --git a/gcc/recog.c b/gcc/recog.c
index 21de5e5f29b..c0b60f8575a 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3059,6 +3059,69 @@ peephole2_optimize (dump_file)
try = peephole2_insns (PATTERN (insn), insn, &match_len);
if (try != NULL)
{
+ /* 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. */
+ for (i = 0; i <= match_len; ++i)
+ {
+ int j, k;
+ rtx old_insn, new_insn, note;
+
+ j = i + peep2_current;
+ if (j >= MAX_INSNS_PER_PEEP2 + 1)
+ j -= MAX_INSNS_PER_PEEP2 + 1;
+ old_insn = peep2_insn_data[j].insn;
+ if (GET_CODE (old_insn) != CALL_INSN)
+ continue;
+
+ new_insn = NULL_RTX;
+ if (GET_CODE (try) == SEQUENCE)
+ for (k = XVECLEN (try, 0) - 1; k >= 0; k--)
+ {
+ rtx x = XVECEXP (try, 0, k);
+ if (GET_CODE (x) == CALL_INSN)
+ {
+ new_insn = x;
+ break;
+ }
+ }
+ else if (GET_CODE (try) == CALL_INSN)
+ new_insn = try;
+ if (! new_insn)
+ abort ();
+
+ CALL_INSN_FUNCTION_USAGE (new_insn)
+ = CALL_INSN_FUNCTION_USAGE (old_insn);
+
+ for (note = REG_NOTES (old_insn);
+ note;
+ note = XEXP (note, 1))
+ switch (REG_NOTE_KIND (note))
+ {
+ case REG_EH_REGION:
+ case REG_NORETURN:
+ case REG_SETJMP:
+ case REG_ALWAYS_RETURN:
+ REG_NOTES (new_insn)
+ = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
+ XEXP (note, 0),
+ REG_NOTES (new_insn));
+ break;
+ }
+
+ /* Croak if there is another call in the sequence. */
+ while (++i <= match_len)
+ {
+ j = i + peep2_current;
+ if (j >= MAX_INSNS_PER_PEEP2 + 1)
+ j -= MAX_INSNS_PER_PEEP2 + 1;
+ old_insn = peep2_insn_data[j].insn;
+ if (GET_CODE (old_insn) == CALL_INSN)
+ abort ();
+ }
+ break;
+ }
+
i = match_len + peep2_current;
if (i >= MAX_INSNS_PER_PEEP2 + 1)
i -= MAX_INSNS_PER_PEEP2 + 1;