Hi,
as Michael pointed out, I introduced long lines primarily because of large
indentation in cgraph_analyze_function.  It makes the code to look better
if the polymorphic call logic in broken out.

Bootstrapping/regtesting x86_64-linux, will commit it once testing conlcude.
Honza
        * cgraphunit.c (walk_polymorphic_call_targets): Break out from...
        (cgraph_analyze_functions): ... here.
Index: cgraphunit.c
===================================================================
--- cgraphunit.c        (revision 202199)
+++ cgraphunit.c        (working copy)
@@ -821,7 +821,77 @@
     varpool_assemble_decl (node);
 }
 
+/* EDGE is an polymorphic call.  Mark all possible targets as reachable
+   and if there is only one target, perform trivial devirtualization. 
+   REACHABLE_CALL_TARGETS collects target lists we already walked to
+   avoid udplicate work.  */
 
+static void
+walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
+                              struct cgraph_edge *edge)
+{
+  unsigned int i;
+  void *cache_token;
+  bool final;
+  vec <cgraph_node *>targets
+    = possible_polymorphic_call_targets
+       (edge, &final, &cache_token);
+
+  if (!pointer_set_insert (reachable_call_targets,
+                          cache_token))
+    {
+      if (cgraph_dump_file)
+       dump_possible_polymorphic_call_targets 
+         (cgraph_dump_file, edge);
+
+      for (i = 0; i < targets.length(); i++)
+       {
+         /* Do not bother to mark virtual methods in anonymous namespace;
+            either we will find use of virtual table defining it, or it is
+            unused.  */
+         if (targets[i]->symbol.definition
+             && TREE_CODE
+                 (TREE_TYPE (targets[i]->symbol.decl))
+                  == METHOD_TYPE
+             && !type_in_anonymous_namespace_p
+                  (method_class_type
+                    (TREE_TYPE (targets[i]->symbol.decl))))
+         enqueue_node ((symtab_node) targets[i]);
+       }
+    }
+
+  /* Very trivial devirtualization; when the type is
+     final or anonymous (so we know all its derivation)
+     and there is only one possible virtual call target,
+     make the edge direct.  */
+  if (final)
+    {
+      gcc_assert (targets.length());
+      if (targets.length() == 1)
+       {
+         if (cgraph_dump_file)
+           {
+             fprintf (cgraph_dump_file,
+                      "Devirtualizing call: ");
+             print_gimple_stmt (cgraph_dump_file,
+                                edge->call_stmt, 0,
+                                TDF_SLIM);
+           }
+         cgraph_make_edge_direct (edge, targets[0]);
+         cgraph_redirect_edge_call_stmt_to_callee (edge);
+         if (cgraph_dump_file)
+           {
+             fprintf (cgraph_dump_file,
+                      "Devirtualized as: ");
+             print_gimple_stmt (cgraph_dump_file,
+                                edge->call_stmt, 0,
+                                TDF_SLIM);
+           }
+       }
+    }
+}
+
+
 /* Discover all functions and variables that are trivially needed, analyze
    them as well as all functions and variables referred by them  */
 
@@ -923,71 +993,13 @@
              if (optimize && flag_devirtualize)
                {
                  struct cgraph_edge *next;
-                 for (edge = cnode->indirect_calls; edge; edge = next)
+
+                 for (edge = cnode->indirect_calls; edge; edge = next)
                    {
                      next = edge->next_callee;
                      if (edge->indirect_info->polymorphic)
-                       {
-                         unsigned int i;
-                         void *cache_token;
-                         bool final;
-                         vec <cgraph_node *>targets
-                           = possible_polymorphic_call_targets
-                               (edge, &final, &cache_token);
-
-                         if (!pointer_set_insert (reachable_call_targets,
-                                                  cache_token))
-                           {
-                             if (cgraph_dump_file)
-                               dump_possible_polymorphic_call_targets 
-                                 (cgraph_dump_file, edge);
-
-                             for (i = 0; i < targets.length(); i++)
-                               {
-                                 /* Do not bother to mark virtual methods in 
anonymous namespace;
-                                    either we will find use of virtual table 
defining it, or it is
-                                    unused.  */
-                                 if (targets[i]->symbol.definition
-                                     && TREE_CODE
-                                         (TREE_TYPE (targets[i]->symbol.decl))
-                                          == METHOD_TYPE
-                                     && !type_in_anonymous_namespace_p
-                                          (method_class_type
-                                            (TREE_TYPE 
(targets[i]->symbol.decl))))
-                                 enqueue_node ((symtab_node) targets[i]);
-                               }
-                           }
-
-                         /* Very trivial devirtualization; when the type is
-                            final or anonymous (so we know all its derivation)
-                            and there is only one possible virtual call target,
-                            make the edge direct.  */
-                         if (final)
-                           {
-                             gcc_assert (targets.length());
-                             if (targets.length() == 1)
-                               {
-                                 if (cgraph_dump_file)
-                                   {
-                                     fprintf (cgraph_dump_file,
-                                              "Devirtualizing call: ");
-                                     print_gimple_stmt (cgraph_dump_file,
-                                                        edge->call_stmt, 0,
-                                                        TDF_SLIM);
-                                   }
-                                 cgraph_make_edge_direct (edge, targets[0]);
-                                 cgraph_redirect_edge_call_stmt_to_callee 
(edge);
-                                 if (cgraph_dump_file)
-                                   {
-                                     fprintf (cgraph_dump_file,
-                                              "Devirtualized as: ");
-                                     print_gimple_stmt (cgraph_dump_file,
-                                                        edge->call_stmt, 0,
-                                                        TDF_SLIM);
-                                   }
-                               }
-                           }
-                       }
+                       walk_polymorphic_call_targets (reachable_call_targets,
+                                                      edge);
                    }
                }
 

Reply via email to