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] Optimize through more typecasts


Typecasts are still getting in the way of the optimizers.  This change
detects a few more cases where typecasts can be ignored.

When EQ_EXPR_VALUE has the form

x = <const>

We walk back to x's definition site and see if it has the form:

x = (type) y;

If the constant in EQ_EXPR_VALUE is representable in Y's type and has
the same value, then we can enter y = <const> into CONST_AND_COPIES.

Note that such equivalences die at the same time the EQ_EXPR_VALUE 
equivalence dies.  FWIW, the most common case is <const> is zero  :-)

We were also failing to recognize that 

(type) &z

is always nonzero.  Opps.

Anyway, these changes fix a couple of the tree-ssa optimization tests.


	* tree-ssa-dom.c (optimize_block): Create infrastructure for
	tracking const_and_copies equivalences which disappear when
	we leave the current block.  Use it for equivalences created
	by EQ_EXPR_VALUE.  Follow use-def chains for EQ_EXPR_VALUE
	equivalences and see if certain NOP_EXPRs can be ignored
	to create a block-local equivalence for const_and_copies.
	(optimize_stmt): Do not get confused by a cast of the return
	value from alloca or the address of a non-weak decl.


Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.46
diff -c -3 -p -r1.1.2.46 tree-ssa-dom.c
*** tree-ssa-dom.c	24 Sep 2003 08:04:05 -0000	1.1.2.46
--- tree-ssa-dom.c	25 Sep 2003 05:21:15 -0000
*************** optimize_block (basic_block bb, tree par
*** 331,341 ****
                  sbitmap vars_to_rename, bool *cfg_altered)
  {
    varray_type block_avail_exprs;
    varray_type stmts_to_rescan;
    bitmap children;
    unsigned long i;
    block_stmt_iterator si;
-   tree prev_value = NULL_TREE;
    tree eq_expr_value = NULL_TREE;
    edge e;
    tree phi;
--- 331,341 ----
                  sbitmap vars_to_rename, bool *cfg_altered)
  {
    varray_type block_avail_exprs;
+   varray_type block_const_and_copies;
    varray_type stmts_to_rescan;
    bitmap children;
    unsigned long i;
    block_stmt_iterator si;
    tree eq_expr_value = NULL_TREE;
    edge e;
    tree phi;
*************** optimize_block (basic_block bb, tree par
*** 349,354 ****
--- 349,355 ----
       AVAIL_EXPRS table.  This stack is used to know which expressions
       to remove from the table.  */
    VARRAY_TREE_INIT (block_avail_exprs, 20, "block_avail_exprs");
+   VARRAY_TREE_INIT (block_const_and_copies, 2, "block_const_and_copies");
    VARRAY_TREE_INIT (stmts_to_rescan, 20, "stmts_to_rescan");
  
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** optimize_block (basic_block bb, tree par
*** 432,442 ****
       VALUE while re-writing the THEN arm of a COND_EXPR.  */
    if (eq_expr_value)
      {
!       prev_value = get_value_for (TREE_OPERAND (eq_expr_value, 0),
! 				  const_and_copies);
!       set_value_for (TREE_OPERAND (eq_expr_value, 0),
! 		     TREE_OPERAND (eq_expr_value, 1),
! 		     const_and_copies);
      }
  
    /* PHI nodes can create equivalences too.
--- 433,488 ----
       VALUE while re-writing the THEN arm of a COND_EXPR.  */
    if (eq_expr_value)
      {
!       tree dest = TREE_OPERAND (eq_expr_value, 0);
!       tree src = TREE_OPERAND (eq_expr_value, 1);
!       tree prev_value = get_value_for (dest, const_and_copies);
! 
!       set_value_for (dest, src, const_and_copies);
! 
!       /* Record the destination and its previous value so that we can
! 	 reset them as we leave this block.  */
!       VARRAY_PUSH_TREE (block_const_and_copies, dest);
!       VARRAY_PUSH_TREE (block_const_and_copies, prev_value);
! 
!       /* If the new value is a constant, then look at DEST's defining
! 	 statement.  If DEST was defined as the result of a typecast,
! 	 we may be able to record additional equivalences.  */
!       if (TREE_CONSTANT (src))
! 	{
! 	  tree def_stmt = SSA_NAME_DEF_STMT (dest);
! 
! 	  /* DEST might have been a parameter, so first make sure it
! 	     was defined by a MODIFY_EXPR.  */
! 	  if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR)
! 	    {
! 	      tree def_rhs = TREE_OPERAND (def_stmt, 1);
! 
! 	      /* Now make sure the RHS of the MODIFY_EXPR is a typecast.  */
! 	      if (TREE_CODE (def_rhs) == NOP_EXPR
! 		  && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME)
! 		{
! 		  tree def_rhs_inner = TREE_OPERAND (def_rhs, 0);
! 		  tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner);
! 		  tree new;
! 
! 		  /* What we want to prove is that if we convert SRC to
! 		     the type of the object inside the NOP_EXPR that the
! 		     result is still equivalent to SRC.  */
! 		  new = fold (build1 (NOP_EXPR, def_rhs_inner_type, src));
! 		  if (is_gimple_val (new)
! 		      && integer_onep (fold (build (EQ_EXPR, boolean_type_node,
! 						    new, src))))
! 		    {
! 		      prev_value = get_value_for (def_rhs_inner,
! 						  const_and_copies);
! 		      set_value_for (def_rhs_inner, new, const_and_copies);
! 
! 		      VARRAY_PUSH_TREE (block_const_and_copies, def_rhs_inner);
! 		      VARRAY_PUSH_TREE (block_const_and_copies, prev_value);
! 		    }
! 		}
! 	    }
! 	}
      }
  
    /* PHI nodes can create equivalences too.
*************** optimize_block (basic_block bb, tree par
*** 664,677 ****
      }
  
    /* Also remove equivalences created by EQ_EXPR_VALUE.  */
!   if (eq_expr_value)
      {
        struct var_value_d vm;
!       vm.var = TREE_OPERAND (eq_expr_value, 0);
        if (prev_value)
!         set_value_for (vm.var, prev_value, const_and_copies);
        else
!         htab_remove_elt (const_and_copies, &vm);
      }
  
    /* Re-scan operands in all statements that may have had new symbols
--- 710,730 ----
      }
  
    /* Also remove equivalences created by EQ_EXPR_VALUE.  */
!   while (VARRAY_ACTIVE_SIZE (block_const_and_copies) > 0)
      {
+       tree prev_value, dest;
        struct var_value_d vm;
! 
!       prev_value = VARRAY_TOP_TREE (block_const_and_copies);
!       VARRAY_POP (block_const_and_copies);
!       dest = VARRAY_TOP_TREE (block_const_and_copies);
!       VARRAY_POP (block_const_and_copies);
! 
!       vm.var = dest;
        if (prev_value)
! 	set_value_for (vm.var, prev_value, const_and_copies);
        else
! 	htab_remove_elt (const_and_copies, &vm);
      }
  
    /* Re-scan operands in all statements that may have had new symbols
*************** optimize_stmt (block_stmt_iterator si, v
*** 1331,1340 ****
  	 is never zero.  */
        if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
  	{
  	  if (alloca_call_p (rhs)
! 	      || (TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
! 		  && DECL_P (TREE_OPERAND (TREE_OPERAND (stmt, 1), 0))
! 		  && ! DECL_WEAK (TREE_OPERAND (TREE_OPERAND (stmt, 1), 0))))
  	    {
  	      tree cond;
  
--- 1384,1398 ----
  	 is never zero.  */
        if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
  	{
+ 	  /* Strip away any NOP_EXPRs since they do not effect this
+ 	     equivalence.  */
+ 	  while (TREE_CODE (rhs) == NOP_EXPR)
+ 	    rhs = TREE_OPERAND (rhs, 0);
+ 
  	  if (alloca_call_p (rhs)
! 	      || (TREE_CODE (rhs) == ADDR_EXPR
! 		  && DECL_P (TREE_OPERAND (rhs, 0))
! 		  && ! DECL_WEAK (TREE_OPERAND (rhs, 0))))
  	    {
  	      tree cond;
  





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