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]

[dataflow]: PATCH COMMITTED to fix dce/dse handling of libcalls.


This patch gets the merge with mainline that dannyb committed two days
ago bootstrapping with no regressions on x86-64, x86-32 and ppc.  The
branch will not bootstrap on the ia-64 because the point where Danny
merged from the mainline was having a bad ia-64 day.  (However, the
dataflow branch does fail in exactly the same place as mainline).

There was one bug uncovered in this merge.  An assertion added to cse by
stevenb triggered.  The assertion was caused by dce deleting part of a
libcall.  This is fixed here.  Stevenb also noticed that dataflow info
being printed in the dumps needed to be prepended with an ";; " so it
looks more like the old dumps (and more importantly can be removed with
the same scripts).  This has been also fixed here.

Kenny


2006-12-22  Kenneth Zadeck <zadeck@naturalbridge.com>
    * df-problems.c (df_ru_start_dump, df_ru_top_dump,
    df_ru_bottom_dump, df_rd_start_dump, df_rd_top_dump,
    df_rd_bottom_dump, df_lr_top_dump, df_lr_bottom_dump,
    df_ur_top_dump, df_ur_bottom_dump, df_live_top_dump,
    df_urec_top_dump, df_urec_bottom_dump, df_chain_start_dump,
    df_ri_start_dump): Added ";; " to the beginning of dataflow
    information put in dump files.
    * dce.c (marked_libcalls, delete_unmarked_insns): Removed.
    (prescan_insns_for_dce, mark_libcall, dce_process_block,
    prescan_insns_for_dse): Replaced libcall marking mechanism.
          (init_dce, end_dce, end_fast_dce, run_fast_df_dce): Removed
    marked_libcalls.

Index: df-problems.c
===================================================================
--- df-problems.c	(revision 120099)
+++ df-problems.c	(working copy)
@@ -687,11 +687,11 @@ df_ru_start_dump (FILE *file)
   if (!df_ru->block_info) 
     return;
 
-  fprintf (file, "Reaching uses:\n");
+  fprintf (file, ";; Reaching uses:\n");
 
-  fprintf (file, "  sparse invalidated \t");
+  fprintf (file, ";;   sparse invalidated \t");
   dump_bitmap (file, problem_data->sparse_invalidated_by_call);
-  fprintf (file, "  dense invalidated \t");
+  fprintf (file, " dense invalidated \t");
   dump_bitmap (file, problem_data->dense_invalidated_by_call);
   
   for (regno = 0; regno < m; regno++)
@@ -712,11 +712,11 @@ df_ru_top_dump (basic_block bb, FILE *fi
   if (!bb_info || !bb_info->in)
     return;
   
-  fprintf (file, "ru  in  \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
+  fprintf (file, ";; ru  in  \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
   dump_bitmap (file, bb_info->in);
-  fprintf (file, "ru  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
+  fprintf (file, ";; ru  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
   dump_bitmap (file, bb_info->gen);
-  fprintf (file, "ru  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
+  fprintf (file, ";; ru  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
   dump_bitmap (file, bb_info->kill);
 }  
 
@@ -730,7 +730,7 @@ df_ru_bottom_dump (basic_block bb, FILE 
   if (!bb_info || !bb_info->out)
     return;
   
-  fprintf (file, "ru  out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
+  fprintf (file, ";; ru  out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
   dump_bitmap (file, bb_info->out);
 }  
 
@@ -1228,7 +1228,7 @@ df_rd_start_dump (FILE *file)
   if (!df_rd->block_info) 
     return;
 
-  fprintf (file, "Reaching defs:\n\n");
+  fprintf (file, ";; Reaching defs:\n\n");
 
   fprintf (file, "  sparse invalidated \t");
   dump_bitmap (file, problem_data->sparse_invalidated_by_call);
@@ -1254,11 +1254,11 @@ df_rd_top_dump (basic_block bb, FILE *fi
   if (!bb_info || !bb_info->in)
     return;
   
-  fprintf (file, "rd  in  \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
+  fprintf (file, ";; rd  in  \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
   dump_bitmap (file, bb_info->in);
-  fprintf (file, "rd  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
+  fprintf (file, ";; rd  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
   dump_bitmap (file, bb_info->gen);
-  fprintf (file, "rd  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
+  fprintf (file, ";; rd  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
   dump_bitmap (file, bb_info->kill);
 }
 
@@ -1272,7 +1272,7 @@ df_rd_bottom_dump (basic_block bb, FILE 
   if (!bb_info || !bb_info->out)
     return;
   
-  fprintf (file, "rd  out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
+  fprintf (file, ";; rd  out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
   dump_bitmap (file, bb_info->out);
 }
 
@@ -1812,11 +1812,11 @@ df_lr_top_dump (basic_block bb, FILE *fi
   if (!bb_info || !bb_info->in)
     return;
       
-  fprintf (file, "lr  in  \t");
+  fprintf (file, ";; lr  in  \t");
   df_print_regset (file, bb_info->in);
-  fprintf (file, "lr  use \t");
+  fprintf (file, ";; lr  use \t");
   df_print_regset (file, bb_info->use);
-  fprintf (file, "lr  def \t");
+  fprintf (file, ";; lr  def \t");
   df_print_regset (file, bb_info->def);
 }  
 
@@ -1830,7 +1830,7 @@ df_lr_bottom_dump (basic_block bb, FILE 
   if (!bb_info || !bb_info->out)
     return;
   
-  fprintf (file, "lr  out \t");
+  fprintf (file, ";; lr  out \t");
   df_print_regset (file, bb_info->out);
 }  
 
@@ -2141,11 +2141,11 @@ df_ur_top_dump (basic_block bb, FILE *fi
   if (!bb_info || !bb_info->in)
     return;
       
-  fprintf (file, "ur  in  \t");
+  fprintf (file, ";; ur  in  \t");
   df_print_regset (file, bb_info->in);
-  fprintf (file, "ur  gen \t");
+  fprintf (file, ";; ur  gen \t");
   df_print_regset (file, bb_info->gen);
-  fprintf (file, "ur  kill\t");
+  fprintf (file, ";; ur  kill\t");
   df_print_regset (file, bb_info->kill);
 }
 
@@ -2159,7 +2159,7 @@ df_ur_bottom_dump (basic_block bb, FILE 
   if (!bb_info || !bb_info->out)
     return;
       
-  fprintf (file, "ur  out \t");
+  fprintf (file, ";; ur  out \t");
   df_print_regset (file, bb_info->out);
 }
 
@@ -2338,7 +2338,7 @@ df_live_top_dump (basic_block bb, FILE *
   if (!bb_info || !bb_info->in)
     return;
   
-  fprintf (file, "live  in  \t");
+  fprintf (file, ";; live  in  \t");
   df_print_regset (file, bb_info->in);
 }
 
@@ -2352,7 +2352,7 @@ df_live_bottom_dump (basic_block bb, FIL
   if (!bb_info || !bb_info->out)
     return;
   
-  fprintf (file, "live  out  \t");
+  fprintf (file, ";; live  out  \t");
   df_print_regset (file, bb_info->out);
 }
 
@@ -2949,13 +2949,13 @@ df_urec_top_dump (basic_block bb, FILE *
   if (!bb_info || !bb_info->in)
     return;
       
-  fprintf (file, "urec  in  \t");
+  fprintf (file, ";; urec  in  \t");
   df_print_regset (file, bb_info->in);
-  fprintf (file, "urec  gen \t");
+  fprintf (file, ";; urec  gen \t");
   df_print_regset (file, bb_info->gen);
-  fprintf (file, "urec  kill\t");
+  fprintf (file, ";; urec  kill\t");
   df_print_regset (file, bb_info->kill);
-  fprintf (file, "urec  ec\t");
+  fprintf (file, ";; urec  ec\t");
   df_print_regset (file, bb_info->earlyclobber);
 }
 
@@ -2968,7 +2968,7 @@ df_urec_bottom_dump (basic_block bb, FIL
   struct df_urec_bb_info *bb_info = df_urec_get_bb_info (bb->index);
   if (!bb_info || !bb_info->out)
     return;
-  fprintf (file, "urec  out \t");
+  fprintf (file, ";; urec  out \t");
   df_print_regset (file, bb_info->out);
 }
 
@@ -3334,13 +3334,13 @@ df_chain_start_dump (FILE *file)
 
   if (df_chain_problem_p (DF_DU_CHAIN))
     {
-      fprintf (file, "Def-use chains:\n");
+      fprintf (file, ";; Def-use chains:\n");
       for (j = 0; j < DF_DEFS_TABLE_SIZE (); j++)
 	{
 	  struct df_ref *def = DF_DEFS_GET (j);
 	  if (def)
 	    {
-	      fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
+	      fprintf (file, ";;   d%d bb %d luid %d insn %d reg %d ",
 		       j, DF_REF_BBNO (def),
 		       DF_REF_INSN (def) ? 
 		       DF_INSN_LUID (DF_REF_INSN (def)):
@@ -3357,13 +3357,13 @@ df_chain_start_dump (FILE *file)
 
   if (df_chain_problem_p (DF_UD_CHAIN))
     {
-      fprintf (file, "Use-def chains:\n");
+      fprintf (file, ";; Use-def chains:\n");
       for (j = 0; j < DF_USES_TABLE_SIZE (); j++)
 	{
 	  struct df_ref *use = DF_USES_GET (j);
 	  if (use)
 	    {
-	      fprintf (file, "u%d bb %d luid %d insn %d reg %d ",
+	      fprintf (file, ";;   u%d bb %d luid %d insn %d reg %d ",
 		       j, DF_REF_BBNO (use),
 		       DF_REF_INSN (use) ? 
 		       DF_INSN_LUID (DF_REF_INSN (use))
@@ -4127,7 +4127,7 @@ df_ri_start_dump (FILE *file)
 {
   if (df_ri_problem_p (DF_RI_LIFE))
     {
-      fprintf (file, "Register info:\n");
+      fprintf (file, ";; Register info:\n");
       dump_reg_info (file);
     }
 }
Index: dce.c
===================================================================
--- dce.c	(revision 120099)
+++ dce.c	(working copy)
@@ -54,7 +54,6 @@ static bool something_changed;
 static VEC(rtx,heap) *worklist;
 
 static bitmap marked = NULL;
-static bitmap marked_libcalls = NULL;
 
 /* Return true if INSN a normal instruction that can be deleted by the
    DCE pass.  */
@@ -165,31 +164,6 @@ mark_nonreg_stores (rtx body, rtx insn, 
 }
 
 
-/* Go through the instructions and mark those whose necessity is not
-   dependent on inter-instruction information.  Make sure all other
-   instructions are not marked.  */
-
-static void
-prescan_insns_for_dce (void)
-{
-  basic_block bb;
-  rtx insn;
-  
-  if (dump_file)
-    fprintf (dump_file, "Finding needed instructions:\n");
-  
-  FOR_EACH_BB (bb)
-    FOR_BB_INSNS (bb, insn)
-    if (INSN_P (insn))
-      {
-	if (deletable_insn_p (insn))
-	  mark_nonreg_stores (PATTERN (insn), insn, true);
-	else
-	  mark_insn (insn, true);
-      }
-}
-
-
 /* Initialize global variables for a new DCE pass.  */
 
 static void
@@ -206,7 +180,6 @@ init_dce (bool fast)
     df_dump (dump_file);
 
   marked = BITMAP_ALLOC (NULL);
-  marked_libcalls = BITMAP_ALLOC (NULL);
 }
 
 
@@ -269,18 +242,6 @@ delete_unmarked_insns (void)
 }
 
 
-/* Return true if INSN has libcall id ID.  */
-static bool
-libcall_matches_p (rtx insn, int id)
-{
-  rtx note;
-  if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
-    return id == INTVAL (XEXP (note, 0));
-  else 
-    return false;
-}
-
-
 /* Mark all insns using DELETE_PARM in the libcall that contains
    START_INSN.  */
 static void 
@@ -293,12 +254,24 @@ mark_libcall (rtx start_insn, bool delet
   mark_insn (start_insn, delete_parm);
   insn = NEXT_INSN (start_insn);
 
+  /* There are tales, long ago and far away, of the mystical nested
+     libcall.  No one alive has actually seen one, but other parts of
+     the compiler support them so we will here.  */
   for (insn = NEXT_INSN (start_insn); insn; insn = NEXT_INSN (insn))
     {
       if (INSN_P (insn))
 	{
-	  if (libcall_matches_p (insn, id))
-	    mark_insn (insn, delete_parm);
+	  /* Stay in the loop as long as we are in any libcall.  */
+	  if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
+	    {
+	      if (id == INTVAL (XEXP (note, 0)))
+		{
+		  mark_insn (insn, delete_parm);
+		  if (dump_file)
+		    fprintf (dump_file, "matching forward libcall %d[%d]\n",
+			     INSN_UID (insn), id);
+		}
+	    }
 	  else 
 	    break;
 	}
@@ -308,8 +281,17 @@ mark_libcall (rtx start_insn, bool delet
     {
       if (INSN_P (insn))
 	{
-	  if (libcall_matches_p (insn, id))
-	    mark_insn (insn, delete_parm);
+	  /* Stay in the loop as long as we are in any libcall.  */
+	  if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
+	    {
+	      if (id == INTVAL (XEXP (note, 0)))
+		{
+		  mark_insn (insn, delete_parm);
+		  if (dump_file)
+		    fprintf (dump_file, "matching backward libcall %d[%d]\n",
+			     INSN_UID (insn), id);
+		}
+	    }
 	  else 
 	    break;
 	}
@@ -317,13 +299,46 @@ mark_libcall (rtx start_insn, bool delet
 }
 
 
+/* Go through the instructions and mark those whose necessity is not
+   dependent on inter-instruction information.  Make sure all other
+   instructions are not marked.  */
+
+static void
+prescan_insns_for_dce (void)
+{
+  basic_block bb;
+  rtx insn;
+  
+  if (dump_file)
+    fprintf (dump_file, "Finding needed instructions:\n");
+  
+  FOR_EACH_BB (bb)
+    FOR_BB_INSNS (bb, insn)
+    if (INSN_P (insn))
+      {
+	if (deletable_insn_p (insn))
+	  mark_nonreg_stores (PATTERN (insn), insn, true);
+	else
+	  {
+	    rtx note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX);
+	    if (note)
+	      mark_libcall (insn, true);
+	    else
+	      mark_insn (insn, true);
+	  }
+      }
+
+  if (dump_file)
+    fprintf (dump_file, "Finished finding needed instructions:\n");
+}
+
+
 /* Free the data allocated by init_dce.  */
 
 static void
 end_dce (void)
 {
   BITMAP_FREE (marked);
-  BITMAP_FREE (marked_libcalls);
   df_in_progress = false;
 }
 
@@ -388,7 +403,6 @@ static void
 end_fast_dce (void)
 {
   BITMAP_FREE (marked);
-  BITMAP_FREE (marked_libcalls);
   df_in_progress = false;
 }
 
@@ -404,8 +418,6 @@ dce_process_block (basic_block bb, bool 
   bool block_changed;
   struct df_ref *def, *use;
   unsigned int bb_index = bb->index;
-  rtx libcall_start = NULL;
-  int libcall_id = -1;
 
   if (redo_out)
     {
@@ -441,29 +453,7 @@ dce_process_block (basic_block bb, bool 
 	if (!marked_insn_p (insn))
 	  {	
 	    bool needed = false;
-	    rtx note;
-	    if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX)))
-	      {
-		int new_id = INTVAL (XEXP (note, 0));
-		if (libcall_start)
-		  {
-		    if (libcall_id != new_id)
-		      {
-			libcall_start = insn;
-			libcall_id = new_id;
-		      }
-		  }
-		else
-		  {
-		    libcall_start = insn;
-		    libcall_id = new_id;
-		  }
-	      }
-	    else 
-	      {
-		libcall_start = NULL;
-		libcall_id = -1;
-	      }
+
 	    for (def = DF_INSN_DEFS (insn); 
 		 def; def = def->next_ref)
 	      if (bitmap_bit_p (local_live, DF_REF_REGNO (def)))
@@ -474,14 +464,18 @@ dce_process_block (basic_block bb, bool 
 	    
 	    if (needed)
 	      {
+		rtx note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX);
+
 		/* If we need to mark an insn in the middle of a
 		   libcall, we need to back up to mark the entire
 		   libcall.  Given that libcalls are rare, rescanning
 		   the block should be a reasonable solution to trying
 		   to figure out how to back up.  */
- 		if (libcall_start)
+		if (note)
 		  {
-		    mark_libcall (libcall_start, true);
+		    if (dump_file)
+		      fprintf (dump_file, "needed libcall %d\n", INSN_UID (insn));
+		    mark_libcall (insn, true);
 		    BITMAP_FREE (local_live);
 		    return dce_process_block (bb, false);
 		  }
@@ -654,7 +648,6 @@ run_fast_df_dce (void)
   init_dce (true);
   fast_dce ();
   BITMAP_FREE (marked);
-  BITMAP_FREE (marked_libcalls);
   df_in_progress = false;
 }
 
@@ -1619,7 +1612,13 @@ prescan_insns_for_dse (void)
 	  if (INSN_P (insn))
 	    {
 	      if (!deletable_insn_p (insn))
-		mark_insn (insn, false);
+		{
+		  rtx note = find_reg_note (insn, REG_LIBCALL_ID, NULL_RTX);
+		  if (note)
+		    mark_libcall (insn, false);
+		  else
+		    mark_insn (insn, false);
+		}
 	      else
 		record_stores (insn);
 	    }

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