From: Bernd Schmidt Date: Wed, 20 Dec 2000 13:53:00 +0000 (+0000) Subject: Backport a fix to the 2.95 branch X-Git-Tag: prereleases/gcc-2.95.3-test1~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d750c728974471c46fdf057f11a86a32afa52f32;p=thirdparty%2Fgcc.git Backport a fix to the 2.95 branch From-SVN: r38397 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49b0610895a2..3edb05f1b2a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2000-12-20 Bernd Schmidt + 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. + Thu Nov 2 19:20:12 2000 J"orn Rennecke * reload.c (find_equiv_reg): Test all hard registers for membership in the requested class. diff --git a/gcc/loop.c b/gcc/loop.c index 1aa56b75029a..a85e6d33d477 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -2773,6 +2773,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; @@ -2824,7 +2825,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 (); @@ -2893,11 +2898,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 8eba5eab5d9d..0f43e87dc751 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1084,6 +1084,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 fb4f87c07de3..49131a4efedc 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2289,3 +2289,82 @@ 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. + + For now, this function only checks that the region contains whole + exception regiongs, but it could be extended to check additional + conditions as well. */ + +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; + + /* By default, assume the end of the region will be what was + suggested. */ + if (new_to) + *new_to = to; + + 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; +}