[PATCH] Don't reject TER unnecessarily (PRs middle-end/58956, middle-end/59470)

Jakub Jelinek jakub@redhat.com
Sat Dec 14 11:03:00 GMT 2013


On Fri, Dec 13, 2013 at 09:47:20AM +0100, Richard Biener wrote:
> Jakub Jelinek <jakub@redhat.com> wrote:
> >On Fri, Dec 13, 2013 at 07:30:12AM +0100, Richard Biener wrote:
> >> Jakub Jelinek <jakub@redhat.com> wrote:
> >> >lhs of a call for calls or somewhere in output arguments of inline
> >asm.
> >> 
> >> Can you please simply use walk_stmt_load_store_ops to get at the stmt
> >outputs?
> >
> >No, unfortunately.  The problem is that
> >walk_stmt_load_store_{addr_,}ops first
> >calls and get_base_loadstore on the operand and thus effectively strips
> >all the
> >handled components from it. 
> 
> That's a defficiency of that function then which we should fix, for
> example with either passing both to the callback or by adding a flag.

Ok, this patch implements the former (passing both the base (as before) and
the gimple operand tree that is either equal to the base or contains the
base.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2013-12-14  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/58956
	PR middle-end/59470
	* gimple-walk.h (walk_stmt_load_store_addr_fn): New typedef.
	(walk_stmt_load_store_addr_ops, walk_stmt_load_store_ops): Use it
	for callback params.
	* gimple-walk.c (walk_stmt_load_store_ops): Likewise.
	(walk_stmt_load_store_addr_ops): Likewise.  Adjust all callback
	calls to supply the gimple operand containing the base tree
	as an extra argument.
	* tree-ssa-ter.c: Include gimple-walk.h.
	(find_ssaname, find_ssaname_in_store): New helper functions.
	(find_replaceable_in_bb): For calls or GIMPLE_ASM, only set
	same_root_var if USE is used somewhere in the stores of the stmt.
	* ipa-prop.c (visit_ref_for_mod_analysis): Remove name of the stmt
	argument and ATTRIBUTE_UNUSED, add another unnamed tree argument.
	* ipa-pure-const.c (check_load, check_store, check_ipa_load,
	check_ipa_store): Likewise.
	* gimple.c (gimple_ior_addresses_taken_1, check_loadstore): Likewise.
	* ipa-split.c (test_nonssa_use, mark_nonssa_use): Likewise.
	(verify_non_ssa_vars, visit_bb): Adjust their callers.
	* cfgexpand.c (add_scope_conflicts_1): Use
	walk_stmt_load_store_addr_fn type for visit variable.
	(visit_op, visit_conflict): Remove name of the stmt
	argument and ATTRIBUTE_UNUSED, add another unnamed tree argument.
	* tree-sra.c (asm_visit_addr): Likewise.  Remove name of the data
	argument and ATTRIBUTE_UNUSED.
	* cgraphbuild.c (mark_address, mark_load, mark_store): Add another
	unnamed tree argument.
	* gimple-ssa-isolate-paths.c (check_loadstore): Likewise.  Remove
	ATTRIBUTE_UNUSED from stmt parameter.

	* gcc.target/i386/pr59470.c: New test.

--- gcc/gimple-walk.h.jj	2013-11-14 09:10:01.000000000 +0100
+++ gcc/gimple-walk.h	2013-12-13 17:11:15.446033263 +0100
@@ -89,11 +89,12 @@ extern gimple walk_gimple_seq (gimple_se
 extern tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *);
 extern tree walk_gimple_stmt (gimple_stmt_iterator *, walk_stmt_fn,
 			      walk_tree_fn, struct walk_stmt_info *);
+typedef bool (*walk_stmt_load_store_addr_fn) (gimple, tree, tree, void *);
 extern bool walk_stmt_load_store_addr_ops (gimple, void *,
-					   bool (*)(gimple, tree, void *),
-					   bool (*)(gimple, tree, void *),
-					   bool (*)(gimple, tree, void *));
+					   walk_stmt_load_store_addr_fn,
+					   walk_stmt_load_store_addr_fn,
+					   walk_stmt_load_store_addr_fn);
 extern bool walk_stmt_load_store_ops (gimple, void *,
-				      bool (*)(gimple, tree, void *),
-				      bool (*)(gimple, tree, void *));
+				      walk_stmt_load_store_addr_fn,
+				      walk_stmt_load_store_addr_fn);
 #endif /* GCC_GIMPLE_WALK_H */
--- gcc/gimple-walk.c.jj	2013-11-22 21:03:03.000000000 +0100
+++ gcc/gimple-walk.c	2013-12-13 17:11:15.452033280 +0100
@@ -649,42 +649,46 @@ get_base_loadstore (tree op)
 
 /* For the statement STMT call the callbacks VISIT_LOAD, VISIT_STORE and
    VISIT_ADDR if non-NULL on loads, store and address-taken operands
-   passing the STMT, the base of the operand and DATA to it.  The base
-   will be either a decl, an indirect reference (including TARGET_MEM_REF)
-   or the argument of an address expression.
+   passing the STMT, the base of the operand, the operand itself containing
+   the base and DATA to it.  The base will be either a decl, an indirect
+   reference (including TARGET_MEM_REF) or the argument of an address
+   expression.
    Returns the results of these callbacks or'ed.  */
 
 bool
 walk_stmt_load_store_addr_ops (gimple stmt, void *data,
-			       bool (*visit_load)(gimple, tree, void *),
-			       bool (*visit_store)(gimple, tree, void *),
-			       bool (*visit_addr)(gimple, tree, void *))
+			       walk_stmt_load_store_addr_fn visit_load,
+			       walk_stmt_load_store_addr_fn visit_store,
+			       walk_stmt_load_store_addr_fn visit_addr)
 {
   bool ret = false;
   unsigned i;
   if (gimple_assign_single_p (stmt))
     {
-      tree lhs, rhs;
+      tree lhs, rhs, arg;
       if (visit_store)
 	{
-	  lhs = get_base_loadstore (gimple_assign_lhs (stmt));
+	  arg = gimple_assign_lhs (stmt);
+	  lhs = get_base_loadstore (arg);
 	  if (lhs)
-	    ret |= visit_store (stmt, lhs, data);
+	    ret |= visit_store (stmt, lhs, arg, data);
 	}
-      rhs = gimple_assign_rhs1 (stmt);
+      arg = gimple_assign_rhs1 (stmt);
+      rhs = arg;
       while (handled_component_p (rhs))
 	rhs = TREE_OPERAND (rhs, 0);
       if (visit_addr)
 	{
 	  if (TREE_CODE (rhs) == ADDR_EXPR)
-	    ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
+	    ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), arg, data);
 	  else if (TREE_CODE (rhs) == TARGET_MEM_REF
 		   && TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
-	    ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
+	    ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), arg,
+			       data);
 	  else if (TREE_CODE (rhs) == OBJ_TYPE_REF
 		   && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR)
 	    ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs),
-						   0), data);
+						   0), arg, data);
 	  else if (TREE_CODE (rhs) == CONSTRUCTOR)
 	    {
 	      unsigned int ix;
@@ -692,23 +696,23 @@ walk_stmt_load_store_addr_ops (gimple st
 
 	      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), ix, val)
 		if (TREE_CODE (val) == ADDR_EXPR)
-		  ret |= visit_addr (stmt, TREE_OPERAND (val, 0), data);
+		  ret |= visit_addr (stmt, TREE_OPERAND (val, 0), arg, data);
 		else if (TREE_CODE (val) == OBJ_TYPE_REF
 			 && TREE_CODE (OBJ_TYPE_REF_OBJECT (val)) == ADDR_EXPR)
 		  ret |= visit_addr (stmt,
 				     TREE_OPERAND (OBJ_TYPE_REF_OBJECT (val),
-						   0), data);
+						   0), arg, data);
 	    }
           lhs = gimple_assign_lhs (stmt);
 	  if (TREE_CODE (lhs) == TARGET_MEM_REF
               && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
-            ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
+	    ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), lhs, data);
 	}
       if (visit_load)
 	{
 	  rhs = get_base_loadstore (rhs);
 	  if (rhs)
-	    ret |= visit_load (stmt, rhs, data);
+	    ret |= visit_load (stmt, rhs, arg, data);
 	}
     }
   else if (visit_addr
@@ -721,17 +725,17 @@ walk_stmt_load_store_addr_ops (gimple st
 	  if (op == NULL_TREE)
 	    ;
 	  else if (TREE_CODE (op) == ADDR_EXPR)
-	    ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+	    ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
 	  /* COND_EXPR and VCOND_EXPR rhs1 argument is a comparison
 	     tree with two operands.  */
 	  else if (i == 1 && COMPARISON_CLASS_P (op))
 	    {
 	      if (TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
 		ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 0),
-						       0), data);
+						       0), op, data);
 	      if (TREE_CODE (TREE_OPERAND (op, 1)) == ADDR_EXPR)
 		ret |= visit_addr (stmt, TREE_OPERAND (TREE_OPERAND (op, 1),
-						       0), data);
+						       0), op, data);
 	    }
 	}
     }
@@ -739,38 +743,39 @@ walk_stmt_load_store_addr_ops (gimple st
     {
       if (visit_store)
 	{
-	  tree lhs = gimple_call_lhs (stmt);
-	  if (lhs)
+	  tree arg = gimple_call_lhs (stmt);
+	  if (arg)
 	    {
-	      lhs = get_base_loadstore (lhs);
+	      tree lhs = get_base_loadstore (arg);
 	      if (lhs)
-		ret |= visit_store (stmt, lhs, data);
+		ret |= visit_store (stmt, lhs, arg, data);
 	    }
 	}
       if (visit_load || visit_addr)
 	for (i = 0; i < gimple_call_num_args (stmt); ++i)
 	  {
-	    tree rhs = gimple_call_arg (stmt, i);
+	    tree arg = gimple_call_arg (stmt, i);
 	    if (visit_addr
-		&& TREE_CODE (rhs) == ADDR_EXPR)
-	      ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
+		&& TREE_CODE (arg) == ADDR_EXPR)
+	      ret |= visit_addr (stmt, TREE_OPERAND (arg, 0), arg, data);
 	    else if (visit_load)
 	      {
-		rhs = get_base_loadstore (rhs);
+		tree rhs = get_base_loadstore (arg);
 		if (rhs)
-		  ret |= visit_load (stmt, rhs, data);
+		  ret |= visit_load (stmt, rhs, arg, data);
 	      }
 	  }
       if (visit_addr
 	  && gimple_call_chain (stmt)
 	  && TREE_CODE (gimple_call_chain (stmt)) == ADDR_EXPR)
 	ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (stmt), 0),
-			   data);
+			   gimple_call_chain (stmt), data);
       if (visit_addr
 	  && gimple_call_return_slot_opt_p (stmt)
 	  && gimple_call_lhs (stmt) != NULL_TREE
 	  && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (stmt))))
-	ret |= visit_addr (stmt, gimple_call_lhs (stmt), data);
+	ret |= visit_addr (stmt, gimple_call_lhs (stmt),
+			   gimple_call_lhs (stmt), data);
     }
   else if (gimple_code (stmt) == GIMPLE_ASM)
     {
@@ -786,7 +791,7 @@ walk_stmt_load_store_addr_ops (gimple st
 	    tree link = gimple_asm_output_op (stmt, i);
 	    tree op = get_base_loadstore (TREE_VALUE (link));
 	    if (op && visit_store)
-	      ret |= visit_store (stmt, op, data);
+	      ret |= visit_store (stmt, op, TREE_VALUE (link), data);
 	    if (visit_addr)
 	      {
 		constraint = TREE_STRING_POINTER
@@ -795,7 +800,7 @@ walk_stmt_load_store_addr_ops (gimple st
 		parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
 					 &allows_reg, &is_inout);
 		if (op && !allows_reg && allows_mem)
-		  ret |= visit_addr (stmt, op, data);
+		  ret |= visit_addr (stmt, op, TREE_VALUE (link), data);
 	      }
 	  }
       if (visit_load || visit_addr)
@@ -805,14 +810,14 @@ walk_stmt_load_store_addr_ops (gimple st
 	    tree op = TREE_VALUE (link);
 	    if (visit_addr
 		&& TREE_CODE (op) == ADDR_EXPR)
-	      ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+	      ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
 	    else if (visit_load || visit_addr)
 	      {
 		op = get_base_loadstore (op);
 		if (op)
 		  {
 		    if (visit_load)
-		      ret |= visit_load (stmt, op, data);
+		      ret |= visit_load (stmt, op, TREE_VALUE (link), data);
 		    if (visit_addr)
 		      {
 			constraint = TREE_STRING_POINTER
@@ -821,7 +826,8 @@ walk_stmt_load_store_addr_ops (gimple st
 						0, oconstraints,
 						&allows_mem, &allows_reg);
 			if (!allows_reg && allows_mem)
-			  ret |= visit_addr (stmt, op, data);
+			  ret |= visit_addr (stmt, op, TREE_VALUE (link),
+					     data);
 		      }
 		  }
 	      }
@@ -834,12 +840,12 @@ walk_stmt_load_store_addr_ops (gimple st
 	{
 	  if (visit_addr
 	      && TREE_CODE (op) == ADDR_EXPR)
-	    ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+	    ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
 	  else if (visit_load)
 	    {
-	      op = get_base_loadstore (op);
-	      if (op)
-		ret |= visit_load (stmt, op, data);
+	      tree base = get_base_loadstore (op);
+	      if (base)
+		ret |= visit_load (stmt, base, op, data);
 	    }
 	}
     }
@@ -850,7 +856,7 @@ walk_stmt_load_store_addr_ops (gimple st
 	{
 	  tree op = gimple_phi_arg_def (stmt, i);
 	  if (TREE_CODE (op) == ADDR_EXPR)
-	    ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+	    ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
 	}
     }
   else if (visit_addr
@@ -858,7 +864,7 @@ walk_stmt_load_store_addr_ops (gimple st
     {
       tree op = gimple_goto_dest (stmt);
       if (TREE_CODE (op) == ADDR_EXPR)
-	ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+	ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
     }
 
   return ret;
@@ -869,8 +875,8 @@ walk_stmt_load_store_addr_ops (gimple st
 
 bool
 walk_stmt_load_store_ops (gimple stmt, void *data,
-			  bool (*visit_load)(gimple, tree, void *),
-			  bool (*visit_store)(gimple, tree, void *))
+			  walk_stmt_load_store_addr_fn visit_load,
+			  walk_stmt_load_store_addr_fn visit_store)
 {
   return walk_stmt_load_store_addr_ops (stmt, data,
 					visit_load, visit_store, NULL);
--- gcc/tree-ssa-ter.c.jj	2013-12-12 14:28:19.973262682 +0100
+++ gcc/tree-ssa-ter.c	2013-12-13 17:11:15.435033099 +0100
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.
 #include "tree-ssa-ter.h"
 #include "tree-outof-ssa.h"
 #include "flags.h"
+#include "gimple-walk.h"
 
 
 /* Temporary Expression Replacement (TER)
@@ -554,6 +555,30 @@ mark_replaceable (temp_expr_table_p tab,
 }
 
 
+/* Helper function for find_ssaname_in_stores.  Called via walk_tree to
+   find a SSA_NAME DATA somewhere in *TP.  */
+
+static tree
+find_ssaname (tree *tp, int *walk_subtrees, void *data)
+{
+  tree var = (tree) data;
+  if (*tp == var)
+    return var;
+  else if (IS_TYPE_OR_DECL_P (*tp))
+    *walk_subtrees = 0;
+  return NULL_TREE;
+}
+
+/* Helper function for find_replaceable_in_bb.  Return true if SSA_NAME DATA
+   is used somewhere in T, which is a store in the statement.  Called via
+   walk_stmt_load_store_addr_ops.  */
+
+static bool
+find_ssaname_in_store (gimple, tree, tree t, void *data)
+{
+  return walk_tree (&t, find_ssaname, data, NULL) != NULL_TREE;
+}
+
 /* This function processes basic block BB, and looks for variables which can
    be replaced by their expressions.  Results are stored in the table TAB.  */
 
@@ -618,7 +643,27 @@ find_replaceable_in_bb (temp_expr_table_
 		      && gimple_assign_single_p (def_stmt)
 		      && stmt_may_clobber_ref_p (stmt,
 						 gimple_assign_rhs1 (def_stmt)))
-		    same_root_var = true;
+		    {
+		      /* For calls, it is not a problem if USE is among
+			 call's arguments or say OBJ_TYPE_REF argument,
+			 all those necessarily need to be evaluated before
+			 the call that may clobber the memory.  But if
+			 LHS of the call refers to USE, expansion might
+			 evaluate it after the call, prevent TER in that
+			 case.
+			 For inline asm, allow TER of loads into input
+			 arguments, but disallow TER for USEs that occur
+			 somewhere in outputs.  */
+		      if (is_gimple_call (stmt)
+			  || gimple_code (stmt) == GIMPLE_ASM)
+			{
+			  if (walk_stmt_load_store_ops (stmt, use, NULL,
+							find_ssaname_in_store))
+			    same_root_var = true;
+			}
+		      else
+			same_root_var = true;
+		    }
 		}
 
 	      /* Mark expression as replaceable unless stmt is volatile, or the
--- gcc/ipa-prop.c.jj	2013-12-11 10:11:06.000000000 +0100
+++ gcc/ipa-prop.c	2013-12-13 17:11:15.437033150 +0100
@@ -2050,8 +2050,7 @@ ipa_analyze_stmt_uses (struct cgraph_nod
    passed in DATA.  */
 
 static bool
-visit_ref_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED,
-			     tree op, void *data)
+visit_ref_for_mod_analysis (gimple, tree op, tree, void *data)
 {
   struct ipa_node_params *info = (struct ipa_node_params *) data;
 
--- gcc/tree-sra.c.jj	2013-12-10 08:52:13.000000000 +0100
+++ gcc/tree-sra.c	2013-12-13 17:11:15.439033191 +0100
@@ -1223,8 +1223,7 @@ build_accesses_from_assign (gimple stmt)
    GIMPLE_ASM operands with memory constrains which cannot be scalarized.  */
 
 static bool
-asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
-		void *data ATTRIBUTE_UNUSED)
+asm_visit_addr (gimple, tree op, tree, void *)
 {
   op = get_base_address (op);
   if (op
--- gcc/ipa-pure-const.c.jj	2013-12-10 08:52:09.000000000 +0100
+++ gcc/ipa-pure-const.c	2013-12-13 17:11:15.442033229 +0100
@@ -589,7 +589,7 @@ check_call (funct_state local, gimple ca
 /* Wrapper around check_decl for loads in local more.  */
 
 static bool
-check_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+check_load (gimple, tree op, tree, void *data)
 {
   if (DECL_P (op))
     check_decl ((funct_state)data, op, false, false);
@@ -601,7 +601,7 @@ check_load (gimple stmt ATTRIBUTE_UNUSED
 /* Wrapper around check_decl for stores in local more.  */
 
 static bool
-check_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+check_store (gimple, tree op, tree, void *data)
 {
   if (DECL_P (op))
     check_decl ((funct_state)data, op, true, false);
@@ -613,7 +613,7 @@ check_store (gimple stmt ATTRIBUTE_UNUSE
 /* Wrapper around check_decl for loads in ipa mode.  */
 
 static bool
-check_ipa_load (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+check_ipa_load (gimple, tree op, tree, void *data)
 {
   if (DECL_P (op))
     check_decl ((funct_state)data, op, false, true);
@@ -625,7 +625,7 @@ check_ipa_load (gimple stmt ATTRIBUTE_UN
 /* Wrapper around check_decl for stores in ipa mode.  */
 
 static bool
-check_ipa_store (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+check_ipa_store (gimple, tree op, tree, void *data)
 {
   if (DECL_P (op))
     check_decl ((funct_state)data, op, true, true);
--- gcc/gimple.c.jj	2013-12-10 08:52:13.000000000 +0100
+++ gcc/gimple.c	2013-12-13 17:11:15.444033243 +0100
@@ -2326,8 +2326,7 @@ gimple_get_alias_set (tree t)
 /* Helper for gimple_ior_addresses_taken_1.  */
 
 static bool
-gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED,
-			      tree addr, void *data)
+gimple_ior_addresses_taken_1 (gimple, tree addr, tree, void *data)
 {
   bitmap addresses_taken = (bitmap)data;
   addr = get_base_address (addr);
@@ -2496,7 +2495,7 @@ nonfreeing_call_p (gimple call)
    This routine only makes a superficial check for a dereference.  Thus
    it must only be used if it is safe to return a false negative.  */
 static bool
-check_loadstore (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+check_loadstore (gimple, tree op, tree, void *data)
 {
   if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
       && operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0))
--- gcc/cgraphbuild.c.jj	2013-12-10 08:52:06.000000000 +0100
+++ gcc/cgraphbuild.c	2013-12-13 17:11:15.448033272 +0100
@@ -224,7 +224,7 @@ compute_call_stmt_bb_frequency (tree dec
 /* Mark address taken in STMT.  */
 
 static bool
-mark_address (gimple stmt, tree addr, void *data)
+mark_address (gimple stmt, tree addr, tree, void *data)
 {
   addr = get_base_address (addr);
   if (TREE_CODE (addr) == FUNCTION_DECL)
@@ -251,7 +251,7 @@ mark_address (gimple stmt, tree addr, vo
 /* Mark load of T.  */
 
 static bool
-mark_load (gimple stmt, tree t, void *data)
+mark_load (gimple stmt, tree t, tree, void *data)
 {
   t = get_base_address (t);
   if (t && TREE_CODE (t) == FUNCTION_DECL)
@@ -279,7 +279,7 @@ mark_load (gimple stmt, tree t, void *da
 /* Mark store of T.  */
 
 static bool
-mark_store (gimple stmt, tree t, void *data)
+mark_store (gimple stmt, tree t, tree, void *data)
 {
   t = get_base_address (t);
   if (t && TREE_CODE (t) == VAR_DECL
--- gcc/gimple-ssa-isolate-paths.c.jj	2013-12-10 08:52:13.000000000 +0100
+++ gcc/gimple-ssa-isolate-paths.c	2013-12-13 17:11:15.450033285 +0100
@@ -55,7 +55,7 @@ static bool cfg_altered;
    This routine only makes a superficial check for a dereference.  Thus,
    it must only be used if it is safe to return a false negative.  */
 static bool
-check_loadstore (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+check_loadstore (gimple stmt, tree op, tree, void *data)
 {
   if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
       && operand_equal_p (TREE_OPERAND (op, 0), (tree)data, 0))
--- gcc/ipa-split.c.jj	2013-12-10 08:52:13.000000000 +0100
+++ gcc/ipa-split.c	2013-12-13 17:11:15.454033263 +0100
@@ -156,7 +156,7 @@ static tree find_retval (basic_block ret
    variable, check it if it is present in bitmap passed via DATA.  */
 
 static bool
-test_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
+test_nonssa_use (gimple, tree t, tree, void *data)
 {
   t = get_base_address (t);
 
@@ -249,7 +249,7 @@ verify_non_ssa_vars (struct split_point
 	    }
 	  if (gimple_code (stmt) == GIMPLE_LABEL
 	      && test_nonssa_use (stmt, gimple_label_label (stmt),
-				  non_ssa_vars))
+				  NULL_TREE, non_ssa_vars))
 	  {
 	    ok = false;
 	    goto done;
@@ -278,7 +278,7 @@ verify_non_ssa_vars (struct split_point
 	      if (virtual_operand_p (gimple_phi_result (stmt)))
 		continue;
 	      if (TREE_CODE (op) != SSA_NAME
-		  && test_nonssa_use (stmt, op, non_ssa_vars))
+		  && test_nonssa_use (stmt, op, op, non_ssa_vars))
 		{
 		  ok = false;
 		  goto done;
@@ -714,7 +714,7 @@ find_retval (basic_block return_bb)
    Return true when access to T prevents splitting the function.  */
 
 static bool
-mark_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data)
+mark_nonssa_use (gimple, tree t, tree, void *data)
 {
   t = get_base_address (t);
 
@@ -874,7 +874,7 @@ visit_bb (basic_block bb, basic_block re
 	    if (TREE_CODE (op) == SSA_NAME)
 	      bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op));
 	    else
-	      can_split &= !mark_nonssa_use (stmt, op, non_ssa_vars);
+	      can_split &= !mark_nonssa_use (stmt, op, op, non_ssa_vars);
 	  }
       }
   return can_split;
--- gcc/cfgexpand.c.jj	2013-12-10 08:52:13.000000000 +0100
+++ gcc/cfgexpand.c	2013-12-13 17:11:15.458033241 +0100
@@ -365,7 +365,7 @@ stack_var_conflict_p (size_t x, size_t y
    enter its partition number into bitmap DATA.  */
 
 static bool
-visit_op (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+visit_op (gimple, tree op, tree, void *data)
 {
   bitmap active = (bitmap)data;
   op = get_base_address (op);
@@ -385,7 +385,7 @@ visit_op (gimple stmt ATTRIBUTE_UNUSED,
    from bitmap DATA.  */
 
 static bool
-visit_conflict (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data)
+visit_conflict (gimple, tree op, tree, void *data)
 {
   bitmap active = (bitmap)data;
   op = get_base_address (op);
@@ -419,7 +419,7 @@ add_scope_conflicts_1 (basic_block bb, b
   edge e;
   edge_iterator ei;
   gimple_stmt_iterator gsi;
-  bool (*visit)(gimple, tree, void *);
+  walk_stmt_load_store_addr_fn visit;
 
   bitmap_clear (work);
   FOR_EACH_EDGE (e, ei, bb->preds)
--- gcc/testsuite/gcc.target/i386/pr59470.c.jj	2013-12-13 16:31:03.150846267 +0100
+++ gcc/testsuite/gcc.target/i386/pr59470.c	2013-12-13 17:11:15.456033250 +0100
@@ -0,0 +1,17 @@
+/* PR middle-end/58956 */
+/* PR middle-end/59470 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int a, b, d[1024];
+
+int
+main ()
+{
+  int c = a;
+  asm ("{movl $6, (%2); movl $1, %0|mov dword ptr [%2], 6; mov %0, 1}"
+       : "=r" (d[c]) : "rm" (b), "r" (&a) : "memory");
+  if (d[0] != 1 || d[6] != 0)
+    __builtin_abort ();
+  return 0;
+}


	Jakub



More information about the Gcc-patches mailing list