An earlier version of this series wanted to collect information about all the gen_* functions that are going to be generated. The current version no longer does that, but the queue seemed worth keeping anyway, since it gives a more consistent structure.
gcc/ * genemit.cc (queue): New static variable. (maybe_queue_insn): New function, split out from... (gen_insn): ...here. (queue_expand): New function, split out from... (gen_expand): ...here. (gen_split): New function, split out from... (queue_split): ...here. (main): Queue definitions for later processing rather than emitting them on the fly. --- gcc/genemit.cc | 97 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 26 deletions(-) diff --git a/gcc/genemit.cc b/gcc/genemit.cc index cb4ae47294d..b73a45a0412 100644 --- a/gcc/genemit.cc +++ b/gcc/genemit.cc @@ -55,6 +55,9 @@ static void output_peephole2_scratches (rtx, FILE*); /* True for <X>_optab if that optab isn't allowed to fail. */ static bool nofail_optabs[NUM_OPTABS]; +/* A list of the md constructs that need a gen_* function. */ +static vec<md_rtx_info> queue; + static void print_code (RTX_CODE code, FILE *file) { @@ -326,14 +329,12 @@ emit_c_code (const char *code, bool can_fail_p, const char *name, FILE *file) fprintf (file, "#undef FAIL\n"); } -/* Generate the `gen_...' function for a DEFINE_INSN. */ +/* Process the DEFINE_INSN in LOC, and queue it if it needs a gen_* + function. */ static void -gen_insn (const md_rtx_info &info, FILE *file) +maybe_queue_insn (const md_rtx_info &info) { - struct pattern_stats stats; - int i; - /* See if the pattern for this insn ends with a group of CLOBBERs of (hard) registers or MATCH_SCRATCHes. If so, store away the information for later. */ @@ -349,6 +350,7 @@ gen_insn (const md_rtx_info &info, FILE *file) && GET_CODE (RTVEC_ELT (pattern, 0)) == PARALLEL) pattern = XVEC (RTVEC_ELT (pattern, 0), 0); + int i; for (i = GET_NUM_ELEM (pattern) - 1; i > 0; i--) { if (GET_CODE (RTVEC_ELT (pattern, i)) != CLOBBER) @@ -422,9 +424,19 @@ gen_insn (const md_rtx_info &info, FILE *file) if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*') return; - fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno); + queue.safe_push (info); +} + +/* Generate the `gen_...' function for a DEFINE_INSN. */ + +static void +gen_insn (const md_rtx_info &info, FILE *file) +{ + struct pattern_stats stats; + int i; /* Find out how many operands this function has. */ + rtx insn = info.def; get_pattern_stats (&stats, XVEC (insn, 1)); if (stats.max_dup_opno > stats.max_opno) fatal_at (info.loc, "match_dup operand number has no match_operand"); @@ -455,23 +467,31 @@ gen_insn (const md_rtx_info &info, FILE *file) XDELETEVEC (used); } -/* Generate the `gen_...' function for a DEFINE_EXPAND. */ +/* Process and queue the DEFINE_EXPAND in INFO. */ static void -gen_expand (const md_rtx_info &info, FILE *file) +queue_expand (const md_rtx_info &info) { - struct pattern_stats stats; - int i; - char *used; - rtx expand = info.def; if (strlen (XSTR (expand, 0)) == 0) fatal_at (info.loc, "define_expand lacks a name"); if (XVEC (expand, 1) == 0) fatal_at (info.loc, "define_expand for %s lacks a pattern", XSTR (expand, 0)); + queue.safe_push (info); +} + +/* Generate the `gen_...' function for a DEFINE_EXPAND. */ + +static void +gen_expand (const md_rtx_info &info, FILE *file) +{ + struct pattern_stats stats; + int i; + char *used; /* Find out how many operands this function has. */ + rtx expand = info.def; get_pattern_stats (&stats, XVEC (expand, 1)); if (stats.min_scratch_opno != -1 && stats.min_scratch_opno <= MAX (stats.max_opno, stats.max_dup_opno)) @@ -564,7 +584,24 @@ gen_expand (const md_rtx_info &info, FILE *file) fprintf (file, " return _val;\n}\n\n"); } -/* Like gen_expand, but generates insns resulting from splitting SPLIT. */ +/* Process and queue the DEFINE_SPLIT or DEFINE_PEEPHOLE2 in INFO. */ + +static void +queue_split (const md_rtx_info &info) +{ + rtx split = info.def; + + if (XVEC (split, 0) == 0) + fatal_at (info.loc, "%s lacks a pattern", + GET_RTX_NAME (GET_CODE (split))); + if (XVEC (split, 2) == 0) + fatal_at (info.loc, "%s lacks a replacement pattern", + GET_RTX_NAME (GET_CODE (split))); + + queue.safe_push (info); +} + +/* Generate the `gen_...' function for a DEFINE_SPLIT or DEFINE_PEEPHOLE2. */ static void gen_split (const md_rtx_info &info, FILE *file) @@ -577,13 +614,6 @@ gen_split (const md_rtx_info &info, FILE *file) const char *unused; char *used; - if (XVEC (split, 0) == 0) - fatal_at (info.loc, "%s lacks a pattern", - GET_RTX_NAME (GET_CODE (split))); - else if (XVEC (split, 2) == 0) - fatal_at (info.loc, "%s lacks a replacement pattern", - GET_RTX_NAME (GET_CODE (split))); - /* Find out how many operands this function has. */ get_pattern_stats (&stats, XVEC (split, 2)); @@ -951,9 +981,30 @@ main (int argc, const char **argv) /* Read the machine description. */ while (read_md_rtx (&info)) + switch (GET_CODE (info.def)) + { + case DEFINE_INSN: + maybe_queue_insn (info); + break; + + case DEFINE_EXPAND: + queue_expand (info); + break; + + case DEFINE_SPLIT: + case DEFINE_PEEPHOLE2: + queue_split (info); + break; + + default: + break; + } + + for (auto &info : queue) { file = choose_output (output_files, file_idx); + fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno); switch (GET_CODE (info.def)) { case DEFINE_INSN: @@ -961,17 +1012,11 @@ main (int argc, const char **argv) break; case DEFINE_EXPAND: - fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno); gen_expand (info, file); break; case DEFINE_SPLIT: - fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno); - gen_split (info, file); - break; - case DEFINE_PEEPHOLE2: - fprintf (file, "/* %s:%d */\n", info.loc.filename, info.loc.lineno); gen_split (info, file); break; -- 2.43.0