diff mbox series

[SVE,ACLE] Two infrastructure tweaks

Message ID 87pnt47eoi.fsf@arm.com
State New
Headers show
Series [SVE,ACLE] Two infrastructure tweaks | expand

Commit Message

Richard Sandiford Jan. 10, 2019, 2:47 p.m. UTC
Hi,

The first patch replaces the autogenerated function enum with an
explicit one, so that we can have more than one .def entry with
the same function base name (e.g. predicated AND vs. integer AND).

The second patch makes us get the expected modes from the insn data,
rather than force callers to supply the modes explicitly.

Committed to aarch64/sve-acle-branch.

Richard
diff mbox series

Patch

[SVE ACLE] Get operand modes from insn_data

Specifying the modes of operands explicitly was getting awkward,
and getting the modes from the insn patterns still gives a decent
amount of sanity checking.


diff --git a/gcc/config/aarch64/aarch64-sve-builtins.c b/gcc/config/aarch64/aarch64-sve-builtins.c
index a439fb9358e..46ff17caf86 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.c
+++ b/gcc/config/aarch64/aarch64-sve-builtins.c
@@ -444,10 +444,10 @@  private:
 
   rtx expand_signed_pred_op (rtx_code, rtx_code, int);
   rtx expand_signed_pred_op (int, int, int);
-  rtx expand_via_unpred_direct_optab (optab, unsigned int = 0);
-  rtx expand_via_unpred_insn (insn_code, unsigned int = 0);
+  rtx expand_via_unpred_direct_optab (optab);
+  rtx expand_via_unpred_insn (insn_code);
   rtx expand_via_pred_direct_optab (optab, unsigned int = DEFAULT_MERGE_ARGNO);
-  rtx expand_via_sel_insn (insn_code, unsigned int);
+  rtx expand_via_sel_insn (insn_code);
   rtx expand_via_pred_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
   rtx expand_via_signed_unpred_insn (rtx_code, rtx_code);
   rtx expand_via_pred_x_insn (insn_code);
@@ -462,8 +462,9 @@  private:
   rtx get_fallback_value (machine_mode, unsigned int,
 			  unsigned int, unsigned int &);
 
-  void add_output_operand (machine_mode);
-  void add_input_operand (rtx, machine_mode);
+  machine_mode get_next_operand_mode (insn_code);
+  void add_output_operand (insn_code);
+  void add_input_operand (insn_code, rtx);
   void add_integer_operand (HOST_WIDE_INT);
   rtx generate_insn (insn_code);
 
@@ -1712,21 +1713,16 @@  function_expander::expand_dup ()
 {
   if (m_fi.pred == PRED_none
       || m_fi.pred == PRED_x)
-    return expand_via_unpred_direct_optab (vec_duplicate_optab, 1);
+    return expand_via_unpred_direct_optab (vec_duplicate_optab);
   else
     {
       insn_code icode;
       machine_mode mode = get_mode (0);
       if (valid_for_const_vector_p (GET_MODE_INNER (mode), m_args.last ()))
-	{
-	  icode = code_for_vcond_mask (get_mode (0), get_mode (0));
-	  return expand_via_sel_insn (icode, 0);
-	}
+	icode = code_for_vcond_mask (get_mode (0), get_mode (0));
       else
-	{
-	  icode = code_for_aarch64_sel_dup (get_mode (0));
-	  return expand_via_sel_insn (icode, 1);
-	}
+	icode = code_for_aarch64_sel_dup (get_mode (0));
+      return expand_via_sel_insn (icode);
     }
 }
 
@@ -1734,7 +1730,7 @@  function_expander::expand_dup ()
 rtx
 function_expander::expand_index ()
 {
-  return expand_via_unpred_direct_optab (vec_series_optab, 2);
+  return expand_via_unpred_direct_optab (vec_series_optab);
 }
 
 /* Expand a call to svmax.  */
@@ -1824,36 +1820,28 @@  function_expander::expand_sub (bool reversed_p)
 }
 
 /* Implement the call using optab OP, which is an unpredicated direct
-   (i.e. single-mode) optab.  The last NSCALAR inputs are scalar, and
-   map to scalar operands in the underlying instruction.  */
+   (i.e. single-mode) optab.  */
 rtx
-function_expander::expand_via_unpred_direct_optab (optab op,
-						   unsigned int nscalar)
+function_expander::expand_via_unpred_direct_optab (optab op)
 {
   machine_mode mode = get_mode (0);
   insn_code icode = direct_optab_handler (op, mode);
-  return expand_via_unpred_insn (icode, nscalar);
+  return expand_via_unpred_insn (icode);
 }
 
-/* Implement the call using instruction ICODE.  The last NSCALAR inputs
-   are scalar, and map to scalar operands in the underlying instruction.  */
+/* Implement the call using instruction ICODE.  */
 rtx
-function_expander::expand_via_unpred_insn (insn_code icode,
-					   unsigned int nscalar)
+function_expander::expand_via_unpred_insn (insn_code icode)
 {
   /* Discount the output operand.  */
   unsigned int nops = insn_data[icode].n_operands - 1;
   /* Drop the predicate argument in the case of _x predication.  */
   unsigned int bias = (m_fi.pred == PRED_x ? 1 : 0);
-  machine_mode mode = get_mode (0);
   unsigned int i = 0;
 
-  add_output_operand (mode);
-
-  for (; i < nops - nscalar; ++i)
-    add_input_operand (m_args[i + bias], mode);
+  add_output_operand (icode);
   for (; i < nops; ++i)
-    add_input_operand (m_args[i + bias], GET_MODE_INNER (mode));
+    add_input_operand (icode, m_args[i + bias]);
 
   return generate_insn (icode);
 }
@@ -1876,29 +1864,21 @@  function_expander::expand_via_pred_direct_optab (optab op,
    0: output
    1: true value
    2: false value
-   3: predicate
-
-   The last NSCALAR inputs are scalar, and map to scalar operands
-   in the underlying instruction.  */
+   3: predicate.  */
 rtx
-function_expander::expand_via_sel_insn (insn_code icode,
-					unsigned int nscalar)
+function_expander::expand_via_sel_insn (insn_code icode)
 {
   machine_mode mode = get_mode (0);
-  machine_mode pred_mode = get_pred_mode (0);
 
   unsigned int opno = 0;
   rtx false_arg = get_fallback_value (mode, 1, 0, opno);
   rtx pred_arg = m_args[opno++];
   rtx true_arg = m_args[opno++];
 
-  add_output_operand (mode);
-  if (nscalar)
-    add_input_operand (true_arg, GET_MODE_INNER (mode));
-  else
-    add_input_operand (true_arg, mode);
-  add_input_operand (false_arg, mode);
-  add_input_operand (pred_arg, pred_mode);
+  add_output_operand (icode);
+  add_input_operand (icode, true_arg);
+  add_input_operand (icode, false_arg);
+  add_input_operand (icode, pred_arg);
   return generate_insn (icode);
 }
 
@@ -1915,17 +1895,16 @@  function_expander::expand_via_pred_insn (insn_code icode,
   /* Discount the output, predicate, and fallback value.  */
   unsigned int nops = insn_data[icode].n_operands - 3;
   machine_mode mode = get_mode (0);
-  machine_mode pred_mode = get_pred_mode (0);
 
   unsigned int opno = 0;
   rtx fallback_arg = get_fallback_value (mode, nops, merge_argno, opno);
   rtx pred_arg = m_args[opno++];
 
-  add_output_operand (mode);
-  add_input_operand (pred_arg, pred_mode);
+  add_output_operand (icode);
+  add_input_operand (icode, pred_arg);
   for (unsigned int i = 0; i < nops; ++i)
-    add_input_operand (m_args[opno + i], mode);
-  add_input_operand (fallback_arg, mode);
+    add_input_operand (icode, m_args[opno + i]);
+  add_input_operand (icode, fallback_arg);
   return generate_insn (icode);
 }
 
@@ -1939,10 +1918,10 @@  function_expander::expand_via_pred_x_insn (insn_code icode)
   machine_mode pred_mode = get_pred_mode (0);
 
   /* Add the normal operands.  */
-  add_output_operand (mode);
-  add_input_operand (m_args[0], pred_mode);
+  add_output_operand (icode);
+  add_input_operand (icode, m_args[0]);
   for (unsigned int i = 0; i < nops; ++i)
-    add_input_operand (m_args[i + 1], mode);
+    add_input_operand (icode, m_args[i + 1]);
 
   /* Add a flag that indicates whether unpredicated instructions
      are allowed.  */
@@ -2150,29 +2129,43 @@  function_expander::get_fallback_value (machine_mode mode, unsigned int nops,
   return m_args[merge_argno];
 }
 
-/* Add an output operand of mode MODE to the instruction, binding it
-   to the preferred target rtx if possible.  */
+/* Return the mode of the next operand of the instruction we're building,
+   which has code ICODE.  */
+machine_mode
+function_expander::get_next_operand_mode (insn_code icode)
+{
+  machine_mode mode = insn_data[icode].operand[m_ops.length ()].mode;
+  /* SVE ACLE patterns must specify a mode for every operand.  */
+  gcc_assert (mode != VOIDmode);
+  return mode;
+}
+
+/* Add an output operand to the instruction we're building, which has
+   code ICODE.  Bind the output to the preferred target rtx if possible.  */
 void
-function_expander::add_output_operand (machine_mode mode)
+function_expander::add_output_operand (insn_code icode)
 {
+  machine_mode mode = get_next_operand_mode (icode);
   m_ops.safe_grow (m_ops.length () + 1);
   create_output_operand (&m_ops.last (), m_target, mode);
 }
 
-/* Add an input operand with mode MODE to the instruction.  Calculate
-   the value of the operand as follows:
+/* Add an input operand to the instruction we're building, which has
+   code ICODE.  Calculate the value of the operand as follows:
 
-   - If MODE is a vector and X is not, broadcast X to fill a vector of
-     mode MODE.
+   - If the operand is a vector and X is not, broadcast X to fill a
+     vector of the appropriate mode.
 
-   - Otherwise, if MODE is a predicate mode, coerce X to have that mode.
-     In this case X is known to be VNx16BImode.
+   - Otherwise, if the operand is a predicate, coerce X to have the
+     mode that the instruction expects.  In this case X is known to be
+     VNx16BImode (the mode of svbool_t).
 
-   - Otherwise use X directly.  The expand machinery checks that X is
-     consistent with MODE.  */
+   - Otherwise use X directly.  The expand machinery checks that X has
+     the right mode for the instruction.  */
 void
-function_expander::add_input_operand (rtx x, machine_mode mode)
+function_expander::add_input_operand (insn_code icode, rtx x)
 {
+  machine_mode mode = get_next_operand_mode (icode);
   if (!VECTOR_MODE_P (GET_MODE (x)) && VECTOR_MODE_P (mode))
     x = expand_vector_broadcast (mode, x);
   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)