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

login
register
mail settings
Submitter Richard Sandiford
Date July 3, 2010, 5:43 p.m.
Message ID <87iq4w4g15.fsf@firetop.home>
Download mbox | patch
Permalink /patch/57819/
State New
Headers show

Comments

Richard Sandiford - July 3, 2010, 5:43 p.m.
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?

Richard


gcc/
	* optabs.h (optab_handlers): Change type of insn_code to int.
	(OPTAB_HANDLER): Treat the insn_code field as "insn_code -
	CODE_FOR_nothing".
	(SET_OPTAB_HANDLER, CONVERT_OPTAB_HANDLER): Likewise.
	(SET_CONVERT_OPTAB_HANDLER): Likewise.
	* 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 18:32:20.000000000 +0100
+++ gcc/optabs.h	2010-07-03 18:39:10.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
@@ -783,14 +782,18 @@  extern rtx expand_vec_cond_expr (tree, t
 extern rtx expand_vec_shift_expr (sepops, rtx);
 
 #define OPTAB_HANDLER(OPTAB, MODE) \
-  ((OPTAB)->handlers[(int) (MODE)].insn_code)
+  ((enum insn_code) ((OPTAB)->handlers[(int) (MODE)].insn_code \
+		     + (int) CODE_FOR_nothing))
 #define SET_OPTAB_HANDLER(OPTAB, MODE, CODE) \
-  ((void) ((OPTAB)->handlers[(int) (MODE)].insn_code = (CODE)))
+  ((void) ((OPTAB)->handlers[(int) (MODE)].insn_code \
+	   = (int) (CODE) - (int) CODE_FOR_nothing))
 
 #define CONVERT_OPTAB_HANDLER(OPTAB, MODE, MODE2) \
-  ((OPTAB)->handlers[(int) (MODE)][(int) (MODE2)].insn_code)
+  ((enum insn_code) ((OPTAB)->handlers[(int) (MODE)][(int) (MODE2)].insn_code \
+		     + (int) CODE_FOR_nothing))
 #define SET_CONVERT_OPTAB_HANDLER(OPTAB, MODE, MODE2, CODE) \
-  ((void) ((OPTAB)->handlers[(int) (MODE)][(int) (MODE2)].insn_code = (CODE)))
+  ((void) ((OPTAB)->handlers[(int) (MODE)][(int) (MODE2)].insn_code \
+	   = (int) (CODE) - (int) CODE_FOR_nothing))
 
 extern rtx optab_libfunc (optab optab, enum machine_mode mode);
 extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2010-07-03 18:32:20.000000000 +0100
+++ gcc/optabs.c	2010-07-03 18:35:34.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,27 +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, 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, j, 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.  */
@@ -6181,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.  */
@@ -6199,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);
@@ -6681,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