re PR ipa/61190 (g++.old-deja/g++.mike/p4736b.C FAILs at -O2/-Os/-O3)
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Wed, 26 Nov 2014 18:10:29 +0000 (18:10 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Wed, 26 Nov 2014 18:10:29 +0000 (18:10 +0000)
2014-11-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR ipa/61190
        * cgraph.h (symtab_node::call_for_symbol_and_aliases): Fix comment.
        (cgraph_node::function_or_virtual_thunk_symbol): New function.
        (cgraph_node::call_for_symbol_and_aliases): Fix comment.
        (cgraph_node::call_for_symbol_thunks_and_aliases): Adjust comment.
        Add new optional parameter exclude_virtual_thunks.
        * cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases): Add new
        optional parameter exclude_virtual_thunks.
        (cgraph_node::set_const_flag): Don't propagate to virtual thunks.
        (cgraph_node::set_pure_flag): Likewise.
        (cgraph_node::function_symbol): Simplified.
        (cgraph_node::function_or_virtual_thunk_symbol): New function.
        * ipa-pure-const.c (analyze_function): For virtual thunks set
        pure_const_state to IPA_NEITHER.
        (propagate_pure_const): Use function_or_virtual_thunk_symbol.

testsuite/ChangeLog:
2014-11-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR ipa/61190
        * g++.old-deja/g++.mike/p4736b.C: Use -O2.

From-SVN: r218091

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-pure-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.mike/p4736b.C

index 79c5411c3247dcce01de4456c699156bf5e2451a..62dcb381af711db96f80ceffd5099fb0b31f08bb 100644 (file)
@@ -1,3 +1,21 @@
+2014-11-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR ipa/61190
+       * cgraph.h (symtab_node::call_for_symbol_and_aliases): Fix comment.
+       (cgraph_node::function_or_virtual_thunk_symbol): New function.
+       (cgraph_node::call_for_symbol_and_aliases): Fix comment.
+       (cgraph_node::call_for_symbol_thunks_and_aliases): Adjust comment.
+       Add new optional parameter exclude_virtual_thunks.
+       * cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases): Add new
+       optional parameter exclude_virtual_thunks.
+       (cgraph_node::set_const_flag): Don't propagate to virtual thunks.
+       (cgraph_node::set_pure_flag): Likewise.
+       (cgraph_node::function_symbol): Simplified.
+       (cgraph_node::function_or_virtual_thunk_symbol): New function.
+       * ipa-pure-const.c (analyze_function): For virtual thunks set
+       pure_const_state to IPA_NEITHER.
+       (propagate_pure_const): Use function_or_virtual_thunk_symbol.
+
 2014-11-26  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/63738
index 5323468b8f52fb352a0d12ae0e1c67648f9f9b2d..6aecb14823c6fe1d67306dbd58f58192d125a856 100644 (file)
@@ -2193,15 +2193,16 @@ cgraph_node::can_be_local_p (void)
                                                NULL, true));
 }
 
-/* Call calback on cgraph_node, thunks and aliases associated to cgraph_node.
+/* Call callback on cgraph_node, thunks and aliases associated to cgraph_node.
    When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
-   skipped. */
-
+   skipped.  When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
+   skipped.  */
 bool
 cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
                                                   (cgraph_node *, void *),
                                                 void *data,
-                                                bool include_overwritable)
+                                                bool include_overwritable,
+                                                bool exclude_virtual_thunks)
 {
   cgraph_edge *e;
   ipa_ref *ref;
@@ -2211,9 +2212,12 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
   for (e = callers; e; e = e->next_caller)
     if (e->caller->thunk.thunk_p
        && (include_overwritable
-           || e->caller->get_availability () > AVAIL_INTERPOSABLE))
+           || e->caller->get_availability () > AVAIL_INTERPOSABLE)
+       && !(exclude_virtual_thunks
+            && e->caller->thunk.virtual_offset_p))
       if (e->caller->call_for_symbol_thunks_and_aliases (callback, data,
-                                                      include_overwritable))
+                                                      include_overwritable,
+                                                      exclude_virtual_thunks))
        return true;
 
   FOR_EACH_ALIAS (this, ref)
@@ -2222,15 +2226,16 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
       if (include_overwritable
          || alias->get_availability () > AVAIL_INTERPOSABLE)
        if (alias->call_for_symbol_thunks_and_aliases (callback, data,
-                                                    include_overwritable))
+                                                    include_overwritable,
+                                                    exclude_virtual_thunks))
          return true;
     }
   return false;
 }
 
-/* Call calback on function and aliases associated to the function.
+/* Call callback on function and aliases associated to the function.
    When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
-   skipped. */
+   skipped.  */
 
 bool
 cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
@@ -2338,7 +2343,7 @@ cgraph_node::set_const_flag (bool readonly, bool looping)
 {
   call_for_symbol_thunks_and_aliases (cgraph_set_const_flag_1,
                                    (void *)(size_t)(readonly + (int)looping * 2),
-                                     false);
+                                   false, true);
 }
 
 /* Worker to set pure flag.  */
@@ -2368,7 +2373,7 @@ cgraph_node::set_pure_flag (bool pure, bool looping)
 {
   call_for_symbol_thunks_and_aliases (cgraph_set_pure_flag_1,
                                    (void *)(size_t)(pure + (int)looping * 2),
-                                   false);
+                                   false, true);
 }
 
 /* Return true when cgraph_node can not return or throw and thus
@@ -3118,30 +3123,52 @@ cgraph_node::verify_cgraph_nodes (void)
 }
 
 /* Walk the alias chain to return the function cgraph_node is alias of.
-   Walk through thunk, too.
+   Walk through thunks, too.
    When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
 
 cgraph_node *
 cgraph_node::function_symbol (enum availability *availability)
 {
-  cgraph_node *node = this;
+  cgraph_node *node = ultimate_alias_target (availability);
 
-  do
+  while (node->thunk.thunk_p)
     {
+      node = node->callees->callee;
+      if (availability)
+       {
+         enum availability a;
+         a = node->get_availability ();
+         if (a < *availability)
+           *availability = a;
+       }
       node = node->ultimate_alias_target (availability);
-      if (node->thunk.thunk_p)
+    }
+  return node;
+}
+
+/* Walk the alias chain to return the function cgraph_node is alias of.
+   Walk through non virtual thunks, too.  Thus we return either a function
+   or a virtual thunk node.
+   When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
+
+cgraph_node *
+cgraph_node::function_or_virtual_thunk_symbol
+                               (enum availability *availability)
+{
+  cgraph_node *node = ultimate_alias_target (availability);
+
+  while (node->thunk.thunk_p && !node->thunk.virtual_offset_p)
+    {
+      node = node->callees->callee;
+      if (availability)
        {
-         node = node->callees->callee;
-         if (availability)
-           {
-             enum availability a;
-             a = node->get_availability ();
-             if (a < *availability)
-               *availability = a;
-           }
-         node = node->ultimate_alias_target (availability);
+         enum availability a;
+         a = node->get_availability ();
+         if (a < *availability)
+           *availability = a;
        }
-    } while (node && node->thunk.thunk_p);
+      node = node->ultimate_alias_target (availability);
+    }
   return node;
 }
 
index a5c5f569d678441e3bfda0a249d85c7494cf9552..04318f58c7a5e74a561073f33f46c705e4aecd31 100644 (file)
@@ -254,9 +254,9 @@ public:
      body aliases.  */
   void fixup_same_cpp_alias_visibility (symtab_node *target);
 
-  /* Call calback on symtab node and aliases associated to this node.
+  /* Call callback on symtab node and aliases associated to this node.
      When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
-     skipped. */
+     skipped.  */
   bool call_for_symbol_and_aliases (bool (*callback) (symtab_node *, void *),
                                  void *data,
                                  bool include_overwrite);
@@ -793,6 +793,13 @@ public:
      When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
   cgraph_node *function_symbol (enum availability *avail = NULL);
 
+  /* Walk the alias chain to return the function cgraph_node is alias of.
+     Walk through non virtual thunks, too.  Thus we return either a function
+     or a virtual thunk node.
+     When AVAILABILITY is non-NULL, get minimal availability in the chain.  */
+  cgraph_node *function_or_virtual_thunk_symbol
+                               (enum availability *avail = NULL);
+
   /* Create node representing clone of N executed COUNT times.  Decrease
      the execution counts from original node too.
      The new clone will have decl set to DECL that may or may not be the same
@@ -1015,7 +1022,7 @@ public:
      if any to PURE.  */
   void set_pure_flag (bool pure, bool looping);
 
-  /* Call calback on function and aliases associated to the function.
+  /* Call callback on function and aliases associated to the function.
      When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
      skipped. */
 
@@ -1023,13 +1030,15 @@ public:
                                                      void *),
                                    void *data, bool include_overwritable);
 
-  /* Call calback on cgraph_node, thunks and aliases associated to NODE.
+  /* Call callback on cgraph_node, thunks and aliases associated to NODE.
      When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+     skipped.  When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
      skipped.  */
   bool call_for_symbol_thunks_and_aliases (bool (*callback) (cgraph_node *node,
-                                                          void *data),
-                                        void *data,
-                                        bool include_overwritable);
+                                                            void *data),
+                                          void *data,
+                                          bool include_overwritable,
+                                          bool exclude_virtual_thunks = false);
 
   /* Likewise indicate that a node is needed, i.e. reachable via some
      external means.  */
index 9c016c1d5862e8474aec300573dc20f15210dca5..13e3a258c9b048ec92a61fb44ba75af3e897342d 100644 (file)
@@ -806,6 +806,8 @@ analyze_function (struct cgraph_node *fn, bool ipa)
     {
       /* Thunk gets propagated through, so nothing interesting happens.  */
       gcc_assert (ipa);
+      if (fn->thunk.thunk_p && fn->thunk.virtual_offset_p)
+       l->pure_const_state = IPA_NEITHER;
       return l;
     }
 
@@ -1247,7 +1249,8 @@ propagate_pure_const (void)
          for (e = w->callees; e; e = e->next_callee)
            {
              enum availability avail;
-             struct cgraph_node *y = e->callee->function_symbol (&avail);
+             struct cgraph_node *y = e->callee->
+                               function_or_virtual_thunk_symbol (&avail);
              enum pure_const_state_e edge_state = IPA_CONST;
              bool edge_looping = false;
 
@@ -1387,7 +1390,8 @@ propagate_pure_const (void)
          for (e = w->callees; e && !can_free; e = e->next_callee)
            {
              enum availability avail;
-             struct cgraph_node *y = e->callee->function_symbol (&avail);
+             struct cgraph_node *y = e->callee->
+                               function_or_virtual_thunk_symbol (&avail);
 
              if (avail > AVAIL_INTERPOSABLE)
                can_free = get_function_state (y)->can_free;
@@ -1517,7 +1521,8 @@ propagate_nothrow (void)
          for (e = w->callees; e && !can_throw; e = e->next_callee)
            {
              enum availability avail;
-             struct cgraph_node *y = e->callee->function_symbol (&avail);
+             struct cgraph_node *y = e->callee->
+                               function_or_virtual_thunk_symbol (&avail);
 
              if (avail > AVAIL_INTERPOSABLE)
                {
index 48e35810079a1d2df56daa1e51355ae5c6601251..c3dcfd2cbf466bf63d157bde889c94b76cc141d6 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       PR ipa/61190
+       * g++.old-deja/g++.mike/p4736b.C: Use -O2.
+
 2014-11-26  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/59114
index c2fce17b4b08b6436bab6a888c29d050d6fddffe..e76bd74040c776344b1d4675f02e87e83be81deb 100644 (file)
@@ -1,4 +1,5 @@
 // { dg-do run  }
+// { dg-options "-O2" }
 // prms-id: 4736
 
 class Rep {