From patchwork Fri Nov 11 14:30:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 81845 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp1296850qge; Fri, 11 Nov 2016 06:31:04 -0800 (PST) X-Received: by 10.107.143.211 with SMTP id r202mr12061894iod.121.1478874664191; Fri, 11 Nov 2016 06:31:04 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id es13si8777554pac.153.2016.11.11.06.31.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Nov 2016 06:31:04 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-441106-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-441106-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-441106-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=QhJY+KIigt78hFLY+xLxRAOHwSC4dTTtR0HZbirG0Zx5Jp8ybB yEDUctpj1PKK3qkDeijPsBxmeMWtPgLFfreoa9BOzkeVpInvESao8Sc47q+6WBPY 9HlpecqXlIe3tiK4e1AStSSDkeSzGADgh6eai0d2hKdcI1BJZzW6GQ4ag= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=hd8QMDHEM60rZfp8zouR4h4sNU4=; b=MkjY9KCKAP2qcDQ/IX1F mho4yH/dKkclu/b8YIcsEjT6l+zHGJwrNMXBbnvDOQceTk6yArZS6FY+SaSCgiY2 QuoJk2H5YId+K1P2L7W2OTfdD7Heau0tRsnniVMCCnWsQhR26i2xBM0uWzC5n17b ++HS9+0VtylVb/ZA426U0Is= Received: (qmail 46029 invoked by alias); 11 Nov 2016 14:30:42 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 45867 invoked by uid 89); 11 Nov 2016 14:30:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=9937, 20161111 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Nov 2016 14:30:23 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4A395AC34 for ; Fri, 11 Nov 2016 14:30:19 +0000 (UTC) To: GCC Patches From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Subject: [PATCH] Introduce -fdump-ipa-clones dump output Message-ID: <392fa755-a89b-2481-bbd8-dac84752c80c@suse.cz> Date: Fri, 11 Nov 2016 15:30:18 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 X-IsSubscribed: yes Hello. Motivation for the patch is to dump IPA clones that were created by all inter-procedural optimizations. Usage of such input is to track set of functions where a code from another function can eventually occur. Usage of the dump file can be seen here: [1]. Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. Ready to be installed? Martin [1] https://github.com/marxin/kgraft-analysis-tool >From 700b9833771a5b646d3db44014af81c007dd48f4 Mon Sep 17 00:00:00 2001 From: marxin Date: Wed, 9 Nov 2016 14:23:30 +0100 Subject: [PATCH] Introduce -fdump-ipa-clones dump output gcc/ChangeLog: 2016-11-11 Martin Liska * 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. --- gcc/cgraph.c | 9 +++++++++ gcc/cgraph.h | 20 ++++++++++++++++---- gcc/cgraphclones.c | 44 ++++++++++++++++++++++++++++++++++++++------ gcc/dumpfile.c | 2 ++ gcc/dumpfile.h | 1 + gcc/ipa-inline-transform.c | 3 +++ 6 files changed, 69 insertions(+), 10 deletions(-) diff --git a/gcc/cgraph.c b/gcc/cgraph.c index b702a7c..867e371 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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 (); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index cc730d2..2d59291 100644 --- a/gcc/cgraph.h +++ b/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 redirect_callers, bool call_duplication_hook, cgraph_node *new_inlined_to, - bitmap args_to_skip); + bitmap args_to_skip, const char *sufix = 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 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 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 *, 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); diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 686c289..349892d 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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 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 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 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 redirect_callers, vec *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 diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c index 74522a6..9630360 100644 --- a/gcc/dumpfile.c +++ b/gcc/dumpfile.c @@ -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, diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h index 3f08b16..ab78286 100644 --- a/gcc/dumpfile.h +++ b/gcc/dumpfile.h @@ -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 */ diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index efe7421..6875080 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -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 { -- 2.10.1