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]

[patch] tree-ssa-copy.c: Clean up copy_prop_visit_assignment.


Hi,

Attached is a patch to clean up copy_prop_visit_assignment.

copy_prop_visit_assignment tries to fold a COND_EXPR_COND and find a
taken edge.

The current code proceeds like so:

1. Check to see if we have at least one SSA_NAME in COND_EXPR_COND.

2. Replace each SSA_NAME with what get_last_copy_of returns.

3. Check to see if we have two identical SSA_NAMEs on both sides of a
   comparison.

4. Fold COND_EXPR_COND and determine a taken edge (if possible).

5. Restore operands.

This is really long winded.  In particular, I don't like

1. use of malloc,

2. use of SET_USE, which involves maintenance of immediate uses, or

3. three uses of FOR_EACH_SSA_USE_OPERAND with one of them hidden in
   NUM_SSA_OPERANDS.

This patch simplifies the process by doing replacement and folding in
a nondestructive manner.  Thanks to fold_binary, we don't have to have
a complete tree node for a comparison.  We just have to have a
comparison's operands and a comparison code.

The only externally visible change is that the dump message now prints
out the original COND_EXPR_COND, not the one with its operands
replaced.  I don't think this is too big a deal, but if this bothers,
let me know.

Tested on i686-pc-linux-gnu.  OK to apply?

Kazu Hirata

2005-05-16  Kazu Hirata  <kazu@cs.umass.edu>

	* tree-ssa-copy.c (copy_prop_visit_assignment): Clean up by
	folding a COND_EXPR_COND in a nondestructive manner.

Index: tree-ssa-copy.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-copy.c,v
retrieving revision 2.29
diff -C5 -d -p -r2.29 tree-ssa-copy.c
*** tree-ssa-copy.c	3 May 2005 12:19:43 -0000	2.29
--- tree-ssa-copy.c	15 May 2005 20:33:14 -0000
*************** copy_prop_visit_assignment (tree stmt, t
*** 592,652 ****
  static enum ssa_prop_result
  copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
  {
    enum ssa_prop_result retval;
    tree cond;
-   use_operand_p use_p;
-   ssa_op_iter iter;
-   unsigned num;
- 
  
    cond = COND_EXPR_COND (stmt);
    retval = SSA_PROP_VARYING;
-   num = NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
  
    /* The only conditionals that we may be able to compute statically
!      are predicates involving at least one SSA_NAME.  */
    if (COMPARISON_CLASS_P (cond)
!       && num >= 1)
      {
!       unsigned i;
!       tree *orig;
! 
!       /* Save the original operands.  */
!       orig = xmalloc (sizeof (tree) * num);
!       i = 0;
!       FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
! 	{
! 	  tree use = USE_FROM_PTR (use_p);
! 	  orig[i++] = use;
! 	  SET_USE (use_p, get_last_copy_of (use));
! 	}
  
        /* See if we can determine the predicate's value.  */
        if (dump_file && (dump_flags & TDF_DETAILS))
  	{
  	  fprintf (dump_file, "Trying to determine truth value of ");
  	  fprintf (dump_file, "predicate ");
  	  print_generic_stmt (dump_file, cond, 0);
  	}
  
!       /* We can fold COND only and get a useful result only when we
! 	 have the same SSA_NAME on both sides of a comparison
! 	 operator.  */
!       if (TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
! 	  && TREE_OPERAND (cond, 0) == TREE_OPERAND (cond, 1))
  	{
! 	  *taken_edge_p = find_taken_edge (bb_for_stmt (stmt), fold (cond));
! 	  if (*taken_edge_p)
! 	    retval = SSA_PROP_INTERESTING;
  	}
- 
-       /* Restore the original operands.  */
-       i = 0;
-       FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
- 	SET_USE (use_p, orig[i++]);
-       free (orig);
      }
  
    if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
      fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
  	     (*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);
--- 592,636 ----
  static enum ssa_prop_result
  copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
  {
    enum ssa_prop_result retval;
    tree cond;
  
    cond = COND_EXPR_COND (stmt);
    retval = SSA_PROP_VARYING;
  
    /* The only conditionals that we may be able to compute statically
!      are predicates involving two SSA_NAMEs.  */
    if (COMPARISON_CLASS_P (cond)
!       && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
!       && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
      {
!       tree op0 = get_last_copy_of (TREE_OPERAND (cond, 0));
!       tree op1 = get_last_copy_of (TREE_OPERAND (cond, 1));
  
        /* See if we can determine the predicate's value.  */
        if (dump_file && (dump_flags & TDF_DETAILS))
  	{
  	  fprintf (dump_file, "Trying to determine truth value of ");
  	  fprintf (dump_file, "predicate ");
  	  print_generic_stmt (dump_file, cond, 0);
  	}
  
!       /* We can fold COND and get a useful result only when we have
! 	 the same SSA_NAME on both sides of a comparison operator.  */
!       if (op0 == op1)
  	{
! 	  tree folded_cond = fold_binary (TREE_CODE (cond), boolean_type_node,
! 					  op0, op1);
! 	  if (folded_cond)
! 	    {
! 	      basic_block bb = bb_for_stmt (stmt);
! 	      *taken_edge_p = find_taken_edge (bb, folded_cond);
! 	      if (*taken_edge_p)
! 		retval = SSA_PROP_INTERESTING;
! 	    }
  	}
      }
  
    if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
      fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
  	     (*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);


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