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][alias-improvements] Fix CCP regressions, fix PR38180


This fixes the CCP regressions on the alias-improvements branch which
were because the VOP related checks in CCP are done wrong, so with
VOPs enabled during early optimization we miss some propagations
(and we did so on the trunk for later passes).  I took the opportunity
to also fix PR38180 on the way.

Bootstrapped and tested on x86_64-unknown-linux-gnu, installed on the
branch.  The remaining ssa-ccp-2.c pieces that fail are FRE related.

Richard.

2008-11-26  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/38180
	* tree-ssa-ccp.c (get_default_value): Simplify.
	(likely_value): Likewise.
	(surely_varying_stmt_p): Properly handle VOP case.
	(ccp_initialize): Likewise.
	(ccp_fold): Handle propagating through *&.
	(fold_const_aggregate_ref): Also handle decls.

	* gcc.dg/tree-ssa/ssa-ccp-24.c: New testcase.

Index: alias-improvements/gcc/tree-ssa-ccp.c
===================================================================
*** alias-improvements.orig/gcc/tree-ssa-ccp.c	2008-11-25 21:28:30.000000000 +0100
--- alias-improvements/gcc/tree-ssa-ccp.c	2008-11-26 12:05:41.000000000 +0100
*************** get_default_value (tree var)
*** 318,369 ****
  {
    tree sym = SSA_NAME_VAR (var);
    prop_value_t val = { UNINITIALIZED, NULL_TREE };
!   tree cst_val;
!   
!   if (!is_gimple_reg (var))
!     {
!       /* Short circuit for regular CCP.  We are not interested in any
! 	 non-register when DO_STORE_CCP is false.  */
!       val.lattice_val = VARYING;
!     }
!   else if ((cst_val = get_symbol_constant_value (sym)) != NULL_TREE)
      {
!       /* Globals and static variables declared 'const' take their
! 	 initial value.  */
!       val.lattice_val = CONSTANT;
!       val.value = cst_val;
      }
!   else
!     {
!       gimple stmt = SSA_NAME_DEF_STMT (var);
! 
!       if (gimple_nop_p (stmt))
  	{
! 	  /* Variables defined by an empty statement are those used
! 	     before being initialized.  If VAR is a local variable, we
! 	     can assume initially that it is UNDEFINED, otherwise we must
! 	     consider it VARYING.  */
! 	  if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
! 	    val.lattice_val = UNDEFINED;
! 	  else
! 	    val.lattice_val = VARYING;
! 	}
!       else if (is_gimple_assign (stmt)
!                /* Value-returning GIMPLE_CALL statements assign to
!                   a variable, and are treated similarly to GIMPLE_ASSIGN.  */
!                || (is_gimple_call (stmt)
!                    && gimple_call_lhs (stmt) != NULL_TREE)
! 	       || gimple_code (stmt) == GIMPLE_PHI)
!         {
! 	  /* Any other variable defined by an assignment or a PHI node
! 	     is considered UNDEFINED.  */
! 	  val.lattice_val = UNDEFINED;
  	}
        else
! 	{
! 	  /* Otherwise, VAR will never take on a constant value.  */
! 	  val.lattice_val = VARYING;
! 	}
      }
  
    return val;
--- 318,362 ----
  {
    tree sym = SSA_NAME_VAR (var);
    prop_value_t val = { UNINITIALIZED, NULL_TREE };
!   gimple stmt;
! 
!   stmt = SSA_NAME_DEF_STMT (var);
! 
!   if (gimple_nop_p (stmt))
      {
!       /* Variables defined by an empty statement are those used
! 	 before being initialized.  If VAR is a local variable, we
! 	 can assume initially that it is UNDEFINED, otherwise we must
! 	 consider it VARYING.  */
!       if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
! 	val.lattice_val = UNDEFINED;
!       else
! 	val.lattice_val = VARYING;
      }
!   else if (is_gimple_assign (stmt)
! 	   /* Value-returning GIMPLE_CALL statements assign to
! 	      a variable, and are treated similarly to GIMPLE_ASSIGN.  */
! 	   || (is_gimple_call (stmt)
! 	       && gimple_call_lhs (stmt) != NULL_TREE)
! 	   || gimple_code (stmt) == GIMPLE_PHI)
!     {
!       tree cst;
!       if (gimple_assign_single_p (stmt)
! 	  && DECL_P (gimple_assign_rhs1 (stmt))
! 	  && (cst = get_symbol_constant_value (gimple_assign_rhs1 (stmt))))
  	{
! 	  val.lattice_val = CONSTANT;
! 	  val.value = cst;
  	}
        else
! 	/* Any other variable defined by an assignment or a PHI node
! 	   is considered UNDEFINED.  */
! 	val.lattice_val = UNDEFINED;
!     }
!   else
!     {
!       /* Otherwise, VAR will never take on a constant value.  */
!       val.lattice_val = VARYING;
      }
  
    return val;
*************** likely_value (gimple stmt)
*** 499,504 ****
--- 492,498 ----
    bool has_constant_operand, has_undefined_operand, all_undefined_operands;
    tree use;
    ssa_op_iter iter;
+   unsigned i;
  
    enum gimple_code code = gimple_code (stmt);
  
*************** likely_value (gimple stmt)
*** 514,546 ****
    if (gimple_has_volatile_ops (stmt))
      return VARYING;
  
-   /* If we are not doing store-ccp, statements with loads
-      and/or stores will never fold into a constant.  */
-   if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
-     return VARYING;
- 
-   /* Note that only a GIMPLE_SINGLE_RHS assignment can satisfy
-      is_gimple_min_invariant, so we do not consider calls or
-      other forms of assignment.  */
-   if (gimple_assign_single_p (stmt)
-       && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
-     return CONSTANT;
- 
-   if (code == GIMPLE_COND
-       && is_gimple_min_invariant (gimple_cond_lhs (stmt))
-       && is_gimple_min_invariant (gimple_cond_rhs (stmt)))
-     return CONSTANT;
- 
-   if (code == GIMPLE_SWITCH
-       && is_gimple_min_invariant (gimple_switch_index (stmt)))
-     return CONSTANT;
- 
    /* Arrive here for more complex cases.  */
- 
    has_constant_operand = false;
    has_undefined_operand = false;
    all_undefined_operands = true;
!   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
      {
        prop_value_t *val = get_value (use);
  
--- 508,518 ----
    if (gimple_has_volatile_ops (stmt))
      return VARYING;
  
    /* Arrive here for more complex cases.  */
    has_constant_operand = false;
    has_undefined_operand = false;
    all_undefined_operands = true;
!   FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
      {
        prop_value_t *val = get_value (use);
  
*************** likely_value (gimple stmt)
*** 553,558 ****
--- 525,541 ----
  	has_constant_operand = true;
      }
  
+   /* There may be constants in regular rhs operands.  */
+   for (i = is_gimple_call (stmt) + gimple_has_lhs (stmt);
+        i < gimple_num_ops (stmt); ++i)
+     {
+       tree op = gimple_op (stmt, i);
+       if (!op || TREE_CODE (op) == SSA_NAME)
+ 	continue;
+       if (is_gimple_min_invariant (op))
+ 	has_constant_operand = true;
+     }
+ 
    /* If the operation combines operands like COMPLEX_EXPR make sure to
       not mark the result UNDEFINED if only one part of the result is
       undefined.  */
*************** likely_value (gimple stmt)
*** 583,593 ****
    if (has_undefined_operand)
      return VARYING;
  
    if (has_constant_operand
!       /* We do not consider virtual operands here -- load from read-only
! 	 memory may have only VARYING virtual operands, but still be
! 	 constant.  */
!       || ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
      return CONSTANT;
  
    return VARYING;
--- 566,576 ----
    if (has_undefined_operand)
      return VARYING;
  
+   /* We do not consider virtual operands here -- load from read-only
+      memory may have only VARYING virtual operands, but still be
+      constant.  */
    if (has_constant_operand
!       || gimple_references_memory_p (stmt))
      return CONSTANT;
  
    return VARYING;
*************** surely_varying_stmt_p (gimple stmt)
*** 603,611 ****
    if (gimple_has_volatile_ops (stmt))
      return true;
  
-   if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
-     return true;
- 
    /* If it is a call and does not return a value or is not a
       builtin and not an indirect call, it is varying.  */
    if (is_gimple_call (stmt))
--- 586,591 ----
*************** surely_varying_stmt_p (gimple stmt)
*** 617,622 ****
--- 597,606 ----
  	return true;
      }
  
+   /* Any other store operation is not interesting.  */
+   else if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
+     return true;
+ 
    /* Anything other than assignments and conditional jumps are not
       interesting for CCP.  */
    if (gimple_code (stmt) != GIMPLE_ASSIGN
*************** ccp_initialize (void)
*** 655,664 ****
  	      /* If the statement will not produce a constant, mark
  		 all its outputs VARYING.  */
  	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
! 		{
! 		  if (is_varying)
! 		    set_value_varying (def);
! 		}
  	    }
            prop_set_simulate_again (stmt, !is_varying);
  	}
--- 639,645 ----
  	      /* If the statement will not produce a constant, mark
  		 all its outputs VARYING.  */
  	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
! 		set_value_varying (def);
  	    }
            prop_set_simulate_again (stmt, !is_varying);
  	}
*************** ccp_fold (gimple stmt)
*** 947,952 ****
--- 928,943 ----
  			return fold_unary (VIEW_CONVERT_EXPR,
  					   TREE_TYPE (rhs), val->value);
  		    }
+ 		  else if (TREE_CODE (rhs) == INDIRECT_REF
+ 			   && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ 		    {
+ 		      prop_value_t *val = get_value (TREE_OPERAND (rhs, 0));
+ 		      if (val->lattice_val == CONSTANT
+ 			  && TREE_CODE (val->value) == ADDR_EXPR
+ 			  && useless_type_conversion_p (TREE_TYPE (rhs),
+ 							TREE_TYPE (TREE_TYPE (val->value))))
+ 			rhs = TREE_OPERAND (val->value, 0);
+ 		    }
  		  return fold_const_aggregate_ref (rhs);
  		}
                else if (kind == tcc_declaration)
*************** fold_const_aggregate_ref (tree t)
*** 1151,1156 ****
--- 1142,1150 ----
    unsigned HOST_WIDE_INT cnt;
    tree cfield, cval;
  
+   if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration)
+     return get_symbol_constant_value (t);
+ 
    switch (TREE_CODE (t))
      {
      case ARRAY_REF:
Index: alias-improvements/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-24.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- alias-improvements/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-24.c	2008-11-26 12:10:38.000000000 +0100
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-ccp1" } */
+ 
+ static const int x;
+ int foo()
+ {
+   const int *p = &x;
+   int y = *p;
+   return y + 1;
+ }
+ 
+ static const int x2[3] = { 1, 0, 2 };
+ int bar()
+ {
+   int i = 1;
+   const int *p = &x2[i];
+   int y = *p;
+   return y + 1;
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "return 1;" 2 "ccp1" } } */
+ /* { dg-final { cleanup-tree-dump "ccp1" } } */
+ 


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