|
|
1.1 ! root 1: /* Top level of GNU C compiler ! 2: Copyright (C) 1987, 1988, 1989, 1992, 1993 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: #ifdef REPORT_EVENT ! 32: #include <errno.h> ! 33: #endif /* REPORT_EVENT */ ! 34: ! 35: #include <sys/stat.h> ! 36: ! 37: #ifdef USG ! 38: #undef FLOAT ! 39: #include <sys/param.h> ! 40: /* This is for hpux. It is a real screw. They should change hpux. */ ! 41: #undef FLOAT ! 42: #include <sys/times.h> ! 43: #include <time.h> /* Correct for hpux at least. Is it good on other USG? */ ! 44: #undef FFS /* Some systems define this in param.h. */ ! 45: #else ! 46: #ifndef VMS ! 47: #include <sys/time.h> ! 48: #include <sys/resource.h> ! 49: #endif ! 50: #endif ! 51: ! 52: #include "input.h" ! 53: #include "tree.h" ! 54: #include "c-tree.h" /* needed for maybe_objc_method_name */ ! 55: #include "rtl.h" ! 56: #include "flags.h" ! 57: #include "insn-attr.h" ! 58: #include "insn-flags.h" ! 59: #include "defaults.h" ! 60: ! 61: #ifdef XCOFF_DEBUGGING_INFO ! 62: #include "xcoffout.h" ! 63: #endif ! 64: ! 65: #include "bytecode.h" ! 66: #include "bc-emit.h" ! 67: ! 68: #ifdef VMS ! 69: /* The extra parameters substantially improve the I/O performance. */ ! 70: static FILE * ! 71: VMS_fopen (fname, type) ! 72: char * fname; ! 73: char * type; ! 74: { ! 75: if (strcmp (type, "w") == 0) ! 76: return fopen (fname, type, "mbc=16", "deq=64", "fop=tef", "shr=nil"); ! 77: return fopen (fname, type, "mbc=16"); ! 78: } ! 79: #define fopen VMS_fopen ! 80: #endif ! 81: ! 82: #ifndef DEFAULT_GDB_EXTENSIONS ! 83: #define DEFAULT_GDB_EXTENSIONS 1 ! 84: #endif ! 85: ! 86: extern int rtx_equal_function_value_matters; ! 87: ! 88: #if ! (defined (VMS) || defined (OS2)) ! 89: extern char **environ; ! 90: #endif ! 91: extern char *version_string, *language_string; ! 92: ! 93: /* Carry information from ASM_DECLARE_OBJECT_NAME ! 94: to ASM_FINISH_DECLARE_OBJECT. */ ! 95: ! 96: extern int size_directive_output; ! 97: extern tree last_assemble_variable_decl; ! 98: ! 99: extern void init_lex (); ! 100: extern void init_decl_processing (); ! 101: extern void init_obstacks (); ! 102: extern void init_tree_codes (); ! 103: extern void init_rtl (); ! 104: extern void init_optabs (); ! 105: extern void init_stmt (); ! 106: extern void init_reg_sets (); ! 107: extern void dump_flow_info (); ! 108: extern void dump_sched_info (); ! 109: extern void dump_local_alloc (); ! 110: ! 111: void rest_of_decl_compilation (); ! 112: void error (); ! 113: void error_with_file_and_line (); ! 114: void fancy_abort (); ! 115: #ifndef abort ! 116: void abort (); ! 117: #endif ! 118: void set_target_switch (); ! 119: #ifdef NEXT_FAT_OUTPUT ! 120: void set_target_architecture (); ! 121: #endif ! 122: static void print_switch_values (); ! 123: static char *decl_name (); ! 124: ! 125: extern char *getenv (); ! 126: ! 127: /* Name of program invoked, sans directories. */ ! 128: ! 129: char *progname; ! 130: ! 131: /* Copy of arguments to main. */ ! 132: int save_argc; ! 133: char **save_argv; ! 134: ! 135: /* Name of current original source file (what was input to cpp). ! 136: This comes from each #-command in the actual input. */ ! 137: ! 138: char *input_filename; ! 139: ! 140: /* Name of top-level original source file (what was input to cpp). ! 141: This comes from the #-command at the beginning of the actual input. ! 142: If there isn't any there, then this is the cc1 input file name. */ ! 143: ! 144: char *main_input_filename; ! 145: ! 146: /* Stream for reading from the input file. */ ! 147: ! 148: FILE *finput; ! 149: ! 150: /* Current line number in real source file. */ ! 151: ! 152: int lineno; ! 153: ! 154: /* Stack of currently pending input files. */ ! 155: ! 156: struct file_stack *input_file_stack; ! 157: ! 158: /* Incremented on each change to input_file_stack. */ ! 159: int input_file_stack_tick; ! 160: ! 161: /* FUNCTION_DECL for function now being parsed or compiled. */ ! 162: ! 163: extern tree current_function_decl; ! 164: ! 165: /* Name to use as base of names for dump output files. */ ! 166: ! 167: char *dump_base_name; ! 168: ! 169: /* Bit flags that specify the machine subtype we are compiling for. ! 170: Bits are tested using macros TARGET_... defined in the tm.h file ! 171: and set by `-m...' switches. Must be defined in rtlanal.c. */ ! 172: ! 173: extern int target_flags; ! 174: ! 175: /* Flags saying which kinds of debugging dump have been requested. */ ! 176: ! 177: int rtl_dump = 0; ! 178: int rtl_dump_and_exit = 0; ! 179: int jump_opt_dump = 0; ! 180: int cse_dump = 0; ! 181: int loop_dump = 0; ! 182: int cse2_dump = 0; ! 183: int flow_dump = 0; ! 184: int combine_dump = 0; ! 185: int sched_dump = 0; ! 186: int fppc_dump = 0; ! 187: int local_reg_dump = 0; ! 188: int global_reg_dump = 0; ! 189: int sched2_dump = 0; ! 190: int jump2_opt_dump = 0; ! 191: int dbr_sched_dump = 0; ! 192: int flag_print_asm_name = 0; ! 193: int stack_reg_dump = 0; ! 194: ! 195: /* Name for output file of assembly code, specified with -o. */ ! 196: ! 197: char *asm_file_name; ! 198: ! 199: /* Value of the -G xx switch, and whether it was passed or not. */ ! 200: int g_switch_value; ! 201: int g_switch_set; ! 202: ! 203: /* Type(s) of debugging information we are producing (if any). ! 204: See flags.h for the definitions of the different possible ! 205: types of debugging information. */ ! 206: enum debug_info_type write_symbols = NO_DEBUG; ! 207: ! 208: /* Level of debugging information we are producing. See flags.h ! 209: for the definitions of the different possible levels. */ ! 210: enum debug_info_level debug_info_level = DINFO_LEVEL_NONE; ! 211: ! 212: /* Nonzero means use GNU-only extensions in the generated symbolic ! 213: debugging information. */ ! 214: /* Currently, this only has an effect when write_symbols is set to ! 215: DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ ! 216: int use_gnu_debug_info_extensions = 0; ! 217: ! 218: /* Nonzero means do optimizations. -O. ! 219: Particular numeric values stand for particular amounts of optimization; ! 220: thus, -O2 stores 2 here. However, the optimizations beyond the basic ! 221: ones are not controlled directly by this variable. Instead, they are ! 222: controlled by individual `flag_...' variables that are defaulted ! 223: based on this variable. */ ! 224: ! 225: int optimize = 0; ! 226: ! 227: /* Number of error messages and warning messages so far. */ ! 228: ! 229: int errorcount = 0; ! 230: int warningcount = 0; ! 231: int sorrycount = 0; ! 232: ! 233: /* Flag to output bytecode instead of native assembler */ ! 234: int output_bytecode = 0; ! 235: ! 236: /* Pointer to function to compute the name to use to print a declaration. */ ! 237: ! 238: char *(*decl_printable_name) (); ! 239: ! 240: /* Pointer to function to compute rtl for a language-specific tree code. */ ! 241: ! 242: struct rtx_def *(*lang_expand_expr) (); ! 243: ! 244: /* Pointer to function to finish handling an incomplete decl at the ! 245: end of compilation. */ ! 246: ! 247: void (*incomplete_decl_finalize_hook) () = 0; ! 248: ! 249: /* Nonzero if generating code to do profiling. */ ! 250: ! 251: int profile_flag = 0; ! 252: ! 253: /* Nonzero if generating code to do profiling on a line-by-line basis. */ ! 254: ! 255: int profile_block_flag; ! 256: ! 257: /* Nonzero for -pedantic switch: warn about anything ! 258: that standard spec forbids. */ ! 259: ! 260: int pedantic = 0; ! 261: ! 262: /* Temporarily suppress certain warnings. ! 263: This is set while reading code from a system header file. */ ! 264: ! 265: int in_system_header = 0; ! 266: ! 267: /* Nonzero means do stupid register allocation. ! 268: Currently, this is 1 if `optimize' is 0. */ ! 269: ! 270: int obey_regdecls = 0; ! 271: ! 272: #ifdef NEXT_FAT_OUTPUT ! 273: /* The name of the architecture we are compiling. -arch */ ! 274: ! 275: static char *architecture = 0; ! 276: ! 277: /* Print the name of this architecture before the first warning or ! 278: error message. -arch_multiple. */ ! 279: ! 280: static int multi_arch_flag = 0; ! 281: #endif /* NEXT_FAT_OUTPUT */ ! 282: ! 283: /* Don't print functions as they are compiled and don't print ! 284: times taken by the various passes. -quiet. */ ! 285: ! 286: int quiet_flag = 0; ! 287: ! 288: /* -f flags. */ ! 289: ! 290: /* Nonzero means `char' should be signed. */ ! 291: ! 292: int flag_signed_char; ! 293: ! 294: /* Nonzero means give an enum type only as many bytes as it needs. */ ! 295: ! 296: int flag_short_enums; ! 297: ! 298: /* Nonzero for -fcaller-saves: allocate values in regs that need to ! 299: be saved across function calls, if that produces overall better code. ! 300: Optional now, so people can test it. */ ! 301: ! 302: #ifdef DEFAULT_CALLER_SAVES ! 303: int flag_caller_saves = 1; ! 304: #else ! 305: int flag_caller_saves = 0; ! 306: #endif ! 307: ! 308: /* Nonzero if the floating point precision controll pass should ! 309: be performed. */ ! 310: ! 311: #if defined (DEFAULT_FPPC) ! 312: int flag_fppc = 1; ! 313: #else ! 314: int flag_fppc = 0; ! 315: #endif ! 316: ! 317: /* Nonzero if we should generate dave-style indirections. */ ! 318: int flag_dave_indirect = 0; ! 319: ! 320: /* Nonzero if structures and unions should be returned in memory. ! 321: ! 322: This should only be defined if compatibility with another compiler or ! 323: with an ABI is needed, because it results in slower code. */ ! 324: ! 325: #ifndef DEFAULT_PCC_STRUCT_RETURN ! 326: #define DEFAULT_PCC_STRUCT_RETURN 1 ! 327: #endif ! 328: ! 329: /* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ ! 330: ! 331: int flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; ! 332: ! 333: /* Nonzero for -fforce-mem: load memory value into a register ! 334: before arithmetic on it. This makes better cse but slower compilation. */ ! 335: ! 336: int flag_force_mem = 0; ! 337: ! 338: /* Nonzero for -fforce-addr: load memory address into a register before ! 339: reference to memory. This makes better cse but slower compilation. */ ! 340: ! 341: int flag_force_addr = 0; ! 342: ! 343: /* Nonzero for -fdefer-pop: don't pop args after each function call; ! 344: instead save them up to pop many calls' args with one insns. */ ! 345: ! 346: int flag_defer_pop = 0; ! 347: ! 348: /* Nonzero for -ffloat-store: don't allocate floats and doubles ! 349: in extended-precision registers. */ ! 350: ! 351: int flag_float_store = 0; ! 352: ! 353: /* Nonzero for -fcse-follow-jumps: ! 354: have cse follow jumps to do a more extensive job. */ ! 355: ! 356: int flag_cse_follow_jumps; ! 357: ! 358: /* Nonzero for -fcse-skip-blocks: ! 359: have cse follow a branch around a block. */ ! 360: int flag_cse_skip_blocks; ! 361: ! 362: /* Nonzero for -fexpensive-optimizations: ! 363: perform miscellaneous relatively-expensive optimizations. */ ! 364: int flag_expensive_optimizations; ! 365: ! 366: /* Nonzero for -fthread-jumps: ! 367: have jump optimize output of loop. */ ! 368: ! 369: int flag_thread_jumps; ! 370: ! 371: /* Nonzero enables strength-reduction in loop.c. */ ! 372: ! 373: int flag_strength_reduce = 0; ! 374: ! 375: /* Nonzero enables loop unrolling in unroll.c. Only loops for which the ! 376: number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, ! 377: UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are ! 378: unrolled. */ ! 379: ! 380: int flag_unroll_loops; ! 381: ! 382: /* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. ! 383: This is generally not a win. */ ! 384: ! 385: int flag_unroll_all_loops; ! 386: ! 387: /* Nonzero for -fwritable-strings: ! 388: store string constants in data segment and don't uniquize them. */ ! 389: ! 390: int flag_writable_strings = 0; ! 391: ! 392: /* Nonzero means don't put addresses of constant functions in registers. ! 393: Used for compiling the Unix kernel, where strange substitutions are ! 394: done on the assembly output. */ ! 395: ! 396: int flag_no_function_cse = 0; ! 397: ! 398: /* Nonzero for -fomit-frame-pointer: ! 399: don't make a frame pointer in simple functions that don't require one. */ ! 400: ! 401: int flag_omit_frame_pointer = 0; ! 402: ! 403: /* Nonzero to inhibit use of define_optimization peephole opts. */ ! 404: ! 405: int flag_no_peephole = 0; ! 406: ! 407: /* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math ! 408: operations in the interest of optimization. For example it allows ! 409: GCC to assume arguments to sqrt are nonnegative numbers, allowing ! 410: faster code for sqrt to be generated. */ ! 411: ! 412: int flag_fast_math = 0; ! 413: ! 414: /* Nonzero means all references through pointers are volatile. */ ! 415: ! 416: int flag_volatile; ! 417: ! 418: /* Nonzero means treat all global and extern variables as global. */ ! 419: ! 420: int flag_volatile_global; ! 421: ! 422: /* Nonzero means just do syntax checking; don't output anything. */ ! 423: ! 424: int flag_syntax_only = 0; ! 425: ! 426: /* Nonzero means to rerun cse after loop optimization. This increases ! 427: compilation time about 20% and picks up a few more common expressions. */ ! 428: ! 429: static int flag_rerun_cse_after_loop; ! 430: ! 431: /* Nonzero for -finline-functions: ok to inline functions that look like ! 432: good inline candidates. */ ! 433: ! 434: int flag_inline_functions; ! 435: ! 436: /* Nonzero for -fkeep-inline-functions: even if we make a function ! 437: go inline everywhere, keep its definition around for debugging ! 438: purposes. */ ! 439: ! 440: int flag_keep_inline_functions; ! 441: ! 442: /* Nonzero means that functions declared `inline' will be treated ! 443: as `static'. Prevents generation of zillions of copies of unused ! 444: static inline functions; instead, `inlines' are written out ! 445: only when actually used. Used in conjunction with -g. Also ! 446: does the right thing with #pragma interface. */ ! 447: ! 448: int flag_no_inline; ! 449: ! 450: /* Nonzero means we should be saving declaration info into a .X file. */ ! 451: ! 452: int flag_gen_aux_info = 0; ! 453: ! 454: /* Specified name of aux-info file. */ ! 455: ! 456: static char *aux_info_file_name; ! 457: ! 458: /* Nonzero means make the text shared if supported. */ ! 459: ! 460: int flag_shared_data; ! 461: ! 462: /* Nonzero means schedule into delayed branch slots if supported. */ ! 463: ! 464: int flag_delayed_branch; ! 465: ! 466: /* Nonzero if we are compiling pure (sharable) code. ! 467: Value is 1 if we are doing reasonable (i.e. simple ! 468: offset into offset table) pic. Value is 2 if we can ! 469: only perform register offsets. */ ! 470: ! 471: int flag_pic; ! 472: ! 473: /* Nonzero means place uninitialized global data in the bss section. */ ! 474: ! 475: int flag_no_common; ! 476: ! 477: /* Nonzero means pretend it is OK to examine bits of target floats, ! 478: even if that isn't true. The resulting code will have incorrect constants, ! 479: but the same series of instructions that the native compiler would make. */ ! 480: ! 481: int flag_pretend_float; ! 482: ! 483: /* Nonzero means change certain warnings into errors. ! 484: Usually these are warnings about failure to conform to some standard. */ ! 485: ! 486: int flag_pedantic_errors = 0; ! 487: ! 488: /* flag_schedule_insns means schedule insns within basic blocks (before ! 489: local_alloc). ! 490: flag_schedule_insns_after_reload means schedule insns after ! 491: global_alloc. */ ! 492: ! 493: int flag_schedule_insns = 0; ! 494: int flag_schedule_insns_after_reload = 0; ! 495: ! 496: /* -finhibit-size-directive inhibits output of .size for ELF. ! 497: This is used only for compiling crtstuff.c, ! 498: and it may be extended to other effects ! 499: needed for crtstuff.c on other systems. */ ! 500: int flag_inhibit_size_directive = 0; ! 501: ! 502: /* -fverbose-asm causes extra commentary information to be produced in ! 503: the generated assembly code (to make it more readable). This option ! 504: is generally only of use to those who actually need to read the ! 505: generated assembly code (perhaps while debugging the compiler itself). */ ! 506: ! 507: int flag_verbose_asm = 0; ! 508: ! 509: /* -fgnu-linker specifies use of the GNU linker for initializations. ! 510: (Or, more generally, a linker that handles initializations.) ! 511: -fno-gnu-linker says that collect2 will be used. */ ! 512: #ifdef USE_COLLECT2 ! 513: int flag_gnu_linker = 0; ! 514: #else ! 515: int flag_gnu_linker = 1; ! 516: #endif ! 517: ! 518: /* Table of language-independent -f options. ! 519: STRING is the option name. VARIABLE is the address of the variable. ! 520: ON_VALUE is the value to store in VARIABLE ! 521: if `-fSTRING' is seen as an option. ! 522: (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ ! 523: ! 524: struct { char *string; int *variable; int on_value;} f_options[] = ! 525: { ! 526: {"float-store", &flag_float_store, 1}, ! 527: {"volatile", &flag_volatile, 1}, ! 528: {"volatile-global", &flag_volatile_global, 1}, ! 529: {"defer-pop", &flag_defer_pop, 1}, ! 530: {"omit-frame-pointer", &flag_omit_frame_pointer, 1}, ! 531: {"cse-follow-jumps", &flag_cse_follow_jumps, 1}, ! 532: {"cse-skip-blocks", &flag_cse_skip_blocks, 1}, ! 533: {"expensive-optimizations", &flag_expensive_optimizations, 1}, ! 534: {"thread-jumps", &flag_thread_jumps, 1}, ! 535: {"strength-reduce", &flag_strength_reduce, 1}, ! 536: {"unroll-loops", &flag_unroll_loops, 1}, ! 537: {"unroll-all-loops", &flag_unroll_all_loops, 1}, ! 538: {"writable-strings", &flag_writable_strings, 1}, ! 539: {"peephole", &flag_no_peephole, 0}, ! 540: {"force-mem", &flag_force_mem, 1}, ! 541: {"force-addr", &flag_force_addr, 1}, ! 542: {"function-cse", &flag_no_function_cse, 0}, ! 543: {"inline-functions", &flag_inline_functions, 1}, ! 544: {"keep-inline-functions", &flag_keep_inline_functions, 1}, ! 545: {"inline", &flag_no_inline, 0}, ! 546: {"syntax-only", &flag_syntax_only, 1}, ! 547: {"shared-data", &flag_shared_data, 1}, ! 548: {"caller-saves", &flag_caller_saves, 1}, ! 549: {"pcc-struct-return", &flag_pcc_struct_return, 1}, ! 550: {"reg-struct-return", &flag_pcc_struct_return, 0}, ! 551: {"delayed-branch", &flag_delayed_branch, 1}, ! 552: {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1}, ! 553: {"pretend-float", &flag_pretend_float, 1}, ! 554: {"schedule-insns", &flag_schedule_insns, 1}, ! 555: {"schedule-insns2", &flag_schedule_insns_after_reload, 1}, ! 556: {"pic", &flag_pic, 1}, ! 557: {"PIC", &flag_pic, 2}, ! 558: {"fast-math", &flag_fast_math, 1}, ! 559: {"common", &flag_no_common, 0}, ! 560: {"inhibit-size-directive", &flag_inhibit_size_directive, 1}, ! 561: {"verbose-asm", &flag_verbose_asm, 1}, ! 562: {"gnu-linker", &flag_gnu_linker, 1}, ! 563: {"bytecode", &output_bytecode, 1}, ! 564: {"fppc", &flag_fppc, 1}, ! 565: {"dave-indirect", &flag_dave_indirect, 1} ! 566: }; ! 567: ! 568: /* Table of language-specific options. */ ! 569: ! 570: char *lang_options[] = ! 571: { ! 572: "-ftraditional", ! 573: "-traditional", ! 574: "-fnotraditional", ! 575: "-fno-traditional", ! 576: "-fallow-single-precision", ! 577: "-fsigned-char", ! 578: "-funsigned-char", ! 579: "-fno-signed-char", ! 580: "-fno-unsigned-char", ! 581: "-fsigned-bitfields", ! 582: "-funsigned-bitfields", ! 583: "-fno-signed-bitfields", ! 584: "-fno-unsigned-bitfields", ! 585: "-fshort-enums", ! 586: "-fno-short-enums", ! 587: "-fcond-mismatch", ! 588: "-fno-cond-mismatch", ! 589: "-fshort-double", ! 590: "-fno-short-double", ! 591: "-fasm", ! 592: "-fno-asm", ! 593: "-fbuiltin", ! 594: "-fno-builtin", ! 595: "-fno-ident", ! 596: "-fident", ! 597: "-fdollars-in-identifiers", ! 598: "-fno-dollars-in-identifiers", ! 599: "-ansi", ! 600: "-Wimplicit", ! 601: "-Wno-implicit", ! 602: "-Wwrite-strings", ! 603: "-Wno-write-strings", ! 604: "-Wcast-qual", ! 605: "-Wno-cast-qual", ! 606: "-Wpointer-arith", ! 607: "-Wno-pointer-arith", ! 608: "-Wstrict-prototypes", ! 609: "-Wno-strict-prototypes", ! 610: "-Wmissing-prototypes", ! 611: "-Wno-missing-prototypes", ! 612: "-Wredundant-decls", ! 613: "-Wno-redundant-decls", ! 614: "-Wnested-externs", ! 615: "-Wno-nested-externs", ! 616: "-Wtraditional", ! 617: "-Wno-traditional", ! 618: "-Wformat", ! 619: "-Wno-format", ! 620: #ifdef NEXT_SEMANTICS ! 621: "-Wnoformat", ! 622: #endif ! 623: "-Wchar-subscripts", ! 624: "-Wno-char-subscripts", ! 625: "-Wconversion", ! 626: "-Wno-conversion", ! 627: "-Wparentheses", ! 628: "-Wno-parentheses", ! 629: "-Wcomment", ! 630: "-Wno-comment", ! 631: "-Wcomments", ! 632: "-Wno-comments", ! 633: "-Wtrigraphs", ! 634: "-Wno-trigraphs", ! 635: "-Wimport", ! 636: "-Wno-import", ! 637: "-Wmissing-braces", ! 638: "-Wno-missing-braces", ! 639: "-Wall", ! 640: ! 641: /* These are for C++. */ ! 642: "-+e0", /* gcc.c tacks the `-' on the front. */ ! 643: "-+e1", ! 644: "-+e2", ! 645: "-fsave-memoized", ! 646: "-fno-save-memoized", ! 647: "-fcadillac", ! 648: "-fno-cadillac", ! 649: "-fgc", ! 650: "-fno-gc", ! 651: "-flabels-ok", ! 652: "-fno-labels-ok", ! 653: "-fstats", ! 654: "-fno-stats", ! 655: "-fthis-is-variable", ! 656: "-fno-this-is-variable", ! 657: "-fstrict-prototype", ! 658: "-fno-strict-prototype", ! 659: "-fall-virtual", ! 660: "-fno-all-virtual", ! 661: "-fmemoize-lookups", ! 662: "-fno-memoize-lookups", ! 663: "-felide-constructors", ! 664: "-fno-elide-constructors", ! 665: "-fhandle-exceptions", ! 666: "-fno-handle-exceptions", ! 667: "-fansi-exceptions", ! 668: "-fno-ansi-exceptions", ! 669: "-fspring-exceptions", ! 670: "-fno-spring-exceptions", ! 671: "-fdefault-inline", ! 672: "-fno-default-inline", ! 673: "-fenum-int-equiv", ! 674: "-fno-enum-int-equiv", ! 675: "-fdossier", ! 676: "-fno-dossier", ! 677: "-fxref", ! 678: "-fno-xref", ! 679: "-fnonnull-objects", ! 680: "-fno-nonnull-objects", ! 681: "-fimplement-inlines", ! 682: "-fno-implement-inlines", ! 683: "-fexternal-templates", ! 684: "-fno-external-templates", ! 685: "-fansi-overloading", ! 686: "-fno-ansi-overloading", ! 687: ! 688: "-Wreturn-type", ! 689: "-Wno-return-type", ! 690: "-Woverloaded-virtual", ! 691: "-Wno-overloaded-virtual", ! 692: "-Wenum-clash", ! 693: "-Wno-enum-clash", ! 694: "-Wtemplate-debugging", ! 695: "-Wno-template-debugging", ! 696: "-Wctor-dtor-privacy", ! 697: "-Wno-ctor-dtor-privacy", ! 698: ! 699: /* these are for obj c */ ! 700: "-fobjc", ! 701: "-fno-objc", ! 702: "-fgen-decls", ! 703: "-fgnu-runtime", ! 704: "-fno-gnu-runtime", ! 705: "-fnext-runtime", ! 706: "-fno-next-runtime", ! 707: "-Wselector", ! 708: "-Wno-selector", ! 709: "-Wprotocol", ! 710: "-Wno-protocol", ! 711: ! 712: #ifdef NEXT_SEMANTICS ! 713: /* These are for objective-c */ ! 714: /* NeXT should change to use the -fobjc and -fobjc++ ones above */ ! 715: "-ObjC++", ! 716: "-ObjC", ! 717: #endif ! 718: ! 719: /* This is for GNAT and is temporary. */ ! 720: "-gnat", ! 721: 0 ! 722: }; ! 723: ! 724: /* Options controlling warnings */ ! 725: ! 726: /* Don't print warning messages. -w. */ ! 727: ! 728: int inhibit_warnings = 0; ! 729: ! 730: /* Print various extra warnings. -W. */ ! 731: ! 732: int extra_warnings = 0; ! 733: ! 734: /* Treat warnings as errors. -Werror. */ ! 735: ! 736: int warnings_are_errors = 0; ! 737: ! 738: /* Nonzero to warn about unused local variables. */ ! 739: ! 740: int warn_unused; ! 741: ! 742: /* Nonzero to warn about variables used before they are initialized. */ ! 743: ! 744: int warn_uninitialized; ! 745: ! 746: /* Nonzero means warn about all declarations which shadow others. */ ! 747: ! 748: int warn_shadow; ! 749: ! 750: /* Warn if a switch on an enum fails to have a case for every enum value. */ ! 751: ! 752: int warn_switch; ! 753: ! 754: /* Nonzero means warn about function definitions that default the return type ! 755: or that use a null return and have a return-type other than void. */ ! 756: ! 757: int warn_return_type; ! 758: ! 759: /* Nonzero means warn about pointer casts that increase the required ! 760: alignment of the target type (and might therefore lead to a crash ! 761: due to a misaligned access). */ ! 762: ! 763: int warn_cast_align; ! 764: ! 765: /* Nonzero means warn about any identifiers that match in the first N ! 766: characters. The value N is in `id_clash_len'. */ ! 767: ! 768: int warn_id_clash; ! 769: int id_clash_len; ! 770: ! 771: /* Nonzero means warn if inline function is too large. */ ! 772: ! 773: int warn_inline; ! 774: ! 775: /* Warn if a function returns an aggregate, ! 776: since there are often incompatible calling conventions for doing this. */ ! 777: ! 778: int warn_aggregate_return; ! 779: ! 780: /* Likewise for -W. */ ! 781: ! 782: struct { char *string; int *variable; int on_value;} W_options[] = ! 783: { ! 784: #ifdef NEXT_CPP_PRECOMP ! 785: {"precomp", NULL, 1}, ! 786: #endif ! 787: {"unused", &warn_unused, 1}, ! 788: {"error", &warnings_are_errors, 1}, ! 789: {"shadow", &warn_shadow, 1}, ! 790: {"switch", &warn_switch, 1}, ! 791: {"aggregate-return", &warn_aggregate_return, 1}, ! 792: {"cast-align", &warn_cast_align, 1}, ! 793: {"uninitialized", &warn_uninitialized, 1}, ! 794: {"inline", &warn_inline, 1} ! 795: }; ! 796: ! 797: /* Output files for assembler code (real compiler output) ! 798: and debugging dumps. */ ! 799: ! 800: FILE *asm_out_file; ! 801: FILE *aux_info_file; ! 802: FILE *rtl_dump_file; ! 803: FILE *jump_opt_dump_file; ! 804: FILE *cse_dump_file; ! 805: FILE *loop_dump_file; ! 806: FILE *cse2_dump_file; ! 807: FILE *flow_dump_file; ! 808: FILE *combine_dump_file; ! 809: FILE *sched_dump_file; ! 810: FILE *fppc_dump_file; ! 811: FILE *local_reg_dump_file; ! 812: FILE *global_reg_dump_file; ! 813: FILE *sched2_dump_file; ! 814: FILE *jump2_opt_dump_file; ! 815: FILE *dbr_sched_dump_file; ! 816: FILE *stack_reg_dump_file; ! 817: ! 818: /* Time accumulators, to count the total time spent in various passes. */ ! 819: ! 820: int parse_time; ! 821: int varconst_time; ! 822: int integration_time; ! 823: int jump_time; ! 824: int cse_time; ! 825: int loop_time; ! 826: int cse2_time; ! 827: int flow_time; ! 828: int combine_time; ! 829: int sched_time; ! 830: int local_alloc_time; ! 831: int global_alloc_time; ! 832: int sched2_time; ! 833: int dbr_sched_time; ! 834: int shorten_branch_time; ! 835: int stack_reg_time; ! 836: int final_time; ! 837: int symout_time; ! 838: int dump_time; ! 839: ! 840: /* Return time used so far, in microseconds. */ ! 841: ! 842: int ! 843: get_run_time () ! 844: { ! 845: #ifdef USG ! 846: struct tms tms; ! 847: #else ! 848: #ifndef VMS ! 849: struct rusage rusage; ! 850: #else /* VMS */ ! 851: struct ! 852: { ! 853: int proc_user_time; ! 854: int proc_system_time; ! 855: int child_user_time; ! 856: int child_system_time; ! 857: } vms_times; ! 858: #endif ! 859: #endif ! 860: ! 861: if (quiet_flag) ! 862: return 0; ! 863: ! 864: #ifdef USG ! 865: times (&tms); ! 866: return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ); ! 867: #else ! 868: #ifndef VMS ! 869: getrusage (0, &rusage); ! 870: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec ! 871: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); ! 872: #else /* VMS */ ! 873: times (&vms_times); ! 874: return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; ! 875: #endif ! 876: #endif ! 877: } ! 878: ! 879: #define TIMEVAR(VAR, BODY) \ ! 880: do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0) ! 881: ! 882: void ! 883: print_time (str, total) ! 884: char *str; ! 885: int total; ! 886: { ! 887: fprintf (stderr, ! 888: "time in %s: %d.%06d\n", ! 889: str, total / 1000000, total % 1000000); ! 890: } ! 891: ! 892: #ifdef REPORT_EVENT ! 893: void ! 894: report_event (type, decl, file, line, msg, arg1, arg2, arg3) ! 895: int type; ! 896: tree decl; ! 897: char *file; ! 898: char *line; ! 899: char *msg; ! 900: int arg1; ! 901: int arg2; ! 902: int arg3; ! 903: { ! 904: char *name, *kind; ! 905: tree method_name = maybe_objc_method_name (decl); ! 906: ! 907: if (decl == NULL) ! 908: name = "top level"; ! 909: else if (method_name) ! 910: name = IDENTIFIER_POINTER (method_name); ! 911: else ! 912: name = (*decl_printable_name) (decl, &kind); ! 913: ! 914: REPORT_EVENT (type, name, file, line, msg, arg1, arg2, arg3); ! 915: } ! 916: #endif /* REPORT_EVENT */ ! 917: ! 918: ! 919: /* Count an error or warning. Return 1 if the message should be printed. */ ! 920: ! 921: int ! 922: count_error (warningp) ! 923: int warningp; ! 924: { ! 925: if (warningp && inhibit_warnings) ! 926: return 0; ! 927: ! 928: #ifdef NEXT_CPP_PRECOMP ! 929: if (multi_arch_flag && architecture) ! 930: { ! 931: const char *a; ! 932: ! 933: if (! strcmp (architecture, "i386")) ! 934: a = "Intel"; ! 935: else if (! strcmp (architecture, "hppa")) ! 936: a = "HPPA"; ! 937: else if (! strcmp (architecture, "m68k")) ! 938: a = "NeXT"; ! 939: else ! 940: a = architecture; ! 941: ! 942: #ifdef REPORT_EVENT ! 943: report_event (1, current_function_decl, input_filename, lineno, ! 944: "For architecture %s", a, 0, 0); ! 945: #endif ! 946: fprintf (stderr, "For architecture %s:\n", architecture); ! 947: multi_arch_flag = 0; ! 948: } ! 949: #endif /* NEXT_CPP_PRECOMP */ ! 950: ! 951: if (warningp && !warnings_are_errors) ! 952: warningcount++; ! 953: else ! 954: { ! 955: static int warning_message = 0; ! 956: ! 957: if (warningp && !warning_message) ! 958: { ! 959: fprintf (stderr, "%s: warnings being treated as errors\n", progname); ! 960: warning_message = 1; ! 961: } ! 962: errorcount++; ! 963: } ! 964: ! 965: return 1; ! 966: } ! 967: ! 968: /* Print a fatal error message. NAME is the text. ! 969: Also include a system error message based on `errno'. */ ! 970: ! 971: void ! 972: pfatal_with_name (name) ! 973: char *name; ! 974: { ! 975: #ifdef REPORT_EVENT ! 976: report_event (0, current_function_decl, input_filename, lineno, ! 977: "%s: ", name, strerror (errno), 0); ! 978: #endif ! 979: fprintf (stderr, "%s: ", progname); ! 980: perror (name); ! 981: exit (35); ! 982: } ! 983: ! 984: void ! 985: fatal_io_error (name) ! 986: char *name; ! 987: { ! 988: #ifdef REPORT_EVENT ! 989: report_event (0, current_function_decl, input_filename, lineno, ! 990: "%s: I/O error\n", name, 0, 0); ! 991: #endif ! 992: fprintf (stderr, "%s: %s: I/O error\n", progname, name); ! 993: exit (35); ! 994: } ! 995: ! 996: /* Called to give a better error message when we don't have an insn to match ! 997: what we are looking for or if the insn's constraints aren't satisfied, ! 998: rather than just calling abort(). */ ! 999: ! 1000: void ! 1001: fatal_insn_not_found (insn) ! 1002: rtx insn; ! 1003: { ! 1004: if (!output_bytecode) ! 1005: { ! 1006: if (INSN_CODE (insn) < 0) ! 1007: error ("internal error--unrecognizable insn:", 0); ! 1008: else ! 1009: error ("internal error--insn does not satisfy its constraints:", 0); ! 1010: debug_rtx (insn); ! 1011: } ! 1012: if (asm_out_file) ! 1013: fflush (asm_out_file); ! 1014: if (aux_info_file) ! 1015: fflush (aux_info_file); ! 1016: if (rtl_dump_file) ! 1017: fflush (rtl_dump_file); ! 1018: if (jump_opt_dump_file) ! 1019: fflush (jump_opt_dump_file); ! 1020: if (cse_dump_file) ! 1021: fflush (cse_dump_file); ! 1022: if (loop_dump_file) ! 1023: fflush (loop_dump_file); ! 1024: if (cse2_dump_file) ! 1025: fflush (cse2_dump_file); ! 1026: if (flow_dump_file) ! 1027: fflush (flow_dump_file); ! 1028: if (combine_dump_file) ! 1029: fflush (combine_dump_file); ! 1030: if (sched_dump_file) ! 1031: fflush (sched_dump_file); ! 1032: if (fppc_dump_file) ! 1033: fflush (fppc_dump_file); ! 1034: if (local_reg_dump_file) ! 1035: fflush (local_reg_dump_file); ! 1036: if (global_reg_dump_file) ! 1037: fflush (global_reg_dump_file); ! 1038: if (sched2_dump_file) ! 1039: fflush (sched2_dump_file); ! 1040: if (jump2_opt_dump_file) ! 1041: fflush (jump2_opt_dump_file); ! 1042: if (dbr_sched_dump_file) ! 1043: fflush (dbr_sched_dump_file); ! 1044: if (stack_reg_dump_file) ! 1045: fflush (stack_reg_dump_file); ! 1046: abort (); ! 1047: } ! 1048: ! 1049: /* This is the default decl_printable_name function. */ ! 1050: ! 1051: static char * ! 1052: decl_name (decl, kind) ! 1053: tree decl; ! 1054: char **kind; ! 1055: { ! 1056: return IDENTIFIER_POINTER (DECL_NAME (decl)); ! 1057: } ! 1058: ! 1059: static int need_error_newline; ! 1060: ! 1061: /* Function of last error message; ! 1062: more generally, function such that if next error message is in it ! 1063: then we don't have to mention the function name. */ ! 1064: static tree last_error_function = NULL; ! 1065: ! 1066: /* Used to detect when input_file_stack has changed since last described. */ ! 1067: static int last_error_tick; ! 1068: ! 1069: /* Called when the start of a function definition is parsed, ! 1070: this function prints on stderr the name of the function. */ ! 1071: ! 1072: void ! 1073: announce_function (decl) ! 1074: tree decl; ! 1075: { ! 1076: if (! quiet_flag) ! 1077: { ! 1078: char *junk; ! 1079: if (rtl_dump_and_exit) ! 1080: fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1081: else ! 1082: fprintf (stderr, " %s", (*decl_printable_name) (decl, &junk)); ! 1083: fflush (stderr); ! 1084: need_error_newline = 1; ! 1085: last_error_function = current_function_decl; ! 1086: } ! 1087: } ! 1088: ! 1089: /* Prints out, if necessary, the name of the current function ! 1090: which caused an error. Called from all error and warning functions. */ ! 1091: ! 1092: void ! 1093: report_error_function (file) ! 1094: char *file; ! 1095: { ! 1096: struct file_stack *p; ! 1097: ! 1098: if (need_error_newline) ! 1099: { ! 1100: fprintf (stderr, "\n"); ! 1101: need_error_newline = 0; ! 1102: } ! 1103: ! 1104: if (last_error_function != current_function_decl) ! 1105: { ! 1106: char *kind = "function"; ! 1107: tree method_name = maybe_objc_method_name (current_function_decl); ! 1108: ! 1109: if (current_function_decl != 0 ! 1110: && TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) ! 1111: kind = "method"; ! 1112: ! 1113: if (file) ! 1114: fprintf (stderr, "%s: ", file); ! 1115: ! 1116: if (current_function_decl == NULL) ! 1117: fprintf (stderr, "At top level:\n"); ! 1118: ! 1119: else if (method_name) ! 1120: fprintf (stderr, "In method `%s'\n", ! 1121: IDENTIFIER_POINTER (method_name)); ! 1122: else ! 1123: { ! 1124: char *name = (*decl_printable_name) (current_function_decl, &kind); ! 1125: fprintf (stderr, "In %s `%s':\n", kind, name); ! 1126: } ! 1127: ! 1128: last_error_function = current_function_decl; ! 1129: } ! 1130: if (input_file_stack && input_file_stack->next != 0 ! 1131: && input_file_stack_tick != last_error_tick) ! 1132: { ! 1133: fprintf (stderr, "In file included"); ! 1134: for (p = input_file_stack->next; p; p = p->next) ! 1135: { ! 1136: fprintf (stderr, " from %s:%d", p->name, p->line); ! 1137: if (p->next) ! 1138: fprintf (stderr, ",\n "); ! 1139: } ! 1140: fprintf (stderr, ":\n"); ! 1141: last_error_tick = input_file_stack_tick; ! 1142: } ! 1143: } ! 1144: ! 1145: /* Report an error at the current line number. ! 1146: S is a string and ARGLIST are args for `printf'. We use HOST_WIDE_INT ! 1147: as the type for these args assuming it is wide enough to hold a ! 1148: pointer. This isn't terribly portable, but is the best we can do ! 1149: without vprintf universally available. */ ! 1150: ! 1151: #define arglist a1, a2, a3 ! 1152: #define arglist_dcl HOST_WIDE_INT a1, a2, a3; ! 1153: ! 1154: void ! 1155: error (s, arglist) ! 1156: char *s; ! 1157: arglist_dcl ! 1158: { ! 1159: error_with_file_and_line (input_filename, lineno, s, arglist); ! 1160: } ! 1161: ! 1162: /* Report an error at line LINE of file FILE. ! 1163: S and ARGLIST are a string and args for `printf'. */ ! 1164: ! 1165: void ! 1166: error_with_file_and_line (file, line, s, arglist) ! 1167: char *file; ! 1168: int line; ! 1169: char *s; ! 1170: arglist_dcl ! 1171: { ! 1172: count_error (0); ! 1173: ! 1174: report_error_function (file); ! 1175: ! 1176: #ifdef REPORT_EVENT ! 1177: report_event (0, current_function_decl, file, line, s, arglist, 0, 0); ! 1178: #endif ! 1179: ! 1180: if (file) ! 1181: fprintf (stderr, "%s:%d: ", file, line); ! 1182: else ! 1183: fprintf (stderr, "%s: ", progname); ! 1184: fprintf (stderr, s, arglist); ! 1185: ! 1186: fprintf (stderr, "\n"); ! 1187: } ! 1188: ! 1189: /* Report an error at the declaration DECL. ! 1190: S and V are a string and an arg which uses %s to substitute ! 1191: the declaration name. */ ! 1192: ! 1193: void ! 1194: error_with_decl (decl, s, v) ! 1195: tree decl; ! 1196: char *s; ! 1197: HOST_WIDE_INT v; ! 1198: { ! 1199: char *junk; ! 1200: count_error (0); ! 1201: ! 1202: report_error_function (DECL_SOURCE_FILE (decl)); ! 1203: ! 1204: #ifdef REPORT_EVENT ! 1205: if (DECL_NAME (decl)) ! 1206: report_event (0, current_function_decl, ! 1207: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), ! 1208: s, (*decl_printable_name) (decl, &junk), v, 0); ! 1209: else ! 1210: report_event (0, current_function_decl, ! 1211: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), ! 1212: s, "((anonymous))", v, 0); ! 1213: #endif ! 1214: ! 1215: fprintf (stderr, "%s:%d: ", ! 1216: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 1217: ! 1218: if (DECL_NAME (decl)) ! 1219: fprintf (stderr, s, (*decl_printable_name) (decl, &junk), v); ! 1220: else ! 1221: fprintf (stderr, s, "((anonymous))", v); ! 1222: fprintf (stderr, "\n"); ! 1223: } ! 1224: ! 1225: /* Report an error at the line number of the insn INSN. ! 1226: S and ARGLIST are a string and args for `printf'. ! 1227: This is used only when INSN is an `asm' with operands, ! 1228: and each ASM_OPERANDS records its own source file and line. */ ! 1229: ! 1230: void ! 1231: error_for_asm (insn, s, arglist) ! 1232: rtx insn; ! 1233: char *s; ! 1234: arglist_dcl ! 1235: { ! 1236: char *filename; ! 1237: int line; ! 1238: rtx body = PATTERN (insn); ! 1239: rtx asmop; ! 1240: ! 1241: /* Find the (or one of the) ASM_OPERANDS in the insn. */ ! 1242: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) ! 1243: asmop = SET_SRC (body); ! 1244: else if (GET_CODE (body) == ASM_OPERANDS) ! 1245: asmop = body; ! 1246: else if (GET_CODE (body) == PARALLEL ! 1247: && GET_CODE (XVECEXP (body, 0, 0)) == SET) ! 1248: asmop = SET_SRC (XVECEXP (body, 0, 0)); ! 1249: else if (GET_CODE (body) == PARALLEL ! 1250: && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) ! 1251: asmop = XVECEXP (body, 0, 0); ! 1252: ! 1253: filename = ASM_OPERANDS_SOURCE_FILE (asmop); ! 1254: line = ASM_OPERANDS_SOURCE_LINE (asmop); ! 1255: ! 1256: error_with_file_and_line (filename, line, s, arglist); ! 1257: } ! 1258: ! 1259: void ! 1260: fatal (s, arglist) ! 1261: char *s; ! 1262: arglist_dcl ! 1263: { ! 1264: error (s, arglist); ! 1265: exit (34); ! 1266: } ! 1267: ! 1268: /* Report a warning at line LINE. ! 1269: S and ARGLIST are a string and args for `printf'. */ ! 1270: ! 1271: void ! 1272: warning_with_file_and_line (file, line, s, arglist) ! 1273: char *file; ! 1274: int line; ! 1275: char *s; ! 1276: arglist_dcl ! 1277: { ! 1278: if (count_error (1) == 0) ! 1279: return; ! 1280: ! 1281: report_error_function (file); ! 1282: ! 1283: #ifdef REPORT_EVENT ! 1284: report_event (1, current_function_decl, file, line, s, arglist, 0, 0); ! 1285: #endif ! 1286: ! 1287: if (file) ! 1288: fprintf (stderr, "%s:%d: ", file, line); ! 1289: else ! 1290: fprintf (stderr, "%s: ", progname); ! 1291: ! 1292: fprintf (stderr, "warning: "); ! 1293: fprintf (stderr, s, arglist); ! 1294: fprintf (stderr, "\n"); ! 1295: } ! 1296: ! 1297: /* Report a warning at the current line number. ! 1298: S and ARGLIST are a string and args for `printf'. */ ! 1299: ! 1300: void ! 1301: warning (s, arglist) ! 1302: char *s; ! 1303: arglist_dcl ! 1304: { ! 1305: warning_with_file_and_line (input_filename, lineno, s, arglist); ! 1306: } ! 1307: ! 1308: /* Report a warning at the declaration DECL. ! 1309: S is string which uses %s to substitute the declaration name. ! 1310: V is a second parameter that S can refer to. */ ! 1311: ! 1312: void ! 1313: warning_with_decl (decl, s, v) ! 1314: tree decl; ! 1315: char *s; ! 1316: HOST_WIDE_INT v; ! 1317: { ! 1318: char *junk; ! 1319: ! 1320: if (count_error (1) == 0) ! 1321: return; ! 1322: ! 1323: report_error_function (DECL_SOURCE_FILE (decl)); ! 1324: ! 1325: #ifdef REPORT_EVENT ! 1326: if (DECL_NAME (decl)) ! 1327: report_event (1, current_function_decl, ! 1328: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), ! 1329: s, (*decl_printable_name) (decl, &junk), v, 0); ! 1330: else ! 1331: report_event (1, current_function_decl, ! 1332: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), ! 1333: s, "((anonymous))", v, 0); ! 1334: #endif ! 1335: ! 1336: fprintf (stderr, "%s:%d: ", ! 1337: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 1338: ! 1339: fprintf (stderr, "warning: "); ! 1340: if (DECL_NAME (decl)) ! 1341: fprintf (stderr, s, (*decl_printable_name) (decl, &junk), v); ! 1342: else ! 1343: fprintf (stderr, s, "((anonymous))", v); ! 1344: fprintf (stderr, "\n"); ! 1345: } ! 1346: ! 1347: /* Report a warning at the line number of the insn INSN. ! 1348: S and ARGLIST are a string and args for `printf'. ! 1349: This is used only when INSN is an `asm' with operands, ! 1350: and each ASM_OPERANDS records its own source file and line. */ ! 1351: ! 1352: void ! 1353: warning_for_asm (insn, s, arglist) ! 1354: rtx insn; ! 1355: char *s; ! 1356: arglist_dcl ! 1357: { ! 1358: char *filename; ! 1359: int line; ! 1360: rtx body = PATTERN (insn); ! 1361: rtx asmop; ! 1362: ! 1363: /* Find the (or one of the) ASM_OPERANDS in the insn. */ ! 1364: if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) ! 1365: asmop = SET_SRC (body); ! 1366: else if (GET_CODE (body) == ASM_OPERANDS) ! 1367: asmop = body; ! 1368: else if (GET_CODE (body) == PARALLEL ! 1369: && GET_CODE (XVECEXP (body, 0, 0)) == SET) ! 1370: asmop = SET_SRC (XVECEXP (body, 0, 0)); ! 1371: else if (GET_CODE (body) == PARALLEL ! 1372: && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) ! 1373: asmop = XVECEXP (body, 0, 0); ! 1374: ! 1375: filename = ASM_OPERANDS_SOURCE_FILE (asmop); ! 1376: line = ASM_OPERANDS_SOURCE_LINE (asmop); ! 1377: ! 1378: warning_with_file_and_line (filename, line, s, arglist); ! 1379: } ! 1380: ! 1381: /* These functions issue either warnings or errors depending on ! 1382: -pedantic-errors. */ ! 1383: ! 1384: void ! 1385: pedwarn (s, arglist) ! 1386: char *s; ! 1387: arglist_dcl ! 1388: { ! 1389: if (flag_pedantic_errors) ! 1390: error (s, arglist); ! 1391: else ! 1392: warning (s, arglist); ! 1393: } ! 1394: ! 1395: void ! 1396: pedwarn_with_decl (decl, s, v) ! 1397: tree decl; ! 1398: char *s; ! 1399: HOST_WIDE_INT v; ! 1400: { ! 1401: if (flag_pedantic_errors) ! 1402: error_with_decl (decl, s, v); ! 1403: else ! 1404: warning_with_decl (decl, s, v); ! 1405: } ! 1406: ! 1407: void ! 1408: pedwarn_with_file_and_line (file, line, s, arglist) ! 1409: char *file; ! 1410: int line; ! 1411: char *s; ! 1412: arglist_dcl ! 1413: { ! 1414: if (flag_pedantic_errors) ! 1415: error_with_file_and_line (file, line, s, arglist); ! 1416: else ! 1417: warning_with_file_and_line (file, line, s, arglist); ! 1418: } ! 1419: ! 1420: /* Apologize for not implementing some feature. ! 1421: S and ARGLIST are a string and args for `printf'. */ ! 1422: ! 1423: void ! 1424: sorry (s, arglist) ! 1425: char *s; ! 1426: arglist_dcl ! 1427: { ! 1428: sorrycount++; ! 1429: #ifdef REPORT_EVENT ! 1430: report_event (0, current_function_decl, input_filename, lineno, ! 1431: s, arglist, 0, 0); ! 1432: #endif ! 1433: if (input_filename) ! 1434: fprintf (stderr, "%s:%d: ", input_filename, lineno); ! 1435: else ! 1436: fprintf (stderr, "%s: ", progname); ! 1437: ! 1438: fprintf (stderr, "sorry, not implemented: "); ! 1439: fprintf (stderr, s, arglist); ! 1440: fprintf (stderr, "\n"); ! 1441: } ! 1442: ! 1443: /* Apologize for not implementing some feature, then quit. ! 1444: S and ARGLIST are a string and args for `printf'. */ ! 1445: ! 1446: void ! 1447: really_sorry (s, arglist) ! 1448: char *s; ! 1449: arglist_dcl ! 1450: { ! 1451: #ifdef REPORT_EVENT ! 1452: report_event (0, current_function_decl, input_filename, lineno, ! 1453: s, arglist, 0, 0); ! 1454: #endif ! 1455: if (input_filename) ! 1456: fprintf (stderr, "%s:%d: ", input_filename, lineno); ! 1457: else ! 1458: fprintf (stderr, "%s: ", progname); ! 1459: ! 1460: fprintf (stderr, "sorry, not implemented: "); ! 1461: fprintf (stderr, s, arglist); ! 1462: fatal (" (fatal)\n"); ! 1463: } ! 1464: ! 1465: /* More 'friendly' abort that prints the line and file. ! 1466: config.h can #define abort fancy_abort if you like that sort of thing. ! 1467: ! 1468: I don't think this is actually a good idea. ! 1469: Other sorts of crashes will look a certain way. ! 1470: It is a good thing if crashes from calling abort look the same way. ! 1471: -- RMS */ ! 1472: ! 1473: void ! 1474: fancy_abort () ! 1475: { ! 1476: fatal ("internal gcc abort"); ! 1477: } ! 1478: ! 1479: /* This calls abort and is used to avoid problems when abort if a macro. ! 1480: It is used when we need to pass the address of abort. */ ! 1481: ! 1482: void ! 1483: do_abort () ! 1484: { ! 1485: abort (); ! 1486: } ! 1487: ! 1488: /* When `malloc.c' is compiled with `rcheck' defined, ! 1489: it calls this function to report clobberage. */ ! 1490: ! 1491: void ! 1492: botch (s) ! 1493: { ! 1494: abort (); ! 1495: } ! 1496: ! 1497: /* Same as `malloc' but report error if no memory available. */ ! 1498: ! 1499: char * ! 1500: xmalloc (size) ! 1501: unsigned size; ! 1502: { ! 1503: register char *value = (char *) malloc (size); ! 1504: if (value == 0) ! 1505: fatal ("virtual memory exhausted"); ! 1506: return value; ! 1507: } ! 1508: ! 1509: /* Same as `realloc' but report error if no memory available. */ ! 1510: ! 1511: char * ! 1512: xrealloc (ptr, size) ! 1513: char *ptr; ! 1514: int size; ! 1515: { ! 1516: char *result = (char *) realloc (ptr, size); ! 1517: if (!result) ! 1518: fatal ("virtual memory exhausted"); ! 1519: return result; ! 1520: } ! 1521: ! 1522: /* Return the logarithm of X, base 2, considering X unsigned, ! 1523: if X is a power of 2. Otherwise, returns -1. ! 1524: ! 1525: This should be used via the `exact_log2' macro. */ ! 1526: ! 1527: int ! 1528: exact_log2_wide (x) ! 1529: register unsigned HOST_WIDE_INT x; ! 1530: { ! 1531: register int log = 0; ! 1532: /* Test for 0 or a power of 2. */ ! 1533: if (x == 0 || x != (x & -x)) ! 1534: return -1; ! 1535: while ((x >>= 1) != 0) ! 1536: log++; ! 1537: return log; ! 1538: } ! 1539: ! 1540: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. ! 1541: If X is 0, return -1. ! 1542: ! 1543: This should be used via the floor_log2 macro. */ ! 1544: ! 1545: int ! 1546: floor_log2_wide (x) ! 1547: register unsigned HOST_WIDE_INT x; ! 1548: { ! 1549: register int log = -1; ! 1550: while (x != 0) ! 1551: log++, ! 1552: x >>= 1; ! 1553: return log; ! 1554: } ! 1555: ! 1556: int float_handled; ! 1557: jmp_buf float_handler; ! 1558: ! 1559: /* Specify where to longjmp to when a floating arithmetic error happens. ! 1560: If HANDLER is 0, it means don't handle the errors any more. */ ! 1561: ! 1562: void ! 1563: set_float_handler (handler) ! 1564: jmp_buf handler; ! 1565: { ! 1566: float_handled = (handler != 0); ! 1567: if (handler) ! 1568: bcopy (handler, float_handler, sizeof (float_handler)); ! 1569: } ! 1570: ! 1571: /* Specify, in HANDLER, where to longjmp to when a floating arithmetic ! 1572: error happens, pushing the previous specification into OLD_HANDLER. ! 1573: Return an indication of whether there was a previous handler in effect. */ ! 1574: ! 1575: int ! 1576: push_float_handler (handler, old_handler) ! 1577: jmp_buf handler, old_handler; ! 1578: { ! 1579: int was_handled = float_handled; ! 1580: ! 1581: float_handled = 1; ! 1582: if (was_handled) ! 1583: bcopy (float_handler, old_handler, sizeof (float_handler)); ! 1584: bcopy (handler, float_handler, sizeof (float_handler)); ! 1585: return was_handled; ! 1586: } ! 1587: ! 1588: /* Restore the previous specification of whether and where to longjmp to ! 1589: when a floating arithmetic error happens. */ ! 1590: ! 1591: void ! 1592: pop_float_handler (handled, handler) ! 1593: int handled; ! 1594: jmp_buf handler; ! 1595: { ! 1596: float_handled = handled; ! 1597: if (handled) ! 1598: bcopy (handler, float_handler, sizeof (float_handler)); ! 1599: } ! 1600: ! 1601: /* Signals actually come here. */ ! 1602: ! 1603: static void ! 1604: float_signal (signo) ! 1605: /* If this is missing, some compilers complain. */ ! 1606: int signo; ! 1607: { ! 1608: if (float_handled == 0) ! 1609: abort (); ! 1610: #if defined (USG) || defined (hpux) ! 1611: signal (SIGFPE, float_signal); /* re-enable the signal catcher */ ! 1612: #endif ! 1613: float_handled = 0; ! 1614: signal (SIGFPE, float_signal); ! 1615: longjmp (float_handler, 1); ! 1616: } ! 1617: ! 1618: /* Handler for SIGPIPE. */ ! 1619: ! 1620: static void ! 1621: pipe_closed (signo) ! 1622: /* If this is missing, some compilers complain. */ ! 1623: int signo; ! 1624: { ! 1625: fatal ("output pipe has been closed"); ! 1626: } ! 1627: ! 1628: /* Strip off a legitimate source ending from the input string NAME of ! 1629: length LEN. */ ! 1630: ! 1631: void ! 1632: strip_off_ending (name, len) ! 1633: char *name; ! 1634: int len; ! 1635: { ! 1636: if (len > 2 && ! strcmp (".c", name + len - 2)) ! 1637: name[len - 2] = 0; ! 1638: else if (len > 2 && ! strcmp (".m", name + len - 2)) ! 1639: name[len - 2] = 0; ! 1640: else if (len > 2 && ! strcmp (".i", name + len - 2)) ! 1641: name[len - 2] = 0; ! 1642: else if (len > 3 && ! strcmp (".ii", name + len - 3)) ! 1643: name[len - 3] = 0; ! 1644: else if (len > 3 && ! strcmp (".co", name + len - 3)) ! 1645: name[len - 3] = 0; ! 1646: else if (len > 3 && ! strcmp (".cc", name + len - 3)) ! 1647: name[len - 3] = 0; ! 1648: else if (len > 2 && ! strcmp (".C", name + len - 2)) ! 1649: name[len - 2] = 0; ! 1650: else if (len > 4 && ! strcmp (".cxx", name + len - 4)) ! 1651: name[len - 4] = 0; ! 1652: else if (len > 2 && ! strcmp (".f", name + len - 2)) ! 1653: name[len - 2] = 0; ! 1654: /* Ada will use extensions like .ada, .adb, and .ads, so just test ! 1655: for "ad". */ ! 1656: else if (len > 4 && ! strncmp (".ad", name + len - 4, 3)) ! 1657: name[len - 4] = 0; ! 1658: else if (len > 4 && ! strcmp (".atr", name + len - 4)) ! 1659: name[len - 4] = 0; ! 1660: } ! 1661: ! 1662: /* Output a quoted string. */ ! 1663: void ! 1664: output_quoted_string (asm_file, string) ! 1665: FILE *asm_file; ! 1666: char *string; ! 1667: { ! 1668: char c; ! 1669: ! 1670: putc ('\"', asm_file); ! 1671: while ((c = *string++) != 0) ! 1672: { ! 1673: if (c == '\"' || c == '\\') ! 1674: putc ('\\', asm_file); ! 1675: putc (c, asm_file); ! 1676: } ! 1677: putc ('\"', asm_file); ! 1678: } ! 1679: ! 1680: /* Output a file name in the form wanted by System V. */ ! 1681: ! 1682: void ! 1683: output_file_directive (asm_file, input_name) ! 1684: FILE *asm_file; ! 1685: char *input_name; ! 1686: { ! 1687: int len = strlen (input_name); ! 1688: char *na = input_name + len; ! 1689: ! 1690: /* NA gets INPUT_NAME sans directory names. */ ! 1691: while (na > input_name) ! 1692: { ! 1693: if (na[-1] == '/') ! 1694: break; ! 1695: na--; ! 1696: } ! 1697: ! 1698: #ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME ! 1699: ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na); ! 1700: #else ! 1701: #ifdef ASM_OUTPUT_SOURCE_FILENAME ! 1702: ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); ! 1703: #else ! 1704: fprintf (asm_file, "\t.file\t"); ! 1705: output_quoted_string (asm_file, na); ! 1706: fputc ('\n', asm_file); ! 1707: #endif ! 1708: #endif ! 1709: } ! 1710: ! 1711: /* Routine to build language identifier for object file. */ ! 1712: static void ! 1713: output_lang_identify (asm_out_file) ! 1714: FILE *asm_out_file; ! 1715: { ! 1716: int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1; ! 1717: char *s = (char *) alloca (len); ! 1718: sprintf (s, "__gnu_compiled_%s", lang_identify ()); ! 1719: ASM_OUTPUT_LABEL (asm_out_file, s); ! 1720: } ! 1721: ! 1722: /* Compile an entire file of output from cpp, named NAME. ! 1723: Write a file of assembly output and various debugging dumps. */ ! 1724: ! 1725: static void ! 1726: compile_file (name) ! 1727: char *name; ! 1728: { ! 1729: tree globals; ! 1730: int start_time; ! 1731: int dump_base_name_length; ! 1732: ! 1733: int name_specified = name != 0; ! 1734: ! 1735: if (dump_base_name == 0) ! 1736: dump_base_name = name ? name : "gccdump"; ! 1737: dump_base_name_length = strlen (dump_base_name); ! 1738: ! 1739: parse_time = 0; ! 1740: varconst_time = 0; ! 1741: integration_time = 0; ! 1742: jump_time = 0; ! 1743: cse_time = 0; ! 1744: loop_time = 0; ! 1745: cse2_time = 0; ! 1746: flow_time = 0; ! 1747: combine_time = 0; ! 1748: sched_time = 0; ! 1749: local_alloc_time = 0; ! 1750: global_alloc_time = 0; ! 1751: sched2_time = 0; ! 1752: dbr_sched_time = 0; ! 1753: shorten_branch_time = 0; ! 1754: stack_reg_time = 0; ! 1755: final_time = 0; ! 1756: symout_time = 0; ! 1757: dump_time = 0; ! 1758: ! 1759: /* Open input file. */ ! 1760: ! 1761: if (name == 0 || !strcmp (name, "-")) ! 1762: { ! 1763: finput = stdin; ! 1764: name = "stdin"; ! 1765: } ! 1766: else ! 1767: finput = fopen (name, "r"); ! 1768: if (finput == 0) ! 1769: pfatal_with_name (name); ! 1770: ! 1771: #ifdef IO_BUFFER_SIZE ! 1772: setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); ! 1773: #endif ! 1774: ! 1775: /* Initialize data in various passes. */ ! 1776: ! 1777: init_obstacks (); ! 1778: init_tree_codes (); ! 1779: init_lex (); ! 1780: /* Some of these really don't need to be called when generating bytecode, ! 1781: but the options would have to be parsed first to know that. -bson */ ! 1782: init_rtl (); ! 1783: init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL ! 1784: || debug_info_level == DINFO_LEVEL_VERBOSE); ! 1785: init_decl_processing (); ! 1786: init_optabs (); ! 1787: init_stmt (); ! 1788: init_expmed (); ! 1789: init_expr_once (); ! 1790: init_loop (); ! 1791: init_reload (); ! 1792: ! 1793: if (flag_caller_saves) ! 1794: init_caller_save (); ! 1795: ! 1796: /* If auxiliary info generation is desired, open the output file. ! 1797: This goes in the same directory as the source file--unlike ! 1798: all the other output files. */ ! 1799: if (flag_gen_aux_info) ! 1800: { ! 1801: aux_info_file = fopen (aux_info_file_name, "w"); ! 1802: if (aux_info_file == 0) ! 1803: pfatal_with_name (aux_info_file_name); ! 1804: } ! 1805: ! 1806: /* If rtl dump desired, open the output file. */ ! 1807: if (rtl_dump) ! 1808: { ! 1809: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1810: strcpy (dumpname, dump_base_name); ! 1811: strcat (dumpname, ".rtl"); ! 1812: rtl_dump_file = fopen (dumpname, "w"); ! 1813: if (rtl_dump_file == 0) ! 1814: pfatal_with_name (dumpname); ! 1815: } ! 1816: ! 1817: /* If jump_opt dump desired, open the output file. */ ! 1818: if (jump_opt_dump) ! 1819: { ! 1820: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1821: strcpy (dumpname, dump_base_name); ! 1822: strcat (dumpname, ".jump"); ! 1823: jump_opt_dump_file = fopen (dumpname, "w"); ! 1824: if (jump_opt_dump_file == 0) ! 1825: pfatal_with_name (dumpname); ! 1826: } ! 1827: ! 1828: /* If cse dump desired, open the output file. */ ! 1829: if (cse_dump) ! 1830: { ! 1831: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1832: strcpy (dumpname, dump_base_name); ! 1833: strcat (dumpname, ".cse"); ! 1834: cse_dump_file = fopen (dumpname, "w"); ! 1835: if (cse_dump_file == 0) ! 1836: pfatal_with_name (dumpname); ! 1837: } ! 1838: ! 1839: /* If loop dump desired, open the output file. */ ! 1840: if (loop_dump) ! 1841: { ! 1842: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1843: strcpy (dumpname, dump_base_name); ! 1844: strcat (dumpname, ".loop"); ! 1845: loop_dump_file = fopen (dumpname, "w"); ! 1846: if (loop_dump_file == 0) ! 1847: pfatal_with_name (dumpname); ! 1848: } ! 1849: ! 1850: /* If cse2 dump desired, open the output file. */ ! 1851: if (cse2_dump) ! 1852: { ! 1853: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1854: strcpy (dumpname, dump_base_name); ! 1855: strcat (dumpname, ".cse2"); ! 1856: cse2_dump_file = fopen (dumpname, "w"); ! 1857: if (cse2_dump_file == 0) ! 1858: pfatal_with_name (dumpname); ! 1859: } ! 1860: ! 1861: /* If flow dump desired, open the output file. */ ! 1862: if (flow_dump) ! 1863: { ! 1864: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1865: strcpy (dumpname, dump_base_name); ! 1866: strcat (dumpname, ".flow"); ! 1867: flow_dump_file = fopen (dumpname, "w"); ! 1868: if (flow_dump_file == 0) ! 1869: pfatal_with_name (dumpname); ! 1870: } ! 1871: ! 1872: /* If combine dump desired, open the output file. */ ! 1873: if (combine_dump) ! 1874: { ! 1875: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); ! 1876: strcpy (dumpname, dump_base_name); ! 1877: strcat (dumpname, ".combine"); ! 1878: combine_dump_file = fopen (dumpname, "w"); ! 1879: if (combine_dump_file == 0) ! 1880: pfatal_with_name (dumpname); ! 1881: } ! 1882: ! 1883: /* If scheduling dump desired, open the output file. */ ! 1884: if (sched_dump) ! 1885: { ! 1886: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 1887: strcpy (dumpname, dump_base_name); ! 1888: strcat (dumpname, ".sched"); ! 1889: sched_dump_file = fopen (dumpname, "w"); ! 1890: if (sched_dump_file == 0) ! 1891: pfatal_with_name (dumpname); ! 1892: } ! 1893: ! 1894: /* If local_reg dump desired, open the output file. */ ! 1895: if (fppc_dump) ! 1896: { ! 1897: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1898: strcpy (dumpname, dump_base_name); ! 1899: strcat (dumpname, ".fppc"); ! 1900: fppc_dump_file = fopen (dumpname, "w"); ! 1901: if (fppc_dump_file == 0) ! 1902: pfatal_with_name (dumpname); ! 1903: } ! 1904: ! 1905: /* If local_reg dump desired, open the output file. */ ! 1906: if (local_reg_dump) ! 1907: { ! 1908: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1909: strcpy (dumpname, dump_base_name); ! 1910: strcat (dumpname, ".lreg"); ! 1911: local_reg_dump_file = fopen (dumpname, "w"); ! 1912: if (local_reg_dump_file == 0) ! 1913: pfatal_with_name (dumpname); ! 1914: } ! 1915: ! 1916: /* If global_reg dump desired, open the output file. */ ! 1917: if (global_reg_dump) ! 1918: { ! 1919: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1920: strcpy (dumpname, dump_base_name); ! 1921: strcat (dumpname, ".greg"); ! 1922: global_reg_dump_file = fopen (dumpname, "w"); ! 1923: if (global_reg_dump_file == 0) ! 1924: pfatal_with_name (dumpname); ! 1925: } ! 1926: ! 1927: /* If 2nd scheduling dump desired, open the output file. */ ! 1928: if (sched2_dump) ! 1929: { ! 1930: register char *dumpname = (char *) xmalloc (dump_base_name_length + 8); ! 1931: strcpy (dumpname, dump_base_name); ! 1932: strcat (dumpname, ".sched2"); ! 1933: sched2_dump_file = fopen (dumpname, "w"); ! 1934: if (sched2_dump_file == 0) ! 1935: pfatal_with_name (dumpname); ! 1936: } ! 1937: ! 1938: /* If jump2_opt dump desired, open the output file. */ ! 1939: if (jump2_opt_dump) ! 1940: { ! 1941: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 1942: strcpy (dumpname, dump_base_name); ! 1943: strcat (dumpname, ".jump2"); ! 1944: jump2_opt_dump_file = fopen (dumpname, "w"); ! 1945: if (jump2_opt_dump_file == 0) ! 1946: pfatal_with_name (dumpname); ! 1947: } ! 1948: ! 1949: /* If dbr_sched dump desired, open the output file. */ ! 1950: if (dbr_sched_dump) ! 1951: { ! 1952: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 1953: strcpy (dumpname, dump_base_name); ! 1954: strcat (dumpname, ".dbr"); ! 1955: dbr_sched_dump_file = fopen (dumpname, "w"); ! 1956: if (dbr_sched_dump_file == 0) ! 1957: pfatal_with_name (dumpname); ! 1958: } ! 1959: ! 1960: #ifdef STACK_REGS ! 1961: ! 1962: /* If stack_reg dump desired, open the output file. */ ! 1963: if (stack_reg_dump) ! 1964: { ! 1965: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); ! 1966: strcpy (dumpname, dump_base_name); ! 1967: strcat (dumpname, ".stack"); ! 1968: stack_reg_dump_file = fopen (dumpname, "w"); ! 1969: if (stack_reg_dump_file == 0) ! 1970: pfatal_with_name (dumpname); ! 1971: } ! 1972: ! 1973: #endif ! 1974: ! 1975: /* Open assembler code output file. */ ! 1976: ! 1977: if (! name_specified && asm_file_name == 0) ! 1978: asm_out_file = stdout; ! 1979: else ! 1980: { ! 1981: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 1982: int len = strlen (dump_base_name); ! 1983: strcpy (dumpname, dump_base_name); ! 1984: strip_off_ending (dumpname, len); ! 1985: strcat (dumpname, ".s"); ! 1986: if (asm_file_name == 0) ! 1987: { ! 1988: asm_file_name = (char *) xmalloc (strlen (dumpname) + 1); ! 1989: strcpy (asm_file_name, dumpname); ! 1990: } ! 1991: if (!strcmp (asm_file_name, "-")) ! 1992: asm_out_file = stdout; ! 1993: else ! 1994: asm_out_file = fopen (asm_file_name, "w"); ! 1995: if (asm_out_file == 0) ! 1996: pfatal_with_name (asm_file_name); ! 1997: } ! 1998: ! 1999: #ifdef IO_BUFFER_SIZE ! 2000: setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), ! 2001: _IOFBF, IO_BUFFER_SIZE); ! 2002: #endif ! 2003: ! 2004: input_filename = name; ! 2005: ! 2006: /* Perform language-specific initialization. ! 2007: This may set main_input_filename. */ ! 2008: lang_init (); ! 2009: ! 2010: /* If the input doesn't start with a #line, use the input name ! 2011: as the official input file name. */ ! 2012: if (main_input_filename == 0) ! 2013: main_input_filename = name; ! 2014: ! 2015: /* Put an entry on the input file stack for the main input file. */ ! 2016: input_file_stack ! 2017: = (struct file_stack *) xmalloc (sizeof (struct file_stack)); ! 2018: input_file_stack->next = 0; ! 2019: input_file_stack->name = input_filename; ! 2020: ! 2021: if (!output_bytecode) ! 2022: { ! 2023: ASM_FILE_START (asm_out_file); ! 2024: } ! 2025: ! 2026: /* Output something to inform GDB that this compilation was by GCC. Also ! 2027: serves to tell GDB file consists of bytecodes. */ ! 2028: if (output_bytecode) ! 2029: fprintf (asm_out_file, "bc_gcc2_compiled.:\n"); ! 2030: else ! 2031: { ! 2032: #ifndef ASM_IDENTIFY_GCC ! 2033: fprintf (asm_out_file, "gcc2_compiled.:\n"); ! 2034: #else ! 2035: ASM_IDENTIFY_GCC (asm_out_file); ! 2036: #endif ! 2037: } ! 2038: ! 2039: /* Output something to identify which front-end produced this file. */ ! 2040: #ifdef ASM_IDENTIFY_LANGUAGE ! 2041: ASM_IDENTIFY_LANGUAGE (asm_out_file); ! 2042: #endif ! 2043: ! 2044: if (output_bytecode) ! 2045: { ! 2046: if (profile_flag || profile_block_flag) ! 2047: error ("profiling not supported in bytecode compilation"); ! 2048: } ! 2049: else ! 2050: { ! 2051: /* ??? Note: There used to be a conditional here ! 2052: to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined. ! 2053: This was to guarantee separation between gcc_compiled. and ! 2054: the first function, for the sake of dbx on Suns. ! 2055: However, having the extra zero here confused the Emacs ! 2056: code for unexec, and might confuse other programs too. ! 2057: Therefore, I took out that change. ! 2058: In future versions we should find another way to solve ! 2059: that dbx problem. -- rms, 23 May 93. */ ! 2060: ! 2061: /* Don't let the first function fall at the same address ! 2062: as gcc_compiled., if profiling. */ ! 2063: #ifndef DBX_DEBUGGING_INFO ! 2064: if (profile_flag || profile_block_flag) ! 2065: assemble_zeros (UNITS_PER_WORD); ! 2066: #endif ! 2067: } ! 2068: ! 2069: /* If dbx symbol table desired, initialize writing it ! 2070: and output the predefined types. */ ! 2071: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 2072: if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) ! 2073: TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename, ! 2074: getdecls ())); ! 2075: #endif ! 2076: #ifdef SDB_DEBUGGING_INFO ! 2077: if (write_symbols == SDB_DEBUG) ! 2078: TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename, ! 2079: getdecls ())); ! 2080: #endif ! 2081: #ifdef DWARF_DEBUGGING_INFO ! 2082: if (write_symbols == DWARF_DEBUG) ! 2083: TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename)); ! 2084: #endif ! 2085: ! 2086: /* Initialize yet another pass. */ ! 2087: ! 2088: if (!output_bytecode) ! 2089: init_final (main_input_filename); ! 2090: ! 2091: start_time = get_run_time (); ! 2092: ! 2093: /* Call the parser, which parses the entire file ! 2094: (calling rest_of_compilation for each function). */ ! 2095: ! 2096: if (yyparse () != 0) ! 2097: if (errorcount == 0) ! 2098: fprintf (stderr, "Errors detected in input file (your bison.simple is out of date)"); ! 2099: ! 2100: /* Compilation is now finished except for writing ! 2101: what's left of the symbol table output. */ ! 2102: ! 2103: parse_time += get_run_time () - start_time; ! 2104: ! 2105: parse_time -= integration_time; ! 2106: parse_time -= varconst_time; ! 2107: ! 2108: globals = getdecls (); ! 2109: ! 2110: /* Really define vars that have had only a tentative definition. ! 2111: Really output inline functions that must actually be callable ! 2112: and have not been output so far. */ ! 2113: ! 2114: { ! 2115: int len = list_length (globals); ! 2116: tree *vec = (tree *) alloca (sizeof (tree) * len); ! 2117: int i; ! 2118: tree decl; ! 2119: ! 2120: /* Process the decls in reverse order--earliest first. ! 2121: Put them into VEC from back to front, then take out from front. */ ! 2122: ! 2123: for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) ! 2124: vec[len - i - 1] = decl; ! 2125: ! 2126: for (i = 0; i < len; i++) ! 2127: { ! 2128: decl = vec[i]; ! 2129: if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0 ! 2130: && incomplete_decl_finalize_hook != 0) ! 2131: (*incomplete_decl_finalize_hook) (decl); ! 2132: ! 2133: if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) ! 2134: && ! TREE_ASM_WRITTEN (decl)) ! 2135: { ! 2136: /* Don't write out static consts, unless we used them. ! 2137: (This used to write them out only if the address was ! 2138: taken, but that was wrong; if the variable was simply ! 2139: referred to, it still needs to exist or else it will ! 2140: be undefined in the linker.) */ ! 2141: if (! TREE_READONLY (decl) ! 2142: || TREE_PUBLIC (decl) ! 2143: || TREE_USED (decl) ! 2144: || TREE_ADDRESSABLE (decl) ! 2145: || TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl))) ! 2146: rest_of_decl_compilation (decl, NULL_PTR, 1, 1); ! 2147: else ! 2148: /* Cancel the RTL for this decl so that, if debugging info ! 2149: output for global variables is still to come, ! 2150: this one will be omitted. */ ! 2151: DECL_RTL (decl) = NULL; ! 2152: } ! 2153: ! 2154: if (TREE_CODE (decl) == FUNCTION_DECL ! 2155: && ! TREE_ASM_WRITTEN (decl) ! 2156: && DECL_INITIAL (decl) != 0 ! 2157: && (TREE_ADDRESSABLE (decl) ! 2158: || TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl))) ! 2159: && ! DECL_EXTERNAL (decl)) ! 2160: { ! 2161: temporary_allocation (); ! 2162: output_inline_function (decl); ! 2163: permanent_allocation (); ! 2164: } ! 2165: ! 2166: /* Warn about any function ! 2167: declared static but not defined. ! 2168: We don't warn about variables, ! 2169: because many programs have static variables ! 2170: that exist only to get some text into the object file. */ ! 2171: if ((warn_unused ! 2172: || TREE_USED (decl) ! 2173: || (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))) ! 2174: && TREE_CODE (decl) == FUNCTION_DECL ! 2175: && DECL_INITIAL (decl) == 0 ! 2176: && DECL_EXTERNAL (decl) ! 2177: && ! TREE_PUBLIC (decl)) ! 2178: { ! 2179: /* This should be a pedwarn, except that there is ! 2180: no easy way to prevent it from happening when the ! 2181: name is used only inside a sizeof. ! 2182: This at least avoids being incorrect. */ ! 2183: warning_with_decl (decl, ! 2184: "`%s' declared `static' but never defined"); ! 2185: /* This symbol is effectively an "extern" declaration now. */ ! 2186: TREE_PUBLIC (decl) = 1; ! 2187: assemble_external (decl); ! 2188: ! 2189: } ! 2190: /* Warn about static fns or vars defined but not used, ! 2191: but not about inline functions ! 2192: since unused inline statics is normal practice. */ ! 2193: if (warn_unused ! 2194: && (TREE_CODE (decl) == FUNCTION_DECL ! 2195: || TREE_CODE (decl) == VAR_DECL) ! 2196: && ! DECL_IN_SYSTEM_HEADER (decl) ! 2197: && ! DECL_EXTERNAL (decl) ! 2198: && ! TREE_PUBLIC (decl) ! 2199: && ! TREE_USED (decl) ! 2200: && ! DECL_INLINE (decl) ! 2201: && ! DECL_REGISTER (decl) ! 2202: /* The TREE_USED bit for file-scope decls ! 2203: is kept in the identifier, to handle multiple ! 2204: external decls in different scopes. */ ! 2205: && ! TREE_USED (DECL_NAME (decl))) ! 2206: warning_with_decl (decl, "`%s' defined but not used"); ! 2207: ! 2208: #ifdef SDB_DEBUGGING_INFO ! 2209: /* The COFF linker can move initialized global vars to the end. ! 2210: And that can screw up the symbol ordering. ! 2211: By putting the symbols in that order to begin with, ! 2212: we avoid a problem. [email protected]. */ ! 2213: if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL ! 2214: && TREE_PUBLIC (decl) && DECL_INITIAL (decl) ! 2215: && DECL_RTL (decl) != 0) ! 2216: TIMEVAR (symout_time, sdbout_symbol (decl, 0)); ! 2217: ! 2218: /* Output COFF information for non-global ! 2219: file-scope initialized variables. */ ! 2220: if (write_symbols == SDB_DEBUG ! 2221: && TREE_CODE (decl) == VAR_DECL ! 2222: && DECL_INITIAL (decl) ! 2223: && DECL_RTL (decl) != 0 ! 2224: && GET_CODE (DECL_RTL (decl)) == MEM) ! 2225: TIMEVAR (symout_time, sdbout_toplevel_data (decl)); ! 2226: #endif /* SDB_DEBUGGING_INFO */ ! 2227: #ifdef DWARF_DEBUGGING_INFO ! 2228: /* Output DWARF information for file-scope tentative data object ! 2229: declarations, file-scope (extern) function declarations (which ! 2230: had no corresponding body) and file-scope tagged type declarations ! 2231: and definitions which have not yet been forced out. */ ! 2232: ! 2233: if (write_symbols == DWARF_DEBUG ! 2234: && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) ! 2235: TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); ! 2236: #endif ! 2237: } ! 2238: } ! 2239: ! 2240: /* Do dbx symbols */ ! 2241: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 2242: if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) ! 2243: TIMEVAR (symout_time, ! 2244: { ! 2245: dbxout_finish (asm_out_file, main_input_filename); ! 2246: }); ! 2247: #endif ! 2248: ! 2249: #ifdef DWARF_DEBUGGING_INFO ! 2250: if (write_symbols == DWARF_DEBUG) ! 2251: TIMEVAR (symout_time, ! 2252: { ! 2253: dwarfout_finish (); ! 2254: }); ! 2255: #endif ! 2256: ! 2257: #ifdef MACHO_PIC ! 2258: TIMEVAR (symout_time, ! 2259: { ! 2260: machopic_finish (asm_out_file); ! 2261: }); ! 2262: #endif ! 2263: ! 2264: /* Output some stuff at end of file if nec. */ ! 2265: ! 2266: if (!output_bytecode) ! 2267: { ! 2268: end_final (main_input_filename); ! 2269: ! 2270: #ifdef ASM_FILE_END ! 2271: ASM_FILE_END (asm_out_file); ! 2272: #endif ! 2273: } ! 2274: ! 2275: after_finish_compilation: ! 2276: ! 2277: /* Language-specific end of compilation actions. */ ! 2278: ! 2279: lang_finish (); ! 2280: ! 2281: /* Close the dump files. */ ! 2282: ! 2283: if (flag_gen_aux_info) ! 2284: { ! 2285: fclose (aux_info_file); ! 2286: if (errorcount) ! 2287: unlink (aux_info_file_name); ! 2288: } ! 2289: ! 2290: if (rtl_dump) ! 2291: fclose (rtl_dump_file); ! 2292: ! 2293: if (jump_opt_dump) ! 2294: fclose (jump_opt_dump_file); ! 2295: ! 2296: if (cse_dump) ! 2297: fclose (cse_dump_file); ! 2298: ! 2299: if (loop_dump) ! 2300: fclose (loop_dump_file); ! 2301: ! 2302: if (cse2_dump) ! 2303: fclose (cse2_dump_file); ! 2304: ! 2305: if (flow_dump) ! 2306: fclose (flow_dump_file); ! 2307: ! 2308: if (combine_dump) ! 2309: { ! 2310: dump_combine_total_stats (combine_dump_file); ! 2311: fclose (combine_dump_file); ! 2312: } ! 2313: ! 2314: if (sched_dump) ! 2315: fclose (sched_dump_file); ! 2316: ! 2317: if (fppc_dump) ! 2318: fclose (fppc_dump_file); ! 2319: ! 2320: if (local_reg_dump) ! 2321: fclose (local_reg_dump_file); ! 2322: ! 2323: if (global_reg_dump) ! 2324: fclose (global_reg_dump_file); ! 2325: ! 2326: if (sched2_dump) ! 2327: fclose (sched2_dump_file); ! 2328: ! 2329: if (jump2_opt_dump) ! 2330: fclose (jump2_opt_dump_file); ! 2331: ! 2332: if (dbr_sched_dump) ! 2333: fclose (dbr_sched_dump_file); ! 2334: ! 2335: #ifdef STACK_REGS ! 2336: if (stack_reg_dump) ! 2337: fclose (stack_reg_dump_file); ! 2338: #endif ! 2339: ! 2340: /* Close non-debugging input and output files. Take special care to note ! 2341: whether fclose returns an error, since the pages might still be on the ! 2342: buffer chain while the file is open. */ ! 2343: ! 2344: fclose (finput); ! 2345: if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0) ! 2346: fatal_io_error (asm_file_name); ! 2347: ! 2348: /* Print the times. */ ! 2349: ! 2350: if (! quiet_flag) ! 2351: { ! 2352: fprintf (stderr,"\n"); ! 2353: print_time ("parse", parse_time); ! 2354: ! 2355: if (!output_bytecode) ! 2356: { ! 2357: print_time ("integration", integration_time); ! 2358: print_time ("jump", jump_time); ! 2359: print_time ("cse", cse_time); ! 2360: print_time ("loop", loop_time); ! 2361: print_time ("cse2", cse2_time); ! 2362: print_time ("flow", flow_time); ! 2363: print_time ("combine", combine_time); ! 2364: print_time ("sched", sched_time); ! 2365: print_time ("local-alloc", local_alloc_time); ! 2366: print_time ("global-alloc", global_alloc_time); ! 2367: print_time ("sched2", sched2_time); ! 2368: print_time ("dbranch", dbr_sched_time); ! 2369: print_time ("shorten-branch", shorten_branch_time); ! 2370: print_time ("stack-reg", stack_reg_time); ! 2371: print_time ("final", final_time); ! 2372: print_time ("varconst", varconst_time); ! 2373: print_time ("symout", symout_time); ! 2374: print_time ("dump", dump_time); ! 2375: } ! 2376: } ! 2377: } ! 2378: ! 2379: /* This is called from various places for FUNCTION_DECL, VAR_DECL, ! 2380: and TYPE_DECL nodes. ! 2381: ! 2382: This does nothing for local (non-static) variables. ! 2383: Otherwise, it sets up the RTL and outputs any assembler code ! 2384: (label definition, storage allocation and initialization). ! 2385: ! 2386: DECL is the declaration. If ASMSPEC is nonzero, it specifies ! 2387: the assembler symbol name to be used. TOP_LEVEL is nonzero ! 2388: if this declaration is not within a function. */ ! 2389: ! 2390: void ! 2391: rest_of_decl_compilation (decl, asmspec, top_level, at_end) ! 2392: tree decl; ! 2393: char *asmspec; ! 2394: int top_level; ! 2395: int at_end; ! 2396: { ! 2397: /* Declarations of variables, and of functions defined elsewhere. */ ! 2398: ! 2399: /* The most obvious approach, to put an #ifndef around where ! 2400: this macro is used, doesn't work since it's inside a macro call. */ ! 2401: #ifndef ASM_FINISH_DECLARE_OBJECT ! 2402: #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END) ! 2403: #endif ! 2404: ! 2405: /* Forward declarations for nested functions are not "external", ! 2406: but we need to treat them as if they were. */ ! 2407: if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) ! 2408: || TREE_CODE (decl) == FUNCTION_DECL) ! 2409: TIMEVAR (varconst_time, ! 2410: { ! 2411: make_decl_rtl (decl, asmspec, top_level); ! 2412: /* Initialized extern variable exists to be replaced ! 2413: with its value, or represents something that will be ! 2414: output in another file. */ ! 2415: if (! (TREE_CODE (decl) == VAR_DECL ! 2416: && DECL_EXTERNAL (decl) && TREE_READONLY (decl) ! 2417: && DECL_INITIAL (decl) != 0 ! 2418: && DECL_INITIAL (decl) != error_mark_node)) ! 2419: /* Don't output anything ! 2420: when a tentative file-scope definition is seen. ! 2421: But at end of compilation, do output code for them. */ ! 2422: if (! (! at_end && top_level ! 2423: && (DECL_INITIAL (decl) == 0 ! 2424: || DECL_INITIAL (decl) == error_mark_node))) ! 2425: assemble_variable (decl, top_level, at_end, 0); ! 2426: if (decl == last_assemble_variable_decl) ! 2427: { ! 2428: ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, ! 2429: top_level, at_end); ! 2430: } ! 2431: }); ! 2432: else if (DECL_REGISTER (decl) && asmspec != 0) ! 2433: { ! 2434: if (decode_reg_name (asmspec) >= 0) ! 2435: { ! 2436: DECL_RTL (decl) = 0; ! 2437: make_decl_rtl (decl, asmspec, top_level); ! 2438: } ! 2439: else ! 2440: error ("invalid register name `%s' for register variable", asmspec); ! 2441: } ! 2442: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 2443: else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) ! 2444: && TREE_CODE (decl) == TYPE_DECL) ! 2445: TIMEVAR (symout_time, dbxout_symbol (decl, 0)); ! 2446: #endif ! 2447: #ifdef SDB_DEBUGGING_INFO ! 2448: else if (write_symbols == SDB_DEBUG && top_level ! 2449: && TREE_CODE (decl) == TYPE_DECL) ! 2450: TIMEVAR (symout_time, sdbout_symbol (decl, 0)); ! 2451: #endif ! 2452: } ! 2453: ! 2454: /* Called after finishing a record, union or enumeral type. */ ! 2455: ! 2456: void ! 2457: rest_of_type_compilation (type, toplev) ! 2458: tree type; ! 2459: int toplev; ! 2460: { ! 2461: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 2462: if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) ! 2463: TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev)); ! 2464: #endif ! 2465: #ifdef SDB_DEBUGGING_INFO ! 2466: if (write_symbols == SDB_DEBUG) ! 2467: TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev)); ! 2468: #endif ! 2469: } ! 2470: ! 2471: /* This is called from finish_function (within yyparse) ! 2472: after each top-level definition is parsed. ! 2473: It is supposed to compile that function or variable ! 2474: and output the assembler code for it. ! 2475: After we return, the tree storage is freed. */ ! 2476: ! 2477: void ! 2478: rest_of_compilation (decl) ! 2479: tree decl; ! 2480: { ! 2481: register rtx insns; ! 2482: int start_time = get_run_time (); ! 2483: int tem; ! 2484: /* Nonzero if we have saved the original DECL_INITIAL of the function, ! 2485: to be restored after we finish compiling the function ! 2486: (for use when compiling inline calls to this function). */ ! 2487: tree saved_block_tree = 0; ! 2488: /* Likewise, for DECL_ARGUMENTS. */ ! 2489: tree saved_arguments = 0; ! 2490: int failure = 0; ! 2491: ! 2492: if (output_bytecode) ! 2493: return; ! 2494: ! 2495: /* If we are reconsidering an inline function ! 2496: at the end of compilation, skip the stuff for making it inline. */ ! 2497: ! 2498: if (DECL_SAVED_INSNS (decl) == 0) ! 2499: { ! 2500: int specd = DECL_INLINE (decl); ! 2501: char *lose; ! 2502: ! 2503: /* If requested, consider whether to make this function inline. */ ! 2504: if (specd || flag_inline_functions) ! 2505: TIMEVAR (integration_time, ! 2506: { ! 2507: lose = function_cannot_inline_p (decl); ! 2508: /* If not optimzing, then make sure the DECL_INLINE ! 2509: bit is off. */ ! 2510: ! 2511: #ifdef NEXT_SEMANTICS ! 2512: if (lose || flag_keep_inline_functions) ! 2513: #else ! 2514: if (lose || ! optimize) ! 2515: #endif ! 2516: { ! 2517: if (warn_inline && specd) ! 2518: warning_with_decl (decl, lose); ! 2519: DECL_INLINE (decl) = 0; ! 2520: /* Don't really compile an extern inline function. ! 2521: If we can't make it inline, pretend ! 2522: it was only declared. */ ! 2523: if (DECL_EXTERNAL (decl)) ! 2524: { ! 2525: DECL_INITIAL (decl) = 0; ! 2526: goto exit_rest_of_compilation; ! 2527: } ! 2528: } ! 2529: else ! 2530: DECL_INLINE (decl) = 1; ! 2531: }); ! 2532: ! 2533: insns = get_insns (); ! 2534: ! 2535: /* Dump the rtl code if we are dumping rtl. */ ! 2536: ! 2537: if (rtl_dump) ! 2538: TIMEVAR (dump_time, ! 2539: { ! 2540: fprintf (rtl_dump_file, "\n;; Function %s\n\n", ! 2541: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2542: if (DECL_SAVED_INSNS (decl)) ! 2543: fprintf (rtl_dump_file, ";; (integrable)\n\n"); ! 2544: print_rtl (rtl_dump_file, insns); ! 2545: fflush (rtl_dump_file); ! 2546: }); ! 2547: ! 2548: /* If function is inline, and we don't yet know whether to ! 2549: compile it by itself, defer decision till end of compilation. ! 2550: finish_compilation will call rest_of_compilation again ! 2551: for those functions that need to be output. */ ! 2552: ! 2553: if (DECL_INLINE (decl) ! 2554: && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) ! 2555: && ! flag_keep_inline_functions) ! 2556: || DECL_EXTERNAL (decl))) ! 2557: { ! 2558: #ifdef DWARF_DEBUGGING_INFO ! 2559: /* Generate the DWARF info for the "abstract" instance ! 2560: of a function which we may later generate inlined and/or ! 2561: out-of-line instances of. */ ! 2562: if (write_symbols == DWARF_DEBUG) ! 2563: { ! 2564: set_decl_abstract_flags (decl, 1); ! 2565: TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); ! 2566: set_decl_abstract_flags (decl, 0); ! 2567: } ! 2568: #endif ! 2569: TIMEVAR (integration_time, save_for_inline_nocopy (decl)); ! 2570: goto exit_rest_of_compilation; ! 2571: } ! 2572: ! 2573: /* If we have to compile the function now, save its rtl and subdecls ! 2574: so that its compilation will not affect what others get. */ ! 2575: if (DECL_INLINE (decl)) ! 2576: { ! 2577: #ifdef DWARF_DEBUGGING_INFO ! 2578: /* Generate the DWARF info for the "abstract" instance of ! 2579: a function which we will generate an out-of-line instance ! 2580: of almost immediately (and which we may also later generate ! 2581: various inlined instances of). */ ! 2582: if (write_symbols == DWARF_DEBUG) ! 2583: { ! 2584: set_decl_abstract_flags (decl, 1); ! 2585: TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); ! 2586: set_decl_abstract_flags (decl, 0); ! 2587: } ! 2588: #endif ! 2589: saved_block_tree = DECL_INITIAL (decl); ! 2590: saved_arguments = DECL_ARGUMENTS (decl); ! 2591: TIMEVAR (integration_time, save_for_inline_copying (decl)); ! 2592: } ! 2593: } ! 2594: ! 2595: TREE_ASM_WRITTEN (decl) = 1; ! 2596: ! 2597: /* Now that integrate will no longer see our rtl, we need not distinguish ! 2598: between the return value of this function and the return value of called ! 2599: functions. */ ! 2600: rtx_equal_function_value_matters = 0; ! 2601: ! 2602: /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */ ! 2603: if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) ! 2604: { ! 2605: goto exit_rest_of_compilation; ! 2606: } ! 2607: ! 2608: /* From now on, allocate rtl in current_obstack, not in saveable_obstack. ! 2609: Note that that may have been done above, in save_for_inline_copying. ! 2610: The call to resume_temporary_allocation near the end of this function ! 2611: goes back to the usual state of affairs. */ ! 2612: ! 2613: rtl_in_current_obstack (); ! 2614: ! 2615: #ifdef FINALIZE_PIC ! 2616: /* If we are doing position-independent code generation, now ! 2617: is the time to output special prologues and epilogues. ! 2618: We do not want to do this earlier, because it just clutters ! 2619: up inline functions with meaningless insns. */ ! 2620: if (flag_pic) ! 2621: FINALIZE_PIC; ! 2622: #endif ! 2623: ! 2624: insns = get_insns (); ! 2625: ! 2626: /* Copy any shared structure that should not be shared. */ ! 2627: ! 2628: unshare_all_rtl (insns); ! 2629: ! 2630: /* Instantiate all virtual registers. */ ! 2631: ! 2632: instantiate_virtual_regs (current_function_decl, get_insns ()); ! 2633: ! 2634: /* See if we have allocated stack slots that are not directly addressable. ! 2635: If so, scan all the insns and create explicit address computation ! 2636: for all references to such slots. */ ! 2637: /* fixup_stack_slots (); */ ! 2638: ! 2639: /* Do jump optimization the first time, if -opt. ! 2640: Also do it if -W, but in that case it doesn't change the rtl code, ! 2641: it only computes whether control can drop off the end of the function. */ ! 2642: ! 2643: if (optimize > 0 || extra_warnings || warn_return_type ! 2644: /* If function is `volatile', we should warn if it tries to return. */ ! 2645: || TREE_THIS_VOLATILE (decl)) ! 2646: { ! 2647: TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); ! 2648: TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1)); ! 2649: } ! 2650: ! 2651: /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ ! 2652: if (rtl_dump_and_exit || flag_syntax_only) ! 2653: goto exit_rest_of_compilation; ! 2654: ! 2655: /* Dump rtl code after jump, if we are doing that. */ ! 2656: ! 2657: if (jump_opt_dump) ! 2658: TIMEVAR (dump_time, ! 2659: { ! 2660: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n", ! 2661: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2662: print_rtl (jump_opt_dump_file, insns); ! 2663: fflush (jump_opt_dump_file); ! 2664: }); ! 2665: ! 2666: /* Perform common subexpression elimination. ! 2667: Nonzero value from `cse_main' means that jumps were simplified ! 2668: and some code may now be unreachable, so do ! 2669: jump optimization again. */ ! 2670: ! 2671: if (cse_dump) ! 2672: TIMEVAR (dump_time, ! 2673: { ! 2674: fprintf (cse_dump_file, "\n;; Function %s\n\n", ! 2675: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2676: }); ! 2677: ! 2678: if (optimize > 0) ! 2679: { ! 2680: TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1)); ! 2681: ! 2682: if (flag_thread_jumps) ! 2683: /* Hacks by tiemann & kenner. */ ! 2684: TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); ! 2685: ! 2686: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (), ! 2687: 0, cse_dump_file)); ! 2688: TIMEVAR (cse_time, delete_dead_from_cse (insns, max_reg_num ())); ! 2689: ! 2690: if (tem) ! 2691: TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0)); ! 2692: } ! 2693: ! 2694: /* Dump rtl code after cse, if we are doing that. */ ! 2695: ! 2696: if (cse_dump) ! 2697: TIMEVAR (dump_time, ! 2698: { ! 2699: print_rtl (cse_dump_file, insns); ! 2700: fflush (cse_dump_file); ! 2701: }); ! 2702: ! 2703: if (loop_dump) ! 2704: TIMEVAR (dump_time, ! 2705: { ! 2706: fprintf (loop_dump_file, "\n;; Function %s\n\n", ! 2707: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2708: }); ! 2709: ! 2710: /* Move constant computations out of loops. */ ! 2711: ! 2712: if (optimize > 0) ! 2713: { ! 2714: TIMEVAR (loop_time, ! 2715: { ! 2716: loop_optimize (insns, loop_dump_file); ! 2717: }); ! 2718: } ! 2719: ! 2720: /* Dump rtl code after loop opt, if we are doing that. */ ! 2721: ! 2722: if (loop_dump) ! 2723: TIMEVAR (dump_time, ! 2724: { ! 2725: print_rtl (loop_dump_file, insns); ! 2726: fflush (loop_dump_file); ! 2727: }); ! 2728: ! 2729: if (cse2_dump) ! 2730: TIMEVAR (dump_time, ! 2731: { ! 2732: fprintf (cse2_dump_file, "\n;; Function %s\n\n", ! 2733: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2734: }); ! 2735: ! 2736: if (optimize > 0 && flag_rerun_cse_after_loop) ! 2737: { ! 2738: TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0)); ! 2739: ! 2740: TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (), ! 2741: 1, cse2_dump_file)); ! 2742: if (tem) ! 2743: TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0)); ! 2744: } ! 2745: ! 2746: if (optimize > 0 && flag_thread_jumps) ! 2747: /* This pass of jump threading straightens out code ! 2748: that was kinked by loop optimization. */ ! 2749: TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); ! 2750: ! 2751: /* Dump rtl code after cse, if we are doing that. */ ! 2752: ! 2753: if (cse2_dump) ! 2754: TIMEVAR (dump_time, ! 2755: { ! 2756: print_rtl (cse2_dump_file, insns); ! 2757: fflush (cse2_dump_file); ! 2758: }); ! 2759: ! 2760: /* We are no longer anticipating cse in this function, at least. */ ! 2761: ! 2762: cse_not_expected = 1; ! 2763: ! 2764: /* Now we choose between stupid (pcc-like) register allocation ! 2765: (if we got the -noreg switch and not -opt) ! 2766: and smart register allocation. */ ! 2767: ! 2768: if (optimize > 0) /* Stupid allocation probably won't work */ ! 2769: obey_regdecls = 0; /* if optimizations being done. */ ! 2770: ! 2771: regclass_init (); ! 2772: ! 2773: /* Print function header into flow dump now ! 2774: because doing the flow analysis makes some of the dump. */ ! 2775: ! 2776: if (flow_dump) ! 2777: TIMEVAR (dump_time, ! 2778: { ! 2779: fprintf (flow_dump_file, "\n;; Function %s\n\n", ! 2780: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2781: }); ! 2782: ! 2783: if (obey_regdecls) ! 2784: { ! 2785: TIMEVAR (flow_time, ! 2786: { ! 2787: regclass (insns, max_reg_num ()); ! 2788: stupid_life_analysis (insns, max_reg_num (), ! 2789: flow_dump_file); ! 2790: }); ! 2791: } ! 2792: else ! 2793: { ! 2794: /* Do control and data flow analysis, ! 2795: and write some of the results to dump file. */ ! 2796: ! 2797: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (), ! 2798: flow_dump_file)); ! 2799: if (warn_uninitialized) ! 2800: { ! 2801: uninitialized_vars_warning (DECL_INITIAL (decl)); ! 2802: setjmp_args_warning (); ! 2803: } ! 2804: } ! 2805: ! 2806: /* Dump rtl after flow analysis. */ ! 2807: ! 2808: if (flow_dump) ! 2809: TIMEVAR (dump_time, ! 2810: { ! 2811: print_rtl (flow_dump_file, insns); ! 2812: fflush (flow_dump_file); ! 2813: }); ! 2814: ! 2815: /* If -opt, try combining insns through substitution. */ ! 2816: ! 2817: if (optimize > 0) ! 2818: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ())); ! 2819: ! 2820: /* Dump rtl code after insn combination. */ ! 2821: ! 2822: if (combine_dump) ! 2823: TIMEVAR (dump_time, ! 2824: { ! 2825: fprintf (combine_dump_file, "\n;; Function %s\n\n", ! 2826: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2827: dump_combine_stats (combine_dump_file); ! 2828: print_rtl (combine_dump_file, insns); ! 2829: fflush (combine_dump_file); ! 2830: }); ! 2831: ! 2832: /* Print function header into sched dump now ! 2833: because doing the sched analysis makes some of the dump. */ ! 2834: ! 2835: if (sched_dump) ! 2836: TIMEVAR (dump_time, ! 2837: { ! 2838: fprintf (sched_dump_file, "\n;; Function %s\n\n", ! 2839: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2840: }); ! 2841: ! 2842: if (optimize > 0 && flag_schedule_insns) ! 2843: { ! 2844: /* Do control and data sched analysis, ! 2845: and write some of the results to dump file. */ ! 2846: ! 2847: TIMEVAR (sched_time, schedule_insns (sched_dump_file)); ! 2848: } ! 2849: ! 2850: /* Dump rtl after instruction scheduling. */ ! 2851: ! 2852: if (sched_dump) ! 2853: TIMEVAR (dump_time, ! 2854: { ! 2855: print_rtl (sched_dump_file, insns); ! 2856: fflush (sched_dump_file); ! 2857: }); ! 2858: ! 2859: #if defined(HAVE_fppc_switch) ! 2860: /* Insert floating point precision control code. */ ! 2861: ! 2862: if (flag_fppc && HAVE_fppc_switch) ! 2863: TIMEVAR (local_alloc_time, ! 2864: { ! 2865: fppc_insns (insns); ! 2866: }); ! 2867: ! 2868: if (fppc_dump) ! 2869: TIMEVAR (dump_time, ! 2870: { ! 2871: fprintf (fppc_dump_file, "\n;; Function %s\n\n", ! 2872: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2873: print_rtl (fppc_dump_file, insns); ! 2874: fflush (fppc_dump_file); ! 2875: }); ! 2876: ! 2877: #endif ! 2878: ! 2879: /* Unless we did stupid register allocation, ! 2880: allocate pseudo-regs that are used only within 1 basic block. */ ! 2881: ! 2882: if (!obey_regdecls) ! 2883: TIMEVAR (local_alloc_time, ! 2884: { ! 2885: regclass (insns, max_reg_num ()); ! 2886: local_alloc (); ! 2887: }); ! 2888: ! 2889: /* Dump rtl code after allocating regs within basic blocks. */ ! 2890: ! 2891: if (local_reg_dump) ! 2892: TIMEVAR (dump_time, ! 2893: { ! 2894: fprintf (local_reg_dump_file, "\n;; Function %s\n\n", ! 2895: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2896: dump_flow_info (local_reg_dump_file); ! 2897: dump_local_alloc (local_reg_dump_file); ! 2898: print_rtl (local_reg_dump_file, insns); ! 2899: fflush (local_reg_dump_file); ! 2900: }); ! 2901: ! 2902: if (global_reg_dump) ! 2903: TIMEVAR (dump_time, ! 2904: fprintf (global_reg_dump_file, "\n;; Function %s\n\n", ! 2905: IDENTIFIER_POINTER (DECL_NAME (decl)))); ! 2906: ! 2907: /* Unless we did stupid register allocation, ! 2908: allocate remaining pseudo-regs, then do the reload pass ! 2909: fixing up any insns that are invalid. */ ! 2910: ! 2911: TIMEVAR (global_alloc_time, ! 2912: { ! 2913: if (!obey_regdecls) ! 2914: failure = global_alloc (global_reg_dump_file); ! 2915: else ! 2916: failure = reload (insns, 0, global_reg_dump_file); ! 2917: }); ! 2918: ! 2919: if (global_reg_dump) ! 2920: TIMEVAR (dump_time, ! 2921: { ! 2922: dump_global_regs (global_reg_dump_file); ! 2923: print_rtl (global_reg_dump_file, insns); ! 2924: fflush (global_reg_dump_file); ! 2925: }); ! 2926: ! 2927: if (failure) ! 2928: goto exit_rest_of_compilation; ! 2929: ! 2930: reload_completed = 1; ! 2931: ! 2932: /* On some machines, the prologue and epilogue code, or parts thereof, ! 2933: can be represented as RTL. Doing so lets us schedule insns between ! 2934: it and the rest of the code and also allows delayed branch ! 2935: scheduling to operate in the epilogue. */ ! 2936: ! 2937: thread_prologue_and_epilogue_insns (insns); ! 2938: ! 2939: if (optimize > 0 && flag_schedule_insns_after_reload) ! 2940: { ! 2941: if (sched2_dump) ! 2942: TIMEVAR (dump_time, ! 2943: { ! 2944: fprintf (sched2_dump_file, "\n;; Function %s\n\n", ! 2945: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2946: }); ! 2947: ! 2948: /* Do control and data sched analysis again, ! 2949: and write some more of the results to dump file. */ ! 2950: ! 2951: TIMEVAR (sched2_time, schedule_insns (sched2_dump_file)); ! 2952: ! 2953: /* Dump rtl after post-reorder instruction scheduling. */ ! 2954: ! 2955: if (sched2_dump) ! 2956: TIMEVAR (dump_time, ! 2957: { ! 2958: print_rtl (sched2_dump_file, insns); ! 2959: fflush (sched2_dump_file); ! 2960: }); ! 2961: } ! 2962: ! 2963: #ifdef LEAF_REGISTERS ! 2964: leaf_function = 0; ! 2965: if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ()) ! 2966: leaf_function = 1; ! 2967: #endif ! 2968: ! 2969: /* One more attempt to remove jumps to .+1 ! 2970: left by dead-store-elimination. ! 2971: Also do cross-jumping this time ! 2972: and delete no-op move insns. */ ! 2973: ! 2974: if (optimize > 0) ! 2975: { ! 2976: TIMEVAR (jump_time, jump_optimize (insns, 1, 1, 0)); ! 2977: } ! 2978: ! 2979: /* Dump rtl code after jump, if we are doing that. */ ! 2980: ! 2981: if (jump2_opt_dump) ! 2982: TIMEVAR (dump_time, ! 2983: { ! 2984: fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n", ! 2985: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2986: print_rtl (jump2_opt_dump_file, insns); ! 2987: fflush (jump2_opt_dump_file); ! 2988: }); ! 2989: ! 2990: /* If a scheduling pass for delayed branches is to be done, ! 2991: call the scheduling code. */ ! 2992: ! 2993: #ifdef DELAY_SLOTS ! 2994: if (optimize > 0 && flag_delayed_branch) ! 2995: { ! 2996: TIMEVAR (dbr_sched_time, dbr_schedule (insns, dbr_sched_dump_file)); ! 2997: if (dbr_sched_dump) ! 2998: { ! 2999: TIMEVAR (dump_time, ! 3000: { ! 3001: fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n", ! 3002: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 3003: print_rtl (dbr_sched_dump_file, insns); ! 3004: fflush (dbr_sched_dump_file); ! 3005: }); ! 3006: } ! 3007: } ! 3008: #endif ! 3009: ! 3010: if (optimize > 0) ! 3011: /* Shorten branches. */ ! 3012: TIMEVAR (shorten_branch_time, ! 3013: { ! 3014: shorten_branches (get_insns ()); ! 3015: }); ! 3016: ! 3017: #ifdef STACK_REGS ! 3018: TIMEVAR (stack_reg_time, reg_to_stack (insns, stack_reg_dump_file)); ! 3019: if (stack_reg_dump) ! 3020: { ! 3021: TIMEVAR (dump_time, ! 3022: { ! 3023: fprintf (stack_reg_dump_file, "\n;; Function %s\n\n", ! 3024: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 3025: print_rtl (stack_reg_dump_file, insns); ! 3026: fflush (stack_reg_dump_file); ! 3027: }); ! 3028: } ! 3029: #endif ! 3030: ! 3031: /* Now turn the rtl into assembler code. */ ! 3032: ! 3033: TIMEVAR (final_time, ! 3034: { ! 3035: rtx x; ! 3036: char *fnname; ! 3037: ! 3038: /* Get the function's name, as described by its RTL. ! 3039: This may be different from the DECL_NAME name used ! 3040: in the source file. */ ! 3041: ! 3042: x = DECL_RTL (decl); ! 3043: if (GET_CODE (x) != MEM) ! 3044: abort (); ! 3045: x = XEXP (x, 0); ! 3046: if (GET_CODE (x) != SYMBOL_REF) ! 3047: abort (); ! 3048: fnname = XSTR (x, 0); ! 3049: ! 3050: assemble_start_function (decl, fnname); ! 3051: final_start_function (insns, asm_out_file, optimize); ! 3052: final (insns, asm_out_file, optimize, 0); ! 3053: final_end_function (insns, asm_out_file, optimize); ! 3054: assemble_end_function (decl, fnname); ! 3055: fflush (asm_out_file); ! 3056: }); ! 3057: ! 3058: /* Write DBX symbols if requested */ ! 3059: ! 3060: /* Note that for those inline functions where we don't initially ! 3061: know for certain that we will be generating an out-of-line copy, ! 3062: the first invocation of this routine (rest_of_compilation) will ! 3063: skip over this code by doing a `goto exit_rest_of_compilation;'. ! 3064: Later on, finish_compilation will call rest_of_compilation again ! 3065: for those inline functions that need to have out-of-line copies ! 3066: generated. During that call, we *will* be routed past here. */ ! 3067: ! 3068: #ifdef DBX_DEBUGGING_INFO ! 3069: if (write_symbols == DBX_DEBUG) ! 3070: TIMEVAR (symout_time, dbxout_function (decl)); ! 3071: #endif ! 3072: ! 3073: #ifdef DWARF_DEBUGGING_INFO ! 3074: if (write_symbols == DWARF_DEBUG) ! 3075: TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); ! 3076: #endif ! 3077: ! 3078: exit_rest_of_compilation: ! 3079: ! 3080: /* In case the function was not output, ! 3081: don't leave any temporary anonymous types ! 3082: queued up for sdb output. */ ! 3083: #ifdef SDB_DEBUGGING_INFO ! 3084: if (write_symbols == SDB_DEBUG) ! 3085: sdbout_types (NULL_TREE); ! 3086: #endif ! 3087: ! 3088: /* Put back the tree of subblocks and list of arguments ! 3089: from before we copied them. ! 3090: Code generation and the output of debugging info may have modified ! 3091: the copy, but the original is unchanged. */ ! 3092: ! 3093: if (saved_block_tree != 0) ! 3094: DECL_INITIAL (decl) = saved_block_tree; ! 3095: if (saved_arguments != 0) ! 3096: DECL_ARGUMENTS (decl) = saved_arguments; ! 3097: ! 3098: reload_completed = 0; ! 3099: ! 3100: /* Clear out the real_constant_chain before some of the rtx's ! 3101: it runs through become garbage. */ ! 3102: ! 3103: clear_const_double_mem (); ! 3104: ! 3105: /* Cancel the effect of rtl_in_current_obstack. */ ! 3106: ! 3107: resume_temporary_allocation (); ! 3108: ! 3109: /* The parsing time is all the time spent in yyparse ! 3110: *except* what is spent in this function. */ ! 3111: ! 3112: parse_time -= get_run_time () - start_time; ! 3113: } ! 3114: ! 3115: /* Entry point of cc1/c++. Decode command args, then call compile_file. ! 3116: Exit code is 35 if can't open files, 34 if fatal error, ! 3117: 33 if had nonfatal errors, else success. */ ! 3118: ! 3119: int ! 3120: main (argc, argv, envp) ! 3121: int argc; ! 3122: char **argv; ! 3123: char **envp; ! 3124: { ! 3125: register int i; ! 3126: char *filename = 0; ! 3127: int flag_print_mem = 0; ! 3128: int version_flag = 0; ! 3129: char *p; ! 3130: ! 3131: /* save in case md file wants to emit args as a comment. */ ! 3132: save_argc = argc; ! 3133: save_argv = argv; ! 3134: ! 3135: p = argv[0] + strlen (argv[0]); ! 3136: while (p != argv[0] && p[-1] != '/') --p; ! 3137: progname = p; ! 3138: ! 3139: #ifdef RLIMIT_STACK ! 3140: /* Get rid of any avoidable limit on stack size. */ ! 3141: if (getenv ("DEBUGING_GCC") == 0) ! 3142: { ! 3143: struct rlimit rlim; ! 3144: ! 3145: /* Set the stack limit huge so that alloca does not fail. */ ! 3146: getrlimit (RLIMIT_STACK, &rlim); ! 3147: rlim.rlim_cur = rlim.rlim_max; ! 3148: setrlimit (RLIMIT_STACK, &rlim); ! 3149: } ! 3150: #endif /* RLIMIT_STACK */ ! 3151: ! 3152: signal (SIGFPE, float_signal); ! 3153: ! 3154: #ifdef SIGPIPE ! 3155: signal (SIGPIPE, pipe_closed); ! 3156: #endif ! 3157: ! 3158: decl_printable_name = decl_name; ! 3159: lang_expand_expr = (struct rtx_def *(*)()) do_abort; ! 3160: ! 3161: /* Initialize whether `char' is signed. */ ! 3162: flag_signed_char = DEFAULT_SIGNED_CHAR; ! 3163: #ifdef DEFAULT_SHORT_ENUMS ! 3164: /* Initialize how much space enums occupy, by default. */ ! 3165: flag_short_enums = DEFAULT_SHORT_ENUMS; ! 3166: #endif ! 3167: ! 3168: /* Scan to see what optimization level has been specified. That will ! 3169: determine the default value of many flags. */ ! 3170: for (i = 1; i < argc; i++) ! 3171: { ! 3172: if (!strcmp (argv[i], "-O")) ! 3173: { ! 3174: optimize = 1; ! 3175: } ! 3176: else if (argv[i][0] == '-' && argv[i][1] == 'O') ! 3177: { ! 3178: /* Handle -O2, -O3, -O69, ... */ ! 3179: char *p = &argv[i][2]; ! 3180: int c; ! 3181: ! 3182: while (c = *p++) ! 3183: if (! (c >= '0' && c <= '9')) ! 3184: break; ! 3185: if (c == 0) ! 3186: optimize = atoi (&argv[i][2]); ! 3187: } ! 3188: } ! 3189: ! 3190: obey_regdecls = (optimize == 0); ! 3191: if (optimize == 0) ! 3192: { ! 3193: flag_no_inline = 1; ! 3194: warn_inline = 0; ! 3195: } ! 3196: ! 3197: if (optimize >= 1) ! 3198: { ! 3199: flag_defer_pop = 1; ! 3200: flag_thread_jumps = 1; ! 3201: #ifdef DELAY_SLOTS ! 3202: flag_delayed_branch = 1; ! 3203: #endif ! 3204: } ! 3205: ! 3206: if (optimize >= 2) ! 3207: { ! 3208: flag_cse_follow_jumps = 1; ! 3209: flag_cse_skip_blocks = 1; ! 3210: flag_expensive_optimizations = 1; ! 3211: flag_strength_reduce = 1; ! 3212: flag_rerun_cse_after_loop = 1; ! 3213: flag_caller_saves = 1; ! 3214: #ifdef INSN_SCHEDULING ! 3215: flag_schedule_insns = 1; ! 3216: flag_schedule_insns_after_reload = 1; ! 3217: #endif ! 3218: } ! 3219: ! 3220: #ifdef OPTIMIZATION_OPTIONS ! 3221: /* Allow default optimizations to be specified on a per-machine basis. */ ! 3222: OPTIMIZATION_OPTIONS (optimize); ! 3223: #endif ! 3224: ! 3225: /* Initialize register usage now so switches may override. */ ! 3226: init_reg_sets (); ! 3227: ! 3228: target_flags = 0; ! 3229: set_target_switch (""); ! 3230: ! 3231: for (i = 1; i < argc; i++) ! 3232: { ! 3233: int j; ! 3234: /* If this is a language-specific option, ! 3235: decode it in a language-specific way. */ ! 3236: for (j = 0; lang_options[j] != 0; j++) ! 3237: if (!strncmp (argv[i], lang_options[j], ! 3238: strlen (lang_options[j]))) ! 3239: break; ! 3240: if (lang_options[j] != 0) ! 3241: /* If the option is valid for *some* language, ! 3242: treat it as valid even if this language doesn't understand it. */ ! 3243: lang_decode_option (argv[i]); ! 3244: else if (argv[i][0] == '-' && argv[i][1] != 0) ! 3245: { ! 3246: register char *str = argv[i] + 1; ! 3247: if (str[0] == 'Y') ! 3248: str++; ! 3249: ! 3250: if (str[0] == 'm') ! 3251: set_target_switch (&str[1]); ! 3252: else if (!strcmp (str, "dumpbase")) ! 3253: { ! 3254: dump_base_name = argv[++i]; ! 3255: } ! 3256: else if (str[0] == 'd') ! 3257: { ! 3258: register char *p = &str[1]; ! 3259: while (*p) ! 3260: switch (*p++) ! 3261: { ! 3262: case 'a': ! 3263: combine_dump = 1; ! 3264: dbr_sched_dump = 1; ! 3265: flow_dump = 1; ! 3266: global_reg_dump = 1; ! 3267: jump_opt_dump = 1; ! 3268: jump2_opt_dump = 1; ! 3269: fppc_dump = 1; ! 3270: local_reg_dump = 1; ! 3271: loop_dump = 1; ! 3272: rtl_dump = 1; ! 3273: cse_dump = 1, cse2_dump = 1; ! 3274: sched_dump = 1; ! 3275: sched2_dump = 1; ! 3276: stack_reg_dump = 1; ! 3277: break; ! 3278: case 'k': ! 3279: stack_reg_dump = 1; ! 3280: break; ! 3281: case 'c': ! 3282: combine_dump = 1; ! 3283: break; ! 3284: case 'd': ! 3285: dbr_sched_dump = 1; ! 3286: break; ! 3287: case 'f': ! 3288: flow_dump = 1; ! 3289: break; ! 3290: case 'g': ! 3291: global_reg_dump = 1; ! 3292: break; ! 3293: case 'j': ! 3294: jump_opt_dump = 1; ! 3295: break; ! 3296: case 'J': ! 3297: jump2_opt_dump = 1; ! 3298: break; ! 3299: case 'l': ! 3300: local_reg_dump = 1; ! 3301: break; ! 3302: case 'L': ! 3303: loop_dump = 1; ! 3304: break; ! 3305: case 'm': ! 3306: flag_print_mem = 1; ! 3307: break; ! 3308: case 'p': ! 3309: flag_print_asm_name = 1; ! 3310: break; ! 3311: case 'r': ! 3312: rtl_dump = 1; ! 3313: break; ! 3314: case 's': ! 3315: cse_dump = 1; ! 3316: break; ! 3317: case 't': ! 3318: cse2_dump = 1; ! 3319: break; ! 3320: case 'S': ! 3321: sched_dump = 1; ! 3322: break; ! 3323: case 'R': ! 3324: sched2_dump = 1; ! 3325: break; ! 3326: case 'y': ! 3327: set_yydebug (1); ! 3328: break; ! 3329: case 'F': ! 3330: fppc_dump = 1; ! 3331: break; ! 3332: ! 3333: case 'x': ! 3334: rtl_dump_and_exit = 1; ! 3335: break; ! 3336: } ! 3337: } ! 3338: else if (str[0] == 'f') ! 3339: { ! 3340: register char *p = &str[1]; ! 3341: int found = 0; ! 3342: ! 3343: /* Some kind of -f option. ! 3344: P's value is the option sans `-f'. ! 3345: Search for it in the table of options. */ ! 3346: ! 3347: for (j = 0; ! 3348: !found && j < sizeof (f_options) / sizeof (f_options[0]); ! 3349: j++) ! 3350: { ! 3351: if (!strcmp (p, f_options[j].string)) ! 3352: { ! 3353: *f_options[j].variable = f_options[j].on_value; ! 3354: /* A goto here would be cleaner, ! 3355: but breaks the vax pcc. */ ! 3356: found = 1; ! 3357: } ! 3358: if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' ! 3359: && ! strcmp (p+3, f_options[j].string)) ! 3360: { ! 3361: *f_options[j].variable = ! f_options[j].on_value; ! 3362: found = 1; ! 3363: } ! 3364: } ! 3365: ! 3366: if (found) ! 3367: ; ! 3368: else if (!strncmp (p, "fixed-", 6)) ! 3369: fix_register (&p[6], 1, 1); ! 3370: else if (!strncmp (p, "call-used-", 10)) ! 3371: fix_register (&p[10], 0, 1); ! 3372: else if (!strncmp (p, "call-saved-", 11)) ! 3373: fix_register (&p[11], 0, 0); ! 3374: #ifdef NEXT_FAT_OUTPUT ! 3375: else if (!strncmp (p, "orce_cpusubtype_ALL", 19)) ! 3376: ; ! 3377: #endif ! 3378: else ! 3379: error ("Invalid option `%s'", argv[i]); ! 3380: } ! 3381: else if (str[0] == 'O') ! 3382: { ! 3383: register char *p = str+1; ! 3384: while (*p && *p >= '0' && *p <= '9') ! 3385: p++; ! 3386: if (*p == '\0') ! 3387: ; ! 3388: else ! 3389: error ("Invalid option `%s'", argv[i]); ! 3390: } ! 3391: else if (!strcmp (str, "pedantic")) ! 3392: pedantic = 1; ! 3393: else if (!strcmp (str, "pedantic-errors")) ! 3394: flag_pedantic_errors = pedantic = 1; ! 3395: #ifdef NEXT_FAT_OUTPUT ! 3396: else if (!strcmp (str, "arch")) ! 3397: { ! 3398: if (i + 1 < argc) ! 3399: architecture = argv[++i]; ! 3400: else ! 3401: error ("Missing argument to -arch"); ! 3402: } ! 3403: else if (!strcmp (str, "arch_multiple")) ! 3404: multi_arch_flag = 1; ! 3405: #endif /* NEXT_FAT_OUTPUT */ ! 3406: else if (!strcmp (str, "quiet")) ! 3407: quiet_flag = 1; ! 3408: else if (!strcmp (str, "version")) ! 3409: version_flag = 1; ! 3410: else if (!strcmp (str, "w")) ! 3411: inhibit_warnings = 1; ! 3412: else if (!strcmp (str, "W")) ! 3413: { ! 3414: extra_warnings = 1; ! 3415: /* We save the value of warn_uninitialized, since if they put ! 3416: -Wuninitialized on the command line, we need to generate a ! 3417: warning about not using it without also specifying -O. */ ! 3418: if (warn_uninitialized != 1) ! 3419: warn_uninitialized = 2; ! 3420: } ! 3421: else if (str[0] == 'W') ! 3422: { ! 3423: register char *p = &str[1]; ! 3424: int found = 0; ! 3425: ! 3426: /* Some kind of -W option. ! 3427: P's value is the option sans `-W'. ! 3428: Search for it in the table of options. */ ! 3429: ! 3430: for (j = 0; ! 3431: !found && j < sizeof (W_options) / sizeof (W_options[0]); ! 3432: j++) ! 3433: { ! 3434: if (!strcmp (p, W_options[j].string)) ! 3435: { ! 3436: if (W_options[j].variable) ! 3437: *W_options[j].variable = W_options[j].on_value; ! 3438: /* A goto here would be cleaner, ! 3439: but breaks the vax pcc. */ ! 3440: found = 1; ! 3441: } ! 3442: if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' ! 3443: && ! strcmp (p+3, W_options[j].string)) ! 3444: { ! 3445: if (W_options[j].variable) ! 3446: *W_options[j].variable = ! W_options[j].on_value; ! 3447: found = 1; ! 3448: } ! 3449: } ! 3450: ! 3451: if (found) ! 3452: ; ! 3453: else if (!strncmp (p, "id-clash-", 9)) ! 3454: { ! 3455: char *endp = p + 9; ! 3456: ! 3457: while (*endp) ! 3458: { ! 3459: if (*endp >= '0' && *endp <= '9') ! 3460: endp++; ! 3461: else ! 3462: { ! 3463: error ("Invalid option `%s'", argv[i]); ! 3464: goto id_clash_lose; ! 3465: } ! 3466: } ! 3467: warn_id_clash = 1; ! 3468: id_clash_len = atoi (str + 10); ! 3469: id_clash_lose: ; ! 3470: } ! 3471: else ! 3472: error ("Invalid option `%s'", argv[i]); ! 3473: } ! 3474: else if (!strcmp (str, "p")) ! 3475: { ! 3476: if (!output_bytecode) ! 3477: profile_flag = 1; ! 3478: else ! 3479: error ("profiling not supported in bytecode compilation"); ! 3480: } ! 3481: else if (!strcmp (str, "a")) ! 3482: { ! 3483: #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER) ! 3484: warning ("`-a' option (basic block profile) not supported"); ! 3485: #else ! 3486: profile_block_flag = 1; ! 3487: #endif ! 3488: } ! 3489: else if (str[0] == 'g') ! 3490: { ! 3491: char *p = str + 1; ! 3492: char *q; ! 3493: unsigned len; ! 3494: unsigned level; ! 3495: ! 3496: while (*p && (*p < '0' || *p > '9')) ! 3497: p++; ! 3498: len = p - str; ! 3499: q = p; ! 3500: while (*q && (*q >= '0' && *q <= '9')) ! 3501: q++; ! 3502: if (*p) ! 3503: level = atoi (p); ! 3504: else ! 3505: level = 2; /* default debugging info level */ ! 3506: if (*q || level > 3) ! 3507: { ! 3508: warning ("invalid debug level specification in option: `-%s'", ! 3509: str); ! 3510: warning ("no debugging information will be generated"); ! 3511: level = 0; ! 3512: } ! 3513: ! 3514: /* If more than one debugging type is supported, ! 3515: you must define PREFERRED_DEBUGGING_TYPE ! 3516: to choose a format in a system-dependent way. */ ! 3517: /* This is one long line cause VAXC can't handle a \-newline. */ ! 3518: #if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO)) ! 3519: #ifdef PREFERRED_DEBUGGING_TYPE ! 3520: if (!strncmp (str, "ggdb", len)) ! 3521: write_symbols = PREFERRED_DEBUGGING_TYPE; ! 3522: #else /* no PREFERRED_DEBUGGING_TYPE */ ! 3523: You Lose! You must define PREFERRED_DEBUGGING_TYPE! ! 3524: #endif /* no PREFERRED_DEBUGGING_TYPE */ ! 3525: #endif /* More than one debugger format enabled. */ ! 3526: #ifdef DBX_DEBUGGING_INFO ! 3527: if (write_symbols != NO_DEBUG) ! 3528: ; ! 3529: else if (!strncmp (str, "ggdb", len)) ! 3530: write_symbols = DBX_DEBUG; ! 3531: else if (!strncmp (str, "gstabs", len)) ! 3532: write_symbols = DBX_DEBUG; ! 3533: else if (!strncmp (str, "gstabs+", len)) ! 3534: write_symbols = DBX_DEBUG; ! 3535: ! 3536: /* Always enable extensions for -ggdb or -gstabs+, ! 3537: always disable for -gstabs. ! 3538: For plain -g, use system-specific default. */ ! 3539: if (write_symbols == DBX_DEBUG && !strncmp (str, "ggdb", len) ! 3540: && len >= 2) ! 3541: use_gnu_debug_info_extensions = 1; ! 3542: else if (write_symbols == DBX_DEBUG && !strncmp (str, "gstabs+", len) ! 3543: && len >= 7) ! 3544: use_gnu_debug_info_extensions = 1; ! 3545: else if (write_symbols == DBX_DEBUG ! 3546: && !strncmp (str, "gstabs", len) && len >= 2) ! 3547: use_gnu_debug_info_extensions = 0; ! 3548: else ! 3549: use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS; ! 3550: #endif /* DBX_DEBUGGING_INFO */ ! 3551: #ifdef DWARF_DEBUGGING_INFO ! 3552: if (write_symbols != NO_DEBUG) ! 3553: ; ! 3554: else if (!strncmp (str, "g", len)) ! 3555: write_symbols = DWARF_DEBUG; ! 3556: else if (!strncmp (str, "ggdb", len)) ! 3557: write_symbols = DWARF_DEBUG; ! 3558: else if (!strncmp (str, "gdwarf", len)) ! 3559: write_symbols = DWARF_DEBUG; ! 3560: ! 3561: /* Always enable extensions for -ggdb or -gdwarf+, ! 3562: always disable for -gdwarf. ! 3563: For plain -g, use system-specific default. */ ! 3564: if (write_symbols == DWARF_DEBUG && !strncmp (str, "ggdb", len) ! 3565: && len >= 2) ! 3566: use_gnu_debug_info_extensions = 1; ! 3567: else if (write_symbols == DWARF_DEBUG && !strcmp (str, "gdwarf+")) ! 3568: use_gnu_debug_info_extensions = 1; ! 3569: else if (write_symbols == DWARF_DEBUG ! 3570: && !strncmp (str, "gdwarf", len) && len >= 2) ! 3571: use_gnu_debug_info_extensions = 0; ! 3572: else ! 3573: use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS; ! 3574: #endif ! 3575: #ifdef SDB_DEBUGGING_INFO ! 3576: if (write_symbols != NO_DEBUG) ! 3577: ; ! 3578: else if (!strncmp (str, "g", len)) ! 3579: write_symbols = SDB_DEBUG; ! 3580: else if (!strncmp (str, "gdb", len)) ! 3581: write_symbols = SDB_DEBUG; ! 3582: else if (!strncmp (str, "gcoff", len)) ! 3583: write_symbols = SDB_DEBUG; ! 3584: #endif /* SDB_DEBUGGING_INFO */ ! 3585: #ifdef XCOFF_DEBUGGING_INFO ! 3586: if (write_symbols != NO_DEBUG) ! 3587: ; ! 3588: else if (!strncmp (str, "g", len)) ! 3589: write_symbols = XCOFF_DEBUG; ! 3590: else if (!strncmp (str, "ggdb", len)) ! 3591: write_symbols = XCOFF_DEBUG; ! 3592: else if (!strncmp (str, "gxcoff", len)) ! 3593: write_symbols = XCOFF_DEBUG; ! 3594: ! 3595: /* Always enable extensions for -ggdb or -gxcoff+, ! 3596: always disable for -gxcoff. ! 3597: For plain -g, use system-specific default. */ ! 3598: if (write_symbols == XCOFF_DEBUG && !strncmp (str, "ggdb", len) ! 3599: && len >= 2) ! 3600: use_gnu_debug_info_extensions = 1; ! 3601: else if (write_symbols == XCOFF_DEBUG && !strcmp (str, "gxcoff+")) ! 3602: use_gnu_debug_info_extensions = 1; ! 3603: else if (write_symbols == XCOFF_DEBUG ! 3604: && !strncmp (str, "gxcoff", len) && len >= 2) ! 3605: use_gnu_debug_info_extensions = 0; ! 3606: else ! 3607: use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS; ! 3608: #endif ! 3609: if (write_symbols == NO_DEBUG) ! 3610: warning ("`-%s' option not supported on this version of GCC", str); ! 3611: else if (level == 0) ! 3612: write_symbols = NO_DEBUG; ! 3613: else ! 3614: debug_info_level = (enum debug_info_level) level; ! 3615: } ! 3616: else if (!strcmp (str, "o")) ! 3617: { ! 3618: asm_file_name = argv[++i]; ! 3619: } ! 3620: else if (str[0] == 'G') ! 3621: { ! 3622: g_switch_set = TRUE; ! 3623: g_switch_value = atoi ((str[1] != '\0') ? str+1 : argv[++i]); ! 3624: } ! 3625: else if (!strncmp (str, "aux-info", 8)) ! 3626: { ! 3627: flag_gen_aux_info = 1; ! 3628: aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]); ! 3629: } ! 3630: else ! 3631: error ("Invalid option `%s'", argv[i]); ! 3632: } ! 3633: else if (argv[i][0] == '+') ! 3634: error ("Invalid option `%s'", argv[i]); ! 3635: else ! 3636: filename = argv[i]; ! 3637: } ! 3638: ! 3639: /* Initialize for bytecode output. A good idea to do this as soon as ! 3640: possible after the "-f" options have been parsed. */ ! 3641: if (output_bytecode) ! 3642: { ! 3643: #ifndef TARGET_SUPPORTS_BYTECODE ! 3644: /* Just die with a fatal error if not supported */ ! 3645: fatal ("-fbytecode can not be used for this target"); ! 3646: #else ! 3647: bc_initialize (); ! 3648: #endif ! 3649: } ! 3650: ! 3651: #ifdef NEXT_FAT_OUTPUT ! 3652: set_target_architecture (architecture); ! 3653: #endif ! 3654: ! 3655: if (optimize == 0) ! 3656: { ! 3657: /* Inlining does not work if not optimizing, ! 3658: so force it not to be done. */ ! 3659: flag_no_inline = 1; ! 3660: warn_inline = 0; ! 3661: ! 3662: /* The c_decode_option and lang_decode_option functions set ! 3663: this to `2' if -Wall is used, so we can avoid giving out ! 3664: lots of errors for people who don't realize what -Wall does. */ ! 3665: if (warn_uninitialized == 1) ! 3666: warning ("-Wuninitialized is not supported without -O"); ! 3667: } ! 3668: ! 3669: #if defined(DWARF_DEBUGGING_INFO) ! 3670: if (write_symbols == DWARF_DEBUG ! 3671: && strcmp (language_string, "GNU C++") == 0) ! 3672: { ! 3673: warning ("-g option not supported for C++ on SVR4 systems"); ! 3674: write_symbols = NO_DEBUG; ! 3675: } ! 3676: #endif /* defined(DWARF_DEBUGGING_INFO) */ ! 3677: ! 3678: #ifdef OVERRIDE_OPTIONS ! 3679: /* Some machines may reject certain combinations of options. */ ! 3680: OVERRIDE_OPTIONS; ! 3681: #endif ! 3682: ! 3683: /* Unrolling all loops implies that standard loop unrolling must also ! 3684: be done. */ ! 3685: if (flag_unroll_all_loops) ! 3686: flag_unroll_loops = 1; ! 3687: /* Loop unrolling requires that strength_reduction be on also. Silently ! 3688: turn on strength reduction here if it isn't already on. Also, the loop ! 3689: unrolling code assumes that cse will be run after loop, so that must ! 3690: be turned on also. */ ! 3691: if (flag_unroll_loops) ! 3692: { ! 3693: flag_strength_reduce = 1; ! 3694: flag_rerun_cse_after_loop = 1; ! 3695: } ! 3696: ! 3697: /* Warn about options that are not supported on this machine. */ ! 3698: #ifndef INSN_SCHEDULING ! 3699: if (flag_schedule_insns || flag_schedule_insns_after_reload) ! 3700: warning ("instruction scheduling not supported on this target machine"); ! 3701: #endif ! 3702: #ifndef DELAY_SLOTS ! 3703: if (flag_delayed_branch) ! 3704: warning ("this target machine does not have delayed branches"); ! 3705: #endif ! 3706: ! 3707: /* If we are in verbose mode, write out the version and maybe all the ! 3708: option flags in use. */ ! 3709: if (version_flag) ! 3710: { ! 3711: fprintf (stderr, "%s version %s", language_string, version_string); ! 3712: #ifdef TARGET_VERSION ! 3713: TARGET_VERSION; ! 3714: #endif ! 3715: #ifdef __GNUC__ ! 3716: #ifndef __VERSION__ ! 3717: #define __VERSION__ "[unknown]" ! 3718: #endif ! 3719: fprintf (stderr, " compiled by GNU C version %s.\n", __VERSION__); ! 3720: #else ! 3721: fprintf (stderr, " compiled by CC.\n"); ! 3722: #endif ! 3723: if (! quiet_flag) ! 3724: print_switch_values (); ! 3725: } ! 3726: ! 3727: /* Now that register usage is specified, convert it to HARD_REG_SETs. */ ! 3728: if (!output_bytecode) ! 3729: init_reg_sets_1 (); ! 3730: ! 3731: compile_file (filename); ! 3732: ! 3733: if (output_bytecode) ! 3734: bc_write_file (stdout); ! 3735: ! 3736: #ifndef OS2 ! 3737: #ifndef VMS ! 3738: if (flag_print_mem) ! 3739: { ! 3740: char *lim = (char *) sbrk (0); ! 3741: ! 3742: fprintf (stderr, "Data size %d.\n", ! 3743: lim - (char *) &environ); ! 3744: fflush (stderr); ! 3745: ! 3746: #ifdef USG ! 3747: system ("ps -l 1>&2"); ! 3748: #else /* not USG */ ! 3749: system ("ps v"); ! 3750: #endif /* not USG */ ! 3751: } ! 3752: #endif /* not VMS */ ! 3753: #endif /* not OS2 */ ! 3754: ! 3755: if (errorcount) ! 3756: exit (FATAL_EXIT_CODE); ! 3757: if (sorrycount) ! 3758: exit (FATAL_EXIT_CODE); ! 3759: exit (SUCCESS_EXIT_CODE); ! 3760: return 34; ! 3761: } ! 3762: ! 3763: /* Decode -m switches. */ ! 3764: ! 3765: /* Here is a table, controlled by the tm.h file, listing each -m switch ! 3766: and which bits in `target_switches' it should set or clear. ! 3767: If VALUE is positive, it is bits to set. ! 3768: If VALUE is negative, -VALUE is bits to clear. ! 3769: (The sign bit is not used so there is no confusion.) */ ! 3770: ! 3771: struct {char *name; int value;} target_switches [] ! 3772: = TARGET_SWITCHES; ! 3773: ! 3774: /* This table is similar, but allows the switch to have a value. */ ! 3775: ! 3776: #ifdef TARGET_OPTIONS ! 3777: struct {char *prefix; char ** variable;} target_options [] ! 3778: = TARGET_OPTIONS; ! 3779: #endif ! 3780: ! 3781: /* Decode the switch -mNAME. */ ! 3782: ! 3783: void ! 3784: set_target_switch (name) ! 3785: char *name; ! 3786: { ! 3787: register int j; ! 3788: int valid = 0; ! 3789: ! 3790: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) ! 3791: if (!strcmp (target_switches[j].name, name)) ! 3792: { ! 3793: if (target_switches[j].value < 0) ! 3794: target_flags &= ~-target_switches[j].value; ! 3795: else ! 3796: target_flags |= target_switches[j].value; ! 3797: valid = 1; ! 3798: } ! 3799: ! 3800: #ifdef TARGET_OPTIONS ! 3801: if (!valid) ! 3802: for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++) ! 3803: { ! 3804: int len = strlen (target_options[j].prefix); ! 3805: if (!strncmp (target_options[j].prefix, name, len)) ! 3806: { ! 3807: *target_options[j].variable = name + len; ! 3808: valid = 1; ! 3809: } ! 3810: } ! 3811: #endif ! 3812: ! 3813: #ifdef NEXT_FAT_OUTPUT ! 3814: if (!valid && !multi_arch_flag) ! 3815: error ("Invalid option `%s'", name); ! 3816: #endif ! 3817: } ! 3818: ! 3819: #ifdef NEXT_FAT_OUTPUT ! 3820: /* Decode -arch options. */ ! 3821: ! 3822: /* This table, filled in by the tm.h file, lists the known values of the ! 3823: -arch option and their effect on `target_flags'. */ ! 3824: ! 3825: void ! 3826: set_target_architecture (name) ! 3827: char *name; ! 3828: { ! 3829: static struct { ! 3830: char *name; ! 3831: int value; ! 3832: } target_arch [] = TARGET_ARCHITECTURE; ! 3833: register int j; ! 3834: int found = 0; ! 3835: ! 3836: if (name == 0) return; ! 3837: ! 3838: for (j = 0; j < sizeof target_arch / sizeof target_arch[0]; j++) ! 3839: { ! 3840: if (!strcmp (target_arch[j].name, name)) ! 3841: { ! 3842: if (target_arch[j].value < 0) ! 3843: target_flags &= ~-target_arch[j].value; ! 3844: else ! 3845: target_flags |= target_arch[j].value; ! 3846: found = 1; ! 3847: } ! 3848: } ! 3849: ! 3850: if (!found) ! 3851: warning ("-arch `%s' not understood", name); ! 3852: } ! 3853: #endif /* NEXT_FAT_OUTPUT */ ! 3854: ! 3855: /* Variable used for communication between the following two routines. */ ! 3856: ! 3857: static int line_position; ! 3858: ! 3859: /* Print an option value and adjust the position in the line. */ ! 3860: ! 3861: static void ! 3862: print_single_switch (type, name) ! 3863: char *type, *name; ! 3864: { ! 3865: fprintf (stderr, " %s%s", type, name); ! 3866: ! 3867: line_position += strlen (type) + strlen (name) + 1; ! 3868: ! 3869: if (line_position > 65) ! 3870: { ! 3871: fprintf (stderr, "\n\t"); ! 3872: line_position = 8; ! 3873: } ! 3874: } ! 3875: ! 3876: /* Print default target switches for -version. */ ! 3877: ! 3878: static void ! 3879: print_switch_values () ! 3880: { ! 3881: register int j; ! 3882: ! 3883: fprintf (stderr, "enabled:"); ! 3884: line_position = 8; ! 3885: ! 3886: for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++) ! 3887: if (*f_options[j].variable == f_options[j].on_value) ! 3888: print_single_switch ("-f", f_options[j].string); ! 3889: ! 3890: for (j = 0; j < sizeof W_options / sizeof W_options[0]; j++) ! 3891: if (W_options[j].variable ! 3892: && *W_options[j].variable == W_options[j].on_value) ! 3893: print_single_switch ("-W", W_options[j].string); ! 3894: ! 3895: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) ! 3896: if (target_switches[j].name[0] != '\0' ! 3897: && target_switches[j].value > 0 ! 3898: && ((target_switches[j].value & target_flags) ! 3899: == target_switches[j].value)) ! 3900: print_single_switch ("-m", target_switches[j].name); ! 3901: ! 3902: fprintf (stderr, "\n"); ! 3903: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.