[tree-ssa] various improvements.

Andrew MacLeod amacleod@redhat.com
Tue Jul 22 18:29:00 GMT 2003


This patch does a few things.

First, it removes the SSA_NAME_HAS_REAL_REF flags. Out of SSA does not
need it, and since it was put in under the false impression that it did,
it should be removed.  It is undesirable that any optimization which
creates a new variable has to set the REF flag properly or the out of
SSA pass might ignore it.  This can be a very difficult bug to detect. 
Removing this also uncovered a couple of latent bugs :-)

Second, there are modification which should allow SSA->normal to handle
constants which have been propagated into PHI nodes. When there is a
constant, we always issue a copy on the incoming edge.

Third, there is a patch from Diego for CCP which was required to get CCP
working properly when I removed the SSA_NAME_HAS_REAL_REF flag.

Fourth, there are some listing issues when we have conditionals for call
names. 
  x = (test ? func1 : func2) (parm);
aborts during generic output, and prints gobbledygook for the SSA
listing. This straightens them out.  

fifth, supply a missing output dump for tree live range infomation.

Sixth, the PHI node copy insertion routine was making assumptions that
the same argument index on all PHI nodes refered to the same edge.
Typically it does, but its not a guaranteed thing. Changes are in place
to verify that the edge is the correct one, and if it isn't, to get the
right value.

This bootstraps on x86, and produces no new errors. Time tests indicate
pretty much no difference in compile times.

Andrew


2003-07-22  Diego Novillo  <dnovillo@redhat.com>

	* tree-ssa-ccp.c (visit_phi_node): Assume default value of CONSTANT 
	if the PHI value was already constant.

2003-07-22  Andrew MacLeod  <amacleod@redhat.com>

	* c-pretty-print.c (print_call_name): Handle COND_EXPR correctly.
	* tree-pretty-print.c (print_call_name): Handle COND_EXPR correctly and
	handle SSA_NAME.
	* tree-dfa.c (add_phi_arg, remove_phi_arg_num): Remove references to 
	SSA_NAME_HAS_REAL_REFS.
	* tree-ssa-ccp.c (visit_phi_node): Remove SSA_NAME_HAS_REAL_REFS.
	* tree-ssa-copyprop.c (copyprop_phi): Remove SSA_NAME_HAS_REAL_REFS.
	* tree-ssa-live.c (register_ssa_partition): Register the PHI and it's 
	arguments if this variable is defined by a PHI.
	(create_ssa_var_map): Only register real uses and defs, and virtual
	operands of ASM_EXPR's. Remove SSA_NAME_HAS_REAL_REFS. Don't set 
	used flag on variables here.
	(calculate_live_on_entry): Ignore constants in PHI arguments.
	(calculate_live_on_exit): Ignore constants in PHI arguments.
	(dump_live_info): New. Dump live range information.
	* tree-ssa-live.h (dump_live_info): New prototype and flags.
	* tree-ssa-pre.c (create_expr_ref, finalize_1, repair_use_injury, 
	code_motion): Remove SSA_NAME_HAS_REAL_REFS.
	* tree-ssa.c (rewrite_operand, register_new_def): Remove real_ref 
	parameter and SSA_NAME_HAS_REAL_REFS.
	(rewrite_block): Remove real_ref parameter from register_new_def call.
	(eliminate_build): Remove SSA_NAME_HAS_REAL_REFS. Insert copy if PHI
	argument is a constant. Handle irregular PHI argument ordering.
	(elim_create): Remove dead code to count PHI nodes.
	(assign_vars): Set used flag on variables when assigned.
	(replace_variable): Eliminate dead code.
	(coalesce_ssa_name): Remove SSA_NAME_HAS_REAL_REFS. Print error for
	constant argument across an abnormal edge.
	(eliminate_extraneous_phis): New. Remove PHI nodes which are not in
	the partition.
	(rewrite_out_of_ssa): Call eliminate_extraneous_phis. 
	(rewrite_stmt): Remove real_ref parameter from rewrite_operand and 
	register_new_def.
	* tree.h (SSA_NAME_HAS_REAL_REFS): Remove.
	(struct tree_ssa_name): Remove 'has_real_refs' field.





Index: c-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pretty-print.c,v
retrieving revision 1.1.4.27
diff -c -p -r1.1.4.27 c-pretty-print.c
*** c-pretty-print.c	3 Jun 2003 16:50:31 -0000	1.1.4.27
--- c-pretty-print.c	22 Jul 2003 15:03:12 -0000
*************** print_call_name (buffer, node)
*** 1916,1923 ****
        break;
      
      case COND_EXPR:
!       PRINT_FUNCTION_NAME (TREE_OPERAND (TREE_OPERAND (op0, 0), 1));
!       PRINT_FUNCTION_NAME (TREE_OPERAND (TREE_OPERAND (op0, 0), 2));
        break;
        
      case COMPONENT_REF:
--- 1916,1927 ----
        break;
      
      case COND_EXPR:
!       output_add_string (buffer, "(");
!       dump_c_node (buffer, TREE_OPERAND (op0, 0), 0, 0);
!       output_add_string (buffer, ") ? ");
!       dump_c_node (buffer, TREE_OPERAND (op0, 1), 0, 0);
!       output_add_string (buffer, " : ");
!       dump_c_node (buffer, TREE_OPERAND (op0, 2), 0, 0);
        break;
        
      case COMPONENT_REF:
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.133
diff -c -p -r1.1.4.133 tree-dfa.c
*** tree-dfa.c	22 Jul 2003 02:52:05 -0000	1.1.4.133
--- tree-dfa.c	22 Jul 2003 15:03:14 -0000
*************** add_phi_arg (tree phi, tree def, edge e)
*** 889,898 ****
    PHI_ARG_DEF (phi, i) = def;
    PHI_ARG_EDGE (phi, i) = e;
    PHI_NUM_ARGS (phi)++;
- 
-   /* Propagate HAS_REAL_REFS to the result of the PHI node.  */
-   if (SSA_NAME_HAS_REAL_REFS (def))
-     SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi)) = true;
  }
  
  
--- 889,894 ----
*************** void
*** 941,952 ****
  remove_phi_arg_num (tree phi, int i)
  {
    int num_elem = PHI_NUM_ARGS (phi);
-   bool last_real_arg_p;
- 
-   /* If argument ARG was the last argument used as a real operand, we will
-      want to update PHI_RESULT so that it is not considered by the
-      coalescer in the SSA->normal pass.  */
-   last_real_arg_p = SSA_NAME_HAS_REAL_REFS (PHI_ARG_DEF (phi, i));
  
    /* If we are not at the last element, switch the last element
       with the element we want to delete.  */
--- 937,942 ----
*************** remove_phi_arg_num (tree phi, int i)
*** 960,977 ****
    PHI_ARG_DEF (phi, num_elem - 1) = NULL_TREE;
    PHI_ARG_EDGE (phi, num_elem - 1) = NULL;
    PHI_NUM_ARGS (phi)--;
- 
-   /* Update SSA_NAME_HAS_REAL_REFS for the LHS of the PHI, if needed.  */
-   if (last_real_arg_p)
-     {
-       for (i = 0; i < num_elem - 1; i++)
- 	if (SSA_NAME_HAS_REAL_REFS (PHI_ARG_DEF (phi, i)))
- 	  return;
- 
-       /* There are no arguments left with real references, update the LHS of
- 	the PHI.  */
-       SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi)) = false;
-     }
  }
  
  
--- 950,955 ----
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-pretty-print.c,v
retrieving revision 1.1.2.32
diff -c -p -r1.1.2.32 tree-pretty-print.c
*** tree-pretty-print.c	15 Jul 2003 05:53:16 -0000	1.1.2.32
--- tree-pretty-print.c	22 Jul 2003 15:03:14 -0000
*************** print_call_name (output_buffer *buffer, 
*** 1773,1780 ****
        break;
  
      case COND_EXPR:
!       PRINT_FUNCTION_NAME (TREE_OPERAND (TREE_OPERAND (op0, 0), 1));
!       PRINT_FUNCTION_NAME (TREE_OPERAND (TREE_OPERAND (op0, 0), 2));
        break;
  
      case COMPONENT_REF:
--- 1773,1784 ----
        break;
  
      case COND_EXPR:
!       output_add_string (buffer, "(");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0);
!       output_add_string (buffer, ") ? ");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, 0);
!       output_add_string (buffer, " : ");
!       dump_generic_node (buffer, TREE_OPERAND (op0, 2), 0, 0);
        break;
  
      case COMPONENT_REF:
*************** print_call_name (output_buffer *buffer, 
*** 1795,1800 ****
--- 1799,1808 ----
  	PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
        else
  	PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 1));
+       break;
+ 
+     case SSA_NAME:
+       dump_generic_node (buffer, op0, 0, 0);
        break;
  
      default:
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.78
diff -c -p -r1.1.2.78 tree-ssa-ccp.c
*** tree-ssa-ccp.c	22 Jul 2003 02:50:15 -0000	1.1.2.78
--- tree-ssa-ccp.c	22 Jul 2003 15:03:15 -0000
*************** static void
*** 351,357 ****
  visit_phi_node (tree phi)
  {
    int i;
!   value phi_val;
  
    /* If the PHI node has already been deemed to be VARYING, don't simulate
       it again.  */
--- 351,357 ----
  visit_phi_node (tree phi)
  {
    int i;
!   value phi_val, *curr_val;
  
    /* If the PHI node has already been deemed to be VARYING, don't simulate
       it again.  */
*************** visit_phi_node (tree phi)
*** 364,376 ****
        print_generic_expr (dump_file, phi, 0);
      }
  
!   phi_val.lattice_val = UNDEFINED;
!   phi_val.const_val = NULL_TREE;
  
    /* If the variable is volatile or the variable is never referenced in a
       real operand, then consider the PHI node VARYING.  */
!   if (TREE_THIS_VOLATILE (SSA_NAME_VAR (PHI_RESULT (phi)))
!       || !SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi)))
      phi_val.lattice_val = VARYING;
    else
      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
--- 364,384 ----
        print_generic_expr (dump_file, phi, 0);
      }
  
!   curr_val = get_value (PHI_RESULT (phi));
!   if (curr_val->lattice_val != CONSTANT)
!     {
!       phi_val.lattice_val = UNDEFINED;
!       phi_val.const_val = NULL_TREE;
!     }
!   else
!     {
!       phi_val.lattice_val = curr_val->lattice_val;
!       phi_val.const_val = curr_val->const_val;
!     }
  
    /* If the variable is volatile or the variable is never referenced in a
       real operand, then consider the PHI node VARYING.  */
!   if (TREE_THIS_VOLATILE (SSA_NAME_VAR (PHI_RESULT (phi))))
      phi_val.lattice_val = VARYING;
    else
      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
Index: tree-ssa-copyprop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-copyprop.c,v
retrieving revision 1.1.2.7
diff -c -p -r1.1.2.7 tree-ssa-copyprop.c
*** tree-ssa-copyprop.c	22 Jul 2003 02:50:15 -0000	1.1.2.7
--- tree-ssa-copyprop.c	22 Jul 2003 15:03:15 -0000
*************** copyprop_phi (tree phi)
*** 168,176 ****
  	    }
  
  	  PHI_ARG_DEF (phi, i) = orig;
- 
- 	  if (SSA_NAME_HAS_REAL_REFS (orig))
- 	    SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi)) = 1;
  	}
      }
  }
--- 168,173 ----
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.11
diff -c -p -r1.1.2.11 tree-ssa-live.c
*** tree-ssa-live.c	22 Jul 2003 02:50:15 -0000	1.1.2.11
--- tree-ssa-live.c	22 Jul 2003 15:03:15 -0000
*************** delete_var_map (var_map map)
*** 101,109 ****
  static inline void
  register_ssa_partition (var_map map, tree ssa_var)
  {
    if (TREE_CODE (ssa_var) != SSA_NAME)
      abort ();
!   map->partition_to_var[SSA_NAME_VERSION (ssa_var)] = ssa_var;
  }
  
  /* This function will combine 2 partitions.  */
--- 101,129 ----
  static inline void
  register_ssa_partition (var_map map, tree ssa_var)
  {
+   tree stmt, arg;
+   int version, i;
+ 
+ #if defined ENABLE_CHECKING
    if (TREE_CODE (ssa_var) != SSA_NAME)
      abort ();
! #endif
! 
!   version = SSA_NAME_VERSION (ssa_var);
!   if (map->partition_to_var[version] == NULL_TREE)
!     {
!       map->partition_to_var[SSA_NAME_VERSION (ssa_var)] = ssa_var;
! 
!       /* If this is a PHI node, register all the PHI elements as well.  */
!       stmt = SSA_NAME_DEF_STMT (ssa_var);
!       if (stmt && TREE_CODE (stmt) == PHI_NODE)
! 	for (i = 0; i < PHI_NUM_ARGS (stmt); i++)
! 	  {
! 	    arg = PHI_ARG_DEF (stmt, i);
! 	    if (!TREE_CONSTANT (arg))
! 	      register_ssa_partition (map, arg);
! 	  }
!     }
  }
  
  /* This function will combine 2 partitions.  */
*************** create_ssa_var_map (void)
*** 286,295 ****
    block_stmt_iterator bsi;
    basic_block bb;
    tree *dest, *use;
!   tree stmt, phi;
    varray_type ops;
    unsigned x;
-   int i;
    var_map map;
  
    map = init_var_map (next_ssa_version + 1);
--- 306,314 ----
    block_stmt_iterator bsi;
    basic_block bb;
    tree *dest, *use;
!   tree stmt;
    varray_type ops;
    unsigned x;
    var_map map;
  
    map = init_var_map (next_ssa_version + 1);
*************** create_ssa_var_map (void)
*** 307,313 ****
  	    {
  	      use = VARRAY_GENERIC_PTR (ops, x);
  	      register_ssa_partition (map, *use);
- 	      set_is_used (*use);
  	    }
  
  	  ops = def_ops (stmt);
--- 326,331 ----
*************** create_ssa_var_map (void)
*** 315,321 ****
  	    {
  	      dest = VARRAY_GENERIC_PTR (ops, x);
  	      register_ssa_partition (map, *dest);
- 	      set_is_used (*dest);
  	    }
  
  	  /* While we do not care about virtual operands for
--- 333,338 ----
*************** create_ssa_var_map (void)
*** 329,355 ****
  	  for (x = 0; ops && x < VARRAY_ACTIVE_SIZE (ops); x++)
  	    set_is_used (VDEF_OP (VARRAY_TREE (ops, x)));
  	}
- 
-       /* Now register elements of PHI nodes.  */
-       for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
-         {
- 	  /* Only register PHI node variables that have had real uses in
- 	     the program.  */
- 	  if (SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi)))
- 	    {
- 	      register_ssa_partition (map, PHI_RESULT (phi));
- 	      set_is_used (PHI_RESULT (phi));
- 
- 	      /* Similarly, only register PHI arguments that have had real uses
- 		in the program.  */
- 	      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
- 		if (SSA_NAME_HAS_REAL_REFS (PHI_ARG_DEF (phi, i)))
- 		  {
- 		    register_ssa_partition (map, PHI_ARG_DEF (phi, i));
- 		    set_is_used (PHI_ARG_DEF (phi, i));
- 		  }
- 	    }
- 	}
      }
  
    return map;
--- 346,351 ----
*************** calculate_live_on_entry (var_map map)
*** 493,498 ****
--- 489,496 ----
  	  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
  	    {
  	      var = PHI_ARG_DEF (phi, i);
+ 	      if (TREE_CONSTANT (var))
+ 	        continue;
  	      stmt = SSA_NAME_DEF_STMT (var);
  	      e = PHI_ARG_EDGE (phi, i);
  	      /* Any uses in PHIs which either don't have def's or are not
*************** calculate_live_on_exit (tree_live_info_p
*** 620,626 ****
  	    { 
  	      t = PHI_ARG_DEF (phi, i);
  	      e = PHI_ARG_EDGE (phi, i);
! 	      if (e->src == ENTRY_BLOCK_PTR)
  	        continue;
  	      set_if_valid (map, on_exit[e->src->index], t);
  	    }
--- 618,624 ----
  	    { 
  	      t = PHI_ARG_DEF (phi, i);
  	      e = PHI_ARG_EDGE (phi, i);
! 	      if (TREE_CONSTANT (t) || e->src == ENTRY_BLOCK_PTR)
  	        continue;
  	      set_if_valid (map, on_exit[e->src->index], t);
  	    }
*************** dump_var_map (FILE *f, var_map map)
*** 812,814 ****
--- 810,854 ----
      }
    fprintf (f, "\n");
  }
+ 
+ /* Output live range info.  */
+ 
+ void
+ dump_live_info (FILE *f, tree_live_info_p live, int flag)
+ {
+   basic_block bb;
+   int i;
+   var_map map = live->map;
+ 
+   if ((flag & LIVEDUMP_ENTRY) && live->livein)
+     {
+       FOR_EACH_BB (bb)
+ 	{
+ 	  fprintf (f, "\nLive on entry to BB%d : ", bb->index);
+ 	  for (i = 0; i < num_var_partitions (map); i++)
+ 	    {
+ 	      if (TEST_BIT (live_entry_blocks (live, i), bb->index))
+ 	        {
+ 		  print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
+ 		  fprintf (f, "  ");
+ 		}
+ 	    }
+ 	  fprintf (f, "\n");
+ 	}
+     }
+ 
+   if ((flag & LIVEDUMP_EXIT) && live->liveout)
+     {
+       FOR_EACH_BB (bb)
+ 	{
+ 	  fprintf (f, "\nLive on exit from BB%d : ", bb->index);
+ 	  EXECUTE_IF_SET_IN_SBITMAP (live->liveout[bb->index], 0, i,
+ 	    {
+ 	      print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
+ 	      fprintf (f, "  ");
+ 	    });
+ 	  fprintf (f, "\n");
+ 	}
+     }
+ }
+ 
Index: tree-ssa-live.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.h,v
retrieving revision 1.1.2.5
diff -c -p -r1.1.2.5 tree-ssa-live.h
*** tree-ssa-live.h	11 Jun 2003 12:41:21 -0000	1.1.2.5
--- tree-ssa-live.h	22 Jul 2003 15:03:15 -0000
*************** extern tree_live_info_p calculate_live_o
*** 180,185 ****
--- 180,190 ----
  extern void calculate_live_on_exit (tree_live_info_p);
  extern void delete_tree_live_info (tree_live_info_p);
  
+ #define LIVEDUMP_ENTRY	0x01
+ #define LIVEDUMP_EXIT	0x02
+ #define LIVEDUMP_ALL	(LIVEDUMP_ENTRY | LIVEDUMP_EXIT)
+ extern void dump_live_info (FILE *, tree_live_info_p, int);
+ 
  
  static inline int partition_is_global (tree_live_info_p, int);
  static inline sbitmap live_entry_blocks (tree_live_info_p, int);
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.65
diff -c -p -r1.1.4.65 tree-ssa-pre.c
*** tree-ssa-pre.c	22 Jul 2003 05:11:48 -0000	1.1.4.65
--- tree-ssa-pre.c	22 Jul 2003 15:03:16 -0000
*************** create_expr_ref (struct expr_info *ei, t
*** 519,525 ****
  	len++;
  
        EREF_TEMP (ret) = make_phi_node (ei->temp, len);
-       SSA_NAME_HAS_REAL_REFS (PHI_RESULT (EREF_TEMP (ret))) = true;
      }
    else
      ret = make_node (type);
--- 519,524 ----
*************** finalize_1 (struct expr_info *ei)
*** 2024,2030 ****
  		  EREF_STMT (x) = NULL;
  		  expr = *EREF_STMT (tempx);		  
  		  newtemp = make_ssa_name (temp, expr);
- 		  SSA_NAME_HAS_REAL_REFS (newtemp) = true;
  		  TREE_OPERAND (expr, 0) = newtemp;
  		  copy = TREE_OPERAND (expr, 1);
  		  EREF_TEMP (x) = newtemp;
--- 2023,2028 ----
*************** repair_use_injury (struct expr_info *ei,
*** 2517,2523 ****
  	  continue;
        expr = build (MODIFY_EXPR, TREE_TYPE (temp), temp, expr);
        newtemp = make_ssa_name (temp, expr);
-       SSA_NAME_HAS_REAL_REFS (newtemp) = true;
        modify_stmt (expr);
        TREE_OPERAND (expr, 0) = newtemp;
        set_bb_for_stmt (expr, bb_for_stmt (injury));
--- 2515,2520 ----
*************** code_motion (struct expr_info *ei)
*** 2683,2689 ****
  	  walk_tree (&copy, copy_tree_r, NULL, NULL);
  	  newexpr = build (MODIFY_EXPR, TREE_TYPE (temp), temp, copy);
  	  newtemp = make_ssa_name (temp, newexpr);
- 	  SSA_NAME_HAS_REAL_REFS (newtemp) = true;
  	  EREF_TEMP (use) = newtemp;
  	  TREE_OPERAND (newexpr, 0) = newtemp;
  	  TREE_OPERAND (*use_stmt_p, 1) = newtemp;
--- 2680,2685 ----
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.107
diff -c -p -r1.1.4.107 tree-ssa.c
*** tree-ssa.c	22 Jul 2003 02:50:15 -0000	1.1.4.107
--- tree-ssa.c	22 Jul 2003 15:03:17 -0000
*************** static void insert_phis_for_deferred_var
*** 148,155 ****
  static void rewrite_block (basic_block);
  static void check_for_new_variables (void);
  static void rewrite_stmt (block_stmt_iterator, varray_type *);
! static inline void rewrite_operand (tree *, bool);
! static void register_new_def (tree, tree, varray_type *, bool);
  static void insert_phi_nodes_for (tree, bitmap *, varray_type);
  static tree remove_annotations_r (tree *, int *, void *);
  static tree get_reaching_def (tree);
--- 148,155 ----
  static void rewrite_block (basic_block);
  static void check_for_new_variables (void);
  static void rewrite_stmt (block_stmt_iterator, varray_type *);
! static inline void rewrite_operand (tree *);
! static void register_new_def (tree, tree, varray_type *);
  static void insert_phi_nodes_for (tree, bitmap *, varray_type);
  static tree remove_annotations_r (tree *, int *, void *);
  static tree get_reaching_def (tree);
*************** static inline void set_if_valid (var_map
*** 182,187 ****
--- 182,188 ----
  static inline void add_conflicts_if_valid (root_var_p, conflict_graph,
  					   var_map, sbitmap, tree);
  static void replace_variable (var_map, tree *);
+ static void eliminate_extraneous_phis (var_map);
  
  /* Main entry point to the SSA builder.  FNDECL is the gimplified function
     to convert.  VARS is an sbitmap representing variables that need to be
*************** rewrite_block (basic_block bb)
*** 777,783 ****
       node introduces a new version for the associated variable.  */
    for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
      register_new_def (SSA_NAME_VAR (PHI_RESULT (phi)), PHI_RESULT (phi),
! 		      &block_defs, false);
  
    /* Step 2.  Rewrite every variable used in each statement the block with
       its immediate reaching definitions.  Update the current definition of
--- 778,784 ----
       node introduces a new version for the associated variable.  */
    for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
      register_new_def (SSA_NAME_VAR (PHI_RESULT (phi)), PHI_RESULT (phi),
! 		      &block_defs);
  
    /* Step 2.  Rewrite every variable used in each statement the block with
       its immediate reaching definitions.  Update the current definition of
*************** eliminate_build (elim_graph g, basic_blo
*** 985,1005 ****
    
    for (phi = phi_nodes (B); phi; phi = TREE_CHAIN (phi))
      {
-       if (!SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi))
- 	  || !SSA_NAME_HAS_REAL_REFS (PHI_ARG_DEF (phi, i)))
- 	continue;
- 
        T0 = var_to_partition_to_var (g->map, PHI_RESULT (phi));
!       Ti = var_to_partition_to_var (g->map, PHI_ARG_DEF (phi, i));
!       if (T0 != Ti)
          {
! 	  eliminate_name (g, T0);
! 	  eliminate_name (g, Ti);
! 	  p0 = var_to_partition (g->map, T0);
! 	  pi = var_to_partition (g->map, Ti);
! 	  bitmap_set_bit (g->pred[pi], p0);
! 	  bitmap_set_bit (g->succ[p0], pi);
! 	  edges++;
  	}
      }
    return edges;
--- 986,1019 ----
    
    for (phi = phi_nodes (B); phi; phi = TREE_CHAIN (phi))
      {
        T0 = var_to_partition_to_var (g->map, PHI_RESULT (phi));
!       if (PHI_ARG_EDGE (phi, i) == g->e)
! 	Ti = PHI_ARG_DEF (phi, i);
!       else
          {
! 	  /* On rare occasions, a PHI node may not have the arguments
! 	     in the same order as all of the other PHI nodes. If they don't 
! 	     match, find the appropriate index here.  */
! 	  pi = phi_arg_from_edge (phi, g->e);
! 	  if (pi == -1)
! 	    abort();
! 	  Ti = PHI_ARG_DEF (phi, pi);
! 	}
!       if (TREE_CONSTANT (Ti))
! 	insert_copy_on_edge (g->e, T0, Ti);
!       else
!         {
! 	  Ti = var_to_partition_to_var (g->map, Ti);
! 	  if (T0 != Ti)
! 	    {
! 	      eliminate_name (g, T0);
! 	      eliminate_name (g, Ti);
! 	      p0 = var_to_partition (g->map, T0);
! 	      pi = var_to_partition (g->map, Ti);
! 	      bitmap_set_bit (g->pred[pi], p0);
! 	      bitmap_set_bit (g->succ[p0], pi);
! 	      edges++;
! 	    }
  	}
      }
    return edges;
*************** elim_create (elim_graph g, int T)
*** 1098,1105 ****
  static void
  eliminate_phi (edge e, int i, elim_graph g)
  {
-   tree phi;
-   int num_phi = 0;
    int num_nodes = 0;
    int x, limit;
    basic_block B = e->dest;
--- 1112,1117 ----
*************** eliminate_phi (edge e, int i, elim_graph
*** 1109,1119 ****
      abort ();
  #endif
  
-   for (phi = phi_nodes (B); phi; phi = TREE_CHAIN (phi))
-     {
-       num_phi++;
-     }
- 
    num_nodes = num_var_partitions (g->map);
    g->e = e;
  
--- 1121,1126 ----
*************** coalesce_ssa_name (var_map map)
*** 1335,1354 ****
  	       edge, and attempt to coalesce the argument with the result.  */
  	    var = PHI_RESULT (phi);
  
- 	    /* Ignore SSA names that have no real references, as those
- 	       don't generate code.  */
- 	    if (!SSA_NAME_HAS_REAL_REFS (var))
- 	      continue;
- 
  	    x = var_to_partition (map, var);
  	    y = phi_arg_from_edge (phi, e);
  	    if (y == -1)
  	      abort ();
  
  	    tmp = PHI_ARG_DEF (phi, y);
! 	    if (!SSA_NAME_HAS_REAL_REFS (tmp))
! 	      continue;
! 
  	    y = var_to_partition (map, tmp);
  	    if (x == NO_PARTITION || y == NO_PARTITION)
  	      abort ();
--- 1342,1362 ----
  	       edge, and attempt to coalesce the argument with the result.  */
  	    var = PHI_RESULT (phi);
  
  	    x = var_to_partition (map, var);
  	    y = phi_arg_from_edge (phi, e);
  	    if (y == -1)
  	      abort ();
  
  	    tmp = PHI_ARG_DEF (phi, y);
! 	    if (TREE_CONSTANT (tmp))
! 	      {
! 		fprintf (stderr, "\nConstant argument in PHI. Can't insert :");
! 		print_generic_expr (stderr, var, TDF_SLIM);
! 		fprintf (stderr, " = ");
! 		print_generic_expr (stderr, tmp, TDF_SLIM);
! 		fprintf (stderr, "' across an abnormal edge\n");
! 		abort ();
! 	      }
  	    y = var_to_partition (map, tmp);
  	    if (x == NO_PARTITION || y == NO_PARTITION)
  	      abort ();
*************** assign_vars (var_map map)
*** 1474,1479 ****
--- 1482,1488 ----
  	     partition doesn't have the same root variable. Simply marked
  	     the variable as assigned.  */
  	  ann = var_ann (var);
+ 	  set_is_used (var);
  	  ann->out_of_ssa_tag = 1;
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
*************** assign_vars (var_map map)
*** 1502,1507 ****
--- 1511,1517 ----
  	  if (!ann->out_of_ssa_tag)
  	    {
  	      change_partition_var (map, var, i);
+ 	      set_is_used (var);
  	      continue;
  	    }
  
*************** replace_variable (var_map map, tree *p)
*** 1536,1559 ****
  {
    tree new_var;
    tree var = *p;
-   tree copy;
  
    new_var = var_to_partition_to_var (map, var);
    if (new_var)
      *p = new_var;
!   else
      {
!       /* Replace (*var)_version with just (*var).  */
!       if (TREE_CODE (SSA_NAME_VAR (var)) == INDIRECT_REF)
! 	{
! 	  tree var2 = TREE_OPERAND (SSA_NAME_VAR (var), 0);
! 	  new_var = var_to_partition_to_var (map, var2);
! 	  copy = copy_node (SSA_NAME_VAR (var));
! 	  if (new_var)
! 	    TREE_OPERAND (copy, 0) = new_var;
! 	  else
! 	    TREE_OPERAND (copy, 0) = var2;
! 	  *p = copy;
  	}
      }
  }
--- 1546,1572 ----
  {
    tree new_var;
    tree var = *p;
  
    new_var = var_to_partition_to_var (map, var);
    if (new_var)
      *p = new_var;
! }
! 
! 
! /* Remove any PHI node which is not in the partition map.  */
! static void
! eliminate_extraneous_phis (var_map map)
! {
!   basic_block bb;
!   tree phi, next;
! 
!   FOR_EACH_BB (bb)
      {
!       for (phi = phi_nodes (bb); phi; phi = next)
!         {
! 	  next = TREE_CHAIN (phi);
! 	  if (var_to_partition_to_var (map, PHI_RESULT (phi)) == NULL_TREE)
! 	    remove_phi_node (phi, NULL_TREE, bb);
  	}
      }
  }
*************** rewrite_out_of_ssa (tree fndecl)
*** 1579,1584 ****
--- 1592,1598 ----
      dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
  
    map = create_ssa_var_map ();
+   eliminate_extraneous_phis (map);
  
    /* Shrink the map to include only referenced variables.  Exclude variables
       which have only one SSA version since there is nothing to coalesce.  */
*************** rewrite_stmt (block_stmt_iterator si, va
*** 2033,2045 ****
      {
        tree *op_p = VARRAY_GENERIC_PTR (uses, i);
        if (TREE_CODE (*op_p) != SSA_NAME)
! 	rewrite_operand (op_p, true);
      }
  
    /* Rewrite virtual uses in the statement.  */
    for (i = 0; vuses && i < VARRAY_ACTIVE_SIZE (vuses); i++)
      if (TREE_CODE (VARRAY_TREE (vuses, i)) != SSA_NAME)
!       rewrite_operand (&(VARRAY_TREE (vuses, i)), false);
  
    /* Step 2.  Register the statement's DEF and VDEF operands.  */
    for (i = 0; defs && i < VARRAY_ACTIVE_SIZE (defs); i++)
--- 2047,2059 ----
      {
        tree *op_p = VARRAY_GENERIC_PTR (uses, i);
        if (TREE_CODE (*op_p) != SSA_NAME)
! 	rewrite_operand (op_p);
      }
  
    /* Rewrite virtual uses in the statement.  */
    for (i = 0; vuses && i < VARRAY_ACTIVE_SIZE (vuses); i++)
      if (TREE_CODE (VARRAY_TREE (vuses, i)) != SSA_NAME)
!       rewrite_operand (&(VARRAY_TREE (vuses, i)));
  
    /* Step 2.  Register the statement's DEF and VDEF operands.  */
    for (i = 0; defs && i < VARRAY_ACTIVE_SIZE (defs); i++)
*************** rewrite_stmt (block_stmt_iterator si, va
*** 2048,2054 ****
        if (TREE_CODE (*def_p) != SSA_NAME)
  	{
  	  *def_p = make_ssa_name (*def_p, stmt);
! 	  register_new_def (SSA_NAME_VAR (*def_p), *def_p, block_defs_p, true);
  	}
      }
  
--- 2062,2068 ----
        if (TREE_CODE (*def_p) != SSA_NAME)
  	{
  	  *def_p = make_ssa_name (*def_p, stmt);
! 	  register_new_def (SSA_NAME_VAR (*def_p), *def_p, block_defs_p);
  	}
      }
  
*************** rewrite_stmt (block_stmt_iterator si, va
*** 2060,2070 ****
        if (TREE_CODE (VDEF_RESULT (vdef)) == SSA_NAME)
  	continue;
  
!       rewrite_operand (&(VDEF_OP (vdef)), false);
  
        VDEF_RESULT (vdef) = make_ssa_name (VDEF_RESULT (vdef), stmt);
        register_new_def (SSA_NAME_VAR (VDEF_RESULT (vdef)), 
! 			VDEF_RESULT (vdef), block_defs_p, false);
      }
  }
  
--- 2074,2084 ----
        if (TREE_CODE (VDEF_RESULT (vdef)) == SSA_NAME)
  	continue;
  
!       rewrite_operand (&(VDEF_OP (vdef)));
  
        VDEF_RESULT (vdef) = make_ssa_name (VDEF_RESULT (vdef), stmt);
        register_new_def (SSA_NAME_VAR (VDEF_RESULT (vdef)), 
! 			VDEF_RESULT (vdef), block_defs_p);
      }
  }
  
*************** set_is_used (tree t)
*** 2083,2089 ****
     definition.  IS_REAL_OPERAND is true when this is a USE operand.  */
  
  static inline void
! rewrite_operand (tree *op_p, bool is_real_operand)
  {
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*op_p) == SSA_NAME)
--- 2097,2103 ----
     definition.  IS_REAL_OPERAND is true when this is a USE operand.  */
  
  static inline void
! rewrite_operand (tree *op_p)
  {
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*op_p) == SSA_NAME)
*************** rewrite_operand (tree *op_p, bool is_rea
*** 2091,2098 ****
  #endif
  
    *op_p = get_reaching_def (*op_p);
-   if (is_real_operand)
-     SSA_NAME_HAS_REAL_REFS (*op_p) = true;
  }
  
  
--- 2105,2110 ----
*************** rewrite_operand (tree *op_p, bool is_rea
*** 2101,2108 ****
     IS_REAL_OPERAND is true when DEF is a real definition.  */
  
  static void
! register_new_def (tree var, tree def, varray_type *block_defs_p,
! 		  bool is_real_operand)
  {
    tree currdef = get_value_for (var, currdefs);
  
--- 2113,2119 ----
     IS_REAL_OPERAND is true when DEF is a real definition.  */
  
  static void
! register_new_def (tree var, tree def, varray_type *block_defs_p)
  {
    tree currdef = get_value_for (var, currdefs);
  
*************** register_new_def (tree var, tree def, va
*** 2121,2129 ****
  
    /* Set the current reaching definition for VAR to be DEF.  */
    set_value_for (var, def, currdefs);
- 
-   if (is_real_operand)
-     SSA_NAME_HAS_REAL_REFS (def) = true;
  }
  
  
--- 2132,2137 ----
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.78
diff -c -p -r1.342.2.78 tree.h
*** tree.h	21 Jul 2003 17:27:52 -0000	1.342.2.78
--- tree.h	22 Jul 2003 15:03:19 -0000
*************** struct tree_exp GTY(())
*** 975,994 ****
  #define SSA_NAME_VAR(NODE)	SSA_NAME_CHECK (NODE)->ssa_name.var
  #define SSA_NAME_DEF_STMT(NODE)	SSA_NAME_CHECK (NODE)->ssa_name.def_stmt
  #define SSA_NAME_VERSION(NODE)	SSA_NAME_CHECK (NODE)->ssa_name.version
- #define SSA_NAME_HAS_REAL_REFS(NODE) \
-     SSA_NAME_CHECK (NODE)->ssa_name.has_real_refs
  #define SSA_NAME_OCCURS_IN_ABNORMAL_PHI(NODE) \
      SSA_NAME_CHECK (NODE)->ssa_name.occurs_in_abnormal_phi
  
  struct tree_ssa_name GTY(())
  {
    struct tree_common common;
- 
-   /* Nonzero if this SSA name is used as a real operand in this function.
-      This is used by the SSA->normal pass to determine which variables to
-      ignore in the coalescing phase.  By default, SSA names are assumed to
-      have no real references.  This is changed by the SSA rename pass.  */
-   unsigned has_real_refs : 1;
  
    /* Nonzero if the SSA name occurs in an abnormal PHI.  */
    unsigned occurs_in_abnormal_phi : 1;
--- 975,986 ----





More information about the Gcc-patches mailing list