diff options
author | YunQiang Su <syq@gcc.gnu.org> | 2024-01-15 09:28:51 +0800 |
---|---|---|
committer | YunQiang Su <syq@gcc.gnu.org> | 2024-01-17 10:38:04 +0800 |
commit | b503c8787503943c2738058828c3d0037d024fea (patch) | |
tree | 92267127e89b8e0b5f4d32507f4350a150a6b5ba /gcc | |
parent | fce3f51f9c252c2650b2bf90401c72cda0eae088 (diff) | |
download | gcc-b503c8787503943c2738058828c3d0037d024fea.zip gcc-b503c8787503943c2738058828c3d0037d024fea.tar.gz gcc-b503c8787503943c2738058828c3d0037d024fea.tar.bz2 |
MIPS: avoid $gp store if global_pointer is not $gp
$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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/mips/mips.cc | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/mips.exp | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c | 11 |
4 files changed, 25 insertions, 0 deletions
diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index e752019..30e9981 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -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; diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 9f8d533..e028bc9 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -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 index 0000000..3f52fc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c @@ -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 index 0000000..631409c --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c @@ -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," } } */ |