Introduce -fdump-ipa-clones dump output
* cgraph.c (symbol_table::initialize): Initialize ipa_clones_dump_file. (cgraph_node::remove): Report to ipa_clones_dump_file. * cgraph.h: Add new argument (suffix) to cloning methods. * cgraphclones.c (dump_callgraph_transformation): New function. (cgraph_node::create_clone): New argument. (cgraph_node::create_virtual_clone): Likewise. (cgraph_node::create_version_clone): Likewise. * dumpfile.c: Add .ipa-clones dump file. * dumpfile.h (enum tree_dump_index): Add TDI_clones * ipa-inline-transform.c (clone_inlined_nodes): Report operation to dump_callgraph_transformation. From-SVN: r243004
This commit is contained in:
parent
fb61d96cf2
commit
0bdad1238b
@ -1,3 +1,18 @@
|
||||
2016-11-30 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* cgraph.c (symbol_table::initialize): Initialize
|
||||
ipa_clones_dump_file.
|
||||
(cgraph_node::remove): Report to ipa_clones_dump_file.
|
||||
* cgraph.h: Add new argument (suffix) to cloning methods.
|
||||
* cgraphclones.c (dump_callgraph_transformation): New function.
|
||||
(cgraph_node::create_clone): New argument.
|
||||
(cgraph_node::create_virtual_clone): Likewise.
|
||||
(cgraph_node::create_version_clone): Likewise.
|
||||
* dumpfile.c: Add .ipa-clones dump file.
|
||||
* dumpfile.h (enum tree_dump_index): Add TDI_clones
|
||||
* ipa-inline-transform.c (clone_inlined_nodes): Report operation
|
||||
to dump_callgraph_transformation.
|
||||
|
||||
2016-11-30 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR sanitizer/78541
|
||||
|
@ -263,6 +263,9 @@ symbol_table::initialize (void)
|
||||
{
|
||||
if (!dump_file)
|
||||
dump_file = dump_begin (TDI_cgraph, NULL);
|
||||
|
||||
if (!ipa_clones_dump_file)
|
||||
ipa_clones_dump_file = dump_begin (TDI_clones, NULL);
|
||||
}
|
||||
|
||||
/* Allocate new callgraph node and insert it into basic data structures. */
|
||||
@ -1815,6 +1818,12 @@ cgraph_node::remove (void)
|
||||
cgraph_node *n;
|
||||
int uid = this->uid;
|
||||
|
||||
if (symtab->ipa_clones_dump_file && symtab->cloned_nodes.contains (this))
|
||||
fprintf (symtab->ipa_clones_dump_file,
|
||||
"Callgraph removal;%s;%d;%s;%d;%d\n", asm_name (), order,
|
||||
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
|
||||
DECL_SOURCE_COLUMN (decl));
|
||||
|
||||
symtab->call_cgraph_removal_hooks (this);
|
||||
remove_callers ();
|
||||
remove_callees ();
|
||||
|
20
gcc/cgraph.h
20
gcc/cgraph.h
@ -906,13 +906,14 @@ public:
|
||||
If the new node is being inlined into another one, NEW_INLINED_TO should be
|
||||
the outline function the new one is (even indirectly) inlined to.
|
||||
All hooks will see this in node's global.inlined_to, when invoked.
|
||||
Can be NULL if the node is not inlined. */
|
||||
Can be NULL if the node is not inlined. SUFFIX is string that is appended
|
||||
to the original name. */
|
||||
cgraph_node *create_clone (tree decl, gcov_type count, int freq,
|
||||
bool update_original,
|
||||
vec<cgraph_edge *> redirect_callers,
|
||||
bool call_duplication_hook,
|
||||
cgraph_node *new_inlined_to,
|
||||
bitmap args_to_skip);
|
||||
bitmap args_to_skip, const char *suffix = NULL);
|
||||
|
||||
/* Create callgraph node clone with new declaration. The actual body will
|
||||
be copied later at compilation stage. */
|
||||
@ -933,11 +934,14 @@ public:
|
||||
|
||||
If non-NULL BLOCK_TO_COPY determine what basic blocks
|
||||
was copied to prevent duplications of calls that are dead
|
||||
in the clone. */
|
||||
in the clone.
|
||||
|
||||
SUFFIX is string that is appended to the original name. */
|
||||
|
||||
cgraph_node *create_version_clone (tree new_decl,
|
||||
vec<cgraph_edge *> redirect_callers,
|
||||
bitmap bbs_to_copy);
|
||||
bitmap bbs_to_copy,
|
||||
const char *suffix = NULL);
|
||||
|
||||
/* Perform function versioning.
|
||||
Function versioning includes copying of the tree and
|
||||
@ -2223,6 +2227,10 @@ public:
|
||||
/* Return symbol used to separate symbol name from suffix. */
|
||||
static char symbol_suffix_separator ();
|
||||
|
||||
FILE* GTY ((skip)) ipa_clones_dump_file;
|
||||
|
||||
hash_set <const cgraph_node *> GTY ((skip)) cloned_nodes;
|
||||
|
||||
private:
|
||||
/* Allocate new callgraph node. */
|
||||
inline cgraph_node * allocate_cgraph_symbol (void);
|
||||
@ -2313,6 +2321,10 @@ tree clone_function_name (tree decl, const char *);
|
||||
void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
|
||||
bool, bitmap, bool, bitmap, basic_block);
|
||||
|
||||
void dump_callgraph_transformation (const cgraph_node *original,
|
||||
const cgraph_node *clone,
|
||||
const char *suffix);
|
||||
|
||||
/* In cgraphbuild.c */
|
||||
int compute_call_stmt_bb_frequency (tree, basic_block bb);
|
||||
void record_references_in_initializer (tree, bool);
|
||||
|
@ -381,6 +381,28 @@ cgraph_node::expand_all_artificial_thunks ()
|
||||
e = e->next_caller;
|
||||
}
|
||||
|
||||
void
|
||||
dump_callgraph_transformation (const cgraph_node *original,
|
||||
const cgraph_node *clone,
|
||||
const char *suffix)
|
||||
{
|
||||
if (symtab->ipa_clones_dump_file)
|
||||
{
|
||||
fprintf (symtab->ipa_clones_dump_file,
|
||||
"Callgraph clone;%s;%d;%s;%d;%d;%s;%d;%s;%d;%d;%s\n",
|
||||
original->asm_name (), original->order,
|
||||
DECL_SOURCE_FILE (original->decl),
|
||||
DECL_SOURCE_LINE (original->decl),
|
||||
DECL_SOURCE_COLUMN (original->decl), clone->asm_name (),
|
||||
clone->order, DECL_SOURCE_FILE (clone->decl),
|
||||
DECL_SOURCE_LINE (clone->decl), DECL_SOURCE_COLUMN (clone->decl),
|
||||
suffix);
|
||||
|
||||
symtab->cloned_nodes.add (original);
|
||||
symtab->cloned_nodes.add (clone);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create node representing clone of N executed COUNT times. Decrease
|
||||
the execution counts from original node too.
|
||||
The new clone will have decl set to DECL that may or may not be the same
|
||||
@ -403,13 +425,16 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq,
|
||||
vec<cgraph_edge *> redirect_callers,
|
||||
bool call_duplication_hook,
|
||||
cgraph_node *new_inlined_to,
|
||||
bitmap args_to_skip)
|
||||
bitmap args_to_skip, const char *suffix)
|
||||
{
|
||||
cgraph_node *new_node = symtab->create_empty ();
|
||||
cgraph_edge *e;
|
||||
gcov_type count_scale;
|
||||
unsigned i;
|
||||
|
||||
if (new_inlined_to)
|
||||
dump_callgraph_transformation (this, new_inlined_to, "inlining to");
|
||||
|
||||
new_node->decl = new_decl;
|
||||
new_node->register_symbol ();
|
||||
new_node->origin = origin;
|
||||
@ -495,6 +520,10 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq,
|
||||
|
||||
if (call_duplication_hook)
|
||||
symtab->call_cgraph_duplication_hooks (this, new_node);
|
||||
|
||||
if (!new_inlined_to)
|
||||
dump_callgraph_transformation (this, new_node, suffix);
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
@ -575,7 +604,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
|
||||
SET_DECL_RTL (new_decl, NULL);
|
||||
|
||||
new_node = create_clone (new_decl, count, CGRAPH_FREQ_BASE, false,
|
||||
redirect_callers, false, NULL, args_to_skip);
|
||||
redirect_callers, false, NULL, args_to_skip, suffix);
|
||||
|
||||
/* Update the properties.
|
||||
Make clone visible only within this translation unit. Make sure
|
||||
@ -863,7 +892,8 @@ update_call_expr (cgraph_node *new_version)
|
||||
cgraph_node *
|
||||
cgraph_node::create_version_clone (tree new_decl,
|
||||
vec<cgraph_edge *> redirect_callers,
|
||||
bitmap bbs_to_copy)
|
||||
bitmap bbs_to_copy,
|
||||
const char *suffix)
|
||||
{
|
||||
cgraph_node *new_version;
|
||||
cgraph_edge *e;
|
||||
@ -904,6 +934,8 @@ cgraph_node::create_version_clone (tree new_decl,
|
||||
|
||||
symtab->call_cgraph_duplication_hooks (this, new_version);
|
||||
|
||||
dump_callgraph_transformation (this, new_version, suffix);
|
||||
|
||||
return new_version;
|
||||
}
|
||||
|
||||
@ -931,7 +963,7 @@ cgraph_node::create_version_clone_with_body
|
||||
(vec<cgraph_edge *> redirect_callers,
|
||||
vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip,
|
||||
bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block,
|
||||
const char *clone_name)
|
||||
const char *suffix)
|
||||
{
|
||||
tree old_decl = decl;
|
||||
cgraph_node *new_version_node = NULL;
|
||||
@ -950,7 +982,7 @@ cgraph_node::create_version_clone_with_body
|
||||
= build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
|
||||
|
||||
/* Generate a new name for the new version. */
|
||||
DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name);
|
||||
DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
|
||||
SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
|
||||
SET_DECL_RTL (new_decl, NULL);
|
||||
|
||||
@ -961,7 +993,7 @@ cgraph_node::create_version_clone_with_body
|
||||
/* Create the new version's call-graph node.
|
||||
and update the edges of the new node. */
|
||||
new_version_node = create_version_clone (new_decl, redirect_callers,
|
||||
bbs_to_copy);
|
||||
bbs_to_copy, suffix);
|
||||
|
||||
if (ipa_transforms_to_apply.exists ())
|
||||
new_version_node->ipa_transforms_to_apply
|
||||
|
@ -55,6 +55,8 @@ static struct dump_file_info dump_files[TDI_end] =
|
||||
0, 0, 0, 0, 0, false, false},
|
||||
{".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
|
||||
0, 0, 0, 0, 0, false, false},
|
||||
{".ipa-clones", "ipa-clones", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
|
||||
0, 0, 0, 0, 0, false, false},
|
||||
{".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
|
||||
0, 0, 0, 0, 1, false, false},
|
||||
{".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
|
||||
|
@ -29,6 +29,7 @@ enum tree_dump_index
|
||||
TDI_none, /* No dump */
|
||||
TDI_cgraph, /* dump function call graph. */
|
||||
TDI_inheritance, /* dump type inheritance graph. */
|
||||
TDI_clones, /* dump IPA cloning decisions. */
|
||||
TDI_tu, /* dump the whole translation unit. */
|
||||
TDI_class, /* dump class hierarchy. */
|
||||
TDI_original, /* dump each function before optimizing it */
|
||||
|
@ -209,6 +209,9 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
|
||||
duplicate = false;
|
||||
e->callee->externally_visible = false;
|
||||
update_noncloned_frequencies (e->callee, e->frequency);
|
||||
|
||||
dump_callgraph_transformation (e->callee, inlining_into,
|
||||
"inlining to");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user