diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2010-09-27 19:55:29 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@gcc.gnu.org> | 2010-09-27 19:55:29 +0000 |
commit | fdf0b018a6fefd7dffa785b5cae6644343f72912 (patch) | |
tree | ce69be03d7ed2ceb937c270359ca6eb571472c46 /gcc/cfgcleanup.c | |
parent | 7458026b018e6635b9d1bae9ec3b9f4738c3d94a (diff) | |
download | gcc-fdf0b018a6fefd7dffa785b5cae6644343f72912.zip gcc-fdf0b018a6fefd7dffa785b5cae6644343f72912.tar.gz gcc-fdf0b018a6fefd7dffa785b5cae6644343f72912.tar.bz2 |
re PR rtl-optimization/45792 (cris-elf build failure (hangs) due to fix for PR44374)
PR rtl-optimization/45792
* cfgcleanup.c (try_head_merge_bb): New rtx vector nextptr.
If not all insns are to be merged, for each edge, stash the
next candidate after the to-be-merged insns before doing the
merge, and use them for the retry at the new insertion point.
Handle CC0 targets when retrying.
Co-Authored-By: Bernd Schmidt <bernds@codesourcery.com>
From-SVN: r164663
Diffstat (limited to 'gcc/cfgcleanup.c')
-rw-r--r-- | gcc/cfgcleanup.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 9f3e68e..d28ae6f 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -1944,7 +1944,7 @@ try_head_merge_bb (basic_block bb) basic_block final_dest_bb = NULL; int max_match = INT_MAX; edge e0; - rtx *headptr, *currptr; + rtx *headptr, *currptr, *nextptr; bool changed, moveall; unsigned ix; rtx e0_last_head, cond, move_before; @@ -2077,6 +2077,7 @@ try_head_merge_bb (basic_block bb) currptr = XNEWVEC (rtx, nedges); headptr = XNEWVEC (rtx, nedges); + nextptr = XNEWVEC (rtx, nedges); for (ix = 0; ix < nedges; ix++) { @@ -2132,6 +2133,14 @@ try_head_merge_bb (basic_block bb) /* Try again, using a different insertion point. */ move_before = jump; + +#ifdef HAVE_cc0 + /* Don't try moving before a cc0 user, as that may invalidate + the cc0. */ + if (reg_mentioned_p (cc0_rtx, jump)) + break; +#endif + continue; } @@ -2155,6 +2164,18 @@ try_head_merge_bb (basic_block bb) } } + /* If we can't currently move all of the identical insns, remember + each insn after the range that we'll merge. */ + if (!moveall) + for (ix = 0; ix < nedges; ix++) + { + rtx curr = currptr[ix]; + do + curr = NEXT_INSN (curr); + while (!NONDEBUG_INSN_P (curr)); + nextptr[ix] = curr; + } + reorder_insns (headptr[0], currptr[0], PREV_INSN (move_before)); df_set_bb_dirty (EDGE_SUCC (bb, 0)->dest); if (final_dest_bb != NULL) @@ -2170,16 +2191,18 @@ try_head_merge_bb (basic_block bb) if (jump == move_before) break; - /* Try again, using a different insertion point. */ + /* For the unmerged insns, try a different insertion point. */ move_before = jump; + +#ifdef HAVE_cc0 + /* Don't try moving before a cc0 user, as that may invalidate + the cc0. */ + if (reg_mentioned_p (cc0_rtx, jump)) + break; +#endif + for (ix = 0; ix < nedges; ix++) - { - rtx curr = currptr[ix]; - do - curr = NEXT_INSN (curr); - while (!NONDEBUG_INSN_P (curr)); - currptr[ix] = headptr[ix] = curr; - } + currptr[ix] = headptr[ix] = nextptr[ix]; } } while (!moveall); @@ -2187,6 +2210,7 @@ try_head_merge_bb (basic_block bb) out: free (currptr); free (headptr); + free (nextptr); crossjumps_occured |= changed; |