public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Add a general mapping from internal fns to target insns
@ 2022-06-16 13:46 Richard Sandiford
  0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2022-06-16 13:46 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:591ff342cc05c6e3b7ab6ca972c701d78676b135

commit 591ff342cc05c6e3b7ab6ca972c701d78676b135
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Thu Jun 16 14:42:40 2022 +0100

    Add a general mapping from internal fns to target insns
    
    IFN_CAP_GLOBAL_DATA_GET maps directly to an instruction defined in
    target-insns.def.  This patch makes it easier to define more such
    functions in future.
    
    This should help to reduce cut-&-paste, but more importantly, it allows
    the difference between optab functions and target-insns.def functions
    to be abstracted away; both are now treated as “directly-mapped”.

Diff:
---
 gcc/internal-fn.c   | 88 +++++++++++++++++++++++++++++++----------------------
 gcc/internal-fn.def | 15 ++++++++-
 gcc/internal-fn.h   | 20 ++++++------
 3 files changed, 76 insertions(+), 47 deletions(-)

diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index f203bb3944b..93c6c76f4be 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -100,38 +100,45 @@ init_internal_fns ()
 
 /* Create static initializers for the information returned by
    direct_internal_fn.  */
-#define not_direct { -2, -2, false }
-#define mask_load_direct { -1, 2, false }
-#define load_lanes_direct { -1, -1, false }
-#define mask_load_lanes_direct { -1, -1, false }
-#define gather_load_direct { 3, 1, false }
-#define len_load_direct { -1, -1, false }
-#define mask_store_direct { 3, 2, false }
-#define store_lanes_direct { 0, 0, false }
-#define mask_store_lanes_direct { 0, 0, false }
-#define vec_cond_mask_direct { 0, 0, false }
-#define vec_cond_direct { 0, 0, false }
-#define vec_condu_direct { 0, 0, false }
-#define vec_condeq_direct { 0, 0, false }
-#define scatter_store_direct { 3, 1, false }
-#define len_store_direct { 3, 3, false }
-#define unary_direct { 0, 0, true }
-#define binary_direct { 0, 0, true }
-#define ternary_direct { 0, 0, true }
-#define cond_unary_direct { 1, 1, true }
-#define cond_binary_direct { 1, 1, true }
-#define cond_ternary_direct { 1, 1, true }
-#define while_direct { 0, 2, false }
-#define fold_extract_direct { 2, 2, false }
-#define fold_left_direct { 1, 1, false }
-#define mask_fold_left_direct { 1, 1, false }
-#define check_ptrs_direct { 0, 0, false }
+#define not_direct			{ -2, -2, false, false }
+#define direct_insn			{ -2, -2, true, false }
+#define optab1(TYPE0)			{ TYPE0, TYPE0, true, false }
+#define optab2(TYPE0, TYPE1)		{ TYPE0, TYPE1, true, false }
+#define vectorizable_optab1(TYPE0)	{ TYPE0, TYPE0, true, true }
+
+#define mask_load_direct		optab2 (-1, 2)
+#define load_lanes_direct		optab1 (-1)
+#define mask_load_lanes_direct		optab1 (-1)
+#define gather_load_direct		optab2 (3, 1)
+#define len_load_direct			optab1 (-1)
+#define mask_store_direct		optab2 (3, 2)
+#define store_lanes_direct		optab1 (0)
+#define mask_store_lanes_direct		optab1 (0)
+#define vec_cond_mask_direct		optab1 (0)
+#define vec_cond_direct			optab1 (0)
+#define vec_condu_direct		optab1 (0)
+#define vec_condeq_direct		optab1 (0)
+#define scatter_store_direct		optab2 (3, 1)
+#define len_store_direct		optab1 (3)
+#define unary_direct			vectorizable_optab1 (0)
+#define binary_direct			vectorizable_optab1 (0)
+#define ternary_direct			vectorizable_optab1 (0)
+#define cond_unary_direct		vectorizable_optab1 (1)
+#define cond_binary_direct		vectorizable_optab1 (1)
+#define cond_ternary_direct		vectorizable_optab1 (1)
+#define while_direct			optab2 (0, 2)
+#define fold_extract_direct		optab1 (2)
+#define fold_left_direct		optab1 (1)
+#define mask_fold_left_direct		optab1 (1)
+#define check_ptrs_direct		optab1 (0)
 
 const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
 #define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
 #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
 				     UNSIGNED_OPTAB, TYPE) TYPE##_direct,
+#define DEF_INTERNAL_INSN_FN(CODE, FLAGS, INSN, NOUTPUTS, NINPUTS) \
+  direct_insn,
 #include "internal-fn.def"
   not_direct
 };
@@ -3104,17 +3111,6 @@ expand_REPLACE_ADDRESS_VALUE (internal_fn, gcall *gc)
 }
 
 
-/* Expand CAP_GLOBAL_DATA_GET internal function.
-   This takes no parameters and returns only the value of the target's default
-   global capability.  */
-
-static void
-expand_CAP_GLOBAL_DATA_GET (internal_fn, gcall *stmt)
-{
-  gcc_assert (targetm.have_cap_global_data_get ());
-  expand_fn_using_insn (stmt, targetm.code_for_cap_global_data_get, 1, 0);
-}
-
 /* Expand a NOP.  */
 
 static void
@@ -3231,6 +3227,10 @@ tree_pair
 direct_internal_fn_types (internal_fn fn, tree return_type, tree *args)
 {
   const direct_internal_fn_info &info = direct_internal_fn (fn);
+  if (info.type0 == -2)
+    /* Functions created by DEF_INTERNAL_INSN_FN are not type-dependent.  */
+    return tree_pair {};
+
   tree type0 = (info.type0 < 0 ? return_type : TREE_TYPE (args[info.type0]));
   tree type1 = (info.type1 < 0 ? return_type : TREE_TYPE (args[info.type1]));
   return tree_pair (type0, type1);
@@ -3244,6 +3244,10 @@ tree_pair
 direct_internal_fn_types (internal_fn fn, gcall *call)
 {
   const direct_internal_fn_info &info = direct_internal_fn (fn);
+  if (info.type0 == -2)
+    /* Functions created by DEF_INTERNAL_INSN_FN are not type-dependent.  */
+    return tree_pair {};
+
   tree op0 = (info.type0 < 0
 	      ? gimple_call_lhs (call)
 	      : gimple_call_arg (call, info.type0));
@@ -3406,6 +3410,8 @@ direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
 	return direct_##TYPE##_optab_supported_p (which_optab, types,	\
 						  opt_type);		\
       }
+#define DEF_INTERNAL_INSN_FN(CODE, FLAGS, INSN, NOUTPUTS, NINPUTS) \
+    case IFN_##CODE: return targetm.have_##INSN ();
 #include "internal-fn.def"
 
     case IFN_LAST:
@@ -3503,6 +3509,14 @@ set_edom_supported_p (void)
     optab which_optab = direct_internal_fn_optab (fn, types);		\
     expand_##TYPE##_optab_fn (fn, stmt, which_optab);			\
   }
+#define DEF_INTERNAL_INSN_FN(CODE, FLAGS, INSN, NOUTPUTS, NINPUTS)	\
+  static void								\
+  expand_##CODE (internal_fn, gcall *stmt)				\
+  {									\
+    gcc_assert (targetm.have_##INSN ());				\
+    expand_fn_using_insn (stmt, targetm.code_for_##INSN,		\
+			  NOUTPUTS, NINPUTS);				\
+  }
 #include "internal-fn.def"
 
 /* Routines to expand each internal function, indexed by function number.
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 2b54f15dfc6..e5a9d0c0aef 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 				   UNSIGNED_OPTAB, TYPE)
      DEF_INTERNAL_FLT_FN (NAME, FLAGS, OPTAB, TYPE)
      DEF_INTERNAL_INT_FN (NAME, FLAGS, OPTAB, TYPE)
+     DEF_INTERNAL_INSN_FN (NAME, FLAGS, INSN, NOUTPUTS, NINPUTS)
 
    where NAME is the name of the function, FLAGS is a set of
    ECF_* flags and FNSPEC is a string describing functions fnspec.
@@ -82,6 +83,11 @@ along with GCC; see the file COPYING3.  If not see
    says that the function extends the C-level BUILT_IN_<NAME>{,L,LL,IMAX}
    group of functions to any integral mode (including vector modes).
 
+   DEF_INTERNAL_INSN_FN defines an internal function that maps to target
+   instruction INSN, which is one of those defined in target-insns.def.
+   The instruction has NOUTPUTS output operands (either 0 or 1) and
+   NINPUTS input operands.
+
    Each entry must have a corresponding expander of the form:
 
      void expand_NAME (gimple_call stmt)
@@ -120,6 +126,11 @@ along with GCC; see the file COPYING3.  If not see
   DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
 #endif
 
+#ifndef DEF_INTERNAL_INSN_FN
+#define DEF_INTERNAL_INSN_FN(NAME, FLAGS, INSN, NOUTPUTS, NINPUTS) \
+  DEF_INTERNAL_FN (NAME, FLAGS | ECF_LEAF, NULL)
+#endif
+
 DEF_INTERNAL_OPTAB_FN (MASK_LOAD, ECF_PURE, maskload, mask_load)
 DEF_INTERNAL_OPTAB_FN (LOAD_LANES, ECF_CONST, vec_load_lanes, load_lanes)
 DEF_INTERNAL_OPTAB_FN (MASK_LOAD_LANES, ECF_PURE,
@@ -396,7 +407,8 @@ DEF_INTERNAL_FN (CO_FRAME, ECF_PURE | ECF_NOTHROW | ECF_LEAF, NULL)
    dereferenced.  */
 DEF_INTERNAL_FN (REPLACE_ADDRESS_VALUE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, ".RR")
 
-DEF_INTERNAL_FN (CAP_GLOBAL_DATA_GET, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_INSN_FN (CAP_GLOBAL_DATA_GET, ECF_CONST | ECF_NOTHROW,
+		      cap_global_data_get, 1, 0)
 
 DEF_INTERNAL_OPTAB_FN (CAP_ADDRESS_GET, ECF_CONST | ECF_NOTHROW,
 		       cap_address_get, unary)
@@ -452,6 +464,7 @@ DEF_INTERNAL_OPTAB_FN (CAP_UNSEAL, ECF_CONST | ECF_NOTHROW,
 /* A NOP function with arbitrary arguments and return value.  */
 DEF_INTERNAL_FN (NOP, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 
+#undef DEF_INTERNAL_INSN_FN
 #undef DEF_INTERNAL_INT_FN
 #undef DEF_INTERNAL_FLT_FN
 #undef DEF_INTERNAL_FLT_FLOATN_FN
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index b75aac268c1..3f72d312010 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -129,7 +129,8 @@ internal_fn_fnspec (enum internal_fn fn)
   return internal_fn_fnspec_array[(int) fn];
 }
 
-/* Describes an internal function that maps directly to an optab.  */
+/* Describes an internal function that maps directly to either an optab
+   or an instruction defined in target-insns.def.  */
 struct direct_internal_fn_info
 {
   /* optabs can be parameterized by one or two modes.  These fields describe
@@ -140,24 +141,25 @@ struct direct_internal_fn_info
      function isn't directly mapped to an optab.  */
   signed int type0 : 8;
   signed int type1 : 8;
+  /* True if the function is directly mapped to either an optab or an
+     instruction defined in target-insns.def.  */
+  unsigned int directly_mapped : 1;
   /* True if the function is pointwise, so that it can be vectorized by
      converting the return type and all argument types to vectors of the
      same number of elements.  E.g. we can vectorize an IFN_SQRT on
-     floats as an IFN_SQRT on vectors of N floats.
-
-     This only needs 1 bit, but occupies the full 16 to ensure a nice
-     layout.  */
-  unsigned int vectorizable : 16;
+     floats as an IFN_SQRT on vectors of N floats.  */
+  unsigned int vectorizable : 1;
 };
 
 extern const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1];
 
-/* Return true if FN is mapped directly to an optab.  */
+/* Return true if FN is mapped directly to either an optab or an instruction
+   defined in target-insns.def.  */
 
 inline bool
 direct_internal_fn_p (internal_fn fn)
 {
-  return direct_internal_fn_array[fn].type0 >= -1;
+  return direct_internal_fn_array[fn].directly_mapped;
 }
 
 /* Return true if FN is a direct internal function that can be vectorized by
@@ -171,7 +173,7 @@ vectorizable_internal_fn_p (internal_fn fn)
   return direct_internal_fn_array[fn].vectorizable;
 }
 
-/* Return optab information about internal function FN.  Only meaningful
+/* Return information about internal function FN.  Only meaningful
    if direct_internal_fn_p (FN).  */
 
 inline const direct_internal_fn_info &


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

only message in thread, other threads:[~2022-06-16 13:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-16 13:46 [gcc(refs/vendors/ARM/heads/morello)] Add a general mapping from internal fns to target insns Richard Sandiford

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