diff mbox

Fix ADDR_EXPR handling in SCCVN and PRE

Message ID alpine.LNX.2.00.1209131415540.28649@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Sept. 13, 2012, 12:17 p.m. UTC
This unifies the two code paths that try to figure out which
VN handling routines are responsible for value-numbering.  It
also fixes ADDR_EXPR handling so that we handle those properly.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2012-09-13  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-sccvn.h (enum vn_kind): New.
	(vn_get_stmt_kind): Likewise.
	* tree-ssa-sccvn.c (vn_get_stmt_kind): New function, adjust
	ADDR_EXPR handling.
	(visit_use): Use it.
	* tree-ssa-pre.c (compute_avail): Likewise, simplify further.

	* gcc.dg/tree-ssa/ssa-fre-37.c: New testcase.
diff mbox

Patch

Index: gcc/tree-ssa-sccvn.h
===================================================================
--- gcc/tree-ssa-sccvn.h	(revision 191247)
+++ gcc/tree-ssa-sccvn.h	(working copy)
@@ -121,6 +121,9 @@  typedef struct vn_constant_s
   tree constant;
 } *vn_constant_t;
 
+enum vn_kind { VN_NONE, VN_CONSTANT, VN_NARY, VN_REFERENCE, VN_PHI };
+enum vn_kind vn_get_stmt_kind (gimple);
+
 /* Hash the constant CONSTANT with distinguishing type incompatible
    constants in the types_compatible_p sense.  */
 
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 191247)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -287,6 +287,63 @@  vn_get_expr_for (tree name)
   return expr;
 }
 
+/* Return the vn_kind the expression computed by the stmt should be
+   associated with.  */
+
+enum vn_kind
+vn_get_stmt_kind (gimple stmt)
+{
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_CALL:
+      return VN_REFERENCE;
+    case GIMPLE_PHI:
+      return VN_PHI;
+    case GIMPLE_ASSIGN:
+      {
+	enum tree_code code = gimple_assign_rhs_code (stmt);
+	tree rhs1 = gimple_assign_rhs1 (stmt);
+	switch (get_gimple_rhs_class (code))
+	  {
+	  case GIMPLE_UNARY_RHS:
+	  case GIMPLE_BINARY_RHS:
+	  case GIMPLE_TERNARY_RHS:
+	    return VN_NARY;
+	  case GIMPLE_SINGLE_RHS:
+	    switch (TREE_CODE_CLASS (code))
+	      {
+	      case tcc_reference:
+		/* VOP-less references can go through unary case.  */
+		if ((code == REALPART_EXPR
+		     || code == IMAGPART_EXPR
+		     || code == VIEW_CONVERT_EXPR
+		     || code == BIT_FIELD_REF)
+		    && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
+		  return VN_NARY;
+
+		/* Fallthrough.  */
+	      case tcc_declaration:
+		return VN_REFERENCE;
+
+	      case tcc_constant:
+		return VN_CONSTANT;
+
+	      default:
+		if (code == ADDR_EXPR)
+		  return (is_gimple_min_invariant (rhs1)
+			  ? VN_CONSTANT : VN_REFERENCE);
+		else if (code == CONSTRUCTOR)
+		  return VN_NARY;
+		return VN_NONE;
+	      }
+	  default:
+	    return VN_NONE;
+	  }
+      }
+    default:
+      return VN_NONE;
+    }
+}
 
 /* Free a phi operation structure VP.  */
 
@@ -3364,44 +3421,13 @@  visit_use (tree use)
 		}
 	      else
 		{
-		  switch (get_gimple_rhs_class (code))
+		  switch (vn_get_stmt_kind (stmt))
 		    {
-		    case GIMPLE_UNARY_RHS:
-		    case GIMPLE_BINARY_RHS:
-		    case GIMPLE_TERNARY_RHS:
+		    case VN_NARY:
 		      changed = visit_nary_op (lhs, stmt);
 		      break;
-		    case GIMPLE_SINGLE_RHS:
-		      switch (TREE_CODE_CLASS (code))
-			{
-			case tcc_reference:
-			  /* VOP-less references can go through unary case.  */
-			  if ((code == REALPART_EXPR
-			       || code == IMAGPART_EXPR
-			       || code == VIEW_CONVERT_EXPR
-			       || code == BIT_FIELD_REF)
-			      && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
-			    {
-			      changed = visit_nary_op (lhs, stmt);
-			      break;
-			    }
-			  /* Fallthrough.  */
-			case tcc_declaration:
-			  changed = visit_reference_op_load (lhs, rhs1, stmt);
-			  break;
-			default:
-			  if (code == ADDR_EXPR)
-			    {
-			      changed = visit_nary_op (lhs, stmt);
-			      break;
-			    }
-			  else if (code == CONSTRUCTOR)
-			    {
-			      changed = visit_nary_op (lhs, stmt);
-			      break;
-			    }
-			  changed = defs_to_varying (stmt);
-			}
+		    case VN_REFERENCE:
+		      changed = visit_reference_op_load (lhs, rhs1, stmt);
 		      break;
 		    default:
 		      changed = defs_to_varying (stmt);
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	(revision 191247)
+++ gcc/tree-ssa-pre.c	(working copy)
@@ -3922,21 +3922,22 @@  compute_avail (void)
 	      bitmap_value_insert_into_set (AVAIL_OUT (block), e);
 	    }
 
-	  if (gimple_has_side_effects (stmt) || stmt_could_throw_p (stmt))
+	  if (gimple_has_side_effects (stmt)
+	      || stmt_could_throw_p (stmt)
+	      || is_gimple_debug (stmt))
 	    continue;
 
+	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
+	    add_to_exp_gen (block, op);
+
 	  switch (gimple_code (stmt))
 	    {
 	    case GIMPLE_RETURN:
-	      FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
-		add_to_exp_gen (block, op);
 	      continue;
 
 	    case GIMPLE_CALL:
 	      {
 		vn_reference_t ref;
-		unsigned int i;
-		vn_reference_op_t vro;
 		pre_expr result = NULL;
 		VEC(vn_reference_op_s, heap) *ops = NULL;
 
@@ -3952,18 +3953,6 @@  compute_avail (void)
 		if (!ref)
 		  continue;
 
-		for (i = 0; VEC_iterate (vn_reference_op_s,
-					 ref->operands, i,
-					 vro); i++)
-		  {
-		    if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
-		      add_to_exp_gen (block, vro->op0);
-		    if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
-		      add_to_exp_gen (block, vro->op1);
-		    if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
-		      add_to_exp_gen (block, vro->op2);
-		  }
-
 		/* If the value of the call is not invalidated in
 		   this block until it is computed, add the expression
 		   to EXP_GEN.  */
@@ -3988,28 +3977,19 @@  compute_avail (void)
 	    case GIMPLE_ASSIGN:
 	      {
 		pre_expr result = NULL;
-		switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
+		switch (vn_get_stmt_kind (stmt))
 		  {
-		  case tcc_unary:
-		  case tcc_binary:
-		  case tcc_comparison:
+		  case VN_NARY:
 		    {
 		      vn_nary_op_t nary;
-		      unsigned int i;
-
 		      vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1,
 						gimple_assign_rhs_code (stmt),
 						gimple_expr_type (stmt),
 						gimple_assign_rhs1_ptr (stmt),
 						&nary);
-
 		      if (!nary)
 			continue;
 
-		      for (i = 0; i < nary->length; i++)
-			if (TREE_CODE (nary->op[i]) == SSA_NAME)
-			  add_to_exp_gen (block, nary->op[i]);
-
 		      /* If the NARY traps and there was a preceding
 		         point in the block that might not return avoid
 			 adding the nary to EXP_GEN.  */
@@ -4024,31 +4004,15 @@  compute_avail (void)
 		      break;
 		    }
 
-		  case tcc_declaration:
-		  case tcc_reference:
+		  case VN_REFERENCE:
 		    {
 		      vn_reference_t ref;
-		      unsigned int i;
-		      vn_reference_op_t vro;
-
 		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
 					   gimple_vuse (stmt),
 					   VN_WALK, &ref);
 		      if (!ref)
 			continue;
 
-		      for (i = 0; VEC_iterate (vn_reference_op_s,
-					       ref->operands, i,
-					       vro); i++)
-			{
-			  if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
-			    add_to_exp_gen (block, vro->op0);
-			  if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
-			    add_to_exp_gen (block, vro->op1);
-			  if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
-			    add_to_exp_gen (block, vro->op2);
-			}
-
 		      /* If the value of the reference is not invalidated in
 			 this block until it is computed, add the expression
 			 to EXP_GEN.  */
@@ -4082,18 +4046,12 @@  compute_avail (void)
 		    }
 
 		  default:
-		    /* For any other statement that we don't
-		       recognize, simply add all referenced
-		       SSA_NAMEs to EXP_GEN.  */
-		    FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
-		      add_to_exp_gen (block, op);
 		    continue;
 		  }
 
 		get_or_alloc_expression_id (result);
 		add_to_value (get_expr_value_id (result), result);
 		bitmap_value_insert_into_set (EXP_GEN (block), result);
-
 		continue;
 	      }
 	    default:
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-37.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-37.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-37.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+int a[256];
+int *b, *c;
+void foo (int i, int j)
+{
+  b = &a[i+j];
+  c = &a[i+j];
+}
+
+/* We should remove the redundant address computation.  */
+
+/* { dg-final { scan-tree-dump-times " = &a" 1 "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */