|
|
1.1 root 1: /* Top level of GNU C compiler 1.1.1.2 ! root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc. 1.1 root 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> 1.1.1.2 ! root 30: ! 31: #ifdef USG ! 32: #include <sys/param.h> ! 33: #include <sys/times.h> ! 34: #include <time.h> /* Correct for hpux at least. Is it good on other USG? */ ! 35: #else ! 36: #ifndef VMS 1.1 root 37: #include <sys/time.h> 38: #include <sys/resource.h> 1.1.1.2 ! root 39: #endif ! 40: #endif ! 41: 1.1 root 42: #ifndef _TYPES_ 43: #include <sys/types.h> 44: #endif 45: #include <sys/stat.h> 1.1.1.2 ! root 46: 1.1 root 47: #include "tree.h" 48: #include "c-tree.h" 49: #include "rtl.h" 1.1.1.2 ! root 50: #include "flags.h" 1.1 root 51: 52: extern int yydebug; 53: 54: extern FILE *finput; 55: 56: extern void init_lex (); 57: extern void init_decl_processing (); 58: extern void init_tree (); 59: extern void init_rtl (); 60: extern void init_optabs (); 1.1.1.2 ! root 61: extern void init_reg_sets (); 1.1 root 62: extern void dump_flow_info (); 63: extern void dump_local_alloc (); 64: 1.1.1.2 ! root 65: void rest_of_decl_compilation (); ! 66: void error (); ! 67: void error_with_file_and_line (); ! 68: void set_target_switch (); ! 69: 1.1 root 70: /* Bit flags that specify the machine subtype we are compiling for. 71: Bits are tested using macros TARGET_... defined in the tm-...h file 72: and set by `-m...' switches. */ 73: 74: int target_flags; 75: 1.1.1.2 ! root 76: /* Name of current original source file (what was input to cpp). ! 77: This comes from each #-command in the actual input. */ 1.1 root 78: 1.1.1.2 ! root 79: char *input_filename; ! 80: ! 81: /* Name of top-level original source file (what was input to cpp). ! 82: This comes from the first #-command in the actual input. */ ! 83: ! 84: char *main_input_filename; 1.1 root 85: 86: /* Current line number in real source file. */ 87: 88: extern int lineno; 89: 90: /* FUNCTION_DECL for function now being parsed or compiled. */ 91: 92: extern tree current_function_decl; 93: 94: /* Name to use as base of names for dump output files. */ 95: 96: char *dump_base_name; 97: 98: /* Flags saying which kinds of debugging dump have been requested. */ 99: 100: int rtl_dump = 0; 101: int rtl_dump_and_exit = 0; 102: int jump_opt_dump = 0; 103: int cse_dump = 0; 104: int loop_dump = 0; 105: int flow_dump = 0; 106: int combine_dump = 0; 107: int local_reg_dump = 0; 108: int global_reg_dump = 0; 1.1.1.2 ! root 109: int jump2_opt_dump = 0; 1.1 root 110: 111: /* 1 => write gdb debugging output (using symout.c). -g 112: 2 => write dbx debugging output (using dbxout.c). -G */ 113: 114: int write_symbols = 0; 115: 116: /* Nonzero means do optimizations. -opt. */ 117: 118: int optimize = 0; 119: 1.1.1.2 ! root 120: /* Nonzero for -fforce-mem: load memory value into a register 1.1 root 121: before arithmetic on it. This makes better cse but slower compilation. */ 122: 1.1.1.2 ! root 123: int flag_force_mem = 0; 1.1 root 124: 1.1.1.2 ! root 125: /* Nonzero for -fforce-addr: load memory address into a register before 1.1 root 126: reference to memory. This makes better cse but slower compilation. */ 127: 1.1.1.2 ! root 128: int flag_force_addr = 0; ! 129: ! 130: /* Nonzero for -fdefer-pop: don't pop args after each function call; ! 131: instead save them up to pop many calls' args with one insns. */ ! 132: ! 133: int flag_defer_pop = 1; ! 134: ! 135: /* Nonzero for -ffloat-store: don't allocate floats and doubles ! 136: in extended-precision registers. */ ! 137: ! 138: int flag_float_store = 0; ! 139: ! 140: /* Nonzero for -fcombine-regs: ! 141: allow instruction combiner to combine an insn ! 142: that just copies one reg to another. */ ! 143: ! 144: int flag_combine_regs = 0; ! 145: ! 146: /* Nonzero for -fwritable-strings: ! 147: store string constants in data segment and don't uniquize them. */ ! 148: ! 149: int flag_writable_strings = 0; ! 150: ! 151: /* Nonzero means don't put addresses of constant functions in registers. ! 152: Used for compiling the Unix kernel, where strange substitutions are ! 153: done on the assembly output. */ ! 154: ! 155: int flag_no_function_cse = 0; ! 156: ! 157: /* Nonzero for -fomit-frame-pointer: ! 158: don't make a frame pointer in simple functions that don't require one. */ ! 159: ! 160: int flag_omit_frame_pointer = 0; ! 161: ! 162: /* Nonzero to inhibit use of define_optimization peephole opts. */ ! 163: ! 164: int flag_no_peephole = 0; ! 165: ! 166: /* Nonzero means `char' should be signed. */ ! 167: ! 168: int flag_signed_char; ! 169: ! 170: /* Nonzero means allow type mismatches in conditional expressions; ! 171: just make their values `void'. */ ! 172: ! 173: int flag_cond_mismatch; ! 174: ! 175: /* Nonzero means don't recognize the keyword `asm'. */ ! 176: ! 177: int flag_no_asm; ! 178: ! 179: /* Nonzero means warn about implicit declarations. */ ! 180: ! 181: int warn_implicit; ! 182: ! 183: /* Nonzero means warn about function definitions that default the return type ! 184: or that use a null return and have a return-type other than void. */ ! 185: ! 186: int warn_return_type; ! 187: ! 188: /* Nonzero means do some things the same way PCC does. */ ! 189: ! 190: int flag_traditional; ! 191: ! 192: /* Nonzero means all references through pointers are volatile. */ ! 193: ! 194: int flag_volatile; 1.1 root 195: 196: /* Nonzero means do stupid register allocation. -noreg. 1.1.1.2 ! root 197: This and `optimize' are controlled by different switches in cc1, 1.1 root 198: but normally cc controls them both with the -O switch. */ 199: 200: int obey_regdecls = 0; 201: 202: /* Don't print functions as they are compiled and don't print 203: times taken by the various passes. -quiet. */ 204: 205: int quiet_flag = 0; 206: 207: /* Don't print warning messages. -w. */ 208: 209: int inhibit_warnings = 0; 210: 1.1.1.2 ! root 211: /* Do print extra warnings (such as for uninitialized variables). -W. */ ! 212: ! 213: int extra_warnings = 0; ! 214: 1.1 root 215: /* Number of error messages and warning messages so far. */ 216: 217: int errorcount = 0; 218: int warningcount = 0; 219: 1.1.1.2 ! root 220: /* Nonzero if generating code to do profiling. */ ! 221: ! 222: int profile_flag = 0; ! 223: 1.1 root 224: /* Nonzero for -pedantic switch: warn about anything 225: that standard C forbids. */ 226: 227: int pedantic = 0; 228: 1.1.1.2 ! root 229: /* Nonzero for -finline-functions: ok to inline functions that look like ! 230: good inline candidates. */ ! 231: ! 232: int flag_inline_functions; ! 233: ! 234: /* Nonzero for -fkeep-inline-functions: even if we make a function ! 235: go inline everywhere, keep its defintion around for debugging ! 236: purposes. */ ! 237: ! 238: int flag_keep_inline_functions; ! 239: 1.1 root 240: /* Name for output file of assembly code, specified with -o. */ 241: 242: char *asm_file_name; 243: 244: /* Name for output file of GDB symbol segment, specified with -symout. */ 245: 246: char *sym_file_name; 247: 248: /* Output files for assembler code (real compiler output) 249: and debugging dumps. */ 250: 251: FILE *asm_out_file; 252: FILE *rtl_dump_file; 253: FILE *jump_opt_dump_file; 254: FILE *cse_dump_file; 255: FILE *loop_dump_file; 256: FILE *flow_dump_file; 257: FILE *combine_dump_file; 258: FILE *local_reg_dump_file; 259: FILE *global_reg_dump_file; 1.1.1.2 ! root 260: FILE *jump2_opt_dump_file; 1.1 root 261: 262: /* Time accumulators, to count the total time spent in various passes. */ 263: 264: int parse_time; 265: int varconst_time; 1.1.1.2 ! root 266: int integration_time; 1.1 root 267: int jump_time; 268: int cse_time; 269: int loop_time; 270: int flow_time; 271: int combine_time; 272: int local_alloc_time; 273: int global_alloc_time; 274: int final_time; 275: int symout_time; 276: int dump_time; 277: 278: /* Return time used so far, in microseconds. */ 279: 1.1.1.2 ! root 280: int 1.1 root 281: gettime () 282: { 1.1.1.2 ! root 283: #ifdef USG ! 284: struct tms tms; ! 285: #else ! 286: #ifndef VMS 1.1 root 287: struct rusage rusage; 1.1.1.2 ! root 288: #else /* VMS */ ! 289: struct ! 290: { ! 291: int proc_user_time; ! 292: int proc_system_time; ! 293: int child_user_time; ! 294: int child_system_time; ! 295: } vms_times; ! 296: #endif ! 297: #endif ! 298: 1.1 root 299: if (quiet_flag) 300: return 0; 1.1.1.2 ! root 301: ! 302: #ifdef USG ! 303: times (&tms); ! 304: return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ); ! 305: #else ! 306: #ifndef VMS 1.1 root 307: getrusage (0, &rusage); 308: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec 309: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); 1.1.1.2 ! root 310: #else /* VMS */ ! 311: times (&vms_times); ! 312: return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; ! 313: #endif ! 314: #endif 1.1 root 315: } 316: 317: #define TIMEVAR(VAR, BODY) \ 318: { int otime = gettime (); BODY; VAR += gettime () - otime; } 319: 1.1.1.2 ! root 320: void 1.1 root 321: print_time (str, total) 322: char *str; 323: int total; 324: { 1.1.1.2 ! root 325: fprintf (stderr, ! 326: "time in %s: %d.%06d\n", ! 327: str, total / 1000000, total % 1000000); 1.1 root 328: } 329: 330: /* Count an error or warning. Return 1 if the message should be printed. */ 331: 332: int 333: count_error (warningp) 334: int warningp; 335: { 336: if (warningp && inhibit_warnings) 337: return 0; 338: 339: if (warningp) 340: warningcount++; 341: else 342: errorcount++; 343: 344: return 1; 345: } 346: 347: /* Print a fatal error message. NAME is the text. 348: Also include a system error message based on `errno'. */ 349: 1.1.1.2 ! root 350: void 1.1 root 351: pfatal_with_name (name) 1.1.1.2 ! root 352: char *name; 1.1 root 353: { 354: fprintf (stderr, "cc1: "); 355: perror (name); 356: exit (35); 357: } 358: 359: void 1.1.1.2 ! root 360: fatal_io_error (name) ! 361: char *name; ! 362: { ! 363: fprintf (stderr, "cc1:%s: I/O error\n", name); ! 364: exit (35); ! 365: } ! 366: ! 367: void 1.1 root 368: fatal (s) 369: char *s; 370: { 1.1.1.2 ! root 371: error (s, 0); 1.1 root 372: exit (34); 373: } 374: 375: /* Called when the start of a function definition is parsed, 376: this function prints on stderr the name of the function. */ 377: 378: void 379: announce_function (decl) 380: tree decl; 381: { 382: if (! quiet_flag) 383: { 384: fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl))); 385: fflush (stderr); 386: } 387: } 388: 1.1.1.2 ! root 389: /* Prints out, if necessary, the name of the current function ! 390: which caused an error. Called from all error and warning functions. */ ! 391: ! 392: void ! 393: report_error_function() ! 394: { ! 395: static tree last_error_function = NULL; ! 396: ! 397: if (last_error_function != current_function_decl) ! 398: { ! 399: if (current_function_decl == NULL) ! 400: { ! 401: if (!quiet_flag) ! 402: fprintf (stderr, "\n"); ! 403: fprintf (stderr, "At top level:\n"); ! 404: } ! 405: else ! 406: { ! 407: if (!quiet_flag) ! 408: /* We already know this info. Don't print it twice. ! 409: But make sure we are at the beginning of a line. */ ! 410: fprintf (stderr, "\n"); ! 411: else ! 412: fprintf (stderr, "In function %s:\n", ! 413: IDENTIFIER_POINTER (DECL_NAME (current_function_decl))); ! 414: } ! 415: last_error_function = current_function_decl; ! 416: } ! 417: } 1.1 root 418: 419: /* Report an error at the current line number. 420: S and V are a string and an arg for `printf'. */ 421: 422: void 1.1.1.2 ! root 423: error (s, v) 1.1 root 424: char *s; 425: int v; /* @@also used as pointer */ 426: { 1.1.1.2 ! root 427: error_with_file_and_line (input_filename, lineno, s, v); 1.1 root 428: } 429: 1.1.1.2 ! root 430: /* Report an error at line LINE of file FILE. 1.1 root 431: S and V are a string and an arg for `printf'. */ 432: 1.1.1.2 ! root 433: void ! 434: error_with_file_and_line (file, line, s, v) ! 435: char *file; 1.1 root 436: int line; 437: char *s; 438: int v; 439: { 440: count_error (0); 441: 1.1.1.2 ! root 442: report_error_function (); ! 443: ! 444: if (file) ! 445: fprintf (stderr, "%s:%d: ", file, line); ! 446: else ! 447: fprintf (stderr, "cc1: "); 1.1 root 448: fprintf (stderr, s, v); 449: fprintf (stderr, "\n"); 450: } 451: 1.1.1.2 ! root 452: /* Report an error at the declaration DECL. ! 453: S is string which uses %s to substitute the declaration name. */ 1.1 root 454: 455: void 1.1.1.2 ! root 456: error_with_decl (decl, s) ! 457: tree decl; 1.1 root 458: char *s; 459: { 1.1.1.2 ! root 460: count_error (0); ! 461: ! 462: report_error_function (); ! 463: ! 464: fprintf (stderr, "%s:%d: ", ! 465: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 466: ! 467: if (DECL_NAME (decl)) ! 468: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl))); ! 469: else ! 470: fprintf (stderr, s, "((anonymous))"); ! 471: fprintf (stderr, "\n"); 1.1 root 472: } 473: 474: /* Report a warning at line LINE. 475: S and V are a string and an arg for `printf'. */ 476: 1.1.1.2 ! root 477: void 1.1 root 478: warning_with_line (line, s, v) 479: int line; 480: char *s; 481: int v; 482: { 483: if (count_error (1) == 0) 484: return; 485: 1.1.1.2 ! root 486: report_error_function (); ! 487: ! 488: if (input_filename) ! 489: fprintf (stderr, "%s:%d: ", input_filename, line); ! 490: else ! 491: fprintf (stderr, "cc1: "); 1.1 root 492: 493: fprintf (stderr, "warning: "); 494: fprintf (stderr, s, v); 495: fprintf (stderr, "\n"); 496: } 1.1.1.2 ! root 497: ! 498: /* Report a warning at the current line number. ! 499: S and V are a string and an arg for `printf'. */ ! 500: ! 501: void ! 502: warning (s, v) ! 503: char *s; ! 504: int v; /* @@also used as pointer */ ! 505: { ! 506: warning_with_line (lineno, s, v); ! 507: } ! 508: ! 509: /* Report a warning at the declaration DECL. ! 510: S is string which uses %s to substitute the declaration name. */ ! 511: ! 512: void ! 513: warning_with_decl (decl, s) ! 514: tree decl; ! 515: char *s; ! 516: { ! 517: if (count_error (1) == 0) ! 518: return; ! 519: ! 520: report_error_function (); ! 521: ! 522: fprintf (stderr, "%s:%d: ", ! 523: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 524: ! 525: fprintf (stderr, "warning: "); ! 526: if (DECL_NAME (decl)) ! 527: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl))); ! 528: else ! 529: fprintf (stderr, s, "((anonymous))"); ! 530: fprintf (stderr, "\n"); ! 531: } 1.1 root 532: 533: /* When `malloc.c' is compiled with `rcheck' defined, 534: it calls this function to report clobberage. */ 535: 1.1.1.2 ! root 536: void 1.1 root 537: botch (s) 538: { 539: abort (); 540: } 541: 542: /* Same as `malloc' but report error if no memory available. */ 543: 1.1.1.2 ! root 544: int 1.1 root 545: xmalloc (size) 546: unsigned size; 547: { 548: register int value = (int) malloc (size); 549: if (value == 0) 550: fatal ("Virtual memory exhausted."); 551: return value; 552: } 553: 554: /* Same as `realloc' but report error if no memory available. */ 555: 556: int 557: xrealloc (ptr, size) 558: char *ptr; 559: int size; 560: { 561: int result = realloc (ptr, size); 562: if (!result) 1.1.1.2 ! root 563: fatal ("Virtual memory exhausted."); 1.1 root 564: return result; 565: } 566: 567: /* Return the logarithm of X, base 2, considering X unsigned, 568: if X is a power of 2. Otherwise, returns -1. */ 569: 570: int 571: exact_log2 (x) 572: register unsigned int x; 573: { 574: register int log = 0; 575: for (log = 0; log < HOST_BITS_PER_INT; log++) 576: if (x == (1 << log)) 577: return log; 578: return -1; 579: } 580: 581: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. 582: If X is 0, return -1. */ 583: 584: int 585: floor_log2 (x) 586: register unsigned int x; 587: { 588: register int log = 0; 589: for (log = 0; log < HOST_BITS_PER_INT; log++) 590: if ((x & ((-1) << log)) == 0) 591: return log - 1; 592: return HOST_BITS_PER_INT - 1; 593: } 594: 595: /* Compile an entire file of output from cpp, named NAME. 596: Write a file of assembly output and various debugging dumps. */ 597: 598: static void 599: compile_file (name) 600: char *name; 601: { 602: tree globals; 603: int start_time; 604: int dump_base_name_length = strlen (dump_base_name); 605: 606: parse_time = 0; 607: varconst_time = 0; 1.1.1.2 ! root 608: integration_time = 0; 1.1 root 609: jump_time = 0; 610: cse_time = 0; 611: loop_time = 0; 612: flow_time = 0; 613: combine_time = 0; 614: local_alloc_time = 0; 615: global_alloc_time = 0; 616: final_time = 0; 617: symout_time = 0; 1.1.1.2 ! root 618: dump_time = 0; 1.1 root 619: 620: /* Open input file. */ 621: 622: finput = fopen (name, "r"); 623: if (finput == 0) 624: pfatal_with_name (name); 625: 626: /* Initialize data in various passes. */ 627: 628: init_tree (); 629: init_lex (); 630: init_rtl (); 1.1.1.2 ! root 631: init_emit_once (); 1.1 root 632: init_decl_processing (); 633: init_optabs (); 634: 635: /* If rtl dump desired, open the output file. */ 636: if (rtl_dump) 637: { 638: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 639: strcpy (dumpname, dump_base_name); 640: strcat (dumpname, ".rtl"); 641: rtl_dump_file = fopen (dumpname, "w"); 642: if (rtl_dump_file == 0) 643: pfatal_with_name (dumpname); 644: } 645: 646: /* If jump_opt dump desired, open the output file. */ 647: if (jump_opt_dump) 648: { 649: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 650: strcpy (dumpname, dump_base_name); 651: strcat (dumpname, ".jump"); 652: jump_opt_dump_file = fopen (dumpname, "w"); 653: if (jump_opt_dump_file == 0) 654: pfatal_with_name (dumpname); 655: } 656: 657: /* If cse dump desired, open the output file. */ 658: if (cse_dump) 659: { 660: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 661: strcpy (dumpname, dump_base_name); 662: strcat (dumpname, ".cse"); 663: cse_dump_file = fopen (dumpname, "w"); 664: if (cse_dump_file == 0) 665: pfatal_with_name (dumpname); 666: } 667: 668: /* If loop dump desired, open the output file. */ 669: if (loop_dump) 670: { 671: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 672: strcpy (dumpname, dump_base_name); 673: strcat (dumpname, ".loop"); 674: loop_dump_file = fopen (dumpname, "w"); 675: if (loop_dump_file == 0) 676: pfatal_with_name (dumpname); 677: } 678: 679: /* If flow dump desired, open the output file. */ 680: if (flow_dump) 681: { 682: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 683: strcpy (dumpname, dump_base_name); 684: strcat (dumpname, ".flow"); 685: flow_dump_file = fopen (dumpname, "w"); 686: if (flow_dump_file == 0) 687: pfatal_with_name (dumpname); 688: } 689: 690: /* If combine dump desired, open the output file. */ 691: if (combine_dump) 692: { 693: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); 694: strcpy (dumpname, dump_base_name); 695: strcat (dumpname, ".combine"); 696: combine_dump_file = fopen (dumpname, "w"); 697: if (combine_dump_file == 0) 698: pfatal_with_name (dumpname); 699: } 700: 701: /* If local_reg dump desired, open the output file. */ 702: if (local_reg_dump) 703: { 704: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 705: strcpy (dumpname, dump_base_name); 706: strcat (dumpname, ".lreg"); 707: local_reg_dump_file = fopen (dumpname, "w"); 708: if (local_reg_dump_file == 0) 709: pfatal_with_name (dumpname); 710: } 711: 712: /* If global_reg dump desired, open the output file. */ 713: if (global_reg_dump) 714: { 715: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 716: strcpy (dumpname, dump_base_name); 717: strcat (dumpname, ".greg"); 718: global_reg_dump_file = fopen (dumpname, "w"); 719: if (global_reg_dump_file == 0) 720: pfatal_with_name (dumpname); 721: } 722: 1.1.1.2 ! root 723: /* If jump2_opt dump desired, open the output file. */ ! 724: if (jump2_opt_dump) ! 725: { ! 726: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 727: strcpy (dumpname, dump_base_name); ! 728: strcat (dumpname, ".jump2"); ! 729: jump2_opt_dump_file = fopen (dumpname, "w"); ! 730: if (jump2_opt_dump_file == 0) ! 731: pfatal_with_name (dumpname); ! 732: } ! 733: 1.1 root 734: /* Open assembler code output file. */ 735: 736: { 737: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 1.1.1.2 ! root 738: int len = strlen (dump_base_name); 1.1 root 739: strcpy (dumpname, dump_base_name); 1.1.1.2 ! root 740: if (len > 2 && ! strcmp (".c", dumpname + len - 2)) ! 741: dumpname[len - 2] = 0; ! 742: else if (len > 3 && ! strcmp (".co", dumpname + len - 3)) ! 743: dumpname[len - 3] = 0; 1.1 root 744: strcat (dumpname, ".s"); 1.1.1.2 ! root 745: if (asm_file_name == 0) ! 746: { ! 747: asm_file_name = (char *) malloc (strlen (dumpname) + 1); ! 748: strcpy (asm_file_name, dumpname); ! 749: } ! 750: asm_out_file = fopen (asm_file_name, "w"); 1.1 root 751: if (asm_out_file == 0) 752: pfatal_with_name (asm_file_name ? asm_file_name : dumpname); 1.1.1.2 ! root 753: fprintf (asm_out_file, ASM_FILE_START); 1.1 root 754: } 755: 756: input_filename = name; 757: 758: /* the beginning of the file is a new line; check for # */ 759: /* With luck, we discover the real source file's name from that 760: and put it in input_filename. */ 761: check_newline (); 762: 763: /* If GDB symbol table desired, open the GDB symbol output file. */ 764: if (write_symbols == 1) 765: { 766: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); 1.1.1.2 ! root 767: int len = strlen (dump_base_name); 1.1 root 768: strcpy (dumpname, dump_base_name); 1.1.1.2 ! root 769: if (len > 2 && ! strcmp (".c", dumpname + len - 2)) ! 770: dumpname[len - 2] = 0; ! 771: else if (len > 3 && ! strcmp (".co", dumpname + len - 3)) ! 772: dumpname[len - 3] = 0; 1.1 root 773: strcat (dumpname, ".sym"); 774: if (sym_file_name == 0) 775: sym_file_name = dumpname; 776: symout_init (sym_file_name, asm_out_file, input_filename); 777: } 778: 779: /* If dbx symbol table desired, initialize writing it 780: and output the predefined types. */ 781: if (write_symbols == 2) 1.1.1.2 ! root 782: dbxout_init (asm_out_file, main_input_filename); 1.1 root 783: 784: /* Initialize yet another pass. */ 785: 1.1.1.2 ! root 786: init_final (main_input_filename); 1.1 root 787: 788: start_time = gettime (); 789: 790: /* Call the parser, which parses the entire file 791: (calling rest_of_compilation for each function). */ 792: 793: yyparse (); 794: 795: /* Compilation is now finished except for writing 796: what's left of the symbol table output. */ 797: 798: parse_time += gettime () - start_time; 799: 1.1.1.2 ! root 800: parse_time -= varconst_time; ! 801: 1.1 root 802: globals = getdecls (); 803: 1.1.1.2 ! root 804: /* Really define vars that have had only a tentative definition. ! 805: Really output inline functions that must actually be callable ! 806: and have not been output so far. */ ! 807: ! 808: { ! 809: tree decl; ! 810: for (decl = globals; decl; decl = TREE_CHAIN (decl)) ! 811: { ! 812: if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) ! 813: && ! TREE_ASM_WRITTEN (decl)) ! 814: rest_of_decl_compilation (decl, 0, 1, 1); ! 815: if (TREE_CODE (decl) == FUNCTION_DECL ! 816: && ! TREE_ASM_WRITTEN (decl) ! 817: && DECL_INITIAL (decl) != 0 ! 818: && TREE_ADDRESSABLE (decl)) ! 819: output_inline_function (decl); ! 820: } ! 821: } ! 822: 1.1 root 823: /* Do dbx symbols */ 824: if (write_symbols == 2) 825: TIMEVAR (symout_time, 826: { 827: dbxout_tags (gettags ()); 828: dbxout_types (get_permanent_types ()); 829: }); 830: 831: /* Do gdb symbols */ 832: if (write_symbols == 1) 833: TIMEVAR (symout_time, 834: { 835: struct stat statbuf; 836: fstat (fileno (finput), &statbuf); 837: symout_types (get_permanent_types ()); 838: symout_top_blocks (globals, gettags ()); 839: symout_finish (name, statbuf.st_ctime); 840: }); 841: 1.1.1.2 ! root 842: /* Close the dump files. */ 1.1 root 843: 844: if (rtl_dump) 845: fclose (rtl_dump_file); 846: 847: if (jump_opt_dump) 848: fclose (jump_opt_dump_file); 849: 850: if (cse_dump) 851: fclose (cse_dump_file); 852: 853: if (loop_dump) 854: fclose (loop_dump_file); 855: 856: if (flow_dump) 857: fclose (flow_dump_file); 858: 859: if (combine_dump) 860: { 861: dump_combine_total_stats (combine_dump_file); 862: fclose (combine_dump_file); 863: } 864: 865: if (local_reg_dump) 866: fclose (local_reg_dump_file); 867: 868: if (global_reg_dump) 869: fclose (global_reg_dump_file); 870: 1.1.1.2 ! root 871: if (jump2_opt_dump) ! 872: fclose (jump2_opt_dump_file); ! 873: ! 874: /* Close non-debugging input and output files. */ ! 875: ! 876: fclose (finput); ! 877: if (ferror (asm_out_file) != 0) ! 878: fatal_io_error (asm_file_name); ! 879: fclose (asm_out_file); ! 880: 1.1 root 881: /* Print the times. */ 882: 883: if (! quiet_flag) 884: { 1.1.1.2 ! root 885: fprintf (stderr,"\n"); 1.1 root 886: print_time ("parse", parse_time); 1.1.1.2 ! root 887: print_time ("integration", integration_time); 1.1 root 888: print_time ("jump", jump_time); 889: print_time ("cse", cse_time); 890: print_time ("loop", loop_time); 891: print_time ("flow", flow_time); 892: print_time ("combine", combine_time); 893: print_time ("local-alloc", local_alloc_time); 894: print_time ("global-alloc", global_alloc_time); 895: print_time ("final", final_time); 896: print_time ("varconst", varconst_time); 897: print_time ("symout", symout_time); 898: print_time ("dump", dump_time); 899: } 900: } 901: 1.1.1.2 ! root 902: /* This is called from finish_decl (within yyparse) ! 903: for each declaration of a function or variable. ! 904: This does nothing for automatic variables. ! 905: Otherwise, it sets up the RTL and outputs any assembler code ! 906: (label definition, storage allocation and initialization). ! 907: ! 908: DECL is the declaration. If ASMSPEC is nonzero, it specifies ! 909: the assembler symbol name to be used. TOP_LEVEL is nonzero ! 910: if this declaration is not within a function. */ ! 911: ! 912: void ! 913: rest_of_decl_compilation (decl, asmspec, top_level, at_end) ! 914: tree decl; ! 915: tree asmspec; ! 916: int top_level; ! 917: int at_end; ! 918: { ! 919: /* Declarations of variables, and of functions defined elsewhere. */ ! 920: ! 921: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl)) ! 922: TIMEVAR (varconst_time, ! 923: { ! 924: assemble_variable (decl, asmspec, top_level, write_symbols, at_end); ! 925: }); ! 926: ! 927: if (top_level) ! 928: { ! 929: if (write_symbols == 1) ! 930: { ! 931: TIMEVAR (symout_time, ! 932: { ! 933: /* The initizations make types when they contain ! 934: string constants. The types are on the temporary ! 935: obstack, so output them now before they go away. */ ! 936: symout_types (get_temporary_types ()); ! 937: }); ! 938: } ! 939: else ! 940: /* Clean out the temporary type list, since the types will go away. */ ! 941: get_temporary_types (); ! 942: } ! 943: } ! 944: 1.1 root 945: /* This is called from finish_function (within yyparse) 1.1.1.2 ! root 946: after each top-level definition is parsed. 1.1 root 947: It is supposed to compile that function or variable 948: and output the assembler code for it. 949: After we return, the tree storage is freed. */ 950: 951: void 1.1.1.2 ! root 952: rest_of_compilation (decl) 1.1 root 953: tree decl; 954: { 955: register rtx insns; 956: int start_time = gettime (); 957: int tem; 958: 1.1.1.2 ! root 959: /* If we are reconsidering an inline function ! 960: at the end of compilation, skip the stuff for making it inline. */ 1.1 root 961: 1.1.1.2 ! root 962: if (DECL_SAVED_INSNS (decl) == 0) 1.1 root 963: { 964: 1.1.1.2 ! root 965: /* If requested, consider whether to make this function inline. */ ! 966: if (flag_inline_functions || TREE_INLINE (decl)) ! 967: { ! 968: TIMEVAR (integration_time, ! 969: { ! 970: int specd = TREE_INLINE (decl); ! 971: char *lose = function_cannot_inline_p (decl); ! 972: if (lose != 0 && specd) ! 973: warning_with_decl (decl, lose); ! 974: if (lose == 0) ! 975: save_for_inline (decl); ! 976: else ! 977: TREE_INLINE (decl) = 0; ! 978: }); ! 979: } 1.1 root 980: 1.1.1.2 ! root 981: insns = get_insns (); 1.1 root 982: 983: /* Dump the rtl code if we are dumping rtl. */ 984: 985: if (rtl_dump) 986: TIMEVAR (dump_time, 987: { 988: fprintf (rtl_dump_file, "\n;; Function %s\n\n", 989: IDENTIFIER_POINTER (DECL_NAME (decl))); 1.1.1.2 ! root 990: if (DECL_SAVED_INSNS (decl)) ! 991: fprintf (rtl_dump_file, ";; (integrable)\n\n"); 1.1 root 992: print_rtl (rtl_dump_file, insns); 993: fflush (rtl_dump_file); 994: }); 995: 1.1.1.2 ! root 996: /* If function is inline, and we don't yet know whether to ! 997: compile it by itself, defer decision till end of compilation. ! 998: finish_compilation will call rest_of_compilation again ! 999: for those functions that need to be output. */ ! 1000: ! 1001: if (TREE_PUBLIC (decl) == 0 ! 1002: && TREE_INLINE (decl) ! 1003: && ! flag_keep_inline_functions) 1.1 root 1004: goto exit_rest_of_compilation; 1.1.1.2 ! root 1005: } 1.1 root 1006: 1.1.1.2 ! root 1007: if (rtl_dump_and_exit) ! 1008: goto exit_rest_of_compilation; 1.1 root 1009: 1.1.1.2 ! root 1010: TREE_ASM_WRITTEN (decl) = 1; 1.1 root 1011: 1.1.1.2 ! root 1012: insns = get_insns (); 1.1 root 1013: 1.1.1.2 ! root 1014: /* Copy any shared structure that should not be shared. */ 1.1 root 1015: 1.1.1.2 ! root 1016: unshare_all_rtl (insns); 1.1 root 1017: 1.1.1.2 ! root 1018: /* See if we have allocated stack slots that are not directly addressable. ! 1019: If so, scan all the insns and create explicit address computation ! 1020: for all references to such slots. */ ! 1021: /* fixup_stack_slots (); */ 1.1 root 1022: 1.1.1.2 ! root 1023: /* Do jump optimization the first time, if -opt. ! 1024: Also do it if -W, but in that case it doesn't change the rtl code, ! 1025: it only computes whether control can drop off the end of the function. */ 1.1 root 1026: 1.1.1.2 ! root 1027: if (optimize || extra_warnings || warn_return_type) ! 1028: TIMEVAR (jump_time, jump_optimize (insns, 0, 0)); 1.1 root 1029: 1.1.1.2 ! root 1030: /* Dump rtl code after jump, if we are doing that. */ 1.1 root 1031: 1.1.1.2 ! root 1032: if (jump_opt_dump) ! 1033: TIMEVAR (dump_time, ! 1034: { ! 1035: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n", ! 1036: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1037: print_rtl (jump_opt_dump_file, insns); ! 1038: fflush (jump_opt_dump_file); ! 1039: }); 1.1 root 1040: 1.1.1.2 ! root 1041: /* Perform common subexpression elimination. ! 1042: Nonzero value from `cse_main' means that jumps were simplified ! 1043: and some code may now be unreachable, so do ! 1044: jump optimization again. */ 1.1 root 1045: 1.1.1.2 ! root 1046: if (optimize) ! 1047: { ! 1048: TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 0)); 1.1 root 1049: 1.1.1.2 ! root 1050: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num ())); 1.1 root 1051: 1.1.1.2 ! root 1052: if (tem) ! 1053: TIMEVAR (jump_time, jump_optimize (insns, 0, 0)); ! 1054: } 1.1 root 1055: 1.1.1.2 ! root 1056: /* Dump rtl code after cse, if we are doing that. */ 1.1 root 1057: 1.1.1.2 ! root 1058: if (cse_dump) ! 1059: TIMEVAR (dump_time, ! 1060: { ! 1061: fprintf (cse_dump_file, "\n;; Function %s\n\n", ! 1062: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1063: print_rtl (cse_dump_file, insns); ! 1064: fflush (cse_dump_file); ! 1065: }); 1.1 root 1066: 1.1.1.2 ! root 1067: if (loop_dump) ! 1068: TIMEVAR (dump_time, ! 1069: { ! 1070: fprintf (loop_dump_file, "\n;; Function %s\n\n", ! 1071: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1072: }); 1.1 root 1073: 1.1.1.2 ! root 1074: /* Move constant computations out of loops. */ 1.1 root 1075: 1.1.1.2 ! root 1076: if (optimize) ! 1077: { ! 1078: TIMEVAR (loop_time, ! 1079: { ! 1080: reg_scan (insns, max_reg_num (), 1); ! 1081: loop_optimize (insns, max_reg_num (), ! 1082: loop_dump ? loop_dump_file : 0); ! 1083: }); ! 1084: } 1.1 root 1085: 1.1.1.2 ! root 1086: /* Dump rtl code after loop opt, if we are doing that. */ 1.1 root 1087: 1.1.1.2 ! root 1088: if (loop_dump) ! 1089: TIMEVAR (dump_time, ! 1090: { ! 1091: print_rtl (loop_dump_file, insns); ! 1092: fflush (loop_dump_file); ! 1093: }); 1.1 root 1094: 1.1.1.2 ! root 1095: /* Now we choose between stupid (pcc-like) register allocation ! 1096: (if we got the -noreg switch and not -opt) ! 1097: and smart register allocation. */ 1.1 root 1098: 1.1.1.2 ! root 1099: if (optimize) /* Stupid allocation probably won't work */ ! 1100: obey_regdecls = 0; /* if optimizations being done. */ 1.1 root 1101: 1.1.1.2 ! root 1102: regclass_init (); 1.1 root 1103: 1.1.1.2 ! root 1104: /* Print function header into flow dump now ! 1105: because doing the flow analysis makes some of the dump. */ 1.1 root 1106: 1.1.1.2 ! root 1107: if (flow_dump) ! 1108: TIMEVAR (dump_time, ! 1109: { ! 1110: fprintf (flow_dump_file, "\n;; Function %s\n\n", ! 1111: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1112: }); ! 1113: ! 1114: if (obey_regdecls) ! 1115: { ! 1116: TIMEVAR (flow_time, ! 1117: { ! 1118: regclass (insns, max_reg_num ()); ! 1119: stupid_life_analysis (insns, max_reg_num (), ! 1120: flow_dump_file); ! 1121: }); ! 1122: } ! 1123: else ! 1124: { ! 1125: /* Do control and data flow analysis, ! 1126: and write some of the results to dump file. */ 1.1 root 1127: 1.1.1.2 ! root 1128: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (), ! 1129: flow_dump_file)); ! 1130: if (extra_warnings) ! 1131: uninitialized_vars_warning (DECL_INITIAL (decl)); ! 1132: } 1.1 root 1133: 1.1.1.2 ! root 1134: /* Dump rtl after flow analysis. */ 1.1 root 1135: 1.1.1.2 ! root 1136: if (flow_dump) ! 1137: TIMEVAR (dump_time, ! 1138: { ! 1139: print_rtl (flow_dump_file, insns); ! 1140: fflush (flow_dump_file); ! 1141: }); 1.1 root 1142: 1.1.1.2 ! root 1143: /* If -opt, try combining insns through substitution. */ 1.1 root 1144: 1.1.1.2 ! root 1145: if (optimize) ! 1146: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ())); 1.1 root 1147: 1.1.1.2 ! root 1148: /* Dump rtl code after insn combination. */ 1.1 root 1149: 1.1.1.2 ! root 1150: if (combine_dump) ! 1151: TIMEVAR (dump_time, ! 1152: { ! 1153: fprintf (combine_dump_file, "\n;; Function %s\n\n", ! 1154: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1155: dump_combine_stats (combine_dump_file); ! 1156: print_rtl (combine_dump_file, insns); ! 1157: fflush (combine_dump_file); ! 1158: }); 1.1 root 1159: 1.1.1.2 ! root 1160: /* Unless we did stupid register allocation, ! 1161: allocate pseudo-regs that are used only within 1 basic block. */ 1.1 root 1162: 1.1.1.2 ! root 1163: if (!obey_regdecls) ! 1164: TIMEVAR (local_alloc_time, ! 1165: { ! 1166: regclass (insns, max_reg_num ()); ! 1167: local_alloc (); ! 1168: }); 1.1 root 1169: 1.1.1.2 ! root 1170: /* Dump rtl code after allocating regs within basic blocks. */ 1.1 root 1171: 1.1.1.2 ! root 1172: if (local_reg_dump) ! 1173: TIMEVAR (dump_time, ! 1174: { ! 1175: fprintf (local_reg_dump_file, "\n;; Function %s\n\n", ! 1176: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1177: dump_flow_info (local_reg_dump_file); ! 1178: dump_local_alloc (local_reg_dump_file); ! 1179: print_rtl (local_reg_dump_file, insns); ! 1180: fflush (local_reg_dump_file); ! 1181: }); 1.1 root 1182: 1.1.1.2 ! root 1183: if (global_reg_dump) ! 1184: TIMEVAR (dump_time, ! 1185: fprintf (global_reg_dump_file, "\n;; Function %s\n\n", ! 1186: IDENTIFIER_POINTER (DECL_NAME (decl)))); ! 1187: ! 1188: /* Unless we did stupid register allocation, ! 1189: allocate remaining pseudo-regs, then do the reload pass ! 1190: fixing up any insns that are invalid. */ ! 1191: ! 1192: TIMEVAR (global_alloc_time, ! 1193: { ! 1194: if (!obey_regdecls) ! 1195: global_alloc (global_reg_dump ? global_reg_dump_file : 0); ! 1196: else ! 1197: reload (insns, 0, ! 1198: global_reg_dump ? global_reg_dump_file : 0); ! 1199: }); ! 1200: ! 1201: if (global_reg_dump) ! 1202: TIMEVAR (dump_time, ! 1203: { ! 1204: dump_global_regs (global_reg_dump_file); ! 1205: print_rtl (global_reg_dump_file, insns); ! 1206: fflush (global_reg_dump_file); ! 1207: }); 1.1 root 1208: 1.1.1.2 ! root 1209: /* One more attempt to remove jumps to .+1 ! 1210: left by dead-store-elimination. ! 1211: Also do cross-jumping this time ! 1212: and delete no-op move insns. */ 1.1 root 1213: 1.1.1.2 ! root 1214: if (optimize) ! 1215: { ! 1216: TIMEVAR (jump_time, jump_optimize (insns, 1, 1)); ! 1217: } 1.1 root 1218: 1.1.1.2 ! root 1219: /* Dump rtl code after jump, if we are doing that. */ ! 1220: ! 1221: if (jump2_opt_dump) ! 1222: TIMEVAR (dump_time, ! 1223: { ! 1224: fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n", ! 1225: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1226: print_rtl (jump2_opt_dump_file, insns); ! 1227: fflush (jump2_opt_dump_file); ! 1228: }); ! 1229: ! 1230: /* Now turn the rtl into assembler code. */ ! 1231: ! 1232: TIMEVAR (final_time, ! 1233: { ! 1234: assemble_function (decl); ! 1235: final_start_function (insns, asm_out_file, ! 1236: write_symbols, optimize); ! 1237: final (insns, asm_out_file, ! 1238: write_symbols, optimize); ! 1239: final_end_function (insns, asm_out_file, ! 1240: write_symbols, optimize); ! 1241: fflush (asm_out_file); ! 1242: }); 1.1 root 1243: 1.1.1.2 ! root 1244: /* Write GDB symbols if requested */ 1.1 root 1245: 1.1.1.2 ! root 1246: if (write_symbols == 1) ! 1247: { ! 1248: TIMEVAR (symout_time, ! 1249: { ! 1250: symout_types (get_permanent_types ()); ! 1251: symout_types (get_temporary_types ()); ! 1252: ! 1253: DECL_BLOCK_SYMTAB_ADDRESS (decl) ! 1254: = symout_function (DECL_INITIAL (decl), ! 1255: DECL_ARGUMENTS (decl), 0); ! 1256: }); 1.1 root 1257: } 1.1.1.2 ! root 1258: else ! 1259: get_temporary_types (); ! 1260: ! 1261: /* Write DBX symbols if requested */ ! 1262: ! 1263: if (write_symbols == 2) ! 1264: TIMEVAR (symout_time, dbxout_function (decl)); 1.1 root 1265: 1266: exit_rest_of_compilation: 1267: 1268: /* The parsing time is all the time spent in yyparse 1269: *except* what is spent in this function. */ 1270: 1271: parse_time -= gettime () - start_time; 1272: } 1273: 1274: /* Entry point of cc1. Decode command args, then call compile_file. 1.1.1.2 ! root 1275: Exit code is 35 if can't open files, 34 if fatal error, ! 1276: 33 if had nonfatal errors, else success. */ 1.1 root 1277: 1278: int 1279: main (argc, argv, envp) 1280: int argc; 1281: char **argv; 1282: char **envp; 1283: { 1284: register int i; 1.1.1.2 ! root 1285: char *filename = 0; ! 1286: int print_mem_flag = 0; ! 1287: ! 1288: #ifdef RLIMIT_STACK ! 1289: /* Get rid of any avoidable limit on stack size. */ ! 1290: { ! 1291: struct rlimit rlim; ! 1292: ! 1293: /* Set the stack limit huge so that alloca does not fail. */ ! 1294: getrlimit (RLIMIT_STACK, &rlim); ! 1295: rlim.rlim_cur = rlim.rlim_max; ! 1296: setrlimit (RLIMIT_STACK, &rlim); ! 1297: } ! 1298: #endif /* RLIMIT_STACK */ ! 1299: ! 1300: /* Initialize whether `char' is signed. */ ! 1301: flag_signed_char = DEFAULT_SIGNED_CHAR; ! 1302: ! 1303: /* Initialize reg-sets now so switches may override. */ ! 1304: init_reg_sets (); 1.1 root 1305: 1306: target_flags = 0; 1307: set_target_switch (""); 1308: 1309: for (i = 1; i < argc; i++) 1310: if (argv[i][0] == '-') 1311: { 1312: register char *str = argv[i] + 1; 1313: if (str[0] == 'Y') 1314: str++; 1315: 1316: if (str[0] == 'm') 1317: set_target_switch (&str[1]); 1318: else if (!strcmp (str, "dumpbase")) 1319: { 1320: dump_base_name = argv[++i]; 1321: } 1322: else if (str[0] == 'd') 1323: { 1324: register char *p = &str[1]; 1325: while (*p) 1326: switch (*p++) 1327: { 1328: case 'c': 1329: combine_dump = 1; 1330: break; 1331: case 'f': 1332: flow_dump = 1; 1333: break; 1334: case 'g': 1335: global_reg_dump = 1; 1336: break; 1337: case 'j': 1338: jump_opt_dump = 1; 1339: break; 1.1.1.2 ! root 1340: case 'J': ! 1341: jump2_opt_dump = 1; ! 1342: break; 1.1 root 1343: case 'l': 1344: local_reg_dump = 1; 1345: break; 1346: case 'L': 1347: loop_dump = 1; 1348: break; 1.1.1.2 ! root 1349: case 'm': ! 1350: print_mem_flag = 1; ! 1351: break; 1.1 root 1352: case 'r': 1353: rtl_dump = 1; 1354: break; 1355: case 's': 1356: cse_dump = 1; 1357: break; 1358: case 'y': 1359: yydebug = 1; 1360: break; 1361: } 1362: } 1.1.1.2 ! root 1363: else if (str[0] == 'f') ! 1364: { ! 1365: register char *p = &str[1]; ! 1366: if (!strcmp (p, "float-store")) ! 1367: flag_float_store = 1; ! 1368: else if (!strcmp (p, "traditional")) ! 1369: flag_traditional = 1; ! 1370: else if (!strcmp (p, "volatile")) ! 1371: flag_volatile = 1; ! 1372: else if (!strcmp (p, "defer-pop")) ! 1373: flag_defer_pop = 1; ! 1374: else if (!strcmp (p, "no-defer-pop")) ! 1375: flag_defer_pop = 0; ! 1376: else if (!strcmp (p, "omit-frame-pointer")) ! 1377: flag_omit_frame_pointer = 1; ! 1378: else if (!strcmp (p, "no-omit-frame-pointer")) ! 1379: flag_omit_frame_pointer = 0; ! 1380: else if (!strcmp (p, "no-peephole")) ! 1381: flag_no_peephole = 1; ! 1382: else if (!strcmp (p, "signed-char")) ! 1383: flag_signed_char = 1; ! 1384: else if (!strcmp (p, "unsigned-char")) ! 1385: flag_signed_char = 0; ! 1386: else if (!strcmp (p, "force-mem")) ! 1387: flag_force_mem = 1; ! 1388: else if (!strcmp (p, "force-addr")) ! 1389: flag_force_addr = 1; ! 1390: else if (!strcmp (p, "combine-regs")) ! 1391: flag_combine_regs = 1; ! 1392: else if (!strcmp (p, "writable-strings")) ! 1393: flag_writable_strings = 1; ! 1394: else if (!strcmp (p, "no-function-cse")) ! 1395: flag_no_function_cse = 1; ! 1396: else if (!strcmp (p, "cond-mismatch")) ! 1397: flag_cond_mismatch = 1; ! 1398: else if (!strcmp (p, "no-asm")) ! 1399: flag_no_asm = 1; ! 1400: else if (!strncmp (p, "fixed-", 6)) ! 1401: fix_register (&p[6], 1, 1); ! 1402: else if (!strncmp (p, "call-used-", 10)) ! 1403: fix_register (&p[10], 0, 1); ! 1404: else if (!strncmp (p, "call-saved-", 11)) ! 1405: fix_register (&p[11], 0, 0); ! 1406: else if (!strcmp (p, "inline-functions")) ! 1407: flag_inline_functions = 1; ! 1408: else if (!strcmp (p, "keep-inline-functions")) ! 1409: flag_keep_inline_functions = 1; ! 1410: else ! 1411: error ("Invalid option, `%s'", argv[i]); ! 1412: } 1.1 root 1413: else if (!strcmp (str, "noreg")) 1414: obey_regdecls = 1; 1.1.1.2 ! root 1415: else if (!strcmp (str, "opt")) ! 1416: optimize = 1; ! 1417: else if (!strcmp (str, "pedantic")) ! 1418: pedantic = 1; ! 1419: else if (!strcmp (str, "traditional")) ! 1420: flag_traditional = 1; ! 1421: else if (!strcmp (str, "ansi")) ! 1422: flag_no_asm = 1; ! 1423: else if (!strcmp (str, "quiet")) ! 1424: quiet_flag = 1; ! 1425: else if (!strcmp (str, "version")) ! 1426: { ! 1427: extern char *version_string; ! 1428: printf ("GNU C version %s", version_string); ! 1429: #ifdef TARGET_VERSION ! 1430: TARGET_VERSION; ! 1431: #endif ! 1432: #ifdef __GNUC__ ! 1433: #ifndef __VERSION__ ! 1434: #define __VERSION__ "[unknown]" ! 1435: #endif ! 1436: printf (" compiled by GNU C version %s.\n", __VERSION__); ! 1437: #else ! 1438: printf (" compiled by CC.\n"); ! 1439: #endif ! 1440: } 1.1 root 1441: else if (!strcmp (str, "w")) 1442: inhibit_warnings = 1; 1.1.1.2 ! root 1443: else if (!strcmp (str, "W")) ! 1444: extra_warnings = 1; ! 1445: else if (!strcmp (str, "Wimplicit")) ! 1446: warn_implicit = 1; ! 1447: else if (!strcmp (str, "Wreturn-type")) ! 1448: warn_return_type = 1; ! 1449: else if (!strcmp (str, "p")) ! 1450: profile_flag = 1; 1.1 root 1451: else if (!strcmp (str, "g")) 1452: write_symbols = 1; 1453: else if (!strcmp (str, "G")) 1454: write_symbols = 2; 1455: else if (!strcmp (str, "symout")) 1456: { 1457: if (write_symbols == 0) 1458: write_symbols = 1; 1459: sym_file_name = argv[++i]; 1460: } 1461: else if (!strcmp (str, "o")) 1462: { 1463: asm_file_name = argv[++i]; 1464: } 1465: else 1.1.1.2 ! root 1466: error ("Invalid switch, %s.", argv[i]); 1.1 root 1467: } 1468: else 1469: filename = argv[i]; 1470: 1471: if (filename == 0) 1472: fatal ("no input file specified"); 1473: 1474: if (dump_base_name == 0) 1475: dump_base_name = filename; 1.1.1.2 ! root 1476: ! 1477: #ifdef OVERRIDE_OPTIONS ! 1478: /* Some machines may reject certain combinations of options. */ ! 1479: OVERRIDE_OPTIONS; ! 1480: #endif ! 1481: 1.1 root 1482: compile_file (filename); 1483: 1.1.1.2 ! root 1484: #ifndef USG ! 1485: #ifndef VMS ! 1486: if (print_mem_flag) ! 1487: { ! 1488: extern char **environ; ! 1489: caddr_t lim = (caddr_t) sbrk (0); ! 1490: ! 1491: fprintf (stderr, "Data size %d.\n", ! 1492: (int) lim - (int) &environ); ! 1493: fflush (stderr); ! 1494: ! 1495: system ("ps v"); ! 1496: } ! 1497: #endif /* not VMS */ ! 1498: #endif /* not USG */ ! 1499: 1.1 root 1500: if (errorcount) 1.1.1.2 ! root 1501: exit (FATAL_EXIT_CODE); ! 1502: exit (SUCCESS_EXIT_CODE); ! 1503: return 34; 1.1 root 1504: } 1505: 1506: /* Decode -m switches. */ 1507: 1508: /* Here is a table, controlled by the tm-...h file, listing each -m switch 1509: and which bits in `target_switches' it should set or clear. 1510: If VALUE is positive, it is bits to set. 1511: If VALUE is negative, -VALUE is bits to clear. 1512: (The sign bit is not used so there is no confusion.) */ 1513: 1514: struct {char *name; int value;} target_switches [] 1515: = TARGET_SWITCHES; 1516: 1517: /* Decode the switch -mNAME. */ 1518: 1.1.1.2 ! root 1519: void 1.1 root 1520: set_target_switch (name) 1521: char *name; 1522: { 1.1.1.2 ! root 1523: register int j; 1.1 root 1524: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) 1525: if (!strcmp (target_switches[j].name, name)) 1526: { 1527: if (target_switches[j].value < 0) 1528: target_flags &= ~-target_switches[j].value; 1529: else 1530: target_flags |= target_switches[j].value; 1531: break; 1532: } 1533: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.