From patchwork Thu Aug 3 11:51:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Die Li X-Patchwork-Id: 130524 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9f41:0:b0:3e4:2afc:c1 with SMTP id v1csp1091187vqx; Thu, 3 Aug 2023 04:52:38 -0700 (PDT) X-Google-Smtp-Source: APBJJlGZy2/1xRVnEeySCXOwsJrLzZotaWqhdaH/Cd6WTn5vKZT/60Qv/bAnXR4IF1CJn3VAfVkH X-Received: by 2002:a17:906:214:b0:99b:56f1:3002 with SMTP id 20-20020a170906021400b0099b56f13002mr8058530ejd.61.1691063557846; Thu, 03 Aug 2023 04:52:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691063557; cv=none; d=google.com; s=arc-20160816; b=yFGCrMXS0j5oswbTi4EotdN201Xunl91p5zrGP3t+vAVsketvP2qvCJXt7nBOF0wd5 U5bhghloL97iUmURbbpFvijFlYv+rLCp/Pmih2vxfpTCrHPalcK24DHoPW63bIEffYcL /LIl6uq38wbNbjBU3fyKyvTUbKMZBkPrkt8bhC4dgIpkIHm272wF/SWYQ/s49BiylZHn tRhDPBNLzhtFms5cttFeQSx99Zr6buSFfcHVPppEmrokM3Di3gdnbU/kPxgzkWsBN39Q 2PCdq8id8Fl/vmPOuHnQGRcu+uj8Ug5Fd4byXxmlGakJpeQQDjUmj2X51jUPfabOHJ2m PQJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:message-id:date:subject:cc:to :from:dmarc-filter:delivered-to; bh=x5vcL529C9PoAWYWe169b2PEB6/6wbfOWy4Tg03MReY=; fh=ZVB6kKdqjSdJ8aydyyWe2ss6klBVhWDwJjtHyvMufvU=; b=cPOIVzJDTtQLBrtyIJCpL7sXB5IG1l4Hm3LyvgvvjdADa8OdaD7atTpSvrXQ1AJtxp 70NOOzfzHZafx8cHZ1x+Mpeg2zqtTQtuLQoC4NeC+rDpeA+EXA4Q4RKcLdKrtiEuRKlC ypyaIt27Hgzvpu4Le06BR9jPRVZR1+T3tG9V2zqZnlZzxpKqppcvL+GUc/ZV71xaxTt/ k+x8PWBJGygt/Trk7T5x7yptvloFMivWLqEo8odHyAG7zHeZgBpbM9Xokt0DYEAKH9nq A5np2lscNm/0hxfvVkc3wKClugUuEmotl8twtq2DiuH5Wkrd9R+ZVG2250cHgqDDBzwB Z24Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id i5-20020a170906850500b00993664a9970si438938ejx.873.2023.08.03.04.52.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Aug 2023 04:52:37 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3BD563857346 for ; Thu, 3 Aug 2023 11:51:29 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from sgoci-sdnproxy-4.icoremail.net (sgoci-sdnproxy-4.icoremail.net [129.150.39.64]) by sourceware.org (Postfix) with ESMTP id 51142385771C for ; Thu, 3 Aug 2023 11:51:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 51142385771C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from host040-ubuntu-1804.lxd (unknown [10.12.130.38]) by app1 (Coremail) with SMTP id EwgMCgBX9cSulMtkKto5AA--.31661S4; Thu, 03 Aug 2023 19:51:10 +0800 (CST) From: Die Li To: binutils@sourceware.org Cc: kito.cheng@gmail.com, palmer@dabbelt.com, lidie@eswincomputing.com Subject: [PATCH] RISC-V: Use tp as gp when no TLS is used. Date: Thu, 3 Aug 2023 11:51:07 +0000 Message-Id: <20230803115107.63736-1-lidie@eswincomputing.com> X-Mailer: git-send-email 2.17.1 X-CM-TRANSID: EwgMCgBX9cSulMtkKto5AA--.31661S4 X-Coremail-Antispam: 1UD129KBjvJXoWfGr15CF1xuFWkuF48WFyfZwb_yoWkGFWrp3 95tr9Y9r4rtFn7Wr9rGr18Wa1fWw109F45G343X3y2y3ZxJrWxZ3yqyrW7Cay5Jr4Fqr4a yr42y3y8CFs0ywUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUk214x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26w1j6s0DM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gc CE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E 2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJV W8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svPMxAI w28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr 4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxG rwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8Jw CI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2 z280aVCY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjfU5WlkUUUUU X-CM-SenderInfo: 5olgxv46hv4xpqfrz1xxwl0woofrz/ X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_VALIDITY_RPBL, SPF_HELO_NONE, 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773208661124815942 X-GMAIL-MSGID: 1773208661124815942 This patch extends the GP-relative addressing mode by adding a 4K address range on top of GP+2k, using the TP register instead of GP for relative addressing. This allows more data to benefit from the relative addressing access mode. As TP register is used for this optimization, it checks for the presence of TLS (Thread-Local Storage) sections to ensure that the optimization is performed only when TP is available. Additionally, a linker option, "--tp-as-gp", is introduced to control the enabling of this optimization. Take the "tp_as_gp.s" from this patch as an example to illustrate its optimization effect: Before this patch: After assembling and processing with "--relax", we have: 00000000000100e8 <_start>: 100e8: 67c5 lui a5,0x11 100ea: 0f878793 add a5,a5,248 # 110f8 100ee: 67c9 lui a5,0x12 100f0: 6d878793 add a5,a5,1752 # 126d8 With this patch: After assembling and processing with "--relax --tp-as-gp", we have: 00000000000100e8 <_start>: 100e8: 67c5 lui a5,0x11 100ea: 0f878793 add a5,a5,248 # 110f8 100ee: de620793 add a5,tp,-538 # .* Check the symbol table, we have: 6: 00000000000118f4 0 NOTYPE GLOBAL DEFAULT ABS __global_pointer$ The addressable range of TP is increased by 4K beyond the addressable range of GP, thus setting TP to GP+0x1000. So the access to global_array2, which was originally represented as "lui a5,0x12" followed by "add a5,a5,1752 # 126d8", is optimized to "add a5,tp,-538", which is feasible. Signed-off-by: Die Li ChangeLog: * bfd/elfnn-riscv.c (tpoff): (_bfd_riscv_relax_lui): Convert R_RISCV_HI20 to R_RISCV_TPREL_HI20, R_RISCV_LO12_I to R_RISCV_TPREL_LO12_I, R_RISCV_LO12_S to R_RISCV_TPREL_LO12_S when use tp as gp. * ld/ldlex.h (enum option_values): Add OPTION_RELAX_TP_AS_GP. * ld/ldmain.c (main): Add option state. * ld/ldmain.h (ENABLE_TP_AS_GP): New macro to control option. * ld/lexsup.c (parse_args): Add --tp-as-gp option. * ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add test entry. * ld/testsuite/ld-riscv-elf/tp_as_gp.d: New test. * ld/testsuite/ld-riscv-elf/tp_as_gp.s: New test. include/ChangeLog: * bfdlink.h (struct bfd_link_info): Clarify the option state. * elf/riscv.h (ENABLE_TP_AS_GP): New macro relative with option. (USED_TP_AS_GP): Likewise. --- bfd/elfnn-riscv.c | 52 +++++++++++++++++----- include/bfdlink.h | 6 +++ include/elf/riscv.h | 6 +++ ld/ldlex.h | 1 + ld/ldmain.c | 1 + ld/ldmain.h | 2 + ld/lexsup.c | 5 +++ ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 1 + ld/testsuite/ld-riscv-elf/tp_as_gp.d | 14 ++++++ ld/testsuite/ld-riscv-elf/tp_as_gp.s | 33 ++++++++++++++ 10 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 ld/testsuite/ld-riscv-elf/tp_as_gp.d create mode 100644 ld/testsuite/ld-riscv-elf/tp_as_gp.s diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 09aa7be225e..9d418521839 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -1700,17 +1700,6 @@ dtpoff (struct bfd_link_info *info, bfd_vma address) return address - elf_hash_table (info)->tls_sec->vma - DTP_OFFSET; } -/* Return the relocation value for a static TLS tp-relative relocation. */ - -static bfd_vma -tpoff (struct bfd_link_info *info, bfd_vma address) -{ - /* If tls_sec is NULL, we should have signalled an error already. */ - if (elf_hash_table (info)->tls_sec == NULL) - return 0; - return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET; -} - /* Return the global pointer's value, or 0 if it is not in use. */ static bfd_vma @@ -1725,6 +1714,25 @@ riscv_global_pointer_value (struct bfd_link_info *info) return h->u.def.value + sec_addr (h->u.def.section); } +/* Return the relocation value for a static TLS tp-relative relocation. */ + +static bfd_vma +tpoff (struct bfd_link_info *info, bfd_vma address) +{ + /* If tls_sec is NULL, we try to use tp as gp, otherwise signal an error. */ + if (elf_hash_table (info)->tls_sec == NULL) + { + if (info->tp_as_gp & USED_TP_AS_GP) + { + bfd_vma gp = riscv_global_pointer_value (info); + bfd_vma tp = gp + 0x1000; + return address - tp; + } + return 0; + } + return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET; +} + /* Emplace a static relocation. */ static bfd_reloc_status_type @@ -4657,6 +4665,28 @@ _bfd_riscv_relax_lui (bfd *abfd, } } + unsigned sym = ELFNN_R_SYM (rel->r_info); + if ((link_info->tp_as_gp & ENABLE_TP_AS_GP) + && (elf_hash_table (link_info)->tls_sec == NULL)) + { + bfd_vma tp = gp + 0x1000; + if (undefined_weak + || VALID_ITYPE_IMM (symval) + || (symval >= tp + && VALID_ITYPE_IMM (symval - tp + max_alignment + reserve_size)) + || (symval < tp + && VALID_ITYPE_IMM (symval - tp - max_alignment - reserve_size))) + { + link_info->tp_as_gp |= USED_TP_AS_GP; + if (ELFNN_R_TYPE (rel->r_info) == R_RISCV_HI20) + rel->r_info = ELFNN_R_INFO (sym, R_RISCV_TPREL_HI20); + if (ELFNN_R_TYPE (rel->r_info) == R_RISCV_LO12_I) + rel->r_info = ELFNN_R_INFO (sym, R_RISCV_TPREL_LO12_I); + if (ELFNN_R_TYPE (rel->r_info) == R_RISCV_LO12_S) + rel->r_info = ELFNN_R_INFO (sym, R_RISCV_TPREL_LO12_S); + } + } + /* Can we relax LUI to C.LUI? Alignment might move the section forward; account for this assuming page alignment at worst. In the presence of RELRO segment the linker aligns it by one page size, therefore sections diff --git a/include/bfdlink.h b/include/bfdlink.h index 840790a298c..bf79035341d 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -557,6 +557,12 @@ struct bfd_link_info /* TRUE if commonpagesize is set on command-line. */ unsigned int commonpagesize_is_set : 1; + /* Tri-state variable: + 0 => option --tp-as-gp is not specified by user. + 1 => option --tp-as-gp is specified by user, but not used. + 3 => option --tp-as-gp is specified by user, and has been used. */ + unsigned int tp_as_gp: 2; + /* Char that may appear as the first char of a symbol, but should be skipped (like symbol_leading_char) when looking up symbols in wrap_hash. Used by PowerPC Linux for 'dot' symbols. */ diff --git a/include/elf/riscv.h b/include/elf/riscv.h index 0aa8b3359c4..5dfe7aee00d 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -115,6 +115,12 @@ END_RELOC_NUMBERS (R_RISCV_max) /* File uses the 32E base integer instruction. */ #define EF_RISCV_RVE 0x0008 +/* Enable the switch of option --tp-as-gp. */ +#define ENABLE_TP_AS_GP 0x1 + +/* Use the switch of option --tp-as-gp. */ +#define USED_TP_AS_GP 0x2 + /* The name of the global pointer symbol. */ #define RISCV_GP_SYMBOL "__global_pointer$" diff --git a/ld/ldlex.h b/ld/ldlex.h index 87cac02141d..ebd9e6282fb 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -54,6 +54,7 @@ enum option_values OPTION_OFORMAT, OPTION_RELAX, OPTION_NO_RELAX, + OPTION_RELAX_TP_AS_GP, OPTION_NO_SYMBOLIC, OPTION_RETAIN_SYMBOLS_FILE, OPTION_RPATH, diff --git a/ld/ldmain.c b/ld/ldmain.c index 06ac2c64fa8..d5c8fa62687 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -339,6 +339,7 @@ main (int argc, char **argv) link_info.combreloc = true; link_info.strip_discarded = true; link_info.prohibit_multiple_definition_absolute = false; + link_info.tp_as_gp = 0; link_info.textrel_check = DEFAULT_LD_TEXTREL_CHECK; link_info.emit_hash = DEFAULT_EMIT_SYSV_HASH; link_info.emit_gnu_hash = DEFAULT_EMIT_GNU_HASH; diff --git a/ld/ldmain.h b/ld/ldmain.h index dda124b96e8..f03ea59daea 100644 --- a/ld/ldmain.h +++ b/ld/ldmain.h @@ -56,6 +56,8 @@ extern char *error_handling_script; do { link_info.disable_target_specific_optimizations = 2; } while (0) #define ENABLE_RELAXATION \ do { link_info.disable_target_specific_optimizations = 0; } while (0) +#define ENABLE_TP_AS_GP \ + do { link_info.tp_as_gp = true; } while (0) extern void add_ysym (const char *); extern void add_wrap (const char *); diff --git a/ld/lexsup.c b/ld/lexsup.c index fe8722313fe..eaa126475ba 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -457,6 +457,8 @@ static const struct ld_option ld_options[] = '\0', NULL, N_("Reduce code size by using target specific optimizations"), TWO_DASHES }, { {"no-relax", no_argument, NULL, OPTION_NO_RELAX}, '\0', NULL, N_("Do not use relaxation techniques to reduce code size"), TWO_DASHES }, + { {"tp-as-gp", no_argument, NULL, OPTION_RELAX_TP_AS_GP}, + '\0', NULL, N_("Use tp as gp when there is no multithreaded scenario that requires the tp"), TWO_DASHES }, { {"retain-symbols-file", required_argument, NULL, OPTION_RETAIN_SYMBOLS_FILE}, '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES }, @@ -1286,6 +1288,9 @@ parse_args (unsigned argc, char **argv) case OPTION_RELAX: ENABLE_RELAXATION; break; + case OPTION_RELAX_TP_AS_GP: + ENABLE_TP_AS_GP; + break; case OPTION_RETAIN_SYMBOLS_FILE: add_keepsyms_file (optarg); break; diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 947a266ba72..45a1d7e487e 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -124,6 +124,7 @@ if [istarget "riscv*-*-*"] { run_dump_test "pcgp-relax-01" run_dump_test "pcgp-relax-01-norelaxgp" run_dump_test "pcgp-relax-02" + run_dump_test "tp_as_gp" run_dump_test "c-lui" run_dump_test "c-lui-2" run_dump_test "disas-jalr" diff --git a/ld/testsuite/ld-riscv-elf/tp_as_gp.d b/ld/testsuite/ld-riscv-elf/tp_as_gp.d new file mode 100644 index 00000000000..51b2e141e63 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/tp_as_gp.d @@ -0,0 +1,14 @@ +#source: tp_as_gp.s +#as: +#ld: --relax --tp-as-gp +#objdump: -d + + +.*:[ ]+file format .* + +Disassembly of section \.text: + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+lui[ ]+a5,.* +.*:[ ]+[0-9a-f]+[ ]+add[ ]+a5,a5,[0-9]+ # [0-9a-f]+ +.*:[ ]+[0-9a-f]+[ ]+add[ ]+a5,tp,\-[0-9]+ # [0-9a-f]+ .* \ No newline at end of file diff --git a/ld/testsuite/ld-riscv-elf/tp_as_gp.s b/ld/testsuite/ld-riscv-elf/tp_as_gp.s new file mode 100644 index 00000000000..6d723b6a14b --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/tp_as_gp.s @@ -0,0 +1,33 @@ + .option nopic + .attribute arch, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0" + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .text + + .globl global_array + .bss + .align 3 + .type global_array, @object + .size global_array, 5600 +global_array: + .zero 5600 + + .globl global_array2 + .bss + .align 3 + .type global_array3, @object + .size global_array3, 200 +global_array2: + .zero 200 + + .text + .align 1 + .globl _start + .type _start, @function +_start: + lui a5,%hi(global_array) + addi a5,a5,%lo(global_array) + + lui a5,%hi(global_array2) + addi a5,a5,%lo(global_array2) +