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]

[tree-ssa] Fix for volatile handling and PR11373 [patch]


Fixes handling of volatile attributes.  Jason changed the gimplifier to
promote volatile attributes to the expressions on the LHS and RHS of
expressions.  This change allows the compiler to detect if the statement
makes volatile references by simply checking if the LHS or RHS of an
assignment are volatile.

It also partially fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11373
We were not marking pointers modified by __asm__ expressions as pointers
that may be pointing to global memory.

The other test case reported in PR11373 is in my queue.  It's basically
this:

foo()
{
   int *p = 0xdeadbeef;
   *p = 3;
}

We are currently killing '*p = 3;'.  I'm no language lawyer, but I've
been told that the above is implementation defined and that a reasonable
default behaviour would be to mark pointer 'p' as 'may point to global
memory'.  This will prevent DCE from killing it.

The patch should also fix the problem reported by dberlin.  The
propagation of ADDR_EXPR was also being done even when the dominator
optimizations were switched off.  This is because we were allowing the
CCP pass from exposing them.  Since propagating ADDR_EXPRs break SSA and
GIMPLE, they should be contained and done only when we are ready to
repair the damage.

Finally, a minor optimization.  In avail_expr_eq, if both statements are
the same pointer, return true without further checks.

Bootstrapped and tested on x86.


Diego.

2003-07-15  Diego Novillo  <dnovillo@redhat.com>

	* tree-dfa.c (add_stmt_operand): Move volatile handling...
	(find_vars_r): ... here.
	Mark when the walker is inside an ASM_EXPR.
	(struct walk_state): Add field 'is_asm_expr'.
	Change flag fields to bitfields.
	(add_referenced_var): If the variable is a pointer being stored by
	an ASM_EXPR, mark it as a global memory pointer.
	* tree-flow-inline.h (is_optimizable_addr_expr): New function.
	* tree-flow.h (is_optimizable_addr_expr): Declare it.
	* tree-ssa.c (rewrite_and_optimize_stmt): Use it.
	(lookup_avail_expr): Likewise.
	(get_eq_expr_value): Likewise.
	(avail_expr_eq): Return 'true' when comparing a statement against
	itself.
	* tree-ssa-dce.c (need_to_preserve_store): Move volatile checking...
	(stmt_useful_p): ...here.

Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.128
diff -d -u -p -r1.1.4.128 tree-dfa.c
--- tree-dfa.c	14 Jul 2003 22:22:19 -0000	1.1.4.128
+++ tree-dfa.c	15 Jul 2003 16:12:07 -0000
@@ -89,10 +89,13 @@ struct walk_state
   htab_t vars_found;
 
   /* Nonzero if the variables found under the current tree are written to.  */
-  int is_store;
+  int is_store : 1;
 
   /* Nonzero if the walker is inside an INDIRECT_REF node.  */
-  int is_indirect_ref;
+  int is_indirect_ref : 1;
+
+  /* Nonzero if the walker is inside an ASM_EXPR node.  */
+  int is_asm_expr : 1;
 };
 
 
@@ -609,11 +612,6 @@ add_stmt_operand (tree *var_p, tree stmt
   if (v_ann->is_alias_tag)
     flags |= opf_force_vop;
 
-  /* If the variable is volatile, inform the statement that it makes
-      volatile storage references.  */
-  if (TREE_THIS_VOLATILE (var))
-    s_ann->has_volatile_ops = 1;
-
   aliases = v_ann->may_aliases;
   if (aliases == NULL)
     {
@@ -1682,6 +1680,7 @@ compute_may_aliases (tree fndecl)
   walk_state.vars_found = vars_found;
   walk_state.is_store = 0;
   walk_state.is_indirect_ref = 0;
+  walk_state.is_asm_expr = 0;
 
   /* Find all the variables referenced in the function.  */
   FOR_EACH_BB (bb)
@@ -2163,16 +2162,23 @@ find_vars_r (tree *tp, int *walk_subtree
 	  && may_access_global_mem_p (TREE_OPERAND (t, 1)))
 	set_may_point_to_global_mem (TREE_OPERAND (t, 0));
 
+      /* If either side makes volatile references, mark the statement.  */
+      if (TREE_THIS_VOLATILE (TREE_OPERAND (t, 0))
+	  || TREE_THIS_VOLATILE (TREE_OPERAND (t, 1)))
+	get_stmt_ann (t)->has_volatile_ops = 1;
+
       return t;
     }
   else if (TREE_CODE (t) == ASM_EXPR)
     {
+      walk_state->is_asm_expr = 1;
       walk_state->is_store = 1;
       walk_tree (&ASM_OUTPUTS (t), find_vars_r, data, NULL);
       walk_tree (&ASM_CLOBBERS (t), find_vars_r, data, NULL);
       walk_state->is_store = 0;
       walk_tree (&ASM_INPUTS (t), find_vars_r, data, NULL);
       walk_state->is_store = saved_is_store;
+      walk_state->is_asm_expr = 0;
       return t;
     }
   else if (TREE_CODE (t) == INDIRECT_REF)
@@ -2296,6 +2302,13 @@ add_referenced_var (tree var, struct wal
      stores to keep track of.  */
   if (walk_state->is_store)
     v_ann->is_stored = 1;
+
+  /* If the variable is a pointer being clobbered by an ASM_EXPR, the
+     pointer may end up pointing to global memory.  */
+  if (POINTER_TYPE_P (TREE_TYPE (var))
+      && walk_state->is_store
+      && walk_state->is_asm_expr)
+    v_ann->may_point_to_global_mem = 1;
 
   /* If VAR is a pointer referenced in an INDIRECT_REF node, create (or
      re-use) a memory tag to represent the location pointed-to by VAR.  */
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.41
diff -d -u -p -r1.1.2.41 tree-flow-inline.h
--- tree-flow-inline.h	15 Jul 2003 03:13:40 -0000	1.1.2.41
+++ tree-flow-inline.h	15 Jul 2003 16:12:07 -0000
@@ -502,14 +502,19 @@ empty_bsi_stack (bsi_list_p list)
 static inline bool
 is_unchanging_value (tree val)
 {
+  return ((TREE_CONSTANT (val) || really_constant_p (val))
+	  && is_gimple_val (val));
+}
+
+static inline bool
+is_optimizable_addr_expr (tree val)
+{
   /* FIXME: It should be possible to accept type-casted ADDR_EXPRs if we
      made sure that the folded INDIRECT_REF kept the type-cast.  See for
      instance, gcc.c-torture/compile/990203-1.c.  */
-  return ((TREE_CODE (val) == ADDR_EXPR
-	   && (TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL
-	       || TREE_CODE (TREE_OPERAND (val, 0)) == PARM_DECL))
-          || ((TREE_CONSTANT (val) || really_constant_p (val))
-	      && is_gimple_val (val)));
+  return (TREE_CODE (val) == ADDR_EXPR
+	  && (TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL
+	      || TREE_CODE (TREE_OPERAND (val, 0)) == PARM_DECL));
 }
 
 #endif /* _TREE_FLOW_INLINE_H  */
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.90
diff -d -u -p -r1.1.4.90 tree-flow.h
--- tree-flow.h	15 Jul 2003 03:13:40 -0000	1.1.4.90
+++ tree-flow.h	15 Jul 2003 16:12:08 -0000
@@ -483,7 +483,8 @@ void propagate_copy (tree *, tree);
 /* In tree-flow-inline.h  */
 static inline int phi_arg_from_edge (tree, edge);
 static inline struct phi_arg_d *phi_element_for_edge (tree, edge);
-static inline bool is_unchanging_value (tree val);
+static inline bool is_unchanging_value (tree);
+static inline bool is_optimizable_addr_expr (tree);
 
 
 /* In tree-must-alias.c  */
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.45
diff -d -u -p -r1.1.2.45 tree-ssa-dce.c
--- tree-ssa-dce.c	14 Jul 2003 21:18:48 -0000	1.1.2.45
+++ tree-ssa-dce.c	15 Jul 2003 16:12:08 -0000
@@ -193,10 +193,6 @@ need_to_preserve_store (tree var)
   sym = SSA_NAME_VAR (var);
   base_symbol = get_base_symbol (var);
 
-  /* Stores to volatiles must be preserved.  */
-  if (TREE_THIS_VOLATILE (sym))
-    return true;
-
   /* File scope variables must be preserved.  */
   if (decl_function_context (base_symbol) == NULL)
     return true;
@@ -289,6 +285,10 @@ stmt_useful_p (tree stmt)
 	  if (e->dest == EXIT_BLOCK_PTR && e->flags & EDGE_ABNORMAL)
 	    return true;
     }
+
+  /* If the statement has volatile operands, it needs to be preserved.  */
+  if (stmt_ann (stmt)->has_volatile_ops)
+    return true;
 
   /* Examine all the stores in this statement.  */
   get_stmt_operands (stmt);
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.101
diff -d -u -p -r1.1.4.101 tree-ssa.c
--- tree-ssa.c	14 Jul 2003 21:18:48 -0000	1.1.4.101
+++ tree-ssa.c	15 Jul 2003 16:12:08 -0000
@@ -2193,7 +2193,8 @@ rewrite_and_optimize_stmt (block_stmt_it
       if (val)
 	{
 	  /* Gather statistics.  */
-	  if (is_unchanging_value (val))
+	  if (is_unchanging_value (val)
+	      || is_optimizable_addr_expr (val))
 	    ssa_stats.num_const_prop++;
 	  else
 	    ssa_stats.num_copy_prop++;
@@ -2204,7 +2205,7 @@ rewrite_and_optimize_stmt (block_stmt_it
 	      fprintf (dump_file, "  Replaced '");
 	      print_generic_expr (dump_file, *op_p, 0);
 	      fprintf (dump_file, "' with %s '",
-		       is_unchanging_value (val) ? "constant" : "variable");
+		       TREE_CODE (val) == SSA_NAME ? "variable" : "constant");
 	      print_generic_expr (dump_file, val, 0);
 	      fprintf (dump_file, "'\n");
 	    }
@@ -2292,7 +2293,9 @@ rewrite_and_optimize_stmt (block_stmt_it
       rhs = TREE_OPERAND (stmt, 1);
       if (may_optimize_p)
 	{
-	  if (TREE_CODE (rhs) == SSA_NAME || is_unchanging_value (rhs))
+	  if (TREE_CODE (rhs) == SSA_NAME
+	      || is_unchanging_value (rhs)
+	      || is_optimizable_addr_expr (rhs))
 	    set_value_for (*def_p, rhs, const_and_copies);
 	}
     }
@@ -2762,7 +2765,8 @@ lookup_avail_expr (tree stmt,
      in rewrite_and_optimize_stmt.  */
   rhs = TREE_OPERAND (stmt, 1);
   if (TREE_CODE (rhs) == SSA_NAME
-      || is_unchanging_value (rhs))
+      || is_unchanging_value (rhs)
+      || is_optimizable_addr_expr (rhs))
     return NULL_TREE;
 
   slot = htab_find_slot (avail_exprs, stmt, INSERT);
@@ -2806,6 +2810,7 @@ get_eq_expr_value (tree if_stmt)
   else if (TREE_CODE (cond) == EQ_EXPR
 	   && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
 	   && (is_unchanging_value (TREE_OPERAND (cond, 1))
+	       || is_optimizable_addr_expr (TREE_OPERAND (cond, 1))
 	       || TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME))
     value = build (MODIFY_EXPR, TREE_TYPE (cond),
 		   TREE_OPERAND (cond, 0),
@@ -2860,6 +2865,10 @@ avail_expr_eq (const void *p1, const voi
 
   s2 = (tree) p2;
   rhs2 = TREE_OPERAND (s2, 1);
+
+  /* If they are the same physical statement, return true.  */
+  if (s1 == s2)
+    return true;
 
   /* In case of a collision, both RHS have to be identical and have the
      same VUSE operands.  */



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