This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: Process '*' in '@'-output-template alternatives
- From: Joern Rennecke <amylaar at spamcop dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 18 Sep 2012 21:51:23 -0400
- Subject: RFA: Process '*' in '@'-output-template alternatives
I am about to submit the ARCompact target port; this port needs a few
patches to target-independent code.
There is a move pattern with 20 alternatives; a few of them need a simple
function call to decide which output pattern to use. With the '@'-syntax
for multi-alternative templates, each alternative is still a one-liner.
Requiring to transform this into some switch statement would make the thing
several times as big, and very hard to take in; besides, it is generally
a maintenance issue if you have to completely rewrite a multi-alternative
template if you just change one alternative from a constant to some C-code,
or vice versa for the last non-literal alternative.
The attached patch makes the '*' syntax for C code fragments available for
individual alternatives of an '@' multi-alternative output template.
It does this by translating the input into a switch statement in the
generated file, so in a way this is just syntactic sugar, but it's syntactic
sugar that makes some machine descriptions easier to write and change.
Bootstrapped in revision 191429 for i686-pc-linux-gnu.
I've been wondering if it'd make sense to also support for '{' / '}' ,
but at least in the ARCompact context, I think the use of that syntax
inside a multi-alternative template would reduce rather than improve
legibility, so, having no application for the '{' / '}' in that place,
there seems to be no use in adding support for that at this point in time.
2008-11-19 J"orn Rennecke <joern.rennecke@arc.com>
* genoutput.c (process_template): Process '*' in '@' alternatives.
Index: genoutput.c
===================================================================
--- genoutput.c (revision 191429)
+++ genoutput.c (working copy)
@@ -662,19 +662,55 @@ process_template (struct data *d, const
list of assembler code templates, one for each alternative. */
else if (template_code[0] == '@')
{
- d->template_code = 0;
- d->output_format = INSN_OUTPUT_FORMAT_MULTI;
+ int found_star = 0;
- printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
+ for (cp = &template_code[1]; *cp; )
+ {
+ while (ISSPACE (*cp))
+ cp++;
+ if (*cp == '*')
+ found_star = 1;
+ while (!IS_VSPACE (*cp) && *cp != '\0')
+ ++cp;
+ }
+ d->template_code = 0;
+ if (found_star)
+ {
+ d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
+ puts ("\nstatic const char *");
+ printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
+ "rtx insn ATTRIBUTE_UNUSED)\n", d->code_number);
+ puts ("{");
+ puts (" switch (which_alternative)\n {");
+ }
+ else
+ {
+ d->output_format = INSN_OUTPUT_FORMAT_MULTI;
+ printf ("\nstatic const char * const output_%d[] = {\n",
+ d->code_number);
+ }
for (i = 0, cp = &template_code[1]; *cp; )
{
- const char *ep, *sp;
+ const char *ep, *sp, *bp;
while (ISSPACE (*cp))
cp++;
- printf (" \"");
+ bp = cp;
+ if (found_star)
+ {
+ printf (" case %d:", i);
+ if (*cp == '*')
+ {
+ printf ("\n ");
+ cp++;
+ }
+ else
+ printf (" return \"");
+ }
+ else
+ printf (" \"");
for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
if (!ISSPACE (*ep))
@@ -690,7 +726,18 @@ process_template (struct data *d, const
cp++;
}
- printf ("\",\n");
+ if (!found_star)
+ puts ("\",");
+ else if (*bp != '*')
+ puts ("\";");
+ else
+ {
+ /* The usual action will end with a return.
+ If there is neither break or return at the end, this is
+ assumed to be intentional; this allows to have multiple
+ consecutive alternatives share some code. */
+ puts ("");
+ }
i++;
}
if (i == 1)
@@ -700,7 +747,10 @@ process_template (struct data *d, const
error_with_line (d->lineno,
"wrong number of alternatives in the output template");
- printf ("};\n");
+ if (found_star)
+ puts (" default: gcc_unreachable ();\n }\n}");
+ else
+ printf ("};\n");
}
else
{