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] Fix PR37542 somewhat


This brings PRE phi-translation simplification closer to what 4.3 did.
In particular it now should catch all cases where 4.3 was able to
simplify something to a constant.  This is what should be safe and
always profitable - more can be done (and was by 4.3), but I do not
think this would be appropriate for this stage of development.

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

Richard.

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

	PR tree-optimization/37542
	* tree-ssa-pre.c (fully_constant_expression): Handle more cases.
	* tree-ssa-sccvn.c (vn_get_expr_for): Fix typo.
	(vn_nary_op_lookup_stmt): Adjust for unary reference trees.
	(vn_nary_op_insert_stmt): Likewise.
	(visit_use): Likewise.

	* gcc.dg/tree-ssa/ssa-pre-22.c: New testcase.
	* gcc.c-torture/compile/20081101-1.c: Likewise.

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 141531)
--- gcc/tree-ssa-pre.c	(working copy)
*************** fully_constant_expression (pre_expr e)
*** 1088,1134 ****
  	vn_nary_op_t nary = PRE_EXPR_NARY (e);
  	switch (TREE_CODE_CLASS (nary->opcode))
  	  {
  	  case tcc_binary:
  	    {
  	      /* We have to go from trees to pre exprs to value ids to
  		 constants.  */
  	      tree naryop0 = nary->op[0];
  	      tree naryop1 = nary->op[1];
! 	      tree const0, const1, result;
! 	      if (is_gimple_min_invariant (naryop0))
! 		const0 = naryop0;
! 	      else
  		{
  		  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
  		  unsigned int vrep0 = get_expr_value_id (rep0);
! 		  const0 = get_constant_for_value_id (vrep0);
  		}
! 	      if (is_gimple_min_invariant (naryop1))
! 		const1 = naryop1;
! 	      else
  		{
  		  pre_expr rep1 = get_or_alloc_expr_for (naryop1);
  		  unsigned int vrep1 = get_expr_value_id (rep1);
! 		  const1 = get_constant_for_value_id (vrep1);
! 		}
! 	      result = NULL;
! 	      if (const0 && const1)
! 		{
! 		  tree type1 = TREE_TYPE (nary->op[0]);
! 		  tree type2 = TREE_TYPE (nary->op[1]);
! 		  const0 = fold_convert (type1, const0);
! 		  const1 = fold_convert (type2, const1);
! 		  result = fold_binary (nary->opcode, nary->type, const0,
! 					const1);
  		}
  	      if (result && is_gimple_min_invariant (result))
  		return get_or_alloc_expr_for_constant (result);
  	      return e;
  	    }
  	  case tcc_unary:
  	    {
! 	    /* We have to go from trees to pre exprs to value ids to
! 	       constants.  */
  	      tree naryop0 = nary->op[0];
  	      tree const0, result;
  	      if (is_gimple_min_invariant (naryop0))
--- 1088,1146 ----
  	vn_nary_op_t nary = PRE_EXPR_NARY (e);
  	switch (TREE_CODE_CLASS (nary->opcode))
  	  {
+ 	  case tcc_expression:
+ 	    if (nary->opcode == TRUTH_NOT_EXPR)
+ 	      goto do_unary;
+ 	    if (nary->opcode != TRUTH_AND_EXPR
+ 		&& nary->opcode != TRUTH_OR_EXPR
+ 		&& nary->opcode != TRUTH_XOR_EXPR)
+ 	      return e;
+ 	    /* Fallthrough.  */
  	  case tcc_binary:
+ 	  case tcc_comparison:
  	    {
  	      /* We have to go from trees to pre exprs to value ids to
  		 constants.  */
  	      tree naryop0 = nary->op[0];
  	      tree naryop1 = nary->op[1];
! 	      tree result;
! 	      if (!is_gimple_min_invariant (naryop0))
  		{
  		  pre_expr rep0 = get_or_alloc_expr_for (naryop0);
  		  unsigned int vrep0 = get_expr_value_id (rep0);
! 		  tree const0 = get_constant_for_value_id (vrep0);
! 		  if (const0)
! 		    naryop0 = fold_convert (TREE_TYPE (naryop0), const0);
  		}
! 	      if (!is_gimple_min_invariant (naryop1))
  		{
  		  pre_expr rep1 = get_or_alloc_expr_for (naryop1);
  		  unsigned int vrep1 = get_expr_value_id (rep1);
! 		  tree const1 = get_constant_for_value_id (vrep1);
! 		  if (const1)
! 		    naryop1 = fold_convert (TREE_TYPE (naryop1), const1);
  		}
+ 	      result = fold_binary (nary->opcode, nary->type,
+ 				    naryop0, naryop1);
  	      if (result && is_gimple_min_invariant (result))
  		return get_or_alloc_expr_for_constant (result);
+ 	      /* We might have simplified the expression to a
+ 		 SSA_NAME for example from x_1 * 1.  But we cannot
+ 		 insert a PHI for x_1 unconditionally as x_1 might
+ 		 not be available readily.  */
  	      return e;
  	    }
+ 	  case tcc_reference:
+ 	    if (nary->opcode != REALPART_EXPR
+ 		&& nary->opcode != IMAGPART_EXPR 
+ 		&& nary->opcode != VIEW_CONVERT_EXPR)
+ 	      return e;
+ 	    /* Fallthrough.  */
  	  case tcc_unary:
+ do_unary:
  	    {
! 	      /* We have to go from trees to pre exprs to value ids to
! 		 constants.  */
  	      tree naryop0 = nary->op[0];
  	      tree const0, result;
  	      if (is_gimple_min_invariant (naryop0))
*************** fully_constant_expression (pre_expr e)
*** 1146,1152 ****
  		  const0 = fold_convert (type1, const0);
  		  result = fold_unary (nary->opcode, nary->type, const0);
  		}
- 	      
  	      if (result && is_gimple_min_invariant (result))
  		return get_or_alloc_expr_for_constant (result);
  	      return e;
--- 1158,1163 ----
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 141532)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** vn_get_expr_for (tree name)
*** 258,265 ****
      {
      case tcc_reference:
        if (gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR
! 	  && gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
! 	  && gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR)
  	expr = fold_build1 (gimple_assign_rhs_code (def_stmt),
  			    gimple_expr_type (def_stmt),
  			    TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0));
--- 258,265 ----
      {
      case tcc_reference:
        if (gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR
! 	  || gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
! 	  || gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR)
  	expr = fold_build1 (gimple_assign_rhs_code (def_stmt),
  			    gimple_expr_type (def_stmt),
  			    TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0));
*************** vn_nary_op_lookup_stmt (gimple stmt, vn_
*** 1281,1286 ****
--- 1281,1290 ----
    vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
    for (i = 0; i < vno1.length; ++i)
      vno1.op[i] = gimple_op (stmt, i + 1);
+   if (vno1.opcode == REALPART_EXPR
+       || vno1.opcode == IMAGPART_EXPR
+       || vno1.opcode == VIEW_CONVERT_EXPR)
+     vno1.op[0] = TREE_OPERAND (vno1.op[0], 0);
    vno1.hashcode = vn_nary_op_compute_hash (&vno1);
    slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
  				   NO_INSERT);
*************** vn_nary_op_insert_stmt (gimple stmt, tre
*** 1385,1390 ****
--- 1389,1398 ----
    vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
    for (i = 0; i < vno1->length; ++i)
      vno1->op[i] = gimple_op (stmt, i + 1);
+   if (vno1->opcode == REALPART_EXPR
+       || vno1->opcode == IMAGPART_EXPR
+       || vno1->opcode == VIEW_CONVERT_EXPR)
+     vno1->op[0] = TREE_OPERAND (vno1->op[0], 0);
    vno1->result = result;
    vno1->hashcode = vn_nary_op_compute_hash (vno1);
    slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
*************** visit_use (tree use)
*** 2380,2387 ****
  		    case GIMPLE_SINGLE_RHS:
  		      switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
  			{
- 			case tcc_declaration:
  			case tcc_reference:
  			  changed = visit_reference_op_load
  			      (lhs, gimple_assign_rhs1 (stmt), stmt);
  			  break;
--- 2388,2405 ----
  		    case GIMPLE_SINGLE_RHS:
  		      switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
  			{
  			case tcc_reference:
+ 			  /* VOP-less references can go through unary case.  */
+ 			  if ((gimple_assign_rhs_code (stmt) == REALPART_EXPR
+ 			       || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR
+ 			       || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR )
+ 			      && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)) == SSA_NAME)
+ 			    {
+ 			      changed = visit_unary_op (lhs, stmt);
+ 			      break;
+ 			    }
+ 			  /* Fallthrough.  */
+ 			case tcc_declaration:
  			  changed = visit_reference_op_load
  			      (lhs, gimple_assign_rhs1 (stmt), stmt);
  			  break;
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-22.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-22.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-22.c	(revision 0)
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-pre-stats" } */
+ 
+ int foo (int i, int b)
+ {
+   int j = 1;
+   if (b)
+     j = i;
+   return j - i;
+ }
+ 
+ /* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */
+ /* { dg-final { cleanup-tree-dump "pre" } } */
Index: gcc/testsuite/gcc.c-torture/compile/20081101-1.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/20081101-1.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/compile/20081101-1.c	(revision 0)
***************
*** 0 ****
--- 1,12 ----
+ int foo (int i, int b)
+ {
+   int mask;
+   int result;
+   if (b)
+     mask = -1;
+   else
+     mask = 0;
+   result = i + 1;
+   result = result & mask;
+   return result;
+ }


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