On 07/29/2009 12:28 AM, Martin Jambor wrote:
That is not really true.

Whee.  I guess I really didn't understand what was going on.

At present I'm testing the following minimal patch to fix
the double lookup problem I mentioned.  It's uglier than
it ought to be because of incorrect indentation in the
original.


r~
--- tree-inline.c       (revision 150180)
+++ tree-inline.c       (local)
@@ -1496,67 +1496,69 @@ copy_bb (copy_body_data *id, basic_block
             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;
+               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 ();
+               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);
+             /* 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));
-                 }
-             }
+                 /* 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)

Reply via email to