aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-09-19 16:04:01 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-09-19 16:04:01 +0000
commit3b10cf4be76c929ba27a62c3dfd70b8017155635 (patch)
tree07f4f7a539e15cea1a65dc0b43285692ada2a516 /gcc
parent47d7090eeb4503fa6123cf1089a560b6379bff56 (diff)
downloadgcc-3b10cf4be76c929ba27a62c3dfd70b8017155635.zip
gcc-3b10cf4be76c929ba27a62c3dfd70b8017155635.tar.gz
gcc-3b10cf4be76c929ba27a62c3dfd70b8017155635.tar.bz2
rtl.h (insns_safe_to_move_p): New function.
* rtl.h (insns_safe_to_move_p): New function. * loop.c (find_and_verify_loops): Use it. * rtlanal.c (insns_safe_to_move_p): Define it. From-SVN: r29509
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/loop.c15
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c70
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/crash1.C22
5 files changed, 110 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a57dd5..a8ff106 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+Sun Sep 19 09:03:40 1999 Mark Mitchell <mark@codesourcery.com>
+
+ * rtl.h (insns_safe_to_move_p): New function.
+ * loop.c (find_and_verify_loops): Use it.
+ * rtlanal.c (insns_safe_to_move_p): Define it.
+
Sat Sep 18 16:01:18 1999 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
* config/i386/sol2.h (CPP_SPEC): Support -[p]threads
diff --git a/gcc/loop.c b/gcc/loop.c
index dcff685..cc278dc 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -2779,6 +2779,7 @@ find_and_verify_loops (f)
{
rtx p;
rtx our_next = next_real_insn (insn);
+ rtx last_insn_to_move = NEXT_INSN (insn);
int dest_loop;
int outer_loop = -1;
@@ -2830,7 +2831,11 @@ find_and_verify_loops (f)
&& INSN_UID (JUMP_LABEL (p)) != 0
&& condjump_p (p)
&& ! simplejump_p (p)
- && next_real_insn (JUMP_LABEL (p)) == our_next)
+ && next_real_insn (JUMP_LABEL (p)) == our_next
+ /* If it's not safe to move the sequence, then we
+ mustn't try. */
+ && insns_safe_to_move_p (p, NEXT_INSN (insn),
+ &last_insn_to_move))
{
rtx target
= JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
@@ -2885,11 +2890,13 @@ find_and_verify_loops (f)
/* Include the BARRIER after INSN and copy the
block after LOC. */
- new_label = squeeze_notes (new_label, NEXT_INSN (insn));
- reorder_insns (new_label, NEXT_INSN (insn), loc);
+ new_label = squeeze_notes (new_label,
+ last_insn_to_move);
+ reorder_insns (new_label, last_insn_to_move, loc);
/* All those insns are now in TARGET_LOOP_NUM. */
- for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
+ for (q = new_label;
+ q != NEXT_INSN (last_insn_to_move);
q = NEXT_INSN (q))
uid_loop_num[INSN_UID (q)] = target_loop_num;
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 59043ea..94790a6 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1130,6 +1130,7 @@ extern int for_each_rtx PROTO((rtx *, rtx_function, void *));
extern rtx regno_use_in PROTO((int, rtx));
extern int auto_inc_p PROTO((rtx));
extern void remove_node_from_expr_list PROTO((rtx, rtx *));
+extern int insns_safe_to_move_p PROTO((rtx, rtx, rtx *));
/* flow.c */
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d1b2322..b02be3e 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2293,3 +2293,73 @@ auto_inc_p (x)
}
return 0;
}
+
+/* Return 1 if the sequence of instructions beginning with FROM and up
+ to and including TO is safe to move. If NEW_TO is non-NULL, and
+ the sequence is not already safe to move, but can be easily
+ extended to a sequence which is safe, then NEW_TO will point to the
+ end of the extended sequence. */
+
+int
+insns_safe_to_move_p (from, to, new_to)
+ rtx from;
+ rtx to;
+ rtx *new_to;
+{
+ int eh_region_count = 0;
+ int past_to_p = 0;
+ rtx r = from;
+
+ while (r)
+ {
+ if (GET_CODE (r) == NOTE)
+ {
+ switch (NOTE_LINE_NUMBER (r))
+ {
+ case NOTE_INSN_EH_REGION_BEG:
+ ++eh_region_count;
+ break;
+
+ case NOTE_INSN_EH_REGION_END:
+ if (eh_region_count == 0)
+ /* This sequence of instructions contains the end of
+ an exception region, but not he beginning. Moving
+ it will cause chaos. */
+ return 0;
+
+ --eh_region_count;
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if (past_to_p)
+ /* If we've passed TO, and we see a non-note instruction, we
+ can't extend the sequence to a movable sequence. */
+ return 0;
+
+ if (r == to)
+ {
+ if (!new_to)
+ /* It's OK to move the sequence if there were matched sets of
+ exception region notes. */
+ return eh_region_count == 0;
+
+ past_to_p = 1;
+ }
+
+ /* It's OK to move the sequence if there were matched sets of
+ exception region notes. */
+ if (past_to_p && eh_region_count == 0)
+ {
+ *new_to = r;
+ return 1;
+ }
+
+ /* Go to the next instruction. */
+ r = NEXT_INSN (r);
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/crash1.C b/gcc/testsuite/g++.old-deja/g++.eh/crash1.C
new file mode 100644
index 0000000..6ba4d08
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.eh/crash1.C
@@ -0,0 +1,22 @@
+// Build don't link:
+// Special g++ Options: -O1 -fno-inline-functions
+
+struct A
+{
+ ~A ();
+};
+
+bool foo ();
+
+int i;
+int j;
+
+A bar ()
+{
+ for (i = 0; i < 1; ++i)
+ if (j)
+ {
+ A tmp;
+ return tmp;
+ }
+}