Annotation of researchv10dc/cmd/gcc/genpeep.c, revision 1.1.1.1

1.1       root        1: /* Generate code from machine description to perform peephole optimizations.
                      2:    Copyright (C) 1987 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU CC General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU CC, but only under the conditions described in the
                     15: GNU CC General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU CC so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include <stdio.h>
                     23: #include "config.h"
                     24: #include "rtl.h"
                     25: #include "obstack.h"
                     26: 
                     27: struct obstack obstack;
                     28: struct obstack *rtl_obstack = &obstack;
                     29: 
                     30: #define obstack_chunk_alloc xmalloc
                     31: #define obstack_chunk_free free
                     32: extern int xmalloc ();
                     33: extern void free ();
                     34: 
                     35: void match_rtx ();
                     36: void gen_exp ();
                     37: void fatal ();
                     38: 
                     39: 
                     40: int max_opno;
                     41: 
                     42: /* While tree-walking an instruction pattern, we keep a chain
                     43:    of these `struct link's to record how to get down to the
                     44:    current position.  In each one, POS is the operand number,
                     45:    and if the operand is a vector VEC is the element number.
                     46:    VEC is -1 if the operand is not a vector.  */
                     47: 
                     48: struct link
                     49: {
                     50:   struct link *next;
                     51:   int pos;
                     52:   int vecelt;
                     53: };
                     54: 
                     55: /* Number of operands used in current peephole definition.  */
                     56: 
                     57: int n_operands;
                     58: 
                     59: /* Peephole optimizations get insn codes just like insn patterns.
                     60:    Count them so we know the code of the define_peephole we are handling.  */
                     61: 
                     62: int insn_code_number = 0;
                     63: 
                     64: void print_path ();
                     65: void print_code ();
                     66: 
                     67: void
                     68: gen_peephole (peep)
                     69:      rtx peep;
                     70: {
                     71:   int ninsns = XVECLEN (peep, 0);
                     72:   int i;
                     73: 
                     74:   n_operands = 0;
                     75: 
                     76:   printf ("  insn = ins1;\n");
                     77: 
                     78:   for (i = 0; i < ninsns; i++)
                     79:     {
                     80:       if (i > 0)
                     81:        {
                     82:          printf ("  do { insn = NEXT_INSN (insn);\n");
                     83:          printf ("       if (insn == 0) goto L%d; }\n",
                     84:                  insn_code_number);
                     85:          printf ("  while (GET_CODE (insn) == NOTE);\n");
                     86:        }
                     87: 
                     88:       printf ("  if (GET_CODE (insn) == CODE_LABEL) goto L%d;\n",
                     89:              insn_code_number);
                     90: 
                     91:       printf ("  pat = PATTERN (insn);\n");
                     92:       /* Walk the insn's pattern, remembering at all times the path
                     93:         down to the walking point.  */
                     94: 
                     95:       match_rtx (XVECEXP (peep, 0, i), 0, insn_code_number);
                     96:     }
                     97: 
                     98:   /* We get this far if the pattern matches.
                     99:      Now test the extra condition.  */
                    100: 
                    101:   if (XSTR (peep, 1) && XSTR (peep, 1)[0])
                    102:     printf ("  if (! (%s)) goto L%d;\n",
                    103:            XSTR (peep, 1), insn_code_number);
                    104: 
                    105:   /* If that matches, construct new pattern and put it in the first insn.
                    106:      This new pattern will never be matched.
                    107:      It exists only so that insn-extract can get the operands back.
                    108:      So use a simple regular form: a PARALLEL containing a vector
                    109:      of all the operands.  */
                    110: 
                    111:   printf ("  PATTERN (ins1) = gen_rtx (PARALLEL, VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands);
                    112:   printf ("  insn = ins1;\n");
                    113: 
                    114:   /* Make sure that labels referred to by the insns
                    115:      don't get deleted because of their counts' going to zero.  */
                    116:   printf ("  for (i = 0; i < %d; i++)\n", n_operands);
                    117:   printf ("    if (GET_CODE (operands[i]) == CODE_LABEL)\n");
                    118:   printf ("      LABEL_NUSES (operands[i])++;\n");
                    119: 
                    120:   /* Record this define_peephole's insn code in the insn,
                    121:      as if it had been recognized to match this.  */
                    122:   printf ("  INSN_CODE (insn) = %d;\n",
                    123:          insn_code_number);
                    124: 
                    125:   /* Delete the remaining insns.  */
                    126:   for (i = 1; i < ninsns; i++)
                    127:     {
                    128:       printf ("  do insn = NEXT_INSN (insn);\n");
                    129:       printf ("  while (GET_CODE (insn) == NOTE);\n");
                    130:       printf ("  delete_insn (insn);\n");
                    131:     }
                    132: 
                    133:   printf ("  return 1;\n");
                    134: 
                    135:   printf (" L%d:\n\n", insn_code_number);
                    136: }
                    137: 
                    138: void
                    139: match_rtx (x, path, fail_label)
                    140:      rtx x;
                    141:      struct link *path;
                    142:      int fail_label;
                    143: {
                    144:   register RTX_CODE code;
                    145:   register int i;
                    146:   register int len;
                    147:   register char *fmt;
                    148:   struct link link;
                    149: 
                    150:   if (x == 0)
                    151:     return;
                    152: 
                    153: 
                    154:   code = GET_CODE (x);
                    155: 
                    156:   switch (code)
                    157:     {
                    158:     case MATCH_OPERAND:
                    159:       if (XINT (x, 0) > max_opno)
                    160:        max_opno = XINT (x, 0);
                    161:       if (XINT (x, 0) >= n_operands)
                    162:        n_operands = 1 + XINT (x, 0);
                    163: 
                    164:       printf ("  x = ");
                    165:       print_path (path);
                    166:       printf (";\n");
                    167: 
                    168:       printf ("  operands[%d] = x;\n", XINT (x, 0));
                    169:       if (XSTR (x, 1) && XSTR (x, 1)[0])
                    170:        printf ("  if (! %s (x, %smode)) goto L%d;\n",
                    171:                XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
                    172:       return;
                    173: 
                    174:     case MATCH_DUP:
                    175:       printf ("  x = ");
                    176:       print_path (path);
                    177:       printf (";\n");
                    178: 
                    179:       printf ("  if (!rtx_equal_p (operands[%d], x)) goto L%d;\n",
                    180:              XINT (x, 0), fail_label);
                    181:       return;
                    182: 
                    183:     case ADDRESS:
                    184:       match_rtx (XEXP (x, 0), path, fail_label);
                    185:       return;
                    186:     }
                    187: 
                    188:   printf ("  x = ");
                    189:   print_path (path);
                    190:   printf (";\n");
                    191: 
                    192:   printf ("  if (GET_CODE (x) != ");
                    193:   print_code (code);
                    194:   printf (") goto L%d;\n", fail_label);
                    195: 
                    196:   if (GET_MODE (x) != VOIDmode)
                    197:     {
                    198:       printf ("  if (GET_MODE (x) != %smode) goto L%d;\n",
                    199:              GET_MODE_NAME (GET_MODE (x)), fail_label);
                    200:     }
                    201: 
                    202:   link.next = path;
                    203:   link.vecelt = -1;
                    204:   fmt = GET_RTX_FORMAT (code);
                    205:   len = GET_RTX_LENGTH (code);
                    206:   for (i = 0; i < len; i++)
                    207:     {
                    208:       link.pos = i;
                    209:       if (fmt[i] == 'e' || fmt[i] == 'u')
                    210:        match_rtx (XEXP (x, i), &link, fail_label);
                    211:       else if (fmt[i] == 'E')
                    212:        {
                    213:          int j;
                    214:          printf ("  if (XVECLEN (x, %d) != %d) goto L%d;\n",
                    215:                  i, XVECLEN (x, i), fail_label);
                    216:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                    217:            {
                    218:              link.vecelt = j;
                    219:              match_rtx (XVECEXP (x, i, j), &link, fail_label);
                    220:            }
                    221:        }
                    222:       else if (fmt[i] == 'i')
                    223:        {
                    224:          /* Make sure that at run time `x' is the RTX we want to test.  */
                    225:          if (i != 0)
                    226:            {
                    227:              printf ("  x = ");
                    228:              print_path (path);
                    229:              printf (";\n");
                    230:            }
                    231: 
                    232:          printf ("  if (XINT (x, %d) != %d) goto L%d;\n",
                    233:                  i, XINT (x, i), fail_label);
                    234:        }
                    235:       else if (fmt[i] == 's')
                    236:        {
                    237:          /* Make sure that at run time `x' is the RTX we want to test.  */
                    238:          if (i != 0)
                    239:            {
                    240:              printf ("  x = ");
                    241:              print_path (path);
                    242:              printf (";\n");
                    243:            }
                    244: 
                    245:          printf ("  if (strcmp (XSTR (x, %d), \"%s\")) goto L%d;\n",
                    246:                  i, XSTR (x, i), fail_label);
                    247:        }
                    248:     }
                    249: }
                    250: 
                    251: /* Given a PATH, representing a path down the instruction's
                    252:    pattern from the root to a certain point, output code to
                    253:    evaluate to the rtx at that point.  */
                    254: 
                    255: void
                    256: print_path (path)
                    257:      struct link *path;
                    258: {
                    259:   if (path == 0)
                    260:     printf ("pat");
                    261:   else if (path->vecelt >= 0)
                    262:     {
                    263:       printf ("XVECEXP (");
                    264:       print_path (path->next);
                    265:       printf (", %d, %d)", path->pos, path->vecelt);
                    266:     }
                    267:   else
                    268:     {
                    269:       printf ("XEXP (");
                    270:       print_path (path->next);
                    271:       printf (", %d)", path->pos);
                    272:     }
                    273: }
                    274: 
                    275: void
                    276: print_code (code)
                    277:      RTX_CODE code;
                    278: {
                    279:   register char *p1;
                    280:   for (p1 = GET_RTX_NAME (code); *p1; p1++)
                    281:     {
                    282:       if (*p1 >= 'a' && *p1 <= 'z')
                    283:        putchar (*p1 + 'A' - 'a');
                    284:       else
                    285:        putchar (*p1);
                    286:     }
                    287: }
                    288: 
                    289: int
                    290: xmalloc (size)
                    291: {
                    292:   register int val = malloc (size);
                    293: 
                    294:   if (val == 0)
                    295:     fatal ("virtual memory exhausted");
                    296:   return val;
                    297: }
                    298: 
                    299: int
                    300: xrealloc (ptr, size)
                    301:      char *ptr;
                    302:      int size;
                    303: {
                    304:   int result = realloc (ptr, size);
                    305:   if (!result)
                    306:     fatal ("virtual memory exhausted");
                    307:   return result;
                    308: }
                    309: 
                    310: void
                    311: fatal (s, a1, a2)
                    312: {
                    313:   fprintf (stderr, "genpeep: ");
                    314:   fprintf (stderr, s, a1, a2);
                    315:   fprintf (stderr, "\n");
                    316:   exit (FATAL_EXIT_CODE);
                    317: }
                    318: 
                    319: int
                    320: main (argc, argv)
                    321:      int argc;
                    322:      char **argv;
                    323: {
                    324:   rtx desc;
                    325:   FILE *infile;
                    326:   extern rtx read_rtx ();
                    327:   register int c, i;
                    328: 
                    329:   max_opno = -1;
                    330: 
                    331:   obstack_init (rtl_obstack);
                    332: 
                    333:   if (argc <= 1)
                    334:     fatal ("No input file name.");
                    335: 
                    336:   infile = fopen (argv[1], "r");
                    337:   if (infile == 0)
                    338:     {
                    339:       perror (argv[1]);
                    340:       exit (FATAL_EXIT_CODE);
                    341:     }
                    342: 
                    343:   init_rtl ();
                    344: 
                    345:   printf ("/* Generated automatically by the program `genpeep'\n\
                    346: from the machine description file `md'.  */\n\n");
                    347: 
                    348:   printf ("#include \"rtl.h\"\n\n");
                    349:   printf ("#include \"config.h\"\n\n");
                    350:   printf ("#include \"regs.h\"\n\n");
                    351: 
                    352:   printf ("rtx peep_operand[];\n\n");
                    353:   printf ("#define operands peep_operand\n\n");
                    354: 
                    355:   printf ("int\npeephole (ins1)\n     rtx ins1;\n{\n");
                    356:   printf ("  rtx insn, x, pat;\n");
                    357:   printf ("  int i;\n");
                    358: 
                    359:   /* Read the machine description.  */
                    360: 
                    361:   while (1)
                    362:     {
                    363:       c = read_skip_spaces (infile);
                    364:       if (c == EOF)
                    365:        break;
                    366:       ungetc (c, infile);
                    367: 
                    368:       desc = read_rtx (infile);
                    369:       if (GET_CODE (desc) == DEFINE_PEEPHOLE)
                    370:        {
                    371:          gen_peephole (desc);
                    372:          insn_code_number++;
                    373:        }
                    374:       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
                    375:        {
                    376:          insn_code_number++;
                    377:        }
                    378:     }
                    379: 
                    380:   printf ("  return 0;\n}\n\n");
                    381: 
                    382:   if (max_opno == -1)
                    383:     max_opno = 1;
                    384: 
                    385:   printf ("rtx peep_operand[%d];\n", max_opno + 1);
                    386: 
                    387:   fflush (stdout);
                    388:   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
                    389: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.