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 volatile vs IPA pure/const pass (PR tree-opt/29964)


Hi,
  The problem here is that we don't currently see the tree
pointer->field as volatile if the field is volatile as we had already
skipped down to *pointer which is not volatile.  This patch changes
where the check for volatile is and also adds some more debugging output
in the dump to get the result of the local pass.

OK? Bootstrapped and tested on i686-linux-gnu with no regressions.

Thanks,
Andrew Pinski

ChangeLog:

	* ipa-pure-const.c (check_tree): If the original tree
	is volatile return early and say the function is not pure
	nor const.  Remove the volatile check for writes.  
	(analyze_function): Print out the result of the local
	analysis pass.
Index: ipa-pure-const.c
===================================================================
--- ipa-pure-const.c	(revision 119134)
+++ ipa-pure-const.c	(working copy)
@@ -166,6 +166,14 @@ check_tree (funct_state local, tree t, b
   if ((TREE_CODE (t) == EXC_PTR_EXPR) || (TREE_CODE (t) == FILTER_EXPR))
     return;
 
+  /* Any tree which is volatile disqualifies thie function from being
+     const or pure. */
+  if (TREE_THIS_VOLATILE (t))
+    {
+      local->pure_const_state = IPA_NEITHER;
+      return;
+    }
+
   while (TREE_CODE (t) == REALPART_EXPR 
 	 || TREE_CODE (t) == IMAGPART_EXPR
 	 || handled_component_p (t))
@@ -183,12 +191,13 @@ check_tree (funct_state local, tree t, b
       
       /* Any indirect reference that occurs on the lhs
 	 disqualifies the function from being pure or const. Any
-	 indirect reference to a volatile disqualifies the
-	 function from being pure or const.  Any indirect
-	 reference that occurs on the rhs disqualifies the
+	 indirect reference that occurs on the rhs disqualifies the
 	 function from being const.  */
-      if (checking_write || TREE_THIS_VOLATILE (t)) 
-	local->pure_const_state = IPA_NEITHER;
+      if (checking_write) 
+	{
+	  local->pure_const_state = IPA_NEITHER;
+	  return;
+	}
       else if (local->pure_const_state == IPA_CONST)
 	local->pure_const_state = IPA_PURE;
     }
@@ -541,7 +550,7 @@ analyze_function (struct cgraph_node *fn
 	      walk_tree (bsi_stmt_ptr (bsi), scan_function, 
 			 fn, visited_nodes);
 	      if (l->pure_const_state == IPA_NEITHER) 
-		return;
+		goto end;
 	    }
 	}
 
@@ -568,6 +577,14 @@ analyze_function (struct cgraph_node *fn
 	  pop_cfun ();
 	}
     }
+
+end:
+  if (dump_file)
+    {
+      fprintf (dump_file, "after local analysis of %s with initial value = %d\n ", 
+	       cgraph_node_name (fn),
+	       l->pure_const_state);
+    }
 }
 
 
Index: testsuite/gcc.dg/pure-1.c
===================================================================
--- testsuite/gcc.dg/pure-1.c	(revision 0)
+++ testsuite/gcc.dg/pure-1.c	(revision 0)
@@ -0,0 +1,16 @@
+/* Regression test for PR middle-end/23584 */
+/* Verify that dereferencing a volatile element in a struct causes
+   the function not be pure.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-ipa-pure-const" } */
+
+struct test_a { volatile int a; };
+
+int func_a(struct test_a *a)
+{
+        return a->a;
+}
+
+/* { dg-final { scan-ipa-dump-not "found to be pure: func_a" "pure-const" } } */
+/* { dg-final { cleanup-ipa-dump "pure-const" } } */

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