diff mbox

[RFA,PR,middle-end/59285] BARRIERS and merged blocks

Message ID 52B48CAC.7050904@redhat.com
State New
Headers show

Commit Message

Jeff Law Dec. 20, 2013, 6:30 p.m. UTC
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 mbox

Patch

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++;
     }