Annotation of gcc/toplev.c, revision 1.1.1.1

1.1       root        1: /* Top level of GNU C compiler
                      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: /* This is the top level of cc1.
                     23:    It parses command args, opens files, invokes the various passes
                     24:    in the proper order, and counts the time used by each.
                     25:    Error messages and low-level interface to malloc also handled here.  */
                     26: 
                     27: #include "config.h"
                     28: #include <stdio.h>
                     29: #include <signal.h>
                     30: #include <strings.h>
                     31: #include <sys/time.h>
                     32: #include <sys/resource.h>
                     33: #ifndef _TYPES_
                     34: #include <sys/types.h>
                     35: #endif
                     36: #include <sys/stat.h>
                     37: #include "tree.h"
                     38: #include "c-tree.h"
                     39: #include "rtl.h"
                     40: 
                     41: extern void dump_tree ();
                     42: extern int yydebug;
                     43: 
                     44: extern FILE *finput;
                     45: 
                     46: extern void init_lex ();
                     47: extern void init_decl_processing ();
                     48: extern void init_tree ();
                     49: extern void init_rtl ();
                     50: extern rtx expand_function ();
                     51: extern void init_optabs ();
                     52: extern void dump_flow_info ();
                     53: extern void dump_local_alloc ();
                     54: 
                     55: /* Bit flags that specify the machine subtype we are compiling for.
                     56:    Bits are tested using macros TARGET_... defined in the tm-...h file
                     57:    and set by `-m...' switches.  */
                     58: 
                     59: int target_flags;
                     60: 
                     61: /* Name of current real source file (what was input to cpp).
                     62:    # commands in the input that specify file names
                     63:    change this value.  */
                     64: 
                     65: extern char *input_filename;
                     66: 
                     67: /* Current line number in real source file.  */
                     68: 
                     69: extern int lineno;
                     70: 
                     71: /* FUNCTION_DECL for function now being parsed or compiled.  */
                     72: 
                     73: extern tree current_function_decl;
                     74: 
                     75: /* Name to use as base of names for dump output files.  */
                     76: 
                     77: char *dump_base_name;
                     78: 
                     79: /* Flags saying which kinds of debugging dump have been requested.  */
                     80: 
                     81: int tree_dump = 0;
                     82: int rtl_dump = 0;
                     83: int rtl_dump_and_exit = 0;
                     84: int jump_opt_dump = 0;
                     85: int cse_dump = 0;
                     86: int loop_dump = 0;
                     87: int flow_dump = 0;
                     88: int combine_dump = 0;
                     89: int local_reg_dump = 0;
                     90: int global_reg_dump = 0;
                     91: 
                     92: /* 1 => write gdb debugging output (using symout.c).  -g
                     93:    2 => write dbx debugging output (using dbxout.c).  -G  */
                     94: 
                     95: int write_symbols = 0;
                     96: 
                     97: /* Nonzero means do optimizations.  -opt.  */
                     98: 
                     99: int optimize = 0;
                    100: 
                    101: /* Nonzero for -optforcemem: load memory value into a register
                    102:    before arithmetic on it.  This makes better cse but slower compilation.  */
                    103: 
                    104: int force_mem = 0;
                    105: 
                    106: /* Nonzero for -optforcemem: load memory address into a register before
                    107:    reference to memory.  This makes better cse but slower compilation.  */
                    108: 
                    109: int force_addr = 0;
                    110: 
                    111: /* Nonzero means do stupid register allocation.  -noreg.
                    112:    This an OPTIMIZE are controlled by different switches in cc1,
                    113:    but normally cc controls them both with the -O switch.  */
                    114: 
                    115: int obey_regdecls = 0;
                    116: 
                    117: /* Don't print functions as they are compiled and don't print
                    118:    times taken by the various passes.  -quiet.  */
                    119: 
                    120: int quiet_flag = 0;
                    121: 
                    122: /* Don't print warning messages.  -w.  */
                    123: 
                    124: int inhibit_warnings = 0;
                    125: 
                    126: /* Number of error messages and warning messages so far.  */
                    127: 
                    128: int errorcount = 0;
                    129: int warningcount = 0;
                    130: 
                    131: /* Nonzero for -pedantic switch: warn about anything
                    132:    that standard C forbids.  */
                    133: 
                    134: int pedantic = 0;
                    135: 
                    136: /* Name for output file of assembly code, specified with -o.  */
                    137: 
                    138: char *asm_file_name;
                    139: 
                    140: /* Name for output file of GDB symbol segment, specified with -symout.  */
                    141: 
                    142: char *sym_file_name;
                    143: 
                    144: /* Output files for assembler code (real compiler output)
                    145:    and debugging dumps.  */
                    146: 
                    147: FILE *asm_out_file;
                    148: FILE *tree_dump_file;
                    149: FILE *rtl_dump_file;
                    150: FILE *jump_opt_dump_file;
                    151: FILE *cse_dump_file;
                    152: FILE *loop_dump_file;
                    153: FILE *flow_dump_file;
                    154: FILE *combine_dump_file;
                    155: FILE *local_reg_dump_file;
                    156: FILE *global_reg_dump_file;
                    157: 
                    158: /* Time accumulators, to count the total time spent in various passes.  */
                    159: 
                    160: int parse_time;
                    161: int varconst_time;
                    162: int expand_time;
                    163: int jump_time;
                    164: int cse_time;
                    165: int loop_time;
                    166: int flow_time;
                    167: int combine_time;
                    168: int local_alloc_time;
                    169: int global_alloc_time;
                    170: int final_time;
                    171: int symout_time;
                    172: int dump_time;
                    173: 
                    174: /* Return time used so far, in microseconds.  */
                    175: 
                    176: gettime ()
                    177: {
                    178:   struct rusage rusage;
                    179:   if (quiet_flag)
                    180:     return 0;
                    181:   getrusage (0, &rusage);
                    182:   return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
                    183:          + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
                    184: }
                    185: 
                    186: #define TIMEVAR(VAR, BODY)    \
                    187:  { int otime = gettime (); BODY; VAR += gettime () - otime; }
                    188: 
                    189: print_time (str, total)
                    190:      char *str;
                    191:      int total;
                    192: {
                    193:   printf ("time in %s: %d.%06d\n", str, total / 1000000, total % 1000000);
                    194: }
                    195: 
                    196: /* Count an error or warning.  Return 1 if the message should be printed.  */
                    197: 
                    198: int
                    199: count_error (warningp)
                    200:      int warningp;
                    201: {
                    202:   if (warningp && inhibit_warnings)
                    203:     return 0;
                    204: 
                    205:   if (warningp)
                    206:     warningcount++;
                    207:   else
                    208:     errorcount++;
                    209: 
                    210:   /* If we are printing function names, make sure error message
                    211:      starts at beginning of line.  */
                    212:   if (!quiet_flag)
                    213:     fprintf (stderr, "\n");
                    214: 
                    215:   return 1;
                    216: }
                    217: 
                    218: /* Print a fatal error message.  NAME is the text.
                    219:    Also include a system error message based on `errno'.  */
                    220: 
                    221: int
                    222: pfatal_with_name (name)
                    223: {
                    224:   fprintf (stderr, "cc1: ");
                    225:   perror (name);
                    226:   exit (35);
                    227: }
                    228: 
                    229: void
                    230: fatal (s)
                    231:      char *s;
                    232: {
                    233:   yyerror (s, 0);
                    234:   exit (34);
                    235: }
                    236: 
                    237: /* Called when the start of a function definition is parsed,
                    238:    this function prints on stderr the name of the function.  */
                    239: 
                    240: void
                    241: announce_function (decl)
                    242:      tree decl;
                    243: {
                    244:   if (! quiet_flag)
                    245:     {
                    246:       fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl)));
                    247:       fflush (stderr);
                    248:     }
                    249: }
                    250: 
                    251: static tree last_error_function;
                    252: 
                    253: /* Report an error at the current line number.
                    254:    S and V are a string and an arg for `printf'.  */
                    255: 
                    256: void
                    257: yyerror (s, v)
                    258:      char *s;
                    259:      int v;                    /* @@also used as pointer */
                    260: {
                    261:   yylineerror (lineno, s, v);
                    262: }
                    263: 
                    264: /* Report an error at line LINE.
                    265:    S and V are a string and an arg for `printf'.  */
                    266: 
                    267: yylineerror (line, s, v)
                    268:      int line;
                    269:      char *s;
                    270:      int v;
                    271: {
                    272:   count_error (0);
                    273: 
                    274:   if (last_error_function != current_function_decl)
                    275:     {
                    276:       fprintf (stderr, "In function %s:\n",
                    277:               IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
                    278:       last_error_function = current_function_decl;
                    279:     }
                    280:   fprintf (stderr, "%s:%d: ", input_filename, line);
                    281:   fprintf (stderr, s, v);
                    282:   fprintf (stderr, "\n");
                    283: }
                    284: 
                    285: /* Report a warning at the current line number.
                    286:    S and V are a string and an arg for `printf'.  */
                    287: 
                    288: void
                    289: warning (s, v)
                    290:      char *s;
                    291:      int v;                    /* @@also used as pointer */
                    292: {
                    293:   warning_with_line (lineno, s, v);
                    294: }
                    295: 
                    296: /* Report a warning at line LINE.
                    297:    S and V are a string and an arg for `printf'.  */
                    298: 
                    299: warning_with_line (line, s, v)
                    300:      int line;
                    301:      char *s;
                    302:      int v;
                    303: {
                    304:   if (count_error (1) == 0)
                    305:     return;
                    306: 
                    307:   if (last_error_function != current_function_decl)
                    308:     {
                    309:       fprintf (stderr, "In function %s:\n",
                    310:               IDENTIFIER_POINTER (DECL_NAME (current_function_decl)));
                    311:       last_error_function = current_function_decl;
                    312:     }
                    313:   fprintf (stderr, "%s:%d: ", input_filename, line);
                    314: 
                    315:   fprintf (stderr, "warning: ");
                    316:   fprintf (stderr, s, v);
                    317:   fprintf (stderr, "\n");
                    318: }
                    319: 
                    320: /* When `malloc.c' is compiled with `rcheck' defined,
                    321:    it calls this function to report clobberage.  */
                    322: 
                    323: botch (s)
                    324: {
                    325:   abort ();
                    326: }
                    327: 
                    328: /* Same as `malloc' but report error if no memory available.  */
                    329: 
                    330: xmalloc (size)
                    331:      unsigned size;
                    332: {
                    333:   register int value = (int) malloc (size);
                    334:   if (value == 0)
                    335:     fatal ("Virtual memory exhausted.");
                    336:   return value;
                    337: }
                    338: 
                    339: /* Same as `realloc' but report error if no memory available.  */
                    340: 
                    341: int
                    342: xrealloc (ptr, size)
                    343:      char *ptr;
                    344:      int size;
                    345: {
                    346:   int result = realloc (ptr, size);
                    347:   if (!result)
                    348:     abort ();
                    349:   return result;
                    350: }
                    351: 
                    352: /* Return the logarithm of X, base 2, considering X unsigned,
                    353:    if X is a power of 2.  Otherwise, returns -1.  */
                    354: 
                    355: int
                    356: exact_log2 (x)
                    357:      register unsigned int x;
                    358: {
                    359:   register int log = 0;
                    360:   for (log = 0; log < HOST_BITS_PER_INT; log++)
                    361:     if (x == (1 << log))
                    362:       return log;
                    363:   return -1;
                    364: }
                    365: 
                    366: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
                    367:    If X is 0, return -1.  */
                    368: 
                    369: int
                    370: floor_log2 (x)
                    371:      register unsigned int x;
                    372: {
                    373:   register int log = 0;
                    374:   for (log = 0; log < HOST_BITS_PER_INT; log++)
                    375:     if ((x & ((-1) << log)) == 0)
                    376:       return log - 1;
                    377:   return HOST_BITS_PER_INT - 1;
                    378: }
                    379: 
                    380: /* Compile an entire file of output from cpp, named NAME.
                    381:    Write a file of assembly output and various debugging dumps.  */
                    382: 
                    383: static void
                    384: compile_file (name)
                    385:      char *name;
                    386: {
                    387:   tree globals;
                    388:   int start_time;
                    389:   int dump_base_name_length = strlen (dump_base_name);
                    390: 
                    391:   parse_time = 0;
                    392:   varconst_time = 0;
                    393:   expand_time = 0;
                    394:   jump_time = 0;
                    395:   cse_time = 0;
                    396:   loop_time = 0;
                    397:   flow_time = 0;
                    398:   combine_time = 0;
                    399:   local_alloc_time = 0;
                    400:   global_alloc_time = 0;
                    401:   final_time = 0;
                    402:   symout_time = 0;
                    403:   dump_time;
                    404: 
                    405:   /* Open input file.  */
                    406: 
                    407:   finput = fopen (name, "r");
                    408:   if (finput == 0)
                    409:     pfatal_with_name (name);
                    410: 
                    411:   /* Initialize data in various passes.  */
                    412: 
                    413:   init_tree ();
                    414:   init_lex ();
                    415:   init_rtl ();
                    416:   init_decl_processing ();
                    417:   init_optabs ();
                    418: 
                    419:   /* If tree dump desired, open the output file.  */
                    420:   if (tree_dump)
                    421:     {
                    422:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    423:       strcpy (dumpname, dump_base_name);
                    424:       strcat (dumpname, ".tree");
                    425:       tree_dump_file = fopen (dumpname, "w");
                    426:       if (tree_dump_file == 0)
                    427:        pfatal_with_name (dumpname);
                    428:     }
                    429: 
                    430:   /* If rtl dump desired, open the output file.  */
                    431:   if (rtl_dump)
                    432:     {
                    433:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    434:       strcpy (dumpname, dump_base_name);
                    435:       strcat (dumpname, ".rtl");
                    436:       rtl_dump_file = fopen (dumpname, "w");
                    437:       if (rtl_dump_file == 0)
                    438:        pfatal_with_name (dumpname);
                    439:     }
                    440: 
                    441:   /* If jump_opt dump desired, open the output file.  */
                    442:   if (jump_opt_dump)
                    443:     {
                    444:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    445:       strcpy (dumpname, dump_base_name);
                    446:       strcat (dumpname, ".jump");
                    447:       jump_opt_dump_file = fopen (dumpname, "w");
                    448:       if (jump_opt_dump_file == 0)
                    449:        pfatal_with_name (dumpname);
                    450:     }
                    451: 
                    452:   /* If cse dump desired, open the output file.  */
                    453:   if (cse_dump)
                    454:     {
                    455:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    456:       strcpy (dumpname, dump_base_name);
                    457:       strcat (dumpname, ".cse");
                    458:       cse_dump_file = fopen (dumpname, "w");
                    459:       if (cse_dump_file == 0)
                    460:        pfatal_with_name (dumpname);
                    461:     }
                    462: 
                    463:   /* If loop dump desired, open the output file.  */
                    464:   if (loop_dump)
                    465:     {
                    466:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    467:       strcpy (dumpname, dump_base_name);
                    468:       strcat (dumpname, ".loop");
                    469:       loop_dump_file = fopen (dumpname, "w");
                    470:       if (loop_dump_file == 0)
                    471:        pfatal_with_name (dumpname);
                    472:     }
                    473: 
                    474:   /* If flow dump desired, open the output file.  */
                    475:   if (flow_dump)
                    476:     {
                    477:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    478:       strcpy (dumpname, dump_base_name);
                    479:       strcat (dumpname, ".flow");
                    480:       flow_dump_file = fopen (dumpname, "w");
                    481:       if (flow_dump_file == 0)
                    482:        pfatal_with_name (dumpname);
                    483:     }
                    484: 
                    485:   /* If combine dump desired, open the output file.  */
                    486:   if (combine_dump)
                    487:     {
                    488:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 10);
                    489:       strcpy (dumpname, dump_base_name);
                    490:       strcat (dumpname, ".combine");
                    491:       combine_dump_file = fopen (dumpname, "w");
                    492:       if (combine_dump_file == 0)
                    493:        pfatal_with_name (dumpname);
                    494:     }
                    495: 
                    496:   /* If local_reg dump desired, open the output file.  */
                    497:   if (local_reg_dump)
                    498:     {
                    499:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    500:       strcpy (dumpname, dump_base_name);
                    501:       strcat (dumpname, ".lreg");
                    502:       local_reg_dump_file = fopen (dumpname, "w");
                    503:       if (local_reg_dump_file == 0)
                    504:        pfatal_with_name (dumpname);
                    505:     }
                    506: 
                    507:   /* If global_reg dump desired, open the output file.  */
                    508:   if (global_reg_dump)
                    509:     {
                    510:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    511:       strcpy (dumpname, dump_base_name);
                    512:       strcat (dumpname, ".greg");
                    513:       global_reg_dump_file = fopen (dumpname, "w");
                    514:       if (global_reg_dump_file == 0)
                    515:        pfatal_with_name (dumpname);
                    516:     }
                    517: 
                    518:   /* Open assembler code output file.  */
                    519:  
                    520:   {
                    521:     register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    522:     strcpy (dumpname, dump_base_name);
                    523:     strcat (dumpname, ".s");
                    524:     asm_out_file = fopen (asm_file_name ? asm_file_name : dumpname, "w");
                    525:     if (asm_out_file == 0)
                    526:       pfatal_with_name (asm_file_name ? asm_file_name : dumpname);
                    527:   }
                    528: 
                    529:   input_filename = name;
                    530: 
                    531:   /* the beginning of the file is a new line; check for # */
                    532:   /* With luck, we discover the real source file's name from that
                    533:      and put it in input_filename.  */
                    534:   check_newline ();
                    535: 
                    536:   /* If GDB symbol table desired, open the GDB symbol output file.  */
                    537:   if (write_symbols == 1)
                    538:     {
                    539:       register char *dumpname = (char *) xmalloc (dump_base_name_length + 6);
                    540:       strcpy (dumpname, dump_base_name);
                    541:       strcat (dumpname, ".sym");
                    542:       if (sym_file_name == 0)
                    543:        sym_file_name = dumpname;
                    544:       symout_init (sym_file_name, asm_out_file, input_filename);
                    545:     }
                    546: 
                    547:   /* If dbx symbol table desired, initialize writing it
                    548:      and output the predefined types.  */
                    549:   if (write_symbols == 2)
                    550:     dbxout_init (asm_out_file, input_filename);
                    551: 
                    552:   /* Initialize yet another pass.  */
                    553: 
                    554:   init_final (input_filename);
                    555: 
                    556:   start_time = gettime ();
                    557: 
                    558:   /* Call the parser, which parses the entire file
                    559:      (calling rest_of_compilation for each function).  */
                    560: 
                    561:   yyparse ();
                    562: 
                    563:   /* Compilation is now finished except for writing
                    564:      what's left of the symbol table output.  */
                    565: 
                    566:   parse_time += gettime () - start_time;
                    567: 
                    568:   globals = getdecls ();
                    569: 
                    570:   /* Do dbx symbols */
                    571:   if (write_symbols == 2)
                    572:     TIMEVAR (symout_time,
                    573:             {
                    574:               dbxout_tags (gettags ());
                    575:               dbxout_types (get_permanent_types ());
                    576:             });
                    577: 
                    578:   /* Do gdb symbols */
                    579:   if (write_symbols == 1)
                    580:     TIMEVAR (symout_time,
                    581:             {
                    582:               struct stat statbuf;
                    583:               fstat (fileno (finput), &statbuf);
                    584:               symout_types (get_permanent_types ());
                    585:               symout_top_blocks (globals, gettags ());
                    586:               symout_finish (name, statbuf.st_ctime);
                    587:             });
                    588: 
                    589:   /* Close non-debugging input and output files.  */
                    590: 
                    591:   fclose (finput);
                    592:   fclose (asm_out_file);
                    593: 
                    594:   if (!quiet_flag)
                    595:     fprintf (stderr,"\n");
                    596: 
                    597:   /* Dump the global nodes and close the tree dump file.  */
                    598:   if (tree_dump)
                    599:     {
                    600:       dump_tree (tree_dump_file, globals);
                    601:       fclose (tree_dump_file);
                    602:     }
                    603: 
                    604:   /* Close all other dump files.  */
                    605: 
                    606:   if (rtl_dump)
                    607:     fclose (rtl_dump_file);
                    608: 
                    609:   if (jump_opt_dump)
                    610:     fclose (jump_opt_dump_file);
                    611: 
                    612:   if (cse_dump)
                    613:     fclose (cse_dump_file);
                    614: 
                    615:   if (loop_dump)
                    616:     fclose (loop_dump_file);
                    617: 
                    618:   if (flow_dump)
                    619:     fclose (flow_dump_file);
                    620: 
                    621:   if (combine_dump)
                    622:     {
                    623:       dump_combine_total_stats (combine_dump_file);
                    624:       fclose (combine_dump_file);
                    625:     }
                    626: 
                    627:   if (local_reg_dump)
                    628:     fclose (local_reg_dump_file);
                    629: 
                    630:   if (global_reg_dump)
                    631:     fclose (global_reg_dump_file);
                    632: 
                    633:   /* Print the times.  */
                    634: 
                    635:   if (! quiet_flag)
                    636:     {
                    637:       print_time ("parse", parse_time);
                    638:       print_time ("expand", expand_time);
                    639:       print_time ("jump", jump_time);
                    640:       print_time ("cse", cse_time);
                    641:       print_time ("loop", loop_time);
                    642:       print_time ("flow", flow_time);
                    643:       print_time ("combine", combine_time);
                    644:       print_time ("local-alloc", local_alloc_time);
                    645:       print_time ("global-alloc", global_alloc_time);
                    646:       print_time ("final", final_time);
                    647:       print_time ("varconst", varconst_time);
                    648:       print_time ("symout", symout_time);
                    649:       print_time ("dump", dump_time);
                    650:     }
                    651: }
                    652: 
                    653: /* This is called from finish_function (within yyparse)
                    654:    after each top-level definition is parsed, and from
                    655:    finish_decl (also within yyparse) for each other top-level declaration.
                    656:    It is supposed to compile that function or variable
                    657:    and output the assembler code for it.
                    658:    After we return, the tree storage is freed.  */
                    659: 
                    660: void
                    661: rest_of_compilation (decl, top_level)
                    662:      tree decl;
                    663:      int top_level;
                    664: {
                    665:   register rtx insns;
                    666:   int start_time = gettime ();
                    667:   int tem;
                    668: 
                    669:   /* Declarations of variables, and of functions defined elsewhere.  */
                    670: 
                    671:   if ((TREE_CODE (decl) == VAR_DECL
                    672:        || (TREE_CODE (decl) == FUNCTION_DECL
                    673:           && DECL_INITIAL (decl) == 0))
                    674:       && (TREE_STATIC  (decl) || TREE_EXTERNAL (decl)))
                    675:     {
                    676:       TIMEVAR (varconst_time,
                    677:               {
                    678:                 assemble_variable (decl, top_level);
                    679:                 if (write_symbols == 2)
                    680:                   dbxout_symbol (decl, 0);
                    681:               });
                    682:     }
                    683: 
                    684:   /* Function definitions are the real work
                    685:      (all the rest of this function).  */
                    686: 
                    687:   else if (TREE_CODE (decl) == FUNCTION_DECL
                    688:           && DECL_INITIAL (decl))
                    689:     {
                    690:       /* Dump the function's tree if we are dumping trees.  */
                    691: 
                    692:       if (tree_dump)
                    693:        TIMEVAR (dump_time,
                    694:                 dump_tree (tree_dump_file, decl));
                    695: 
                    696:       /* Output some preliminaries for assembler.  */
                    697: 
                    698:       TIMEVAR (varconst_time, assemble_function (decl));
                    699: 
                    700:       /* Generate rtl code for this function (see stmt.c, expr.c).  */
                    701: 
                    702:       TIMEVAR (expand_time,
                    703:               {
                    704:                 init_emit (write_symbols);
                    705:                 insns = expand_function (decl, !optimize);
                    706:               });
                    707: 
                    708:       /* Dump the rtl code if we are dumping rtl.  */
                    709: 
                    710:       if (rtl_dump)
                    711:        TIMEVAR (dump_time,
                    712:                 {
                    713:                   fprintf (rtl_dump_file, "\n;; Function %s\n\n",
                    714:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    715:                   print_rtl (rtl_dump_file, insns);
                    716:                   fflush (rtl_dump_file);
                    717:                 });
                    718: 
                    719:       if (rtl_dump_and_exit)
                    720:        goto exit_rest_of_compilation;
                    721: 
                    722:       /* Do jump optimization the first time, if -opt.  */
                    723: 
                    724:       if (optimize)
                    725:        TIMEVAR (jump_time, jump_optimize (insns, 0));
                    726: 
                    727:       /* Dump rtl code after jump, if we are doing that.  */
                    728: 
                    729:       if (jump_opt_dump)
                    730:        TIMEVAR (dump_time,
                    731:                 {
                    732:                   fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
                    733:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    734:                   print_rtl (jump_opt_dump_file, insns);
                    735:                   fflush (jump_opt_dump_file);
                    736:                 });
                    737: 
                    738:       /* Perform common subexpression elimination.
                    739:         Nonzero value from `cse_main' means that jumps were simplified
                    740:         and some code may now be unreachable, so do
                    741:         jump optimization again.  */
                    742: 
                    743:       if (optimize)
                    744:        {
                    745:          TIMEVAR (cse_time, reg_scan (insns, max_reg_num ()));
                    746: 
                    747:          TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num ()));
                    748: 
                    749:          if (tem)
                    750:            TIMEVAR (jump_time, jump_optimize (insns, 0));
                    751:        }
                    752: 
                    753:       /* Dump rtl code after cse, if we are doing that.  */
                    754: 
                    755:       if (cse_dump)
                    756:        TIMEVAR (dump_time,
                    757:                 {
                    758:                   fprintf (cse_dump_file, "\n;; Function %s\n\n",
                    759:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    760:                   print_rtl (cse_dump_file, insns);
                    761:                   fflush (cse_dump_file);
                    762:                 });
                    763: 
                    764:       /* Move constant computations out of loops.  */
                    765: 
                    766:       if (optimize)
                    767:        {
                    768:          TIMEVAR (loop_time, loop_optimize (insns, max_reg_num ()));
                    769:        }
                    770: 
                    771:       /* Dump rtl code after loop opt, if we are doing that.  */
                    772: 
                    773:       if (loop_dump)
                    774:        TIMEVAR (dump_time,
                    775:                 {
                    776:                   fprintf (loop_dump_file, "\n;; Function %s\n\n",
                    777:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    778:                   print_rtl (loop_dump_file, insns);
                    779:                   fflush (loop_dump_file);
                    780:                 });
                    781: 
                    782:       /* Now we choose between stupid (pcc-like) register allocation
                    783:         (if we got the -noreg switch and not -opt)
                    784:         and smart register allocation.  */
                    785: 
                    786:       if (optimize)            /* Stupid allocation probably won't work */
                    787:        obey_regdecls = 0;      /* if optimizations being done.  */
                    788: 
                    789:       /* Print function header into flow dump now
                    790:         because doing the flow analysis makes some of the dump.  */
                    791: 
                    792:       if (flow_dump)
                    793:        TIMEVAR (dump_time,
                    794:                 {
                    795:                   fprintf (flow_dump_file, "\n;; Function %s\n\n",
                    796:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    797:                 });
                    798: 
                    799:       if (obey_regdecls)
                    800:        {
                    801:          TIMEVAR (flow_time,
                    802:                   {
                    803:                     regclass (insns, max_reg_num ());
                    804:                     stupid_life_analysis (insns, max_reg_num (),
                    805:                                           flow_dump_file);
                    806:                   });
                    807:        }
                    808:       else
                    809:        {
                    810:          /* Do control and data flow analysis,
                    811:             and write some of the results to dump file.  */
                    812: 
                    813:          TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
                    814:                                             flow_dump_file));
                    815:        }
                    816: 
                    817:       /* Dump rtl after flow analysis.  */
                    818: 
                    819:       if (flow_dump)
                    820:        TIMEVAR (dump_time,
                    821:                 {
                    822:                   print_rtl (flow_dump_file, insns);
                    823:                   fflush (flow_dump_file);
                    824:                 });
                    825: 
                    826:       /* If -opt, try combining insns through substitution.  */
                    827: 
                    828:       if (optimize)
                    829:        TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
                    830: 
                    831:       /* Dump rtl code after insn combination.  */
                    832: 
                    833:       if (combine_dump)
                    834:        TIMEVAR (dump_time,
                    835:                 {
                    836:                   fprintf (combine_dump_file, "\n;; Function %s\n\n",
                    837:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    838:                   dump_combine_stats (combine_dump_file);
                    839:                   print_rtl (combine_dump_file, insns);
                    840:                   fflush (combine_dump_file);
                    841:                 });
                    842: 
                    843:       /* Unless we did stupid register allocation,
                    844:         allocate pseudo-regs that are used only within 1 basic block.  */
                    845: 
                    846:       if (!obey_regdecls)
                    847:        TIMEVAR (local_alloc_time,
                    848:                 {
                    849:                   regclass (insns, max_reg_num ());
                    850:                   local_alloc ();
                    851:                 });
                    852: 
                    853:       /* Dump rtl code after allocating regs within basic blocks.  */
                    854: 
                    855:       if (local_reg_dump)
                    856:        TIMEVAR (dump_time,
                    857:                 {
                    858:                   fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
                    859:                            IDENTIFIER_POINTER (DECL_NAME (decl)));
                    860:                   dump_flow_info (local_reg_dump_file);
                    861:                   dump_local_alloc (local_reg_dump_file);
                    862:                   print_rtl (local_reg_dump_file, insns);
                    863:                   fflush (local_reg_dump_file);
                    864:                 });
                    865: 
                    866:       if (global_reg_dump)
                    867:        TIMEVAR (dump_time,
                    868:                 fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
                    869:                          IDENTIFIER_POINTER (DECL_NAME (decl))));
                    870: 
                    871:       /* Unless we did stupid register allocation,
                    872:         allocate remaining pseudo-regs, then do the reload pass
                    873:         fixing up any insns that are invalid.  */
                    874: 
                    875:       TIMEVAR (global_alloc_time,
                    876:               {
                    877:                 if (!obey_regdecls)
                    878:                   global_alloc (global_reg_dump ? global_reg_dump_file : 0);
                    879:                 else
                    880:                   reload (insns, 0,
                    881:                           global_reg_dump ? global_reg_dump_file : 0);
                    882:               });
                    883: 
                    884:       if (global_reg_dump)
                    885:        TIMEVAR (dump_time,
                    886:                 {
                    887:                   dump_global_regs (global_reg_dump_file);
                    888:                   print_rtl (global_reg_dump_file, insns);
                    889:                   fflush (global_reg_dump_file);
                    890:                 });
                    891: 
                    892:       /* One more attempt to remove jumps to .+1
                    893:         left by dead-store-elimination.
                    894:         Also do cross-jumping this time.  */
                    895: 
                    896:       if (optimize)
                    897:        TIMEVAR (jump_time, jump_optimize (insns, 1));
                    898: 
                    899:       /* Now turn the rtl into assembler code.  */
                    900: 
                    901:       TIMEVAR (final_time,
                    902:               {
                    903:                 final (insns, asm_out_file,
                    904:                        IDENTIFIER_POINTER (DECL_NAME (decl)),
                    905:                        write_symbols, optimize);
                    906:                 fflush (asm_out_file);
                    907:               });
                    908: 
                    909:       /* Write GDB symbols if requested */
                    910: 
                    911:       if (write_symbols == 1)
                    912:        TIMEVAR (symout_time,
                    913:                 {
                    914:                   symout_types (get_permanent_types ());
                    915:                   symout_types (get_temporary_types ());
                    916: 
                    917:                   DECL_BLOCK_SYMTAB_ADDRESS (decl)
                    918:                     = symout_function (DECL_INITIAL (decl),
                    919:                                        DECL_ARGUMENTS (decl), 0);
                    920:                 });
                    921: 
                    922:       /* Write DBX symbols if requested */
                    923: 
                    924:       if (write_symbols == 2)
                    925:        TIMEVAR (symout_time, dbxout_function (decl));
                    926:     }
                    927: 
                    928:  exit_rest_of_compilation:
                    929: 
                    930:   /* The parsing time is all the time spent in yyparse
                    931:      *except* what is spent in this function.  */
                    932: 
                    933:   parse_time -= gettime () - start_time;
                    934: }
                    935: 
                    936: /* Entry point of cc1.  Decode command args, then call compile_file.
                    937:    Exit code is 34 if fatal error, else 33 if have error messages,
                    938:    else 1 if have warnings, else 0.  */
                    939: 
                    940: int
                    941: main (argc, argv, envp)
                    942:      int argc;
                    943:      char **argv;
                    944:      char **envp;
                    945: {
                    946:   register int i;
                    947:   char *filename;
                    948: 
                    949:   target_flags = 0;
                    950:   set_target_switch ("");
                    951: 
                    952:   for (i = 1; i < argc; i++)
                    953:     if (argv[i][0] == '-')
                    954:       {
                    955:        register char *str = argv[i] + 1;
                    956:        if (str[0] == 'Y')
                    957:          str++;
                    958: 
                    959:        if (str[0] == 'm')
                    960:          set_target_switch (&str[1]);
                    961:        else if (!strcmp (str, "dumpbase"))
                    962:          {
                    963:            dump_base_name = argv[++i];
                    964:          }
                    965:        else if (str[0] == 'd')
                    966:          {
                    967:            register char *p = &str[1];
                    968:            while (*p)
                    969:              switch (*p++)
                    970:                {
                    971:                case 'c':
                    972:                  combine_dump = 1;
                    973:                  break;
                    974:                case 'f':
                    975:                  flow_dump = 1;
                    976:                  break;
                    977:                case 'g':
                    978:                  global_reg_dump = 1;
                    979:                  break;
                    980:                case 'j':
                    981:                  jump_opt_dump = 1;
                    982:                  break;
                    983:                case 'l':
                    984:                  local_reg_dump = 1;
                    985:                  break;
                    986:                case 'L':
                    987:                  loop_dump = 1;
                    988:                  break;
                    989:                case 'r':
                    990:                  rtl_dump = 1;
                    991:                  break;
                    992:                case 's':
                    993:                  cse_dump = 1;
                    994:                  break;
                    995:                case 't':
                    996:                  tree_dump = 1;
                    997:                  break;
                    998:                case 'y':
                    999:                  yydebug = 1;
                   1000:                  break;
                   1001:                }
                   1002:          }
                   1003:        else if (!strcmp (str, "quiet"))
                   1004:          quiet_flag = 1;
                   1005:        else if (!strcmp (str, "opt"))
                   1006:          optimize = 1;
                   1007:        else if (!strcmp (str, "optforcemem"))
                   1008:          force_mem = 1;
                   1009:        else if (!strcmp (str, "optforceaddr"))
                   1010:          force_addr = 1;
                   1011:        else if (!strcmp (str, "noreg"))
                   1012:          obey_regdecls = 1;
                   1013:        else if (!strcmp (str, "w"))
                   1014:          inhibit_warnings = 1;
                   1015:        else if (!strcmp (str, "g"))
                   1016:          write_symbols = 1;
                   1017:        else if (!strcmp (str, "G"))
                   1018:          write_symbols = 2;
                   1019:        else if (!strcmp (str, "symout"))
                   1020:          {
                   1021:            if (write_symbols == 0)
                   1022:              write_symbols = 1;
                   1023:            sym_file_name = argv[++i];
                   1024:          }
                   1025:        else if (!strcmp (str, "o"))
                   1026:          {
                   1027:            asm_file_name = argv[++i];
                   1028:          }
                   1029:        else
                   1030:          yylineerror (0, "Invalid switch, %s.", argv[i]);
                   1031:       }
                   1032:     else
                   1033:       filename = argv[i];
                   1034: 
                   1035:   if (filename == 0)
                   1036:     fatal ("no input file specified");
                   1037: 
                   1038:   if (dump_base_name == 0)
                   1039:     dump_base_name = filename;
                   1040:   compile_file (filename);
                   1041: 
                   1042:   if (errorcount)
                   1043:     return 33;
                   1044:   else
                   1045:     return (warningcount > 0);
                   1046: }
                   1047: 
                   1048: /* Decode -m switches.  */
                   1049: 
                   1050: /* Here is a table, controlled by the tm-...h file, listing each -m switch
                   1051:    and which bits in `target_switches' it should set or clear.
                   1052:    If VALUE is positive, it is bits to set.
                   1053:    If VALUE is negative, -VALUE is bits to clear.
                   1054:    (The sign bit is not used so there is no confusion.)  */
                   1055: 
                   1056: struct {char *name; int value;} target_switches []
                   1057:   = TARGET_SWITCHES;
                   1058: 
                   1059: /* Decode the switch -mNAME.  */
                   1060: 
                   1061: set_target_switch (name)
                   1062:      char *name;
                   1063: {
                   1064:   register int j = 0;
                   1065:   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
                   1066:     if (!strcmp (target_switches[j].name, name))
                   1067:       {
                   1068:        if (target_switches[j].value < 0)
                   1069:          target_flags &= ~-target_switches[j].value;
                   1070:        else
                   1071:          target_flags |= target_switches[j].value;
                   1072:        break;
                   1073:       }
                   1074: }

unix.superglobalmegacorp.com

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