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]

Re: [patch] Stay in cfglayout mode until after cse2


Steven Bosscher wrote:
> Hi,
> 
> This patch postpones going out of cfglayout mode until after cse2.
> It will probably stay there for a while, because combine is totally
> unprepared for cfglayout mode right now.  Paolo Bonzini has fixes
> for this on the dataflow branch, but until that branch is merged,
> we'll have to go out of cfglayout mode before combine.
> 
> The next hurdle will be regmove.  I'm hoping a Google Summer of
> Code student will re-implement regmove (with my help if required)...
> 
> This patch has been bootstrapped&tested on i686-pc-linux-gnu.
> OK for the trunk?

Once this hits dataflow branch, I'll re-regtest the patch for
combine (which currently bootstraps but has regressions).

Paolo
2007-03-14  Paolo Bonzini  <bonzini@gnu.org>

	* cfglayout.c (fixup_reorder_chain): Add a barrier when there
	is a jump but no fallthrough edge -- I'm pretty confident that
	this is not necessary, but I bootstrapped with this so I'm
	including it.
	* combine.c (find_single_use): Use CFG to go through EBBs.
        (update_cfg_for_uncondjump): New.
        (try_combine): Check for unconditional jumps after marking insns for
        rescan.  Use update_cfg_for_uncondjump.
        (reg_dead_at_p): Stop at head of BB, don't go back to beginning of EBB.
	(rest_of_handle_combine): Enter/exit cfglayout mode.

Index: cfglayout.c
===================================================================
--- cfglayout.c	(revision 122655)
+++ cfglayout.c	(working copy)
@@ -741,6 +741,10 @@ fixup_reorder_chain (void)
 		 jump.  In the 99% case, there should not have been a
 		 fallthru edge.  */
 	      gcc_assert (returnjump_p (bb_end_insn) || !e_fall);
+
+              if (NEXT_INSN (bb_end_insn) == 0
+                  || !BARRIER_P (NEXT_INSN (bb_end_insn)))
+                emit_barrier_after (bb_end_insn);
 	      continue;
 	    }
 	}
Index: combine.c
===================================================================
--- combine.c	(revision 122655)
+++ combine.c	(working copy)
@@ -103,6 +103,7 @@ Software Foundation, 51 Franklin Street,
 #include "params.h"
 #include "timevar.h"
 #include "tree-pass.h"
+#include "cfglayout.h"
 #include "df.h"
 
 /* Number of attempts to combine instructions in this function.  */
@@ -588,6 +589,7 @@ find_single_use_1 (rtx dest, rtx *loc)
 static rtx *
 find_single_use (rtx dest, rtx insn, rtx *ploc)
 {
+  basic_block bb;
   rtx next;
   rtx *result;
   rtx link;
@@ -610,23 +612,41 @@ find_single_use (rtx dest, rtx insn, rtx
   if (!REG_P (dest))
     return 0;
 
-  for (next = next_nonnote_insn (insn);
-       next != 0 && !LABEL_P (next);
-       next = next_nonnote_insn (next))
-    if (INSN_P (next) && dead_or_set_p (next, dest))
-      {
-	for (link = LOG_LINKS (next); link; link = XEXP (link, 1))
-	  if (XEXP (link, 0) == insn)
+  next = insn;
+  bb = BLOCK_FOR_INSN (next);
+  for (;;)
+    {
+      /* Follow an extended basic block.  */
+      if (next == BB_END (bb))
+	{
+	  if (!single_succ_p (bb))
+	    break;
+	  bb = single_succ (bb);
+	  if (!single_pred_p (bb))
 	    break;
+	  next = BB_HEAD (bb);
+	}
+      else
+	next = NEXT_INSN (next);
 
-	if (link)
-	  {
-	    result = find_single_use_1 (dest, &PATTERN (next));
-	    if (ploc)
-	      *ploc = next;
-	    return result;
-	  }
-      }
+      if (!next)
+	break;
+
+      if (INSN_P (next) && dead_or_set_p (next, dest))
+        {
+	  for (link = LOG_LINKS (next); link; link = XEXP (link, 1))
+	    if (XEXP (link, 0) == insn)
+	      break;
+
+	  if (link)
+	    {
+	      result = find_single_use_1 (dest, &PATTERN (next));
+	      if (ploc)
+	        *ploc = next;
+	      return result;
+	    }
+        }
+    }
 
   return 0;
 }
@@ -2103,6 +2123,36 @@ reg_subword_p (rtx x, rtx reg)
 	 && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT;
 }
 
+static void
+update_cfg_for_uncondjump (rtx insn, bool fallthru)
+{
+  basic_block bb = BLOCK_FOR_INSN (insn);
+
+  if (current_ir_type () == IR_RTL_CFGLAYOUT)
+    {
+      /* For a (set (pc) (label_ref FOO)), we need to delete the insn *after*
+	 removing the dead edges.  Otherwise, we always keep the old fallthrough
+	 edge, which is wrong.  */
+      if (BB_END (bb) == insn)
+	purge_dead_edges (bb);
+
+      delete_insn (insn);
+      if (EDGE_COUNT (bb->succs) == 1)
+        single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
+    }
+  else
+    {
+      if (fallthru)
+	delete_insn (insn);
+      else
+        {
+          /* Emit a BARRIER after the unconditional jump.  */
+          if (NEXT_INSN (insn) == 0 || !BARRIER_P (NEXT_INSN (insn)))
+            emit_barrier_after (insn);
+        }
+    }
+}
+
 
 /* Try to combine the insns I1 and I2 into I3.
    Here I1 and I2 appear earlier than I3.
@@ -3679,43 +3729,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int
     if (newi2pat)
       note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
     note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
-
-    /* Set new_direct_jump_p if a new return or simple jump instruction
-       has been created.
-
-       If I3 is now an unconditional jump, ensure that it has a
-       BARRIER following it since it may have initially been a
-       conditional jump.  It may also be the last nonnote insn.  */
-
-    if (returnjump_p (i3) || any_uncondjump_p (i3))
-      {
-	*new_direct_jump_p = 1;
-	mark_jump_label (PATTERN (i3), i3, 0);
-
-	if ((temp = next_nonnote_insn (i3)) == NULL_RTX
-	    || !BARRIER_P (temp))
-	  emit_barrier_after (i3);
-      }
-
-    if (undobuf.other_insn != NULL_RTX
-	&& (returnjump_p (undobuf.other_insn)
-	    || any_uncondjump_p (undobuf.other_insn)))
-      {
-	*new_direct_jump_p = 1;
-
-	if ((temp = next_nonnote_insn (undobuf.other_insn)) == NULL_RTX
-	    || !BARRIER_P (temp))
-	  emit_barrier_after (undobuf.other_insn);
-      }
-
-    /* An NOOP jump does not need barrier, but it does need cleaning up
-       of CFG.  */
-    if (GET_CODE (newpat) == SET
-	&& SET_SRC (newpat) == pc_rtx
-	&& SET_DEST (newpat) == pc_rtx)
-      *new_direct_jump_p = 1;
   }
-  
+
   if (undobuf.other_insn != NULL_RTX)
     {
       if (dump_file)
@@ -3756,6 +3771,37 @@ try_combine (rtx i3, rtx i2, rtx i1, int
       df_insn_rescan (i3);
     }
   
+  /* Set new_direct_jump_p if a new return or simple jump instruction
+     has been created.
+
+     If I3 is now an unconditional jump, ensure that it has a
+     BARRIER following it since it may have initially been a
+     conditional jump.  It may also be the last nonnote insn.  */
+
+  if (returnjump_p (i3) || any_uncondjump_p (i3))
+    {
+      *new_direct_jump_p = 1;
+      mark_jump_label (PATTERN (i3), i3, 0);
+      update_cfg_for_uncondjump (i3, false);
+    }
+
+  if (undobuf.other_insn != NULL_RTX
+      && (returnjump_p (undobuf.other_insn)
+	  || any_uncondjump_p (undobuf.other_insn)))
+    {
+      *new_direct_jump_p = 1;
+      update_cfg_for_uncondjump (undobuf.other_insn, false);
+    }
+
+  /* An NOOP also needs cleaning up of CFG.  */
+  if (GET_CODE (newpat) == SET
+      && SET_SRC (newpat) == pc_rtx
+      && SET_DEST (newpat) == pc_rtx)
+    {
+      *new_direct_jump_p = 1;
+      update_cfg_for_uncondjump (i3, true);
+    }
+  
   combine_successes++;
   undo_commit ();
 
@@ -11850,32 +11896,28 @@ reg_dead_at_p (rtx reg, rtx insn)
 	  return 0;
     }
 
-  /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, label, or
-     beginning of function.  */
-  for (; insn && !LABEL_P (insn) && !BARRIER_P (insn);
-       insn = prev_nonnote_insn (insn))
-    {
-      note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
-      if (reg_dead_flag)
-	return reg_dead_flag == 1 ? 1 : 0;
+  /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, or
+     beginning of basic block.  */
+  block = BLOCK_FOR_INSN (insn);
+  for (;;)
+    {
+      if (INSN_P (insn))
+        {
+	  note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
+	  if (reg_dead_flag)
+	    return reg_dead_flag == 1 ? 1 : 0;
 
-      if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
-	return 1;
-    }
+	  if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
+	    return 1;
+        }
 
-  /* Get the basic block that we were in.  */
-  if (insn == 0)
-    block = ENTRY_BLOCK_PTR->next_bb;
-  else
-    {
-      FOR_EACH_BB (block)
-	if (insn == BB_HEAD (block))
-	  break;
+      if (insn == BB_HEAD (block))
+	break;
 
-      if (block == EXIT_BLOCK_PTR)
-	return 0;
+      insn = PREV_INSN (insn);
     }
 
+  /* Look at live-in sets for the basic block that we were in.  */
   for (i = reg_dead_regno; i < reg_dead_endregno; i++)
     if (REGNO_REG_SET_P (DF_LIVE_IN (block), i))
       return 0;
@@ -12935,6 +12977,9 @@ static unsigned int
 rest_of_handle_combine (void)
 {
   int rebuild_jump_labels_after_combine;
+  basic_block bb;
+
+  cfg_layout_initialize (0);
 
   df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
   df_ri_add_problem (DF_RI_LIFE);
@@ -12943,6 +12988,12 @@ rest_of_handle_combine (void)
   rebuild_jump_labels_after_combine
     = combine_instructions (get_insns (), max_reg_num ());
 
+  FOR_EACH_BB (bb)
+    if (bb->index >= NUM_FIXED_BLOCKS
+        && bb->next_bb->index >= NUM_FIXED_BLOCKS)
+      bb->aux = bb->next_bb;
+  cfg_layout_finalize ();
+
   /* Combining insns may have turned an indirect jump into a
      direct jump.  Rebuild the JUMP_LABEL fields of jumping
      instructions.  */

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