This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

shrink insn-attrtab.o by 4kB


This simple patch shrinks insn-attrtab.o by 4kB:

   text    data     bss     dec     hex filename
 367201       8     780  367989   59d75 insn-attrtab.o.old
 362729       8     780  363517   58bfd insn-attrtab.o

(note "text" includes .rodata segments).  I simply replaced a giant
dense switch statement, each of whose entries called fprintf with a
different format string (and no format escapes), with a giant table
of strings and one call to fputs, in print_reservation.  This is an
optimization it might be interesting to see if we can get GCC to do
automatically, by the way, once we can do very high level factoring
like this.

internal_insn_latency should be susceptible to the same optimization,
for somewhat less space savings -- print_reservation went from 4713 to
233 bytes; internal_insn_latency is only 607 bytes long to begin with.
But it's late and I'm going to bed.  Bootstrap running overnight.

zw

        * genautomata.c (output_print_reservation_func): Use a static
        table of strings instead of a switch statement, to save space.

===================================================================
Index: genautomata.c
--- genautomata.c	15 Jan 2003 01:21:44 -0000	1.31
+++ genautomata.c	19 Jan 2003 10:33:10 -0000
@@ -8966,44 +8966,69 @@ static void
 output_print_reservation_func ()
 {
   decl_t decl;
-  int i;
+  int i, j, insn_num;
+  bool need_null_check = false;
 
-  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 ();
-        }
+	  insn_num = DECL_INSN_RESERV (decl)->insn_num;
+	  if (j > insn_num)
+	    abort ();
+	  if (j < insn_num)
+	    {
+	      need_null_check = true;
+	      fputs ("\n     ", output_file);
+	      do 
+		fputs (" 0,", output_file);
+	      while (++j < insn_num);
+	    }
+	  fprintf (output_file, "\n      \"%s\",",
+		   regexp_representation (DECL_INSN_RESERV (decl)->regexp));
+	  finish_regexp_representation ();
+	  j++;
+	}
     }
-  fprintf (output_file, "    default:\n      fprintf (%s, \"%s\");\n    }\n",
-           FILE_PARAMETER_NAME, NOTHING_NAME);
-  fprintf (output_file, "}\n\n");
+	      
+  fprintf (output_file, "\n    };\n  int %s;\n",
+	   INTERNAL_INSN_CODE_NAME);
+
+  fprintf (output_file, "\n\
+  if (%s == 0)\n\
+    {\n\
+      fputs (\"%s\", %s);\n\
+      return;\n\
+    }\n", INSN_PARAMETER_NAME, NOTHING_NAME, FILE_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      || %s >= ARRAY_SIZE (reservation_names)",
+	   INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+	   INTERNAL_INSN_CODE_NAME);
+  if (need_null_check)
+    fprintf (output_file, "\n      || reservation_names[%s] == 0",
+	     INTERNAL_INSN_CODE_NAME);
+  fprintf (output_file, ")\n\
+    {\n\
+      fputs (\"%s\", %s);\n\
+      return;\n\
+    }\n",
+           NOTHING_NAME, FILE_PARAMETER_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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]