From patchwork Mon Oct 18 23:28:54 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 68251 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]) by ozlabs.org (Postfix) with SMTP id 2F2CB1007D4 for ; Tue, 19 Oct 2010 10:29:16 +1100 (EST) Received: (qmail 29955 invoked by alias); 18 Oct 2010 23:29:14 -0000 Received: (qmail 29947 invoked by uid 22791); 18 Oct 2010 23:29:13 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam-dmz.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 18 Oct 2010 23:28:56 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 8983B9AC86F; Tue, 19 Oct 2010 01:28:54 +0200 (CEST) Date: Tue, 19 Oct 2010 01:28:54 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Visibility cleanups Message-ID: <20101018232854.GA9107@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) 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 Hi, this patch cleans up function_and_variable_visibility so the logic on when variable is externally visible is broken out into separate function. Also cgraph_externally_visible_p might bring comdat local even when it is declared with used attribute. Fixed thus. Bootstrapped/regtested x86_64-linux. Will commit it shortly. Honza * ipa.c (cgraph_externally_visible_p): Handle externally visible and preserve flags before trying to guess on visibility. (varpool_externally_visible_p): New function. (function_and_variable_visibility): Use it. Index: ipa.c =================================================================== --- ipa.c (revision 165655) +++ ipa.c (working copy) @@ -607,6 +607,11 @@ cgraph_externally_visible_p (struct cgra /* If linker counts on us, we must preserve the function. */ if (cgraph_used_from_object_file_p (node)) return true; + if (DECL_PRESERVE_P (node->decl)) + return true; + if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl))) + return true; + /* When doing link time optimizations, hidden symbols become local. */ if (in_lto_p && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN @@ -638,11 +643,64 @@ cgraph_externally_visible_p (struct cgra return true; } } - if (DECL_PRESERVE_P (node->decl)) - return true; + if (MAIN_NAME_P (DECL_NAME (node->decl))) return true; - if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl))) + + return false; +} + +/* Return true when variable VNODE should be considered externally visible. */ + +static bool +varpool_externally_visible_p (struct varpool_node *vnode, bool aliased) +{ + if (!DECL_COMDAT (vnode->decl) && !TREE_PUBLIC (vnode->decl)) + return false; + + /* Do not even try to be smart about aliased nodes. Until we properly + represent everything by same body alias, these are just evil. */ + if (aliased) + return true; + + /* If linker counts on us, we must preserve the function. */ + if (varpool_used_from_object_file_p (vnode)) + return true; + + if (DECL_PRESERVE_P (vnode->decl)) + return true; + if (lookup_attribute ("externally_visible", + DECL_ATTRIBUTES (vnode->decl))) + return true; + + /* See if we have linker information about symbol not being used or + if we need to make guess based on the declaration. + + Even if the linker clams the symbol is unused, never bring internal + symbols that are declared by user as used or externally visible. + This is needed for i.e. references from asm statements. */ + if (varpool_used_from_object_file_p (vnode)) + return true; + + /* When doing link time optimizations, hidden symbols become local. */ + if (in_lto_p + && (DECL_VISIBILITY (vnode->decl) == VISIBILITY_HIDDEN + || DECL_VISIBILITY (vnode->decl) == VISIBILITY_INTERNAL) + /* Be sure that node is defined in IR file, not in other object + file. In that case we don't set used_from_other_object_file. */ + && vnode->finalized) + ; + else if (!flag_whole_program) + return true; + + /* Do not attempt to privatize COMDATS by default. + This would break linking with C++ libraries sharing + inline definitions. + + FIXME: We can do so for readonly vars with no address taken and + possibly also for vtables since no direct pointer comparsion is done. + It might be interesting to do so to reduce linking overhead. */ + if (DECL_COMDAT (vnode->decl) || DECL_WEAK (vnode->decl)) return true; return false; } @@ -798,27 +856,9 @@ function_and_variable_visibility (bool w if (!vnode->finalized) continue; if (vnode->needed - && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl)) - && (((!whole_program - /* We can privatize comdat readonly variables whose address is - not taken, but doing so is not going to bring us - optimization oppurtunities until we start reordering - datastructures. */ - || DECL_COMDAT (vnode->decl) - || DECL_WEAK (vnode->decl)) - /* When doing linktime optimizations, all hidden symbols will - become local. */ - && (!in_lto_p - || (DECL_VISIBILITY (vnode->decl) != VISIBILITY_HIDDEN - && DECL_VISIBILITY (vnode->decl) != VISIBILITY_INTERNAL) - /* We can get prevailing decision in other object file. - In this case we do not sed used_from_object_file. */ - || !vnode->finalized)) - || DECL_PRESERVE_P (vnode->decl) - || varpool_used_from_object_file_p (vnode) - || pointer_set_contains (aliased_vnodes, vnode) - || lookup_attribute ("externally_visible", - DECL_ATTRIBUTES (vnode->decl)))) + && varpool_externally_visible_p + (vnode, + pointer_set_contains (aliased_vnodes, vnode))) vnode->externally_visible = true; else vnode->externally_visible = false;