This is the mail archive of the gcc@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]

How to reverse patch reversal in cfgcleanup.c (Was: RFA: re-instate struct_equiv code)


For easier reviewing, I have attached the diff to the cfgcleanup version previous to the patch backout.

I'm not sure what the best way to keep the svn history sane is. When/if the patch is approved, should I first do an
svn merge -r108792:108791, check that in, and then apply the patch with the actual new stuff?
Or will an svn copy of cfgcleanup.c work better?
Index: cfgcleanup.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L cfgcleanup.c	(revision 108713) -L cfgcleanup.c	(working copy) .svn/tmp/text-base/cfgcleanup.c.svn-base cfgcleanup.c
--- cfgcleanup.c	(revision 108713)
+++ cfgcleanup.c	(working copy)
@@ -936,8 +936,8 @@ condjump_equiv_p (struct equiv_info *inf
   if (code2 == UNKNOWN)
     return false;
 
-  if (call_init && !struct_equiv_init (STRUCT_EQUIV_START | info->mode, info))
-    gcc_unreachable ();
+  if (call_init)
+    struct_equiv_init (STRUCT_EQUIV_START | info->mode, info, false);
   /* Make the sources of the pc sets unreadable so that when we call
      insns_match_p it won't process them.
      The death_notes_match_p from insns_match_p won't see the local registers
@@ -1096,7 +1096,7 @@ outgoing_edges_match (int *mode, struct 
 		}
 
 	      if (identical
-		  && struct_equiv_init (STRUCT_EQUIV_START | *mode, info))
+		  && struct_equiv_init (STRUCT_EQUIV_START | *mode, info, true))
 		{
 		  bool match;
 
@@ -1118,17 +1118,20 @@ outgoing_edges_match (int *mode, struct 
 	}
     }
 
+  /* Ensure that the edge counts do match.  */
+  if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
+    return false;
+
   /* First ensure that the instructions match.  There may be many outgoing
      edges so this test is generally cheaper.  */
-  if (!struct_equiv_init (STRUCT_EQUIV_START | *mode, info)
+  /* FIXME: the regset compare might be costly.  We should try to get a cheap
+     and reasonably effective test first.  */
+  if (!struct_equiv_init (STRUCT_EQUIV_START | *mode, info, true)
       || !insns_match_p (BB_END (bb1), BB_END (bb2), info))
     return false;
 
-  /* Search the outgoing edges, ensure that the counts do match, find possible
-     fallthru and exception handling edges since these needs more
-     validation.  */
-  if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
-    return false;
+  /* Search the outgoing edges, find possible fallthru and exception
+     handling edges since these needs more validation.  */
 
   FOR_EACH_EDGE (e1, ei, bb1->succs)
     {
@@ -1353,8 +1356,6 @@ try_crossjump_to_edge (int mode, edge e1
 	fprintf (dump_file, "Splitting bb %i before %i insns\n",
 		 src2->index, nmatch);
       redirect_to = split_block (src2, PREV_INSN (info.cur.x_start))->dest;
-      COPY_REG_SET (info.y_block->il.rtl->global_live_at_end,
-		    info.x_block->il.rtl->global_live_at_end);
     }
 
   if (dump_file)
@@ -1432,6 +1433,8 @@ try_crossjump_to_edge (int mode, edge e1
   to_remove = single_succ (redirect_from);
 
   redirect_edge_and_branch_force (single_succ_edge (redirect_from), redirect_to);
+  COPY_REG_SET (redirect_from->il.rtl->global_live_at_end,
+		redirect_to->il.rtl->global_live_at_start);
   delete_basic_block (to_remove);
 
   update_forwarder_flag (redirect_from);
@@ -1588,9 +1591,22 @@ try_optimize_cfg (int mode)
   bool changed;
   int iterations = 0;
   basic_block bb, b, next;
+  bool can_modify_jumps = ! targetm.cannot_modify_jumps_p ();
+  bool do_crossjump = false;
 
-  if (mode & CLEANUP_CROSSJUMP)
-    add_noreturn_fake_exit_edges ();
+  if (can_modify_jumps && (mode & CLEANUP_CROSSJUMP))
+    {
+      do_crossjump = true;
+      /* Life info updates malfunction in the presence of fake edges.
+	 If we want to do any updates while fake edges are present, we'll have
+	 to make sure to exclude them when recomputing global_live_at_end,
+	 or treat them like EH edges.  */
+      update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
+					(PROP_DEATH_NOTES
+					 | ((mode & CLEANUP_POST_REGSTACK)
+					    ? PROP_POST_REGSTACK : 0)));
+      add_noreturn_fake_exit_edges ();
+    }
 
   if (mode & (CLEANUP_UPDATE_LIFE | CLEANUP_CROSSJUMP | CLEANUP_THREADING))
     clear_bb_flags ();
@@ -1598,7 +1614,7 @@ try_optimize_cfg (int mode)
   FOR_EACH_BB (bb)
     update_forwarder_flag (bb);
 
-  if (! targetm.cannot_modify_jumps_p ())
+  if (can_modify_jumps)
     {
       first_pass = true;
       /* Attempt to merge blocks as made possible by edge removal.  If
@@ -1754,8 +1770,8 @@ try_optimize_cfg (int mode)
 		changed_here = true;
 
 	      /* Look for shared code between blocks.  */
-	      if ((mode & CLEANUP_CROSSJUMP)
-		  && try_crossjump_bb (mode, b))
+	      if (do_crossjump
+		  && try_crossjump_bb (mode | STRUCT_EQUIV_SUSPEND_UPDATES, b))
 		changed_here = true;
 
 	      /* Don't get confused by the index shift caused by
@@ -1766,8 +1782,9 @@ try_optimize_cfg (int mode)
 		changed = true;
 	    }
 
-	  if ((mode & CLEANUP_CROSSJUMP)
-	      && try_crossjump_bb (mode, EXIT_BLOCK_PTR))
+	  if (do_crossjump
+	      && try_crossjump_bb (mode | STRUCT_EQUIV_SUSPEND_UPDATES,
+				   EXIT_BLOCK_PTR))
 	    changed = true;
 
 #ifdef ENABLE_CHECKING
@@ -1781,7 +1798,7 @@ try_optimize_cfg (int mode)
       while (changed);
     }
 
-  if (mode & CLEANUP_CROSSJUMP)
+  if (do_crossjump)
     remove_fake_exit_edges ();
 
   FOR_ALL_BB (b)

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