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]

[tcb] Fix value numbering of expressions with overflow constants


An overflow constant is not a GIMPLE invariant and should not be value
numbered.  This triggers some C++ regressions in the branch.

Bootstrapped and tested x86, x86-64 and ppc.


Diego.


	* tree-ssa-pre.c (valid_in_set): Return false for
	tcc_declaration.
	(create_value_expr_from): Return NULL if one of the operands
	in the expression is an overflowed constant.
	(compute_avail): Only insert new expression if
	create_value_expr_from returns non-NULL.

Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-pre.c,v
retrieving revision 2.36.2.4
diff -d -c -p -r2.36.2.4 tree-ssa-pre.c
*** tree-ssa-pre.c	13 Oct 2004 16:04:21 -0000	2.36.2.4
--- tree-ssa-pre.c	15 Oct 2004 00:47:42 -0000
*************** valid_in_set (value_set_t set, tree expr
*** 1077,1082 ****
--- 1077,1086 ----
        gcc_assert (TREE_CODE (expr) == SSA_NAME);
        return true;
  
+     case tcc_declaration:
+       /* VAR_DECL and PARM_DECL are never anticipatable.  */
+       return false;
+ 
      default:
        /* No other cases should be encountered.  */
        gcc_unreachable (); 
*************** create_value_expr_from (tree expr, basic
*** 1668,1699 ****
    int i;
    enum tree_code code = TREE_CODE (expr);
    tree vexpr;
  
    gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
  	      || TREE_CODE_CLASS (code) == tcc_binary
  	      || TREE_CODE_CLASS (code) == tcc_reference);
  
    if (TREE_CODE_CLASS (code) == tcc_unary)
!     vexpr = pool_alloc (unary_node_pool);
    else if (TREE_CODE_CLASS (code) == tcc_reference)
!     vexpr = pool_alloc (reference_node_pool);
    else
!     vexpr = pool_alloc (binary_node_pool);
  
    memcpy (vexpr, expr, tree_size (expr));
  
    for (i = 0; i < TREE_CODE_LENGTH (code); i++)
      {
!       tree op = TREE_OPERAND (expr, i);
!       if (op != NULL)
  	{
! 	  tree val = vn_lookup_or_add (op, vuses);
! 	  if (!is_undefined_value (op))
! 	    value_insert_into_set (EXP_GEN (block), op);
! 	  if (TREE_CODE (val) == VALUE_HANDLE)
! 	    TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
! 	  TREE_OPERAND (vexpr, i) = val;
  	}
      }
  
    return vexpr;
--- 1672,1720 ----
    int i;
    enum tree_code code = TREE_CODE (expr);
    tree vexpr;
+   alloc_pool pool;
  
    gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
  	      || TREE_CODE_CLASS (code) == tcc_binary
  	      || TREE_CODE_CLASS (code) == tcc_reference);
  
    if (TREE_CODE_CLASS (code) == tcc_unary)
!     pool = unary_node_pool;
    else if (TREE_CODE_CLASS (code) == tcc_reference)
!     pool = reference_node_pool;
    else
!     pool = binary_node_pool;
  
+   vexpr = pool_alloc (pool);
    memcpy (vexpr, expr, tree_size (expr));
  
    for (i = 0; i < TREE_CODE_LENGTH (code); i++)
      {
!       tree val, op;
!       
!       op = TREE_OPERAND (expr, i);
!       if (op == NULL_TREE)
! 	continue;
! 
!       /* If OP is a constant that has overflowed, do not value number
! 	 this expression.  */
!       if (TREE_CODE_CLASS (TREE_CODE (op)) == tcc_constant
! 	  && TREE_OVERFLOW (op))
  	{
! 	  pool_free (pool, vexpr);
! 	  return NULL;
  	}
+ 
+       /* Create a value handle for OP and add it to VEXPR.  */
+       val = vn_lookup_or_add (op, vuses);
+ 
+       if (!is_undefined_value (op))
+ 	value_insert_into_set (EXP_GEN (block), op);
+ 
+       if (TREE_CODE (val) == VALUE_HANDLE)
+ 	TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
+ 
+       TREE_OPERAND (vexpr, i) = val;
      }
  
    return vexpr;
*************** compute_avail (basic_block block)
*** 1795,1811 ****
  		}	   
  	      else if (UNARY_CLASS_P (rhs)
  		       || BINARY_CLASS_P (rhs)
! 		       || TREE_CODE (rhs) == tcc_reference)
  		{
  		  /* For binary, unary, and reference expressions,
  		     create a duplicate expression with the operands
  		     replaced with the value handles of the original
  		     RHS.  */
  		  tree newt = create_value_expr_from (rhs, block, vuses);
! 		  add_to_sets (lhs, newt, vuses, TMP_GEN (block),
! 			       AVAIL_OUT (block));
! 		  value_insert_into_set (EXP_GEN (block), newt);
! 		  continue;
  		}
  	    }
  
--- 1816,1835 ----
  		}	   
  	      else if (UNARY_CLASS_P (rhs)
  		       || BINARY_CLASS_P (rhs)
! 		       || TREE_CODE_CLASS (TREE_CODE (rhs)) == tcc_reference)
  		{
  		  /* For binary, unary, and reference expressions,
  		     create a duplicate expression with the operands
  		     replaced with the value handles of the original
  		     RHS.  */
  		  tree newt = create_value_expr_from (rhs, block, vuses);
! 		  if (newt)
! 		    {
! 		      add_to_sets (lhs, newt, vuses, TMP_GEN (block),
! 				   AVAIL_OUT (block));
! 		      value_insert_into_set (EXP_GEN (block), newt);
! 		      continue;
! 		    }
  		}
  	    }
  



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