From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14100 invoked by alias); 3 Jun 2011 14:49:28 -0000 Received: (qmail 14086 invoked by uid 22791); 3 Jun 2011 14:49:25 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (74.125.121.67) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 03 Jun 2011 14:49:02 +0000 Received: from wpaz33.hot.corp.google.com (wpaz33.hot.corp.google.com [172.24.198.97]) by smtp-out.google.com with ESMTP id p53Emxbu007614; Fri, 3 Jun 2011 07:49:00 -0700 Received: from topo.tor.corp.google.com (topo.tor.corp.google.com [172.29.41.2]) by wpaz33.hot.corp.google.com with ESMTP id p53Emw4x025925; Fri, 3 Jun 2011 07:48:58 -0700 Received: by topo.tor.corp.google.com (Postfix, from userid 54752) id 544B11DA1CC; Fri, 3 Jun 2011 10:48:58 -0400 (EDT) To: reply@codereview.appspotmail.com, rguenther@suse.de, jh@suse.de, gcc-patches@gcc.gnu.org Subject: [lto] Unify decl and type registration (issue4515186) Message-Id: <20110603144858.544B11DA1CC@topo.tor.corp.google.com> Date: Fri, 03 Jun 2011 14:49:00 -0000 From: dnovillo@google.com (Diego Novillo) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-06/txt/msg00239.txt.bz2 As discussed in http://gcc.gnu.org/ml/gcc-patches/2011-06/msg00063.html, this patch moves decl registration in symbol tables to the LTO front end. It makes type and symbol registration happen at the same time in uniquify_nodes. Tested with LTO profiledbootstrap on x86_64. Committed to trunk. Diego. 2011-06-03 Diego Novillo * lto-streamer-in.c (get_resolution): Move to lto/lto.c. (lto_register_var_decl_in_symtab): Likewise. (lto_register_function_decl_in_symtab): Likewise. (lto_read_tree): Move VAR_DECL and FUNCTION_DECL registration logic to lto_read_decls. lto/ChangeLog * lto.c (get_resolution): Move from lto-streamer-in.c. (lto_register_var_decl_in_symtab): Likewise. (lto_register_function_decl_in_symtab): Likewise. (uniquify_nodes): Call lto_register_var_decl and lto_register_function_decl_in_symtab after reading a new VAR_DECL or FUNCTION_DECL. diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 88966f2..a0c5509 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -1533,31 +1533,6 @@ lto_input_constructors_and_inits (struct lto_file_decl_data *file_data, } -/* Return the resolution for the decl with index INDEX from DATA_IN. */ - -static enum ld_plugin_symbol_resolution -get_resolution (struct data_in *data_in, unsigned index) -{ - if (data_in->globals_resolution) - { - ld_plugin_symbol_resolution_t ret; - /* We can have references to not emitted functions in - DECL_FUNCTION_PERSONALITY at least. So we can and have - to indeed return LDPR_UNKNOWN in some cases. */ - if (VEC_length (ld_plugin_symbol_resolution_t, - data_in->globals_resolution) <= index) - return LDPR_UNKNOWN; - ret = VEC_index (ld_plugin_symbol_resolution_t, - data_in->globals_resolution, - index); - return ret; - } - else - /* Delay resolution finding until decl merging. */ - return LDPR_UNKNOWN; -} - - /* Unpack all the non-pointer fields of the TS_BASE structure of expression EXPR from bitpack BP. */ @@ -2473,117 +2448,6 @@ lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, } -/* Register DECL with the global symbol table and change its - name if necessary to avoid name clashes for static globals across - different files. */ - -static void -lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl) -{ - tree context; - - /* Variable has file scope, not local. Need to ensure static variables - between different files don't clash unexpectedly. */ - if (!TREE_PUBLIC (decl) - && !((context = decl_function_context (decl)) - && auto_var_in_fn_p (decl, context))) - { - /* ??? We normally pre-mangle names before we serialize them - out. Here, in lto1, we do not know the language, and - thus cannot do the mangling again. Instead, we just - append a suffix to the mangled name. The resulting name, - however, is not a properly-formed mangled name, and will - confuse any attempt to unmangle it. */ - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - char *label; - - ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); - SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); - rest_of_decl_compilation (decl, 1, 0); - - VEC_safe_push (tree, gc, lto_global_var_decls, decl); - } - - /* If this variable has already been declared, queue the - declaration for merging. */ - if (TREE_PUBLIC (decl)) - { - unsigned ix; - if (!lto_streamer_cache_lookup (data_in->reader_cache, decl, &ix)) - gcc_unreachable (); - lto_symtab_register_decl (decl, get_resolution (data_in, ix), - data_in->file_data); - } -} - - - -/* Register DECL with the global symbol table and change its - name if necessary to avoid name clashes for static globals across - different files. DATA_IN contains descriptors and tables for the - file being read. */ - -static void -lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl) -{ - /* Need to ensure static entities between different files - don't clash unexpectedly. */ - if (!TREE_PUBLIC (decl)) - { - /* We must not use the DECL_ASSEMBLER_NAME macro here, as it - may set the assembler name where it was previously empty. */ - tree old_assembler_name = decl->decl_with_vis.assembler_name; - - /* FIXME lto: We normally pre-mangle names before we serialize - them out. Here, in lto1, we do not know the language, and - thus cannot do the mangling again. Instead, we just append a - suffix to the mangled name. The resulting name, however, is - not a properly-formed mangled name, and will confuse any - attempt to unmangle it. */ - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - char *label; - - ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); - SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); - - /* We may arrive here with the old assembler name not set - if the function body is not needed, e.g., it has been - inlined away and does not appear in the cgraph. */ - if (old_assembler_name) - { - tree new_assembler_name = DECL_ASSEMBLER_NAME (decl); - - /* Make the original assembler name available for later use. - We may have used it to indicate the section within its - object file where the function body may be found. - FIXME lto: Find a better way to maintain the function decl - to body section mapping so we don't need this hack. */ - lto_record_renamed_decl (data_in->file_data, - IDENTIFIER_POINTER (old_assembler_name), - IDENTIFIER_POINTER (new_assembler_name)); - - /* Also register the reverse mapping so that we can find the - new name given to an existing assembler name (used when - restoring alias pairs in input_constructors_or_inits. */ - lto_record_renamed_decl (data_in->file_data, - IDENTIFIER_POINTER (new_assembler_name), - IDENTIFIER_POINTER (old_assembler_name)); - } - } - - /* If this variable has already been declared, queue the - declaration for merging. */ - if (TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl)) - { - unsigned ix; - if (!lto_streamer_cache_lookup (data_in->reader_cache, decl, &ix)) - gcc_unreachable (); - lto_symtab_register_decl (decl, get_resolution (data_in, ix), - data_in->file_data); - } -} - - /* Read an index IX from input block IB and return the tree node at DATA_IN->FILE_DATA->GLOBALS_INDEX[IX]. */ @@ -2665,11 +2529,6 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in, if (TREE_CODE (result) == FUNCTION_DECL) gcc_assert (!lto_stream_as_builtin_p (result)); - if (TREE_CODE (result) == VAR_DECL) - lto_register_var_decl_in_symtab (data_in, result); - else if (TREE_CODE (result) == FUNCTION_DECL && !DECL_BUILT_IN (result)) - lto_register_function_decl_in_symtab (data_in, result); - /* end_marker = */ lto_input_1_unsigned (ib); #ifdef LTO_STREAMER_DEBUG diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 9d4e2ed..70d5bde 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -501,6 +501,141 @@ lto_fixup_types (tree t) } } + +/* Return the resolution for the decl with index INDEX from DATA_IN. */ + +static enum ld_plugin_symbol_resolution +get_resolution (struct data_in *data_in, unsigned index) +{ + if (data_in->globals_resolution) + { + ld_plugin_symbol_resolution_t ret; + /* We can have references to not emitted functions in + DECL_FUNCTION_PERSONALITY at least. So we can and have + to indeed return LDPR_UNKNOWN in some cases. */ + if (VEC_length (ld_plugin_symbol_resolution_t, + data_in->globals_resolution) <= index) + return LDPR_UNKNOWN; + ret = VEC_index (ld_plugin_symbol_resolution_t, + data_in->globals_resolution, + index); + return ret; + } + else + /* Delay resolution finding until decl merging. */ + return LDPR_UNKNOWN; +} + + +/* Register DECL with the global symbol table and change its + name if necessary to avoid name clashes for static globals across + different files. */ + +static void +lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl) +{ + tree context; + + /* Variable has file scope, not local. Need to ensure static variables + between different files don't clash unexpectedly. */ + if (!TREE_PUBLIC (decl) + && !((context = decl_function_context (decl)) + && auto_var_in_fn_p (decl, context))) + { + /* ??? We normally pre-mangle names before we serialize them + out. Here, in lto1, we do not know the language, and + thus cannot do the mangling again. Instead, we just + append a suffix to the mangled name. The resulting name, + however, is not a properly-formed mangled name, and will + confuse any attempt to unmangle it. */ + const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + char *label; + + ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); + SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); + rest_of_decl_compilation (decl, 1, 0); + VEC_safe_push (tree, gc, lto_global_var_decls, decl); + } + + /* If this variable has already been declared, queue the + declaration for merging. */ + if (TREE_PUBLIC (decl)) + { + unsigned ix; + if (!lto_streamer_cache_lookup (data_in->reader_cache, decl, &ix)) + gcc_unreachable (); + lto_symtab_register_decl (decl, get_resolution (data_in, ix), + data_in->file_data); + } +} + + +/* Register DECL with the global symbol table and change its + name if necessary to avoid name clashes for static globals across + different files. DATA_IN contains descriptors and tables for the + file being read. */ + +static void +lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl) +{ + /* Need to ensure static entities between different files + don't clash unexpectedly. */ + if (!TREE_PUBLIC (decl)) + { + /* We must not use the DECL_ASSEMBLER_NAME macro here, as it + may set the assembler name where it was previously empty. */ + tree old_assembler_name = decl->decl_with_vis.assembler_name; + + /* FIXME lto: We normally pre-mangle names before we serialize + them out. Here, in lto1, we do not know the language, and + thus cannot do the mangling again. Instead, we just append a + suffix to the mangled name. The resulting name, however, is + not a properly-formed mangled name, and will confuse any + attempt to unmangle it. */ + const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + char *label; + + ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); + SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); + + /* We may arrive here with the old assembler name not set + if the function body is not needed, e.g., it has been + inlined away and does not appear in the cgraph. */ + if (old_assembler_name) + { + tree new_assembler_name = DECL_ASSEMBLER_NAME (decl); + + /* Make the original assembler name available for later use. + We may have used it to indicate the section within its + object file where the function body may be found. + FIXME lto: Find a better way to maintain the function decl + to body section mapping so we don't need this hack. */ + lto_record_renamed_decl (data_in->file_data, + IDENTIFIER_POINTER (old_assembler_name), + IDENTIFIER_POINTER (new_assembler_name)); + + /* Also register the reverse mapping so that we can find the + new name given to an existing assembler name (used when + restoring alias pairs in input_constructors_or_inits. */ + lto_record_renamed_decl (data_in->file_data, + IDENTIFIER_POINTER (new_assembler_name), + IDENTIFIER_POINTER (old_assembler_name)); + } + } + + /* If this variable has already been declared, queue the + declaration for merging. */ + if (TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl)) + { + unsigned ix; + if (!lto_streamer_cache_lookup (data_in->reader_cache, decl, &ix)) + gcc_unreachable (); + lto_symtab_register_decl (decl, get_resolution (data_in, ix), + data_in->file_data); + } +} + + /* Given a streamer cache structure DATA_IN (holding a sequence of trees for one compilation unit) go over all trees starting at index FROM until the end of the sequence and replace fields of those trees, and the trees @@ -513,20 +648,25 @@ uniquify_nodes (struct data_in *data_in, unsigned from) unsigned len = VEC_length (tree, cache->nodes); unsigned i; - /* Go backwards because childs streamed for the first time come + /* Go backwards because children streamed for the first time come as part of their parents, and hence are created after them. */ - /* First register all types in the cache. + /* First register all declarations and types in the cache. This makes sure to have the original structure in the type cycles when registering them and computing hashes. */ for (i = len; i-- > from;) { tree t = VEC_index (tree, cache->nodes, i); - if (!t - || !TYPE_P (t)) + + if (t == NULL_TREE) continue; - gimple_register_type (t); + if (TREE_CODE (t) == VAR_DECL) + lto_register_var_decl_in_symtab (data_in, t); + else if (TREE_CODE (t) == FUNCTION_DECL && !DECL_BUILT_IN (t)) + lto_register_function_decl_in_symtab (data_in, t); + else if (TYPE_P (t)) + gimple_register_type (t); } /* Second fixup all trees in the new cache entries. */ @@ -665,6 +805,7 @@ uniquify_nodes (struct data_in *data_in, unsigned from) } } + /* Read all the symbols from buffer DATA, using descriptors in DECL_DATA. RESOLUTIONS is the set of symbols picked by the linker (read from the resolution file when the linker plugin is being used). */ -- This patch is available for review at http://codereview.appspot.com/4515186