* cgraph.c (cgraph_set_call_stmt_including_clones): Tidy.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Jul 2009 00:34:47 +0000 (00:34 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Jul 2009 00:34:47 +0000 (00:34 +0000)
        (cgraph_create_edge_including_clones): Likewise.
        * tree-inline.c (copy_bb): Operate on the correct edges
        when updating the callgraph.

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

gcc/ChangeLog
gcc/cgraph.c
gcc/tree-inline.c

index 43e94c1..d61bf2d 100644 (file)
@@ -1,3 +1,10 @@
+2009-07-29  Richard Henderson  <rth@redhat.com>
+
+       * cgraph.c (cgraph_set_call_stmt_including_clones): Tidy.
+       (cgraph_create_edge_including_clones): Likewise.
+       * tree-inline.c (copy_bb): Operate on the correct edges
+       when updating the callgraph.
+
 2009-07-29  Douglas B Rupp  <rupp@gnat.com>
 
        * config/alpha/vms-cc.c: Deleted.
index ea47aa3..ded99f9 100644 (file)
@@ -654,8 +654,8 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
     }
 }
 
-/* Like cgraph_set_call_stmt but walk the clone tree and update all clones sharing
-   same function body.  */
+/* Like cgraph_set_call_stmt but walk the clone tree and update all
+   clones sharing the same function body.  */
 
 void
 cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
@@ -666,8 +666,10 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
 
   if (edge)
     cgraph_set_call_stmt (edge, new_stmt);
-  if (orig->clones)
-    for (node = orig->clones; node != orig;)
+
+  node = orig->clones;
+  if (node)
+    while (node != orig)
       {
        struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
        if (edge)
@@ -690,29 +692,36 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
    same function body.  
    
    TODO: COUNT and LOOP_DEPTH should be properly distributed based on relative
-   frequencies of the clones.
-   */
+   frequencies of the clones.  */
 
 void
-cgraph_create_edge_including_clones (struct cgraph_node *orig, struct cgraph_node *callee,
-                                    gimple stmt, gcov_type count, int freq,
-                                    int loop_depth,
+cgraph_create_edge_including_clones (struct cgraph_node *orig,
+                                    struct cgraph_node *callee,
+                                    gimple stmt, gcov_type count,
+                                    int freq, int loop_depth,
                                     cgraph_inline_failed_t reason)
 {
   struct cgraph_node *node;
+  struct cgraph_edge *edge;
 
   if (!cgraph_edge (orig, stmt))
-     cgraph_create_edge (orig, callee, stmt,
-                        count, freq, loop_depth)->inline_failed = reason;
+    {
+      edge = cgraph_create_edge (orig, callee, stmt, count, freq, loop_depth);
+      edge->inline_failed = reason;
+    }
 
-  if (orig->clones)
-    for (node = orig->clones; node != orig;)
+  node = orig->clones;
+  if (node)
+    while (node != orig)
       {
         /* It is possible that we already constant propagated into the clone
           and turned indirect call into dirrect call.  */
         if (!cgraph_edge (node, stmt))
-         cgraph_create_edge (node, callee, stmt, count, freq,
-                             loop_depth)->inline_failed = reason;
+         {
+           edge = cgraph_create_edge (node, callee, stmt, count,
+                                      freq, loop_depth);
+           edge->inline_failed = reason;
+         }
 
        if (node->clones)
          node = node->clones;
index 605f91e..e62c5c1 100644 (file)
@@ -1496,67 +1496,69 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
             callgraph edges and update or duplicate them.  */
          if (is_gimple_call (stmt))
            {
-             struct cgraph_edge *edge = cgraph_edge (id->src_node, orig_stmt);
+             struct cgraph_edge *edge;
              int flags;
 
              switch (id->transform_call_graph_edges)
                {
-             case CB_CGE_DUPLICATE:
-               if (edge)
-                 cgraph_clone_edge (edge, id->dst_node, stmt,
-                                          REG_BR_PROB_BASE, 1,
-                                          edge->frequency, true);
-               break;
-
-             case CB_CGE_MOVE_CLONES:
-               cgraph_set_call_stmt_including_clones (id->dst_node, orig_stmt, stmt);
-               break;
-
-             case CB_CGE_MOVE:
-               if (edge)
-                 cgraph_set_call_stmt (edge, stmt);
-               break;
-
-             default:
-               gcc_unreachable ();
+               case CB_CGE_DUPLICATE:
+                 edge = cgraph_edge (id->src_node, orig_stmt);
+                 if (edge)
+                   edge = cgraph_clone_edge (edge, id->dst_node, stmt,
+                                             REG_BR_PROB_BASE, 1,
+                                             edge->frequency, true);
+                 break;
+
+               case CB_CGE_MOVE_CLONES:
+                 cgraph_set_call_stmt_including_clones (id->dst_node,
+                                                        orig_stmt, stmt);
+                 edge = cgraph_edge (id->dst_node, stmt);
+                 break;
+
+               case CB_CGE_MOVE:
+                 edge = cgraph_edge (id->dst_node, orig_stmt);
+                 if (edge)
+                   cgraph_set_call_stmt (edge, stmt);
+                 break;
+
+               default:
+                 gcc_unreachable ();
                }
 
-           edge = cgraph_edge (id->src_node, orig_stmt);
-           /* Constant propagation on argument done during inlining
-              may create new direct call.  Produce an edge for it.  */
-           if ((!edge 
-                || (edge->indirect_call
-                    && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
-               && is_gimple_call (stmt)
-               && (fn = gimple_call_fndecl (stmt)) != NULL)
-             {
-               struct cgraph_node *dest = cgraph_node (fn);
-
-               /* We have missing edge in the callgraph.  This can happen in one case
-                  where previous inlining turned indirect call into direct call by
-                  constant propagating arguments.  In all other cases we hit a bug
-                  (incorrect node sharing is most common reason for missing edges.  */
-               gcc_assert (dest->needed || !dest->analyzed);
-               if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
-                 cgraph_create_edge_including_clones (id->dst_node, dest, stmt,
-                                                      bb->count,
-                                                      compute_call_stmt_bb_frequency (id->dst_node->decl, bb),
-                                                      bb->loop_depth,
-                                                      CIF_ORIGINALLY_INDIRECT_CALL);
-               else
-                 cgraph_create_edge (id->dst_node, dest, stmt,
-                                     bb->count, CGRAPH_FREQ_BASE,
-                                     bb->loop_depth)->inline_failed
-                   = CIF_ORIGINALLY_INDIRECT_CALL;
-               if (dump_file)
-                 {
-                    fprintf (dump_file, "Created new direct edge to %s",
-                             cgraph_node_name (dest));
-                 }
-             }
+             /* Constant propagation on argument done during inlining
+                may create new direct call.  Produce an edge for it.  */
+             if ((!edge 
+                  || (edge->indirect_call
+                      && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
+                 && is_gimple_call (stmt)
+                 && (fn = gimple_call_fndecl (stmt)) != NULL)
+               {
+                 struct cgraph_node *dest = cgraph_node (fn);
+
+                 /* We have missing edge in the callgraph.  This can happen
+                    when previous inlining turned an indirect call into a
+                    direct call by constant propagating arguments.  In all
+                    other cases we hit a bug (incorrect node sharing is the
+                    most common reason for missing edges).  */
+                 gcc_assert (dest->needed || !dest->analyzed);
+                 if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
+                   cgraph_create_edge_including_clones
+                     (id->dst_node, dest, stmt, bb->count,
+                      compute_call_stmt_bb_frequency (id->dst_node->decl, bb),
+                      bb->loop_depth, CIF_ORIGINALLY_INDIRECT_CALL);
+                 else
+                   cgraph_create_edge (id->dst_node, dest, stmt,
+                                       bb->count, CGRAPH_FREQ_BASE,
+                                       bb->loop_depth)->inline_failed
+                     = CIF_ORIGINALLY_INDIRECT_CALL;
+                 if (dump_file)
+                   {
+                     fprintf (dump_file, "Created new direct edge to %s",
+                              cgraph_node_name (dest));
+                   }
+               }
 
              flags = gimple_call_flags (stmt);
-
              if (flags & ECF_MAY_BE_ALLOCA)
                cfun->calls_alloca = true;
              if (flags & ECF_RETURNS_TWICE)