public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR65650 (1/n in merging CCP and copyprop)
@ 2015-04-02  9:16 Richard Biener
  2015-04-21 12:51 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Biener @ 2015-04-02  9:16 UTC (permalink / raw)
  To: gcc-patches


The following makes CCP track copies which avoids pass ordering
issues between CCP and copyprop as seen from the testcase.

Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1.

For stage1 I'd like to get rid of copyprop completely, a 2nd patch
in the series will remove the copyprop instances immediately
preceeding/following CCP.

CCP needs some TLC and I'm going to apply that during stage1.

Thanks,
Richard.

2015-04-02  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/65650
	* tree-ssa-ccp.c (valid_lattice_transition): Allow lattice
	transitions involving copies.
	(set_lattice_value): Adjust for copy lattice state.
	(ccp_lattice_meet): Do not merge UNDEFINED and a copy to the copy.
	(bit_value_unop): Adjust what we treat as varying mask.
	(bit_value_binop): Likewise.
	(bit_value_assume_aligned): Likewise.
	(evaluate_stmt): When we simplified to a SSA name record a copy
	instead of dropping to varying.
	(visit_assignment): Simplify.

	* gimple-match.h (gimple_simplify): Add another callback.
	* gimple-fold.c (fold_stmt_1): Adjust caller.
	(gimple_fold_stmt_to_constant_1): Likewise - pass valueize
	for the 2nd callback.
	* gimple-match-head.c (gimple_simplify): Add a callback that is
	used to valueize the stmt operands and use it that way.

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

Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c.orig	2015-04-01 15:13:46.424457049 +0200
--- gcc/tree-ssa-ccp.c	2015-04-01 16:33:50.194715581 +0200
*************** valid_lattice_transition (ccp_prop_value
*** 439,444 ****
--- 439,455 ----
  
    /* Now both lattice values are CONSTANT.  */
  
+   /* Allow arbitrary copy changes as we might look through PHI <a_1, ...>
+      when only a single copy edge is executable.  */
+   if (TREE_CODE (old_val.value) == SSA_NAME
+       && TREE_CODE (new_val.value) == SSA_NAME)
+     return true;
+ 
+   /* Allow transitioning from a constant to a copy.  */
+   if (is_gimple_min_invariant (old_val.value)
+       && TREE_CODE (new_val.value) == SSA_NAME)
+     return true;
+ 
    /* Allow transitioning from PHI <&x, not executable> == &x
       to PHI <&x, &y> == common alignment.  */
    if (TREE_CODE (old_val.value) != INTEGER_CST
*************** set_lattice_value (tree var, ccp_prop_va
*** 527,535 ****
       caller that this was a non-transition.  */
    if (old_val->lattice_val != new_val.lattice_val
        || (new_val.lattice_val == CONSTANT
! 	  && TREE_CODE (new_val.value) == INTEGER_CST
! 	  && (TREE_CODE (old_val->value) != INTEGER_CST
! 	      || new_val.mask != old_val->mask)))
      {
        /* ???  We would like to delay creation of INTEGER_CSTs from
  	 partially constants here.  */
--- 538,547 ----
       caller that this was a non-transition.  */
    if (old_val->lattice_val != new_val.lattice_val
        || (new_val.lattice_val == CONSTANT
! 	  && (TREE_CODE (new_val.value) != TREE_CODE (old_val->value)
! 	      || simple_cst_equal (new_val.value, old_val->value) != 1
! 	      || (TREE_CODE (new_val.value) == INTEGER_CST
! 		  && new_val.mask != old_val->mask))))
      {
        /* ???  We would like to delay creation of INTEGER_CSTs from
  	 partially constants here.  */
*************** ccp_finalize (void)
*** 958,969 ****
  static void
  ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
  {
!   if (val1->lattice_val == UNDEFINED)
      {
        /* UNDEFINED M any = any   */
        *val1 = *val2;
      }
!   else if (val2->lattice_val == UNDEFINED)
      {
        /* any M UNDEFINED = any
           Nothing to do.  VAL1 already contains the value we want.  */
--- 970,989 ----
  static void
  ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
  {
!   if (val1->lattice_val == UNDEFINED
!       /* For UNDEFINED M SSA we can't use SSA because its definition
!          may not dominate the PHI node.  */
!       && (val2->lattice_val != CONSTANT
! 	  || TREE_CODE (val2->value) != SSA_NAME))
      {
        /* UNDEFINED M any = any   */
        *val1 = *val2;
      }
!   else if (val2->lattice_val == UNDEFINED
! 	   /* For UNDEFINED M SSA we can't use SSA because its definition
! 	      may not dominate the PHI node.  */
! 	   && (val1->lattice_val != CONSTANT
! 	       || TREE_CODE (val1->value) != SSA_NAME))
      {
        /* any M UNDEFINED = any
           Nothing to do.  VAL1 already contains the value we want.  */
*************** bit_value_unop (enum tree_code code, tre
*** 1513,1519 ****
  	      || rval.mask == -1);
    bit_value_unop_1 (code, type, &value, &mask,
  		    TREE_TYPE (rhs), value_to_wide_int (rval), rval.mask);
!   if (mask != -1)
      {
        val.lattice_val = CONSTANT;
        val.mask = mask;
--- 1533,1539 ----
  	      || rval.mask == -1);
    bit_value_unop_1 (code, type, &value, &mask,
  		    TREE_TYPE (rhs), value_to_wide_int (rval), rval.mask);
!   if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
      {
        val.lattice_val = CONSTANT;
        val.mask = mask;
*************** bit_value_binop (enum tree_code code, tr
*** 1568,1574 ****
    bit_value_binop_1 (code, type, &value, &mask,
  		     TREE_TYPE (rhs1), value_to_wide_int (r1val), r1val.mask,
  		     TREE_TYPE (rhs2), value_to_wide_int (r2val), r2val.mask);
!   if (mask != -1)
      {
        val.lattice_val = CONSTANT;
        val.mask = mask;
--- 1588,1594 ----
    bit_value_binop_1 (code, type, &value, &mask,
  		     TREE_TYPE (rhs1), value_to_wide_int (r1val), r1val.mask,
  		     TREE_TYPE (rhs2), value_to_wide_int (r2val), r2val.mask);
!   if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
      {
        val.lattice_val = CONSTANT;
        val.mask = mask;
*************** bit_value_assume_aligned (gimple stmt, t
*** 1669,1675 ****
    bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask,
  		     type, value_to_wide_int (ptrval), ptrval.mask,
  		     type, value_to_wide_int (alignval), alignval.mask);
!   if (mask != -1)
      {
        val.lattice_val = CONSTANT;
        val.mask = mask;
--- 1689,1695 ----
    bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask,
  		     type, value_to_wide_int (ptrval), ptrval.mask,
  		     type, value_to_wide_int (alignval), alignval.mask);
!   if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
      {
        val.lattice_val = CONSTANT;
        val.mask = mask;
*************** evaluate_stmt (gimple stmt)
*** 1946,1960 ****
        if (likelyvalue == UNDEFINED)
  	{
  	  val.lattice_val = likelyvalue;
  	  val.mask = 0;
  	}
        else
  	{
  	  val.lattice_val = VARYING;
  	  val.mask = -1;
  	}
- 
-       val.value = NULL_TREE;
      }
  
    return val;
--- 1966,1988 ----
        if (likelyvalue == UNDEFINED)
  	{
  	  val.lattice_val = likelyvalue;
+ 	  val.value = NULL_TREE;
  	  val.mask = 0;
  	}
+       /* The statement produced a copy.  */
+       else if (simplified && TREE_CODE (simplified) == SSA_NAME
+ 	       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified))
+ 	{
+ 	  val.lattice_val = CONSTANT;
+ 	  val.value = simplified;
+ 	  val.mask = -1;
+ 	}
        else
  	{
  	  val.lattice_val = VARYING;
+ 	  val.value = NULL_TREE;
  	  val.mask = -1;
  	}
      }
  
    return val;
*************** static enum ssa_prop_result
*** 2266,2292 ****
  visit_assignment (gimple stmt, tree *output_p)
  {
    ccp_prop_value_t val;
!   enum ssa_prop_result retval;
  
    tree lhs = gimple_get_lhs (stmt);
- 
-   gcc_assert (gimple_code (stmt) != GIMPLE_CALL
-               || gimple_call_lhs (stmt) != NULL_TREE);
- 
-   if (gimple_assign_single_p (stmt)
-       && gimple_assign_rhs_code (stmt) == SSA_NAME)
-     /* For a simple copy operation, we copy the lattice values.  */
-     val = *get_value (gimple_assign_rhs1 (stmt));
-   else
-     /* Evaluate the statement, which could be
-        either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
-     val = evaluate_stmt (stmt);
- 
-   retval = SSA_PROP_NOT_INTERESTING;
- 
-   /* Set the lattice value of the statement's output.  */
    if (TREE_CODE (lhs) == SSA_NAME)
      {
        /* If STMT is an assignment to an SSA_NAME, we only have one
  	 value to set.  */
        if (set_lattice_value (lhs, val))
--- 2294,2308 ----
  visit_assignment (gimple stmt, tree *output_p)
  {
    ccp_prop_value_t val;
!   enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING;
  
    tree lhs = gimple_get_lhs (stmt);
    if (TREE_CODE (lhs) == SSA_NAME)
      {
+       /* Evaluate the statement, which could be
+ 	 either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
+       val = evaluate_stmt (stmt);
+ 
        /* If STMT is an assignment to an SSA_NAME, we only have one
  	 value to set.  */
        if (set_lattice_value (lhs, val))
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-36.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-36.c	2015-04-01 15:14:45.183125909 +0200
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-ccp1" } */
+ 
+ int foo (int i)
+ {
+   int j = i;
+   int k = 0;
+   int l = j + k;
+   int m = l - j;
+   return m;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */
+ /* { dg-final { cleanup-tree-dump "ccp1" } } */
Index: gcc/gimple-match.h
===================================================================
*** gcc/gimple-match.h.orig	2015-01-08 13:25:14.965227263 +0100
--- gcc/gimple-match.h	2015-04-01 15:14:45.183125909 +0200
*************** private:
*** 41,47 ****
  };
  
  bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *,
! 		      tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
  			    gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
--- 41,47 ----
  };
  
  bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *,
! 		      tree (*)(tree), tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
  			    gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c.orig	2015-03-19 13:22:12.073305248 +0100
--- gcc/gimple-fold.c	2015-04-01 15:14:45.184125920 +0200
*************** fold_stmt_1 (gimple_stmt_iterator *gsi,
*** 3621,3627 ****
        gimple_seq seq = NULL;
        code_helper rcode;
        tree ops[3] = {};
!       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize))
  	{
  	  if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
  	    changed = true;
--- 3621,3628 ----
        gimple_seq seq = NULL;
        code_helper rcode;
        tree ops[3] = {};
!       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq,
! 			   valueize, valueize))
  	{
  	  if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
  	    changed = true;
*************** gimple_fold_stmt_to_constant_1 (gimple s
*** 4928,4934 ****
       edges if there are intermediate VARYING defs.  For this reason
       do not follow SSA edges here even though SCCVN can technically
       just deal fine with that.  */
!   if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize)
        && rcode.is_tree_code ()
        && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
  	  || ((tree_code) rcode) == ADDR_EXPR)
--- 4929,4935 ----
       edges if there are intermediate VARYING defs.  For this reason
       do not follow SSA edges here even though SCCVN can technically
       just deal fine with that.  */
!   if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize)
        && rcode.is_tree_code ()
        && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
  	  || ((tree_code) rcode) == ADDR_EXPR)
Index: gcc/gimple-match-head.c
===================================================================
*** gcc/gimple-match-head.c.orig	2015-01-19 14:56:30.246131739 +0100
--- gcc/gimple-match-head.c	2015-04-01 15:14:45.184125920 +0200
*************** gimple_simplify (enum built_in_function
*** 601,607 ****
  bool
  gimple_simplify (gimple stmt,
  		 code_helper *rcode, tree *ops,
! 		 gimple_seq *seq, tree (*valueize)(tree))
  {
    switch (gimple_code (stmt))
      {
--- 601,608 ----
  bool
  gimple_simplify (gimple stmt,
  		 code_helper *rcode, tree *ops,
! 		 gimple_seq *seq,
! 		 tree (*valueize)(tree), tree (*top_valueize)(tree))
  {
    switch (gimple_code (stmt))
      {
*************** gimple_simplify (gimple stmt,
*** 617,625 ****
  		|| code == VIEW_CONVERT_EXPR)
  	      {
  		tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
! 		if (valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
--- 618,626 ----
  		|| code == VIEW_CONVERT_EXPR)
  	      {
  		tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
! 		if (top_valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 631,639 ****
  	      {
  		tree rhs1 = gimple_assign_rhs1 (stmt);
  		tree op0 = TREE_OPERAND (rhs1, 0);
! 		if (valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
--- 632,640 ----
  	      {
  		tree rhs1 = gimple_assign_rhs1 (stmt);
  		tree op0 = TREE_OPERAND (rhs1, 0);
! 		if (top_valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 644,653 ****
  		return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  	      }
  	    else if (code == SSA_NAME
! 		     && valueize)
  	      {
  		tree op0 = gimple_assign_rhs1 (stmt);
! 		tree valueized = valueize (op0);
  		if (!valueized || op0 == valueized)
  		  return false;
  		ops[0] = valueized;
--- 645,654 ----
  		return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  	      }
  	    else if (code == SSA_NAME
! 		     && top_valueize)
  	      {
  		tree op0 = gimple_assign_rhs1 (stmt);
! 		tree valueized = top_valueize (op0);
  		if (!valueized || op0 == valueized)
  		  return false;
  		ops[0] = valueized;
*************** gimple_simplify (gimple stmt,
*** 658,666 ****
  	  case GIMPLE_UNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
--- 659,667 ----
  	  case GIMPLE_UNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
*************** gimple_simplify (gimple stmt,
*** 671,686 ****
  	  case GIMPLE_BINARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
--- 672,687 ----
  	  case GIMPLE_BINARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
*************** gimple_simplify (gimple stmt,
*** 692,714 ****
  	  case GIMPLE_TERNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
  	      tree rhs3 = gimple_assign_rhs3 (stmt);
! 	      if (valueize && TREE_CODE (rhs3) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs3);
  		  if (tem)
  		    rhs3 = tem;
  		}
--- 693,715 ----
  	  case GIMPLE_TERNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
  	      tree rhs3 = gimple_assign_rhs3 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs3);
  		  if (tem)
  		    rhs3 = tem;
  		}
*************** gimple_simplify (gimple stmt,
*** 732,740 ****
  	  /* ???  Internal function support missing.  */
  	  if (!fn)
  	    return false;
! 	  if (valueize && TREE_CODE (fn) == SSA_NAME)
  	    {
! 	      tree tem = valueize (fn);
  	      if (tem)
  		fn = tem;
  	    }
--- 733,741 ----
  	  /* ???  Internal function support missing.  */
  	  if (!fn)
  	    return false;
! 	  if (top_valueize && TREE_CODE (fn) == SSA_NAME)
  	    {
! 	      tree tem = top_valueize (fn);
  	      if (tem)
  		fn = tem;
  	    }
*************** gimple_simplify (gimple stmt,
*** 754,762 ****
  	    case 1:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
--- 755,763 ----
  	    case 1:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 767,782 ****
  	    case 2:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
--- 768,783 ----
  	    case 2:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 788,810 ****
  	    case 3:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
  		tree arg3 = gimple_call_arg (stmt, 2);
! 		if (valueize && TREE_CODE (arg3) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg3);
  		    if (tem)
  		      arg3 = tem;
  		  }
--- 789,811 ----
  	    case 3:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
  		tree arg3 = gimple_call_arg (stmt, 2);
! 		if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg3);
  		    if (tem)
  		      arg3 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 823,838 ****
      case GIMPLE_COND:
        {
  	tree lhs = gimple_cond_lhs (stmt);
! 	if (valueize && TREE_CODE (lhs) == SSA_NAME)
  	  {
! 	    tree tem = valueize (lhs);
  	    if (tem)
  	      lhs = tem;
  	  }
  	tree rhs = gimple_cond_rhs (stmt);
! 	if (valueize && TREE_CODE (rhs) == SSA_NAME)
  	  {
! 	    tree tem = valueize (rhs);
  	    if (tem)
  	      rhs = tem;
  	  }
--- 824,839 ----
      case GIMPLE_COND:
        {
  	tree lhs = gimple_cond_lhs (stmt);
! 	if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
  	  {
! 	    tree tem = top_valueize (lhs);
  	    if (tem)
  	      lhs = tem;
  	  }
  	tree rhs = gimple_cond_rhs (stmt);
! 	if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
  	  {
! 	    tree tem = top_valueize (rhs);
  	    if (tem)
  	      rhs = tem;
  	  }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix PR65650 (1/n in merging CCP and copyprop)
  2015-04-02  9:16 [PATCH] Fix PR65650 (1/n in merging CCP and copyprop) Richard Biener
@ 2015-04-21 12:51 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2015-04-21 12:51 UTC (permalink / raw)
  To: gcc-patches

On Thu, 2 Apr 2015, Richard Biener wrote:

> 
> The following makes CCP track copies which avoids pass ordering
> issues between CCP and copyprop as seen from the testcase.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for stage1.
> 
> For stage1 I'd like to get rid of copyprop completely, a 2nd patch
> in the series will remove the copyprop instances immediately
> preceeding/following CCP.
> 
> CCP needs some TLC and I'm going to apply that during stage1.

With the propagator engine improvement this need some extra
testcase adjustments.

Re-bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Note that the "obvious" improvement of ccp_lattice_meet to

  if (val1->lattice_val == UNDEFINED
      /* For UNDEFINED M SSA we can't always SSA because its definition
         may not dominate the PHI node.  */
      && (val2->lattice_val != CONSTANT
          || TREE_CODE (val2->value) != SSA_NAME
          || SSA_NAME_IS_DEFAULT_DEF (val2->value)
          || (gimple_bb (SSA_NAME_DEF_STMT (val2->value)) != where
              && dominated_by_p (CDI_DOMINATORS, where,
                                 gimple_bb (SSA_NAME_DEF_STMT 
(val2->value))))))

to enable optimistic copy propagation (yes, copyprop doesn't do that)
regresses quite some gcc.dg/uninit-pred*.c testcases, so I'm at least
not enabling this with this patch.  For example in
gcc.dg/uninit-pred-2_a.c:

int foo (int n, int m, int r)
{
  int flag = 0;
  int v;

  if (n)
    {
      v = r;
      flag = 1;
    }

  if (m)
    g++;
  else
    bar();

  /* Wrong guard */
  if (!flag)
    blah(v); /* { dg-warning "uninitialized" "real uninitialized var 
warning" } */

we see that we can optimistically propagate r into v for the call
due to the PHI

 v_3 = PHI <v_1(D)(2), v_2(3)>

and v being uninitialized on one path.  We have similar missed
uninit warnings for optimistic constant propagations already
so I think optimistically propagating copies isn't wrong.
We might want to provide a flag to turn both off, of course.

I'll send a followup enabling optimistic copyprop once I get
my mind around on how to fix the testcases.

Richard.

2015-04-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/65650
	* tree-ssa-ccp.c (valid_lattice_transition): Allow lattice
	transitions involving copies.
	(set_lattice_value): Adjust for copy lattice state.
	(ccp_lattice_meet): Do not merge UNDEFINED and a copy to the copy
	if that doesn't dominate the merge point.
	(bit_value_unop): Adjust what we treat as varying mask.
	(bit_value_binop): Likewise.
	(bit_value_assume_aligned): Likewise.
	(evaluate_stmt): When we simplified to a SSA name record a copy
	instead of dropping to varying.
	(visit_assignment): Simplify.

	* gimple-match.h (gimple_simplify): Add another callback.
	* gimple-fold.c (fold_stmt_1): Adjust caller.
	(gimple_fold_stmt_to_constant_1): Likewise - pass valueize
	for the 2nd callback.
	* gimple-match-head.c (gimple_simplify): Add a callback that is
	used to valueize the stmt operands and use it that way.

	* gcc.dg/tree-ssa/ssa-ccp-37.c: New testcase.
	* gcc.dg/tree-ssa/forwprop-11.c: Adjust.
	* gcc.dg/tree-ssa/ssa-fre-3.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-4.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-5.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-32.c: Likewise.


Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c	(revision 222266)
--- gcc/gimple-fold.c	(working copy)
*************** fold_stmt_1 (gimple_stmt_iterator *gsi,
*** 3621,3627 ****
        gimple_seq seq = NULL;
        code_helper rcode;
        tree ops[3] = {};
!       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize))
  	{
  	  if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
  	    changed = true;
--- 3621,3628 ----
        gimple_seq seq = NULL;
        code_helper rcode;
        tree ops[3] = {};
!       if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq,
! 			   valueize, valueize))
  	{
  	  if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace))
  	    changed = true;
*************** gimple_fold_stmt_to_constant_1 (gimple s
*** 4928,4934 ****
       edges if there are intermediate VARYING defs.  For this reason
       do not follow SSA edges here even though SCCVN can technically
       just deal fine with that.  */
!   if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize)
        && rcode.is_tree_code ()
        && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
  	  || ((tree_code) rcode) == ADDR_EXPR)
--- 4929,4935 ----
       edges if there are intermediate VARYING defs.  For this reason
       do not follow SSA edges here even though SCCVN can technically
       just deal fine with that.  */
!   if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize)
        && rcode.is_tree_code ()
        && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
  	  || ((tree_code) rcode) == ADDR_EXPR)
Index: gcc/gimple-match-head.c
===================================================================
*** gcc/gimple-match-head.c	(revision 222266)
--- gcc/gimple-match-head.c	(working copy)
*************** gimple_simplify (enum built_in_function
*** 601,607 ****
  bool
  gimple_simplify (gimple stmt,
  		 code_helper *rcode, tree *ops,
! 		 gimple_seq *seq, tree (*valueize)(tree))
  {
    switch (gimple_code (stmt))
      {
--- 601,608 ----
  bool
  gimple_simplify (gimple stmt,
  		 code_helper *rcode, tree *ops,
! 		 gimple_seq *seq,
! 		 tree (*valueize)(tree), tree (*top_valueize)(tree))
  {
    switch (gimple_code (stmt))
      {
*************** gimple_simplify (gimple stmt,
*** 617,625 ****
  		|| code == VIEW_CONVERT_EXPR)
  	      {
  		tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
! 		if (valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
--- 618,626 ----
  		|| code == VIEW_CONVERT_EXPR)
  	      {
  		tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
! 		if (top_valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 631,639 ****
  	      {
  		tree rhs1 = gimple_assign_rhs1 (stmt);
  		tree op0 = TREE_OPERAND (rhs1, 0);
! 		if (valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
--- 632,640 ----
  	      {
  		tree rhs1 = gimple_assign_rhs1 (stmt);
  		tree op0 = TREE_OPERAND (rhs1, 0);
! 		if (top_valueize && TREE_CODE (op0) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (op0);
  		    if (tem)
  		      op0 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 644,653 ****
  		return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  	      }
  	    else if (code == SSA_NAME
! 		     && valueize)
  	      {
  		tree op0 = gimple_assign_rhs1 (stmt);
! 		tree valueized = valueize (op0);
  		if (!valueized || op0 == valueized)
  		  return false;
  		ops[0] = valueized;
--- 645,654 ----
  		return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  	      }
  	    else if (code == SSA_NAME
! 		     && top_valueize)
  	      {
  		tree op0 = gimple_assign_rhs1 (stmt);
! 		tree valueized = top_valueize (op0);
  		if (!valueized || op0 == valueized)
  		  return false;
  		ops[0] = valueized;
*************** gimple_simplify (gimple stmt,
*** 658,666 ****
  	  case GIMPLE_UNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
--- 659,667 ----
  	  case GIMPLE_UNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
*************** gimple_simplify (gimple stmt,
*** 671,686 ****
  	  case GIMPLE_BINARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
--- 672,687 ----
  	  case GIMPLE_BINARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
*************** gimple_simplify (gimple stmt,
*** 692,714 ****
  	  case GIMPLE_TERNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
  	      tree rhs3 = gimple_assign_rhs3 (stmt);
! 	      if (valueize && TREE_CODE (rhs3) == SSA_NAME)
  		{
! 		  tree tem = valueize (rhs3);
  		  if (tem)
  		    rhs3 = tem;
  		}
--- 693,715 ----
  	  case GIMPLE_TERNARY_RHS:
  	    {
  	      tree rhs1 = gimple_assign_rhs1 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs1);
  		  if (tem)
  		    rhs1 = tem;
  		}
  	      tree rhs2 = gimple_assign_rhs2 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs2);
  		  if (tem)
  		    rhs2 = tem;
  		}
  	      tree rhs3 = gimple_assign_rhs3 (stmt);
! 	      if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
  		{
! 		  tree tem = top_valueize (rhs3);
  		  if (tem)
  		    rhs3 = tem;
  		}
*************** gimple_simplify (gimple stmt,
*** 732,740 ****
  	  /* ???  Internal function support missing.  */
  	  if (!fn)
  	    return false;
! 	  if (valueize && TREE_CODE (fn) == SSA_NAME)
  	    {
! 	      tree tem = valueize (fn);
  	      if (tem)
  		fn = tem;
  	    }
--- 733,741 ----
  	  /* ???  Internal function support missing.  */
  	  if (!fn)
  	    return false;
! 	  if (top_valueize && TREE_CODE (fn) == SSA_NAME)
  	    {
! 	      tree tem = top_valueize (fn);
  	      if (tem)
  		fn = tem;
  	    }
*************** gimple_simplify (gimple stmt,
*** 754,762 ****
  	    case 1:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
--- 755,763 ----
  	    case 1:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 767,782 ****
  	    case 2:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
--- 768,783 ----
  	    case 2:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 788,810 ****
  	    case 3:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
  		tree arg3 = gimple_call_arg (stmt, 2);
! 		if (valueize && TREE_CODE (arg3) == SSA_NAME)
  		  {
! 		    tree tem = valueize (arg3);
  		    if (tem)
  		      arg3 = tem;
  		  }
--- 789,811 ----
  	    case 3:
  	      {
  		tree arg1 = gimple_call_arg (stmt, 0);
! 		if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg1);
  		    if (tem)
  		      arg1 = tem;
  		  }
  		tree arg2 = gimple_call_arg (stmt, 1);
! 		if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg2);
  		    if (tem)
  		      arg2 = tem;
  		  }
  		tree arg3 = gimple_call_arg (stmt, 2);
! 		if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
  		  {
! 		    tree tem = top_valueize (arg3);
  		    if (tem)
  		      arg3 = tem;
  		  }
*************** gimple_simplify (gimple stmt,
*** 823,838 ****
      case GIMPLE_COND:
        {
  	tree lhs = gimple_cond_lhs (stmt);
! 	if (valueize && TREE_CODE (lhs) == SSA_NAME)
  	  {
! 	    tree tem = valueize (lhs);
  	    if (tem)
  	      lhs = tem;
  	  }
  	tree rhs = gimple_cond_rhs (stmt);
! 	if (valueize && TREE_CODE (rhs) == SSA_NAME)
  	  {
! 	    tree tem = valueize (rhs);
  	    if (tem)
  	      rhs = tem;
  	  }
--- 824,839 ----
      case GIMPLE_COND:
        {
  	tree lhs = gimple_cond_lhs (stmt);
! 	if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
  	  {
! 	    tree tem = top_valueize (lhs);
  	    if (tem)
  	      lhs = tem;
  	  }
  	tree rhs = gimple_cond_rhs (stmt);
! 	if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
  	  {
! 	    tree tem = top_valueize (rhs);
  	    if (tem)
  	      rhs = tem;
  	  }
Index: gcc/gimple-match.h
===================================================================
*** gcc/gimple-match.h	(revision 222266)
--- gcc/gimple-match.h	(working copy)
*************** private:
*** 41,47 ****
  };
  
  bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *,
! 		      tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
  			    gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
--- 41,47 ----
  };
  
  bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *,
! 		      tree (*)(tree), tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
  			    gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c	(revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c	(working copy)
*************** int g(int *p, int n)
*** 16,20 ****
    return q[-1];
  }
  
! /* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_.. \\\+ 4B\\\];" 2 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- 16,20 ----
    return q[-1];
  }
  
! /* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_\[0-9\]+(?:\\(D\\))? \\\+ 4B\\\];" 2 "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c	(working copy)
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-ccp1" } */
+ 
+ int foo (int i)
+ {
+   int j = i;
+   int k = 0;
+   int l = j + k;
+   int m = l - j;
+   return m;
+ }
+ 
+ /* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */
+ /* { dg-final { cleanup-tree-dump "ccp1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c	(revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c	(working copy)
***************
*** 6,12 ****
     When the condition is true, we distribute "(int) (a + b)" as
     "(int) a + (int) b", otherwise we keep the original.  */
  /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */
! /* { dg-options "-O -fno-tree-forwprop -fwrapv -fdump-tree-fre1-details" } */
  
  /* From PR14844.  */
  
--- 6,12 ----
     When the condition is true, we distribute "(int) (a + b)" as
     "(int) a + (int) b", otherwise we keep the original.  */
  /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */
! /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fwrapv -fdump-tree-fre1-details" } */
  
  /* From PR14844.  */
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c	(revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c	(working copy)
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  _Complex float m;
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fdump-tree-fre1-details" } */
  
  _Complex float m;
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c	(revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c	(working copy)
***************
*** 1,7 ****
  /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there
     will be no casts for FRE to eliminate and the test will fail.  */
  /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* } } */
! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  /* From PR21608.  */
  
--- 1,7 ----
  /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there
     will be no casts for FRE to eliminate and the test will fail.  */
  /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* } } */
! /* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  /* From PR21608.  */
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c	(revision 222266)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c	(working copy)
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  /* From PR19792.  */
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop -fdump-tree-fre1-details" } */
  
  /* From PR19792.  */
  
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c	(revision 222266)
--- gcc/tree-ssa-ccp.c	(working copy)
*************** valid_lattice_transition (ccp_prop_value
*** 439,444 ****
--- 439,455 ----
  
    /* Now both lattice values are CONSTANT.  */
  
+   /* Allow arbitrary copy changes as we might look through PHI <a_1, ...>
+      when only a single copy edge is executable.  */
+   if (TREE_CODE (old_val.value) == SSA_NAME
+       && TREE_CODE (new_val.value) == SSA_NAME)
+     return true;
+ 
+   /* Allow transitioning from a constant to a copy.  */
+   if (is_gimple_min_invariant (old_val.value)
+       && TREE_CODE (new_val.value) == SSA_NAME)
+     return true;
+ 
    /* Allow transitioning from PHI <&x, not executable> == &x
       to PHI <&x, &y> == common alignment.  */
    if (TREE_CODE (old_val.value) != INTEGER_CST
*************** set_lattice_value (tree var, ccp_prop_va
*** 527,535 ****
       caller that this was a non-transition.  */
    if (old_val->lattice_val != new_val.lattice_val
        || (new_val.lattice_val == CONSTANT
! 	  && TREE_CODE (new_val.value) == INTEGER_CST
! 	  && (TREE_CODE (old_val->value) != INTEGER_CST
! 	      || new_val.mask != old_val->mask)))
      {
        /* ???  We would like to delay creation of INTEGER_CSTs from
  	 partially constants here.  */
--- 538,547 ----
       caller that this was a non-transition.  */
    if (old_val->lattice_val != new_val.lattice_val
        || (new_val.lattice_val == CONSTANT
! 	  && (TREE_CODE (new_val.value) != TREE_CODE (old_val->value)
! 	      || simple_cst_equal (new_val.value, old_val->value) != 1
! 	      || (TREE_CODE (new_val.value) == INTEGER_CST
! 		  && new_val.mask != old_val->mask))))
      {
        /* ???  We would like to delay creation of INTEGER_CSTs from
  	 partially constants here.  */
*************** ccp_finalize (void)
*** 965,978 ****
     */
  
  static void
! ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
  {
!   if (val1->lattice_val == UNDEFINED)
      {
        /* UNDEFINED M any = any   */
        *val1 = *val2;
      }
!   else if (val2->lattice_val == UNDEFINED)
      {
        /* any M UNDEFINED = any
           Nothing to do.  VAL1 already contains the value we want.  */
--- 977,999 ----
     */
  
  static void
! ccp_lattice_meet (basic_block where,
! 		  ccp_prop_value_t *val1, ccp_prop_value_t *val2)
  {
!   if (val1->lattice_val == UNDEFINED
!       /* For UNDEFINED M SSA we can't always SSA because its definition
!          may not dominate the PHI node.  Doing optimistic copy propagation
! 	 also causes a lot of gcc.dg/uninit-pred*.c FAILs.  */
!       && (val2->lattice_val != CONSTANT
! 	  || TREE_CODE (val2->value) != SSA_NAME))
      {
        /* UNDEFINED M any = any   */
        *val1 = *val2;
      }
!   else if (val2->lattice_val == UNDEFINED
! 	   /* See above.  */
! 	   && (val1->lattice_val != CONSTANT
! 	       || TREE_CODE (val1->value) != SSA_NAME))
      {
        /* any M UNDEFINED = any
           Nothing to do.  VAL1 already contains the value we want.  */
*************** ccp_lattice_meet (ccp_prop_value_t *val1
*** 1026,1032 ****
  	*val1 = get_value_for_expr (val1->value, true);
        if (TREE_CODE (val2->value) == ADDR_EXPR)
  	tem = get_value_for_expr (val2->value, true);
!       ccp_lattice_meet (val1, &tem);
      }
    else
      {
--- 1047,1053 ----
  	*val1 = get_value_for_expr (val1->value, true);
        if (TREE_CODE (val2->value) == ADDR_EXPR)
  	tem = get_value_for_expr (val2->value, true);
!       ccp_lattice_meet (where, val1, &tem);
      }
    else
      {
*************** ccp_visit_phi_node (gphi *phi)
*** 1095,1101 ****
  	  tree arg = gimple_phi_arg (phi, i)->def;
  	  ccp_prop_value_t arg_val = get_value_for_expr (arg, false);
  
! 	  ccp_lattice_meet (&new_val, &arg_val);
  
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
--- 1116,1122 ----
  	  tree arg = gimple_phi_arg (phi, i)->def;
  	  ccp_prop_value_t arg_val = get_value_for_expr (arg, false);
  
! 	  ccp_lattice_meet (gimple_bb (phi), &new_val, &arg_val);
  
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
*************** evaluate_stmt (gimple stmt)
*** 1929,1937 ****
    /* The statement produced a nonconstant value.  */
    if (!is_constant)
      {
!       val.lattice_val = VARYING;
!       val.mask = -1;
!       val.value = NULL_TREE;
      }
  
    return val;
--- 1950,1970 ----
    /* The statement produced a nonconstant value.  */
    if (!is_constant)
      {
!       /* The statement produced a copy.  */
!       if (simplified && TREE_CODE (simplified) == SSA_NAME
! 	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified))
! 	{
! 	  val.lattice_val = CONSTANT;
! 	  val.value = simplified;
! 	  val.mask = -1;
! 	}
!       /* The statement is VARYING.  */
!       else
! 	{
! 	  val.lattice_val = VARYING;
! 	  val.value = NULL_TREE;
! 	  val.mask = -1;
! 	}
      }
  
    return val;
*************** static enum ssa_prop_result
*** 2243,2269 ****
  visit_assignment (gimple stmt, tree *output_p)
  {
    ccp_prop_value_t val;
!   enum ssa_prop_result retval;
  
    tree lhs = gimple_get_lhs (stmt);
- 
-   gcc_assert (gimple_code (stmt) != GIMPLE_CALL
-               || gimple_call_lhs (stmt) != NULL_TREE);
- 
-   if (gimple_assign_single_p (stmt)
-       && gimple_assign_rhs_code (stmt) == SSA_NAME)
-     /* For a simple copy operation, we copy the lattice values.  */
-     val = *get_value (gimple_assign_rhs1 (stmt));
-   else
-     /* Evaluate the statement, which could be
-        either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
-     val = evaluate_stmt (stmt);
- 
-   retval = SSA_PROP_NOT_INTERESTING;
- 
-   /* Set the lattice value of the statement's output.  */
    if (TREE_CODE (lhs) == SSA_NAME)
      {
        /* If STMT is an assignment to an SSA_NAME, we only have one
  	 value to set.  */
        if (set_lattice_value (lhs, val))
--- 2276,2290 ----
  visit_assignment (gimple stmt, tree *output_p)
  {
    ccp_prop_value_t val;
!   enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING;
  
    tree lhs = gimple_get_lhs (stmt);
    if (TREE_CODE (lhs) == SSA_NAME)
      {
+       /* Evaluate the statement, which could be
+ 	 either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
+       val = evaluate_stmt (stmt);
+ 
        /* If STMT is an assignment to an SSA_NAME, we only have one
  	 value to set.  */
        if (set_lattice_value (lhs, val))

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-04-21 12:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-02  9:16 [PATCH] Fix PR65650 (1/n in merging CCP and copyprop) Richard Biener
2015-04-21 12:51 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).