Mips built-in functions are currently not marked as pure, which
invalidates pointers across built-in function calls. If a pointer is
alive across built-in call, dereferencing it before and after the call
will generate two load instructions instead of one.
This marks the built-ins as pure, which removes the unnecessary load.
Tested on mips-mti-linux-gnu.
gcc/ChangeLog:
* config/mips/mips.c (DIRECT_BUILTIN_PURE): New macro. Add a
pure qualifier to the built-in.
(MSA_BUILTIN_PURE): New macro. Add a pure qualifier to the MSA
built-ins.
(struct mips_builtin_description): Add is_pure flag.
(mips_init_builtins): Mark built-in as pure if the flag in the
corresponding mips_builtin_description struct is set.
gcc/testsuite/ChangeLog:
* gcc.target/mips/mips-builtins-pure.c: New test.
---
gcc/config/mips/mips.c | 1306 ++--
gcc/testsuite/gcc.target/mips/mips-builtins-pure.c | 20 +
2 files changed, 684 insertions(+), 642 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/mips/mips-builtins-pure.c
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 3a77097..e337b82 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -15242,6 +15242,9 @@ struct mips_builtin_description {
/* Whether the function is available. */
unsigned int (*avail) (void);
+
+ /* Whether the function is pure. */
+ bool is_pure;
};
AVAIL_ALL (hard_float, TARGET_HARD_FLOAT_ABI)
@@ -15273,24 +15276,33 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA)
AVAIL is the name of the availability predicate, without the leading
mips_builtin_avail_. */
#define MIPS_BUILTIN(INSN, COND, NAME, BUILTIN_TYPE, \
-FUNCTION_TYPE, AVAIL) \
+FUNCTION_TYPE, AVAIL, PURE)\
{ CODE_FOR_mips_ ## INSN, MIPS_FP_COND_ ## COND, \
"__builtin_mips_" NAME, BUILTIN_TYPE, FUNCTION_TYPE, \
-mips_builtin_avail_ ## AVAIL }
+mips_builtin_avail_ ## AVAIL, PURE }
/* Define __builtin_mips_, which is a MIPS_BUILTIN_DIRECT function
mapped to instruction CODE_FOR_mips_, FUNCTION_TYPE and AVAIL
are as for MIPS_BUILTIN. */
#define DIRECT_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \
- MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, AVAIL)
+ MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE,\
+ AVAIL, false)
+
+/* Define __builtin_mips_, which is a MIPS_BUILTIN_DIRECT pure function
+ mapped to instruction CODE_FOR_mips_, FUNCTION_TYPE and AVAIL
+ are as for MIPS_BUILTIN. */
+#define DIRECT_BUILTIN_PURE(INSN, FUNCTION_TYPE, AVAIL)\
+ MIPS_BUILTIN (INSN, f, #INSN, MIPS_BUILTIN_DIRECT, FUNCTION_TYPE,\
+ AVAIL, true)
/* Define __builtin_mips___{s,d} functions, both of which
are subject to mips_builtin_avail_. */
#define CMP_SCALAR_BUILTINS(INSN, COND, AVAIL) \
MIPS_BUILTIN (INSN ## _cond_s, COND, #INSN "_" #COND "_s", \
- MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, AVAIL), \
+ MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_SF_SF, AVAIL, \
+ false), \
MIPS_BUILTIN (INSN ## _cond_d, COND, #INSN "_" #COND "_d", \
- MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, AVAIL)
+ MIPS_BUILTIN_CMP_SINGLE, MIPS_INT_FTYPE_DF_DF, AVAIL, false)
/* Define __builtin_mips_{any,all,upper,lower}___ps.
The lower and upper forms are subject to mips_builtin_avail_
@@ -15298,36 +15310,36 @@ AVAIL_NON_MIPS16 (msa, TARGET_MSA)
#define CMP_PS_BUILTINS(INSN, COND, AVAIL) \
MIPS_BUILTIN (INSN ## _cond_ps, COND, "any_" #INSN "_" #COND "_ps", \
MIPS_BUILTIN_CMP_ANY, MIPS_INT_FTYPE_V2SF_V2SF, \
- mips3d),\
+ mips3d, false), \
MIPS_BUILTIN (INSN ## _cond_ps, COND, "all_" #INSN "_" #COND "_ps", \
MIPS_BUILTIN_CMP_ALL, MIPS_INT_FTYPE_V2SF_V2SF, \
- mips3d),\
+ mips3d, false), \
MIPS_BUILTIN (INSN ## _cond_ps, COND, "lower_" #INSN "_" #COND "_ps",
\
MIPS_BUILTIN_CMP_LOWER, MIPS_INT_FTYPE_V2SF_V2SF, \
- AVAIL), \
+ AVAIL, false), \
MIPS_BUILTIN (INSN ## _cond_ps, COND, "upper_" #INSN "_" #COND "_ps",
\
MIPS_BUILTIN_CMP_UPPER, MIPS_INT_FTYPE_V2SF_V2SF, \
- AVAIL)
+ AVAIL, false)
/* Define __builtin_mips_{a