From patchwork Fri Aug 30 15:54:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 271346 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "www.sourceware.org", Issuer "StartCom Class 1 Primary Intermediate Server CA" (not verified)) by ozlabs.org (Postfix) with ESMTPS id A2A1D2C0090 for ; Sat, 31 Aug 2013 01:54:22 +1000 (EST) 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=f7jROL6nBsa4H+fQ7035xpi1wHpQm01iO6rqqvaL55SlljlL4Wobp BRQzyBN+Jlh4OitNhmP9ErqYBeWYbXAABYcWtG2dnI4n5oEiva7+RGvxmPVelZln AKzd5oPRDR5MABFCztFhig2omEa3R5IG/WyIKohF+jxOpFZFXo7D9s= 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=ZPJs8I7Z/bFyJxOggqshnV5Vek0=; b=XaTCo4IZXgPcAcua121y liF54+ekODktnmBpiSdvixTsK+18pe95EnWvyaaoIN6UJAktuhnAwzP8mDfm/SCZ m81vnqe3/51ONZE9S8jJHWf2QdktTrqHIn+Eqv03OyGIV7wkeZntBthYlRDdgJ1d q80pTR0RZLrgLhRmLXaTRBY= Received: (qmail 4875 invoked by alias); 30 Aug 2013 15:54:10 -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 4820 invoked by uid 89); 30 Aug 2013 15:54:10 -0000 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 (AES256-SHA encrypted) ESMTPS; Fri, 30 Aug 2013 15:54:10 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, NO_RELAYS autolearn=no version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 80783543B9A; Fri, 30 Aug 2013 17:54:05 +0200 (CEST) Date: Fri, 30 Aug 2013 17:54:05 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: More weakref fixes Message-ID: <20130830155405.GB4601@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Hi, this patch fixes gcc.dg/tree-ssa/attr-alias.c on x86-64 target. The problem here is that we attempt to create local alias since we consider weakref of test() to be overwritable and at the same time available. The change in cgraph_function_body_availability makes weakref to properly inherit availability of their target (that is weak in the testcase). Fixing it uncovered more issues - with -flto-partition=none and -O0 we run into problem that cgraph edge redirections are not applied. This is becuase inliner is not run in this scenario when it ought to be (precisely because edge redirection is happened). So the patch removes ipa_inline's gate logic, makes it to not do something useless at -O0 and also removes fixup_cfg pass that is really part of inliner's transform. While updating varpool part of availability I noticed that it is wrong for vtables and constant pool. Fixed thus. Finally I noticed that symbol renaming is broken on non-weakref targets. Bootstrapped/regtested x86_64-linux, comitted. Honza * cgraph.c (cgraph_function_body_availability): Handle weakref correctly. * gcc.dg/tree-ssa/attr-alias.c: Rename test3 to test1 to match template and comment. * passes.def: Remove pass_fixup_cfg. * ipa-inline.c (ipa_inline): When not optimizing, do not inline; track when we need to remove functions. (gate_ipa_inline): Execute inlining always; add comment why. (pass_data_ipa_inline): Remove TODO_remove_functions. * ipa-inline-analysis.c (inline_generate_summary): When not optimizing do not produce summaries. * symtab.c (change_decl_assembler_name): Handle renaming of weakrefs. (symtab_nonoverwritable_alias): Assert we are not called on weakref. * varpool.c (cgraph_variable_initializer_availability): Fix weakrefs, constant pool and vtable. Index: cgraph.c =================================================================== --- cgraph.c (revision 202093) +++ cgraph.c (working copy) @@ -2046,6 +2046,8 @@ cgraph_function_body_availability (struc avail = AVAIL_NOT_AVAILABLE; else if (node->local.local) avail = AVAIL_LOCAL; + else if (node->symbol.alias && node->symbol.weakref) + cgraph_function_or_thunk_node (node, &avail); else if (!node->symbol.externally_visible) avail = AVAIL_AVAILABLE; /* Inline functions are safe to be analyzed even if their symbol can Index: testsuite/gcc.dg/tree-ssa/attr-alias.c =================================================================== --- testsuite/gcc.dg/tree-ssa/attr-alias.c (revision 202092) +++ testsuite/gcc.dg/tree-ssa/attr-alias.c (working copy) @@ -8,7 +8,7 @@ int test() return 0; } static int test2() __attribute__ ((alias("test"))); -static int test3() __attribute__ ((weakref)) __attribute__ ((alias("test2"))); +static int test1() __attribute__ ((weakref)) __attribute__ ((alias("test2"))); static int test4() __attribute__ ((weakref)) __attribute__ ((alias("test"))); main() { Index: passes.def =================================================================== --- passes.def (revision 202092) +++ passes.def (working copy) @@ -126,7 +126,6 @@ along with GCC; see the file COPYING3. /* These passes are run after IPA passes on every function that is being output to the assembler file. */ INSERT_PASSES_AFTER (all_passes) - NEXT_PASS (pass_fixup_cfg); NEXT_PASS (pass_lower_eh_dispatch); NEXT_PASS (pass_all_optimizations); PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations) Index: ipa-inline.c =================================================================== --- ipa-inline.c (revision 202092) +++ ipa-inline.c (working copy) @@ -1904,6 +1904,10 @@ ipa_inline (void) XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); int i; int cold; + bool remove_functions = false; + + if (!optimize) + return 0; if (in_lto_p && optimize) ipa_update_after_lto_read (); @@ -1984,6 +1988,7 @@ ipa_inline (void) { cgraph_resolve_speculation (edge, NULL); update = true; + remove_functions = true; } } if (update) @@ -2018,6 +2023,7 @@ ipa_inline (void) } inline_call (node->callers, true, NULL, NULL, true); + remove_functions = true; if (dump_file) fprintf (dump_file, " Inlined into %s which now has %i size\n", @@ -2048,7 +2054,7 @@ ipa_inline (void) /* In WPA we use inline summaries for partitioning process. */ if (!flag_wpa) inline_free_summary (); - return 0; + return remove_functions ? TODO_remove_functions : 0; } /* Inline always-inline function calls in NODE. */ @@ -2292,13 +2298,13 @@ make_pass_early_inline (gcc::context *ct /* When to run IPA inlining. Inlining of always-inline functions happens during early inlining. - Enable inlining unconditoinally at -flto. We need size estimates to - drive partitioning. */ + Enable inlining unconditoinally, because callgraph redirection + happens here. */ static bool gate_ipa_inline (void) { - return optimize || flag_lto || flag_wpa; + return true; } namespace { @@ -2315,7 +2321,7 @@ const pass_data pass_data_ipa_inline = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_remove_functions, /* todo_flags_start */ - ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */ + ( TODO_dump_symtab ), /* todo_flags_finish */ }; class pass_ipa_inline : public ipa_opt_pass_d Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 202092) +++ ipa-inline-analysis.c (working copy) @@ -3698,6 +3698,11 @@ inline_generate_summary (void) { struct cgraph_node *node; + /* When not optimizing, do not bother to analyze. Inlining is still done + because edge redirection needs to happen there. */ + if (!optimize && !flag_lto && !flag_wpa) + return; + function_insertion_hook_holder = cgraph_add_function_insertion_hook (&add_new_function, NULL); Index: symtab.c =================================================================== --- symtab.c (revision 202092) +++ symtab.c (working copy) @@ -390,6 +390,9 @@ change_decl_assembler_name (tree decl, t if (name == DECL_ASSEMBLER_NAME (decl)) return; + tree alias = (IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl)) + ? TREE_CHAIN (DECL_ASSEMBLER_NAME (decl)) + : NULL); if (node) unlink_from_assembler_name_hash (node, true); if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) @@ -397,6 +400,11 @@ change_decl_assembler_name (tree decl, t warning (0, "%D renamed after being referenced in assembly", decl); SET_DECL_ASSEMBLER_NAME (decl, name); + if (alias) + { + IDENTIFIER_TRANSPARENT_ALIAS (name) = 1; + TREE_CHAIN (DECL_ASSEMBLER_NAME (name)) = alias; + } if (node) insert_to_assembler_name_hash (node, true); } @@ -1065,11 +1073,17 @@ symtab_nonoverwritable_alias (symtab_nod { tree new_decl; symtab_node new_node = NULL; + + /* First try to look up existing alias or base object + (if that is already non-overwritable). */ + node = symtab_alias_ultimate_target (node, NULL); + gcc_assert (!node->symbol.alias && !node->symbol.weakref); symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1, (void *)&new_node, true); if (new_node) return new_node; + /* Otherwise create a new one. */ new_decl = copy_node (node->symbol.decl); DECL_NAME (new_decl) = clone_function_name (node->symbol.decl, "localalias"); if (TREE_CODE (new_decl) == FUNCTION_DECL) Index: varpool.c =================================================================== --- varpool.c (revision 202092) +++ varpool.c (working copy) @@ -260,10 +260,22 @@ cgraph_variable_initializer_availability return AVAIL_NOT_AVAILABLE; if (!TREE_PUBLIC (node->symbol.decl)) return AVAIL_AVAILABLE; + if (DECL_IN_CONSTANT_POOL (node->symbol.decl) + || DECL_VIRTUAL_P (node->symbol.decl)) + return AVAIL_AVAILABLE; + if (node->symbol.alias && node->symbol.weakref) + { + enum availability avail; + + cgraph_variable_initializer_availability + (varpool_variable_node (node, &avail)); + return avail; + } /* If the variable can be overwritten, return OVERWRITABLE. Takes care of at least one notable extension - the COMDAT variables used to share template instantiations in C++. */ - if (!decl_replaceable_p (node->symbol.decl)) + if (decl_replaceable_p (node->symbol.decl) + || DECL_EXTERNAL (node->symbol.decl)) return AVAIL_OVERWRITABLE; return AVAIL_AVAILABLE; }