From patchwork Fri Jul 29 17:17:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 313 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:b5d6:b0:2b9:3548:2db5 with SMTP id v22csp929219pxt; Fri, 29 Jul 2022 10:18:18 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tKJ9HvUmHDycV2qsOLVXlbdDqqXemiLmyDkcfEDfdVIpJ+2shXjfGVIQOZwIxS6LyfEpDx X-Received: by 2002:a17:907:3fa0:b0:72f:aefd:621e with SMTP id hr32-20020a1709073fa000b0072faefd621emr3720121ejc.475.1659115098212; Fri, 29 Jul 2022 10:18:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659115098; cv=none; d=google.com; s=arc-20160816; b=TuPF2hOBCAEmoZHke6E36n4OfetjrDeVD58Dy315EbYmZ6AAoncKwtFAVYdGTO+baa HfnYSURd+6RCtufg+4TwInMbGDsqMUz72nTR7Rslz5PHR0b6dArFoETPwVRL5TDhiwRF 7uWX/AvDN/zXIPWmTTTzcUqFVKyKjb3xe/VobNfQ1ZBDpRbNfLQUTG/97kJwakJ21s54 OoHw1mYQWJeD+zntChUF0JfJoGPyyzhi3RF0e5FDYSU6xaeF5Rcg5qQv+CPK34pyyvXg 6qW4u6YPGxenL+cKuFXRjBZGPGclig8ebSixOmhtps3Sdi7sul7616QosjsQiR7Dp1XI z/yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mime-version:user-agent:content-transfer-encoding:references :in-reply-to:date:to:subject:message-id:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=9K0Da2ePwmMDbd+tt0bnq/ZOYohGnojzuG3S5KnIZr4=; b=1E4r/3V+DlQfUbZCiyaXyNNUyz9dR6x2V1p9TRi2cHuODxgE9gr+VTxo8DUequ7ms5 xUuNTVAHONBk/id48EnENym5GKu0XBHnghZsabsQxiXXCsyflTh4NzMkZth6uTbSFcpV YTFqbEGtiKWn8OByD2VAa+/9/P4VDjiK82MK+6/w4oH6SSDI7foKus6EE95zsCPWmy43 lL7P547Oa+phv971W8pLde98xjD87+wFCs5MuksktooDx0aQAIs7lHOt4qG+lShor0Xj tOEruYEZwVqbRKM7HtTqQ1//bb+stH9c2ZyRg/dU7eSMCfpT7IX6CWYktNAEuknjnRNU lh6g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=XQcDZVjR; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id i18-20020a170906251200b00722e89ba02bsi3305329ejb.736.2022.07.29.10.18.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Jul 2022 10:18:18 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=XQcDZVjR; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C11253857B9D for ; Fri, 29 Jul 2022 17:18:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C11253857B9D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1659115096; bh=9K0Da2ePwmMDbd+tt0bnq/ZOYohGnojzuG3S5KnIZr4=; h=Subject:To:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=XQcDZVjRHJN/+mD/eOn6DLp5AY+G6IrbvwzSRq+s6ph05TbkQs53luHriDGLMrVWw ih3NHWgKo2sYTFRFVkpoSellQK+J3W747Vh7G5FsnHe1vpANFxCdFOwKhiMIjqSwGE nw67jUdAz0V1uvtudmdDEac/8nBPLU1kEXNjxvbY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 09F533857B9D for ; Fri, 29 Jul 2022 17:17:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 09F533857B9D Received: from [IPv6:240e:358:1187:8600:dc73:854d:832e:3] (unknown [IPv6:240e:358:1187:8600:dc73:854d:832e:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 025F46688E; Fri, 29 Jul 2022 13:17:26 -0400 (EDT) Message-ID: <9b6b0e68cfb7e87ae961ef8a7bb7987f534da19c.camel@xry111.site> Subject: [PATCH v3] LoongArch: add addr_global attribute To: gcc-patches@gcc.gnu.org, Lulu Cheng Date: Sat, 30 Jul 2022 01:17:15 +0800 In-Reply-To: References: User-Agent: Evolution 3.44.3 MIME-Version: 1.0 X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FROM_SUSPICIOUS_NTLD, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, LIKELY_SPAM_FROM, PDS_OTHER_BAD_TLD, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Xi Ruoyao via Gcc-patches From: Xi Ruoyao Reply-To: Xi Ruoyao Cc: Youling Tang , xuchenghua@loongson.cn, Huacai Chen , Jinyang He , Wang Xuerui Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1739697306429001340?= X-GMAIL-MSGID: =?utf-8?q?1739708273203030147?= Change v2 to v3: - Disable section anchor for addr_global symbols. - Use -O2 in test to make sure section anchor is disabled. --- Background: https://lore.kernel.org/loongarch/d7670b60-2782-4642-995b-7baa01779a66@loongson.cn/T/#e1d47e2fe185f2e2be8fdc0784f0db2f644119379 Question: Do you have a better name than "addr_global"? Alternatives: 1. Just use "-mno-explicit-relocs -mla-local-with-abs" for kernel modules. It's stupid IMO. 2. Implement a "-maddress-local-with-got" option for GCC and use it for kernel modules. It seems too overkill: we might create many unnecessary GOT entries. 3. For all variables with a section attribute, consider it global. It may make sense, but I just checked x86_64 and riscv and they don't do this. 4. Implement -mcmodel=extreme and use it for kernel modules. To me "extreme" seems really too extreme. 5. More hacks in kernel. (Convert relocations against .data..percpu with objtool? But objtool is not even implemented for LoongArch yet.) Note: I'll be mostly AFK in the following week. My attempt to finish the kernel support for new relocs before going AFK now failed miserably :(. -- >8 -- A linker script and/or a section attribute may locate a local object in some way unexpected by the code model, leading to a link failure. This happens when the Linux kernel loads a module with "local" per-CPU variables. Add an attribute to explicitly mark an variable with the address unlimited by the code model so we would be able to work around such problems. gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_attribute_table): New attribute table. (TARGET_ATTRIBUTE_TABLE): Define the target hook. (loongarch_handle_addr_global_attribute): New static function. (loongarch_classify_symbol): Return SYMBOL_GOT_DISP for SYMBOL_REF_DECL with addr_global attribute. (loongarch_use_anchors_for_symbol_p): New static function. (TARGET_USE_ANCHORS_FOR_SYMBOL_P): Define the target hook. * doc/extend.texi (Variable Attributes): Document new LoongArch specific attribute. gcc/testsuite/ChangeLog: * gcc.target/loongarch/addr-global.c: New test. --- gcc/config/loongarch/loongarch.cc | 61 +++++++++++++++++++ gcc/doc/extend.texi | 17 ++++++ .../gcc.target/loongarch/addr-global.c | 28 +++++++++ 3 files changed, 106 insertions(+) create mode 100644 gcc/testsuite/gcc.target/loongarch/addr-global.c diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 79687340dfd..db6f84d4e66 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -1643,6 +1643,13 @@ loongarch_classify_symbol (const_rtx x) && !loongarch_symbol_binds_local_p (x)) return SYMBOL_GOT_DISP; + if (SYMBOL_REF_P (x)) + { + tree decl = SYMBOL_REF_DECL (x); + if (decl && lookup_attribute ("addr_global", DECL_ATTRIBUTES (decl))) + return SYMBOL_GOT_DISP; + } + return SYMBOL_PCREL; } @@ -6068,6 +6075,54 @@ loongarch_starting_frame_offset (void) return crtl->outgoing_args_size; } +static tree +loongarch_handle_addr_global_attribute (tree *node, tree name, tree, int, + bool *no_add_attrs) +{ + tree decl = *node; + if (TREE_CODE (decl) == VAR_DECL) + { + if (DECL_CONTEXT (decl) + && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL + && !TREE_STATIC (decl)) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute cannot be specified for local " + "variables", name); + *no_add_attrs = true; + } + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + return NULL_TREE; +} + +static const struct attribute_spec loongarch_attribute_table[] = +{ + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, + affects_type_identity, handler, exclude } */ + { "addr_global", 0, 0, true, false, false, false, + loongarch_handle_addr_global_attribute, NULL }, + /* The last attribute spec is set to be NULL. */ + {} +}; + +bool +loongarch_use_anchors_for_symbol_p (const_rtx symbol) +{ + tree decl = SYMBOL_REF_DECL (symbol); + + /* addr_global indicates we don't know how the linker will locate the symbol, + so the use of anchor may cause relocation overflow. */ + if (decl && lookup_attribute ("addr_global", DECL_ATTRIBUTES (decl))) + return false; + + return default_use_anchors_for_symbol_p (symbol); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -6256,6 +6311,12 @@ loongarch_starting_frame_offset (void) #undef TARGET_HAVE_SPECULATION_SAFE_VALUE #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed +#undef TARGET_ATTRIBUTE_TABLE +#define TARGET_ATTRIBUTE_TABLE loongarch_attribute_table + +#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P +#define TARGET_USE_ANCHORS_FOR_SYMBOL_P loongarch_use_anchors_for_symbol_p + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-loongarch.h" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 7fe7f8817cd..4a1cd7ab5e4 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7314,6 +7314,7 @@ attributes. * Blackfin Variable Attributes:: * H8/300 Variable Attributes:: * IA-64 Variable Attributes:: +* LoongArch Variable Attributes:: * M32R/D Variable Attributes:: * MeP Variable Attributes:: * Microsoft Windows Variable Attributes:: @@ -8098,6 +8099,22 @@ defined by shared libraries. @end table +@node LoongArch Variable Attributes +@subsection LoongArch Variable Attributes + +One attribute is currently defined for the LoongArch. + +@table @code +@item addr_global +@cindex @code{addr_global} variable attribute, LoongArch +@cindex variable addressability on the LoongArch +Use this attribute on the LoongArch to mark an object with address +unlimited limited by the local data section range specified by the code +model, even if the object is defined locally. This attribute is mostly +useful if a @code{section} attribute or a linker script will move the +object somewhere unexpected by the code model. +@end table + @node M32R/D Variable Attributes @subsection M32R/D Variable Attributes diff --git a/gcc/testsuite/gcc.target/loongarch/addr-global.c b/gcc/testsuite/gcc.target/loongarch/addr-global.c new file mode 100644 index 00000000000..46a895c84bb --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/addr-global.c @@ -0,0 +1,28 @@ +/* addr_global attribute should mark x and y possibly outside of the local + data range defined by the code model, so GOT should be used instead of + PC-relative. */ + +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs -mcmodel=normal -O2" } */ +/* { dg-final { scan-assembler-not "%pc" } } */ +/* { dg-final { scan-assembler-times "%got_pc_hi20" 3 } } */ + +int x __attribute__((addr_global)); +int y __attribute__((addr_global)); + +int +test(void) +{ + return x + y; +} + +/* The following will be used for kernel per-cpu storage implemention. */ + +register char *per_cpu_base __asm__("r21"); +static int counter __attribute__((section(".data..percpu"), addr_global)); +void +inc_counter(void) +{ + int *ptr = (int *)(per_cpu_base + (long)&counter); + (*ptr)++; +}