]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-pure-const.c (ignore_edge): Rename to ...
authorJan Hubicka <hubicka@ucw.cz>
Thu, 3 Dec 2015 04:19:44 +0000 (05:19 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 3 Dec 2015 04:19:44 +0000 (04:19 +0000)
* ipa-pure-const.c (ignore_edge): Rename to ...
(ignore_edge_for_nothrow) ... this one; also ignore eges to
interposable functions or ones that can not throw.
(propagate_nothrow): Fix handling of availability.

From-SVN: r231218

gcc/ChangeLog
gcc/ipa-pure-const.c

index 1d96d7b61cfbd1d4d56be467aca541f629d79e5e..0cb5593f5551c80839d596ea63a9b804ed2dc295 100644 (file)
@@ -1,3 +1,10 @@
+2015-12-02  Jan Hubicka  <hubicka@ucw.cz>
+
+       * ipa-pure-const.c (ignore_edge): Rename to ...
+       (ignore_edge_for_nothrow) ... this one; also ignore eges to
+       interposable functions or ones that can not throw.
+       (propagate_nothrow): Fix handling of availability.
+
 2015-12-02  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/68184
index 840ca7ad844edc51236c917365700c2fe3101124..654791ad42de43bdadc13640987f5b50ed1a523b 100644 (file)
@@ -1124,11 +1124,18 @@ pure_const_read_summary (void)
     }
 }
 
+/* We only propagate across edges that can throw externally and their callee
+   is not interposable.  */
 
 static bool
-ignore_edge (struct cgraph_edge *e)
+ignore_edge_for_nothrow (struct cgraph_edge *e)
 {
-  return (!e->can_throw_external);
+  if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl))
+    return true;
+
+  enum availability avail;
+  cgraph_node *n = e->callee->function_or_virtual_thunk_symbol (&avail);
+  return (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl));
 }
 
 /* Return true if NODE is self recursive function.
@@ -1491,7 +1498,8 @@ propagate_nothrow (void)
   int i;
   struct ipa_dfs_info * w_info;
 
-  order_pos = ipa_reduced_postorder (order, true, false, ignore_edge);
+  order_pos = ipa_reduced_postorder (order, true, false,
+                                    ignore_edge_for_nothrow);
   if (dump_file)
     {
       cgraph_node::dump_cgraph (dump_file);
@@ -1515,32 +1523,38 @@ propagate_nothrow (void)
       while (w && !can_throw)
        {
          struct cgraph_edge *e, *ie;
-         funct_state w_l = get_function_state (w);
-
-         if (w_l->can_throw
-             || w->get_availability () == AVAIL_INTERPOSABLE)
-           can_throw = true;
 
-         for (e = w->callees; e && !can_throw; e = e->next_callee)
+         if (!TREE_NOTHROW (w->decl))
            {
-             enum availability avail;
-             struct cgraph_node *y = e->callee->
-                               function_or_virtual_thunk_symbol (&avail);
+             funct_state w_l = get_function_state (w);
 
-             if (avail > AVAIL_INTERPOSABLE)
+             if (w_l->can_throw
+                 || w->get_availability () == AVAIL_INTERPOSABLE)
+               can_throw = true;
+
+             for (e = w->callees; e && !can_throw; e = e->next_callee)
                {
-                 funct_state y_l = get_function_state (y);
+                 enum availability avail;
+
+                 if (!e->can_throw_external || TREE_NOTHROW (e->callee->decl))
+                   continue;
+
+                 struct cgraph_node *y = e->callee->
+                                   function_or_virtual_thunk_symbol (&avail);
 
-                 if (y_l->can_throw && !TREE_NOTHROW (w->decl)
-                     && e->can_throw_external)
+                 /* We can use info about the callee only if we know it can
+                    not be interposed.  */
+                 if (avail <= AVAIL_INTERPOSABLE
+                     || (!TREE_NOTHROW (y->decl)
+                         && get_function_state (y)->can_throw))
                    can_throw = true;
                }
-             else if (e->can_throw_external && !TREE_NOTHROW (y->decl))
-               can_throw = true;
+             for (ie = w->indirect_calls; ie && !can_throw;
+                  ie = ie->next_callee)
+               if (ie->can_throw_external
+                   && !(ie->indirect_info->ecf_flags & ECF_NOTHROW))
+                 can_throw = true;
            }
-          for (ie = w->indirect_calls; ie && !can_throw; ie = ie->next_callee)
-           if (ie->can_throw_external)
-             can_throw = true;
          w_info = (struct ipa_dfs_info *) w->aux;
          w = w_info->next_cycle;
        }
@@ -1650,7 +1664,7 @@ skip_function_for_local_pure_const (struct cgraph_node *node)
   if (node->get_availability () <= AVAIL_INTERPOSABLE)
     {
       if (dump_file)
-        fprintf (dump_file, "Function is not available or overwritable; not analyzing.\n");
+        fprintf (dump_file, "Function is not available or interposable; not analyzing.\n");
       return true;
     }
   return false;