[tree-ssa] Live range patch

Andrew MacLeod amacleod@redhat.com
Sat Sep 13 02:07:00 GMT 2003



The following patch switches the SSA->normal coalescer to use the
default_def fields instead of trying to calculate what needs to be
coalesced for live-on-entry variables. Jason had a program which
demonstrated a deficiency in the old way.  This was in the pending list
anyway, so its time to do it.

I also added a bunch of new checking code in the live on entry
calculator to verify the calulations with the default_def information.
The messsages are clearer and have more detail, and there is a wider
variety of them now.  Maybe we'll catch something :-)

The recent bugs in PRE relating to extending live ranges across abnormal
PHI's pointed out the need for a little more detail to help narrow down
where the problem actually occurs. We now indicate which abnormal edge
the problem occurs across. That really helps with large programs.

This has all been bootstrapped on x86 and causes no new regressions.

I'll be checking it in momentarily.

Andrew



	* tree-ssa-live.c (calculate_live_on_entry): Use default_def to add 
	addition checks to live on entry calculations.
	* tree-ssa.c (print_exprs_edge): New debug output function.
	(coalesce_abnormal_edges): Add basic block information to output.
	(coalesce_ssa_name): Use default_def instead of trying to compute live
	on entry variables.

Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.17
diff -c -p -r1.1.2.17 tree-ssa-live.c
*** tree-ssa-live.c	10 Sep 2003 13:24:36 -0000	1.1.2.17
--- tree-ssa-live.c	12 Sep 2003 16:34:15 -0000
*************** calculate_live_on_entry (var_map map)
*** 634,650 ****
     /* Check for live on entry partitions and report those with a DEF in
        the program. This will typically mean an optimization has done
        something wrong.  */
!   for (num=0, i = 0; i < num_var_partitions (map); i++)
      {
!       if (TEST_BIT (live_entry_blocks (live, i), 0))
!         {
  	  var = partition_to_var (map, i);
! 	  if (!IS_EMPTY_STMT (SSA_NAME_DEF_STMT (var)))
  	    {
! 	      num++;
! 	      print_generic_expr (stderr, var, TDF_SLIM);
! 	      fprintf (stderr, " is defined, but is also live on entry.\n");
  	    }
  	}
      }
    if (num > 0)
--- 634,713 ----
     /* Check for live on entry partitions and report those with a DEF in
        the program. This will typically mean an optimization has done
        something wrong.  */
! 
!   bb = ENTRY_BLOCK_PTR;
!   for (e = bb->succ; e; e = e->succ_next)
      {
!       int entry_block = e->dest->index;
!       if (e->dest == EXIT_BLOCK_PTR)
!         continue;
!       for (num = 0, i = 0; i < num_var_partitions (map); i++)
! 	{
! 	  basic_block tmp;
! 	  tree d;
  	  var = partition_to_var (map, i);
! 	  stmt = SSA_NAME_DEF_STMT (var);
! 	  tmp = bb_for_stmt (stmt);
! 	  d = default_def (SSA_NAME_VAR (var));
! 
! 	  if (TEST_BIT (live_entry_blocks (live, i), entry_block))
  	    {
! 	      if (!IS_EMPTY_STMT (stmt))
! 		{
! 		  num++;
! 		  print_generic_expr (stderr, var, TDF_SLIM);
! 		  fprintf (stderr, " is defined ");
! 		  if (tmp)
! 		    fprintf (stderr, " in BB%d, ", tmp->index);
! 		  fprintf (stderr, "by:\n");
! 		  print_generic_expr (stderr, stmt, TDF_SLIM);
! 		  fprintf (stderr, "\nIt is also live-on-entry to entry BB %d", 
! 			   entry_block);
! 		  fprintf (stderr, " So it appears to have multiple defs.\n");
! 		}
! 	      else
! 	        {
! 		  if (d != var)
! 		    {
! 		      num++;
! 		      print_generic_expr (stderr, var, TDF_SLIM);
! 		      fprintf (stderr, " is live-on-entry to BB%d ",entry_block);
! 		      if (d)
! 		        {
! 			  fprintf (stderr, " but is not the default def of ");
! 			  print_generic_expr (stderr, d, TDF_SLIM);
! 			  fprintf (stderr, "\n");
! 			}
! 		      else
! 			fprintf (stderr, " and there is no default def.\n");
! 		    }
! 		}
  	    }
+ 	  else
+ 	    if (d == var)
+ 	      {
+ 		/* The only way this var shouldn't be marked live on entry to 
+ 		   this block is if it occurs in a PHI argument of the block.  */
+ 		int z, ok = 0;
+ 		for (phi = phi_nodes (e->dest); 
+ 		     phi && !ok; 
+ 		     phi = TREE_CHAIN (phi))
+ 		  {
+ 		    for (z = 0; z < PHI_NUM_ARGS (phi); z++)
+ 		      if (var == PHI_ARG_DEF (phi, z))
+ 			{
+ 			  ok = 1;
+ 			  break;
+ 			}
+ 		  }
+ 		if (ok)
+ 		  continue;
+ 	        num++;
+ 		print_generic_expr (stderr, var, TDF_SLIM);
+ 		fprintf (stderr, " is not marked live-on-entry to entry BB%d ", 
+ 			 entry_block);
+ 		fprintf (stderr, "but it is the default def so it should be.\n");
+ 	      }
  	}
      }
    if (num > 0)
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.124
diff -c -p -r1.1.4.124 tree-ssa.c
*** tree-ssa.c	6 Sep 2003 13:39:25 -0000	1.1.4.124
--- tree-ssa.c	12 Sep 2003 16:34:16 -0000
*************** static void eliminate_extraneous_phis (v
*** 184,189 ****
--- 184,191 ----
  static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
  static void print_exprs (FILE *, const char *, tree, const char *, tree,
  			 const char *);
+ static void print_exprs_edge (FILE *, edge, const char *, tree, const char *, 
+ 			      tree);
  
  /* Main entry point to the SSA builder.  FNDECL is the gimplified function
     to convert.  VARS is an sbitmap representing variables that need to be
*************** print_exprs (FILE *f, const char *str1, 
*** 1208,1213 ****
--- 1210,1223 ----
    fprintf (f, "%s", str3);
  }
  
+ static void
+ print_exprs_edge (FILE *f, edge e, const char *str1, tree expr1, 
+ 		  const char *str2, tree expr2)
+ {
+   print_exprs (f, str1, expr1, str2, expr2, " across an abnormal edge");
+   fprintf (f, " from BB%d->BB%d\n", e->src->index,
+ 	       e->dest->index);
+ }
  
  /* Coalesce partitions which are live across abnormal edges. Since code 
     cannot be inserted on these edges, failure to coalesce something across
*************** coalesce_abnormal_edges (var_map map, co
*** 1243,1251 ****
  	    tmp = PHI_ARG_DEF (phi, y);
  	    if (TREE_CONSTANT (tmp))
  	      {
! 	        print_exprs (stderr,
! 			     "\nConstant argument in PHI. Can't insert :",
! 			     var, " = ", tmp, "' across an abnormal edge\n");
  		abort ();
  	      }
  	    y = var_to_partition (map, tmp);
--- 1253,1261 ----
  	    tmp = PHI_ARG_DEF (phi, y);
  	    if (TREE_CONSTANT (tmp))
  	      {
! 	        print_exprs_edge (stderr, e,
! 				  "\nConstant argument in PHI. Can't insert :",
! 				  var, " = ", tmp);
  		abort ();
  	      }
  	    y = var_to_partition (map, tmp);
*************** coalesce_abnormal_edges (var_map map, co
*** 1253,1262 ****
  	      abort ();
  	    if (root_var_find (rv, x) != root_var_find (rv, y))
  	      {
! 		print_exprs (stderr, "\nDifferent root vars '\n",
! 			     root_var (rv, root_var_find (rv, x)), "' and '",
! 			     root_var (rv, root_var_find (rv, y)),
! 			     "' across an abnormal edge\n");
  		abort ();
  	      }
  
--- 1263,1271 ----
  	      abort ();
  	    if (root_var_find (rv, x) != root_var_find (rv, y))
  	      {
! 		print_exprs_edge (stderr, e, "\nDifferent root vars: ",
! 				  root_var (rv, root_var_find (rv, x)), 
! 				  " and ", root_var (rv, root_var_find (rv, y)));
  		abort ();
  	      }
  
*************** coalesce_abnormal_edges (var_map map, co
*** 1270,1293 ****
  		    if (dump_file 
  			&& (dump_flags & TDF_DETAILS))
  		      {
! 			print_exprs (dump_file, "ABNORMAL: Coalescing ", var,
! 				     " and ", tmp, " over abnormal edge.\n");
  		      }
  		    if (var_union (map, var, tmp) == NO_PARTITION)
  		      {
! 			print_exprs (stderr, "\nUnable to coalesce", 
! 				     partition_to_var (map, x), " and ", 
! 				     partition_to_var (map, y),
! 				     " across an abnormal edge\n");
  			abort ();
  		      }
  		    conflict_graph_merge_regs (graph, x, y);
  		  }
  		else
  		  {
! 		    print_exprs (stderr, "\n", partition_to_var (map, x),
! 				 " and ", partition_to_var (map, y),
! 				 " conflict across an abnormal edge\n");
  		    abort ();
  		  }
  	      }
--- 1279,1301 ----
  		    if (dump_file 
  			&& (dump_flags & TDF_DETAILS))
  		      {
! 			print_exprs_edge (dump_file, e, "ABNORMAL: Coalescing ",
! 					  var, " and ", tmp);
  		      }
  		    if (var_union (map, var, tmp) == NO_PARTITION)
  		      {
! 			print_exprs_edge (stderr, e, "\nUnable to coalesce", 
! 					  partition_to_var (map, x), " and ", 
! 					  partition_to_var (map, y));
  			abort ();
  		      }
  		    conflict_graph_merge_regs (graph, x, y);
  		  }
  		else
  		  {
! 		    print_exprs_edge (stderr, e, "\n Conflict ", 
! 				      partition_to_var (map, x),
! 				      " and ", partition_to_var (map, y));
  		    abort ();
  		  }
  	      }
*************** coalesce_ssa_name (var_map map)
*** 1310,1316 ****
    tree var;
    root_var_p rv;
    tree_live_info_p liveinfo;
-   edge e;
    var_ann_t ann;
    conflict_graph graph;
  
--- 1318,1323 ----
*************** coalesce_ssa_name (var_map map)
*** 1340,1351 ****
  
    num = num_var_partitions (map);
    for (x = 0 ; x < num; x++)
!     for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
!       if (e->dest != EXIT_BLOCK_PTR)
! 	{
! 	  if (TEST_BIT (live_entry_blocks (liveinfo, x), e->dest->index))
! 	    SET_BIT (live, x);
! 	}
  
    if (!flag_tree_combine_temps)
      {
--- 1347,1357 ----
  
    num = num_var_partitions (map);
    for (x = 0 ; x < num; x++)
!     {
!       var = partition_to_var (map, x);
!       if (default_def (SSA_NAME_VAR (var)) == var)
! 	SET_BIT (live, x);
!     }
  
    if (!flag_tree_combine_temps)
      {



More information about the Gcc-patches mailing list