This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA][PATCH][PR middle-end/59285] BARRIERS and merged blocks
- From: Jeff Law <law at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 20 Dec 2013 11:30:04 -0700
- Subject: [RFA][PATCH][PR middle-end/59285] BARRIERS and merged blocks
- Authentication-results: sourceware.org; auth=none
So here's an alternate approach to fixing 59285. I still think
attacking this in rtl_merge_blocks is better, but with nobody else
chiming in to break the deadlock Steven and myself are in, I'll go with
Steven's preferred solution (fix the callers in ifcvt.c).
If we were to return to a "fix rtl_merge_blocks" approach, I would
revamp that patch to utilize the ideas in this one. Namely that it's
not just barriers between the merged blocks that are a problem. In
fact, that's a symptom of the problem. Things have already gone wrong
by that point.
Given blocks A & B that will be merged. If A has > 1 successor and B
has no successors, the combined block will always have at least 1
successor. However, the combined block will be followed by a BARRIER
that must be removed.
Bootstrapped and regression tested on arm-unknown-linux-gnu. OK for the
trunk?
* ifcvt.c (merge_if_block): If we are merging a block with more than
one successor with a block with no successors, remove any BARRIER
after the second block.
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index ac0276c..8a4e01b 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3152,6 +3152,20 @@ merge_if_block (struct ce_if_block * ce_info)
if (then_bb)
{
+ /* If THEN_BB has no successors, then there's a BARRIER after it.
+ If COMBO_BB has more than one successor (THEN_BB), then that BARRIER
+ is no longer needed, and in fact it is incorrect to leave it in
+ the insn stream. */
+ if (EDGE_COUNT (then_bb->succs) == 0
+ && EDGE_COUNT (combo_bb->succs) > 1)
+ {
+ rtx end = NEXT_INSN (BB_END (then_bb));
+ while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
+ end = NEXT_INSN (end);
+
+ if (end && BARRIER_P (end))
+ delete_insn (end);
+ }
merge_blocks (combo_bb, then_bb);
num_true_changes++;
}
@@ -3161,6 +3175,20 @@ merge_if_block (struct ce_if_block * ce_info)
get their addresses taken. */
if (else_bb)
{
+ /* If ELSE_BB has no successors, then there's a BARRIER after it.
+ If COMBO_BB has more than one successor (ELSE_BB), then that BARRIER
+ is no longer needed, and in fact it is incorrect to leave it in
+ the insn stream. */
+ if (EDGE_COUNT (else_bb->succs) == 0
+ && EDGE_COUNT (combo_bb->succs) > 1)
+ {
+ rtx end = NEXT_INSN (BB_END (else_bb));
+ while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
+ end = NEXT_INSN (end);
+
+ if (end && BARRIER_P (end))
+ delete_insn (end);
+ }
merge_blocks (combo_bb, else_bb);
num_true_changes++;
}