Annotation of researchv10dc/cmd/gcc/genpeep.c, revision 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.