This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]