Patchwork [2/3] optabs: Bias optabs by -CODE_FOR_nothing

login
register
mail settings
Submitter Richard Sandiford
Date July 4, 2010, 1:46 p.m.
Message ID <87pqz3nyw5.fsf@firetop.home>
Download mbox | patch
Permalink /patch/57845/
State New
Headers show

Comments

Richard Sandiford - July 4, 2010, 1:46 p.m.
Richard Sandiford <rdsandiford@googlemail.com> writes:
> This patch biases the opcode "insn_code" by -CODE_FOR_nothing, so that
> optabs without insns have an insn_code of 0.  The change incurs an extra
> addition when determining which generator function to call, but the
> cost is going to be dwarfed by the call and rtx generation.
> The change often simplifies the common idiom:
>
>    OPTAB_HANDLER (...) ==/!= CODE_FOR_nothing
>
> Bootstrapped & regression-tested on x86_64-linux-gnu.  OK to intsall?

Now updated to use inlines.  Tested as before.  OK to install?

Richard


gcc/
	* optabs.h (optab_handlers): Change type of insn_code to int.
	(optab_handler, set_optab_handler, convert_optab_handler)
	(set_convert_optab_handler): Treat the insn_code field as "insn_code -
	CODE_FOR_nothing".
	* optabs.c (optab_table, convert_optab_table): Always zero-initialize.
	(init_insn_codes): Zero both the above arrays.
	(init_optabs): Never call init_insn_codes first time around.

Patch

Index: gcc/optabs.h
===================================================================
--- gcc/optabs.h	2010-07-03 20:07:57.000000000 +0100
+++ gcc/optabs.h	2010-07-03 20:10:45.000000000 +0100
@@ -29,10 +29,6 @@  #define GCC_OPTABS_H
 
    For example, add_optab applies to addition.
 
-   The insn_code slot is the enum insn_code that says how to
-   generate an insn for this operation on a particular machine mode.
-   It is CODE_FOR_nothing if there is no such insn on the target machine.
-
    The `lib_call' slot is the name of the library function that
    can be used to perform the operation.
 
@@ -40,7 +36,10 @@  #define GCC_OPTABS_H
 
 struct optab_handlers
 {
-  enum insn_code insn_code;
+  /* I - CODE_FOR_nothing, where I is either the insn code of the
+     associated insn generator or CODE_FOR_nothing if there is no such
+     insn on the target machine.  */
+  int insn_code;
 };
 
 struct optab_d
@@ -788,7 +787,8 @@  extern rtx expand_vec_shift_expr (sepops
 static inline enum insn_code
 optab_handler (optab op, enum machine_mode mode)
 {
-  return op->handlers[(int) mode].insn_code;
+  return (enum insn_code) (op->handlers[(int) mode].insn_code
+			   + (int) CODE_FOR_nothing);
 }
 
 /* Record that insn CODE should be used to implement mode MODE of OP.  */
@@ -796,7 +796,7 @@  optab_handler (optab op, enum machine_mo
 static inline void
 set_optab_handler (optab op, enum machine_mode mode, enum insn_code code)
 {
-  op->handlers[(int) mode].insn_code = code;
+  op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;
 }
 
 /* Return the insn used to perform conversion OP from mode FROM_MODE
@@ -807,7 +807,9 @@  set_optab_handler (optab op, enum machin
 convert_optab_handler (convert_optab op, enum machine_mode to_mode,
 		       enum machine_mode from_mode)
 {
-  return op->handlers[(int) to_mode][(int) from_mode].insn_code;
+  return ((enum insn_code)
+	  (op->handlers[(int) to_mode][(int) from_mode].insn_code
+	   + (int) CODE_FOR_nothing));
 }
 
 /* Record that insn CODE should be used to perform conversion OP
@@ -817,7 +819,8 @@  convert_optab_handler (convert_optab op,
 set_convert_optab_handler (convert_optab op, enum machine_mode to_mode,
 			   enum machine_mode from_mode, enum insn_code code)
 {
-  op->handlers[(int) to_mode][(int) from_mode].insn_code = code;
+  op->handlers[(int) to_mode][(int) from_mode].insn_code
+    = (int) code - (int) CODE_FOR_nothing;
 }
 
 extern rtx optab_libfunc (optab optab, enum machine_mode mode);
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2010-07-03 20:07:43.000000000 +0100
+++ gcc/optabs.c	2010-07-03 20:10:45.000000000 +0100
@@ -53,27 +53,12 @@  Software Foundation; either version 3, o
 
    See expr.h for documentation of these optabs.  */
 
-#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
-__extension__ struct optab_d optab_table[OTI_MAX]
-  = { [0 ... OTI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1].insn_code
-      = CODE_FOR_nothing };
-#else
-/* init_insn_codes will do runtime initialization otherwise.  */
 struct optab_d optab_table[OTI_MAX];
-#endif
 
 rtx libfunc_table[LTI_MAX];
 
 /* Tables of patterns for converting one mode to another.  */
-#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
-__extension__ struct convert_optab_d convert_optab_table[COI_MAX]
-  = { [0 ... COI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1]
-	[0 ... NUM_MACHINE_MODES - 1].insn_code
-      = CODE_FOR_nothing };
-#else
-/* init_convert_optab will do runtime initialization otherwise.  */
 struct convert_optab_d convert_optab_table[COI_MAX];
-#endif
 
 /* Contains the optab used for each rtx code.  */
 optab code_to_optab[NUM_RTX_CODE + 1];
@@ -5452,28 +5437,8 @@  have_insn_for (enum rtx_code code, enum
 static void
 init_insn_codes (void)
 {
-  unsigned int i;
-
-  for (i = 0; i < (unsigned int) OTI_MAX; i++)
-    {
-      unsigned int j;
-      optab op;
-
-      op = &optab_table[i];
-      for (j = 0; j < NUM_MACHINE_MODES; j++)
-	set_optab_handler (op, (enum machine_mode) j, CODE_FOR_nothing);
-    }
-  for (i = 0; i < (unsigned int) COI_MAX; i++)
-    {
-      unsigned int j, k;
-      convert_optab op;
-
-      op = &convert_optab_table[i];
-      for (j = 0; j < NUM_MACHINE_MODES; j++)
-	for (k = 0; k < NUM_MACHINE_MODES; k++)
-	  set_convert_optab_handler (op, (enum machine_mode) j,
-				     (enum machine_mode) k, CODE_FOR_nothing);
-    }
+  memset (optab_table, 0, sizeof (optab_table));
+  memset (convert_optab_table, 0, sizeof (convert_optab_table));
 }
 
 /* Initialize OP's code to CODE, and write it into the code_to_optab table.  */
@@ -6182,9 +6147,7 @@  set_conv_libfunc (convert_optab optable,
 init_optabs (void)
 {
   unsigned int i;
-#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
   static bool reinit;
-#endif
 
   libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
   /* Start by initializing all tables to contain CODE_FOR_nothing.  */
@@ -6200,14 +6163,10 @@  init_optabs (void)
       vcondu_gen_code[i] = CODE_FOR_nothing;
     }
 
-#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
   /* We statically initialize the insn_codes with the equivalent of
      CODE_FOR_nothing.  */
   if (reinit)
     init_insn_codes ();
-#else
-  init_insn_codes ();
-#endif
 
   init_optab (add_optab, PLUS);
   init_optabv (addv_optab, PLUS);
@@ -6682,9 +6641,7 @@  init_optabs (void)
   /* Allow the target to add more libcalls or rename some, etc.  */
   targetm.init_libfuncs ();
 
-#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
   reinit = true;
-#endif
 }
 
 /* Print information about the current contents of the optabs on