genautomata.c: Space savings in generated code:
authorZack Weinberg <zack@codesourcery.com>
Tue, 21 Jan 2003 08:33:20 +0000 (08:33 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Tue, 21 Jan 2003 08:33:20 +0000 (08:33 +0000)
* genautomata.c: Space savings in generated code:
(output_dfa_insn_code_func): Split out the table-enlargement
path to an out-of-line static function, dfa_insn_code_enlarge.
(output_internal_insn_latency_func): Use a lookup table for the
default latencies.
(output_print_reservation_func): Use a lookup table for the
strings.

From-SVN: r61541

gcc/ChangeLog
gcc/genautomata.c

index ec08e1f92c7be4170526f01c8303d7ff0ca4437c..54d87d33323a60d9c1ab4379354edc6f6b9ac9cb 100644 (file)
@@ -1,3 +1,13 @@
+2003-01-21  Zack Weinberg  <zack@codesourcery.com>
+
+       * genautomata.c: Space savings in generated code:
+       (output_dfa_insn_code_func): Split out the table-enlargement
+       path to an out-of-line static function, dfa_insn_code_enlarge.
+       (output_internal_insn_latency_func): Use a lookup table for the
+       default latencies.
+       (output_print_reservation_func): Use a lookup table for the
+       strings.
+
 2003-01-21  Christian Ehrhardt  <ehrhardt@mathematik.uni-ulm.de>
 
        PR opt/7507
index 384405834a349096605c367bf2158c8192249b2b..8442461ca774cd097bf010f7a86605491a359674 100644 (file)
@@ -8613,40 +8613,57 @@ output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
 }
 
 
-/* The function outputs function `dfa_insn_code'.  */
+/* This function outputs `dfa_insn_code' and its helper function
+   `dfa_insn_code_enlarge'.  */
 static void
 output_dfa_insn_code_func ()
 {
-  fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
-  fprintf (output_file, "static int %s PARAMS ((rtx));\n",
-          DFA_INSN_CODE_FUNC_NAME);
-  fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
-          DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
-  fprintf (output_file, "{\n  int %s;\n  int %s;\n\n",
-          INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
-  fprintf (output_file, "  if (INSN_UID (%s) >= %s)\n    {\n",
-          INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
-  fprintf (output_file, "      %s = %s;\n      %s = 2 * INSN_UID (%s);\n",
-          TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
-          DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
-  fprintf (output_file, "      %s = xrealloc (%s, %s * sizeof (int));\n",
-          DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
-          DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
-  fprintf (output_file,
-          "      for (; %s < %s; %s++)\n        %s [%s] = -1;\n    }\n",
-          TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
-          TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
-          TEMPORARY_VARIABLE_NAME);
-  fprintf (output_file, "  if ((%s = %s [INSN_UID (%s)]) < 0)\n    {\n",
-          INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
-          INSN_PARAMETER_NAME);
-  fprintf (output_file, "      %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
-          INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
-  fprintf (output_file, "      %s [INSN_UID (%s)] = %s;\n",
-          DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
-          INTERNAL_INSN_CODE_NAME);
-  fprintf (output_file, "    }\n  return %s;\n}\n\n",
+  /* Emacs c-mode gets really confused if there's a { or } in column 0
+     inside a string, so don't do that.  */
+  fprintf (output_file, "\
+static void dfa_insn_code_enlarge PARAMS ((int));\n\
+static void\n\
+dfa_insn_code_enlarge (uid)\n\
+     int uid;\n{\n\
+  int i = %s;\n\
+  %s = 2 * uid;\n\
+  %s = xrealloc (%s,\n\
+                 %s * sizeof(int));\n\
+  for (; i < %s; i++)\n\
+    %s[i] = -1;\n}\n\n",
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+          DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+          DFA_INSN_CODES_VARIABLE_NAME);
+  fprintf (output_file, "\
+static inline int %s PARAMS ((rtx));\n\
+static inline int\n%s (%s)\n\
+    rtx %s;\n{\n\
+ int uid = INSN_UID (%s);\n\
+ int %s;\n\n",
+          DFA_INSN_CODE_FUNC_NAME, DFA_INSN_CODE_FUNC_NAME,
+          INSN_PARAMETER_NAME, INSN_PARAMETER_NAME,
+          INSN_PARAMETER_NAME,
           INTERNAL_INSN_CODE_NAME);
+
+  fprintf (output_file,
+          "  if (uid >= %s)\n    dfa_insn_code_enlarge (uid);\n\n",
+          DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+  fprintf (output_file, "  %s = %s[uid];\n",
+          INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
+  fprintf (output_file, "\
+  if (%s < 0)\n\
+    {\n\
+      %s = %s (%s);\n\
+      %s[uid] = %s;\n\
+    }\n",
+          INTERNAL_INSN_CODE_NAME,
+          INTERNAL_INSN_CODE_NAME,
+          INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
+          DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
+  fprintf (output_file, "  return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
 }
 
 /* The function outputs PHR interface function `state_transition'.  */
@@ -8881,8 +8898,22 @@ output_internal_insn_latency_func ()
 {
   decl_t decl;
   struct bypass_decl *bypass;
-  int i;
+  int i, j, col;
+  const char *tabletype = "unsigned char";
 
+  /* Find the smallest integer type that can hold all the default
+     latency values.  */
+  for (i = 0; i < description->decls_num; i++)
+    if (description->decls[i]->mode == dm_insn_reserv)
+      {
+       decl = description->decls[i];
+       if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
+           && tabletype[0] != 'i')  /* don't shrink it */
+         tabletype = "unsigned short";
+       if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
+         tabletype = "int";
+      }
+    
   fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
           INTERNAL_INSN_LATENCY_FUNC_NAME);
   fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
@@ -8892,50 +8923,70 @@ output_internal_insn_latency_func ()
   fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
           INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
   fprintf (output_file,
-          "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
+          "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n{\n",
           INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
-  fprintf (output_file, "{\n  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
+
+  fprintf (output_file, "  static const %s default_latencies[] =\n    {",
+          tabletype);
+
+  for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
+    if (description->decls[i]->mode == dm_insn_reserv
+       && description->decls[i] != advance_cycle_insn_decl)
+      {
+       if ((col = (col+1) % 8) == 0)
+         fputs ("\n     ", output_file);
+       decl = description->decls[i];
+       if (j++ != DECL_INSN_RESERV (decl)->insn_num)
+         abort ();
+       fprintf (output_file, "% 4d,",
+                DECL_INSN_RESERV (decl)->default_latency);
+      }
+  if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
+    abort ();
+  fputs ("\n    };\n", output_file);
+
+  fprintf (output_file, "  if (%s >= %s || %s >= %s)\n    return 0;\n",
+          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+          INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+
+  fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
   for (i = 0; i < description->decls_num; i++)
-    {
-      decl = description->decls [i];
-      if (decl->mode == dm_insn_reserv)
-       {
-         fprintf (output_file, "    case %d:\n",
-                  DECL_INSN_RESERV (decl)->insn_num);
-         if (DECL_INSN_RESERV (decl)->bypass_list == NULL)
-           fprintf (output_file, "      return (%s != %s ? %d : 0);\n",
-                    INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
-                    DECL_INSN_RESERV (decl)->default_latency);
-         else
-           {
-             fprintf (output_file, "      switch (%s)\n        {\n",
-                      INTERNAL_INSN2_CODE_NAME);
-             for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
-                  bypass != NULL;
-                  bypass = bypass->next)
-               {
-                 fprintf (output_file, "        case %d:\n",
-                          bypass->in_insn_reserv->insn_num);
-                 if (bypass->bypass_guard_name == NULL)
-                   fprintf (output_file, "          return %d;\n",
-                            bypass->latency);
-                 else
-                   fprintf (output_file,
-                            "          return (%s (%s, %s) ? %d : %d);\n",
-                            bypass->bypass_guard_name, INSN_PARAMETER_NAME,
-                            INSN2_PARAMETER_NAME, bypass->latency,
-                            DECL_INSN_RESERV (decl)->default_latency);
-               }
-             fprintf (output_file, "        default:\n");
-             fprintf (output_file,
-                      "          return (%s != %s ? %d : 0);\n        }\n",
-                      INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
-                      DECL_INSN_RESERV (decl)->default_latency);
-             
-           }
-       }
-    }
-  fprintf (output_file, "    default:\n      return 0;\n    }\n}\n\n");
+    if (description->decls[i]->mode == dm_insn_reserv
+       && DECL_INSN_RESERV (description->decls[i])->bypass_list)
+      {
+       decl = description->decls [i];
+       fprintf (output_file,
+                "    case %d:\n      switch (%s)\n        {\n",
+                DECL_INSN_RESERV (decl)->insn_num,
+                INTERNAL_INSN2_CODE_NAME);
+       for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
+            bypass != NULL;
+            bypass = bypass->next)
+         {
+           if (bypass->in_insn_reserv->insn_num
+               == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
+             abort ();
+           fprintf (output_file, "        case %d:\n",
+                    bypass->in_insn_reserv->insn_num);
+           if (bypass->bypass_guard_name == NULL)
+             fprintf (output_file, "          return %d;\n",
+                      bypass->latency);
+           else
+             {
+               fprintf (output_file,
+                        "          if (%s (%s, %s)\n",
+                        bypass->bypass_guard_name, INSN_PARAMETER_NAME,
+                        INSN2_PARAMETER_NAME);
+               fprintf (output_file,
+                        "            return %d;\n          break;\n",
+                        bypass->latency);
+             }
+         }
+       fputs ("        }\n", output_file);
+      }
+
+  fprintf (output_file, "    }\n  return default_latencies[%s];\n}\n\n",
+          INTERNAL_INSN_CODE_NAME);
 }
 
 /* The function outputs PHR interface function `insn_latency'.  */
@@ -8962,44 +9013,50 @@ static void
 output_print_reservation_func ()
 {
   decl_t decl;
-  int i;
+  int i, j;
 
-  fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
+  fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n{\n",
            PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
            INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
            INSN_PARAMETER_NAME);
-  fprintf (output_file, "{\n  int %s;\n", INTERNAL_INSN_CODE_NAME);
-  fprintf (output_file, "\n  if (%s != 0)\n    {\n", INSN_PARAMETER_NAME);
-  fprintf (output_file, "      %s = %s (%s);\n",
-          INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
-          INSN_PARAMETER_NAME);
-  fprintf (output_file, "      if (%s > %s)\n",
-          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
-  fprintf (output_file, "        {\n          fprintf (%s, \"%s\");\n",
-           FILE_PARAMETER_NAME, NOTHING_NAME);
-  fprintf (output_file, "          return;\n        }\n");
-  fprintf (output_file, "    }\n  else\n");
-  fprintf (output_file,
-           "    {\n      fprintf (%s, \"%s\");\n      return;\n    }\n",
-           FILE_PARAMETER_NAME, NOTHING_NAME);
-  fprintf (output_file, "  switch (%s)\n    {\n", INTERNAL_INSN_CODE_NAME);
-  for (i = 0; i < description->decls_num; i++)
+
+  fputs ("  static const char *const reservation_names[] =\n    {",
+        output_file);
+
+  for (i = 0, j = 0; i < description->decls_num; i++)
     {
       decl = description->decls [i];
       if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
        {
-          fprintf (output_file,
-                   "    case %d:\n", DECL_INSN_RESERV (decl)->insn_num);
-          fprintf (output_file,
-                   "      fprintf (%s, \"%s\");\n      break;\n",
-                   FILE_PARAMETER_NAME,
-                   regexp_representation (DECL_INSN_RESERV (decl)->regexp));
-          finish_regexp_representation ();
-        }
+         if (j++ != DECL_INSN_RESERV (decl)->insn_num)
+           abort ();
+         fprintf (output_file, "\n      \"%s\",",
+                  regexp_representation (DECL_INSN_RESERV (decl)->regexp));
+         finish_regexp_representation ();
+       }
     }
-  fprintf (output_file, "    default:\n      fprintf (%s, \"%s\");\n    }\n",
-           FILE_PARAMETER_NAME, NOTHING_NAME);
-  fprintf (output_file, "}\n\n");
+  if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
+    abort ();
+             
+  fprintf (output_file, "\n      \"%s\"\n    };\n  int %s;\n\n",
+          NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
+
+  fprintf (output_file, "  if (%s == 0)\n    %s = %s;\n",
+          INSN_PARAMETER_NAME,
+          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+  fprintf (output_file, "  else\n\
+    {\n\
+      %s = %s (%s);\n\
+      if (%s > %s)\n\
+        %s = %s;\n\
+    }\n",
+          INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
+              INSN_PARAMETER_NAME,
+          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+          INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+
+  fprintf (output_file, "  fputs (reservation_names[%s], %s);\n}\n\n",
+          INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
 }
 
 /* The following function is used to sort unit declaration by their