public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4849] LoongArch: Use explicit relocs for GOT access when -mexplicit-relocs=auto and LTO during a final lin
@ 2023-10-23  7:31 Xi Ruoyao
  0 siblings, 0 replies; only message in thread
From: Xi Ruoyao @ 2023-10-23  7:31 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:8811630df88bccfab232f8ab7da4bb43b70fa9de

commit r14-4849-g8811630df88bccfab232f8ab7da4bb43b70fa9de
Author: Xi Ruoyao <xry111@xry111.site>
Date:   Sat Sep 30 18:46:28 2023 +0800

    LoongArch: Use explicit relocs for GOT access when -mexplicit-relocs=auto and LTO during a final link with linker plugin
    
    If we are performing LTO for a final link and linker plugin is enabled,
    then we are sure any GOT access may resolve to a symbol out of the link
    unit (otherwise the linker plugin will tell us the symbol should be
    resolved locally and we'll use PC-relative access instead).
    
    Produce machine instructions with explicit relocs instead of la.global
    for better scheduling.
    
    gcc/ChangeLog:
    
            * config/loongarch/loongarch-protos.h
            (loongarch_explicit_relocs_p): Declare new function.
            * config/loongarch/loongarch.cc (loongarch_explicit_relocs_p):
            Implement.
            (loongarch_symbol_insns): Call loongarch_explicit_relocs_p for
            SYMBOL_GOT_DISP, instead of using TARGET_EXPLICIT_RELOCS.
            (loongarch_split_symbol): Call loongarch_explicit_relocs_p for
            deciding if return early, instead of using
            TARGET_EXPLICIT_RELOCS.
            (loongarch_output_move): CAll loongarch_explicit_relocs_p
            instead of using TARGET_EXPLICIT_RELOCS.
            * config/loongarch/loongarch.md (*low<mode>): Remove
            TARGET_EXPLICIT_RELOCS from insn condition.
            (@ld_from_got<mode>): Likewise.
            * config/loongarch/predicates.md (move_operand): Call
            loongarch_explicit_relocs_p instead of using
            TARGET_EXPLICIT_RELOCS.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/loongarch/explicit-relocs-auto-lto.c: New test.

Diff:
---
 gcc/config/loongarch/loongarch-protos.h            |  1 +
 gcc/config/loongarch/loongarch.cc                  | 34 +++++++++++++++++-----
 gcc/config/loongarch/loongarch.md                  |  4 +--
 gcc/config/loongarch/predicates.md                 |  8 ++---
 .../loongarch/explicit-relocs-auto-lto.c           | 26 +++++++++++++++++
 5 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h
index 72ae9918b096..cb8fc36b0863 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -220,4 +220,5 @@ extern rtx loongarch_gen_const_int_vector_shuffle (machine_mode, int);
 extern tree loongarch_build_builtin_va_list (void);
 
 extern rtx loongarch_build_signbit_mask (machine_mode, bool, bool);
+extern bool loongarch_explicit_relocs_p (enum loongarch_symbol_type);
 #endif /* ! GCC_LOONGARCH_PROTOS_H */
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 5df8b12ed921..c12d77ea1449 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1925,6 +1925,29 @@ loongarch_symbolic_constant_p (rtx x, enum loongarch_symbol_type *symbol_type)
   gcc_unreachable ();
 }
 
+/* If -mexplicit-relocs=auto, we use machine operations with reloc hints
+   for cases where the linker is unable to relax so we can schedule the
+   machine operations, otherwise use an assembler pseudo-op so the
+   assembler will generate R_LARCH_RELAX.  */
+
+bool
+loongarch_explicit_relocs_p (enum loongarch_symbol_type type)
+{
+  if (la_opt_explicit_relocs != EXPLICIT_RELOCS_AUTO)
+    return la_opt_explicit_relocs == EXPLICIT_RELOCS_ALWAYS;
+
+  /* If we are performing LTO for a final link, and we have the linker
+     plugin so we know the resolution of the symbols, then all GOT
+     references are binding to external symbols or preemptable symbols.
+     So the linker cannot relax them.  */
+  return (in_lto_p
+	  && !flag_incremental_link
+	  && HAVE_LTO_PLUGIN == 2
+	  && (!global_options_set.x_flag_use_linker_plugin
+	      || global_options.x_flag_use_linker_plugin)
+	  && type == SYMBOL_GOT_DISP);
+}
+
 /* Returns the number of instructions necessary to reference a symbol.  */
 
 static int
@@ -1940,7 +1963,7 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode)
     case SYMBOL_GOT_DISP:
       /* The constant will have to be loaded from the GOT before it
 	 is used in an address.  */
-      if (!TARGET_EXPLICIT_RELOCS && mode != MAX_MACHINE_MODE)
+      if (!loongarch_explicit_relocs_p (type) && mode != MAX_MACHINE_MODE)
 	return 0;
 
       return 3;
@@ -3038,7 +3061,7 @@ loongarch_symbol_extreme_p (enum loongarch_symbol_type type)
    If so, and if LOW_OUT is nonnull, emit the high part and store the
    low part in *LOW_OUT.  Leave *LOW_OUT unchanged otherwise.
 
-   Return false if build with '-mno-explicit-relocs'.
+   Return false if build with '-mexplicit-relocs=none'.
 
    TEMP is as for loongarch_force_temporary and is used to load the high
    part into a register.
@@ -3052,12 +3075,9 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
 {
   enum loongarch_symbol_type symbol_type;
 
-  /* If build with '-mno-explicit-relocs', don't split symbol.  */
-  if (!TARGET_EXPLICIT_RELOCS)
-    return false;
-
   if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE)
       || !loongarch_symbolic_constant_p (addr, &symbol_type)
+      || !loongarch_explicit_relocs_p (symbol_type)
       || loongarch_symbol_insns (symbol_type, mode) == 0
       || !loongarch_split_symbol_type (symbol_type))
     return false;
@@ -4797,7 +4817,7 @@ loongarch_output_move (rtx dest, rtx src)
 	}
     }
 
-  if (!TARGET_EXPLICIT_RELOCS
+  if (!loongarch_explicit_relocs_p (loongarch_classify_symbol (src))
       && dest_code == REG && symbolic_operand (src, VOIDmode))
     {
       if (loongarch_classify_symbol (src) == SYMBOL_PCREL)
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 365b4127e31e..bec73f1bc916 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -2247,7 +2247,7 @@
   [(set (match_operand:P 0 "register_operand" "=r")
  (lo_sum:P (match_operand:P 1 "register_operand" " r")
      (match_operand:P 2 "symbolic_operand" "")))]
-  "TARGET_EXPLICIT_RELOCS"
+  ""
   "addi.<d>\t%0,%1,%L2"
   [(set_attr "type" "arith")
    (set_attr "mode" "<MODE>")])
@@ -2275,7 +2275,7 @@
 				(match_operand:P 1 "register_operand" "r")
 				(match_operand:P 2 "symbolic_operand")))]
 	UNSPEC_LOAD_FROM_GOT))]
-  "TARGET_EXPLICIT_RELOCS"
+  ""
   "ld.<d>\t%0,%1,%L2"
   [(set_attr "type" "move")]
 )
diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md
index 499518b82ba6..359878f5bcf2 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -541,16 +541,14 @@
     case SYMBOL_REF:
     case LABEL_REF:
       return (loongarch_symbolic_constant_p (op, &symbol_type)
-	      && (!TARGET_EXPLICIT_RELOCS
+	      && (!loongarch_explicit_relocs_p (symbol_type)
 		  || !loongarch_split_symbol_type (symbol_type)));
 
     case HIGH:
-      /* '-mno-explicit-relocs' don't generate high/low pairs.  */
-      if (!TARGET_EXPLICIT_RELOCS)
-	return false;
-
       op = XEXP (op, 0);
+
       return (loongarch_symbolic_constant_p (op, &symbol_type)
+	      && loongarch_explicit_relocs_p (symbol_type)
 	      && loongarch_split_symbol_type (symbol_type));
 
     default:
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c
new file mode 100644
index 000000000000..f53b54689242
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-lto.c
@@ -0,0 +1,26 @@
+/* { dg-do link } */
+/* { dg-require-effective-target lto } */
+/* { dg-require-linker-plugin "" } */
+/* { dg-options "-fpic -shared -O2 --save-temps -mexplicit-relocs=auto -flto -fuse-linker-plugin -flto-partition=one" } */
+
+int pcrel __attribute__ ((visibility ("hidden")));
+int got __attribute__ ((visibility ("default")));
+
+int
+*addr_pcrel (void)
+{
+  return &pcrel;
+}
+
+int
+*addr_got (void)
+{
+  return &got;
+}
+
+/* With linker plugin we should use la.local (it can be relaxed to pcaddi),
+   but not la.global (we are pretty sure the linker cannot relax la.global
+   got).  */
+/* { dg-final { scan-lto-assembler "la.local.*pcrel" } } */
+/* { dg-final { scan-lto-assembler "pcalau12i.*%got_pc_hi20\\\(got\\\)" } } */
+/* { dg-final { scan-lto-assembler "ld.*%got_pc_lo12\\\(got\\\)" } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-10-23  7:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-23  7:31 [gcc r14-4849] LoongArch: Use explicit relocs for GOT access when -mexplicit-relocs=auto and LTO during a final lin Xi Ruoyao

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).