summaryrefslogtreecommitdiff
path: root/gcc/genautomata.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@codesourcery.com>2003-01-21 08:33:20 +0000
committerZack Weinberg <zack@gcc.gnu.org>2003-01-21 08:33:20 +0000
commita543eb5e9af8c0a0cc50f82f4d88506204a70886 (patch)
treeed6a0806e92cec01adef962ac308bf2047fdd0e8 /gcc/genautomata.c
parent292e35a31bcfd1648b087a0de16c04fab0cb0d76 (diff)
downloadgcc-a543eb5e9af8c0a0cc50f82f4d88506204a70886.tar.gz
genautomata.c: Space savings in generated code:
* 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
Diffstat (limited to 'gcc/genautomata.c')
-rw-r--r--gcc/genautomata.c261
1 files changed, 159 insertions, 102 deletions
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index 384405834a3..8442461ca77 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -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