From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 27D12385841A for ; Thu, 25 Aug 2022 08:53:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 27D12385841A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from [10.20.4.52] (unknown [10.20.4.52]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxX+CPOAdjSaIJAA--.42776S2; Thu, 25 Aug 2022 16:53:35 +0800 (CST) Subject: Re: [PATCH v2 2/2 resend] LoongArch: add model attribute To: Xi Ruoyao , gcc-patches@gcc.gnu.org Cc: Chenghua Xu , Youling Tang , Huacai Chen , Jinyang He , Wang Xuerui References: <33ecfc0e63844d9d1254190c3d964989a1e68cfe.camel@xry111.site> <7a57979ed30cdb47b51b24c7af80ad2b79be401c.camel@xry111.site> From: Lulu Cheng Message-ID: Date: Thu, 25 Aug 2022 16:53:34 +0800 User-Agent: Mozilla/5.0 (X11; Linux mips64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <7a57979ed30cdb47b51b24c7af80ad2b79be401c.camel@xry111.site> Content-Type: multipart/alternative; boundary="------------4054EB81151D80446BBC6225" Content-Language: en-US X-CM-TRANSID:AQAAf8DxX+CPOAdjSaIJAA--.42776S2 X-Coremail-Antispam: 1UD129KBjvAXoW3Cr4ftr47tF1UtF15AF4xJFb_yoW8Wr1xWo WfAFWrX34kWr1FkrWfKrnIqryDZF4vyrW8A3sxZw15CFs7ZrZ8C3y7Grs8t39rArn7Xr4q yryDCa9xAFZrua4Dn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUY47AC8VAFwI0_Gr0_Xr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWx JVW8Jr1l84ACjcxK6I8E87Iv67AKxVWxJr0_GcWl84ACjcxK6I8E87Iv6xkF7I0E14v26r xl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21lYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0E x4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvEwIxGrwACjI8F5V A0II8E6IAqYI8I648v4I1l7480Y4vEI4kI2Ix0rVAqx4xJMxk0xIA0c2IEe2xFo4CEbIxv r21lc2xSY4AK6svPMxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I 0E5I8CrVAFwI0_JrI_JrWlx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWU AVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcV CY1x0267AKxVWUJVW8JwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAF wI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa 7VU1g4S7UUUUU== X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,GIT_PATCH_0,HTML_MESSAGE,KAM_DMARC_STATUS,KAM_SHORT,KAM_STOCKGEN,NICE_REPLY_A,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Message-ID: <20220825085334.dK-Z2AD2cb2Ks7NvFMwUq51cZbvW8vrnkRtL_Q4QdKI@z> This is a multi-part message in MIME format. --------------4054EB81151D80446BBC6225 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit 在 2022/8/24 下午10:12, Xi Ruoyao 写道: > On Wed, 2022-08-24 at 22:08 +0800, Xi Ruoyao wrote: >> v1 -> v2: >> >>  * Avoid introduce of SYMBOL_PCREL32, use SYMBOL_PCREL for 32-bit PC >>    relative. >>  * Rebase onto a bug fix ([1/2] in the series) to avoid merge conflict. >>  * Fix missed ChangeLog entries. > Resend because my mail client has done some stupid thing to the patch :( > > -- >8 -- > > A linker script and/or a section attribute may locate some object > specially, so we need to handle the code model for such objects > differently than the -mcmodel setting. This happens when the Linux > kernel loads a module with per-CPU variables. > > Add an attribute to override the code model for a specific variable. > > gcc/ChangeLog: > > * config/loongarch/loongarch-protos.h (loongarch_symbol_type): > Add SYMBOL_PCREL64 and change the description for SYMBOL_PCREL. > * config/loongarch/loongarch.cc (loongarch_attribute_table): > New attribute table. > (TARGET_ATTRIBUTE_TABLE): Define the target hook. > (loongarch_handle_model_attribute): New static function. > (loongarch_classify_symbol): Take TARGET_CMODEL_EXTREME and the > model attribute of SYMBOL_REF_DECL into account returning > SYMBOL_PCREL or SYMBOL_PCREL64. > (loongarch_use_anchors_for_symbol_p): New static function. > (TARGET_USE_ANCHORS_FOR_SYMBOL_P): Define the target hook. > (loongarch_symbol_extreme_p): New static function. > (loongarch_symbolic_constant_p): Handle SYMBOL_PCREL64. > (loongarch_symbol_insns): Likewise. > (loongarch_split_symbol_type): Likewise. > (loongarch_split_symbol): Check SYMBOL_PCREL64 instead of > TARGET_CMODEL_EXTREME for PC-relative addressing. > (loongarch_print_operand_reloc): Likewise. > * doc/extend.texi (Variable Attributes): Document new > LoongArch specific attribute. > > gcc/testsuite/ChangeLog: > > * gcc.target/loongarch/attr-model-test.c: New test. > * gcc.target/loongarch/attr-model-1.c: New test. > * gcc.target/loongarch/attr-model-2.c: New test. > * gcc.target/loongarch/attr-model-diag.c: New test. > --- > gcc/config/loongarch/loongarch-protos.h | 8 +- > gcc/config/loongarch/loongarch.cc | 190 ++++++++++++++++-- > gcc/doc/extend.texi | 16 ++ > .../gcc.target/loongarch/attr-model-1.c | 6 + > .../gcc.target/loongarch/attr-model-2.c | 6 + > .../gcc.target/loongarch/attr-model-diag.c | 7 + > .../gcc.target/loongarch/attr-model-test.c | 25 +++ > 7 files changed, 237 insertions(+), 21 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-1.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-2.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-diag.c > create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-test.c > > diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h > index cadaad7519c..77b2217247d 100644 > --- a/gcc/config/loongarch/loongarch-protos.h > +++ b/gcc/config/loongarch/loongarch-protos.h > @@ -28,7 +28,12 @@ along with GCC; see the file COPYING3. If not see > The symbol's value will be loaded directly from the GOT. > > SYMBOL_PCREL > - The symbol's value will be loaded directly from data section. > + The symbol's value will be loaded directly from data section within > + +/- 2GiB range. > + > + SYMBOL_PCREL64 > + The symbol's value will be loaded directly from data section within > + +/- 8EiB range. > > SYMBOL_TLS > A thread-local symbol. > @@ -42,6 +47,7 @@ along with GCC; see the file COPYING3. If not see > enum loongarch_symbol_type { > SYMBOL_GOT_DISP, > SYMBOL_PCREL, > + SYMBOL_PCREL64, > SYMBOL_TLS, > SYMBOL_TLS_IE, > SYMBOL_TLS_LE, > diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc > index 41d9cca6d31..d9061cdeee3 100644 > --- a/gcc/config/loongarch/loongarch.cc > +++ b/gcc/config/loongarch/loongarch.cc > @@ -1633,8 +1633,11 @@ loongarch_rtx_constant_in_small_data_p (machine_mode mode) > static enum loongarch_symbol_type > loongarch_classify_symbol (const_rtx x) > { > + enum loongarch_symbol_type pcrel = > + TARGET_CMODEL_EXTREME ? SYMBOL_PCREL64 : SYMBOL_PCREL; > + > if (!SYMBOL_REF_P (x)) > - return SYMBOL_PCREL; > + return pcrel; > > if (SYMBOL_REF_TLS_MODEL (x)) > return SYMBOL_TLS; > @@ -1642,7 +1645,28 @@ loongarch_classify_symbol (const_rtx x) > if (!loongarch_symbol_binds_local_p (x)) > return SYMBOL_GOT_DISP; > > - return SYMBOL_PCREL; > + tree t = SYMBOL_REF_DECL (x); > + if (!t) > + return pcrel; > + > + t = lookup_attribute ("model", DECL_ATTRIBUTES (t)); > + if (!t) > + return pcrel; > + > + t = TREE_VALUE (TREE_VALUE (t)); > + > + /* loongarch_handle_model_attribute should reject other values. */ > + gcc_assert (TREE_CODE (t) == STRING_CST); > + > + const char *model = TREE_STRING_POINTER (t); > + if (strcmp (model, "normal") == 0) > + return SYMBOL_PCREL; > + if (strcmp (model, "extreme") == 0) > + return SYMBOL_PCREL64; > + > + /* loongarch_handle_model_attribute should reject unknown model > + name. */ > + gcc_unreachable (); > } > > /* Classify the base of symbolic expression X, given that X appears in > @@ -1695,6 +1719,7 @@ loongarch_symbolic_constant_p (rtx x, enum loongarch_symbol_type *symbol_type) > case SYMBOL_TLSGD: > case SYMBOL_TLSLDM: > case SYMBOL_PCREL: > + case SYMBOL_PCREL64: > /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */ > return sext_hwi (INTVAL (offset), 32) == INTVAL (offset); > > @@ -1729,6 +1754,9 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode) > case SYMBOL_TLSLDM: > return 3; > > + case SYMBOL_PCREL64: > + return 5; > + > case SYMBOL_TLS: > /* We don't treat a bare TLS symbol as a constant. */ > return 0; > @@ -1833,7 +1861,7 @@ loongarch_valid_offset_p (rtx x, machine_mode mode) > return true; > } > > -/* Should a symbol of type SYMBOL_TYPE should be split in two? */ > +/* Should a symbol of type SYMBOL_TYPE should be split in two or more? */ > > bool > loongarch_split_symbol_type (enum loongarch_symbol_type symbol_type) > @@ -1841,6 +1869,7 @@ loongarch_split_symbol_type (enum loongarch_symbol_type symbol_type) > switch (symbol_type) > { > case SYMBOL_PCREL: > + case SYMBOL_PCREL64: > case SYMBOL_GOT_DISP: > case SYMBOL_TLS_IE: > case SYMBOL_TLS_LE: > @@ -2718,6 +2747,20 @@ loongarch_force_address (rtx x, machine_mode mode) > return x; > } > > +static bool > +loongarch_symbol_extreme_p (enum loongarch_symbol_type type) > +{ > + switch (type) > + { > + case SYMBOL_PCREL: > + return false; > + case SYMBOL_PCREL64: > + return true; > + default: > + return TARGET_CMODEL_EXTREME; > + } > +} > + > /* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise > it appears in a MEM of that mode. Return true if ADDR is a legitimate > constant in that context and can be split into high and low parts. > @@ -2757,7 +2800,7 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) > high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); > high = loongarch_force_temporary (temp, high); > > - if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) > + if (loongarch_symbol_extreme_p (symbol_type) && can_create_pseudo_p ()) > { > gcc_assert (TARGET_EXPLICIT_RELOCS); > > @@ -2771,14 +2814,16 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) > if (low_out) > switch (symbol_type) > { > - case SYMBOL_PCREL: > - { > - if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) > + case SYMBOL_PCREL64: > + if (can_create_pseudo_p ()) > + { > *low_out = gen_rtx_PLUS (Pmode, high, temp1); > - else > - *low_out = gen_rtx_LO_SUM (Pmode, high, addr); > - break; > - } > + break; > + } > + /* fall through */ > + case SYMBOL_PCREL: > + *low_out = gen_rtx_LO_SUM (Pmode, high, addr); > + break; > > case SYMBOL_GOT_DISP: > /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */ > @@ -4745,22 +4790,23 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part, > bool hi_reloc) > { > const char *reloc; > + enum loongarch_symbol_type symbol_type = > + loongarch_classify_symbolic_expression (op); > > - if (TARGET_CMODEL_EXTREME) > + if (loongarch_symbol_extreme_p (symbol_type)) > gcc_assert (TARGET_EXPLICIT_RELOCS); > > - switch (loongarch_classify_symbolic_expression (op)) > + switch (symbol_type) > { > - case SYMBOL_PCREL: > + case SYMBOL_PCREL64: > if (hi64_part) > { > - if (TARGET_CMODEL_EXTREME) > - reloc = hi_reloc ? "%pc64_hi12" : "%pc64_lo20"; > - else > - gcc_unreachable (); > + reloc = hi_reloc ? "%pc64_hi12" : "%pc64_lo20"; > + break; > } > - else > - reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12"; > + /* fall through */ > + case SYMBOL_PCREL: > + reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12"; > break; > > case SYMBOL_GOT_DISP: > @@ -6316,6 +6362,104 @@ loongarch_starting_frame_offset (void) > return crtl->outgoing_args_size; > } > > +static tree > +loongarch_handle_model_attribute (tree *node, tree name, tree arg, int, > + bool *no_add_attrs) > +{ > + tree decl = *node; > + if (TREE_CODE (decl) == VAR_DECL) > + { > + if (DECL_THREAD_LOCAL_P (decl)) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "%qE attribute cannot be specified for thread-local " > + "variables", name); > + *no_add_attrs = true; > + return NULL_TREE; > + } > + 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; > + return NULL_TREE; > + } > + if (DECL_REGISTER (decl)) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "%qE attribute cannot be specified for register " > + "variables", name); > + *no_add_attrs = true; > + return NULL_TREE; > + } > + if (!TARGET_EXPLICIT_RELOCS) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "%qE attribute requires %s", name, "-mexplicit-relocs"); > + *no_add_attrs = true; > + return NULL_TREE; > + } > + > + arg = TREE_VALUE (arg); > + if (TREE_CODE (arg) != STRING_CST) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "invalid argument of %qE attribute", name); > + *no_add_attrs = true; > + return NULL_TREE; > + } > + > + const char *model = TREE_STRING_POINTER (arg); > + if (strcmp (model, "normal") != 0 > + && strcmp (model, "extreme") != 0) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "invalid argument of %qE attribute", name); > + *no_add_attrs = true; > + return NULL_TREE; > + } > + > + if (lookup_attribute ("model", DECL_ATTRIBUTES (decl))) > + { > + error_at (DECL_SOURCE_LOCATION (decl), > + "multiple %qE attribute", name); > + *no_add_attrs = true; > + return NULL_TREE; > + } > + } > + 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 } */ > + { "model", 1, 1, true, false, false, false, > + loongarch_handle_model_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); > + > + /* The section anchor optimization may break custom address model. */ > + if (decl && lookup_attribute ("model", 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" > @@ -6504,6 +6648,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..431811c7b26 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,21 @@ 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 model("@var{name}") > +@cindex @code{model} variable attribute, LoongArch > +Use this attribute on the LoongArch to use a different code model for > +addressing this variable, than the code model specified by the global > +@option{-mcmodel} option.This attribute is mostly useful if a > +@code{section} attribute and/or a linker script will locate this object > +specially. I think this should add a sentence: "Currently, the identifier name can only be one of small or extreme." Others I think are ok. > +@end table > + > @node M32R/D Variable Attributes > @subsection M32R/D Variable Attributes > > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-1.c b/gcc/testsuite/gcc.target/loongarch/attr-model-1.c > new file mode 100644 > index 00000000000..916d715b98b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-1.c > @@ -0,0 +1,6 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mexplicit-relocs -mcmodel=normal -O2" } */ > +/* { dg-final { scan-assembler-times "%pc64_hi12" 2 } } */ > + > +#define ATTR_MODEL_TEST > +#include "attr-model-test.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-2.c b/gcc/testsuite/gcc.target/loongarch/attr-model-2.c > new file mode 100644 > index 00000000000..a74c795ac3e > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-2.c > @@ -0,0 +1,6 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mexplicit-relocs -mcmodel=extreme -O2" } */ > +/* { dg-final { scan-assembler-times "%pc64_hi12" 3 } } */ > + > +#define ATTR_MODEL_TEST > +#include "attr-model-test.c" > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-diag.c b/gcc/testsuite/gcc.target/loongarch/attr-model-diag.c > new file mode 100644 > index 00000000000..88beede74df > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-diag.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-mexplicit-relocs" } */ > + > +__thread int x __attribute__((model("extreme"))); /* { dg-error "attribute cannot be specified for thread-local variables" } */ > +register int y __asm__("tp") __attribute__((model("extreme"))); /* { dg-error "attribute cannot be specified for register variables" } */ > +int z __attribute__((model(114))); /* { dg-error "invalid argument" } */ > +int t __attribute__((model("good"))); /* { dg-error "invalid argument" } */ > diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-test.c b/gcc/testsuite/gcc.target/loongarch/attr-model-test.c > new file mode 100644 > index 00000000000..5b61a7af9c3 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-test.c > @@ -0,0 +1,25 @@ > +#ifdef ATTR_MODEL_TEST > +int x __attribute__((model("extreme"))); > +int y __attribute__((model("normal"))); > +int z; > + > +int > +test(void) > +{ > + return x + y + z; > +} > + > +/* 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"), model("extreme"))); > + > +void > +inc_counter(void) > +{ > + int *ptr = (int *)(per_cpu_base + (long)&counter); > + (*ptr)++; > +} > +#endif > + > +int dummy; --------------4054EB81151D80446BBC6225--