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 ] cprop into PHI nodes, avoid optimizing unreachable code


This doesn't fix any of the failures in the tree-ssa tests, but is a
critical hunk of infrastructure for a following set of changes (which
will fix a half-dozen or so failures).

This patch does basically three things.

  1. We copy propagate values into PHI nodes [ This nearly makes
     tree-ssa-copyprop useless. ]

  2. If a COND_EXPR is proven to always go to the same arm, then we remove
     edges which reach the other arm.

  3. If a block has no incoming edges, then it is unreachable and we
     don't bother optimizing it.

Bootstrapped, regression tested, etc.

	* tree-ssa-dom.c (optimize_block): Propagate values into PHI nodes.
	Do not optimize a block which has become unreachable.
	If a COND_EXPR has a compile-time constant condition, then remove
	outgoing from the COND_EXPR which can not execute.

Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 tree-ssa-dom.c
*** tree-ssa-dom.c	16 Jul 2003 22:02:16 -0000	1.1.2.4
--- tree-ssa-dom.c	17 Jul 2003 18:03:56 -0000
*************** optimize_block (basic_block bb, tree par
*** 168,173 ****
--- 168,175 ----
    block_stmt_iterator si;
    tree prev_value = NULL_TREE;
    tree eq_expr_value = NULL_TREE;
+   edge e;
+   tree phi;
  
    /* Initialize the local stacks.
       
*************** optimize_block (basic_block bb, tree par
*** 207,212 ****
--- 209,242 ----
    for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
      optimize_stmt (si, &block_avail_exprs);
  
+   /* Propagate known constants/copies into PHI node alternatives for
+      successors of this block.  */
+   for (e = bb->succ; e; e = e->succ_next)
+     {
+       for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
+ 	{
+ 	  int i;
+ 
+ 	  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ 	    {
+ 	      tree new;
+ 	      if (PHI_ARG_EDGE (phi, i) == e)
+ 		{
+ 		  tree *orig_p = &PHI_ARG_DEF (phi, i);
+ 
+ 		  /* FIXME.  We should be able to propagate constants into
+ 		     PHI nodes in the not too distant future.  */
+ 		  new = get_value_for (*orig_p, const_and_copies);
+ 		  if (new
+ 		      && TREE_CODE (new) == SSA_NAME
+ 		      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new)
+ 		      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*orig_p))
+ 		    *orig_p = new;
+ 		}
+ 	    }
+ 	}
+     }
+ 
    /* Recursively optimize the dominator children of BB.  */
    children = dom_children (bb);
    if (children)
*************** optimize_block (basic_block bb, tree par
*** 215,227 ****
  	{
  	  tree last = last_stmt (bb);
  	  EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! 	    optimize_block (BASIC_BLOCK (i), last,
! 			    BASIC_BLOCK (i)->pred->flags));
  	}
        else
  	{
  	  EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! 	    optimize_block (BASIC_BLOCK (i), NULL_TREE, 0));
  	}
      }
  
--- 245,270 ----
  	{
  	  tree last = last_stmt (bb);
  	  EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! 	    {
! 	      basic_block dest = BASIC_BLOCK (i);
! 
! 	      /* The destination block may have become unreachable, in
! 		 which case there's no point in optimizing it.  */
! 	      if (dest->pred)
! 		optimize_block (dest, last, dest->pred->flags);
! 	    });
  	}
        else
  	{
  	  EXECUTE_IF_SET_IN_BITMAP (children, 0, i,
! 	    {
! 	      basic_block dest = BASIC_BLOCK (i);
! 
! 	      /* The destination block may have become unreachable, in
! 		 which case there's no point in optimizing it. */
! 	      if (dest->pred)
! 		optimize_block (dest, NULL_TREE, 0);
! 	    });
  	}
      }
  
*************** optimize_stmt (block_stmt_iterator si, v
*** 470,475 ****
--- 513,542 ----
  	    set_value_for (*def_p, rhs, const_and_copies);
  	}
      }
+ 
+   /* If STMT is a COND_EXPR and it was modified, then we may know
+      where it goes.  In which case we can remove some edges, simplify
+      some PHI nodes, maybe even avoid optimizing some blocks completely,
+      etc.  */
+   if (TREE_CODE (stmt) == COND_EXPR && ann->modified)
+     {
+       basic_block bb = bb_for_stmt (stmt);
+       edge taken_edge = find_taken_edge (bb, TREE_OPERAND (stmt, 0));
+ 
+       if (taken_edge)
+ 	{
+ 	  edge e, next;
+ 	  /* The other edges leaving this block are not executable
+ 	     and can be removed.  */
+ 	  for (e = bb_for_stmt (stmt)->succ; e; e = next)
+ 	    {
+ 	      next = e->succ_next;
+ 	      if (e != taken_edge)
+ 		ssa_remove_edge (e);
+ 	   }
+ 	}
+     }
+ 
  }
  
  /* Hashing and equality functions for VAR_VALUE_D.  */




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