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]

Re: RFA: Process '*' in '@'-output-template alternatives


On Wed, Sep 19, 2012 at 3:51 AM, Joern Rennecke <amylaar@spamcop.net> wrote:
> 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.

I think that needs to be documented somewhere in the internals manual,
possibly with an example.

Richard.

> 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
>      {
>


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