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]

[tree-ssa] Various fixes to virtual operand handling


This patch reverses the trend I had started with the change to the last
may-alias changes.  For a while I thought it would be better if we were
able to mix virtual and real operands in aliased variables.  The idea
was to emit real operands when the variable was accessed directly and
virtual operands when it was referenced via pointer dereferences.

While that could be made to work, Jeff and Andrew had very good
arguments against it.  Mixing real and virtual operands in the basic
framework forces the optimizers to do extra work and always be careful
about what they're doing.

This patch reverses that trend.  We no longer mix real and virtual
operands.  Notice that this produces a slight slowdown in compile times
as the number of virtual operands we now generate is bigger.  But the
slowdown was almost unnoticeable.

Notice that we still generate some mix of virtual and real operands. 
Particularly in the presence of ADDR_EXPR and ASM_EXPR.  I will be
addressing that problem next.

The patch includes other minor fixes:

     1. The accessors to statement and variable annotations have been
        tightened to not allow anything other than statements or
        _DECLs.  This uncovered a buglet in
        tree-cfg.c:find_contained_blocks.  We were looking for basic
        blocks inside COND_EXPR_COND and SWITCH_COND expressions.  Those
        aren't statements, so they can't contain a statement annotation.
     2. The annotations 'has_real_refs' and 'occurs_in_abnormal_phi'
        aren't for _DECLs.  They apply to SSA_NAMEs.


Bootstrapped and tested x86, alpha, amd64 and ppc.  Bootstraps on ia64
are still broken.  I haven't found the problem yet.


Diego.


	* tree-flow.h (struct tree_ann_common_d): Remove 'stmt' field.
	Update all users.
	(struct var_ann_d): Remove field 'has_real_refs'.  Update all callers
	with calls to SSA_NAME_HAS_REAL_REFS.
	Remove field 'occurs_in_abnormal_phi'.  Update all callers with
	calls to SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
	* tree-flow-inline.h (var_ann): Only accept _DECL nodes.
	(stmt_ann): Only accept GIMPLE statements.
	(tree_stmt): Remove.  Update all users.

	* tree-cfg.c (linearize_cond_expr): Handle cases where BB doesn't
	have a postdominator.
	(find_contained_blocks): Do not look inside COND_EXPR_COND nor
	SWITCH_COND expressions.

	* tree-dfa.c (get_stmt_operands): Force virtual operands on
	ASM_EXPRs.
	(get_expr_operands): Handle SSA names when adding operands for
	memory tags.
	(add_stmt_operand): Handle SSA names.
	Move checks for volatile operands earlier in the code.
	(add_vdef): Re-format for readability.
	(create_var_ann): Only allow _DECL nodes.
	(create_stmt_ann): Only allow GIMPLE statements.
	(dump_variable): Handle SSA names.
	(dump_may_aliases_for): Likewise.
	(may_access_global_mem_p): Handle SSA names.
	(remove_phi_arg): If the argument removed was the last one with
	real references, update the LHS of the PHI node.
	(add_phi_arg): If the argument added has real references, propagate
	the attribute into the LHS of the PHI node.

	* tree-pretty-print.c (dump_generic_node): Only retrieve basic
	block information from GIMPLE statements.
	Always output the THEN and ELSE clauses of COND_EXPR nodes.

	* tree-simple.c (is_gimple_stmt): Accept PHI_NODEs.
	(is_gimple_id): Accept SSA_NAMEs.

	* tree-ssa-copyprop.c (copyprop_phi): If an argument is used as a
	real operand, propagate the attribute into the LHS of the PHI.

	* tree-ssa-live.c (create_ssa_var_map): Don't set 'used' flag on
	both the operand and the result of VDEFs.
	Only register PHI results and arguments that have been used as real
	operands.
	(calculate_live_on_entry): Fix formatting in debugging message.

	* tree-ssa.c (register_new_def): Add new argument
	'is_real_operand'.  If it's set, set SSA_NAME_HAS_REAL_REFS for the
	new name.  Update all callers.
	(rewrite_operand): Add new argument 'is_real_operand'.  If it's
	set, set SSA_NAME_HAS_REAL_REFS to the operand.
	(eliminate_build): Ignore PHI arguments and PHI results that have
	not been used in real operands.
	(rewrite_vdefs): Remove.  Update all users.
	(set_is_used): Don't handle SSA names.
	(coalesce_ssa_name): Ignore PHI arguments that have not had real
	references in the program.

	* tree.c (make_ssa_name): Update documentation.
	* tree.h (IS_EMPTY_STMT): Call integer_zerop instead of comparing
	against size_zero_node.
	(SSA_NAME_HAS_REAL_REFS): Define.
	(SSA_NAME_OCCURS_IN_ABNORMAL_PHI): Define.
	(struct tree_ssa_name): Add bitfields 'has_real_refs' and
	'occurs_in_abnormal_phi'.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.122
diff -d -c -p -r1.1.4.122 tree-cfg.c
*** tree-cfg.c	1 Jul 2003 02:04:51 -0000	1.1.4.122
--- tree-cfg.c	1 Jul 2003 03:43:43 -0000
*************** find_contained_blocks (tree *stmt_p, bit
*** 992,998 ****
  	}
        else if (code == COND_EXPR)
  	{
- 	  find_contained_blocks (&COND_EXPR_COND (stmt), my_blocks, last_p);
  	  find_contained_blocks (&COND_EXPR_THEN (stmt), my_blocks, last_p);
  	  find_contained_blocks (&COND_EXPR_ELSE (stmt), my_blocks, last_p);
  	}
--- 992,997 ----
*************** find_contained_blocks (tree *stmt_p, bit
*** 1029,1035 ****
  	}
        else if (code == SWITCH_EXPR)
  	{
- 	  find_contained_blocks (&SWITCH_COND (stmt), my_blocks, last_p);
  	  find_contained_blocks (&SWITCH_BODY (stmt), my_blocks, last_p);
  	}
        else if (code == BIND_EXPR)
--- 1028,1033 ----
*************** linearize_cond_expr (tree *entry_p, basi
*** 2363,2369 ****
        if (pdom_info == NULL)
  	pdom_info = calculate_dominance_info (CDI_POST_DOMINATORS);
        pdom_bb = get_immediate_dominator (pdom_info, bb);
!       if (!phi_nodes (pdom_bb))
          {
  	  remove_stmt (entry_p);
  	  return true;
--- 2361,2367 ----
        if (pdom_info == NULL)
  	pdom_info = calculate_dominance_info (CDI_POST_DOMINATORS);
        pdom_bb = get_immediate_dominator (pdom_info, bb);
!       if (!pdom_bb || !phi_nodes (pdom_bb))
          {
  	  remove_stmt (entry_p);
  	  return true;
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.124
diff -d -c -p -r1.1.4.124 tree-dfa.c
*** tree-dfa.c	25 Jun 2003 02:37:31 -0000	1.1.4.124
--- tree-dfa.c	1 Jul 2003 03:43:43 -0000
*************** get_stmt_operands (tree stmt)
*** 208,216 ****
        break;
  
      case ASM_EXPR:
!       get_expr_operands (stmt, &ASM_INPUTS (stmt), opf_none, prev_vops);
!       get_expr_operands (stmt, &ASM_OUTPUTS (stmt), opf_is_def, prev_vops);
!       get_expr_operands (stmt, &ASM_CLOBBERS (stmt), opf_is_def, prev_vops);
        break;
  
      case RETURN_EXPR:
--- 208,222 ----
        break;
  
      case ASM_EXPR:
!       /* FIXME: We don't treat ASM_EXPR operands as real operands so that
! 	 optimizations don't try to transform them.  In execute/20020107-1.c
! 	 CCP tries to propagate constants into some __asm__ operands,
! 	 causing an ICE during RTL expansion.  */
!       get_expr_operands (stmt, &ASM_INPUTS (stmt), opf_force_vop, prev_vops);
!       get_expr_operands (stmt, &ASM_OUTPUTS (stmt), opf_is_def|opf_force_vop,
! 			 prev_vops);
!       get_expr_operands (stmt, &ASM_CLOBBERS (stmt), opf_is_def|opf_force_vop,
! 			 prev_vops);
        break;
  
      case RETURN_EXPR:
*************** get_expr_operands (tree stmt, tree *expr
*** 357,363 ****
  
        if (SSA_VAR_P (ptr))
  	{
! 	  ann = var_ann (ptr);
  	  if (ann->mem_tag)
  	    add_stmt_operand (&ann->mem_tag, stmt, flags|opf_force_vop,
  			      prev_vops);
--- 363,369 ----
  
        if (SSA_VAR_P (ptr))
  	{
! 	  ann = var_ann (TREE_CODE (ptr) == SSA_NAME ? SSA_NAME_VAR (ptr) : ptr);
  	  if (ann->mem_tag)
  	    add_stmt_operand (&ann->mem_tag, stmt, flags|opf_force_vop,
  			      prev_vops);
*************** add_stmt_operand (tree *var_p, tree stmt
*** 533,539 ****
      return;
  
    s_ann = stmt_ann (stmt);
!   v_ann = var_ann (var);
  
    /* FIXME: Currently, global and local static variables are always treated as
       virtual operands.  Otherwise, we would have to insert copy-in/copy-out
--- 539,545 ----
      return;
  
    s_ann = stmt_ann (stmt);
!   v_ann = var_ann (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
  
    /* FIXME: Currently, global and local static variables are always treated as
       virtual operands.  Otherwise, we would have to insert copy-in/copy-out
*************** add_stmt_operand (tree *var_p, tree stmt
*** 547,566 ****
        s_ann->has_volatile_ops = 1;
      }
  
    aliases = v_ann->may_aliases;
    if (aliases == NULL)
      {
!       /* The variable is not aliased.  If it's a scalar that is not used as
! 	 an alias tag for other variables, process it as a real operand.
! 	 Otherwise, add it to the virtual operands.  Note that we never
! 	 consider ASM_EXPR operands as real.  They are always added to
! 	 virtual operands so that optimizations don't try to optimize them.
! 
! 	 FIXME: This is true for CCP.  It tries to propagate constants in
! 		some __asm__ operands causing ICEs during RTL expansion
! 		(execute/20020107-1.c).  Do we really need to be this
! 		drastic?  Or should each optimization take care when
! 		dealing with ASM_EXPRs?  */
        if (flags & opf_is_def)
  	{
  	  if (is_scalar
--- 553,575 ----
        s_ann->has_volatile_ops = 1;
      }
  
+   /* If the variable is an alias tag, it means that its address has been
+      taken and it's being accessed directly and via pointers.  To avoid
+      mixing real and virtual operands, we treat all references to aliased
+      variables as virtual.  */
+   if (v_ann->is_alias_tag)
+     flags |= opf_force_vop;
+ 
+   /* If the variable is volatile, inform the statement that it makes
+       volatile storage references.  */
+   if (TREE_THIS_VOLATILE (var))
+     s_ann->has_volatile_ops = 1;
+ 
    aliases = v_ann->may_aliases;
    if (aliases == NULL)
      {
!       /* The variable is not aliased.  Add it as a real operand (unless
! 	 opf_force_vop is set).  */
        if (flags & opf_is_def)
  	{
  	  if (is_scalar
*************** add_stmt_operand (tree *var_p, tree stmt
*** 577,597 ****
        else
  	{
  	  if (is_scalar
! 	      && !(flags & opf_force_vop)
! 	      && TREE_CODE (stmt) != ASM_EXPR)
  	    add_use (var_p, stmt);
  	  else
  	    add_vuse (var, stmt, prev_vops);
  
  	  /* If the variable is an alias tag, mark the statement.  */
  	  if (v_ann->is_alias_tag)
! 	    s_ann->makes_aliased_stores = 1;
  	}
- 
-       /* If the variable is volatile, inform the statement that it makes
- 	 volatile storage references.  */
-       if (TREE_THIS_VOLATILE (var))
- 	s_ann->has_volatile_ops = 1;
      }
    else
      {
--- 586,600 ----
        else
  	{
  	  if (is_scalar
! 	      && !(flags & opf_force_vop))
  	    add_use (var_p, stmt);
  	  else
  	    add_vuse (var, stmt, prev_vops);
  
  	  /* If the variable is an alias tag, mark the statement.  */
  	  if (v_ann->is_alias_tag)
! 	    s_ann->makes_aliased_loads = 1;
  	}
      }
    else
      {
*************** set_def (tree *def_p, tree stmt)
*** 645,651 ****
      }
  
    ann->ops->def_op = def_p;
-   get_var_ann (*def_p)->has_real_refs = 1;
  }
  
  
--- 648,653 ----
*************** add_use (tree *use_p, tree stmt)
*** 674,680 ****
      VARRAY_GENERIC_PTR_INIT (ann->ops->use_ops, 3, "use_ops");
  
    VARRAY_PUSH_GENERIC_PTR (ann->ops->use_ops, use_p);
-   get_var_ann (*use_p)->has_real_refs = 1;
  }
  
  
--- 676,681 ----
*************** add_vdef (tree var, tree stmt, voperands
*** 690,700 ****
    stmt_ann_t ann;
    size_t i;
  
    if (prev_vops && prev_vops->vdef_ops)
      return;
-   else
-     vdef = build_vdef_expr (var);
  
    ann = stmt_ann (stmt);
    if (ann->vops == NULL)
      {
--- 691,701 ----
    stmt_ann_t ann;
    size_t i;
  
+   /* The statement already had virtual definitions.  Do nothing.  */
    if (prev_vops && prev_vops->vdef_ops)
      return;
  
+   vdef = build_vdef_expr (var);
    ann = stmt_ann (stmt);
    if (ann->vops == NULL)
      {
*************** add_vuse (tree var, tree stmt, voperands
*** 725,730 ****
--- 726,732 ----
    stmt_ann_t ann;
    size_t i;
  
+   /* The statement already had virtual uses.  Do nothing.  */
    if (prev_vops && prev_vops->vuse_ops)
      return;
  
*************** add_phi_arg (tree phi, tree def, edge e)
*** 794,806 ****
       PHI nodes.  This is a convenient place to record such information.  */
    if (e->flags & EDGE_ABNORMAL)
      {
!       var_ann (def)->occurs_in_abnormal_phi = 1;
!       var_ann (PHI_RESULT (phi))->occurs_in_abnormal_phi = 1;
      }
  
    PHI_ARG_DEF (phi, i) = def;
    PHI_ARG_EDGE (phi, i) = e;
    PHI_NUM_ARGS (phi)++;
  }
  
  
--- 796,812 ----
       PHI nodes.  This is a convenient place to record such information.  */
    if (e->flags & EDGE_ABNORMAL)
      {
!       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) = 1;
!       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)) = 1;
      }
  
    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;
  }
  
  
*************** void
*** 842,847 ****
--- 848,859 ----
  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.  */
*************** remove_phi_arg_num (tree phi, int i)
*** 855,860 ****
--- 867,884 ----
    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;
+     }
  }
  
  
*************** create_var_ann (tree t)
*** 1015,1021 ****
    var_ann_t ann;
  
  #if defined ENABLE_CHECKING
!   if (t == NULL_TREE || !DECL_P (t))
      abort ();
  #endif
  
--- 1039,1048 ----
    var_ann_t ann;
  
  #if defined ENABLE_CHECKING
!   if (t == NULL_TREE
!       || !DECL_P (t)
!       || (t->common.ann
! 	  && t->common.ann->common.type != VAR_ANN))
      abort ();
  #endif
  
*************** create_stmt_ann (tree t)
*** 1038,1046 ****
    stmt_ann_t ann;
  
  #if defined ENABLE_CHECKING
!   if (t == NULL_TREE
!       || TREE_CODE_CLASS (TREE_CODE (t)) == 'c'
!       || TREE_CODE_CLASS (TREE_CODE (t)) == 't')
      abort ();
  #endif
  
--- 1065,1073 ----
    stmt_ann_t ann;
  
  #if defined ENABLE_CHECKING
!   if (!is_gimple_stmt (t)
!       || (t->common.ann
! 	  && t->common.ann->common.type != STMT_ANN))
      abort ();
  #endif
  
*************** create_stmt_ann (tree t)
*** 1053,1081 ****
    ann->modified = true;
  
    t->common.ann = (tree_ann) ann;
-   ann->common.stmt = t; 
- 
-   /* SSA-PRE currently needs to be able to get to the parent node of an
-      arbitrary RHS.  This should eventually be fixed as it makes removal
-      of annotations more complicated than it should be (consider 
-      propagation of a constant that appeared on the RHS of a MODIFY_EXPR
-      and eventual removal of the MODIFY_EXPR). 
- 
-      If additional annotations are created, then the removal code for
-      annotations needs to be updated.  Such code appears in 
-      remove_annotation_r and remove_stmt.  */
-   if (TREE_CODE (t) == MODIFY_EXPR)
-     {
-       tree op = TREE_OPERAND (t, 1);
-       if (op->common.ann != NULL)
-         op->common.ann->common.stmt = t;
-       else
-         {
-           op->common.ann = ggc_alloc (sizeof (struct tree_ann_common_d));
-           op->common.ann->common.type = TREE_ANN_COMMON;
- 	  op->common.ann->common.stmt = t;
-         }
-     }
  
    return ann;
  }
--- 1080,1085 ----
*************** dump_variable (FILE *file, tree var)
*** 1129,1134 ****
--- 1133,1141 ----
  
    print_generic_expr (file, var, 0);
    
+   if (TREE_CODE (var) == SSA_NAME)
+     var = SSA_NAME_VAR (var);
+ 
    ann = var_ann (var);
  
    if (ann->mem_tag)
*************** dump_variable (FILE *file, tree var)
*** 1152,1160 ****
    if (ann->is_call_clobbered)
      fprintf (file, ", call clobbered");
  
-   if (ann->occurs_in_abnormal_phi)
-     fprintf (file, ", occurs in an abnormal PHI node");
- 
    if (ann->is_stored)
      fprintf (file, ", is stored");
  
--- 1159,1164 ----
*************** debug_variable (tree var)
*** 1182,1189 ****
  void
  dump_may_aliases_for (FILE *file, tree var)
  {
!   varray_type aliases = var_ann (var)->may_aliases;
  
    if (aliases)
      {
        size_t i, num_aliases = VARRAY_ACTIVE_SIZE (aliases);
--- 1186,1197 ----
  void
  dump_may_aliases_for (FILE *file, tree var)
  {
!   varray_type aliases;
!   
!   if (TREE_CODE (var) == SSA_NAME)
!     var = SSA_NAME_VAR (var);
  
+   aliases = var_ann (var)->may_aliases;
    if (aliases)
      {
        size_t i, num_aliases = VARRAY_ACTIVE_SIZE (aliases);
*************** may_access_global_mem_p (tree expr)
*** 1901,1907 ****
       return true.  */
    if (SSA_VAR_P (expr))
      {
!       var_ann_t ann = var_ann (expr);
        if (ann->may_point_to_global_mem || ann->may_alias_global_mem)
  	return true;
      }
--- 1909,1916 ----
       return true.  */
    if (SSA_VAR_P (expr))
      {
!       var_ann_t ann;
!       ann = var_ann (TREE_CODE (expr) == SSA_NAME ? SSA_NAME_VAR (expr) : expr);
        if (ann->may_point_to_global_mem || ann->may_alias_global_mem)
  	return true;
      }
*************** add_referenced_var (tree var, struct wal
*** 2120,2130 ****
  	  && (TREE_CODE (var) == PARM_DECL
  	      || decl_function_context (var) == NULL_TREE))
  	v_ann->may_point_to_global_mem = 1;
- 
-       /* By default, assume that the variable has no real references.  If
- 	 the variable is used as a real operand to a statement (i.e.,
- 	 add_use and set_def), this field will be set to 1.  */
-       v_ann->has_real_refs = 0;
  
        is_addressable = TREE_ADDRESSABLE (var)
  		       || decl_function_context (var) == NULL;
--- 2129,2134 ----
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.37
diff -d -c -p -r1.1.2.37 tree-flow-inline.h
*** tree-flow-inline.h	24 May 2003 13:08:51 -0000	1.1.2.37
--- tree-flow-inline.h	1 Jul 2003 03:43:43 -0000
*************** var_ann (t)
*** 30,51 ****
       tree t;
  {
  #if defined ENABLE_CHECKING
!   if (!SSA_VAR_P (t))
      abort ();
  #endif
  
!   /* SSA_NAME nodes share the same annotations as the VAR_DECL
!      node that they wrap.  */
!   if (TREE_CODE (t) == SSA_NAME)
!     t = SSA_NAME_VAR (t);
! 
!   return (t->common.ann && t->common.ann->common.type == VAR_ANN)
! 	 ? (var_ann_t) t->common.ann
! 	 : NULL;
  }
  
- /* Return the annotation for variable VAR.  If none exists, create a new
-    one.  */
  static inline var_ann_t
  get_var_ann (tree var)
  {
--- 30,45 ----
       tree t;
  {
  #if defined ENABLE_CHECKING
!   if (t == NULL_TREE
!       || !DECL_P (t)
!       || (t->common.ann
! 	  && t->common.ann->common.type != VAR_ANN))
      abort ();
  #endif
  
!   return (var_ann_t) t->common.ann;
  }
  
  static inline var_ann_t
  get_var_ann (tree var)
  {
*************** get_var_ann (tree var)
*** 53,76 ****
    return (ann) ? ann : create_var_ann (var);
  }
  
- static inline tree
- tree_stmt (t)
-      tree t;
- {
-   return t->common.ann->common.stmt;
- }
- 
  static inline stmt_ann_t
  stmt_ann (t)
       tree t;
  {
!   return (t->common.ann && t->common.ann->common.type == STMT_ANN)
! 	 ? (stmt_ann_t) t->common.ann
! 	 : NULL;
  }
  
- /* Return the annotation for statement STMT.  If none exists, create a new
-    one.  */
  static inline stmt_ann_t
  get_stmt_ann (tree stmt)
  {
--- 47,64 ----
    return (ann) ? ann : create_var_ann (var);
  }
  
  static inline stmt_ann_t
  stmt_ann (t)
       tree t;
  {
! #if defined ENABLE_CHECKING
!   if (!is_gimple_stmt (t))
!     abort ();
! #endif
! 
!   return (stmt_ann_t) t->common.ann;
  }
  
  static inline stmt_ann_t
  get_stmt_ann (tree stmt)
  {
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.87
diff -d -c -p -r1.1.4.87 tree-flow.h
*** tree-flow.h	26 Jun 2003 01:07:05 -0000	1.1.4.87
--- tree-flow.h	1 Jul 2003 03:43:43 -0000
*************** struct tree_ann_common_d GTY(())
*** 45,52 ****
  {
    /* Annotation type.  */
    enum tree_ann_type type;
-   /* Statement this annotation belongs to. */
-   tree stmt;
  };
  
  
--- 45,50 ----
*************** struct var_ann_d GTY(())
*** 77,92 ****
    /* Nonzero if the variable may be modified by function calls.  */
    unsigned is_call_clobbered : 1;
  
!   /* Used by the out of SSA pass to determine whether this var has been
!      seen yet or not.  */
    unsigned out_of_ssa_tag : 1;
  
    /* Used when building root_var structures in tree_ssa_live.[ch].  */
    unsigned root_var_processed : 1;
  
-   /* Nonzero if the variable occurs in an abnormal PHI.  */
-   unsigned occurs_in_abnormal_phi : 1;
- 
    /* Nonzero if this variable is a memory tag used to represent the memory
       pointed-to by the pointer in MEM_TAG.  */
    unsigned is_mem_tag : 1;
--- 75,87 ----
    /* Nonzero if the variable may be modified by function calls.  */
    unsigned is_call_clobbered : 1;
  
!   /* Used by the out of SSA pass to determine whether this variable has
!      been seen yet or not.  */
    unsigned out_of_ssa_tag : 1;
  
    /* Used when building root_var structures in tree_ssa_live.[ch].  */
    unsigned root_var_processed : 1;
  
    /* Nonzero if this variable is a memory tag used to represent the memory
       pointed-to by the pointer in MEM_TAG.  */
    unsigned is_mem_tag : 1;
*************** struct var_ann_d GTY(())
*** 96,108 ****
       of other variables).  */
    unsigned is_alias_tag : 1;
  
-   /* Nonzero if this variable 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, all variables start with
-      this flag set to 0.  This changes if the variable is added as an
-      operand using add_use or set_def.  */
-   unsigned has_real_refs : 1;
- 
    /* Nonzero if this variable was used after SSA optimizations were
       applied.  We set this when translating out of SSA form.  */
    unsigned used : 1;
--- 91,96 ----
*************** typedef union tree_ann_d *tree_ann;
*** 249,255 ****
  typedef struct var_ann_d *var_ann_t;
  typedef struct stmt_ann_d *stmt_ann_t;
  
- static inline tree tree_stmt			PARAMS ((tree));
  static inline var_ann_t var_ann			PARAMS ((tree));
  static inline var_ann_t get_var_ann		PARAMS ((tree));
  static inline stmt_ann_t stmt_ann		PARAMS ((tree));
--- 237,242 ----
Index: tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-pretty-print.c,v
retrieving revision 1.1.2.30
diff -d -c -p -r1.1.2.30 tree-pretty-print.c
*** tree-pretty-print.c	16 Jun 2003 18:54:00 -0000	1.1.2.30
--- tree-pretty-print.c	1 Jul 2003 03:43:43 -0000
*************** dump_generic_node (buffer, node, spc, fl
*** 155,161 ****
    if (node == NULL_TREE)
      return spc;
  
!   if (node != error_mark_node)
      {
        basic_block curr_bb = bb_for_stmt (node);
  
--- 155,162 ----
    if (node == NULL_TREE)
      return spc;
  
!   if (TREE_CODE (node) != ERROR_MARK
!       && is_gimple_stmt (node))
      {
        basic_block curr_bb = bb_for_stmt (node);
  
*************** dump_generic_node (buffer, node, spc, fl
*** 698,725 ****
  	  output_add_character (buffer, ')');
  	  if (!(flags & TDF_SLIM))
  	    {
! 	      if (IS_EMPTY_STMT (COND_EXPR_THEN (node)))
! 		{
! 		  output_add_character (buffer, ';');
! 		}
! 	      else
  		{
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '{');
  		  newline_and_indent (buffer, spc+4);
! 		  dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4,
! 		                     flags);
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '}');
  		}
! 	      if (!IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
  		{
  		  newline_and_indent (buffer, spc);
  		  output_add_string (buffer, "else");
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '{');
  		  newline_and_indent (buffer, spc+4);
! 		  dump_generic_node (buffer, TREE_OPERAND (node, 2), spc+4,
  			             flags);
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '}');
--- 699,725 ----
  	  output_add_character (buffer, ')');
  	  if (!(flags & TDF_SLIM))
  	    {
! 	      /* Output COND_EXPR_THEN.  */
! 	      if (COND_EXPR_THEN (node))
  		{
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '{');
  		  newline_and_indent (buffer, spc+4);
! 		  dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
! 				     flags);
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '}');
  		}
! 
! 	      /* Output COND_EXPR_ELSE.  */
! 	      if (COND_EXPR_ELSE (node))
  		{
  		  newline_and_indent (buffer, spc);
  		  output_add_string (buffer, "else");
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '{');
  		  newline_and_indent (buffer, spc+4);
! 		  dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
  			             flags);
  		  newline_and_indent (buffer, spc+2);
  		  output_add_character (buffer, '}');
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.42
diff -d -c -p -r1.1.4.42 tree-simple.c
*** tree-simple.c	26 Jun 2003 19:58:31 -0000	1.1.4.42
--- tree-simple.c	1 Jul 2003 03:43:43 -0000
*************** is_gimple_stmt (tree t)
*** 631,636 ****
--- 631,642 ----
        /* Might be OK.  */
        break;
  
+     case 'x':
+       if (code == PHI_NODE)
+ 	return 1;
+       else
+ 	return 0;
+ 
      default:
        /* Not an expression?!?  */
        return 0;
*************** is_gimple_id (t)
*** 699,705 ****
  	  || (TREE_CODE (t) == ADDR_EXPR
  	      && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
  	  /* Allow string constants.  */
! 	  || TREE_CODE (t) == STRING_CST);
  }
  
  
--- 705,712 ----
  	  || (TREE_CODE (t) == ADDR_EXPR
  	      && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
  	  /* Allow string constants.  */
! 	  || TREE_CODE (t) == STRING_CST
! 	  || TREE_CODE (t) == SSA_NAME);
  }
  
  
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.74
diff -d -c -p -r1.1.2.74 tree-ssa-ccp.c
*** tree-ssa-ccp.c	17 Jun 2003 02:27:39 -0000	1.1.2.74
--- tree-ssa-ccp.c	1 Jul 2003 03:43:43 -0000
*************** visit_phi_node (tree phi)
*** 371,377 ****
    /* 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)))
!       || !var_ann (SSA_NAME_VAR (PHI_RESULT (phi)))->has_real_refs)
      phi_val.lattice_val = VARYING;
    else
      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
--- 371,377 ----
    /* 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++)
Index: tree-ssa-copyprop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-copyprop.c,v
retrieving revision 1.1.2.4
diff -d -c -p -r1.1.2.4 tree-ssa-copyprop.c
*** tree-ssa-copyprop.c	11 Jun 2003 12:41:21 -0000	1.1.2.4
--- tree-ssa-copyprop.c	1 Jul 2003 03:43:43 -0000
*************** copyprop_stmt (tree stmt)
*** 113,120 ****
        tree orig = get_original (*use_p, &vuse);
  
        if (orig
! 	  && ! var_ann (SSA_NAME_VAR (*use_p))->occurs_in_abnormal_phi
! 	  && ! var_ann (SSA_NAME_VAR (orig))->occurs_in_abnormal_phi)
  	{
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
--- 113,120 ----
        tree orig = get_original (*use_p, &vuse);
  
        if (orig
! 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*use_p)
! 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
  	{
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
*************** copyprop_phi (tree phi)
*** 159,166 ****
        tree orig = get_original (arg, &vuse);
  
        if (orig
! 	  && ! var_ann (SSA_NAME_VAR (arg))->occurs_in_abnormal_phi
! 	  && ! var_ann (SSA_NAME_VAR (orig))->occurs_in_abnormal_phi)
  	{
  	  if (dump_file && dump_flags & TDF_DETAILS)
  	    {
--- 159,166 ----
        tree orig = get_original (arg, &vuse);
  
        if (orig
! 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg)
! 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
  	{
  	  if (dump_file && dump_flags & TDF_DETAILS)
  	    {
*************** copyprop_phi (tree phi)
*** 172,177 ****
--- 172,180 ----
  	    }
  
  	  PHI_ARG_DEF (phi, i) = orig;
+ 
+ 	  if (SSA_NAME_HAS_REAL_REFS (orig))
+ 	    SSA_NAME_HAS_REAL_REFS (PHI_RESULT (phi)) = 1;
  	}
      }
  }
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.9
diff -d -c -p -r1.1.2.9 tree-ssa-live.c
*** tree-ssa-live.c	26 Jun 2003 01:07:05 -0000	1.1.2.9
--- tree-ssa-live.c	1 Jul 2003 03:43:43 -0000
*************** create_ssa_var_map (void)
*** 301,306 ****
--- 301,307 ----
  	  stmt = bsi_stmt (bsi);
  	  get_stmt_operands (stmt);
  
+ 	  /* Register USE and DEF operands in each statement.  */
  	  ops = use_ops (stmt);
  	  for (x = 0; ops && x < VARRAY_ACTIVE_SIZE (ops); x++)
  	    {
*************** create_ssa_var_map (void)
*** 325,352 ****
  
  	  ops = vdef_ops (stmt);
  	  for (x = 0; ops && x < VARRAY_ACTIVE_SIZE (ops); x++)
! 	    {
! 	      set_is_used (VDEF_OP (VARRAY_TREE (ops, x)));
! 	      set_is_used (VDEF_RESULT (VARRAY_TREE (ops, x)));
! 	    }
! 	  
  	}
  
        /* Now register elements of PHI nodes.  */
        for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
          {
! 	  tree var = PHI_RESULT (phi);
! 	  
! 	  /* Only process variables that have real references.  */
! 	  if (var_ann (var)->has_real_refs)
  	    {
! 	      register_ssa_partition (map, var);
  	      set_is_used (PHI_RESULT (phi));
  	      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
! 		{
! 		  register_ssa_partition (map, PHI_ARG_DEF (phi, i));
! 		  set_is_used (PHI_ARG_DEF (phi, i));
! 		}
  	    }
  	}
      }
--- 326,352 ----
  
  	  ops = vdef_ops (stmt);
  	  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));
! 		  }
  	    }
  	}
      }
*************** calculate_live_on_entry (var_map map)
*** 579,585 ****
  	    {
  	      num++;
  	      print_generic_expr (stderr, var, TDF_SLIM);
! 	      fprintf (stderr, " is defined, but is also live on entry.");
  	    }
  	}
      }
--- 579,585 ----
  	    {
  	      num++;
  	      print_generic_expr (stderr, var, TDF_SLIM);
! 	      fprintf (stderr, " is defined, but is also live on entry.\n");
  	    }
  	}
      }
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.98
diff -d -c -p -r1.1.4.98 tree-ssa.c
*** tree-ssa.c	26 Jun 2003 01:07:05 -0000	1.1.4.98
--- tree-ssa.c	1 Jul 2003 03:43:43 -0000
*************** static void rewrite_block (basic_block, 
*** 167,174 ****
  static int rewrite_and_optimize_stmt (block_stmt_iterator, varray_type *,
  				      varray_type *);
  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);
--- 167,174 ----
  static int rewrite_and_optimize_stmt (block_stmt_iterator, varray_type *,
  				      varray_type *);
  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);
*************** static inline void set_if_valid (var_map
*** 205,211 ****
  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 rewrite_vdefs (block_stmt_iterator *, varray_type, var_map);
  
  /* Main entry point to the SSA builder.  FNDECL is the gimplified function
     to convert.
--- 205,210 ----
*************** rewrite_block (basic_block bb, tree eq_e
*** 745,751 ****
       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
--- 744,750 ----
       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
*************** rewrite_block (basic_block bb, tree eq_e
*** 777,784 ****
  
        for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
  	{
! 	  /* FIXME.  [UNSSA] After fixing the SSA->normal pass, allow
! 	     constants and copies to be propagated into PHI arguments.  */
  	  tree currdef = get_reaching_def (SSA_NAME_VAR (PHI_RESULT (phi)));
  	  add_phi_arg (phi, currdef, e);
  	}
--- 776,783 ----
  
        for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
  	{
! 	  /* FIXME.  [UNSSA] If -ftree-dominator-opts, allow constants and
! 	     copies to be propagated into PHI arguments.  */
  	  tree currdef = get_reaching_def (SSA_NAME_VAR (PHI_RESULT (phi)));
  	  add_phi_arg (phi, currdef, e);
  	}
*************** eliminate_build (elim_graph g, basic_blo
*** 1002,1007 ****
--- 1001,1010 ----
    
    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)
*************** coalesce_ssa_name (var_map map)
*** 1346,1361 ****
  	       edge, and attempt to coalesce the argument with the result.  */
  	    var = PHI_RESULT (phi);
  
! 	    /* Ignore variables that have no real references, as those
  	       don't generate code.  */
! 	    if (!var_ann (var)->has_real_refs)
  	      continue;
  
  	    x = var_to_partition (map, var);
  	    y = phi_arg_from_edge (phi, e);
  	    if (y == -1)
  	      abort ();
  	    tmp = PHI_ARG_DEF (phi, y);
  	    y = var_to_partition (map, tmp);
  	    if (x == NO_PARTITION || y == NO_PARTITION)
  	      abort ();
--- 1349,1368 ----
  	       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 ();
*************** rewrite_out_of_ssa (tree fndecl)
*** 1628,1637 ****
  
  	  get_stmt_operands (stmt);
  
- 	  ops = vdef_ops (stmt);
- 	  if (ops)
- 	    rewrite_vdefs (&si, ops, map);
- 
  	  if (TREE_CODE (stmt) == MODIFY_EXPR 
  	      && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME))
  	    is_copy = 1;
--- 1635,1640 ----
*************** rewrite_out_of_ssa (tree fndecl)
*** 1709,1760 ****
  }
  
  
- /* Rewrite virtual definitions in VDEFS from the statement pointed by
-    iterator SI_P, potentially converting them into real copy operations.  A
-    virtual definition is converted into a copy operation when the LHS of
-    the VDEF has been used as a real operand in some statement.
-    
-    This happens when variables are aliased and are referenced directly or
-    via their aliased pointers.  Converting the VDEF into a real copy
-    operation is necessary for correctly coalescing the different names when
-    two or more are live simultaneously.  */
- 
- static void
- rewrite_vdefs (block_stmt_iterator *si_p, varray_type vdefs, var_map map)
- {
-   size_t i;
- 
-   for (i = 0; i < VARRAY_ACTIVE_SIZE (vdefs); i++)
-     {
-       tree lhs, rhs, vdef = VARRAY_TREE (vdefs, i);
- 
-       if (!var_ann (SSA_NAME_VAR (VDEF_RESULT (vdef)))->has_real_refs)
- 	continue;
- 
-       lhs = var_to_partition_to_var (map, VDEF_RESULT (vdef));
-       rhs = var_to_partition_to_var (map, VDEF_OP (vdef));
- 
-       if (lhs
- 	  && rhs
- 	  && TREE_CODE (lhs) != SSA_NAME
- 	  && TREE_CODE (rhs) != SSA_NAME
- 	  && lhs != rhs)
- 	{
- 	  tree t = build (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
- 	  bsi_insert_before (si_p, t, BSI_SAME_STMT);
- 	  if (tree_ssa_dump_file && (tree_ssa_dump_flags & TDF_DETAILS))
- 	    {
- 	      fprintf (tree_ssa_dump_file, "Promoting VDEF ");
- 	      print_generic_stmt (tree_ssa_dump_file, vdef, 0);
- 	      fprintf (tree_ssa_dump_file, "into the real assignment ");
- 	      print_generic_stmt (tree_ssa_dump_file, t, 0);
- 	      fprintf (tree_ssa_dump_file, "\n");
- 	    }
- 	}
-     }
- }
- 
- 
  /* Remove edge E and remove the corresponding arguments from the PHI nodes
     in E's destination block.  Return a TREE_LIST node with all the removed
     PHI arguments.  */
--- 1712,1717 ----
*************** rewrite_and_optimize_stmt (block_stmt_it
*** 2107,2113 ****
      {
        tree val;
        tree *op_p = (tree *) VARRAY_GENERIC_PTR (uses, i);
!       rewrite_operand (op_p);
  
        /* If the operand has a known constant value or it is known to be a
  	 copy of some other variable, use the value or copy stored in
--- 2064,2070 ----
      {
        tree val;
        tree *op_p = (tree *) VARRAY_GENERIC_PTR (uses, i);
!       rewrite_operand (op_p, true);
  
        /* If the operand has a known constant value or it is known to be a
  	 copy of some other variable, use the value or copy stored in
*************** rewrite_and_optimize_stmt (block_stmt_it
*** 2140,2146 ****
  
    /* Rewrite virtual uses in the statement.  */
    for (i = 0; vuses && i < VARRAY_ACTIVE_SIZE (vuses); i++)
!     rewrite_operand (&(VARRAY_TREE (vuses, i)));
  
    /* If the statement has been modified with constant replacements,
        fold its RHS before checking for redundant computations.  */
--- 2097,2103 ----
  
    /* Rewrite virtual uses in the statement.  */
    for (i = 0; vuses && i < VARRAY_ACTIVE_SIZE (vuses); i++)
!     rewrite_operand (&(VARRAY_TREE (vuses, i)), false);
  
    /* If the statement has been modified with constant replacements,
        fold its RHS before checking for redundant computations.  */
*************** rewrite_and_optimize_stmt (block_stmt_it
*** 2196,2202 ****
        tree rhs;
  
        *def_p = make_ssa_name (*def_p, stmt);
!       register_new_def (SSA_NAME_VAR (*def_p), *def_p, block_defs_p);
  
        /* If the RHS of the assignment is a constant or another variable
  	 that may be propagated, register it in the CONST_AND_COPIES table.  */
--- 2153,2159 ----
        tree rhs;
  
        *def_p = make_ssa_name (*def_p, stmt);
!       register_new_def (SSA_NAME_VAR (*def_p), *def_p, block_defs_p, true);
  
        /* If the RHS of the assignment is a constant or another variable
  	 that may be propagated, register it in the CONST_AND_COPIES table.  */
*************** rewrite_and_optimize_stmt (block_stmt_it
*** 2213,2222 ****
    for (i = 0; vdefs && i < VARRAY_ACTIVE_SIZE (vdefs); i++)
      {
        tree vdef = VARRAY_TREE (vdefs, i);
!       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);
      }
  
    return 0;
--- 2170,2179 ----
    for (i = 0; vdefs && i < VARRAY_ACTIVE_SIZE (vdefs); i++)
      {
        tree vdef = VARRAY_TREE (vdefs, i);
!       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);
      }
  
    return 0;
*************** rewrite_stmt (block_stmt_iterator si, va
*** 2279,2326 ****
    for (i = 0; uses && i < VARRAY_ACTIVE_SIZE (uses); i++)
      {
        tree *op_p = (tree *) VARRAY_GENERIC_PTR (uses, i);
!       rewrite_operand (op_p);
      }
  
    /* Rewrite virtual uses in the statement.  */
    for (i = 0; vuses && i < VARRAY_ACTIVE_SIZE (vuses); i++)
!     rewrite_operand (&(VARRAY_TREE (vuses, i)));
  
    /* Step 2.  Register the statement's DEF and VDEF operands.  */
    if (def_p)
      {
        *def_p = make_ssa_name (*def_p, stmt);
!       register_new_def (SSA_NAME_VAR (*def_p), *def_p, block_defs_p);
      }
  
    /* Register new virtual definitions made by the statement.  */
    for (i = 0; vdefs && i < VARRAY_ACTIVE_SIZE (vdefs); i++)
      {
        tree vdef = VARRAY_TREE (vdefs, i);
!       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 the USED bit in the annotation for T.  */
  
  void
  set_is_used (tree t)
  {
    t = get_base_symbol (t);
-   if (TREE_CODE (t) == SSA_NAME)
-     t = SSA_NAME_VAR (t);
    var_ann (t)->used = 1;
  }
  
  
  /* Replace the operand pointed by OP_P with its immediate reaching
!    definition.  */
  
  static inline void
! rewrite_operand (tree *op_p)
  {
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*op_p) == SSA_NAME)
--- 2236,2282 ----
    for (i = 0; uses && i < VARRAY_ACTIVE_SIZE (uses); i++)
      {
        tree *op_p = (tree *) VARRAY_GENERIC_PTR (uses, i);
!       rewrite_operand (op_p, true);
      }
  
    /* Rewrite virtual uses in the statement.  */
    for (i = 0; vuses && i < VARRAY_ACTIVE_SIZE (vuses); i++)
!     rewrite_operand (&(VARRAY_TREE (vuses, i)), false);
  
    /* Step 2.  Register the statement's DEF and VDEF operands.  */
    if (def_p)
      {
        *def_p = make_ssa_name (*def_p, stmt);
!       register_new_def (SSA_NAME_VAR (*def_p), *def_p, block_defs_p, true);
      }
  
    /* Register new virtual definitions made by the statement.  */
    for (i = 0; vdefs && i < VARRAY_ACTIVE_SIZE (vdefs); i++)
      {
        tree vdef = VARRAY_TREE (vdefs, i);
!       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);
      }
  }
  
+ 
  /* Set the USED bit in the annotation for T.  */
  
  void
  set_is_used (tree t)
  {
    t = get_base_symbol (t);
    var_ann (t)->used = 1;
  }
  
  
  /* Replace the operand pointed by OP_P with its immediate reaching
!    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)
*************** rewrite_operand (tree *op_p)
*** 2328,2341 ****
  #endif
  
    *op_p = get_reaching_def (*op_p);
  }
  
  
  /* Register DEF to be a new definition for variable VAR and push VAR's
!    current reaching definition into the stack pointed by BLOCK_DEFS_P.  */
  
  static void
! register_new_def (tree var, tree def, varray_type *block_defs_p)
  {
    tree currdef = get_value_for (var, currdefs);
  
--- 2284,2301 ----
  #endif
  
    *op_p = get_reaching_def (*op_p);
+   if (is_real_operand)
+     SSA_NAME_HAS_REAL_REFS (*op_p) = true;
  }
  
  
  /* Register DEF to be a new definition for variable VAR and push VAR's
!    current reaching definition into the stack pointed by BLOCK_DEFS_P.
!    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);
  
*************** register_new_def (tree var, tree def, va
*** 2354,2359 ****
--- 2314,2322 ----
  
    /* 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;
  }
  
  
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.263.2.37
diff -d -c -p -r1.263.2.37 tree.c
*** tree.c	12 Jun 2003 21:31:08 -0000	1.263.2.37
--- tree.c	1 Jul 2003 03:43:43 -0000
*************** make_phi_node (var, len)
*** 5176,5182 ****
  /* Return an SSA_NAME node for variable VAR defined in statement STMT.
     STMT may be an empty statement for artificial references (e.g., default
     definitions created when a variable is used without a preceding
!    definition.  See currdef_for.)  */
  
  tree
  make_ssa_name (var, stmt)
--- 5176,5182 ----
  /* Return an SSA_NAME node for variable VAR defined in statement STMT.
     STMT may be an empty statement for artificial references (e.g., default
     definitions created when a variable is used without a preceding
!    definition).  */
  
  tree
  make_ssa_name (var, stmt)
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.71
diff -d -c -p -r1.342.2.71 tree.h
*** tree.h	1 Jul 2003 02:04:51 -0000	1.342.2.71
--- tree.h	1 Jul 2003 03:43:43 -0000
*************** struct tree_vec GTY(())
*** 848,854 ****
  /* Non-zero if NODE is an emtpy statement (NOP_EXPR <0>).  */
  #define IS_EMPTY_STMT(NODE)	(TREE_CODE (NODE) == NOP_EXPR \
  				 && VOID_TYPE_P (TREE_TYPE (NODE)) \
! 				 && TREE_OPERAND (NODE, 0) == size_zero_node)
  
  /* In a SAVE_EXPR node.  */
  #define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1)
--- 848,854 ----
  /* Non-zero if NODE is an emtpy statement (NOP_EXPR <0>).  */
  #define IS_EMPTY_STMT(NODE)	(TREE_CODE (NODE) == NOP_EXPR \
  				 && VOID_TYPE_P (TREE_TYPE (NODE)) \
! 				 && integer_zerop (TREE_OPERAND (NODE, 0)))
  
  /* In a SAVE_EXPR node.  */
  #define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1)
*************** struct tree_exp GTY(())
*** 978,989 ****
--- 978,1008 ----
  #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;
+ 
+   /* _DECL wrapped by this SSA name.  */
    tree var;
+ 
+   /* Statement that creates this SSA name.  */
    tree def_stmt;
+ 
+   /* SSA version number.  */
    unsigned int version;
  };
  



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