public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Patrick O'Neill <patrick@rivosinc.com>
To: binutils@sourceware.org
Cc: kito.cheng@gmail.com, palmer@dabbelt.com,
	gnu-toolchain@rivosinc.com,
	Patrick O'Neill <patrick@rivosinc.com>
Subject: [PATCH v2 2/5] RISCV: Arrange DELETE pass after .align pass
Date: Mon,  2 May 2022 06:50:45 -0700	[thread overview]
Message-ID: <20220502135048.1392596-3-patrick@rivosinc.com> (raw)
In-Reply-To: <20220502135048.1392596-1-patrick@rivosinc.com>

By moving the deletion pass after the align pass, the linker can touch
each byte once via piecewise deletion. Otherwise, it may need to move
the same bytes twice.

2022-04-29 Patrick O'Neill <patrick@rivosinc.com>

	* elfnn-riscv.c (_bfd_riscv_relax_align): Count to-be-deleted
	  bytes so the alignments are still accurate.
	* elfnn-riscv.c (_bfd_riscv_relax_section): Move DELETE pass
	  after ALIGN pass.

Signed-off-by: Patrick O'Neill <patrick@rivosinc.com>
---
This gives us an O(n^2) runtime when the align pass counts the number of 
deleted bytes preceding it, but this will be fixed in Patch 4/5.
---
 bfd/elfnn-riscv.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 8f9f0d8a86a..17f9607744f 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4435,7 +4435,7 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 static bool
 _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			asection *sym_sec,
-			struct bfd_link_info *link_info,
+			struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			bfd_vma max_alignment ATTRIBUTE_UNUSED,
@@ -4449,6 +4449,18 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
   while (alignment <= rel->r_addend)
     alignment *= 2;
 
+  Elf_Internal_Rela *relocs = elf_section_data (sec)->relocs;
+  for (unsigned int i = 0; i < sec->reloc_count; i++)
+    {
+      Elf_Internal_Rela *reloc = relocs + i;
+      /* Ignore annotations after this alignment directive.  */
+      if (reloc == rel)
+	break;
+      /* Account for to-be-deleted bytes  */
+      else if (ELFNN_R_TYPE (reloc->r_info) == R_RISCV_DELETE)
+	symval -= reloc->r_addend;
+    }
+
   symval -= rel->r_addend;
   bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
   bfd_vma nop_bytes = aligned_addr - symval;
@@ -4468,12 +4480,12 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
       return false;
     }
 
-  /* Delete the reloc.  */
-  rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
-
-  /* If the number of NOPs is already correct, there's nothing to do.  */
+  /* If the number of NOPs is already correct, delete the reloc.  */
   if (nop_bytes == rel->r_addend)
-    return true;
+    {
+      rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+      return true;
+    }
 
   /* Write as many RISC-V NOPs as we need.  */
   for (pos = 0; pos < (nop_bytes & -4); pos += 4)
@@ -4483,10 +4495,11 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
   if (nop_bytes % 4 != 0)
     bfd_putl16 (RVC_NOP, contents + rel->r_offset + pos);
 
-  /* Delete the excess bytes.  */
-  return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
-				   rel->r_addend - nop_bytes, link_info,
-				   NULL);
+  /* Mark the excess bytes for deletion.  */
+  rel->r_info = ELFNN_R_INFO (0, R_RISCV_DELETE);
+  rel->r_addend = rel->r_addend - nop_bytes;
+  rel->r_offset = rel->r_offset + nop_bytes;
+  return true;
 }
 
 /* Relax PC-relative references to GP-relative references.  */
@@ -4677,8 +4690,8 @@ bfd_elfNN_riscv_set_data_segment_info (struct bfd_link_info *info,
 /* Relax a section.
 
    Pass 0: Shortens code sequences for LUI/CALL/TPREL/PCREL relocs.
-   Pass 1: Deletes the bytes that PCREL relaxation in pass 0 made obsolete.
-   Pass 2: Which cannot be disabled, handles code alignment directives.  */
+   Pass 1: Which cannot be disabled, handles code alignment directives.
+   Pass 2: Handle DELETE directives.  */
 
 static bool
 _bfd_riscv_relax_section (bfd *abfd, asection *sec,
@@ -4697,7 +4710,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   *again = false;
 
   if (bfd_link_relocatable (info)
-      || sec->sec_flg0
+      || (sec->sec_flg0 && info->relax_pass == 0)
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (info->disable_target_specific_optimizations
@@ -4771,10 +4784,10 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  /* Skip over the R_RISCV_RELAX.  */
 	  i++;
 	}
-      else if (info->relax_pass == 1 && type == R_RISCV_DELETE)
-	relax_func = _bfd_riscv_relax_delete;
-      else if (info->relax_pass == 2 && type == R_RISCV_ALIGN)
+      else if (info->relax_pass == 1 && type == R_RISCV_ALIGN)
 	relax_func = _bfd_riscv_relax_align;
+      else if (info->relax_pass == 2 && type == R_RISCV_DELETE)
+	relax_func = _bfd_riscv_relax_delete;
       else
 	continue;
 
-- 
2.25.1


  parent reply	other threads:[~2022-05-02 13:51 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-12 16:25 [PATCH 0/4] RISCV: Improve linker time complexity Patrick O'Neill
2022-04-12 16:25 ` [PATCH 1/4] RISCV: Add linker relaxation tests Patrick O'Neill
2022-04-12 16:25 ` [PATCH 2/4] RISCV: Arrange DELETE pass after .align pass Patrick O'Neill
2022-04-12 16:26 ` [PATCH 3/4] RISCV: Implement piecewise deletion Patrick O'Neill
2022-04-12 16:26 ` [PATCH 4/4] RISCV: Improve runtime of align directives Patrick O'Neill
2022-04-13  0:58 ` [PATCH 0/4] RISCV: Improve linker time complexity Kito Cheng
2022-04-13  2:23   ` Palmer Dabbelt
2022-04-13  5:12   ` Alan Modra
2022-04-13 18:11     ` Palmer Dabbelt
2022-04-25 17:26       ` Patrick O'Neill
2022-05-02 13:50 ` [PATCH v2 0/5] " Patrick O'Neill
2022-05-02 13:50   ` [PATCH v2 1/5] RISCV: Add linker relaxation tests Patrick O'Neill
2022-05-02 13:50   ` Patrick O'Neill [this message]
2022-05-02 13:50   ` [PATCH v2 3/5] RISCV: Implement piecewise deletion Patrick O'Neill
2022-05-20 10:48     ` Nelson Chu
2022-05-20 17:36       ` Patrick O'Neill
2022-05-02 13:50   ` [PATCH v2 4/5] RISCV: Improve runtime of align directives Patrick O'Neill
2022-05-02 13:50   ` [PATCH v2 5/5] RISCV: Add --defer-deletion flag Patrick O'Neill
2022-05-27 21:20   ` [PATCH v3 0/3] RISCV: Improve linker time complexity Patrick O'Neill
2022-05-27 21:20     ` [PATCH v3 1/3] RISCV: Add linker relaxation tests Patrick O'Neill
2022-05-27 21:20     ` [PATCH v3 2/3] RISCV: Implement piecewise deletion Patrick O'Neill
2022-05-27 21:20     ` [PATCH v3 3/3] RISCV: Add --defer-deletion flag Patrick O'Neill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220502135048.1392596-3-patrick@rivosinc.com \
    --to=patrick@rivosinc.com \
    --cc=binutils@sourceware.org \
    --cc=gnu-toolchain@rivosinc.com \
    --cc=kito.cheng@gmail.com \
    --cc=palmer@dabbelt.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).