OSDN Git Service

PR c++/35546
[pf3gnuchains/gcc-fork.git] / gcc / ipa-pure-const.c
index 519b402..c180e35 100644 (file)
@@ -114,7 +114,10 @@ check_decl (funct_state local,
      are CHECKING_WRITE, this cannot be a pure or constant
      function.  */
   if (checking_write) 
-    local->pure_const_state = IPA_NEITHER;
+    {
+      local->pure_const_state = IPA_NEITHER;
+      return;
+    }
 
   if (DECL_EXTERNAL (t) || TREE_PUBLIC (t))
     {
@@ -641,6 +644,7 @@ static_execute (void)
   for (i = 0; i < order_pos; i++ )
     {
       enum pure_const_state_e pure_const_state = IPA_CONST;
+      int count = 0;
       node = order[i];
 
       /* Find the worst state for any node in the cycle.  */
@@ -657,11 +661,40 @@ static_execute (void)
          if (!w_l->state_set_in_source)
            {
              struct cgraph_edge *e;
+             count++;
+
+             /* FIXME!!!  Because of pr33826, we cannot have either
+                immediate or transitive recursive functions marked as
+                pure or const because dce can delete a function that
+                is in reality an infinite loop.  A better solution
+                than just outlawing them is to add another bit the
+                functions to distinguish recursive from non recursive
+                pure and const function.  This would allow the
+                recursive ones to be cse'd but not dce'd.  In this
+                same vein, we could allow functions with loops to
+                also be cse'd but not dce'd.
+
+                Unfortunately we are late in stage 3, and the fix
+                described above is is not appropriate.  */
+             if (count > 1)
+               {
+                 pure_const_state = IPA_NEITHER;
+                 break;
+               }
+                   
              for (e = w->callees; e; e = e->next_callee) 
                {
                  struct cgraph_node *y = e->callee;
                  /* Only look at the master nodes and skip external nodes.  */
                  y = cgraph_master_clone (y);
+
+                 /* Check for immediate recursive functions.  See the
+                    FIXME above.  */
+                 if (w == y)
+                   {
+                     pure_const_state = IPA_NEITHER;
+                     break;
+                   }
                  if (y)
                    {
                      funct_state y_l = get_function_state (y);
@@ -736,8 +769,10 @@ gate_pure_const (void)
          && !(errorcount || sorrycount));
 }
 
-struct tree_opt_pass pass_ipa_pure_const =
+struct simple_ipa_opt_pass pass_ipa_pure_const =
 {
+ {
+  SIMPLE_IPA_PASS,
   "pure-const",                                /* name */
   gate_pure_const,                     /* gate */
   static_execute,                      /* execute */
@@ -749,8 +784,8 @@ struct tree_opt_pass pass_ipa_pure_const =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  0                                    /* letter */
+  0                                     /* todo_flags_finish */
+ }
 };