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