[PATCH v3 3/3] RISCV: Add --defer-deletion flag
Patrick O'Neill
patrick@rivosinc.com
Fri May 27 21:20:05 GMT 2022
Previously the linker failed to relax only the backwards case (where a
relaxation enables another relaxation that has already been checked).
With patches 1-4, the behavior has been changed to fail in both the
forward and backwards case. It's possible that this will lead to worse
performance, so the --no-defer-deletion flag allows you to use the
non-linear immediate deletion method.
By default, the linear deletion method is enabled as this is expected to
be more performant.
2022-05-27 Patrick O'Neill <patrick@rivosinc.com>
* elfnn-riscv.c: Pass flag to deletion function to immediately
delete bytes (or not).
* bfdlink.h: Add delete_immediately flag.
* ld/ld.texi: Document the new --defer-deletion flag.
* ld/ldlex.h: Add DEFER_DELETION and NO_DEFER_DELETION options.
* ld/lexsup.c: Parse --defer-deletion and --no-defer-deletion
flags.
Signed-off-by: Patrick O'Neill <patrick@rivosinc.com>
---
I think that there may be a better way to phrase the --defer-deletion
flag. I'm also unsure if this is the correct way of expressing
a target-specific linker flag.
---
v2 Changelog:
- This is a new patch.
---
v3 Changelog:
- Rebase with changes to elfnn-riscv.c from patch 2/3.
---
bfd/elfnn-riscv.c | 12 ++++++++----
include/bfdlink.h | 4 ++++
ld/ld.texi | 10 ++++++++++
ld/ldlex.h | 2 ++
ld/lexsup.c | 10 ++++++++++
5 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4b6ea179442..0a750773d47 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4324,7 +4324,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
/* Delete unnecessary JALR. */
*again = true;
return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + len, 8 - len,
- rel + 1, link_info, pcgp_relocs, true);
+ rel + 1, link_info, pcgp_relocs,
+ !link_info->immediate_deletion);
}
/* Traverse all output sections and return the max alignment. */
@@ -4417,7 +4418,8 @@ _bfd_riscv_relax_lui (bfd *abfd,
/* We can delete the unnecessary LUI and reuse the reloc. */
*again = true;
return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, rel,
- link_info, pcgp_relocs, true);
+ link_info, pcgp_relocs,
+ !link_info->immediate_deletion);
default:
abort ();
@@ -4450,7 +4452,8 @@ _bfd_riscv_relax_lui (bfd *abfd,
*again = true;
return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + 2, 2, rel + 1,
- link_info, pcgp_relocs, true);
+ link_info, pcgp_relocs,
+ !link_info->immediate_deletion);
}
return true;
@@ -4492,7 +4495,8 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
*again = true;
return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, rel,
- link_info, pcgp_relocs, true);
+ link_info, pcgp_relocs,
+ !link_info->immediate_deletion);
default:
abort ();
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 09a3ec01685..f6c87fbe911 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -587,6 +587,10 @@ struct bfd_link_info
args_type structure in ldmain.c:main. */
signed int disable_target_specific_optimizations;
+ /* Enable or disable deferred deletion of linker relaxations.
+ This option is enabled my default. */
+ unsigned int immediate_deletion: 1;
+
/* Function callbacks. */
const struct bfd_link_callbacks *callbacks;
diff --git a/ld/ld.texi b/ld/ld.texi
index eabbec8faa9..c536eed4162 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -2186,6 +2186,16 @@ This option is ignored for Linux compatibility.
@item -Qy
This option is ignored for SVR4 compatibility.
+@cindex defer relaxation deletion
+@kindex --defer-relaxation-deletions
+@kindex --no-defer-relaxation-deletions
+@item --defer-relaxation-deletions
+@itemx --no-defer-relaxation-deletions
+Enable (or don't enable) linear time linker relaxations by deferring byte
+deletion. This assumes the pathologial case is rare. If the pathological case
+is common, disabling linear linking will improve performance.
+Default to linear time linker relaxation.
+
@kindex --relax
@cindex synthesizing linker
@cindex relaxing addressing modes
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 57ade1f754b..ce9f5d5aafe 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -54,6 +54,8 @@ enum option_values
OPTION_OFORMAT,
OPTION_RELAX,
OPTION_NO_RELAX,
+ OPTION_DEFER_DELETION,
+ OPTION_NO_DEFER_DELETION,
OPTION_NO_SYMBOLIC,
OPTION_RETAIN_SYMBOLS_FILE,
OPTION_RPATH,
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 9225f71b3ce..1a0d9a31fef 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -442,6 +442,10 @@ 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 },
+ { {"defer-deletion", no_argument, NULL, OPTION_DEFER_DELETION},
+ '\0', NULL, N_("Defer deletions caused by linker relaxation"), TWO_DASHES },
+ { {"no-defer-deletion", no_argument, NULL, OPTION_NO_DEFER_DELETION},
+ '\0', NULL, N_("Do not defer deletions caused by linker relaxation"), TWO_DASHES },
{ {"retain-symbols-file", required_argument, NULL,
OPTION_RETAIN_SYMBOLS_FILE},
'\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES },
@@ -935,6 +939,12 @@ parse_args (unsigned argc, char **argv)
case OPTION_NO_WARN_RWX_SEGMENTS:
link_info.no_warn_rwx_segments = 1;
break;
+ case OPTION_DEFER_DELETION:
+ link_info.immediate_deletion = false;
+ break;
+ case OPTION_NO_DEFER_DELETION:
+ link_info.immediate_deletion = true;
+ break;
case 'e':
lang_add_entry (optarg, true);
break;
--
2.25.1
More information about the Binutils
mailing list