From 3b10cf4be76c929ba27a62c3dfd70b8017155635 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sun, 19 Sep 1999 16:04:01 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++ gcc/loop.c | 15 +++-- gcc/rtl.h | 1 + gcc/rtlanal.c | 70 ++++++++++++++++++++++ gcc/testsuite/g++.old-deja/g++.eh/crash1.C | 22 +++++++ 5 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.eh/crash1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a57dd51872..a8ff106d887 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +Sun Sep 19 09:03:40 1999 Mark Mitchell + + * 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 * config/i386/sol2.h (CPP_SPEC): Support -[p]threads diff --git a/gcc/loop.c b/gcc/loop.c index dcff6850fbd..cc278dce848 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 59043eadaea..94790a6e19e 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 d1b23222ad7..b02be3e2e53 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 00000000000..6ba4d0854b1 --- /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; + } +} -- 2.30.2