Commit 0bdad123 by Martin Liska Committed by Martin Liska

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
parent fb61d96c
2016-11-30 Martin Liska <mliska@suse.cz> 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 PR sanitizer/78541
* asan.c (asan_expand_mark_ifn): Properly * asan.c (asan_expand_mark_ifn): Properly
select a VAR_DECL from FRAME.* component reference. select a VAR_DECL from FRAME.* component reference.
...@@ -263,6 +263,9 @@ symbol_table::initialize (void) ...@@ -263,6 +263,9 @@ symbol_table::initialize (void)
{ {
if (!dump_file) if (!dump_file)
dump_file = dump_begin (TDI_cgraph, NULL); 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. */ /* Allocate new callgraph node and insert it into basic data structures. */
...@@ -1815,6 +1818,12 @@ cgraph_node::remove (void) ...@@ -1815,6 +1818,12 @@ cgraph_node::remove (void)
cgraph_node *n; cgraph_node *n;
int uid = this->uid; 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); symtab->call_cgraph_removal_hooks (this);
remove_callers (); remove_callers ();
remove_callees (); remove_callees ();
......
...@@ -906,13 +906,14 @@ public: ...@@ -906,13 +906,14 @@ public:
If the new node is being inlined into another one, NEW_INLINED_TO should be 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. the outline function the new one is (even indirectly) inlined to.
All hooks will see this in node's global.inlined_to, when invoked. 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, cgraph_node *create_clone (tree decl, gcov_type count, int freq,
bool update_original, bool update_original,
vec<cgraph_edge *> redirect_callers, vec<cgraph_edge *> redirect_callers,
bool call_duplication_hook, bool call_duplication_hook,
cgraph_node *new_inlined_to, 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 /* Create callgraph node clone with new declaration. The actual body will
be copied later at compilation stage. */ be copied later at compilation stage. */
...@@ -933,11 +934,14 @@ public: ...@@ -933,11 +934,14 @@ public:
If non-NULL BLOCK_TO_COPY determine what basic blocks If non-NULL BLOCK_TO_COPY determine what basic blocks
was copied to prevent duplications of calls that are dead 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, cgraph_node *create_version_clone (tree new_decl,
vec<cgraph_edge *> redirect_callers, vec<cgraph_edge *> redirect_callers,
bitmap bbs_to_copy); bitmap bbs_to_copy,
const char *suffix = NULL);
/* Perform function versioning. /* Perform function versioning.
Function versioning includes copying of the tree and Function versioning includes copying of the tree and
...@@ -2223,6 +2227,10 @@ public: ...@@ -2223,6 +2227,10 @@ public:
/* Return symbol used to separate symbol name from suffix. */ /* Return symbol used to separate symbol name from suffix. */
static char symbol_suffix_separator (); static char symbol_suffix_separator ();
FILE* GTY ((skip)) ipa_clones_dump_file;
hash_set <const cgraph_node *> GTY ((skip)) cloned_nodes;
private: private:
/* Allocate new callgraph node. */ /* Allocate new callgraph node. */
inline cgraph_node * allocate_cgraph_symbol (void); inline cgraph_node * allocate_cgraph_symbol (void);
...@@ -2313,6 +2321,10 @@ tree clone_function_name (tree decl, const char *); ...@@ -2313,6 +2321,10 @@ tree clone_function_name (tree decl, const char *);
void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *, void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
bool, bitmap, bool, bitmap, basic_block); bool, bitmap, bool, bitmap, basic_block);
void dump_callgraph_transformation (const cgraph_node *original,
const cgraph_node *clone,
const char *suffix);
/* In cgraphbuild.c */ /* In cgraphbuild.c */
int compute_call_stmt_bb_frequency (tree, basic_block bb); int compute_call_stmt_bb_frequency (tree, basic_block bb);
void record_references_in_initializer (tree, bool); void record_references_in_initializer (tree, bool);
......
...@@ -381,6 +381,28 @@ cgraph_node::expand_all_artificial_thunks () ...@@ -381,6 +381,28 @@ cgraph_node::expand_all_artificial_thunks ()
e = e->next_caller; 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 /* Create node representing clone of N executed COUNT times. Decrease
the execution counts from original node too. the execution counts from original node too.
The new clone will have decl set to DECL that may or may not be the same 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, ...@@ -403,13 +425,16 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq,
vec<cgraph_edge *> redirect_callers, vec<cgraph_edge *> redirect_callers,
bool call_duplication_hook, bool call_duplication_hook,
cgraph_node *new_inlined_to, cgraph_node *new_inlined_to,
bitmap args_to_skip) bitmap args_to_skip, const char *suffix)
{ {
cgraph_node *new_node = symtab->create_empty (); cgraph_node *new_node = symtab->create_empty ();
cgraph_edge *e; cgraph_edge *e;
gcov_type count_scale; gcov_type count_scale;
unsigned i; unsigned i;
if (new_inlined_to)
dump_callgraph_transformation (this, new_inlined_to, "inlining to");
new_node->decl = new_decl; new_node->decl = new_decl;
new_node->register_symbol (); new_node->register_symbol ();
new_node->origin = origin; new_node->origin = origin;
...@@ -495,6 +520,10 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq, ...@@ -495,6 +520,10 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq,
if (call_duplication_hook) if (call_duplication_hook)
symtab->call_cgraph_duplication_hooks (this, new_node); symtab->call_cgraph_duplication_hooks (this, new_node);
if (!new_inlined_to)
dump_callgraph_transformation (this, new_node, suffix);
return new_node; return new_node;
} }
...@@ -575,7 +604,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, ...@@ -575,7 +604,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
SET_DECL_RTL (new_decl, NULL); SET_DECL_RTL (new_decl, NULL);
new_node = create_clone (new_decl, count, CGRAPH_FREQ_BASE, false, 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. /* Update the properties.
Make clone visible only within this translation unit. Make sure Make clone visible only within this translation unit. Make sure
...@@ -863,7 +892,8 @@ update_call_expr (cgraph_node *new_version) ...@@ -863,7 +892,8 @@ update_call_expr (cgraph_node *new_version)
cgraph_node * cgraph_node *
cgraph_node::create_version_clone (tree new_decl, cgraph_node::create_version_clone (tree new_decl,
vec<cgraph_edge *> redirect_callers, vec<cgraph_edge *> redirect_callers,
bitmap bbs_to_copy) bitmap bbs_to_copy,
const char *suffix)
{ {
cgraph_node *new_version; cgraph_node *new_version;
cgraph_edge *e; cgraph_edge *e;
...@@ -904,6 +934,8 @@ cgraph_node::create_version_clone (tree new_decl, ...@@ -904,6 +934,8 @@ cgraph_node::create_version_clone (tree new_decl,
symtab->call_cgraph_duplication_hooks (this, new_version); symtab->call_cgraph_duplication_hooks (this, new_version);
dump_callgraph_transformation (this, new_version, suffix);
return new_version; return new_version;
} }
...@@ -931,7 +963,7 @@ cgraph_node::create_version_clone_with_body ...@@ -931,7 +963,7 @@ cgraph_node::create_version_clone_with_body
(vec<cgraph_edge *> redirect_callers, (vec<cgraph_edge *> redirect_callers,
vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip, vec<ipa_replace_map *, va_gc> *tree_map, bitmap args_to_skip,
bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block, bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block,
const char *clone_name) const char *suffix)
{ {
tree old_decl = decl; tree old_decl = decl;
cgraph_node *new_version_node = NULL; cgraph_node *new_version_node = NULL;
...@@ -950,7 +982,7 @@ cgraph_node::create_version_clone_with_body ...@@ -950,7 +982,7 @@ cgraph_node::create_version_clone_with_body
= build_function_decl_skip_args (old_decl, args_to_skip, skip_return); = build_function_decl_skip_args (old_decl, args_to_skip, skip_return);
/* Generate a new name for the new version. */ /* 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_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
SET_DECL_RTL (new_decl, NULL); SET_DECL_RTL (new_decl, NULL);
...@@ -961,7 +993,7 @@ cgraph_node::create_version_clone_with_body ...@@ -961,7 +993,7 @@ cgraph_node::create_version_clone_with_body
/* Create the new version's call-graph node. /* Create the new version's call-graph node.
and update the edges of the new node. */ and update the edges of the new node. */
new_version_node = create_version_clone (new_decl, redirect_callers, new_version_node = create_version_clone (new_decl, redirect_callers,
bbs_to_copy); bbs_to_copy, suffix);
if (ipa_transforms_to_apply.exists ()) if (ipa_transforms_to_apply.exists ())
new_version_node->ipa_transforms_to_apply new_version_node->ipa_transforms_to_apply
......
...@@ -55,6 +55,8 @@ static struct dump_file_info dump_files[TDI_end] = ...@@ -55,6 +55,8 @@ static struct dump_file_info dump_files[TDI_end] =
0, 0, 0, 0, 0, false, false}, 0, 0, 0, 0, 0, false, false},
{".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA, {".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
0, 0, 0, 0, 0, false, false}, 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, {".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
0, 0, 0, 0, 1, false, false}, 0, 0, 0, 0, 1, false, false},
{".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE, {".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
......
...@@ -29,6 +29,7 @@ enum tree_dump_index ...@@ -29,6 +29,7 @@ enum tree_dump_index
TDI_none, /* No dump */ TDI_none, /* No dump */
TDI_cgraph, /* dump function call graph. */ TDI_cgraph, /* dump function call graph. */
TDI_inheritance, /* dump type inheritance graph. */ TDI_inheritance, /* dump type inheritance graph. */
TDI_clones, /* dump IPA cloning decisions. */
TDI_tu, /* dump the whole translation unit. */ TDI_tu, /* dump the whole translation unit. */
TDI_class, /* dump class hierarchy. */ TDI_class, /* dump class hierarchy. */
TDI_original, /* dump each function before optimizing it */ TDI_original, /* dump each function before optimizing it */
......
...@@ -209,6 +209,9 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, ...@@ -209,6 +209,9 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
duplicate = false; duplicate = false;
e->callee->externally_visible = false; e->callee->externally_visible = false;
update_noncloned_frequencies (e->callee, e->frequency); update_noncloned_frequencies (e->callee, e->frequency);
dump_callgraph_transformation (e->callee, inlining_into,
"inlining to");
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment