]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
MIPS: avoid $gp store if global_pointer is not $gp
authorYunQiang Su <syq@gcc.gnu.org>
Mon, 15 Jan 2024 01:28:51 +0000 (09:28 +0800)
committerYunQiang Su <syq@gcc.gnu.org>
Wed, 17 Jan 2024 02:38:04 +0000 (10:38 +0800)
$GP is used for expanding GOT load, but in the afterward passes,
a temporary register is tried to replace $gp.

If sucess, we have no need to store and reload $gp. The example
of failure is that the function calls a preemtive function.

We shouldn't use $GP for any other purpose in the code we generate.
If a user's inline asm code clobbers $GP, it's their duty to save
and restore $GP.

gcc
* config/mips/mips.cc (mips_compute_frame_info): If another
register is used as global_pointer, mark $GP live false.

gcc/testsuite
* gcc.target/mips/mips.exp (mips_option_groups):
Add -mxgot/-mno-xgot options.
* gcc.target/mips/xgot-n32-avoid-gp.c: New test.
* gcc.target/mips/xgot-n32-need-gp.c: New test.

gcc/config/mips/mips.cc
gcc/testsuite/gcc.target/mips/mips.exp
gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c [new file with mode: 0644]

index e752019b5e27fbd101e89bf122e66ea4da17a95d..30e99811ff65ec19f55c01b196da4595de46642d 100644 (file)
@@ -11353,6 +11353,8 @@ mips_compute_frame_info (void)
      in, which is why the global_pointer field is initialised here and not
      earlier.  */
   cfun->machine->global_pointer = mips_global_pointer ();
+  if (cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM)
+    df_set_regs_ever_live (GLOBAL_POINTER_REGNUM, false);
 
   offset = frame->args_size + frame->cprestore_size;
 
index 9f8d533cfa57bbe8a4944096266b4f38837e2272..e028bc93b40fee7c2e64920a09ed054a385d862b 100644 (file)
@@ -266,6 +266,7 @@ set mips_option_groups {
     stack-protector "-fstack-protector"
     stdlib "REQUIRES_STDLIB"
     unaligned-access "-m(no-|)unaligned-access"
+    xgot "-m(no-|)xgot"
 }
 
 for { set option 0 } { $option < 32 } { incr option } {
diff --git a/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c b/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c
new file mode 100644 (file)
index 0000000..3f52fc5
--- /dev/null
@@ -0,0 +1,11 @@
+/* Check if we skip store and load gp if there is no stub function call.  */
+/* { dg-options "-mips64r2 -mxgot -mabi=n32 -fPIC" } */
+
+extern int a;
+int
+foo ()
+{
+  return a;
+}
+/* { dg-final { scan-assembler-not "\tsd\t\\\$28," } } */
+/* { dg-final { scan-assembler-not "\tld\t\\\$28," } } */
diff --git a/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c b/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c
new file mode 100644 (file)
index 0000000..631409c
--- /dev/null
@@ -0,0 +1,11 @@
+/* We cannot skip store and load gp if there is stub function call.  */
+/* { dg-options "-mips64r2 -mxgot -mabi=n32 -fPIC" } */
+
+extern int f();
+int
+foo ()
+{
+  return f();
+}
+/* { dg-final { scan-assembler "\tsd\t\\\$28," } } */
+/* { dg-final { scan-assembler "\tld\t\\\$28," } } */