OSDN Git Service

* ipa-pure-const.c (special_builtlin_state): New function.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Jun 2010 15:12:48 +0000 (15:12 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Jun 2010 15:12:48 +0000 (15:12 +0000)
(check_call): Use it instead of special casign BUILT_IN_RETURN.
(propagate_pure_const): Use it.

* gcc.dg/ipa/pure-const-2.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160615 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ipa-pure-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/pure-const-2.c [new file with mode: 0644]

index d564d36..13e4ee6 100644 (file)
@@ -1,5 +1,11 @@
 2010-06-11  Jan Hubicka  <jh@suse.cz>
 
+       * ipa-pure-const.c (special_builtlin_state): New function.
+       (check_call): Use it instead of special casign BUILT_IN_RETURN.
+       (propagate_pure_const): Use it.
+
+2010-06-11  Jan Hubicka  <jh@suse.cz>
+
        * df-problems.c (df_live_scratch): Convert to bitmap_head.
        (df_live_alloc): Initialize df_live_scratch when initializing
        problem_data.
index da8d442..8678663 100644 (file)
@@ -420,6 +420,40 @@ worse_state (enum pure_const_state_e *state, bool *looping,
   *looping = MAX (*looping, looping2);
 }
 
+/* Recognize special cases of builtins that are by themself not pure or const
+   but function using them is.  */
+static bool
+special_builtlin_state (enum pure_const_state_e *state, bool *looping,
+                       tree callee)
+{
+  if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+    switch (DECL_FUNCTION_CODE (callee))
+      {
+       case BUILT_IN_RETURN:
+       case BUILT_IN_UNREACHABLE:
+       case BUILT_IN_ALLOCA:
+       case BUILT_IN_STACK_SAVE:
+       case BUILT_IN_STACK_RESTORE:
+       case BUILT_IN_EH_POINTER:
+       case BUILT_IN_EH_FILTER:
+       case BUILT_IN_UNWIND_RESUME:
+       case BUILT_IN_CXA_END_CLEANUP:
+       case BUILT_IN_EH_COPY_VALUES:
+       case BUILT_IN_FRAME_ADDRESS:
+       case BUILT_IN_APPLY:
+       case BUILT_IN_APPLY_ARGS:
+       case BUILT_IN_ARGS_INFO:
+         *looping = false;
+         *state = IPA_CONST;
+         return true;
+       case BUILT_IN_PREFETCH:
+         *looping = true;
+         *state = IPA_CONST;
+         return true;
+      }
+  return false;
+}
+
 /* Check the parameters of a function call to CALL_EXPR to see if
    there are any references in the parameters that are not allowed for
    pure or const functions.  Also check to see if this is either an
@@ -470,9 +504,15 @@ check_call (funct_state local, gimple call, bool ipa)
      graph.  */
   if (callee_t)
     {
-      /* built_in_return is really just an return statemnt.  */
-      if (gimple_call_builtin_p (call, BUILT_IN_RETURN))
-       return;
+      enum pure_const_state_e call_state;
+      bool call_looping;
+
+      if (special_builtlin_state (&call_state, &call_looping, callee_t))
+       {
+         worse_state (&local->pure_const_state, &local->looping,
+                      call_state, call_looping);
+         return;
+       }
       /* When bad things happen to bad functions, they cannot be const
         or pure.  */
       if (setjmp_call_p (callee_t))
@@ -1153,10 +1193,13 @@ propagate_pure_const (void)
                      edge_looping = y_l->looping;
                    }
                }
+             else if (special_builtlin_state (&edge_state, &edge_looping,
+                                              y->decl))
+               ;
              else
                state_from_flags (&edge_state, &edge_looping,
-                                 flags_from_decl_or_type (y->decl),
-                                 cgraph_edge_cannot_lead_to_return (e));
+                                 flags_from_decl_or_type (y->decl),
+                                 cgraph_edge_cannot_lead_to_return (e));
 
              /* Merge the results with what we already know.  */
              better_state (&edge_state, &edge_looping,
index 372d595..ce3db3e 100644 (file)
@@ -1,7 +1,11 @@
 2010-06-11  Jan Hubicka  <jh@suse.cz>
 
-       * testsuite/gcc.dg/noreturn-7.c: Update.
-       * testsuite/gcc.dg/noreturn-4.c: Update.
+       * gcc.dg/ipa/pure-const-2.c: New testcase.
+
+2010-06-11  Jan Hubicka  <jh@suse.cz>
+
+       * gcc.dg/noreturn-7.c: Update.
+       * gcc.dg/noreturn-4.c: Update.
 
 2010-06-10  Dodji Seketeli  <dodji@redhat.com>
 
diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-2.c b/gcc/testsuite/gcc.dg/ipa/pure-const-2.c
new file mode 100644 (file)
index 0000000..51d7797
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-tree-optimized" } */
+static __attribute__ ((noinline, noclone))
+int i_am_pure(char *c, int n)
+{
+  char *d=__builtin_alloca (n);
+  int i;
+  int sum;
+  for (i=0;i<n;i++)
+    d[i] = c[i];
+  for (i=0;i<n;i++)
+    d[i] *= c[n-i];
+  for (i=0;i<n;i++)
+    sum+=d[i];
+  if (sum)
+    __builtin_unreachable ();
+  return sum;
+}
+char array[11];
+int
+main(void)
+{
+  i_am_pure (array,5);
+  i_am_pure (array,11);
+  return 0;
+}
+/* { dg-final { scan-tree-dump "found to be pure: i_am_pure" "local-pure-const1"} } */
+/* { dg-final { scan-tree-dump-not "i_am_pure" "optimized"} } */