|
|
1.1 ! root 1: /* Top level of GNU C compiler ! 2: Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: /* This is the top level of cc1/c++. ! 22: It parses command args, opens files, invokes the various passes ! 23: in the proper order, and counts the time used by each. ! 24: Error messages and low-level interface to malloc also handled here. */ ! 25: ! 26: #include "config.h" ! 27: #include <sys/types.h> ! 28: #include <stdio.h> ! 29: #include <signal.h> ! 30: #include <setjmp.h> ! 31: ! 32: #include <sys/stat.h> ! 33: ! 34: #ifdef USG ! 35: #undef FLOAT ! 36: #include <sys/param.h> ! 37: /* This is for hpux. It is a real screw. They should change hpux. */ ! 38: #undef FLOAT ! 39: #include <sys/times.h> ! 40: #include <time.h> /* Correct for hpux at least. Is it good on other USG? */ ! 41: #undef FFS /* Some systems define this in param.h. */ ! 42: #else ! 43: #ifndef VMS ! 44: #include <sys/time.h> ! 45: #include <sys/resource.h> ! 46: #endif ! 47: #endif ! 48: ! 49: #include "input.h" ! 50: #include "tree.h" ! 51: /* #include "c-tree.h" */ ! 52: #include "rtl.h" ! 53: #include "flags.h" ! 54: #include "insn-attr.h" ! 55: ! 56: #ifdef VMS ! 57: /* The extra parameters substantially improve the I/O performance. */ ! 58: static FILE * ! 59: VMS_fopen (fname, type) ! 60: char * fname; ! 61: char * type; ! 62: { ! 63: if (strcmp (type, "w") == 0) ! 64: return fopen (fname, type, "mbc=16", "deq=64", "fop=tef", "shr=nil"); ! 65: return fopen (fname, type, "mbc=16"); ! 66: } ! 67: #define fopen VMS_fopen ! 68: #endif ! 69: ! 70: #ifndef DEFAULT_GDB_EXTENSIONS ! 71: #define DEFAULT_GDB_EXTENSIONS 1 ! 72: #endif ! 73: ! 74: extern int rtx_equal_function_value_matters; ! 75: ! 76: extern char **environ; ! 77: extern char *version_string, *language_string; ! 78: ! 79: extern void init_lex (); ! 80: extern void init_decl_processing (); ! 81: extern void init_obstacks (); ! 82: extern void init_tree_codes (); ! 83: extern void init_rtl (); ! 84: extern void init_optabs (); ! 85: extern void init_stmt (); ! 86: extern void init_reg_sets (); ! 87: extern void dump_flow_info (); ! 88: extern void dump_sched_info (); ! 89: extern void dump_local_alloc (); ! 90: ! 91: void rest_of_decl_compilation (); ! 92: void error (); ! 93: void error_with_file_and_line (); ! 94: void fancy_abort (); ! 95: #ifndef abort ! 96: void abort (); ! 97: #endif ! 98: void set_target_switch (); ! 99: static void print_switch_values (); ! 100: static char *decl_name (); ! 101: ! 102: /* Name of program invoked, sans directories. */ ! 103: ! 104: char *progname; ! 105: ! 106: /* Copy of arguments to main. */ ! 107: int save_argc; ! 108: char **save_argv; ! 109: ! 110: /* Name of current original source file (what was input to cpp). ! 111: This comes from each #-command in the actual input. */ ! 112: ! 113: char *input_filename; ! 114: ! 115: /* Name of top-level original source file (what was input to cpp). ! 116: This comes from the #-command at the beginning of the actual input. ! 117: If there isn't any there, then this is the cc1 input file name. */ ! 118: ! 119: char *main_input_filename; ! 120: ! 121: /* Stream for reading from the input file. */ ! 122: ! 123: FILE *finput; ! 124: ! 125: /* Current line number in real source file. */ ! 126: ! 127: int lineno; ! 128: ! 129: /* Stack of currently pending input files. */ ! 130: ! 131: struct file_stack *input_file_stack; ! 132: ! 133: /* Incremented on each change to input_file_stack. */ ! 134: int input_file_stack_tick; ! 135: ! 136: /* FUNCTION_DECL for function now being parsed or compiled. */ ! 137: ! 138: extern tree current_function_decl; ! 139: ! 140: /* Name to use as base of names for dump output files. */ ! 141: ! 142: char *dump_base_name; ! 143: ! 144: /* Bit flags that specify the machine subtype we are compiling for. ! 145: Bits are tested using macros TARGET_... defined in the tm.h file ! 146: and set by `-m...' switches. Must be defined in rtlanal.c. */ ! 147: ! 148: extern int target_flags; ! 149: ! 150: /* Flags saying which kinds of debugging dump have been requested. */ ! 151: ! 152: int rtl_dump = 0; ! 153: int rtl_dump_and_exit = 0; ! 154: int jump_opt_dump = 0; ! 155: int cse_dump = 0; ! 156: int loop_dump = 0; ! 157: int cse2_dump = 0; ! 158: int flow_dump = 0; ! 159: int combine_dump = 0; ! 160: int sched_dump = 0; ! 161: int local_reg_dump = 0; ! 162: int global_reg_dump = 0; ! 163: int sched2_dump = 0; ! 164: int jump2_opt_dump = 0; ! 165: int dbr_sched_dump = 0; ! 166: int flag_print_asm_name = 0; ! 167: int stack_reg_dump = 0; ! 168: ! 169: /* Name for output file of assembly code, specified with -o. */ ! 170: ! 171: char *asm_file_name; ! 172: ! 173: /* Value of the -G xx switch, and whether it was passed or not. */ ! 174: int g_switch_value; ! 175: int g_switch_set; ! 176: ! 177: /* Type(s) of debugging information we are producing (if any). ! 178: See flags.h for the definitions of the different possible ! 179: types of debugging information. */ ! 180: enum debug_info_type write_symbols = NO_DEBUG; ! 181: ! 182: /* Level of debugging information we are producing. See flags.h ! 183: for the definitions of the different possible levels. */ ! 184: enum debug_info_level debug_info_level = DINFO_LEVEL_NONE; ! 185: ! 186: #ifdef DBX_DEBUGGING_INFO ! 187: /* Nonzero means can use our own extensions to DBX format. ! 188: Relevant only when write_symbols == DBX_DEBUG. */ ! 189: int use_gdb_dbx_extensions = 0; ! 190: #endif ! 191: ! 192: /* Nonzero means do optimizations. -O. ! 193: Particular numeric values stand for particular amounts of optimization; ! 194: thus, -O2 stores 2 here. However, the optimizations beyond the basic ! 195: ones are not controlled directly by this variable. Instead, they are ! 196: controlled by individual `flag_...' variables that are defaulted ! 197: based on this variable. */ ! 198: ! 199: int optimize = 0; ! 200: ! 201: /* Number of error messages and warning messages so far. */ ! 202: ! 203: int errorcount = 0; ! 204: int warningcount = 0; ! 205: int sorrycount = 0; ! 206: ! 207: /* Pointer to function to compute the name to use to print a declaration. */ ! 208: ! 209: char *(*decl_printable_name) (); ! 210: ! 211: /* Pointer to function to compute rtl for a language-specific tree code. */ ! 212: ! 213: struct rtx_def *(*lang_expand_expr) (); ! 214: ! 215: /* Nonzero if generating code to do profiling. */ ! 216: ! 217: int profile_flag = 0; ! 218: ! 219: /* Nonzero if generating code to do profiling on a line-by-line basis. */ ! 220: ! 221: int profile_block_flag; ! 222: ! 223: /* Nonzero for -pedantic switch: warn about anything ! 224: that standard spec forbids. */ ! 225: ! 226: int pedantic = 0; ! 227: ! 228: /* Temporarily suppress certain warnings. ! 229: This is set while reading code from a system header file. */ ! 230: ! 231: int in_system_header = 0; ! 232: ! 233: /* Nonzero means do stupid register allocation. ! 234: Currently, this is 1 if `optimize' is 0. */ ! 235: ! 236: int obey_regdecls = 0; ! 237: ! 238: /* Don't print functions as they are compiled and don't print ! 239: times taken by the various passes. -quiet. */ ! 240: ! 241: int quiet_flag = 0; ! 242: ! 243: /* -f flags. */ ! 244: ! 245: /* Nonzero means `char' should be signed. */ ! 246: ! 247: int flag_signed_char; ! 248: ! 249: /* Nonzero means give an enum type only as many bytes as it needs. */ ! 250: ! 251: int flag_short_enums; ! 252: ! 253: /* Nonzero for -fcaller-saves: allocate values in regs that need to ! 254: be saved across function calls, if that produces overall better code. ! 255: Optional now, so people can test it. */ ! 256: ! 257: #ifdef DEFAULT_CALLER_SAVES ! 258: int flag_caller_saves = 1; ! 259: #else ! 260: int flag_caller_saves = 0; ! 261: #endif ! 262: ! 263: /* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ ! 264: ! 265: int flag_pcc_struct_return = 0; ! 266: ! 267: /* Nonzero for -fforce-mem: load memory value into a register ! 268: before arithmetic on it. This makes better cse but slower compilation. */ ! 269: ! 270: int flag_force_mem = 0; ! 271: ! 272: /* Nonzero for -fforce-addr: load memory address into a register before ! 273: reference to memory. This makes better cse but slower compilation. */ ! 274: ! 275: int flag_force_addr = 0; ! 276: ! 277: /* Nonzero for -fdefer-pop: don't pop args after each function call; ! 278: instead save them up to pop many calls' args with one insns. */ ! 279: ! 280: int flag_defer_pop = 1; ! 281: ! 282: /* Nonzero for -ffloat-store: don't allocate floats and doubles ! 283: in extended-precision registers. */ ! 284: ! 285: int flag_float_store = 0; ! 286: ! 287: /* Nonzero for -fcse-follow-jumps: ! 288: have cse follow jumps to do a more extensive job. */ ! 289: ! 290: int flag_cse_follow_jumps; ! 291: ! 292: /* Nonzero for -fexpensive-optimizations: ! 293: perform miscellaneous relatively-expensive optimizations. */ ! 294: int flag_expensive_optimizations; ! 295: ! 296: /* Nonzero for -fthread-jumps: ! 297: have jump optimize output of loop. */ ! 298: ! 299: int flag_thread_jumps; ! 300: ! 301: /* Nonzero enables strength-reduction in loop.c. */ ! 302: ! 303: int flag_strength_reduce = 0; ! 304: ! 305: /* Nonzero enables loop unrolling in unroll.c. Only loops for which the ! 306: number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, ! 307: UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are ! 308: unrolled. */ ! 309: ! 310: int flag_unroll_loops; ! 311: ! 312: /* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. ! 313: This is generally not a win. */ ! 314: ! 315: int flag_unroll_all_loops; ! 316: ! 317: /* Nonzero for -fwritable-strings: ! 318: store string constants in data segment and don't uniquize them. */ ! 319: ! 320: int flag_writable_strings = 0; ! 321: ! 322: /* Nonzero means don't put addresses of constant functions in registers. ! 323: Used for compiling the Unix kernel, where strange substitutions are ! 324: done on the assembly output. */ ! 325: ! 326: int flag_no_function_cse = 0; ! 327: ! 328: /* Nonzero for -fomit-frame-pointer: ! 329: don't make a frame pointer in simple functions that don't require one. */ ! 330: ! 331: int flag_omit_frame_pointer = 0; ! 332: ! 333: /* Nonzero to inhibit use of define_optimization peephole opts. */ ! 334: ! 335: int flag_no_peephole = 0; ! 336: ! 337: /* Nonzero means all references through pointers are volatile. */ ! 338: ! 339: int flag_volatile; ! 340: ! 341: /* Nonzero means just do syntax checking; don't output anything. */ ! 342: ! 343: int flag_syntax_only = 0; ! 344: ! 345: /* Nonzero means to rerun cse after loop optimization. This increases ! 346: compilation time about 20% and picks up a few more common expressions. */ ! 347: ! 348: static int flag_rerun_cse_after_loop; ! 349: ! 350: /* Nonzero for -finline-functions: ok to inline functions that look like ! 351: good inline candidates. */ ! 352: ! 353: int flag_inline_functions; ! 354: ! 355: /* Nonzero for -fkeep-inline-functions: even if we make a function ! 356: go inline everywhere, keep its defintion around for debugging ! 357: purposes. */ ! 358: ! 359: int flag_keep_inline_functions; ! 360: ! 361: /* Nonzero means that functions declared `inline' will be treated ! 362: as `static'. Prevents generation of zillions of copies of unused ! 363: static inline functions; instead, `inlines' are written out ! 364: only when actually used. Used in conjunction with -g. Also ! 365: does the right thing with #pragma interface. */ ! 366: ! 367: int flag_no_inline; ! 368: ! 369: /* Nonzero means we should be saving declaration info into a .X file. */ ! 370: ! 371: int flag_gen_aux_info = 0; ! 372: ! 373: /* Nonzero means make the text shared if supported. */ ! 374: ! 375: int flag_shared_data; ! 376: ! 377: /* Nonzero means schedule into delayed branch slots if supported. */ ! 378: ! 379: int flag_delayed_branch; ! 380: ! 381: /* Nonzero if we are compiling pure (sharable) code. ! 382: Value is 1 if we are doing reasonable (i.e. simple ! 383: offset into offset table) pic. Value is 2 if we can ! 384: only perform register offsets. */ ! 385: ! 386: int flag_pic; ! 387: ! 388: /* Nonzero means place uninitialized global data in the bss section. */ ! 389: ! 390: int flag_no_common; ! 391: ! 392: /* Nonzero means pretend it is OK to examine bits of target floats, ! 393: even if that isn't true. The resulting code will have incorrect constants, ! 394: but the same series of instructions that the native compiler would make. */ ! 395: ! 396: int flag_pretend_float; ! 397: ! 398: /* Nonzero means change certain warnings into errors. ! 399: Usually these are warnings about failure to conform to some standard. */ ! 400: ! 401: int flag_pedantic_errors = 0; ! 402: ! 403: /* flag_schedule_insns means schedule insns within basic blocks (before ! 404: local_alloc). ! 405: flag_schedule_insns_after_reload means schedule insns after ! 406: global_alloc. */ ! 407: ! 408: int flag_schedule_insns = 0; ! 409: int flag_schedule_insns_after_reload = 0; ! 410: ! 411: /* -finhibit-size-directive inhibits output of .size for ELF. ! 412: This is used only for compiling crtstuff.c, ! 413: and it may be extended to other effects ! 414: needed for crtstuff.c on other systems. */ ! 415: int flag_inhibit_size_directive = 0; ! 416: ! 417: /* -fgnu-linker specifies use of the GNU linker for initializations. ! 418: -fno-gnu-linker says that collect will be used. */ ! 419: int flag_gnu_linker = 1; ! 420: ! 421: /* Table of language-independent -f options. ! 422: STRING is the option name. VARIABLE is the address of the variable. ! 423: ON_VALUE is the value to store in VARIABLE ! 424: if `-fSTRING' is seen as an option. ! 425: (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ ! 426: ! 427: struct { char *string; int *variable; int on_value;} f_options[] = ! 428: { ! 429: {"float-store", &flag_float_store, 1}, ! 430: {"volatile", &flag_volatile, 1}, ! 431: {"defer-pop", &flag_defer_pop, 1}, ! 432: {"omit-frame-pointer", &flag_omit_frame_pointer, 1}, ! 433: {"cse-follow-jumps", &flag_cse_follow_jumps, 1}, ! 434: {"expensive-optimizations", &flag_expensive_optimizations, 1}, ! 435: {"thread-jumps", &flag_thread_jumps, 1}, ! 436: {"strength-reduce", &flag_strength_reduce, 1}, ! 437: {"unroll-loops", &flag_unroll_loops, 1}, ! 438: {"unroll-all-loops", &flag_unroll_all_loops, 1}, ! 439: {"writable-strings", &flag_writable_strings, 1}, ! 440: {"peephole", &flag_no_peephole, 0}, ! 441: {"force-mem", &flag_force_mem, 1}, ! 442: {"force-addr", &flag_force_addr, 1}, ! 443: {"function-cse", &flag_no_function_cse, 0}, ! 444: {"inline-functions", &flag_inline_functions, 1}, ! 445: {"keep-inline-functions", &flag_keep_inline_functions, 1}, ! 446: {"inline", &flag_no_inline, 0}, ! 447: {"syntax-only", &flag_syntax_only, 1}, ! 448: {"gen-aux-info", &flag_gen_aux_info, 1}, ! 449: {"shared-data", &flag_shared_data, 1}, ! 450: {"caller-saves", &flag_caller_saves, 1}, ! 451: {"pcc-struct-return", &flag_pcc_struct_return, 1}, ! 452: {"delayed-branch", &flag_delayed_branch, 1}, ! 453: {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1}, ! 454: {"pretend-float", &flag_pretend_float, 1}, ! 455: {"schedule-insns", &flag_schedule_insns, 1}, ! 456: {"schedule-insns2", &flag_schedule_insns_after_reload, 1}, ! 457: {"pic", &flag_pic, 1}, ! 458: {"PIC", &flag_pic, 2}, ! 459: {"common", &flag_no_common, 0}, ! 460: {"inhibit-size-directive", &flag_inhibit_size_directive, 1}, ! 461: {"gnu-linker", &flag_gnu_linker, 1} ! 462: }; ! 463: ! 464: /* Options controlling warnings */ ! 465: ! 466: /* Don't print warning messages. -w. */ ! 467: ! 468: int inhibit_warnings = 0; ! 469: ! 470: /* Print various extra warnings. -W. */ ! 471: ! 472: int extra_warnings = 0; ! 473: ! 474: /* Treat warnings as errors. -Werror. */ ! 475: ! 476: int warnings_are_errors = 0; ! 477: ! 478: /* Nonzero to warn about unused local variables. */ ! 479: ! 480: int warn_unused; ! 481: ! 482: /* Nonzero to warn about variables used before they are initialized. */ ! 483: ! 484: int warn_uninitialized; ! 485: ! 486: /* Nonzero means warn about all declarations which shadow others. */ ! 487: ! 488: int warn_shadow; ! 489: ! 490: /* Warn if a switch on an enum fails to have a case for every enum value. */ ! 491: ! 492: int warn_switch; ! 493: ! 494: /* Nonzero means warn about function definitions that default the return type ! 495: or that use a null return and have a return-type other than void. */ ! 496: ! 497: int warn_return_type; ! 498: ! 499: /* Nonzero means warn about pointer casts that increase the required ! 500: alignment of the target type (and might therefore lead to a crash ! 501: due to a misaligned access). */ ! 502: ! 503: int warn_cast_align; ! 504: ! 505: /* Nonzero means warn about any identifiers that match in the first N ! 506: characters. The value N is in `id_clash_len'. */ ! 507: ! 508: int warn_id_clash; ! 509: int id_clash_len; ! 510: ! 511: /* Nonzero means warn if inline function is too large. */ ! 512: ! 513: int warn_inline; ! 514: ! 515: /* Warn if a function returns an aggregate, ! 516: since there are often incompatible calling conventions for doing this. */ ! 517: ! 518: int warn_aggregate_return; ! 519: ! 520: /* Likewise for -W. */ ! 521: ! 522: struct { char *string; int *variable; int on_value;} W_options[] = ! 523: { ! 524: {"unused", &warn_unused, 1}, ! 525: {"error", &warnings_are_errors, 1}, ! 526: {"shadow", &warn_shadow, 1}, ! 527: {"switch", &warn_switch, 1}, ! 528: {"return-type", &warn_return_type, 1}, ! 529: {"aggregate-return", &warn_aggregate_return, 1}, ! 530: {"cast-align", &warn_cast_align, 1}, ! 531: {"uninitialized", &warn_uninitialized, 1} ! 532: }; ! 533: ! 534: /* Output files for assembler code (real compiler output) ! 535: and debugging dumps. */ ! 536: ! 537: FILE *asm_out_file; ! 538: FILE *aux_info_file; ! 539: FILE *rtl_dump_file; ! 540: FILE *jump_opt_dump_file; ! 541: FILE *cse_dump_file; ! 542: FILE *loop_dump_file; ! 543: FILE *cse2_dump_file; ! 544: FILE *flow_dump_file; ! 545: FILE *combine_dump_file; ! 546: FILE *sched_dump_file; ! 547: FILE *local_reg_dump_file; ! 548: FILE *global_reg_dump_file; ! 549: FILE *sched2_dump_file; ! 550: FILE *jump2_opt_dump_file; ! 551: FILE *dbr_sched_dump_file; ! 552: FILE *stack_reg_dump_file; ! 553: ! 554: /* Time accumulators, to count the total time spent in various passes. */ ! 555: ! 556: int parse_time; ! 557: int varconst_time; ! 558: int integration_time; ! 559: int jump_time; ! 560: int cse_time; ! 561: int loop_time; ! 562: int cse2_time; ! 563: int flow_time; ! 564: int combine_time; ! 565: int sched_time; ! 566: int local_alloc_time; ! 567: int global_alloc_time; ! 568: int sched2_time; ! 569: int dbr_sched_time; ! 570: int shorten_branch_time; ! 571: int stack_reg_time; ! 572: int final_time; ! 573: int symout_time; ! 574: int dump_time; ! 575: ! 576: /* Return time used so far, in microseconds. */ ! 577: ! 578: int ! 579: get_run_time () ! 580: { ! 581: #ifdef USG ! 582: struct tms tms; ! 583: #else ! 584: #ifndef VMS ! 585: struct rusage rusage; ! 586: #else /* VMS */ ! 587: struct ! 588: { ! 589: int proc_user_time; ! 590: int proc_system_time; ! 591: int child_user_time; ! 592: int child_system_time; ! 593: } vms_times; ! 594: #endif ! 595: #endif ! 596: ! 597: if (quiet_flag) ! 598: return 0; ! 599: ! 600: #ifdef USG ! 601: times (&tms); ! 602: return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ); ! 603: #else ! 604: #ifndef VMS ! 605: getrusage (0, &rusage); ! 606: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec ! 607: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); ! 608: #else /* VMS */ ! 609: times (&vms_times); ! 610: return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; ! 611: #endif ! 612: #endif ! 613: } ! 614: ! 615: #define TIMEVAR(VAR, BODY) \ ! 616: do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0) ! 617: ! 618: void ! 619: print_time (str, total) ! 620: char *str; ! 621: int total; ! 622: { ! 623: fprintf (stderr, ! 624: "time in %s: %d.%06d\n", ! 625: str, total / 1000000, total % 1000000); ! 626: } ! 627: ! 628: /* Count an error or warning. Return 1 if the message should be printed. */ ! 629: ! 630: int ! 631: count_error (warningp) ! 632: int warningp; ! 633: { ! 634: if (warningp && inhibit_warnings) ! 635: return 0; ! 636: ! 637: if (warningp && !warnings_are_errors) ! 638: warningcount++; ! 639: else ! 640: { ! 641: static int warning_message = 0; ! 642: ! 643: if (warningp && !warning_message) ! 644: { ! 645: fprintf (stderr, "%s: warnings being treated as errors\n", progname); ! 646: warning_message = 1; ! 647: } ! 648: errorcount++; ! 649: } ! 650: ! 651: return 1; ! 652: } ! 653: ! 654: /* Print a fatal error message. NAME is the text. ! 655: Also include a system error message based on `errno'. */ ! 656: ! 657: void ! 658: pfatal_with_name (name) ! 659: char *name; ! 660: { ! 661: fprintf (stderr, "%s: ", progname); ! 662: perror (name); ! 663: exit (35); ! 664: } ! 665: ! 666: void ! 667: fatal_io_error (name) ! 668: char *name; ! 669: { ! 670: fprintf (stderr, "%s: %s: I/O error\n", progname, name); ! 671: exit (35); ! 672: } ! 673: ! 674: void ! 675: fatal (s, v) ! 676: char *s; ! 677: int v; ! 678: { ! 679: error (s, v); ! 680: exit (34); ! 681: } ! 682: ! 683: /* Called to give a better error message when we don't have an insn to match ! 684: what we are looking for or if the insn's constraints aren't satisfied, ! 685: rather than just calling abort(). */ ! 686: ! 687: void ! 688: fatal_insn_not_found (insn) ! 689: rtx insn; ! 690: { ! 691: if (INSN_CODE (insn) < 0) ! 692: error ("internal error--unrecognizable insn:", 0); ! 693: else ! 694: error ("internal error--insn does not satisfy its constraints:", 0); ! 695: debug_rtx (insn); ! 696: if (asm_out_file) ! 697: fflush (asm_out_file); ! 698: if (aux_info_file) ! 699: fflush (aux_info_file); ! 700: if (rtl_dump_file) ! 701: fflush (rtl_dump_file); ! 702: if (jump_opt_dump_file) ! 703: fflush (jump_opt_dump_file); ! 704: if (cse_dump_file) ! 705: fflush (cse_dump_file); ! 706: if (loop_dump_file) ! 707: fflush (loop_dump_file); ! 708: if (cse2_dump_file) ! 709: fflush (cse2_dump_file); ! 710: if (flow_dump_file) ! 711: fflush (flow_dump_file); ! 712: if (combine_dump_file) ! 713: fflush (combine_dump_file); ! 714: if (sched_dump_file) ! 715: fflush (sched_dump_file); ! 716: if (local_reg_dump_file) ! 717: fflush (local_reg_dump_file); ! 718: if (global_reg_dump_file) ! 719: fflush (global_reg_dump_file); ! 720: if (sched2_dump_file) ! 721: fflush (sched2_dump_file); ! 722: if (jump2_opt_dump_file) ! 723: fflush (jump2_opt_dump_file); ! 724: if (dbr_sched_dump_file) ! 725: fflush (dbr_sched_dump_file); ! 726: if (stack_reg_dump_file) ! 727: fflush (stack_reg_dump_file); ! 728: abort (); ! 729: } ! 730: ! 731: /* This is the default decl_printable_name function. */ ! 732: ! 733: static char * ! 734: decl_name (decl, kind) ! 735: tree decl; ! 736: char **kind; ! 737: { ! 738: return IDENTIFIER_POINTER (DECL_NAME (decl)); ! 739: } ! 740: ! 741: static int need_error_newline; ! 742: ! 743: /* Function of last error message; ! 744: more generally, function such that if next error message is in it ! 745: then we don't have to mention the function name. */ ! 746: static tree last_error_function = NULL; ! 747: ! 748: /* Used to detect when input_file_stack has changed since last described. */ ! 749: static int last_error_tick; ! 750: ! 751: /* Called when the start of a function definition is parsed, ! 752: this function prints on stderr the name of the function. */ ! 753: ! 754: void ! 755: announce_function (decl) ! 756: tree decl; ! 757: { ! 758: if (! quiet_flag) ! 759: { ! 760: char *junk; ! 761: if (rtl_dump_and_exit) ! 762: fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl))); ! 763: else ! 764: fprintf (stderr, " %s", (*decl_printable_name) (decl, &junk)); ! 765: fflush (stderr); ! 766: need_error_newline = 1; ! 767: last_error_function = current_function_decl; ! 768: } ! 769: } ! 770: ! 771: /* Prints out, if necessary, the name of the current function ! 772: which caused an error. Called from all error and warning functions. */ ! 773: ! 774: void ! 775: report_error_function (file) ! 776: char *file; ! 777: { ! 778: struct file_stack *p; ! 779: ! 780: if (need_error_newline) ! 781: { ! 782: fprintf (stderr, "\n"); ! 783: need_error_newline = 0; ! 784: } ! 785: ! 786: if (last_error_function != current_function_decl) ! 787: { ! 788: char *kind = "function"; ! 789: if (current_function_decl != 0 ! 790: && TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) ! 791: kind = "method"; ! 792: ! 793: if (file) ! 794: fprintf (stderr, "%s: ", file); ! 795: ! 796: if (current_function_decl == NULL) ! 797: fprintf (stderr, "At top level:\n"); ! 798: else ! 799: { ! 800: char *name = (*decl_printable_name) (current_function_decl, &kind); ! 801: fprintf (stderr, "In %s `%s':\n", kind, name); ! 802: } ! 803: ! 804: last_error_function = current_function_decl; ! 805: } ! 806: if (input_file_stack && input_file_stack->next != 0 ! 807: && input_file_stack_tick != last_error_tick) ! 808: { ! 809: fprintf (stderr, "In file included"); ! 810: for (p = input_file_stack->next; p; p = p->next) ! 811: { ! 812: fprintf (stderr, " from %s:%d", p->name, p->line); ! 813: if (p->next) ! 814: fprintf (stderr, ","); ! 815: } ! 816: fprintf (stderr, ":\n"); ! 817: last_error_tick = input_file_stack_tick; ! 818: } ! 819: } ! 820: ! 821: /* Report an error at the current line number. ! 822: S and V are a string and an arg for `printf'. */ ! 823: ! 824: void ! 825: error (s, v, v2) ! 826: char *s; ! 827: int v; /* @@also used as pointer */ ! 828: int v2; /* @@also used as pointer */ ! 829: { ! 830: error_with_file_and_line (input_filename, lineno, s, v, v2); ! 831: } ! 832: ! 833: /* Report an error at line LINE of file FILE. ! 834: S and V are a string and an arg for `printf'. */ ! 835: ! 836: void ! 837: error_with_file_and_line (file, line, s, v, v2) ! 838: char *file; ! 839: int line; ! 840: char *s; ! 841: int v; ! 842: int v2; ! 843: { ! 844: count_error (0); ! 845: ! 846: report_error_function (file); ! 847: ! 848: if (file) ! 849: fprintf (stderr, "%s:%d: ", file, line); ! 850: else ! 851: fprintf (stderr, "%s: ", progname); ! 852: fprintf (stderr, s, v, v2); ! 853: fprintf (stderr, "\n"); ! 854: } ! 855: ! 856: /* Report an error at the declaration DECL. ! 857: S and V are a string and an arg which uses %s to substitute the declaration name. */ ! 858: ! 859: void ! 860: error_with_decl (decl, s, v) ! 861: tree decl; ! 862: char *s; ! 863: int v; ! 864: { ! 865: char *junk; ! 866: count_error (0); ! 867: ! 868: report_error_function (DECL_SOURCE_FILE (decl)); ! 869: ! 870: fprintf (stderr, "%s:%d: ", ! 871: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 872: ! 873: if (DECL_NAME (decl)) ! 874: fprintf (stderr, s, (*decl_printable_name) (decl, &junk), v); ! 875: else ! 876: fprintf (stderr, s, "((anonymous))", v); ! 877: fprintf (stderr, "\n"); ! 878: } ! 879: ! 880: /* Report an error at the line number of the insn INSN. ! 881: S and V are a string and an arg for `printf'. ! 882: This is used only when INSN is an `asm' with operands, ! 883: and each ASM_OPERANDS records its own source file and line. */ ! 884: ! 885: void ! 886: error_for_asm (insn, s, v, v2) ! 887: rtx insn; ! 888: char *s; ! 889: int v; /* @@also used as pointer */ ! 890: int v2; /* @@also used as pointer */ ! 891: { ! 892: char *filename; ! 893: int line; ! 894: rtx body = PATTERN (insn); ! 895: rtx asmop; ! 896: ! 897: /* Find the (or one of the) ASM_OPERANDS in the insn. */ ! 898: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) ! 899: asmop = SET_SRC (body); ! 900: else if (GET_CODE (body) == ASM_OPERANDS) ! 901: asmop = body; ! 902: else if (GET_CODE (body) == PARALLEL ! 903: && GET_CODE (XVECEXP (body, 0, 0)) == SET) ! 904: asmop = SET_SRC (XVECEXP (body, 0, 0)); ! 905: else if (GET_CODE (body) == PARALLEL ! 906: && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) ! 907: asmop = XVECEXP (body, 0, 0); ! 908: ! 909: filename = ASM_OPERANDS_SOURCE_FILE (asmop); ! 910: line = ASM_OPERANDS_SOURCE_LINE (asmop); ! 911: ! 912: error_with_file_and_line (filename, line, s, v, v2); ! 913: } ! 914: ! 915: /* Report a warning at line LINE. ! 916: S and V are a string and an arg for `printf'. */ ! 917: ! 918: void ! 919: warning_with_file_and_line (file, line, s, v, v2, v3) ! 920: char *file; ! 921: int line; ! 922: char *s; ! 923: int v; ! 924: int v2; ! 925: int v3; ! 926: { ! 927: if (count_error (1) == 0) ! 928: return; ! 929: ! 930: report_error_function (file); ! 931: ! 932: if (file) ! 933: fprintf (stderr, "%s:%d: ", file, line); ! 934: else ! 935: fprintf (stderr, "%s: ", progname); ! 936: ! 937: fprintf (stderr, "warning: "); ! 938: fprintf (stderr, s, v, v2, v3); ! 939: fprintf (stderr, "\n"); ! 940: } ! 941: ! 942: /* Report a warning at the current line number. ! 943: S and V are a string and an arg for `printf'. */ ! 944: ! 945: void ! 946: warning (s, v, v2, v3) ! 947: char *s; ! 948: int v; /* @@also used as pointer */ ! 949: int v2; ! 950: int v3; ! 951: { ! 952: warning_with_file_and_line (input_filename, lineno, s, v, v2, v3); ! 953: } ! 954: ! 955: /* Report a warning at the declaration DECL. ! 956: S is string which uses %s to substitute the declaration name. ! 957: V is a second parameter that S can refer to. */ ! 958: ! 959: void ! 960: warning_with_decl (decl, s, v) ! 961: tree decl; ! 962: char *s; ! 963: int v; ! 964: { ! 965: char *junk; ! 966: ! 967: if (count_error (1) == 0) ! 968: return; ! 969: ! 970: report_error_function (DECL_SOURCE_FILE (decl)); ! 971: ! 972: fprintf (stderr, "%s:%d: ", ! 973: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 974: ! 975: fprintf (stderr, "warning: "); ! 976: if (DECL_NAME (decl)) ! 977: fprintf (stderr, s, (*decl_printable_name) (decl, &junk), v); ! 978: else ! 979: fprintf (stderr, s, "((anonymous))", v); ! 980: fprintf (stderr, "\n"); ! 981: } ! 982: ! 983: /* Report a warning at the line number of the insn INSN. ! 984: S and V are a string and an arg for `printf'. ! 985: This is used only when INSN is an `asm' with operands, ! 986: and each ASM_OPERANDS records its own source file and line. */ ! 987: ! 988: void ! 989: warning_for_asm (insn, s, v, v2) ! 990: rtx insn; ! 991: char *s; ! 992: int v; /* @@also used as pointer */ ! 993: int v2; /* @@also used as pointer */ ! 994: { ! 995: char *filename; ! 996: int line; ! 997: rtx body = PATTERN (insn); ! 998: rtx asmop; ! 999: ! 1000: /* Find the (or one of the) ASM_OPERANDS in the insn. */ ! 1001: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) ! 1002: asmop = SET_SRC (body); ! 1003: else if (GET_CODE (body) == ASM_OPERANDS) ! 1004: asmop = body; ! 1005: else if (GET_CODE (body) == PARALLEL ! 1006: && GET_CODE (XVECEXP (body, 0, 0)) == SET) ! 1007: asmop = SET_SRC (XVECEXP (body, 0, 0)); ! 1008: else if (GET_CODE (body) == PARALLEL ! 1009: && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) ! 1010: asmop = XVECEXP (body, 0, 0); ! 1011: ! 1012: filename = ASM_OPERANDS_SOURCE_FILE (asmop); ! 1013: line = ASM_OPERANDS_SOURCE_LINE (asmop); ! 1014: ! 1015: warning_with_file_and_line (filename, line, s, v, v2); ! 1016: } ! 1017: ! 1018: /* These functions issue either warnings or errors depending on ! 1019: -pedantic-errors. */ ! 1020: ! 1021: void ! 1022: pedwarn (s, v, v2) ! 1023: char *s; ! 1024: int v; /* @@also used as pointer */ ! 1025: int v2; ! 1026: { ! 1027: if (flag_pedantic_errors) ! 1028: error (s, v, v2); ! 1029: else ! 1030: warning (s, v, v2); ! 1031: } ! 1032: ! 1033: void ! 1034: pedwarn_with_decl (decl, s, v) ! 1035: tree decl; ! 1036: char *s; ! 1037: int v; ! 1038: { ! 1039: if (flag_pedantic_errors) ! 1040: error_with_decl (decl, s, v); ! 1041: else ! 1042: warning_with_decl (decl, s, v); ! 1043: } ! 1044: ! 1045: void ! 1046: pedwarn_with_file_and_line (file, line, s, v, v2) ! 1047: char *file; ! 1048: int line; ! 1049: char *s; ! 1050: int v; ! 1051: int v2; ! 1052: { ! 1053: if (flag_pedantic_errors) ! 1054: error_with_file_and_line (file, line, s, v, v2); ! 1055: else ! 1056: warning_with_file_and_line (file, line, s, v, v2); ! 1057: } ! 1058: ! 1059: /* Apologize for not implementing some feature. ! 1060: S, V, and V2 are a string and args for `printf'. */ ! 1061: ! 1062: void ! 1063: sorry (s, v, v2) ! 1064: char *s; ! 1065: int v, v2; ! 1066: { ! 1067: sorrycount++; ! 1068: if (input_filename) ! 1069: fprintf (stderr, "%s:%d: ", input_filename, lineno); ! 1070: else ! 1071: fprintf (stderr, "%s: ", progname); ! 1072: ! 1073: fprintf (stderr, "sorry, not implemented: "); ! 1074: fprintf (stderr, s, v, v2); ! 1075: fprintf (stderr, "\n"); ! 1076: } ! 1077: ! 1078: /* Apologize for not implementing some feature, then quit. ! 1079: S, V, and V2 are a string and args for `printf'. */ ! 1080: ! 1081: void ! 1082: really_sorry (s, v, v2) ! 1083: char *s; ! 1084: int v, v2; ! 1085: { ! 1086: if (input_filename) ! 1087: fprintf (stderr, "%s:%d: ", input_filename, lineno); ! 1088: else ! 1089: fprintf (stderr, "c++: "); ! 1090: ! 1091: fprintf (stderr, "sorry, not implemented: "); ! 1092: fprintf (stderr, s, v, v2); ! 1093: fatal (" (fatal)\n"); ! 1094: } ! 1095: ! 1096: /* More 'friendly' abort that prints the line and file. ! 1097: config.h can #define abort fancy_abort if you like that sort of thing. ! 1098: ! 1099: I don't think this is actually a good idea. ! 1100: Other sorts of crashes will look a certain way. ! 1101: It is a good thing if crashes from calling abort look the same way. ! 1102: -- RMS */ ! 1103: ! 1104: void ! 1105: fancy_abort () ! 1106: { ! 1107: fatal ("internal gcc abort"); ! 1108: } ! 1109: ! 1110: /* This calls abort and is used to avoid problems when abort if a macro. ! 1111: It is used when we need to pass the address of abort. */ ! 1112: ! 1113: void ! 1114: do_abort () ! 1115: { ! 1116: abort (); ! 1117: } ! 1118: ! 1119: /* When `malloc.c' is compiled with `rcheck' defined, ! 1120: it calls this function to report clobberage. */ ! 1121: ! 1122: void ! 1123: botch (s) ! 1124: { ! 1125: abort (); ! 1126: } ! 1127: ! 1128: /* Same as `malloc' but report error if no memory available. */ ! 1129: ! 1130: int ! 1131: xmalloc (size) ! 1132: unsigned size; ! 1133: { ! 1134: register int value = (int) malloc (size); ! 1135: if (value == 0) ! 1136: fatal ("virtual memory exhausted"); ! 1137: return value; ! 1138: } ! 1139: ! 1140: /* Same as `realloc' but report error if no memory available. */ ! 1141: ! 1142: int ! 1143: xrealloc (ptr, size) ! 1144: char *ptr; ! 1145: int size; ! 1146: { ! 1147: int result = realloc (ptr, size); ! 1148: if (!result) ! 1149: fatal ("virtual memory exhausted"); ! 1150: return result; ! 1151: } ! 1152: ! 1153: /* Return the logarithm of X, base 2, considering X unsigned, ! 1154: if X is a power of 2. Otherwise, returns -1. */ ! 1155: ! 1156: int ! 1157: exact_log2 (x) ! 1158: register unsigned int x; ! 1159: { ! 1160: register int log = 0; ! 1161: /* Test for 0 or a power of 2. */ ! 1162: if (x == 0 || x != (x & -x)) ! 1163: return -1; ! 1164: while ((x >>= 1) != 0) ! 1165: log++; ! 1166: return log; ! 1167: } ! 1168: ! 1169: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. ! 1170: If X is 0, return -1. */ ! 1171: ! 1172: int ! 1173: floor_log2 (x) ! 1174: register unsigned int x; ! 1175: { ! 1176: register int log = -1; ! 1177: while (x != 0) ! 1178: log++, ! 1179: x >>= 1; ! 1180: return log; ! 1181: } ! 1182: ! 1183: int float_handled; ! 1184: jmp_buf float_handler; ! 1185: ! 1186: /* Specify where to longjmp to when a floating arithmetic error happens. ! 1187: If HANDLER is 0, it means don't handle the errors any more. */ ! 1188: ! 1189: void ! 1190: set_float_handler (handler) ! 1191: jmp_buf handler; ! 1192: { ! 1193: float_handled = (handler != 0); ! 1194: if (handler) ! 1195: bcopy (handler, float_handler, sizeof (float_handler)); ! 1196: } ! 1197: ! 1198: /* Signals actually come here. */ ! 1199: ! 1200: static void ! 1201: float_signal (signo) ! 1202: /* If this is missing, some compilers complain. */ ! 1203: int signo; ! 1204: { ! 1205: if (float_handled == 0) ! 1206: abort (); ! 1207: #if defined (USG) || defined (hpux) ! 1208: signal (SIGFPE, float_signal); /* re-enable the signal catcher */ ! 1209: #endif ! 1210: float_handled = 0; ! 1211: signal (SIGFPE, float_signal); ! 1212: longjmp (float_handler, 1); ! 1213: } ! 1214: ! 1215: /* Handler for SIGPIPE. */ ! 1216: ! 1217: static void ! 1218: pipe_closed (signo) ! 1219: /* If this is missing, some compilers complain. */ ! 1220: int signo; ! 1221: { ! 1222: fatal ("output pipe has been closed"); ! 1223: } ! 1224: ! 1225: /* Strip off a legitimate source ending from the input string NAME of ! 1226: length LEN. */ ! 1227: ! 1228: void ! 1229: strip_off_ending (name, len) ! 1230: char *name; ! 1231: int len; ! 1232: { ! 1233: if (len > 2 && ! strcmp (".c", name + len - 2)) ! 1234: name[len - 2] = 0; ! 1235: else if (len > 2 && ! strcmp (".m", name + len - 2)) ! 1236: name[len - 2] = 0; ! 1237: else if (len > 2 && ! strcmp (".i", name + len - 2)) ! 1238: name[len - 2] = 0; ! 1239: else if (len > 3 && ! strcmp (".ii", name + len - 3)) ! 1240: name[len - 3] = 0; ! 1241: else if (len > 3 && ! strcmp (".co", name + len - 3)) ! 1242: name[len - 3] = 0; ! 1243: else if (len > 3 && ! strcmp (".cc", name + len - 3)) ! 1244: name[len - 3] = 0; ! 1245: else if (len > 2 && ! strcmp (".f", name + len - 2)) ! 1246: name[len - 2] = 0; ! 1247: else if (len > 4 && ! strcmp (".ada", name + len - 4)) ! 1248: name[len - 4] = 0; ! 1249: } ! 1250: ! 1251: /* Output a file name in the form wanted by System V. */ ! 1252: ! 1253: void ! 1254: output_file_directive (asm_file, input_name) ! 1255: FILE *asm_file; ! 1256: char *input_name; ! 1257: { ! 1258: int len = strlen (input_name); ! 1259: char *na = input_name + len; ! 1260: ! 1261: /* NA gets INPUT_NAME sans directory names. */ ! 1262: while (na > input_name) ! 1263: { ! 1264: if (na[-1] == '/') ! 1265: break; ! 1266: na--; ! 1267: } ! 1268: ! 1269: #ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME ! 1270: ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na); ! 1271: #else ! 1272: #ifdef ASM_OUTPUT_SOURCE_FILENAME ! 1273: ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); ! 1274: #else ! 1275: fprintf (asm_file, "\t.file\t\"%s\"\n", na); ! 1276: #endif ! 1277: #endif ! 1278: } ! 1279: ! 1280: /* Compile an entire file of output from cpp, named NAME. ! 1281: Write a file of assembly output and various debugging dumps. */ ! 1282: ! 1283: static void ! 1284: compile_file (name) ! 1285: char *name; ! 1286: { ! 1287: tree globals; ! 1288: int start_time; ! 1289: int dump_base_name_length; ! 1290: char *aux_info_file_name; ! 1291: ! 1292: int name_specified = name != 0; ! 1293: ! 1294: if (dump_base_name == 0) ! 1295: dump_base_name = name ? name : "gccdump"; ! 1296: dump_base_name_length = strlen (dump_base_name); ! 1297: ! 1298: parse_time = 0; ! 1299: varconst_time = 0; ! 1300: integration_time = 0; ! 1301: jump_time = 0; ! 1302: cse_time = 0; ! 1303: loop_time = 0; ! 1304: cse2_time = 0; ! 1305: flow_time = 0; ! 1306: combine_time = 0; ! 1307: sched_time = 0; ! 1308: local_alloc_time = 0; ! 1309: global_alloc_time = 0; ! 1310: sched2_time = 0; ! 1311: dbr_sched_time = 0; ! 1312: shorten_branch_time = 0; ! 1313: stack_reg_time = 0; ! 1314: final_time = 0; ! 1315: symout_time = 0; ! 1316: dump_time = 0; ! 1317: ! 1318: /* Open input file. */ ! 1319: ! 1320: if (name == 0 || !strcmp (name, "-")) ! 1321: { ! 1322: finput = stdin; ! 1323: name = "stdin"; ! 1324: } ! 1325: else ! 1326: finput = fopen (name, "r"); ! 1327: if (finput == 0) ! 1328: pfatal_with_name (name); ! 1329: ! 1330: /* Initialize data in various passes. */ ! 1331: ! 1332: init_obstacks (); ! 1333: init_tree_codes (); ! 1334: init_lex (); ! 1335: init_rtl (); ! 1336: init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL ! 1337: || debug_info_level == DINFO_LEVEL_VERBOSE); ! 1338: init_decl_processing (); ! 1339: init_optabs (); ! 1340: init_stmt (); ! 1341: init_expmed (); ! 1342: init_loop (); ! 1343: init_reload (); ! 1344: ! 1345: if (flag_caller_saves) ! 1346: init_caller_save (); ! 1347: ! 1348: /* If auxilliary info generation is desired, open the output file. */ ! 1349: if (flag_gen_aux_info) ! 1350: { ! 1351: aux_info_file_name = (char *) xmalloc (dump_base_name_length + 6); ! 1352: strcpy (aux_info_file_name, dump_base_name); ! 1353: strcat (aux_info_file_name, ".X"); ! 1354: aux_info_file = fopen (aux_info_file_name, "w"); ! 1355: if (aux_info_file == 0) ! 1356: pfatal_with_name (aux_info_file_name); ! 1357: } ! 1358: ! 1359: /* If rtl dump desired, open the output file. */ ! 1360: if (rtl_dump) ! 1361: { ! 1362: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1363: strcpy (dumpname, dump_base_name); ! 1364: strcat (dumpname, ".rtl"); ! 1365: rtl_dump_file = fopen (dumpname, "w"); ! 1366: if (rtl_dump_file == 0) ! 1367: pfatal_with_name (dumpname); ! 1368: } ! 1369: ! 1370: /* If jump_opt dump desired, open the output file. */ ! 1371: if (jump_opt_dump) ! 1372: { ! 1373: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1374: strcpy (dumpname, dump_base_name); ! 1375: strcat (dumpname, ".jump"); ! 1376: jump_opt_dump_file = fopen (dumpname, "w"); ! 1377: if (jump_opt_dump_file == 0) ! 1378: pfatal_with_name (dumpname); ! 1379: } ! 1380: ! 1381: /* If cse dump desired, open the output file. */ ! 1382: if (cse_dump) ! 1383: { ! 1384: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1385: strcpy (dumpname, dump_base_name); ! 1386: strcat (dumpname, ".cse"); ! 1387: cse_dump_file = fopen (dumpname, "w"); ! 1388: if (cse_dump_file == 0) ! 1389: pfatal_with_name (dumpname); ! 1390: } ! 1391: ! 1392: /* If loop dump desired, open the output file. */ ! 1393: if (loop_dump) ! 1394: { ! 1395: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1396: strcpy (dumpname, dump_base_name); ! 1397: strcat (dumpname, ".loop"); ! 1398: loop_dump_file = fopen (dumpname, "w"); ! 1399: if (loop_dump_file == 0) ! 1400: pfatal_with_name (dumpname); ! 1401: } ! 1402: ! 1403: /* If cse2 dump desired, open the output file. */ ! 1404: if (cse2_dump) ! 1405: { ! 1406: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1407: strcpy (dumpname, dump_base_name); ! 1408: strcat (dumpname, ".cse2"); ! 1409: cse2_dump_file = fopen (dumpname, "w"); ! 1410: if (cse2_dump_file == 0) ! 1411: pfatal_with_name (dumpname); ! 1412: } ! 1413: ! 1414: /* If flow dump desired, open the output file. */ ! 1415: if (flow_dump) ! 1416: { ! 1417: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1418: strcpy (dumpname, dump_base_name); ! 1419: strcat (dumpname, ".flow"); ! 1420: flow_dump_file = fopen (dumpname, "w"); ! 1421: if (flow_dump_file == 0) ! 1422: pfatal_with_name (dumpname); ! 1423: } ! 1424: ! 1425: /* If combine dump desired, open the output file. */ ! 1426: if (combine_dump) ! 1427: { ! 1428: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); ! 1429: strcpy (dumpname, dump_base_name); ! 1430: strcat (dumpname, ".combine"); ! 1431: combine_dump_file = fopen (dumpname, "w"); ! 1432: if (combine_dump_file == 0) ! 1433: pfatal_with_name (dumpname); ! 1434: } ! 1435: ! 1436: /* If scheduling dump desired, open the output file. */ ! 1437: if (sched_dump) ! 1438: { ! 1439: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 1440: strcpy (dumpname, dump_base_name); ! 1441: strcat (dumpname, ".sched"); ! 1442: sched_dump_file = fopen (dumpname, "w"); ! 1443: if (sched_dump_file == 0) ! 1444: pfatal_with_name (dumpname); ! 1445: } ! 1446: ! 1447: /* If local_reg dump desired, open the output file. */ ! 1448: if (local_reg_dump) ! 1449: { ! 1450: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1451: strcpy (dumpname, dump_base_name); ! 1452: strcat (dumpname, ".lreg"); ! 1453: local_reg_dump_file = fopen (dumpname, "w"); ! 1454: if (local_reg_dump_file == 0) ! 1455: pfatal_with_name (dumpname); ! 1456: } ! 1457: ! 1458: /* If global_reg dump desired, open the output file. */ ! 1459: if (global_reg_dump) ! 1460: { ! 1461: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1462: strcpy (dumpname, dump_base_name); ! 1463: strcat (dumpname, ".greg"); ! 1464: global_reg_dump_file = fopen (dumpname, "w"); ! 1465: if (global_reg_dump_file == 0) ! 1466: pfatal_with_name (dumpname); ! 1467: } ! 1468: ! 1469: /* If 2nd scheduling dump desired, open the output file. */ ! 1470: if (sched2_dump) ! 1471: { ! 1472: register char *dumpname = (char *) xmalloc (dump_base_name_length + 8); ! 1473: strcpy (dumpname, dump_base_name); ! 1474: strcat (dumpname, ".sched2"); ! 1475: sched2_dump_file = fopen (dumpname, "w"); ! 1476: if (sched2_dump_file == 0) ! 1477: pfatal_with_name (dumpname); ! 1478: } ! 1479: ! 1480: /* If jump2_opt dump desired, open the output file. */ ! 1481: if (jump2_opt_dump) ! 1482: { ! 1483: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 1484: strcpy (dumpname, dump_base_name); ! 1485: strcat (dumpname, ".jump2"); ! 1486: jump2_opt_dump_file = fopen (dumpname, "w"); ! 1487: if (jump2_opt_dump_file == 0) ! 1488: pfatal_with_name (dumpname); ! 1489: } ! 1490: ! 1491: /* If dbr_sched dump desired, open the output file. */ ! 1492: if (dbr_sched_dump) ! 1493: { ! 1494: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 1495: strcpy (dumpname, dump_base_name); ! 1496: strcat (dumpname, ".dbr"); ! 1497: dbr_sched_dump_file = fopen (dumpname, "w"); ! 1498: if (dbr_sched_dump_file == 0) ! 1499: pfatal_with_name (dumpname); ! 1500: } ! 1501: ! 1502: #ifdef STACK_REGS ! 1503: ! 1504: /* If stack_reg dump desired, open the output file. */ ! 1505: if (stack_reg_dump) ! 1506: { ! 1507: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); ! 1508: strcpy (dumpname, dump_base_name); ! 1509: strcat (dumpname, ".stack"); ! 1510: stack_reg_dump_file = fopen (dumpname, "w"); ! 1511: if (stack_reg_dump_file == 0) ! 1512: pfatal_with_name (dumpname); ! 1513: } ! 1514: ! 1515: #endif ! 1516: ! 1517: /* Open assembler code output file. */ ! 1518: ! 1519: if (! name_specified && asm_file_name == 0) ! 1520: asm_out_file = stdout; ! 1521: else ! 1522: { ! 1523: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1524: int len = strlen (dump_base_name); ! 1525: strcpy (dumpname, dump_base_name); ! 1526: strip_off_ending (dumpname, len); ! 1527: strcat (dumpname, ".s"); ! 1528: if (asm_file_name == 0) ! 1529: { ! 1530: asm_file_name = (char *) xmalloc (strlen (dumpname) + 1); ! 1531: strcpy (asm_file_name, dumpname); ! 1532: } ! 1533: if (!strcmp (asm_file_name, "-")) ! 1534: asm_out_file = stdout; ! 1535: else ! 1536: asm_out_file = fopen (asm_file_name, "w"); ! 1537: if (asm_out_file == 0) ! 1538: pfatal_with_name (asm_file_name); ! 1539: } ! 1540: ! 1541: input_filename = name; ! 1542: ! 1543: /* Perform language-specific initialization. ! 1544: This may set main_input_filename. */ ! 1545: lang_init (); ! 1546: ! 1547: /* If the input doesn't start with a #line, use the input name ! 1548: as the official input file name. */ ! 1549: if (main_input_filename == 0) ! 1550: main_input_filename = name; ! 1551: ! 1552: /* Put an entry on the input file stack for the main input file. */ ! 1553: input_file_stack ! 1554: = (struct file_stack *) xmalloc (sizeof (struct file_stack)); ! 1555: input_file_stack->next = 0; ! 1556: input_file_stack->name = input_filename; ! 1557: ! 1558: ASM_FILE_START (asm_out_file); ! 1559: ! 1560: /* Output something to inform GDB that this compilation was by GCC. */ ! 1561: #ifndef ASM_IDENTIFY_GCC ! 1562: fprintf (asm_out_file, "gcc2_compiled.:\n"); ! 1563: #else ! 1564: ASM_IDENTIFY_GCC (asm_out_file); ! 1565: #endif ! 1566: /* Don't let the first function fall at the same address ! 1567: as gcc_compiled., if profiling. */ ! 1568: if (profile_flag || profile_block_flag) ! 1569: assemble_zeros (UNITS_PER_WORD); ! 1570: ! 1571: /* If dbx symbol table desired, initialize writing it ! 1572: and output the predefined types. */ ! 1573: #ifdef DBX_DEBUGGING_INFO ! 1574: if (write_symbols == DBX_DEBUG) ! 1575: TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename, ! 1576: getdecls ())); ! 1577: #endif ! 1578: #ifdef SDB_DEBUGGING_INFO ! 1579: if (write_symbols == SDB_DEBUG) ! 1580: TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename, ! 1581: getdecls ())); ! 1582: #endif ! 1583: #ifdef DWARF_DEBUGGING_INFO ! 1584: if (write_symbols == DWARF_DEBUG) ! 1585: TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename)); ! 1586: #endif ! 1587: ! 1588: /* Initialize yet another pass. */ ! 1589: ! 1590: init_final (main_input_filename); ! 1591: ! 1592: start_time = get_run_time (); ! 1593: ! 1594: /* Call the parser, which parses the entire file ! 1595: (calling rest_of_compilation for each function). */ ! 1596: ! 1597: if (yyparse () != 0) ! 1598: if (errorcount == 0) ! 1599: fprintf (stderr, "Errors detected in input file (your bison.simple is out of date)"); ! 1600: ! 1601: /* Compilation is now finished except for writing ! 1602: what's left of the symbol table output. */ ! 1603: ! 1604: parse_time += get_run_time () - start_time; ! 1605: ! 1606: parse_time -= integration_time; ! 1607: parse_time -= varconst_time; ! 1608: ! 1609: globals = getdecls (); ! 1610: ! 1611: /* Really define vars that have had only a tentative definition. ! 1612: Really output inline functions that must actually be callable ! 1613: and have not been output so far. */ ! 1614: ! 1615: { ! 1616: int len = list_length (globals); ! 1617: tree *vec = (tree *) alloca (sizeof (tree) * len); ! 1618: int i; ! 1619: tree decl; ! 1620: ! 1621: /* Process the decls in reverse order--earliest first. ! 1622: Put them into VEC from back to front, then take out from front. */ ! 1623: ! 1624: for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) ! 1625: vec[len - i - 1] = decl; ! 1626: ! 1627: for (i = 0; i < len; i++) ! 1628: { ! 1629: decl = vec[i]; ! 1630: if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) ! 1631: && ! TREE_ASM_WRITTEN (decl)) ! 1632: { ! 1633: /* Don't write out static consts, unless we used them. ! 1634: (This used to write them out only if the address was ! 1635: taken, but that was wrong; if the variable was simply ! 1636: referred to, it still needs to exist or else it will ! 1637: be undefined in the linker.) */ ! 1638: if (! TREE_READONLY (decl) ! 1639: || TREE_PUBLIC (decl) ! 1640: || TREE_USED (decl) ! 1641: || TREE_ADDRESSABLE (decl) ! 1642: || TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl))) ! 1643: rest_of_decl_compilation (decl, 0, 1, 1); ! 1644: else ! 1645: /* Cancel the RTL for this decl so that, if debugging info ! 1646: output for global variables is still to come, ! 1647: this one will be omitted. */ ! 1648: DECL_RTL (decl) = NULL; ! 1649: } ! 1650: ! 1651: if (TREE_CODE (decl) == FUNCTION_DECL ! 1652: && ! TREE_ASM_WRITTEN (decl) ! 1653: && DECL_INITIAL (decl) != 0 ! 1654: && (TREE_ADDRESSABLE (decl) ! 1655: || TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl))) ! 1656: && ! TREE_EXTERNAL (decl)) ! 1657: output_inline_function (decl); ! 1658: ! 1659: /* Warn about any function or variable ! 1660: declared static but not defined. */ ! 1661: if ((warn_unused ! 1662: || TREE_USED (decl) ! 1663: || (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))) ! 1664: /* && TREE_CODE (decl) == FUNCTION_DECL */ ! 1665: && DECL_INITIAL (decl) == 0 ! 1666: && TREE_EXTERNAL (decl) ! 1667: && ! TREE_PUBLIC (decl)) ! 1668: warning_with_decl (decl, "`%s' declared `static' but never defined"); ! 1669: /* Warn about static fns or vars defined but not used, ! 1670: but not about inline functions ! 1671: since unused inline statics is normal practice. */ ! 1672: if (warn_unused ! 1673: && (TREE_CODE (decl) == FUNCTION_DECL ! 1674: || TREE_CODE (decl) == VAR_DECL) ! 1675: && ! TREE_EXTERNAL (decl) ! 1676: && ! TREE_PUBLIC (decl) ! 1677: && ! TREE_USED (decl) ! 1678: && ! TREE_INLINE (decl) ! 1679: /* The TREE_USED bit for file-scope decls ! 1680: is kept in the identifier, to handle multiple ! 1681: external decls in different scopes. */ ! 1682: && ! TREE_USED (DECL_NAME (decl))) ! 1683: warning_with_decl (decl, "`%s' defined but not used"); ! 1684: ! 1685: #ifdef SDB_DEBUGGING_INFO ! 1686: /* The COFF linker can move initialized global vars to the end. ! 1687: And that can screw up the symbol ordering. ! 1688: By putting the symbols in that order to begin with, ! 1689: we avoid a problem. [email protected]. */ ! 1690: if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL ! 1691: && TREE_PUBLIC (decl) && DECL_INITIAL (decl) ! 1692: && DECL_RTL (decl) != 0) ! 1693: TIMEVAR (symout_time, sdbout_symbol (decl, 0)); ! 1694: ! 1695: /* Output COFF information for non-global ! 1696: file-scope initialized variables. */ ! 1697: if (write_symbols == SDB_DEBUG ! 1698: && TREE_CODE (decl) == VAR_DECL ! 1699: && DECL_INITIAL (decl) ! 1700: && DECL_RTL (decl) != 0 ! 1701: && GET_CODE (DECL_RTL (decl)) == MEM) ! 1702: TIMEVAR (symout_time, sdbout_toplevel_data (decl)); ! 1703: #endif /* SDB_DEBUGGING_INFO */ ! 1704: #ifdef DWARF_DEBUGGING_INFO ! 1705: /* Output DWARF information for file-scope tenative data object ! 1706: declarations, file-scope (extern) function declarations (which ! 1707: had no corresponding body) and file-scope tagged type declarations ! 1708: and definitions which have not yet been forced out. */ ! 1709: ! 1710: if (write_symbols == DWARF_DEBUG ! 1711: && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) ! 1712: TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); ! 1713: #endif ! 1714: } ! 1715: } ! 1716: ! 1717: /* Do dbx symbols */ ! 1718: #ifdef DBX_DEBUGGING_INFO ! 1719: if (write_symbols == DBX_DEBUG) ! 1720: TIMEVAR (symout_time, ! 1721: { ! 1722: dbxout_finish (asm_out_file, main_input_filename); ! 1723: }); ! 1724: #endif ! 1725: ! 1726: #ifdef DWARF_DEBUGGING_INFO ! 1727: if (write_symbols == DWARF_DEBUG) ! 1728: TIMEVAR (symout_time, ! 1729: { ! 1730: dwarfout_finish (); ! 1731: }); ! 1732: #endif ! 1733: ! 1734: /* Output some stuff at end of file if nec. */ ! 1735: ! 1736: end_final (main_input_filename); ! 1737: ! 1738: #ifdef ASM_FILE_END ! 1739: ASM_FILE_END (asm_out_file); ! 1740: #endif ! 1741: ! 1742: after_finish_compilation: ! 1743: ! 1744: /* Language-specific end of compilation actions. */ ! 1745: ! 1746: lang_finish (); ! 1747: ! 1748: /* Close the dump files. */ ! 1749: ! 1750: if (flag_gen_aux_info) ! 1751: { ! 1752: fclose (aux_info_file); ! 1753: if (errorcount) ! 1754: unlink (aux_info_file_name); ! 1755: } ! 1756: ! 1757: if (rtl_dump) ! 1758: fclose (rtl_dump_file); ! 1759: ! 1760: if (jump_opt_dump) ! 1761: fclose (jump_opt_dump_file); ! 1762: ! 1763: if (cse_dump) ! 1764: fclose (cse_dump_file); ! 1765: ! 1766: if (loop_dump) ! 1767: fclose (loop_dump_file); ! 1768: ! 1769: if (cse2_dump) ! 1770: fclose (cse2_dump_file); ! 1771: ! 1772: if (flow_dump) ! 1773: fclose (flow_dump_file); ! 1774: ! 1775: if (combine_dump) ! 1776: { ! 1777: dump_combine_total_stats (combine_dump_file); ! 1778: fclose (combine_dump_file); ! 1779: } ! 1780: ! 1781: if (sched_dump) ! 1782: fclose (sched_dump_file); ! 1783: ! 1784: if (local_reg_dump) ! 1785: fclose (local_reg_dump_file); ! 1786: ! 1787: if (global_reg_dump) ! 1788: fclose (global_reg_dump_file); ! 1789: ! 1790: if (sched2_dump) ! 1791: fclose (sched2_dump_file); ! 1792: ! 1793: if (jump2_opt_dump) ! 1794: fclose (jump2_opt_dump_file); ! 1795: ! 1796: if (dbr_sched_dump) ! 1797: fclose (dbr_sched_dump_file); ! 1798: ! 1799: #ifdef STACK_REGS ! 1800: if (stack_reg_dump) ! 1801: fclose (stack_reg_dump_file); ! 1802: #endif ! 1803: ! 1804: /* Close non-debugging input and output files. Take special care to note ! 1805: whether fclose returns an error, since the pages might still be on the ! 1806: buffer chain while the file is open. */ ! 1807: ! 1808: fclose (finput); ! 1809: if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0) ! 1810: fatal_io_error (asm_file_name); ! 1811: ! 1812: /* Print the times. */ ! 1813: ! 1814: if (! quiet_flag) ! 1815: { ! 1816: fprintf (stderr,"\n"); ! 1817: print_time ("parse", parse_time); ! 1818: print_time ("integration", integration_time); ! 1819: print_time ("jump", jump_time); ! 1820: print_time ("cse", cse_time); ! 1821: print_time ("loop", loop_time); ! 1822: print_time ("cse2", cse2_time); ! 1823: print_time ("flow", flow_time); ! 1824: print_time ("combine", combine_time); ! 1825: print_time ("sched", sched_time); ! 1826: print_time ("local-alloc", local_alloc_time); ! 1827: print_time ("global-alloc", global_alloc_time); ! 1828: print_time ("sched2", sched2_time); ! 1829: print_time ("dbranch", dbr_sched_time); ! 1830: print_time ("shorten-branch", shorten_branch_time); ! 1831: print_time ("stack-reg", stack_reg_time); ! 1832: print_time ("final", final_time); ! 1833: print_time ("varconst", varconst_time); ! 1834: print_time ("symout", symout_time); ! 1835: print_time ("dump", dump_time); ! 1836: } ! 1837: } ! 1838: ! 1839: /* This is called from various places for FUNCTION_DECL, VAR_DECL, ! 1840: and TYPE_DECL nodes. ! 1841: ! 1842: This does nothing for local (non-static) variables. ! 1843: Otherwise, it sets up the RTL and outputs any assembler code ! 1844: (label definition, storage allocation and initialization). ! 1845: ! 1846: DECL is the declaration. If ASMSPEC is nonzero, it specifies ! 1847: the assembler symbol name to be used. TOP_LEVEL is nonzero ! 1848: if this declaration is not within a function. */ ! 1849: ! 1850: void ! 1851: rest_of_decl_compilation (decl, asmspec, top_level, at_end) ! 1852: tree decl; ! 1853: char *asmspec; ! 1854: int top_level; ! 1855: int at_end; ! 1856: { ! 1857: /* Declarations of variables, and of functions defined elsewhere. */ ! 1858: ! 1859: /* Forward declarations for nested functions are not "external", ! 1860: but we need to treat them as if they were. */ ! 1861: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl) ! 1862: || TREE_CODE (decl) == FUNCTION_DECL) ! 1863: TIMEVAR (varconst_time, ! 1864: { ! 1865: make_decl_rtl (decl, asmspec, top_level); ! 1866: /* Don't output anything ! 1867: when a tentative file-scope definition is seen. ! 1868: But at end of compilation, do output code for them. */ ! 1869: if (! (! at_end && top_level ! 1870: && (DECL_INITIAL (decl) == 0 ! 1871: || DECL_INITIAL (decl) == error_mark_node))) ! 1872: assemble_variable (decl, top_level, at_end); ! 1873: }); ! 1874: else if (TREE_REGDECL (decl) && asmspec != 0) ! 1875: { ! 1876: if (decode_reg_name (asmspec) >= 0) ! 1877: { ! 1878: DECL_RTL (decl) = 0; ! 1879: make_decl_rtl (decl, asmspec, top_level); ! 1880: } ! 1881: else ! 1882: error ("invalid register name `%s' for register variable", asmspec); ! 1883: } ! 1884: #ifdef DBX_DEBUGGING_INFO ! 1885: else if (write_symbols == DBX_DEBUG && TREE_CODE (decl) == TYPE_DECL) ! 1886: TIMEVAR (symout_time, dbxout_symbol (decl, 0)); ! 1887: #endif ! 1888: #ifdef SDB_DEBUGGING_INFO ! 1889: else if (write_symbols == SDB_DEBUG && top_level ! 1890: && TREE_CODE (decl) == TYPE_DECL) ! 1891: TIMEVAR (symout_time, sdbout_symbol (decl, 0)); ! 1892: #endif ! 1893: } ! 1894: ! 1895: /* Called after finishing a record, union or enumeral type. */ ! 1896: ! 1897: void ! 1898: rest_of_type_compilation (type, toplev) ! 1899: tree type; ! 1900: int toplev; ! 1901: { ! 1902: #ifdef DBX_DEBUGGING_INFO ! 1903: if (write_symbols == DBX_DEBUG) ! 1904: TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev)); ! 1905: #endif ! 1906: #ifdef SDB_DEBUGGING_INFO ! 1907: if (write_symbols == SDB_DEBUG) ! 1908: TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev)); ! 1909: #endif ! 1910: } ! 1911: ! 1912: /* This is called from finish_function (within yyparse) ! 1913: after each top-level definition is parsed. ! 1914: It is supposed to compile that function or variable ! 1915: and output the assembler code for it. ! 1916: After we return, the tree storage is freed. */ ! 1917: ! 1918: void ! 1919: rest_of_compilation (decl) ! 1920: tree decl; ! 1921: { ! 1922: register rtx insns; ! 1923: int start_time = get_run_time (); ! 1924: int tem; ! 1925: /* Nonzero if we have saved the original DECL_INITIAL of the function, ! 1926: to be restored after we finish compiling the function ! 1927: (for use when compiling inline calls to this function). */ ! 1928: tree saved_block_tree = 0; ! 1929: ! 1930: /* If we are reconsidering an inline function ! 1931: at the end of compilation, skip the stuff for making it inline. */ ! 1932: ! 1933: if (DECL_SAVED_INSNS (decl) == 0) ! 1934: { ! 1935: int specd = TREE_INLINE (decl); ! 1936: char *lose; ! 1937: ! 1938: /* If requested, consider whether to make this function inline. */ ! 1939: if (specd || flag_inline_functions) ! 1940: TIMEVAR (integration_time, ! 1941: { ! 1942: lose = function_cannot_inline_p (decl); ! 1943: if (lose) ! 1944: { ! 1945: if (warn_inline && specd) ! 1946: warning_with_decl (decl, lose); ! 1947: TREE_INLINE (decl) = 0; ! 1948: } ! 1949: else ! 1950: TREE_INLINE (decl) = 1; ! 1951: }); ! 1952: ! 1953: insns = get_insns (); ! 1954: ! 1955: /* Dump the rtl code if we are dumping rtl. */ ! 1956: ! 1957: if (rtl_dump) ! 1958: TIMEVAR (dump_time, ! 1959: { ! 1960: fprintf (rtl_dump_file, "\n;; Function %s\n\n", ! 1961: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1962: if (DECL_SAVED_INSNS (decl)) ! 1963: fprintf (rtl_dump_file, ";; (integrable)\n\n"); ! 1964: print_rtl (rtl_dump_file, insns); ! 1965: fflush (rtl_dump_file); ! 1966: }); ! 1967: ! 1968: /* If function is inline, and we don't yet know whether to ! 1969: compile it by itself, defer decision till end of compilation. ! 1970: finish_compilation will call rest_of_compilation again ! 1971: for those functions that need to be output. */ ! 1972: ! 1973: if (TREE_INLINE (decl) ! 1974: && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) ! 1975: && ! flag_keep_inline_functions) ! 1976: || TREE_EXTERNAL (decl))) ! 1977: { ! 1978: TIMEVAR (integration_time, save_for_inline_nocopy (decl)); ! 1979: goto exit_rest_of_compilation; ! 1980: } ! 1981: ! 1982: /* If we have to compile the function now, save its rtl ! 1983: so that its compilation will not affect what others get. */ ! 1984: if (TREE_INLINE (decl)) ! 1985: { ! 1986: saved_block_tree = DECL_INITIAL (decl); ! 1987: TIMEVAR (integration_time, save_for_inline_copying (decl)); ! 1988: } ! 1989: } ! 1990: ! 1991: /* Suppress warnings for unused static functions ! 1992: defined (not just declared) in system headers. */ ! 1993: if (in_system_header && TREE_STATIC (decl) && !TREE_INLINE (decl)) ! 1994: TREE_USED (decl) = 1; ! 1995: ! 1996: TREE_ASM_WRITTEN (decl) = 1; ! 1997: ! 1998: /* Now that integrate will no longer see our rtl, we need not distinguish ! 1999: between the return value of this function and the return value of called ! 2000: functions. */ ! 2001: rtx_equal_function_value_matters = 0; ! 2002: ! 2003: if (rtl_dump_and_exit || flag_syntax_only) ! 2004: { ! 2005: goto exit_rest_of_compilation; ! 2006: } ! 2007: ! 2008: /* From now on, allocate rtl in current_obstack, not in saveable_obstack. ! 2009: Note that that may have been done above, in save_for_inline_copying. ! 2010: The call to resume_temporary_allocation near the end of this function ! 2011: goes back to the usual state of affairs. */ ! 2012: ! 2013: rtl_in_current_obstack (); ! 2014: ! 2015: #ifdef FINALIZE_PIC ! 2016: /* If we are doing position-independent code generation, now ! 2017: is the time to output special prologues and epilogues. ! 2018: We do not want to do this earlier, because it just clutters ! 2019: up inline functions with meaningless insns. */ ! 2020: if (flag_pic) ! 2021: FINALIZE_PIC; ! 2022: #endif ! 2023: ! 2024: insns = get_insns (); ! 2025: ! 2026: /* Copy any shared structure that should not be shared. */ ! 2027: ! 2028: unshare_all_rtl (insns); ! 2029: ! 2030: /* Instantiate all virtual registers. */ ! 2031: ! 2032: instantiate_virtual_regs (current_function_decl, get_insns ()); ! 2033: ! 2034: /* See if we have allocated stack slots that are not directly addressable. ! 2035: If so, scan all the insns and create explicit address computation ! 2036: for all references to such slots. */ ! 2037: /* fixup_stack_slots (); */ ! 2038: ! 2039: /* Do jump optimization the first time, if -opt. ! 2040: Also do it if -W, but in that case it doesn't change the rtl code, ! 2041: it only computes whether control can drop off the end of the function. */ ! 2042: ! 2043: if (optimize > 0 || extra_warnings || warn_return_type ! 2044: /* If function is `volatile', we should warn if it tries to return. */ ! 2045: || TREE_THIS_VOLATILE (decl)) ! 2046: { ! 2047: TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); ! 2048: TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1)); ! 2049: } ! 2050: ! 2051: /* Dump rtl code after jump, if we are doing that. */ ! 2052: ! 2053: if (jump_opt_dump) ! 2054: TIMEVAR (dump_time, ! 2055: { ! 2056: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n", ! 2057: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2058: print_rtl (jump_opt_dump_file, insns); ! 2059: fflush (jump_opt_dump_file); ! 2060: }); ! 2061: ! 2062: /* Perform common subexpression elimination. ! 2063: Nonzero value from `cse_main' means that jumps were simplified ! 2064: and some code may now be unreachable, so do ! 2065: jump optimization again. */ ! 2066: ! 2067: if (cse_dump) ! 2068: TIMEVAR (dump_time, ! 2069: { ! 2070: fprintf (cse_dump_file, "\n;; Function %s\n\n", ! 2071: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2072: }); ! 2073: ! 2074: if (optimize > 0) ! 2075: { ! 2076: TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1)); ! 2077: ! 2078: if (flag_thread_jumps) ! 2079: /* Hacks by tiemann & kenner. */ ! 2080: TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); ! 2081: ! 2082: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (), ! 2083: 0, cse_dump_file)); ! 2084: TIMEVAR (cse_time, delete_dead_from_cse (insns, max_reg_num ())); ! 2085: ! 2086: if (tem) ! 2087: TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0)); ! 2088: } ! 2089: ! 2090: /* Dump rtl code after cse, if we are doing that. */ ! 2091: ! 2092: if (cse_dump) ! 2093: TIMEVAR (dump_time, ! 2094: { ! 2095: print_rtl (cse_dump_file, insns); ! 2096: fflush (cse_dump_file); ! 2097: }); ! 2098: ! 2099: if (loop_dump) ! 2100: TIMEVAR (dump_time, ! 2101: { ! 2102: fprintf (loop_dump_file, "\n;; Function %s\n\n", ! 2103: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2104: }); ! 2105: ! 2106: /* Move constant computations out of loops. */ ! 2107: ! 2108: if (optimize > 0) ! 2109: { ! 2110: TIMEVAR (loop_time, ! 2111: { ! 2112: loop_optimize (insns, loop_dump ? loop_dump_file : 0); ! 2113: }); ! 2114: } ! 2115: ! 2116: /* Dump rtl code after loop opt, if we are doing that. */ ! 2117: ! 2118: if (loop_dump) ! 2119: TIMEVAR (dump_time, ! 2120: { ! 2121: print_rtl (loop_dump_file, insns); ! 2122: fflush (loop_dump_file); ! 2123: }); ! 2124: ! 2125: if (cse2_dump) ! 2126: TIMEVAR (dump_time, ! 2127: { ! 2128: fprintf (cse2_dump_file, "\n;; Function %s\n\n", ! 2129: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2130: }); ! 2131: ! 2132: if (optimize > 0 && flag_rerun_cse_after_loop) ! 2133: { ! 2134: TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0)); ! 2135: ! 2136: TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (), ! 2137: 1, cse2_dump_file)); ! 2138: if (tem) ! 2139: TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0)); ! 2140: } ! 2141: ! 2142: if (optimize > 0 && flag_thread_jumps) ! 2143: /* This pass of jump threading straightens out code ! 2144: that was kinked by loop optimization. */ ! 2145: TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); ! 2146: ! 2147: /* Dump rtl code after cse, if we are doing that. */ ! 2148: ! 2149: if (cse2_dump) ! 2150: TIMEVAR (dump_time, ! 2151: { ! 2152: print_rtl (cse2_dump_file, insns); ! 2153: fflush (cse2_dump_file); ! 2154: }); ! 2155: ! 2156: /* We are no longer anticipating cse in this function, at least. */ ! 2157: ! 2158: cse_not_expected = 1; ! 2159: ! 2160: /* Now we choose between stupid (pcc-like) register allocation ! 2161: (if we got the -noreg switch and not -opt) ! 2162: and smart register allocation. */ ! 2163: ! 2164: if (optimize > 0) /* Stupid allocation probably won't work */ ! 2165: obey_regdecls = 0; /* if optimizations being done. */ ! 2166: ! 2167: regclass_init (); ! 2168: ! 2169: /* Print function header into flow dump now ! 2170: because doing the flow analysis makes some of the dump. */ ! 2171: ! 2172: if (flow_dump) ! 2173: TIMEVAR (dump_time, ! 2174: { ! 2175: fprintf (flow_dump_file, "\n;; Function %s\n\n", ! 2176: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2177: }); ! 2178: ! 2179: if (obey_regdecls) ! 2180: { ! 2181: TIMEVAR (flow_time, ! 2182: { ! 2183: regclass (insns, max_reg_num ()); ! 2184: stupid_life_analysis (insns, max_reg_num (), ! 2185: flow_dump_file); ! 2186: }); ! 2187: } ! 2188: else ! 2189: { ! 2190: /* Do control and data flow analysis, ! 2191: and write some of the results to dump file. */ ! 2192: ! 2193: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (), ! 2194: flow_dump_file)); ! 2195: if (warn_uninitialized) ! 2196: { ! 2197: uninitialized_vars_warning (DECL_INITIAL (decl)); ! 2198: setjmp_args_warning (); ! 2199: } ! 2200: } ! 2201: ! 2202: /* Dump rtl after flow analysis. */ ! 2203: ! 2204: if (flow_dump) ! 2205: TIMEVAR (dump_time, ! 2206: { ! 2207: print_rtl (flow_dump_file, insns); ! 2208: fflush (flow_dump_file); ! 2209: }); ! 2210: ! 2211: /* If -opt, try combining insns through substitution. */ ! 2212: ! 2213: if (optimize > 0) ! 2214: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ())); ! 2215: ! 2216: /* Dump rtl code after insn combination. */ ! 2217: ! 2218: if (combine_dump) ! 2219: TIMEVAR (dump_time, ! 2220: { ! 2221: fprintf (combine_dump_file, "\n;; Function %s\n\n", ! 2222: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2223: dump_combine_stats (combine_dump_file); ! 2224: print_rtl (combine_dump_file, insns); ! 2225: fflush (combine_dump_file); ! 2226: }); ! 2227: ! 2228: /* Print function header into sched dump now ! 2229: because doing the sched analysis makes some of the dump. */ ! 2230: ! 2231: if (sched_dump) ! 2232: TIMEVAR (dump_time, ! 2233: { ! 2234: fprintf (sched_dump_file, "\n;; Function %s\n\n", ! 2235: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2236: }); ! 2237: ! 2238: if (optimize > 0 && flag_schedule_insns) ! 2239: { ! 2240: /* Do control and data sched analysis, ! 2241: and write some of the results to dump file. */ ! 2242: ! 2243: TIMEVAR (sched_time, schedule_insns (sched_dump_file)); ! 2244: } ! 2245: ! 2246: /* Dump rtl after instruction scheduling. */ ! 2247: ! 2248: if (sched_dump) ! 2249: TIMEVAR (dump_time, ! 2250: { ! 2251: print_rtl (sched_dump_file, insns); ! 2252: fflush (sched_dump_file); ! 2253: }); ! 2254: ! 2255: /* Unless we did stupid register allocation, ! 2256: allocate pseudo-regs that are used only within 1 basic block. */ ! 2257: ! 2258: if (!obey_regdecls) ! 2259: TIMEVAR (local_alloc_time, ! 2260: { ! 2261: regclass (insns, max_reg_num ()); ! 2262: local_alloc (); ! 2263: }); ! 2264: ! 2265: /* Dump rtl code after allocating regs within basic blocks. */ ! 2266: ! 2267: if (local_reg_dump) ! 2268: TIMEVAR (dump_time, ! 2269: { ! 2270: fprintf (local_reg_dump_file, "\n;; Function %s\n\n", ! 2271: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2272: dump_flow_info (local_reg_dump_file); ! 2273: dump_local_alloc (local_reg_dump_file); ! 2274: print_rtl (local_reg_dump_file, insns); ! 2275: fflush (local_reg_dump_file); ! 2276: }); ! 2277: ! 2278: if (global_reg_dump) ! 2279: TIMEVAR (dump_time, ! 2280: fprintf (global_reg_dump_file, "\n;; Function %s\n\n", ! 2281: IDENTIFIER_POINTER (DECL_NAME (decl)))); ! 2282: ! 2283: /* Unless we did stupid register allocation, ! 2284: allocate remaining pseudo-regs, then do the reload pass ! 2285: fixing up any insns that are invalid. */ ! 2286: ! 2287: TIMEVAR (global_alloc_time, ! 2288: { ! 2289: if (!obey_regdecls) ! 2290: global_alloc (global_reg_dump ? global_reg_dump_file : 0); ! 2291: else ! 2292: reload (insns, 0, ! 2293: global_reg_dump ? global_reg_dump_file : 0); ! 2294: }); ! 2295: ! 2296: if (global_reg_dump) ! 2297: TIMEVAR (dump_time, ! 2298: { ! 2299: dump_global_regs (global_reg_dump_file); ! 2300: print_rtl (global_reg_dump_file, insns); ! 2301: fflush (global_reg_dump_file); ! 2302: }); ! 2303: ! 2304: reload_completed = 1; ! 2305: ! 2306: if (optimize > 0 && flag_schedule_insns_after_reload) ! 2307: { ! 2308: if (sched2_dump) ! 2309: TIMEVAR (dump_time, ! 2310: { ! 2311: fprintf (sched2_dump_file, "\n;; Function %s\n\n", ! 2312: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2313: }); ! 2314: ! 2315: /* Do control and data sched analysis again, ! 2316: and write some more of the results to dump file. */ ! 2317: ! 2318: TIMEVAR (sched2_time, schedule_insns (sched2_dump_file)); ! 2319: ! 2320: /* Dump rtl after post-reorder instruction scheduling. */ ! 2321: ! 2322: if (sched2_dump) ! 2323: TIMEVAR (dump_time, ! 2324: { ! 2325: print_rtl (sched2_dump_file, insns); ! 2326: fflush (sched2_dump_file); ! 2327: }); ! 2328: } ! 2329: ! 2330: #ifdef LEAF_REGISTERS ! 2331: leaf_function = 0; ! 2332: if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ()) ! 2333: leaf_function = 1; ! 2334: #endif ! 2335: ! 2336: /* One more attempt to remove jumps to .+1 ! 2337: left by dead-store-elimination. ! 2338: Also do cross-jumping this time ! 2339: and delete no-op move insns. */ ! 2340: ! 2341: if (optimize > 0) ! 2342: { ! 2343: TIMEVAR (jump_time, jump_optimize (insns, 1, 1, 0)); ! 2344: } ! 2345: ! 2346: /* Dump rtl code after jump, if we are doing that. */ ! 2347: ! 2348: if (jump2_opt_dump) ! 2349: TIMEVAR (dump_time, ! 2350: { ! 2351: fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n", ! 2352: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2353: print_rtl (jump2_opt_dump_file, insns); ! 2354: fflush (jump2_opt_dump_file); ! 2355: }); ! 2356: ! 2357: /* If a scheduling pass for delayed branches is to be done, ! 2358: call the scheduling code. */ ! 2359: ! 2360: #ifdef DELAY_SLOTS ! 2361: if (optimize > 0 && flag_delayed_branch) ! 2362: { ! 2363: TIMEVAR (dbr_sched_time, dbr_schedule (insns, dbr_sched_dump_file)); ! 2364: if (dbr_sched_dump) ! 2365: { ! 2366: TIMEVAR (dump_time, ! 2367: { ! 2368: fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n", ! 2369: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2370: print_rtl (dbr_sched_dump_file, insns); ! 2371: fflush (dbr_sched_dump_file); ! 2372: }); ! 2373: } ! 2374: } ! 2375: #endif ! 2376: ! 2377: if (optimize > 0) ! 2378: /* Shorten branches. */ ! 2379: TIMEVAR (shorten_branch_time, ! 2380: { ! 2381: shorten_branches (get_insns ()); ! 2382: }); ! 2383: ! 2384: #ifdef STACK_REGS ! 2385: TIMEVAR (stack_reg_time, reg_to_stack (insns, stack_reg_dump_file)); ! 2386: if (stack_reg_dump) ! 2387: { ! 2388: TIMEVAR (dump_time, ! 2389: { ! 2390: fprintf (stack_reg_dump_file, "\n;; Function %s\n\n", ! 2391: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2392: print_rtl (stack_reg_dump_file, insns); ! 2393: fflush (stack_reg_dump_file); ! 2394: }); ! 2395: } ! 2396: #endif ! 2397: ! 2398: /* Now turn the rtl into assembler code. */ ! 2399: ! 2400: TIMEVAR (final_time, ! 2401: { ! 2402: rtx x; ! 2403: char *fnname; ! 2404: ! 2405: /* Get the function's name, as described by its RTL. ! 2406: This may be different from the DECL_NAME name used ! 2407: in the source file. */ ! 2408: ! 2409: x = DECL_RTL (decl); ! 2410: if (GET_CODE (x) != MEM) ! 2411: abort (); ! 2412: x = XEXP (x, 0); ! 2413: if (GET_CODE (x) != SYMBOL_REF) ! 2414: abort (); ! 2415: fnname = XSTR (x, 0); ! 2416: ! 2417: assemble_start_function (decl, fnname); ! 2418: final_start_function (insns, asm_out_file, optimize); ! 2419: final (insns, asm_out_file, optimize, 0); ! 2420: final_end_function (insns, asm_out_file, optimize); ! 2421: assemble_end_function (decl, fnname); ! 2422: fflush (asm_out_file); ! 2423: }); ! 2424: ! 2425: /* Write DBX symbols if requested */ ! 2426: ! 2427: /* Note that for those inline functions where we don't initially ! 2428: know for certain that we will be generating an out-of-line copy, ! 2429: the first invocation of this routine (rest_of_compilation) will ! 2430: skip over this code by doing a `goto exit_rest_of_compilation;'. ! 2431: Later on, finish_compilation will call rest_of_compilation again ! 2432: for those inline functions that need to have out-of-line copies ! 2433: generated. During that call, we *will* be routed past here. */ ! 2434: ! 2435: #ifdef DBX_DEBUGGING_INFO ! 2436: if (write_symbols == DBX_DEBUG) ! 2437: TIMEVAR (symout_time, dbxout_function (decl)); ! 2438: #endif ! 2439: ! 2440: #ifdef DWARF_DEBUGGING_INFO ! 2441: if (write_symbols == DWARF_DEBUG) ! 2442: TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); ! 2443: #endif ! 2444: ! 2445: exit_rest_of_compilation: ! 2446: ! 2447: /* Put back the tree of subblocks from before we copied it. ! 2448: Code generation and the output of debugging info may have modified ! 2449: the copy, but the original is unchanged. */ ! 2450: ! 2451: if (saved_block_tree != 0) ! 2452: DECL_INITIAL (decl) = saved_block_tree; ! 2453: ! 2454: reload_completed = 0; ! 2455: ! 2456: /* Clear out the real_constant_chain before some of the rtx's ! 2457: it runs through become garbage. */ ! 2458: ! 2459: clear_const_double_mem (); ! 2460: ! 2461: /* Cancel the effect of rtl_in_current_obstack. */ ! 2462: ! 2463: resume_temporary_allocation (); ! 2464: ! 2465: /* The parsing time is all the time spent in yyparse ! 2466: *except* what is spent in this function. */ ! 2467: ! 2468: parse_time -= get_run_time () - start_time; ! 2469: } ! 2470: ! 2471: /* Entry point of cc1/c++. Decode command args, then call compile_file. ! 2472: Exit code is 35 if can't open files, 34 if fatal error, ! 2473: 33 if had nonfatal errors, else success. */ ! 2474: ! 2475: int ! 2476: main (argc, argv, envp) ! 2477: int argc; ! 2478: char **argv; ! 2479: char **envp; ! 2480: { ! 2481: register int i; ! 2482: char *filename = 0; ! 2483: int flag_print_mem = 0; ! 2484: int version_flag = 0; ! 2485: char *p; ! 2486: ! 2487: /* save in case md file wants to emit args as a comment. */ ! 2488: save_argc = argc; ! 2489: save_argv = argv; ! 2490: ! 2491: p = argv[0] + strlen (argv[0]); ! 2492: while (p != argv[0] && p[-1] != '/') --p; ! 2493: progname = p; ! 2494: ! 2495: #ifdef RLIMIT_STACK ! 2496: /* Get rid of any avoidable limit on stack size. */ ! 2497: { ! 2498: struct rlimit rlim; ! 2499: ! 2500: /* Set the stack limit huge so that alloca does not fail. */ ! 2501: getrlimit (RLIMIT_STACK, &rlim); ! 2502: rlim.rlim_cur = rlim.rlim_max; ! 2503: setrlimit (RLIMIT_STACK, &rlim); ! 2504: } ! 2505: #endif /* RLIMIT_STACK */ ! 2506: ! 2507: signal (SIGFPE, float_signal); ! 2508: ! 2509: signal (SIGPIPE, pipe_closed); ! 2510: ! 2511: decl_printable_name = decl_name; ! 2512: lang_expand_expr = (struct rtx_def *(*)()) do_abort; ! 2513: ! 2514: /* Initialize whether `char' is signed. */ ! 2515: flag_signed_char = DEFAULT_SIGNED_CHAR; ! 2516: #ifdef DEFAULT_SHORT_ENUMS ! 2517: /* Initialize how much space enums occupy, by default. */ ! 2518: flag_short_enums = DEFAULT_SHORT_ENUMS; ! 2519: #endif ! 2520: ! 2521: /* Scan to see what optimization level has been specified. That will ! 2522: determine the default value of many flags. */ ! 2523: for (i = 1; i < argc; i++) ! 2524: { ! 2525: if (!strcmp (argv[i], "-O")) ! 2526: { ! 2527: optimize = 1; ! 2528: } ! 2529: else if (argv[i][0] == '-' && argv[i][1] == 'O') ! 2530: { ! 2531: /* Handle -O2, -O3, -O69, ... */ ! 2532: char *p = &argv[i][2]; ! 2533: int c; ! 2534: ! 2535: while (c = *p++) ! 2536: if (! (c >= '0' && c <= '9')) ! 2537: break; ! 2538: if (c == 0) ! 2539: optimize = atoi (&argv[i][2]); ! 2540: } ! 2541: } ! 2542: ! 2543: obey_regdecls = (optimize == 0); ! 2544: flag_no_inline = (optimize == 0); ! 2545: if (flag_no_inline) ! 2546: warn_inline = 0; ! 2547: ! 2548: if (optimize >= 1) ! 2549: { ! 2550: flag_thread_jumps = 1; ! 2551: #ifdef DELAY_SLOTS ! 2552: flag_delayed_branch = 1; ! 2553: #endif ! 2554: } ! 2555: ! 2556: if (optimize >= 2) ! 2557: { ! 2558: flag_cse_follow_jumps = 1; ! 2559: flag_expensive_optimizations = 1; ! 2560: flag_strength_reduce = 1; ! 2561: flag_rerun_cse_after_loop = 1; ! 2562: #ifdef INSN_SCHEDULING ! 2563: flag_schedule_insns = 1; ! 2564: flag_schedule_insns_after_reload = 1; ! 2565: #endif ! 2566: } ! 2567: ! 2568: #ifdef OPTIMIZATION_OPTIONS ! 2569: /* Allow default optimizations to be specified on a per-machine basis. */ ! 2570: OPTIMIZATION_OPTIONS (optimize); ! 2571: #endif ! 2572: ! 2573: /* Initialize register usage now so switches may override. */ ! 2574: init_reg_sets (); ! 2575: ! 2576: target_flags = 0; ! 2577: set_target_switch (""); ! 2578: ! 2579: for (i = 1; i < argc; i++) ! 2580: { ! 2581: if (argv[i][0] == '-' && argv[i][1] != 0) ! 2582: { ! 2583: register char *str = argv[i] + 1; ! 2584: if (str[0] == 'Y') ! 2585: str++; ! 2586: ! 2587: if (str[0] == 'm') ! 2588: set_target_switch (&str[1]); ! 2589: else if (!strcmp (str, "dumpbase")) ! 2590: { ! 2591: dump_base_name = argv[++i]; ! 2592: } ! 2593: else if (str[0] == 'd') ! 2594: { ! 2595: register char *p = &str[1]; ! 2596: while (*p) ! 2597: switch (*p++) ! 2598: { ! 2599: case 'a': ! 2600: combine_dump = 1; ! 2601: dbr_sched_dump = 1; ! 2602: flow_dump = 1; ! 2603: global_reg_dump = 1; ! 2604: jump_opt_dump = 1; ! 2605: jump2_opt_dump = 1; ! 2606: local_reg_dump = 1; ! 2607: loop_dump = 1; ! 2608: rtl_dump = 1; ! 2609: cse_dump = 1, cse2_dump = 1; ! 2610: sched_dump = 1; ! 2611: sched2_dump = 1; ! 2612: stack_reg_dump = 1; ! 2613: break; ! 2614: case 'k': ! 2615: stack_reg_dump = 1; ! 2616: break; ! 2617: case 'c': ! 2618: combine_dump = 1; ! 2619: break; ! 2620: case 'd': ! 2621: dbr_sched_dump = 1; ! 2622: break; ! 2623: case 'f': ! 2624: flow_dump = 1; ! 2625: break; ! 2626: case 'g': ! 2627: global_reg_dump = 1; ! 2628: break; ! 2629: case 'j': ! 2630: jump_opt_dump = 1; ! 2631: break; ! 2632: case 'J': ! 2633: jump2_opt_dump = 1; ! 2634: break; ! 2635: case 'l': ! 2636: local_reg_dump = 1; ! 2637: break; ! 2638: case 'L': ! 2639: loop_dump = 1; ! 2640: break; ! 2641: case 'm': ! 2642: flag_print_mem = 1; ! 2643: break; ! 2644: case 'p': ! 2645: flag_print_asm_name = 1; ! 2646: break; ! 2647: case 'r': ! 2648: rtl_dump = 1; ! 2649: break; ! 2650: case 's': ! 2651: cse_dump = 1; ! 2652: break; ! 2653: case 't': ! 2654: cse2_dump = 1; ! 2655: break; ! 2656: case 'S': ! 2657: sched_dump = 1; ! 2658: break; ! 2659: case 'R': ! 2660: sched2_dump = 1; ! 2661: break; ! 2662: case 'y': ! 2663: set_yydebug (1); ! 2664: break; ! 2665: ! 2666: case 'x': ! 2667: rtl_dump_and_exit = 1; ! 2668: break; ! 2669: } ! 2670: } ! 2671: else if (str[0] == 'f') ! 2672: { ! 2673: int j; ! 2674: register char *p = &str[1]; ! 2675: int found = 0; ! 2676: ! 2677: /* Some kind of -f option. ! 2678: P's value is the option sans `-f'. ! 2679: Search for it in the table of options. */ ! 2680: ! 2681: for (j = 0; ! 2682: !found && j < sizeof (f_options) / sizeof (f_options[0]); ! 2683: j++) ! 2684: { ! 2685: if (!strcmp (p, f_options[j].string)) ! 2686: { ! 2687: *f_options[j].variable = f_options[j].on_value; ! 2688: /* A goto here would be cleaner, ! 2689: but breaks the vax pcc. */ ! 2690: found = 1; ! 2691: } ! 2692: if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' ! 2693: && ! strcmp (p+3, f_options[j].string)) ! 2694: { ! 2695: *f_options[j].variable = ! f_options[j].on_value; ! 2696: found = 1; ! 2697: } ! 2698: } ! 2699: ! 2700: if (found) ! 2701: ; ! 2702: else if (!strncmp (p, "fixed-", 6)) ! 2703: fix_register (&p[6], 1, 1); ! 2704: else if (!strncmp (p, "call-used-", 10)) ! 2705: fix_register (&p[10], 0, 1); ! 2706: else if (!strncmp (p, "call-saved-", 11)) ! 2707: fix_register (&p[11], 0, 0); ! 2708: else if (! lang_decode_option (argv[i])) ! 2709: error ("Invalid option `%s'", argv[i]); ! 2710: } ! 2711: else if (str[0] == 'O') ! 2712: { ! 2713: register char *p = str+1; ! 2714: while (*p && *p >= '0' && *p <= '9') ! 2715: p++; ! 2716: if (*p == '\0') ! 2717: ; ! 2718: else ! 2719: error ("Invalid option `%s'", argv[i]); ! 2720: } ! 2721: else if (!strcmp (str, "pedantic")) ! 2722: pedantic = 1; ! 2723: else if (!strcmp (str, "pedantic-errors")) ! 2724: flag_pedantic_errors = pedantic = 1; ! 2725: else if (lang_decode_option (argv[i])) ! 2726: ; ! 2727: else if (!strcmp (str, "quiet")) ! 2728: quiet_flag = 1; ! 2729: else if (!strcmp (str, "version")) ! 2730: version_flag = 1; ! 2731: else if (!strcmp (str, "w")) ! 2732: inhibit_warnings = 1; ! 2733: else if (!strcmp (str, "W")) ! 2734: { ! 2735: extra_warnings = 1; ! 2736: warn_uninitialized = 1; ! 2737: } ! 2738: else if (str[0] == 'W') ! 2739: { ! 2740: int j; ! 2741: register char *p = &str[1]; ! 2742: int found = 0; ! 2743: ! 2744: /* Some kind of -W option. ! 2745: P's value is the option sans `-W'. ! 2746: Search for it in the table of options. */ ! 2747: ! 2748: for (j = 0; ! 2749: !found && j < sizeof (W_options) / sizeof (W_options[0]); ! 2750: j++) ! 2751: { ! 2752: if (!strcmp (p, W_options[j].string)) ! 2753: { ! 2754: *W_options[j].variable = W_options[j].on_value; ! 2755: /* A goto here would be cleaner, ! 2756: but breaks the vax pcc. */ ! 2757: found = 1; ! 2758: } ! 2759: if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' ! 2760: && ! strcmp (p+3, W_options[j].string)) ! 2761: { ! 2762: *W_options[j].variable = ! W_options[j].on_value; ! 2763: found = 1; ! 2764: } ! 2765: } ! 2766: ! 2767: if (found) ! 2768: ; ! 2769: else if (!strncmp (p, "id-clash-", 9)) ! 2770: { ! 2771: char *endp = p + 9; ! 2772: ! 2773: while (*endp) ! 2774: { ! 2775: if (*endp >= '0' && *endp <= '9') ! 2776: endp++; ! 2777: else ! 2778: error ("Invalid option `%s'", argv[i]); ! 2779: } ! 2780: warn_id_clash = 1; ! 2781: id_clash_len = atoi (str + 10); ! 2782: } ! 2783: else ! 2784: error ("Invalid option `%s'", argv[i]); ! 2785: } ! 2786: else if (!strcmp (str, "p")) ! 2787: profile_flag = 1; ! 2788: else if (!strcmp (str, "a")) ! 2789: { ! 2790: #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER) ! 2791: warning ("`-a' option (basic block profile) not supported"); ! 2792: #else ! 2793: profile_block_flag = 1; ! 2794: #endif ! 2795: } ! 2796: else if (str[0] == 'g') ! 2797: { ! 2798: char *p = str + 1; ! 2799: char *q; ! 2800: unsigned len; ! 2801: unsigned level; ! 2802: ! 2803: while (*p && (*p < '0' || *p > '9')) ! 2804: p++; ! 2805: len = p - str; ! 2806: q = p; ! 2807: while (*q && (*q >= '0' && *q <= '9')) ! 2808: q++; ! 2809: if (*p) ! 2810: level = atoi (p); ! 2811: else ! 2812: level = 2; /* default debugging info level */ ! 2813: if (*q || level > 3) ! 2814: { ! 2815: warning ("invalid debug level specification in option: `-%s'", ! 2816: str); ! 2817: warning ("no debugging information will be generated"); ! 2818: level = 0; ! 2819: } ! 2820: ! 2821: /* If more than one debugging type is supported, ! 2822: you must define PREFERRED_DEBUGGING_TYPE ! 2823: to choose a format in a system-dependent way. */ ! 2824: #if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) \ ! 2825: + defined (DWARF_DEBUGGING_INFO)) ! 2826: #ifdef PREFERRED_DEBUGGING_TYPE ! 2827: if (!strncmp (str, "ggdb", len)) ! 2828: write_symbols = PREFERRED_DEBUGGING_TYPE; ! 2829: #else /* no PREFERRED_DEBUGGING_TYPE */ ! 2830: You Lose! You must define PREFERRED_DEBUGGING_TYPE! ! 2831: #endif /* no PREFERRED_DEBUGGING_TYPE */ ! 2832: #endif /* More than one debugger format enabled. */ ! 2833: #ifdef DBX_DEBUGGING_INFO ! 2834: if (write_symbols != NO_DEBUG) ! 2835: ; ! 2836: else if (!strncmp (str, "ggdb", len)) ! 2837: write_symbols = DBX_DEBUG; ! 2838: else if (!strncmp (str, "gstabs", len)) ! 2839: write_symbols = DBX_DEBUG; ! 2840: ! 2841: /* Always enable extensions for -ggdb or -gstabs+, ! 2842: always disable for -gstabs. ! 2843: For plain -g, use system-specific default. */ ! 2844: if (write_symbols == DBX_DEBUG && !strncmp (str, "ggdb", len) ! 2845: && len >= 2) ! 2846: use_gdb_dbx_extensions = 1; ! 2847: else if (write_symbols == DBX_DEBUG && !strcmp (str, "gstabs+")) ! 2848: use_gdb_dbx_extensions = 1; ! 2849: else if (write_symbols == DBX_DEBUG ! 2850: && !strncmp (str, "gstabs", len) && len >= 2) ! 2851: use_gdb_dbx_extensions = 0; ! 2852: else ! 2853: use_gdb_dbx_extensions = DEFAULT_GDB_EXTENSIONS; ! 2854: #endif /* DBX_DEBUGGING_INFO */ ! 2855: #ifdef DWARF_DEBUGGING_INFO ! 2856: if (write_symbols != NO_DEBUG) ! 2857: ; ! 2858: else if (!strncmp (str, "ggdb", len)) ! 2859: write_symbols = DWARF_DEBUG; ! 2860: /* For orthogonality. */ ! 2861: else if (!strncmp (str, "gdwarf", len)) ! 2862: write_symbols = DWARF_DEBUG; ! 2863: #endif ! 2864: #ifdef SDB_DEBUGGING_INFO ! 2865: if (write_symbols != NO_DEBUG) ! 2866: ; ! 2867: else if (!strncmp (str, "ggdb", len)) ! 2868: write_symbols = SDB_DEBUG; ! 2869: else if (!strncmp (str, "gcoff", len)) ! 2870: write_symbols = SDB_DEBUG; ! 2871: #endif /* SDB_DEBUGGING_INFO */ ! 2872: if (write_symbols == NO_DEBUG) ! 2873: warning ("`-%s' option not supported on this version of GCC", str); ! 2874: else if (level == 0) ! 2875: write_symbols = NO_DEBUG; ! 2876: else ! 2877: debug_info_level = level; ! 2878: } ! 2879: else if (!strcmp (str, "o")) ! 2880: { ! 2881: asm_file_name = argv[++i]; ! 2882: } ! 2883: else if (str[0] == 'G') ! 2884: { ! 2885: g_switch_set = TRUE; ! 2886: g_switch_value = atoi ((str[1] != '\0') ? str+1 : argv[++i]); ! 2887: } ! 2888: else ! 2889: error ("Invalid option `%s'", argv[i]); ! 2890: } ! 2891: else if (argv[i][0] == '+') ! 2892: { ! 2893: if (lang_decode_option (argv[i])) ! 2894: ; ! 2895: else ! 2896: error ("Invalid option `%s'", argv[i]); ! 2897: } ! 2898: else ! 2899: filename = argv[i]; ! 2900: } ! 2901: ! 2902: #ifdef OVERRIDE_OPTIONS ! 2903: /* Some machines may reject certain combinations of options. */ ! 2904: OVERRIDE_OPTIONS; ! 2905: #endif ! 2906: ! 2907: /* Unrolling all loops implies that standard loop unrolling must also ! 2908: be done. */ ! 2909: if (flag_unroll_all_loops) ! 2910: flag_unroll_loops = 1; ! 2911: /* Loop unrolling requires that strength_reduction be on also. Silently ! 2912: turn on strength reduction here if it isn't already on. Also, the loop ! 2913: unrolling code assumes that cse will be run after loop, so that must ! 2914: be turned on also. */ ! 2915: if (flag_unroll_loops) ! 2916: { ! 2917: flag_strength_reduce = 1; ! 2918: flag_rerun_cse_after_loop = 1; ! 2919: } ! 2920: ! 2921: /* Warn about options that are not supported on this machine. */ ! 2922: #ifndef INSN_SCHEDULING ! 2923: if (flag_schedule_insns || flag_schedule_insns_after_reload) ! 2924: warning ("instruction scheduling not supported on this target machine"); ! 2925: #endif ! 2926: #ifndef DELAY_SLOTS ! 2927: if (flag_delayed_branch) ! 2928: warning ("this target machine does not have delayed branches"); ! 2929: #endif ! 2930: ! 2931: /* If we are in verbose mode, write out the version and maybe all the ! 2932: option flags in use. */ ! 2933: if (version_flag) ! 2934: { ! 2935: fprintf (stderr, "%s version %s", language_string, version_string); ! 2936: #ifdef TARGET_VERSION ! 2937: TARGET_VERSION; ! 2938: #endif ! 2939: #ifdef __GNUC__ ! 2940: #ifndef __VERSION__ ! 2941: #define __VERSION__ "[unknown]" ! 2942: #endif ! 2943: fprintf (stderr, " compiled by GNU C version %s.\n", __VERSION__); ! 2944: #else ! 2945: fprintf (stderr, " compiled by CC.\n"); ! 2946: #endif ! 2947: if (! quiet_flag) ! 2948: print_switch_values (); ! 2949: } ! 2950: ! 2951: /* Now that register usage is specified, convert it to HARD_REG_SETs. */ ! 2952: init_reg_sets_1 (); ! 2953: ! 2954: compile_file (filename); ! 2955: ! 2956: #ifndef VMS ! 2957: if (flag_print_mem) ! 2958: { ! 2959: char *lim = (char *) sbrk (0); ! 2960: ! 2961: fprintf (stderr, "Data size %d.\n", ! 2962: (int) lim - (int) &environ); ! 2963: fflush (stderr); ! 2964: ! 2965: #ifdef USG ! 2966: system ("ps -l 1>&2"); ! 2967: #else /* not USG */ ! 2968: system ("ps v"); ! 2969: #endif /* not USG */ ! 2970: } ! 2971: #endif /* not VMS */ ! 2972: ! 2973: if (errorcount) ! 2974: exit (FATAL_EXIT_CODE); ! 2975: if (sorrycount) ! 2976: exit (FATAL_EXIT_CODE); ! 2977: exit (SUCCESS_EXIT_CODE); ! 2978: return 34; ! 2979: } ! 2980: ! 2981: /* Decode -m switches. */ ! 2982: ! 2983: /* Here is a table, controlled by the tm.h file, listing each -m switch ! 2984: and which bits in `target_switches' it should set or clear. ! 2985: If VALUE is positive, it is bits to set. ! 2986: If VALUE is negative, -VALUE is bits to clear. ! 2987: (The sign bit is not used so there is no confusion.) */ ! 2988: ! 2989: struct {char *name; int value;} target_switches [] ! 2990: = TARGET_SWITCHES; ! 2991: ! 2992: /* This table is similar, but allows the switch to have a value. */ ! 2993: ! 2994: #ifdef TARGET_OPTIONS ! 2995: struct {char *prefix; char ** variable;} target_options [] ! 2996: = TARGET_OPTIONS; ! 2997: #endif ! 2998: ! 2999: /* Decode the switch -mNAME. */ ! 3000: ! 3001: void ! 3002: set_target_switch (name) ! 3003: char *name; ! 3004: { ! 3005: register int j; ! 3006: int valid = 0; ! 3007: ! 3008: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) ! 3009: if (!strcmp (target_switches[j].name, name)) ! 3010: { ! 3011: if (target_switches[j].value < 0) ! 3012: target_flags &= ~-target_switches[j].value; ! 3013: else ! 3014: target_flags |= target_switches[j].value; ! 3015: valid = 1; ! 3016: } ! 3017: ! 3018: #ifdef TARGET_OPTIONS ! 3019: if (!valid) ! 3020: for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++) ! 3021: { ! 3022: int len = strlen (target_options[j].prefix); ! 3023: if (!strncmp (target_options[j].prefix, name, len)) ! 3024: { ! 3025: *target_options[j].variable = name + len; ! 3026: valid = 1; ! 3027: } ! 3028: } ! 3029: #endif ! 3030: ! 3031: if (!valid) ! 3032: error ("Invalid option `%s'", name); ! 3033: } ! 3034: ! 3035: /* Variable used for communication between the following two routines. */ ! 3036: ! 3037: static int line_position; ! 3038: ! 3039: /* Print an option value and adjust the position in the line. */ ! 3040: ! 3041: static void ! 3042: print_single_switch (type, name) ! 3043: char *type, *name; ! 3044: { ! 3045: fprintf (stderr, " %s%s", type, name); ! 3046: ! 3047: line_position += strlen (type) + strlen (name) + 1; ! 3048: ! 3049: if (line_position > 65) ! 3050: { ! 3051: fprintf (stderr, "\n\t"); ! 3052: line_position = 8; ! 3053: } ! 3054: } ! 3055: ! 3056: /* Print default target switches for -version. */ ! 3057: ! 3058: static void ! 3059: print_switch_values () ! 3060: { ! 3061: register int j; ! 3062: ! 3063: fprintf (stderr, "enabled:"); ! 3064: line_position = 8; ! 3065: ! 3066: for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++) ! 3067: if (*f_options[j].variable == f_options[j].on_value) ! 3068: print_single_switch ("-f", f_options[j].string); ! 3069: ! 3070: for (j = 0; j < sizeof W_options / sizeof W_options[0]; j++) ! 3071: if (*W_options[j].variable == W_options[j].on_value) ! 3072: print_single_switch ("-W", W_options[j].string); ! 3073: ! 3074: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) ! 3075: if (target_switches[j].name[0] != '\0' ! 3076: && target_switches[j].value > 0 ! 3077: && ((target_switches[j].value & target_flags) ! 3078: == target_switches[j].value)) ! 3079: print_single_switch ("-m", target_switches[j].name); ! 3080: ! 3081: fprintf (stderr, "\n"); ! 3082: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.