From patchwork Fri Jun 8 14:57:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 926869 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-479356-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yJLF+1C3"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 412QWS21Mhz9s4Y for ; Sat, 9 Jun 2018 00:57:56 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=ToQ8Q2HfD9dVDhwyREcYzxjSn+UZUlmr7HFfklaYsCUrWf0DOKyJs RyvgnNz6/62rkNnRiRZIJ7fcUJmdsKFU2Sgineq0EK4OA0sCB2YWpBohEyq/Q6sJ MFah/yo+J/o3alkKquCQBkZwv/HAOY4tSgN33khPO3dM3kExSn91XY= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=sRzyiw/lrZQ5P119aM1AnRnVaqc=; b=yJLF+1C32OX1tcghs3xj 90obL+oNAhg6/Zm8lv0pt/AAwQM4YqYbzpRg6TWfguJgHO5ZfYEQgfrEjTxa/qRo QMscU7hFtBPobgEsBnb/3ayowrfN/mw51S9whuWDTj5zMnM8avhyl6Gm5oluvSU8 u6GGnKgJUFildSyYPqXUcF8= Received: (qmail 71569 invoked by alias); 8 Jun 2018 14:57:48 -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 71547 invoked by uid 89); 8 Jun 2018 14:57:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-9.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=Watch, shares, 5848, Step X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 08 Jun 2018 14:57:44 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id B7DDC542D41; Fri, 8 Jun 2018 16:57:41 +0200 (CEST) Date: Fri, 8 Jun 2018 16:57:41 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Break LTO cgraph dump into more pieces. Message-ID: <20180608145741.GA99335@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Hi, this patch splits LTO cgraph dump file into multiple files: 1) cgraph which contains pretty much what cgraph dump has in normal compilation 2) lto-link which contains symtab before symtab merging and decision of the LTO linker 3) lto-decl-merge which dumps declaration merging 4) lto-partition which contains partitioning decisions. The main motivation is to make it easier to find relevant data. Bit ugly is that dumps are not quite chronological. Technically lto-link happens first, decl-merge next, then all optimization passes are done and lto-partition is last. I don't know how to arrange it and I think i tis OK as it is. Other bit non-standard thing is that I have added them as ipa dumps. It may also make sense to declare them language dumps since LTO is techincally front-end but it seems bit misleading to me. I think it makes more sense if they appear with -fdump-ipa-all. Bootstrapped/regtested x86_64-linux, will commit later if there are no complains. Honza * dumpfile.c (FIRST_ME_AUTO_NUMBERED_DUMP): Bump to 4. * lto-lang.c (lto_link_dump_id, decl_merge_dump_id, partition_dump_id): New global vars. (lto_register_dumps): New hook. (LANG_HOOKS_REGISTER_DUMPS): New. * lto-partition.c: Dump into dump_file instead of symtab->dump_file. * lto-symtab.c: Include lto.h; dump into dump_file instead of symtab->dump_file. (lto_symtab_merge_decls): Initialize dump file. * lto.c (read_cgraph_and_symbols): Initialize dump file. (do_whole_program_analysis): Likewise. Index: dumpfile.c =================================================================== --- dumpfile.c (revision 261327) +++ dumpfile.c (working copy) @@ -65,7 +65,7 @@ DUMP_FILE_INFO (".gimple", "tree-gimple", DK_tree, 0), DUMP_FILE_INFO (".nested", "tree-nested", DK_tree, 0), #define FIRST_AUTO_NUMBERED_DUMP 1 -#define FIRST_ME_AUTO_NUMBERED_DUMP 3 +#define FIRST_ME_AUTO_NUMBERED_DUMP 4 DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0), DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0), Index: lto/lto-lang.c =================================================================== --- lto/lto-lang.c (revision 261327) +++ lto/lto-lang.c (working copy) @@ -37,6 +37,9 @@ #include "stringpool.h" #include "attribs.h" +/* LTO specific dumps. */ +int lto_link_dump_id, decl_merge_dump_id, partition_dump_id; + static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); static tree handle_const_attribute (tree *, tree, tree, int, bool *); @@ -1375,6 +1378,23 @@ return true; } +/* Register c++-specific dumps. */ + +void +lto_register_dumps (gcc::dump_manager *dumps) +{ + lto_link_dump_id = dumps->dump_register + (".lto-link", "ipa-lto-link", "ipa-lto-link", + DK_ipa, OPTGROUP_NONE, false); + decl_merge_dump_id = dumps->dump_register + (".lto-decl-merge", "ipa-lto-decl-merge", "ipa-lto-decl-merge", + DK_ipa, OPTGROUP_NONE, false); + partition_dump_id = dumps->dump_register + (".lto-partition", "ipa-lto-partition", "ipa-lto-partition", + DK_ipa, OPTGROUP_NONE, false); +} + + /* Initialize tree structures required by the LTO front end. */ static void lto_init_ts (void) @@ -1390,6 +1410,8 @@ #define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lto_complain_wrong_lang_p #undef LANG_HOOKS_INIT_OPTIONS_STRUCT #define LANG_HOOKS_INIT_OPTIONS_STRUCT lto_init_options_struct +#undef LANG_HOOKS_REGISTER_DUMPS +#define LANG_HOOKS_REGISTER_DUMPS lto_register_dumps #undef LANG_HOOKS_HANDLE_OPTION #define LANG_HOOKS_HANDLE_OPTION lto_handle_option #undef LANG_HOOKS_POST_OPTIONS Index: lto/lto-partition.c =================================================================== --- lto/lto-partition.c (revision 261327) +++ lto/lto-partition.c (working copy) @@ -160,8 +160,8 @@ if (symbol_partitioned_p (node)) { node->in_other_partition = 1; - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Symbol node %s now used in multiple partitions\n", node->name ()); } @@ -541,13 +541,13 @@ order.qsort (node_cmp); noreorder.qsort (node_cmp); - if (symtab->dump_file) + if (dump_file) { for (unsigned i = 0; i < order.length (); i++) - fprintf (symtab->dump_file, "Balanced map symbol order:%s:%u\n", + fprintf (dump_file, "Balanced map symbol order:%s:%u\n", order[i]->name (), order[i]->tp_first_run); for (unsigned i = 0; i < noreorder.length (); i++) - fprintf (symtab->dump_file, "Balanced map symbol no_reorder:%s:%u\n", + fprintf (dump_file, "Balanced map symbol no_reorder:%s:%u\n", noreorder[i]->name (), noreorder[i]->tp_first_run); } @@ -569,8 +569,8 @@ partition_size = PARAM_VALUE (MIN_PARTITION_SIZE); npartitions = 1; partition = new_partition (""); - if (symtab->dump_file) - fprintf (symtab->dump_file, "Total unit size: %" PRId64 ", partition size: %" PRId64 "\n", + if (dump_file) + fprintf (dump_file, "Total unit size: %" PRId64 ", partition size: %" PRId64 "\n", total_size, partition_size); auto_vec next_nodes; @@ -763,8 +763,8 @@ best_n_nodes = lto_symtab_encoder_size (partition->encoder); best_varpool_pos = varpool_pos; } - if (symtab->dump_file) - fprintf (symtab->dump_file, "Step %i: added %s/%i, size %i, " + if (dump_file) + fprintf (dump_file, "Step %i: added %s/%i, size %i, " "cost %" PRId64 "/%" PRId64 " " "best %" PRId64 "/%" PRId64", step %i\n", i, order[i]->name (), order[i]->order, @@ -777,8 +777,8 @@ { if (best_i != i) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Unwinding %i insertions to step %i\n", + if (dump_file) + fprintf (dump_file, "Unwinding %i insertions to step %i\n", i - best_i, best_i); undo_partition (partition, best_n_nodes); varpool_pos = best_varpool_pos; @@ -785,8 +785,8 @@ } gcc_assert (best_size == partition->insns); i = best_i; - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Partition insns: %i (want %" PRId64 ")\n", partition->insns, partition_size); /* When we are finished, avoid creating empty partition. */ @@ -799,8 +799,8 @@ last_visited_node = 0; cost = 0; - if (symtab->dump_file) - fprintf (symtab->dump_file, "New partition\n"); + if (dump_file) + fprintf (dump_file, "New partition\n"); best_n_nodes = 0; best_cost = -1; @@ -812,8 +812,8 @@ /* Watch for overflow. */ partition_size = INT_MAX / 16; - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Total size: %" PRId64 " partition_size: %" PRId64 "\n", total_size, partition_size); if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) @@ -840,21 +840,21 @@ gcc_assert (next_nodes.length () || npartitions != 1 || !best_cost || best_cost == -1); add_sorted_nodes (next_nodes, partition); - if (symtab->dump_file) + if (dump_file) { - fprintf (symtab->dump_file, "\nPartition sizes:\n"); + fprintf (dump_file, "\nPartition sizes:\n"); unsigned partitions = ltrans_partitions.length (); for (unsigned i = 0; i < partitions ; i++) { ltrans_partition p = ltrans_partitions[i]; - fprintf (symtab->dump_file, "partition %d contains %d (%2.2f%%)" + fprintf (dump_file, "partition %d contains %d (%2.2f%%)" " symbols and %d (%2.2f%%) insns\n", i, p->symbols, 100.0 * p->symbols / order.length (), p->insns, 100.0 * p->insns / original_total_size); } - fprintf (symtab->dump_file, "\n"); + fprintf (dump_file, "\n"); } } @@ -869,8 +869,8 @@ if (node->lto_file_data && lto_get_decl_name_mapping (node->lto_file_data, name) != name) { - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Not privatizing symbol name: %s. It privatized already.\n", name); return true; @@ -881,8 +881,8 @@ that are not really clones. */ if (node->unique_name) { - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Not privatizing symbol name: %s. Has unique name.\n", name); return true; @@ -972,8 +972,8 @@ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Privatizing symbol name: %s -> %s\n", name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); @@ -1018,8 +1018,8 @@ TREE_PUBLIC (node->decl) = 1; DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN; DECL_VISIBILITY_SPECIFIED (node->decl) = true; - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Promoting as hidden: %s (%s)\n", node->name (), IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); @@ -1035,8 +1035,8 @@ TREE_PUBLIC (alias->decl) = 1; DECL_VISIBILITY (alias->decl) = VISIBILITY_HIDDEN; DECL_VISIBILITY_SPECIFIED (alias->decl) = true; - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Promoting alias as hidden: %s\n", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); } @@ -1102,8 +1102,8 @@ if (!s) return; - if (symtab->dump_file) - fprintf (symtab->dump_file, + if (dump_file) + fprintf (dump_file, "Renaming statics with asm name: %s\n", node->name ()); /* Assign every symbol in the set that shares the same ASM name an unique Index: lto/lto-symtab.c =================================================================== --- lto/lto-symtab.c (revision 261327) +++ lto/lto-symtab.c (working copy) @@ -31,6 +31,7 @@ #include "ipa-utils.h" #include "builtins.h" #include "alias.h" +#include "lto.h" #include "lto-symtab.h" #include "stringpool.h" #include "attribs.h" @@ -45,9 +46,9 @@ struct cgraph_edge *e, *next; bool compatible_p; - if (symtab->dump_file) + if (dump_file) { - fprintf (symtab->dump_file, "Replacing cgraph node %s by %s" + fprintf (dump_file, "Replacing cgraph node %s by %s" " for symbol %s\n", node->dump_name (), prevailing_node->dump_name (), @@ -536,8 +537,8 @@ { if (TREE_CODE (prevailing) != TREE_CODE (decl)) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Not merging decls; " + if (dump_file) + fprintf (dump_file, "Not merging decls; " "TREE_CODE mismatch\n"); return false; } @@ -547,8 +548,8 @@ { if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl)) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Not merging decls; " + if (dump_file) + fprintf (dump_file, "Not merging decls; " "DECL_BUILT_IN mismatch\n"); return false; } @@ -556,8 +557,8 @@ && (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl) || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl))) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Not merging decls; " + if (dump_file) + fprintf (dump_file, "Not merging decls; " "DECL_BUILT_IN_CLASS or CODE mismatch\n"); return false; } @@ -572,8 +573,8 @@ if ((prev_attr == NULL) != (attr == NULL) || (prev_attr && !attribute_value_equal (prev_attr, attr))) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Not merging decls; " + if (dump_file) + fprintf (dump_file, "Not merging decls; " "error attribute mismatch\n"); return false; } @@ -583,8 +584,8 @@ if ((prev_attr == NULL) != (attr == NULL) || (prev_attr && !attribute_value_equal (prev_attr, attr))) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Not merging decls; " + if (dump_file) + fprintf (dump_file, "Not merging decls; " "warning attribute mismatch\n"); return false; } @@ -593,8 +594,8 @@ attr = lookup_attribute ("noreturn", DECL_ATTRIBUTES (decl)); if ((prev_attr == NULL) != (attr == NULL)) { - if (symtab->dump_file) - fprintf (symtab->dump_file, "Not merging decls; " + if (dump_file) + fprintf (dump_file, "Not merging decls; " "noreturn attribute mismatch\n"); return false; } @@ -753,13 +754,13 @@ symtab_node *prevailing; bool diagnosed_p = false; - if (symtab->dump_file) + if (dump_file) { - fprintf (symtab->dump_file, "Merging nodes for %s. Candidates:\n", + fprintf (dump_file, "Merging nodes for %s. Candidates:\n", first->asm_name ()); for (e = first; e; e = e->next_sharing_asm_name) if (TREE_PUBLIC (e->decl)) - e->dump (symtab->dump_file); + e->dump (dump_file); } /* Compute the symbol resolutions. This is a no-op when using the @@ -849,11 +850,11 @@ mismatches. */ lto_symtab_merge_decls_2 (prevailing, diagnosed_p); - if (symtab->dump_file) + if (dump_file) { - fprintf (symtab->dump_file, "After resolution:\n"); + fprintf (dump_file, "After resolution:\n"); for (e = prevailing; e; e = e->next_sharing_asm_name) - e->dump (symtab->dump_file); + e->dump (dump_file); } } @@ -864,6 +865,9 @@ { symtab_node *node; + gcc_assert (!dump_file); + dump_file = dump_begin (decl_merge_dump_id, NULL); + /* Populate assembler name hash. */ symtab->symtab_initialize_asm_name_hash (); @@ -871,6 +875,10 @@ if (!node->previous_sharing_asm_name && node->next_sharing_asm_name) lto_symtab_merge_decls_1 (node); + + if (dump_file) + dump_end (decl_merge_dump_id, dump_file); + dump_file = NULL; } /* Helper to process the decl chain for the symbol table entry *SLOT. */ Index: lto/lto.c =================================================================== --- lto/lto.c (revision 261327) +++ lto/lto.c (working copy) @@ -2972,30 +2972,44 @@ all_file_decl_data[i]->current_decl_state = NULL; } - /* Finally merge the cgraph according to the decl merging decisions. */ - timevar_push (TV_IPA_LTO_CGRAPH_MERGE); - if (symtab->dump_file) - { - fprintf (symtab->dump_file, "Before merging:\n"); - symtab->dump (symtab->dump_file); - } if (!flag_ltrans) { + /* Finally merge the cgraph according to the decl merging decisions. */ + timevar_push (TV_IPA_LTO_CGRAPH_MERGE); + + gcc_assert (!dump_file); + dump_file = dump_begin (lto_link_dump_id, NULL); + + if (dump_file) + { + fprintf (dump_file, "Before merging:\n"); + symtab->dump (dump_file); + } lto_symtab_merge_symbols (); /* Removal of unreachable symbols is needed to make verify_symtab to pass; we are still having duplicated comdat groups containing local statics. We could also just remove them while merging. */ symtab->remove_unreachable_nodes (dump_file); + ggc_collect (); + + if (dump_file) + dump_end (lto_link_dump_id, dump_file); + dump_file = NULL; + timevar_pop (TV_IPA_LTO_CGRAPH_MERGE); } - ggc_collect (); symtab->state = IPA_SSA; - /* FIXME: Technically all node removals happening here are useless, because - WPA should not stream them. */ + /* All node removals happening here are useless, because + WPA should not stream them. Still always perform remove_unreachable_nodes + because we may reshape clone tree, get rid of dead masters of inline + clones and remove symbol entries for read-only variables we keep around + only to be able to constant fold them. */ if (flag_ltrans) - symtab->remove_unreachable_nodes (dump_file); + { + if (symtab->dump_file) + symtab->dump (symtab->dump_file); + symtab->remove_unreachable_nodes (symtab->dump_file); + } - timevar_pop (TV_IPA_LTO_CGRAPH_MERGE); - /* Indicate that the cgraph is built and ready. */ symtab->function_flags_ready = true; @@ -3152,19 +3166,19 @@ if (seen_error ()) return; - if (symtab->dump_file) - { - fprintf (symtab->dump_file, "Optimized "); - symtab->dump (symtab->dump_file); - } - - symtab_node::checking_verify_symtab_nodes (); - bitmap_obstack_release (NULL); - /* We are about to launch the final LTRANS phase, stop the WPA timer. */ timevar_pop (TV_WHOPR_WPA); timevar_push (TV_WHOPR_PARTITIONING); + + gcc_assert (!dump_file); + dump_file = dump_begin (partition_dump_id, NULL); + + if (dump_file) + symtab->dump (dump_file); + + symtab_node::checking_verify_symtab_nodes (); + bitmap_obstack_release (NULL); if (flag_lto_partition == LTO_PARTITION_1TO1) lto_1_to_1_map (); else if (flag_lto_partition == LTO_PARTITION_MAX) @@ -3192,6 +3206,9 @@ to globals with hidden visibility because they are accessed from multiple partitions. */ lto_promote_cross_file_statics (); + if (dump_file) + dump_end (partition_dump_id, dump_file); + dump_file = NULL; timevar_pop (TV_WHOPR_PARTITIONING); timevar_stop (TV_PHASE_OPT_GEN); Index: lto/lto.h =================================================================== --- lto/lto.h (revision 261327) +++ lto/lto.h (working copy) @@ -51,6 +51,8 @@ extern lto_file *lto_set_current_out_file (lto_file *file); extern lto_file *lto_get_current_out_file (void); +extern int lto_link_dump_id, decl_merge_dump_id, partition_dump_id; + /* Hash table entry to hold the start offset and length of an LTO section in a .o file. */ struct lto_section_slot