PR jit/63854: Introduce xstrdup_for_dump
authorDavid Malcolm <dmalcolm@redhat.com>
Mon, 8 Dec 2014 19:31:45 +0000 (19:31 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Mon, 8 Dec 2014 19:31:45 +0000 (19:31 +0000)
gcc/ChangeLog:
PR jit/63854
* cgraph.h (xstrdup_for_dump): New function.
* cgraph.c (cgraph_node::get_create): Replace use of xstrdup
within fprintf with xstrdup_for_dump.
(cgraph_edge::make_speculative): Likewise.
(cgraph_edge::resolve_speculation): Likewise.
(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
(cgraph_node::dump): Likewise.
* cgraphclones.c (symbol_table::materialize_all_clones): Likewise.
* ipa-cp.c (perhaps_add_new_callers): Likewise.
* ipa-inline.c (report_inline_failed_reason): Likewise.
(want_early_inline_function_p): Likewise.
(edge_badness): Likewise.
(update_edge_key): Likewise.
(flatten_function): Likewise.
(inline_always_inline_functions): Likewise.
* ipa-profile.c (ipa_profile): Likewise.
* ipa-prop.c (ipa_print_node_jump_functions): Likewise.
(ipa_make_edge_direct_to_target): Likewise.
(remove_described_reference): Likewise.
(propagate_controlled_uses): Likewise.
* ipa-utils.c (ipa_merge_profiles): Likewise.

From-SVN: r218490

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphclones.c
gcc/ipa-cp.c
gcc/ipa-inline.c
gcc/ipa-profile.c
gcc/ipa-prop.c
gcc/ipa-utils.c

index edc26df8d153dba5dbeaf2a4db8db2150665615a..5e4306d8b0a9652e1d7e282cef3b92c98fd1d16c 100644 (file)
@@ -1,3 +1,28 @@
+2014-12-08  David Malcolm  <dmalcolm@redhat.com>
+
+       PR jit/63854
+       * cgraph.h (xstrdup_for_dump): New function.
+       * cgraph.c (cgraph_node::get_create): Replace use of xstrdup
+       within fprintf with xstrdup_for_dump.
+       (cgraph_edge::make_speculative): Likewise.
+       (cgraph_edge::resolve_speculation): Likewise.
+       (cgraph_edge::redirect_call_stmt_to_callee): Likewise.
+       (cgraph_node::dump): Likewise.
+       * cgraphclones.c (symbol_table::materialize_all_clones): Likewise.
+       * ipa-cp.c (perhaps_add_new_callers): Likewise.
+       * ipa-inline.c (report_inline_failed_reason): Likewise.
+       (want_early_inline_function_p): Likewise.
+       (edge_badness): Likewise.
+       (update_edge_key): Likewise.
+       (flatten_function): Likewise.
+       (inline_always_inline_functions): Likewise.
+       * ipa-profile.c (ipa_profile): Likewise.
+       * ipa-prop.c (ipa_print_node_jump_functions): Likewise.
+       (ipa_make_edge_direct_to_target): Likewise.
+       (remove_described_reference): Likewise.
+       (propagate_controlled_uses): Likewise.
+       * ipa-utils.c (ipa_merge_profiles): Likewise.
+
 2014-12-08  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        PR ipa/64049
index 6aecb14823c6fe1d67306dbd58f58192d125a856..50c7b34b3dc9efd85a1a989de4fe814d1bebcc67 100644 (file)
@@ -537,11 +537,11 @@ cgraph_node::get_create (tree decl)
       if (dump_file)
        fprintf (dump_file, "Introduced new external node "
                 "(%s/%i) and turned into root of the clone tree.\n",
-                xstrdup (node->name ()), node->order);
+                xstrdup_for_dump (node->name ()), node->order);
     }
   else if (dump_file)
     fprintf (dump_file, "Introduced new external node "
-            "(%s/%i).\n", xstrdup (node->name ()),
+            "(%s/%i).\n", xstrdup_for_dump (node->name ()),
             node->order);
   return node;
 }
@@ -1070,8 +1070,8 @@ cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count,
     {
       fprintf (dump_file, "Indirect call -> speculative call"
               " %s/%i => %s/%i\n",
-              xstrdup (n->name ()), n->order,
-              xstrdup (n2->name ()), n2->order);
+              xstrdup_for_dump (n->name ()), n->order,
+              xstrdup_for_dump (n2->name ()), n2->order);
     }
   speculative = true;
   e2 = n->create_edge (n2, call_stmt, direct_count, direct_frequency);
@@ -1190,16 +1190,20 @@ cgraph_edge::resolve_speculation (tree callee_decl)
            {
              fprintf (dump_file, "Speculative indirect call %s/%i => %s/%i has "
                       "turned out to have contradicting known target ",
-                      xstrdup (edge->caller->name ()), edge->caller->order,
-                      xstrdup (e2->callee->name ()), e2->callee->order);
+                      xstrdup_for_dump (edge->caller->name ()),
+                      edge->caller->order,
+                      xstrdup_for_dump (e2->callee->name ()),
+                      e2->callee->order);
              print_generic_expr (dump_file, callee_decl, 0);
              fprintf (dump_file, "\n");
            }
          else
            {
              fprintf (dump_file, "Removing speculative call %s/%i => %s/%i\n",
-                      xstrdup (edge->caller->name ()), edge->caller->order,
-                      xstrdup (e2->callee->name ()), e2->callee->order);
+                      xstrdup_for_dump (edge->caller->name ()),
+                      edge->caller->order,
+                      xstrdup_for_dump (e2->callee->name ()),
+                      e2->callee->order);
            }
        }
     }
@@ -1319,9 +1323,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
          if (dump_file)
            fprintf (dump_file, "Not expanding speculative call of %s/%i -> %s/%i\n"
                     "Type mismatch.\n",
-                    xstrdup (e->caller->name ()),
+                    xstrdup_for_dump (e->caller->name ()),
                     e->caller->order,
-                    xstrdup (e->callee->name ()),
+                    xstrdup_for_dump (e->callee->name ()),
                     e->callee->order);
          e = e->resolve_speculation ();
          /* We are producing the final function body and will throw away the
@@ -1338,9 +1342,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
            fprintf (dump_file,
                     "Expanding speculative call of %s/%i -> %s/%i count:"
                     "%"PRId64"\n",
-                    xstrdup (e->caller->name ()),
+                    xstrdup_for_dump (e->caller->name ()),
                     e->caller->order,
-                    xstrdup (e->callee->name ()),
+                    xstrdup_for_dump (e->callee->name ()),
                     e->callee->order,
                     (int64_t)e->count);
          gcc_assert (e2->speculative);
@@ -1415,8 +1419,8 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
   if (symtab->dump_file)
     {
       fprintf (symtab->dump_file, "updating call of %s/%i -> %s/%i: ",
-              xstrdup (e->caller->name ()), e->caller->order,
-              xstrdup (e->callee->name ()), e->callee->order);
+              xstrdup_for_dump (e->caller->name ()), e->caller->order,
+              xstrdup_for_dump (e->callee->name ()), e->callee->order);
       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
       if (e->callee->clone.combined_args_to_skip)
        {
@@ -1965,9 +1969,9 @@ cgraph_node::dump (FILE *f)
 
   if (global.inlined_to)
     fprintf (f, "  Function %s/%i is inline copy in %s/%i\n",
-            xstrdup (name ()),
+            xstrdup_for_dump (name ()),
             order,
-            xstrdup (global.inlined_to->name ()),
+            xstrdup_for_dump (global.inlined_to->name ()),
             global.inlined_to->order);
   if (clone_of)
     fprintf (f, "  Clone of %s/%i\n",
index 997414ce894aab146860fab2c1d4adeff3dcba9a..891b92500e7539a81d0829332cac8e262d01dec7 100644 (file)
@@ -2833,4 +2833,32 @@ cgraph_local_p (cgraph_node *node)
   return node->local.local && node->instrumented_version->local.local;
 }
 
+/* When using fprintf (or similar), problems can arise with
+   transient generated strings.  Many string-generation APIs
+   only support one result being alive at once (e.g. by
+   returning a pointer to a statically-allocated buffer).
+
+   If there is more than one generated string within one
+   fprintf call: the first string gets evicted or overwritten
+   by the second, before fprintf is fully evaluated.
+   See e.g. PR/53136.
+
+   This function provides a workaround for this, by providing
+   a simple way to create copies of these transient strings,
+   without the need to have explicit cleanup:
+
+       fprintf (dumpfile, "string 1: %s string 2:%s\n",
+                xstrdup_for_dump (EXPR_1),
+                xstrdup_for_dump (EXPR_2));
+
+   This is actually a simple wrapper around ggc_strdup, but
+   the name documents the intent.  We require that no GC can occur
+   within the fprintf call.  */
+
+static inline const char *
+xstrdup_for_dump (const char *transient_str)
+{
+  return ggc_strdup (transient_str);
+}
+
 #endif  /* GCC_CGRAPH_H  */
index 1bf0477a48cd60fd11b25799f26a4c94022dab5b..13bb0e95b44a0c1cc1d5a2b70df4a375c07e779c 100644 (file)
@@ -1094,8 +1094,8 @@ symbol_table::materialize_all_clones (void)
                  if (symtab->dump_file)
                    {
                      fprintf (symtab->dump_file, "cloning %s to %s\n",
-                              xstrdup (node->clone_of->name ()),
-                              xstrdup (node->name ()));
+                              xstrdup_for_dump (node->clone_of->name ()),
+                              xstrdup_for_dump (node->name ()));
                      if (node->clone.tree_map)
                        {
                          unsigned int i;
index 9b6784b8b5fc6a2be36b9f573ce1fbf8b7fe5a6d..79a1799d90137295e015a629ca0709c2e068fbaa 100644 (file)
@@ -3907,9 +3907,9 @@ perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
              if (dump_file)
                fprintf (dump_file, " - adding an extra caller %s/%i"
                         " of %s/%i\n",
-                        xstrdup (cs->caller->name ()),
+                        xstrdup_for_dump (cs->caller->name ()),
                         cs->caller->order,
-                        xstrdup (val->spec_node->name ()),
+                        xstrdup_for_dump (val->spec_node->name ()),
                         val->spec_node->order);
 
              cs->redirect_callee_duplicating_thunks (val->spec_node);
index 26335ec4b182b326b5eefb10f581585515d35e96..f62760fd39ca06315604000ebcf494daeea12440 100644 (file)
@@ -248,8 +248,8 @@ report_inline_failed_reason (struct cgraph_edge *e)
   if (dump_file)
     {
       fprintf (dump_file, "  not inlinable: %s/%i -> %s/%i, %s\n",
-              xstrdup (e->caller->name ()), e->caller->order,
-              xstrdup (e->callee->name ()), e->callee->order,
+              xstrdup_for_dump (e->caller->name ()), e->caller->order,
+              xstrdup_for_dump (e->callee->name ()), e->callee->order,
               cgraph_inline_failed_string (e->inline_failed));
     }
 }
@@ -480,9 +480,9 @@ want_early_inline_function_p (struct cgraph_edge *e)
          if (dump_file)
            fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
                     "call is cold and code would grow by %i\n",
-                    xstrdup (e->caller->name ()),
+                    xstrdup_for_dump (e->caller->name ()),
                     e->caller->order,
-                    xstrdup (callee->name ()), callee->order,
+                    xstrdup_for_dump (callee->name ()), callee->order,
                     growth);
          want_inline = false;
        }
@@ -491,9 +491,9 @@ want_early_inline_function_p (struct cgraph_edge *e)
          if (dump_file)
            fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
                     "growth %i exceeds --param early-inlining-insns\n",
-                    xstrdup (e->caller->name ()),
+                    xstrdup_for_dump (e->caller->name ()),
                     e->caller->order,
-                    xstrdup (callee->name ()), callee->order,
+                    xstrdup_for_dump (callee->name ()), callee->order,
                     growth);
          want_inline = false;
        }
@@ -504,9 +504,9 @@ want_early_inline_function_p (struct cgraph_edge *e)
            fprintf (dump_file, "  will not early inline: %s/%i->%s/%i, "
                     "growth %i exceeds --param early-inlining-insns "
                     "divided by number of calls\n",
-                    xstrdup (e->caller->name ()),
+                    xstrdup_for_dump (e->caller->name ()),
                     e->caller->order,
-                    xstrdup (callee->name ()), callee->order,
+                    xstrdup_for_dump (callee->name ()), callee->order,
                     growth);
          want_inline = false;
        }
@@ -925,9 +925,9 @@ edge_badness (struct cgraph_edge *edge, bool dump)
   if (dump)
     {
       fprintf (dump_file, "    Badness calculation for %s/%i -> %s/%i\n",
-              xstrdup (edge->caller->name ()),
+              xstrdup_for_dump (edge->caller->name ()),
               edge->caller->order,
-              xstrdup (callee->name ()),
+              xstrdup_for_dump (callee->name ()),
               edge->callee->order);
       fprintf (dump_file, "      size growth %i, time %i ",
               growth,
@@ -1094,9 +1094,9 @@ update_edge_key (edge_heap_t *heap, struct cgraph_edge *edge)
              fprintf (dump_file,
                       "  decreasing badness %s/%i -> %s/%i, %"PRId64
                       " to %"PRId64"\n",
-                      xstrdup (edge->caller->name ()),
+                      xstrdup_for_dump (edge->caller->name ()),
                       edge->caller->order,
-                      xstrdup (edge->callee->name ()),
+                      xstrdup_for_dump (edge->callee->name ()),
                       edge->callee->order,
                       n->get_key ().to_int (),
                       badness.to_int ());
@@ -1111,9 +1111,9 @@ update_edge_key (edge_heap_t *heap, struct cgraph_edge *edge)
         {
           fprintf (dump_file,
                    "  enqueuing call %s/%i -> %s/%i, badness %"PRId64"\n",
-                   xstrdup (edge->caller->name ()),
+                   xstrdup_for_dump (edge->caller->name ()),
                    edge->caller->order,
-                   xstrdup (edge->callee->name ()),
+                   xstrdup_for_dump (edge->callee->name ()),
                    edge->callee->order,
                    badness.to_int ());
         }
@@ -1892,8 +1892,8 @@ flatten_function (struct cgraph_node *node, bool early)
          if (dump_file)
            fprintf (dump_file,
                     "Not inlining %s into %s to avoid cycle.\n",
-                    xstrdup (callee->name ()),
-                    xstrdup (e->caller->name ()));
+                    xstrdup_for_dump (callee->name ()),
+                    xstrdup_for_dump (e->caller->name ()));
          e->inline_failed = CIF_RECURSIVE_INLINING;
          continue;
        }
@@ -1933,8 +1933,8 @@ flatten_function (struct cgraph_node *node, bool early)
          recursing through the original node if the node was cloned.  */
       if (dump_file)
        fprintf (dump_file, " Inlining %s into %s.\n",
-                xstrdup (callee->name ()),
-                xstrdup (e->caller->name ()));
+                xstrdup_for_dump (callee->name ()),
+                xstrdup_for_dump (e->caller->name ()));
       orig_callee = callee;
       inline_call (e, true, NULL, NULL, false);
       if (e->callee != orig_callee)
@@ -2311,8 +2311,8 @@ inline_always_inline_functions (struct cgraph_node *node)
 
       if (dump_file)
        fprintf (dump_file, "  Inlining %s into %s (always_inline).\n",
-                xstrdup (e->callee->name ()),
-                xstrdup (e->caller->name ()));
+                xstrdup_for_dump (e->callee->name ()),
+                xstrdup_for_dump (e->caller->name ()));
       inline_call (e, true, NULL, NULL, false);
       inlined = true;
     }
@@ -2363,8 +2363,8 @@ early_inline_small_functions (struct cgraph_node *node)
 
       if (dump_file)
        fprintf (dump_file, " Inlining %s into %s.\n",
-                xstrdup (callee->name ()),
-                xstrdup (e->caller->name ()));
+                xstrdup_for_dump (callee->name ()),
+                xstrdup_for_dump (e->caller->name ()));
       inline_call (e, true, NULL, NULL, true);
       inlined = true;
     }
index 340d033b6a52fa2714460192e8b37c52778a66eb..f540bd6558b6b58dcb2d5b50def14de4e5e87de4 100644 (file)
@@ -607,8 +607,8 @@ ipa_profile (void)
                    {
                      fprintf (dump_file, "Indirect call -> direct call from"
                               " other module %s/%i => %s/%i, prob %3.2f\n",
-                              xstrdup (n->name ()), n->order,
-                              xstrdup (n2->name ()), n2->order,
+                              xstrdup_for_dump (n->name ()), n->order,
+                              xstrdup_for_dump (n2->name ()), n2->order,
                               e->indirect_info->common_target_probability
                               / (float)REG_BR_PROB_BASE);
                    }
index 9fab47df2617dab2404b4f7f759df0a33582e8fe..50adefbcde51d708cf58f34d08d0712df6236e38 100644 (file)
@@ -401,8 +401,8 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
        continue;
 
       fprintf (f, "    callsite  %s/%i -> %s/%i : \n",
-              xstrdup (node->name ()), node->order,
-              xstrdup (cs->callee->name ()),
+              xstrdup_for_dump (node->name ()), node->order,
+              xstrdup_for_dump (cs->callee->name ()),
               cs->callee->order);
       ipa_print_node_jump_functions_for_edge (f, cs);
     }
@@ -2657,9 +2657,9 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
          if (dump_file)
            fprintf (dump_file, "ipa-prop: Discovered call to a known target "
                     "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
-                    xstrdup (ie->caller->name ()),
+                    xstrdup_for_dump (ie->caller->name ()),
                     ie->caller->order,
-                    xstrdup (ie->callee->name ()),
+                    xstrdup_for_dump (ie->callee->name ()),
                     ie->callee->order);
          return NULL;
        }
@@ -2678,11 +2678,11 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
          if (dump_file)
            fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
                     "(%s/%i -> %s/%i) but the call is already speculated to %s/%i. Giving up.\n",
-                    xstrdup (ie->caller->name ()),
+                    xstrdup_for_dump (ie->caller->name ()),
                     ie->caller->order,
-                    xstrdup (callee->name ()),
+                    xstrdup_for_dump (callee->name ()),
                     callee->order,
-                    xstrdup (e2->callee->name ()),
+                    xstrdup_for_dump (e2->callee->name ()),
                     e2->callee->order);
        }
       else
@@ -2690,9 +2690,9 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
          if (dump_file)
            fprintf (dump_file, "ipa-prop: Discovered call to a speculative target "
                     "(%s/%i -> %s/%i) this agree with previous speculation.\n",
-                    xstrdup (ie->caller->name ()),
+                    xstrdup_for_dump (ie->caller->name ()),
                     ie->caller->order,
-                    xstrdup (callee->name ()),
+                    xstrdup_for_dump (callee->name ()),
                     callee->order);
        }
       return NULL;
@@ -2713,9 +2713,9 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
               "(%s/%i -> %s/%i), for stmt ",
               ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
               speculative ? "speculative" : "known",
-              xstrdup (ie->caller->name ()),
+              xstrdup_for_dump (ie->caller->name ()),
               ie->caller->order,
-              xstrdup (callee->name ()),
+              xstrdup_for_dump (callee->name ()),
               callee->order);
       if (ie->call_stmt)
        print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
@@ -2799,8 +2799,8 @@ remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
   to_del->remove_reference ();
   if (dump_file)
     fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
-            xstrdup (origin->caller->name ()),
-            origin->caller->order, xstrdup (symbol->name ()));
+            xstrdup_for_dump (origin->caller->name ()),
+            origin->caller->order, xstrdup_for_dump (symbol->name ()));
   return true;
 }
 
@@ -3214,9 +3214,9 @@ propagate_controlled_uses (struct cgraph_edge *cs)
                  if (dump_file)
                    fprintf (dump_file, "ipa-prop: Removing cloning-created "
                             "reference from %s/%i to %s/%i.\n",
-                            xstrdup (new_root->name ()),
+                            xstrdup_for_dump (new_root->name ()),
                             new_root->order,
-                            xstrdup (n->name ()), n->order);
+                            xstrdup_for_dump (n->name ()), n->order);
                  ref->remove_reference ();
                }
            }
@@ -3255,9 +3255,9 @@ propagate_controlled_uses (struct cgraph_edge *cs)
                            fprintf (dump_file, "ipa-prop: Removing "
                                     "cloning-created reference "
                                     "from %s/%i to %s/%i.\n",
-                                    xstrdup (clone->name ()),
+                                    xstrdup_for_dump (clone->name ()),
                                     clone->order,
-                                    xstrdup (n->name ()),
+                                    xstrdup_for_dump (n->name ()),
                                     n->order);
                          ref->remove_reference ();
                        }
index 7613205f6735a6e7a93565ff81be080b32a126db..c158837ba364e629d7691069aadaa93a0a446281 100644 (file)
@@ -427,8 +427,8 @@ ipa_merge_profiles (struct cgraph_node *dst,
   if (symtab->dump_file)
     {
       fprintf (symtab->dump_file, "Merging profiles of %s/%i to %s/%i\n",
-              xstrdup (src->name ()), src->order,
-              xstrdup (dst->name ()), dst->order);
+              xstrdup_for_dump (src->name ()), src->order,
+              xstrdup_for_dump (dst->name ()), dst->order);
     }
   dst->count += src->count;