From 2a72a9538fdd3e7ea5de08cbe233e1eb3dc5d44a Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 8 Dec 2014 19:31:45 +0000 Subject: [PATCH] PR jit/63854: Introduce xstrdup_for_dump 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 | 25 +++++++++++++++++++++++++ gcc/cgraph.c | 36 ++++++++++++++++++++---------------- gcc/cgraph.h | 28 ++++++++++++++++++++++++++++ gcc/cgraphclones.c | 4 ++-- gcc/ipa-cp.c | 4 ++-- gcc/ipa-inline.c | 44 ++++++++++++++++++++++---------------------- gcc/ipa-profile.c | 4 ++-- gcc/ipa-prop.c | 34 +++++++++++++++++----------------- gcc/ipa-utils.c | 4 ++-- 9 files changed, 120 insertions(+), 63 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edc26df8d15..5e4306d8b0a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2014-12-08 David Malcolm + + 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 PR ipa/64049 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 6aecb14823c..50c7b34b3dc 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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", diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 997414ce894..891b92500e7 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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 */ diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 1bf0477a48c..13bb0e95b44 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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; diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 9b6784b8b5f..79a1799d901 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3907,9 +3907,9 @@ perhaps_add_new_callers (cgraph_node *node, ipcp_value *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); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 26335ec4b18..f62760fd39c 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -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; } diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c index 340d033b6a5..f540bd6558b 100644 --- a/gcc/ipa-profile.c +++ b/gcc/ipa-profile.c @@ -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); } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 9fab47df261..50adefbcde5 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -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 (); } diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 7613205f673..c158837ba36 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -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; -- 2.30.2