aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgcleanup.c
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2010-09-27 19:55:29 +0000
committerHans-Peter Nilsson <hp@axis.com>2010-09-27 19:55:29 +0000
commit506caef4fc3f5ee0ab95d692a866d79c6110f039 (patch)
treece69be03d7ed2ceb937c270359ca6eb571472c46 /gcc/cfgcleanup.c
parent88a1724aef9e79dbe06f0cf12d73cf117e0f6cb7 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@164663 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgcleanup.c')
-rw-r--r--gcc/cfgcleanup.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 9f3e68ee082..d28ae6fb0df 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;