From patchwork Tue May 22 18:32:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 918517 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-478200-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="DTqNljjg"; 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 40r44g5wtBz9s15 for ; Wed, 23 May 2018 04:32:18 +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 :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=MK/kOLRHuFHwDF/eRjSx2+8Js1sF/yUNCeFQMxRyWVL PX8o9JOXuhzUUx8t3Nc/nvt6LK/zoxRcNreDBw0GGd5DHMZjiLMd6dkSLx6z1LON SZ7Njo9+JjCNLBwzN6cBYrgsk6TDR9sTUxKC+C1zN3YaK0TQLa2MoWf7srZyEwCQ = 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 :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=ZT/O5lMR5g7IRtRH6/uoLDRnAXs=; b=DTqNljjgREhbrUAuG UDf8+X5RC52cgnAEi2QRjD8LsemS2At1UcuRYfUDYUzbStVrL05b1bbfSmhFBVbK vmtkrOobSxMTRPx4KvDXhDFXaFYo570Sh3IZijLdJZ0w5lOpj3RyDzKV2A+sSVQF fyCmtv/nS2InVILfmEAbURTVxM= Received: (qmail 54744 invoked by alias); 22 May 2018 18:32:11 -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 54731 invoked by uid 89); 22 May 2018 18:32:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=avail, error_at X-HELO: mail-ot0-f193.google.com Received: from mail-ot0-f193.google.com (HELO mail-ot0-f193.google.com) (74.125.82.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 22 May 2018 18:32:07 +0000 Received: by mail-ot0-f193.google.com with SMTP id 77-v6so22161758otd.4 for ; Tue, 22 May 2018 11:32:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=FymYwgQfPP2KxoJMSLJkPFgitTyi675qvZ/3U3G9XQ8=; b=RdMy+jhU0rlvJU42jB5nLSGp7fR+HWeSrGNAYfdTqV4d7ezN8S2NiK0IUO4JSXBVkm 5VGv9LA3Ov8GP9x5znOVwgAKjsscPrumXAt4YkVxHQz56vSvLospdOIRT49y6DFzcNDs weaVVxIO5Ro9YG9IVGR6FxivB31bzgVI6Qx6BlyL8Dej/8Dptexb/ItjjPukLkbedFxl zscwdQjOaIO7qt4gN1eOjil1eMDTlMw5wEy1eG5CkFs2DCnqnBm0yko/OVxGzDupOVOu sHTYLVgoU64eLfJebjXiqGX2MBNJdYVXReeSnn873mpkwyxg/xsxSdaMNzN8tIHX7sip Mg/Q== X-Gm-Message-State: ALKqPwfEqzbxZLWgcrdqQrYplp9YZnPqilwhmhiepp89QWpxTQ7bT4jr Ye75kEFGzCsG12/mzOA/4Acw97/xi1K22cV3oIE= X-Google-Smtp-Source: AB8JxZq247J/KtOfU3hvn9uY2qzAWgEHT14tgzv6RfONgwfaQAgG5qjlxK1gHNa15xBRXtymtvCReDvcdmGjv+4YJrM= X-Received: by 2002:a9d:73c5:: with SMTP id m5-v6mr17885159otk.332.1527013925646; Tue, 22 May 2018 11:32:05 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a4a:2e12:0:0:0:0:0 with HTTP; Tue, 22 May 2018 11:32:04 -0700 (PDT) From: "H.J. Lu" Date: Tue, 22 May 2018 11:32:04 -0700 Message-ID: Subject: [PATCH v2] Don't mark IFUNC resolver as only called directly To: Jan Hubicka Cc: Richard Biener , GCC Patches X-IsSubscribed: yes On Tue, May 22, 2018 at 10:11 AM, H.J. Lu wrote: > On Tue, May 22, 2018 at 9:21 AM, Jan Hubicka wrote: >>> >>>>> > class ipa_opt_pass_d; >>> >>>>> > typedef ipa_opt_pass_d *ipa_opt_pass; >>> >>>>> > @@ -2894,7 +2896,8 @@ cgraph_node::only_called_directly_or_aliased_p (void) >>> >>>>> > && !DECL_STATIC_CONSTRUCTOR (decl) >>> >>>>> > && !DECL_STATIC_DESTRUCTOR (decl) >>> >>>>> > && !used_from_object_file_p () >>> >>>>> > - && !externally_visible); >>> >>>>> > + && !externally_visible >>> >>>>> > + && !lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))); >>> >>>>> >>> >>>>> How's it handled for our own generated resolver functions? That is, >>> >>>>> isn't there sth cheaper than doing a lookup_attribute here? I see >>> >>>>> that make_dispatcher_decl nor ix86_get_function_versions_dispatcher >>> >>>>> adds the 'ifunc' attribute (though they are TREE_PUBLIC there). >>> >>>> >>> >>>> Is there any drawback of setting force_output flag? >>> >>>> Honza >>> >>> >>> >>> Setting force_output may prevent some optimizations. Can we add a bit >>> >>> for IFUNC resolver? >>> >>> >>> >> >>> >> Here is the patch to add ifunc_resolver to cgraph_node. Tested on x86-64 >>> >> and i686. Any comments? >>> >> >>> > >>> > PING: >>> > >>> > https://gcc.gnu.org/ml/gcc-patches/2018-04/msg00647.html >>> > >>> >>> PING. >> OK, but please extend the verifier that ifunc_resolver flag is equivalent to >> lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)) >> so we are sure things stays in sync. >> > > Like this > > diff --git a/gcc/symtab.c b/gcc/symtab.c > index 80f6f910c3b..954920b6dff 100644 > --- a/gcc/symtab.c > +++ b/gcc/symtab.c > @@ -998,6 +998,13 @@ symtab_node::verify_base (void) > error ("function symbol is not function"); > error_found = true; > } > + else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)) > + != NULL) > + != dyn_cast (this)->ifunc_resolver) > + { > + error ("inconsistent `ifunc' attribute"); > + error_found = true; > + } > } > else if (is_a (this)) > { > > > Thanks. > This is the patch I am checking in. Tested on x86-64. Thanks. From 91d0b4bc0222ce85bd529a7b3ae9e11904802c26 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 11 Apr 2018 12:31:21 -0700 Subject: [PATCH] Don't mark IFUNC resolver as only called directly Since IFUNC resolver is called indirectly, don't mark IFUNC resolver as only called directly. This patch adds ifunc_resolver to cgraph_node, sets ifunc_resolver for ifunc attribute and checks ifunc_resolver instead of looking up ifunc attribute. gcc/ PR target/85345 * cgraph.h (cgraph_node::create): Set ifunc_resolver for ifunc attribute. (cgraph_node::create_alias): Likewise. (cgraph_node::get_availability): Check ifunc_resolver instead of looking up ifunc attribute. * cgraphunit.c (maybe_diag_incompatible_alias): Likewise. * varasm.c (do_assemble_alias): Likewise. (assemble_alias): Likewise. (default_binds_local_p_3): Likewise. * cgraph.h (cgraph_node): Add ifunc_resolver. (cgraph_node::only_called_directly_or_aliased_p): Return false for IFUNC resolver. * lto-cgraph.c (input_node): Set ifunc_resolver for ifunc attribute. * symtab.c (symtab_node::verify_base): Verify that ifunc_resolver is equivalent to lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)). (symtab_node::binds_to_current_def_p): Check ifunc_resolver instead of looking up ifunc attribute. gcc/testsuite/ PR target/85345 * gcc.target/i386/pr85345.c: New test. --- gcc/cgraph.c | 7 +++- gcc/cgraph.h | 4 +++ gcc/cgraphunit.c | 2 +- gcc/lto-cgraph.c | 2 ++ gcc/symtab.c | 11 +++++-- gcc/testsuite/gcc.target/i386/pr85345.c | 44 +++++++++++++++++++++++++ gcc/varasm.c | 8 +++-- 7 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr85345.c diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 9a7d54d7cee..9f3a2929f6b 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -517,6 +517,9 @@ cgraph_node::create (tree decl) g->have_offload = true; } + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + node->ifunc_resolver = true; + node->register_symbol (); if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL) @@ -575,6 +578,8 @@ cgraph_node::create_alias (tree alias, tree target) alias_node->alias = true; if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL) alias_node->transparent_alias = alias_node->weakref = true; + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias))) + alias_node->ifunc_resolver = true; return alias_node; } @@ -2299,7 +2304,7 @@ cgraph_node::get_availability (symtab_node *ref) avail = AVAIL_AVAILABLE; else if (transparent_alias) ultimate_alias_target (&avail, ref); - else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)) + else if (ifunc_resolver || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl))) avail = AVAIL_INTERPOSABLE; else if (!externally_visible) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index ee7ebb41c24..afb2745a841 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -530,6 +530,9 @@ public: /* Set when symbol can be streamed into bytecode for offloading. */ unsigned offloadable : 1; + /* Set when symbol is an IFUNC resolver. */ + unsigned ifunc_resolver : 1; + /* Ordering of all symtab entries. */ int order; @@ -2886,6 +2889,7 @@ cgraph_node::only_called_directly_or_aliased_p (void) { gcc_assert (!global.inlined_to); return (!force_output && !address_taken + && !ifunc_resolver && !used_from_other_partition && !DECL_VIRTUAL_P (decl) && !DECL_STATIC_CONSTRUCTOR (decl) diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index e418ec04149..212ee7b8340 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1307,7 +1307,7 @@ maybe_diag_incompatible_alias (tree alias, tree target) tree altype = TREE_TYPE (alias); tree targtype = TREE_TYPE (target); - bool ifunc = lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)); + bool ifunc = cgraph_node::get (alias)->ifunc_resolver; tree funcptr = altype; if (ifunc) diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index dcd5391012c..40baf858ca5 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -1257,6 +1257,8 @@ input_node (struct lto_file_decl_data *file_data, of ipa passes is done. Alays forcingly create a fresh node. */ node = symtab->create_empty (); node->decl = fn_decl; + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl))) + node->ifunc_resolver = 1; node->register_symbol (); } diff --git a/gcc/symtab.c b/gcc/symtab.c index c1533083573..954920b6dff 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -998,6 +998,13 @@ symtab_node::verify_base (void) error ("function symbol is not function"); error_found = true; } + else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)) + != NULL) + != dyn_cast (this)->ifunc_resolver) + { + error ("inconsistent `ifunc' attribute"); + error_found = true; + } } else if (is_a (this)) { @@ -2253,13 +2260,13 @@ symtab_node::binds_to_current_def_p (symtab_node *ref) if (transparent_alias) return definition && get_alias_target()->binds_to_current_def_p (ref); - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + cgraph_node *cnode = dyn_cast (this); + if (cnode && cnode->ifunc_resolver) return false; if (decl_binds_to_current_def_p (decl)) return true; /* Inline clones always binds locally. */ - cgraph_node *cnode = dyn_cast (this); if (cnode && cnode->global.inlined_to) return true; diff --git a/gcc/testsuite/gcc.target/i386/pr85345.c b/gcc/testsuite/gcc.target/i386/pr85345.c new file mode 100644 index 00000000000..ceb94e4b940 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85345.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection" } */ +/* { dg-final { scan-assembler-times {\mendbr} 4 } } */ + +int resolver_fn = 0; +int resolved_fn = 0; + +static inline void +do_it_right_at_runtime_A (void) +{ + resolved_fn++; +} + +static inline void +do_it_right_at_runtime_B (void) +{ + resolved_fn++; +} + +static inline void do_it_right_at_runtime (void); + +void do_it_right_at_runtime (void) + __attribute__ ((ifunc ("resolve_do_it_right_at_runtime"))); + +extern int r; +static void (*resolve_do_it_right_at_runtime (void)) (void) +{ + resolver_fn++; + + typeof(do_it_right_at_runtime) *func; + if (r & 1) + func = do_it_right_at_runtime_A; + else + func = do_it_right_at_runtime_B; + + return (void *) func; +} + +int +main () +{ + do_it_right_at_runtime (); + return 0; +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 8cf6e1e2758..3bd9cbb69f0 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5833,7 +5833,8 @@ do_assemble_alias (tree decl, tree target) globalize_decl (decl); maybe_assemble_visibility (decl); } - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + if (TREE_CODE (decl) == FUNCTION_DECL + && cgraph_node::get (decl)->ifunc_resolver) { #if defined (ASM_OUTPUT_TYPE_DIRECTIVE) if (targetm.has_ifunc_p ()) @@ -5916,7 +5917,7 @@ assemble_alias (tree decl, tree target) # else if (!DECL_WEAK (decl)) { - if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))) + if (cgraph_node::get (decl)->ifunc_resolver) error_at (DECL_SOURCE_LOCATION (decl), "ifunc is not supported in this configuration"); else @@ -7048,7 +7049,8 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate, weakref alias. */ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)) || (TREE_CODE (exp) == FUNCTION_DECL - && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp)))) + && cgraph_node::get (exp) + && cgraph_node::get (exp)->ifunc_resolver)) return false; /* Static variables are always local. */ -- 2.17.0