toplev.c revision 72566
118334Speter/* Top level of GNU C compiler 272566Sobrien Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 372566Sobrien 1999, 2000, 2001 Free Software Foundation, Inc. 418334Speter 518334SpeterThis file is part of GNU CC. 618334Speter 718334SpeterGNU CC is free software; you can redistribute it and/or modify 818334Speterit under the terms of the GNU General Public License as published by 918334Speterthe Free Software Foundation; either version 2, or (at your option) 1018334Speterany later version. 1118334Speter 1218334SpeterGNU CC is distributed in the hope that it will be useful, 1318334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1418334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1518334SpeterGNU General Public License for more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1818334Speteralong with GNU CC; see the file COPYING. If not, write to 1918334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 2018334SpeterBoston, MA 02111-1307, USA. */ 2118334Speter 2252558Sobrien/* $FreeBSD: head/contrib/gcc/toplev.c 72566 2001-02-17 09:06:31Z obrien $ */ 2352558Sobrien 2418334Speter/* This is the top level of cc1/c++. 2518334Speter It parses command args, opens files, invokes the various passes 2618334Speter in the proper order, and counts the time used by each. 2718334Speter Error messages and low-level interface to malloc also handled here. */ 2818334Speter 2918334Speter#include "config.h" 3050615Sobrien#undef FLOAT /* This is for hpux. They should change hpux. */ 3150615Sobrien#undef FFS /* Some systems define this in param.h. */ 3250615Sobrien#include "system.h" 3318334Speter#include <signal.h> 3418334Speter#include <setjmp.h> 3518334Speter 3650615Sobrien#ifdef HAVE_SYS_RESOURCE_H 3750615Sobrien# include <sys/resource.h> 3818334Speter#endif 3950615Sobrien 4050615Sobrien#ifdef HAVE_SYS_TIMES_H 4150615Sobrien# include <sys/times.h> 4218334Speter#endif 4318334Speter 4418334Speter#include "input.h" 4518334Speter#include "tree.h" 4618334Speter#include "rtl.h" 4718334Speter#include "flags.h" 4818334Speter#include "insn-attr.h" 4950615Sobrien#include "insn-codes.h" 5050615Sobrien#include "insn-config.h" 5150615Sobrien#include "recog.h" 5218334Speter#include "defaults.h" 5318334Speter#include "output.h" 5450615Sobrien#include "except.h" 5550615Sobrien#include "toplev.h" 5652558Sobrien#include "expr.h" 5752558Sobrien#include "basic-block.h" 5852558Sobrien#include "intl.h" 5918334Speter 6050615Sobrien#ifdef DWARF_DEBUGGING_INFO 6150615Sobrien#include "dwarfout.h" 6250615Sobrien#endif 6350615Sobrien 6450615Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) 6550615Sobrien#include "dwarf2out.h" 6650615Sobrien#endif 6750615Sobrien 6850615Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) 6950615Sobrien#include "dbxout.h" 7050615Sobrien#endif 7150615Sobrien 7250615Sobrien#ifdef SDB_DEBUGGING_INFO 7350615Sobrien#include "sdbout.h" 7450615Sobrien#endif 7550615Sobrien 7618334Speter#ifdef XCOFF_DEBUGGING_INFO 7718334Speter#include "xcoffout.h" 7818334Speter#endif 7918334Speter 8018334Speter#ifdef VMS 8118334Speter/* The extra parameters substantially improve the I/O performance. */ 8218334Speterstatic FILE * 8318334Spetervms_fopen (fname, type) 8418334Speter char * fname; 8518334Speter char * type; 8618334Speter{ 8718334Speter /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two 8818334Speter fixed arguments, which matches ANSI's specification but not VAXCRTL's 8918334Speter pre-ANSI implementation. This hack circumvents the mismatch problem. */ 9018334Speter FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen; 9118334Speter 9218334Speter if (*type == 'w') 9318334Speter return (*vmslib_fopen) (fname, type, "mbc=32", 9418334Speter "deq=64", "fop=tef", "shr=nil"); 9518334Speter else 9618334Speter return (*vmslib_fopen) (fname, type, "mbc=32"); 9718334Speter} 9818334Speter#define fopen vms_fopen 9918334Speter#endif /* VMS */ 10018334Speter 10118334Speter#ifndef DEFAULT_GDB_EXTENSIONS 10218334Speter#define DEFAULT_GDB_EXTENSIONS 1 10318334Speter#endif 10418334Speter 10550615Sobrien/* If more than one debugging type is supported, you must define 10650615Sobrien PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way. 10750615Sobrien 10850615Sobrien This is one long line cause VAXC can't handle a \-newline. */ 10950615Sobrien#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO)) 11050615Sobrien#ifndef PREFERRED_DEBUGGING_TYPE 11150615SobrienYou Lose! You must define PREFERRED_DEBUGGING_TYPE! 11250615Sobrien#endif /* no PREFERRED_DEBUGGING_TYPE */ 11350615Sobrien#else /* Only one debugging format supported. Define PREFERRED_DEBUGGING_TYPE 11450615Sobrien so the following code needn't care. */ 11550615Sobrien#ifdef DBX_DEBUGGING_INFO 11650615Sobrien#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG 11750615Sobrien#endif 11850615Sobrien#ifdef SDB_DEBUGGING_INFO 11950615Sobrien#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG 12050615Sobrien#endif 12150615Sobrien#ifdef DWARF_DEBUGGING_INFO 12250615Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG 12350615Sobrien#endif 12450615Sobrien#ifdef DWARF2_DEBUGGING_INFO 12550615Sobrien#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG 12650615Sobrien#endif 12750615Sobrien#ifdef XCOFF_DEBUGGING_INFO 12850615Sobrien#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG 12950615Sobrien#endif 13050615Sobrien#endif /* More than one debugger format enabled. */ 13150615Sobrien 13250615Sobrien/* If still not defined, must have been because no debugging formats 13350615Sobrien are supported. */ 13450615Sobrien#ifndef PREFERRED_DEBUGGING_TYPE 13550615Sobrien#define PREFERRED_DEBUGGING_TYPE NO_DEBUG 13650615Sobrien#endif 13750615Sobrien 13852558Sobrien#ifndef DIR_SEPARATOR 13952558Sobrien#define DIR_SEPARATOR '/' 14052558Sobrien#endif 14152558Sobrien 14218334Speterextern int rtx_equal_function_value_matters; 14318334Speter 14418334Speter#if ! (defined (VMS) || defined (OS2)) 14518334Speterextern char **environ; 14618334Speter#endif 14718334Speterextern char *version_string, *language_string; 14818334Speter 14918334Speter/* Carry information from ASM_DECLARE_OBJECT_NAME 15018334Speter to ASM_FINISH_DECLARE_OBJECT. */ 15118334Speter 15218334Speterextern int size_directive_output; 15318334Speterextern tree last_assemble_variable_decl; 15418334Speter 15550615Sobrienextern char *init_parse PVPROTO((char *)); 15650615Sobrienextern void finish_parse (); 15718334Speterextern void init_decl_processing (); 15818334Speterextern void init_obstacks (); 15918334Speterextern void init_tree_codes (); 16018334Speterextern void init_rtl (); 16118334Speterextern void init_regs (); 16218334Speterextern void init_optabs (); 16318334Speterextern void init_stmt (); 16418334Speterextern void init_reg_sets (); 16518334Speterextern void dump_flow_info (); 16618334Speterextern void dump_sched_info (); 16718334Speterextern void dump_local_alloc (); 16850615Sobrienextern void regset_release_memory (); 16918334Speter 17050615Sobrienextern void print_rtl (); 17150615Sobrienextern void print_rtl_with_bb (); 17250615Sobrien 17318334Spetervoid rest_of_decl_compilation (); 17452558Sobrienvoid error_with_file_and_line PVPROTO((const char *file, 17552558Sobrien int line, const char *s, ...)); 17652558Sobrienvoid error_with_decl PVPROTO((tree decl, const char *s, ...)); 17752558Sobrienvoid error_for_asm PVPROTO((rtx insn, const char *s, ...)); 17852558Sobrienvoid notice PVPROTO((const char *s, ...)); 17952558Sobrienvoid error PVPROTO((const char *s, ...)); 18052558Sobrienvoid fatal PVPROTO((const char *s, ...)); 18152558Sobrienvoid warning_with_file_and_line PVPROTO((const char *file, 18252558Sobrien int line, const char *s, ...)); 18352558Sobrienvoid warning_with_decl PVPROTO((tree decl, const char *s, ...)); 18452558Sobrienvoid warning PVPROTO((const char *s, ...)); 18552558Sobrienvoid pedwarn PVPROTO((const char *s, ...)); 18652558Sobrienvoid pedwarn_with_decl PVPROTO((tree decl, const char *s, ...)); 18752558Sobrienvoid pedwarn_with_file_and_line PVPROTO((const char *file, 18852558Sobrien int line, const char *s, ...)); 18952558Sobrienvoid sorry PVPROTO((const char *s, ...)); 19052558Sobrienstatic void set_target_switch PROTO((const char *)); 19150615Sobrienstatic char *decl_name PROTO((tree, int)); 19252558Sobrienstatic void vmessage PROTO((const char *, const char *, va_list)); 19352558Sobrienstatic void v_message_with_file_and_line PROTO((const char *, int, int, 19452558Sobrien const char *, va_list)); 19552558Sobrienstatic void v_message_with_decl PROTO((tree, int, const char *, va_list)); 19650615Sobrienstatic void file_and_line_for_asm PROTO((rtx, char **, int *)); 19752558Sobrienstatic void v_error_with_file_and_line PROTO((const char *, int, 19852558Sobrien const char *, va_list)); 19952558Sobrienstatic void v_error_with_decl PROTO((tree, const char *, va_list)); 20052558Sobrienstatic void v_error_for_asm PROTO((rtx, const char *, va_list)); 20152558Sobrienstatic void verror PROTO((const char *, va_list)); 20252558Sobrienstatic void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN; 20352558Sobrienstatic void v_warning_with_file_and_line PROTO ((const char *, int, 20452558Sobrien const char *, va_list)); 20552558Sobrienstatic void v_warning_with_decl PROTO((tree, const char *, va_list)); 20652558Sobrienstatic void v_warning_for_asm PROTO((rtx, const char *, va_list)); 20752558Sobrienstatic void vwarning PROTO((const char *, va_list)); 20852558Sobrienstatic void vpedwarn PROTO((const char *, va_list)); 20952558Sobrienstatic void v_pedwarn_with_decl PROTO((tree, const char *, va_list)); 21052558Sobrienstatic void v_pedwarn_with_file_and_line PROTO((const char *, int, 21152558Sobrien const char *, va_list)); 21252558Sobrienstatic void vsorry PROTO((const char *, va_list)); 21352558Sobrienstatic void float_signal PROTO((int)) ATTRIBUTE_NORETURN; 21452558Sobrienstatic void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN; 21552558Sobrien#ifdef ASM_IDENTIFY_LANGUAGE 21652558Sobrien/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */ 21752558Sobrienstatic void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED; 21852558Sobrien#endif 21952558Sobrienstatic void open_dump_file PROTO((const char *, const char *)); 22050615Sobrienstatic void close_dump_file PROTO((void (*) (FILE *, rtx), rtx)); 22152558Sobrienstatic void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx)); 22252558Sobrienstatic void clean_dump_file PROTO((const char *)); 22350615Sobrienstatic void compile_file PROTO((char *)); 22450615Sobrienstatic void display_help PROTO ((void)); 22518334Speter 22652558Sobrienstatic void print_version PROTO((FILE *, const char *)); 22752558Sobrienstatic int print_single_switch PROTO((FILE *, int, int, const char *, 22852558Sobrien const char *, const char *, 22952558Sobrien const char *, const char *)); 23052558Sobrienstatic void print_switch_values PROTO((FILE *, int, int, const char *, 23152558Sobrien const char *, const char *)); 23252558Sobrien 23352558Sobrienvoid print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx)); 23452558Sobrienvoid clean_graph_dump_file PROTO ((const char *, const char *)); 23552558Sobrienvoid finish_graph_dump_file PROTO ((const char *, const char *)); 23650615Sobrien/* Length of line when printing switch values. */ 23750615Sobrien#define MAX_LINE 75 23818334Speter 23918334Speter/* Name of program invoked, sans directories. */ 24018334Speter 24118334Speterchar *progname; 24218334Speter 24318334Speter/* Copy of arguments to main. */ 24418334Speterint save_argc; 24518334Speterchar **save_argv; 24618334Speter 24718334Speter/* Name of current original source file (what was input to cpp). 24818334Speter This comes from each #-command in the actual input. */ 24918334Speter 25018334Speterchar *input_filename; 25118334Speter 25218334Speter/* Name of top-level original source file (what was input to cpp). 25318334Speter This comes from the #-command at the beginning of the actual input. 25418334Speter If there isn't any there, then this is the cc1 input file name. */ 25518334Speter 25618334Speterchar *main_input_filename; 25718334Speter 25818334Speter/* Current line number in real source file. */ 25918334Speter 26018334Speterint lineno; 26118334Speter 26252558Sobrien/* Nonzero if it is unsafe to create any new pseudo registers. */ 26352558Sobrienint no_new_pseudos; 26452558Sobrien 26518334Speter/* Stack of currently pending input files. */ 26618334Speter 26718334Speterstruct file_stack *input_file_stack; 26818334Speter 26918334Speter/* Incremented on each change to input_file_stack. */ 27018334Speterint input_file_stack_tick; 27118334Speter 27218334Speter/* FUNCTION_DECL for function now being parsed or compiled. */ 27318334Speter 27418334Speterextern tree current_function_decl; 27518334Speter 27618334Speter/* Name to use as base of names for dump output files. */ 27718334Speter 27852558Sobrienconst char *dump_base_name; 27918334Speter 28018334Speter/* Bit flags that specify the machine subtype we are compiling for. 28118334Speter Bits are tested using macros TARGET_... defined in the tm.h file 28218334Speter and set by `-m...' switches. Must be defined in rtlanal.c. */ 28318334Speter 28418334Speterextern int target_flags; 28518334Speter 28618334Speter/* Flags saying which kinds of debugging dump have been requested. */ 28718334Speter 28818334Speterint rtl_dump = 0; 28918334Speterint rtl_dump_and_exit = 0; 29018334Speterint jump_opt_dump = 0; 29150615Sobrienint addressof_dump = 0; 29218334Speterint cse_dump = 0; 29350615Sobrienint gcse_dump = 0; 29418334Speterint loop_dump = 0; 29518334Speterint cse2_dump = 0; 29650615Sobrienint branch_prob_dump = 0; 29718334Speterint flow_dump = 0; 29818334Speterint combine_dump = 0; 29950615Sobrienint regmove_dump = 0; 30018334Speterint sched_dump = 0; 30118334Speterint local_reg_dump = 0; 30218334Speterint global_reg_dump = 0; 30352558Sobrienint flow2_dump = 0; 30418334Speterint sched2_dump = 0; 30518334Speterint jump2_opt_dump = 0; 30650615Sobrien#ifdef DELAY_SLOTS 30718334Speterint dbr_sched_dump = 0; 30850615Sobrien#endif 30918334Speterint flag_print_asm_name = 0; 31050615Sobrien#ifdef STACK_REGS 31118334Speterint stack_reg_dump = 0; 31250615Sobrien#endif 31350615Sobrien#ifdef MACHINE_DEPENDENT_REORG 31450615Sobrienint mach_dep_reorg_dump = 0; 31550615Sobrien#endif 31652558Sobrienenum graph_dump_types graph_dump_format; 31718334Speter 31818334Speter/* Name for output file of assembly code, specified with -o. */ 31918334Speter 32018334Speterchar *asm_file_name; 32118334Speter 32218334Speter/* Value of the -G xx switch, and whether it was passed or not. */ 32318334Speterint g_switch_value; 32418334Speterint g_switch_set; 32518334Speter 32618334Speter/* Type(s) of debugging information we are producing (if any). 32718334Speter See flags.h for the definitions of the different possible 32818334Speter types of debugging information. */ 32918334Speterenum debug_info_type write_symbols = NO_DEBUG; 33018334Speter 33118334Speter/* Level of debugging information we are producing. See flags.h 33218334Speter for the definitions of the different possible levels. */ 33318334Speterenum debug_info_level debug_info_level = DINFO_LEVEL_NONE; 33418334Speter 33518334Speter/* Nonzero means use GNU-only extensions in the generated symbolic 33618334Speter debugging information. */ 33718334Speter/* Currently, this only has an effect when write_symbols is set to 33818334Speter DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ 33918334Speterint use_gnu_debug_info_extensions = 0; 34018334Speter 34118334Speter/* Nonzero means do optimizations. -O. 34218334Speter Particular numeric values stand for particular amounts of optimization; 34318334Speter thus, -O2 stores 2 here. However, the optimizations beyond the basic 34418334Speter ones are not controlled directly by this variable. Instead, they are 34518334Speter controlled by individual `flag_...' variables that are defaulted 34618334Speter based on this variable. */ 34718334Speter 34818334Speterint optimize = 0; 34918334Speter 35050615Sobrien/* Nonzero means optimize for size. -Os. 35150615Sobrien The only valid values are zero and non-zero. When optimize_size is 35250615Sobrien non-zero, optimize defaults to 2, but certain individual code 35350615Sobrien bloating optimizations are disabled. */ 35450615Sobrien 35550615Sobrienint optimize_size = 0; 35650615Sobrien 35718334Speter/* Number of error messages and warning messages so far. */ 35818334Speter 35918334Speterint errorcount = 0; 36018334Speterint warningcount = 0; 36118334Speterint sorrycount = 0; 36218334Speter 36350615Sobrien/* Pointer to function to compute the name to use to print a declaration. 36450615Sobrien DECL is the declaration in question. 36550615Sobrien VERBOSITY determines what information will be printed: 36650615Sobrien 0: DECL_NAME, demangled as necessary. 36750615Sobrien 1: and scope information. 36850615Sobrien 2: and any other information that might be interesting, such as function 36950615Sobrien parameter types in C++. */ 37018334Speter 37152558Sobrienchar *(*decl_printable_name) PROTO ((tree, int)); 37218334Speter 37318334Speter/* Pointer to function to compute rtl for a language-specific tree code. */ 37418334Speter 37552558Sobrientypedef rtx (*lang_expand_expr_t) 37652558Sobrien PROTO ((union tree_node *, rtx, enum machine_mode, 37752558Sobrien enum expand_modifier modifier)); 37818334Speter 37952558Sobrienlang_expand_expr_t lang_expand_expr = 0; 38052558Sobrien 38152558Sobrientree (*lang_expand_constant) PROTO((tree)) = 0; 38252558Sobrien 38318334Speter/* Pointer to function to finish handling an incomplete decl at the 38418334Speter end of compilation. */ 38518334Speter 38652558Sobrienvoid (*incomplete_decl_finalize_hook) PROTO((tree)) = 0; 38718334Speter 38818334Speter/* Nonzero if generating code to do profiling. */ 38918334Speter 39018334Speterint profile_flag = 0; 39118334Speter 39218334Speter/* Nonzero if generating code to do profiling on a line-by-line basis. */ 39318334Speter 39418334Speterint profile_block_flag; 39518334Speter 39650615Sobrien/* Nonzero if generating code to profile program flow graph arcs. */ 39750615Sobrien 39850615Sobrienint profile_arc_flag = 0; 39950615Sobrien 40050615Sobrien/* Nonzero if generating info for gcov to calculate line test coverage. */ 40150615Sobrien 40250615Sobrienint flag_test_coverage = 0; 40350615Sobrien 40450615Sobrien/* Nonzero indicates that branch taken probabilities should be calculated. */ 40550615Sobrien 40650615Sobrienint flag_branch_probabilities = 0; 40750615Sobrien 40818334Speter/* Nonzero for -pedantic switch: warn about anything 40918334Speter that standard spec forbids. */ 41018334Speter 41118334Speterint pedantic = 0; 41218334Speter 41318334Speter/* Temporarily suppress certain warnings. 41418334Speter This is set while reading code from a system header file. */ 41518334Speter 41618334Speterint in_system_header = 0; 41718334Speter 41818334Speter/* Nonzero means do stupid register allocation. 41918334Speter Currently, this is 1 if `optimize' is 0. */ 42018334Speter 42118334Speterint obey_regdecls = 0; 42218334Speter 42318334Speter/* Don't print functions as they are compiled and don't print 42418334Speter times taken by the various passes. -quiet. */ 42518334Speter 42618334Speterint quiet_flag = 0; 42718334Speter 42818334Speter/* -f flags. */ 42918334Speter 43018334Speter/* Nonzero means `char' should be signed. */ 43118334Speter 43218334Speterint flag_signed_char; 43318334Speter 43418334Speter/* Nonzero means give an enum type only as many bytes as it needs. */ 43518334Speter 43618334Speterint flag_short_enums; 43718334Speter 43818334Speter/* Nonzero for -fcaller-saves: allocate values in regs that need to 43918334Speter be saved across function calls, if that produces overall better code. 44018334Speter Optional now, so people can test it. */ 44118334Speter 44218334Speter#ifdef DEFAULT_CALLER_SAVES 44318334Speterint flag_caller_saves = 1; 44418334Speter#else 44518334Speterint flag_caller_saves = 0; 44618334Speter#endif 44718334Speter 44818334Speter/* Nonzero if structures and unions should be returned in memory. 44918334Speter 45018334Speter This should only be defined if compatibility with another compiler or 45118334Speter with an ABI is needed, because it results in slower code. */ 45218334Speter 45318334Speter#ifndef DEFAULT_PCC_STRUCT_RETURN 45418334Speter#define DEFAULT_PCC_STRUCT_RETURN 1 45518334Speter#endif 45618334Speter 45718334Speter/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ 45818334Speter 45918334Speterint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; 46018334Speter 46118334Speter/* Nonzero for -fforce-mem: load memory value into a register 46218334Speter before arithmetic on it. This makes better cse but slower compilation. */ 46318334Speter 46418334Speterint flag_force_mem = 0; 46518334Speter 46618334Speter/* Nonzero for -fforce-addr: load memory address into a register before 46718334Speter reference to memory. This makes better cse but slower compilation. */ 46818334Speter 46918334Speterint flag_force_addr = 0; 47018334Speter 47118334Speter/* Nonzero for -fdefer-pop: don't pop args after each function call; 47218334Speter instead save them up to pop many calls' args with one insns. */ 47318334Speter 47418334Speterint flag_defer_pop = 0; 47518334Speter 47618334Speter/* Nonzero for -ffloat-store: don't allocate floats and doubles 47718334Speter in extended-precision registers. */ 47818334Speter 47918334Speterint flag_float_store = 0; 48018334Speter 48118334Speter/* Nonzero for -fcse-follow-jumps: 48218334Speter have cse follow jumps to do a more extensive job. */ 48318334Speter 48418334Speterint flag_cse_follow_jumps; 48518334Speter 48618334Speter/* Nonzero for -fcse-skip-blocks: 48718334Speter have cse follow a branch around a block. */ 48818334Speterint flag_cse_skip_blocks; 48918334Speter 49018334Speter/* Nonzero for -fexpensive-optimizations: 49118334Speter perform miscellaneous relatively-expensive optimizations. */ 49218334Speterint flag_expensive_optimizations; 49318334Speter 49418334Speter/* Nonzero for -fthread-jumps: 49518334Speter have jump optimize output of loop. */ 49618334Speter 49718334Speterint flag_thread_jumps; 49818334Speter 49918334Speter/* Nonzero enables strength-reduction in loop.c. */ 50018334Speter 50118334Speterint flag_strength_reduce = 0; 50218334Speter 50318334Speter/* Nonzero enables loop unrolling in unroll.c. Only loops for which the 50418334Speter number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, 50518334Speter UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are 50618334Speter unrolled. */ 50718334Speter 50818334Speterint flag_unroll_loops; 50918334Speter 51018334Speter/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. 51118334Speter This is generally not a win. */ 51218334Speter 51318334Speterint flag_unroll_all_loops; 51418334Speter 51550615Sobrien/* Nonzero forces all invariant computations in loops to be moved 51650615Sobrien outside the loop. */ 51750615Sobrien 51850615Sobrienint flag_move_all_movables = 0; 51950615Sobrien 52050615Sobrien/* Nonzero forces all general induction variables in loops to be 52150615Sobrien strength reduced. */ 52250615Sobrien 52350615Sobrienint flag_reduce_all_givs = 0; 52450615Sobrien 52550615Sobrien/* Nonzero to perform full register move optimization passes. This is the 52650615Sobrien default for -O2. */ 52750615Sobrien 52850615Sobrienint flag_regmove = 0; 52950615Sobrien 53018334Speter/* Nonzero for -fwritable-strings: 53118334Speter store string constants in data segment and don't uniquize them. */ 53218334Speter 53318334Speterint flag_writable_strings = 0; 53418334Speter 53518334Speter/* Nonzero means don't put addresses of constant functions in registers. 53618334Speter Used for compiling the Unix kernel, where strange substitutions are 53718334Speter done on the assembly output. */ 53818334Speter 53918334Speterint flag_no_function_cse = 0; 54018334Speter 54118334Speter/* Nonzero for -fomit-frame-pointer: 54218334Speter don't make a frame pointer in simple functions that don't require one. */ 54318334Speter 54418334Speterint flag_omit_frame_pointer = 0; 54518334Speter 54650615Sobrien/* Nonzero means place each function into its own section on those platforms 54750615Sobrien which support arbitrary section names and unlimited numbers of sections. */ 54850615Sobrien 54950615Sobrienint flag_function_sections = 0; 55050615Sobrien 55152558Sobrien/* ... and similar for data. */ 55252558Sobrien 55352558Sobrienint flag_data_sections = 0; 55452558Sobrien 55518334Speter/* Nonzero to inhibit use of define_optimization peephole opts. */ 55618334Speter 55718334Speterint flag_no_peephole = 0; 55818334Speter 55918334Speter/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math 56018334Speter operations in the interest of optimization. For example it allows 56118334Speter GCC to assume arguments to sqrt are nonnegative numbers, allowing 56250615Sobrien faster code for sqrt to be generated. */ 56318334Speter 56418334Speterint flag_fast_math = 0; 56518334Speter 56652558Sobrien/* Nonzero means the front end generally wants `errno' maintained by math 56752558Sobrien operations, like built-in SQRT, unless overridden by flag_fast_math. */ 56852558Sobrien 56952558Sobrienint flag_errno_math = 1; 57052558Sobrien 57152558Sobrien/* 0 means straightforward implementation of complex divide acceptable. 57252558Sobrien 1 means wide ranges of inputs must work for complex divide. 57352558Sobrien 2 means C9X-like requirements for complex divide (not yet implemented). */ 57452558Sobrien 57552558Sobrienint flag_complex_divide_method = 0; 57652558Sobrien 57718334Speter/* Nonzero means all references through pointers are volatile. */ 57818334Speter 57918334Speterint flag_volatile; 58018334Speter 58152558Sobrien/* Nonzero means treat all global and extern variables as volatile. */ 58218334Speter 58318334Speterint flag_volatile_global; 58418334Speter 58552558Sobrien/* Nonzero means treat all static variables as volatile. */ 58652558Sobrien 58752558Sobrienint flag_volatile_static; 58852558Sobrien 58918334Speter/* Nonzero means just do syntax checking; don't output anything. */ 59018334Speter 59118334Speterint flag_syntax_only = 0; 59218334Speter 59350615Sobrien/* Nonzero means perform global cse. */ 59450615Sobrien 59550615Sobrienstatic int flag_gcse; 59650615Sobrien 59718334Speter/* Nonzero means to rerun cse after loop optimization. This increases 59818334Speter compilation time about 20% and picks up a few more common expressions. */ 59918334Speter 60018334Speterstatic int flag_rerun_cse_after_loop; 60118334Speter 60250615Sobrien/* Nonzero means to run loop optimizations twice. */ 60350615Sobrien 60450615Sobrienint flag_rerun_loop_opt; 60550615Sobrien 60618334Speter/* Nonzero for -finline-functions: ok to inline functions that look like 60718334Speter good inline candidates. */ 60818334Speter 60918334Speterint flag_inline_functions; 61018334Speter 61118334Speter/* Nonzero for -fkeep-inline-functions: even if we make a function 61218334Speter go inline everywhere, keep its definition around for debugging 61318334Speter purposes. */ 61418334Speter 61518334Speterint flag_keep_inline_functions; 61618334Speter 61718334Speter/* Nonzero means that functions will not be inlined. */ 61818334Speter 61918334Speterint flag_no_inline; 62018334Speter 62150615Sobrien/* Nonzero means that we should emit static const variables 62250615Sobrien regardless of whether or not optimization is turned on. */ 62350615Sobrien 62450615Sobrienint flag_keep_static_consts = 1; 62550615Sobrien 62618334Speter/* Nonzero means we should be saving declaration info into a .X file. */ 62718334Speter 62818334Speterint flag_gen_aux_info = 0; 62918334Speter 63018334Speter/* Specified name of aux-info file. */ 63118334Speter 63218334Speterstatic char *aux_info_file_name; 63318334Speter 63418334Speter/* Nonzero means make the text shared if supported. */ 63518334Speter 63618334Speterint flag_shared_data; 63718334Speter 63818334Speter/* Nonzero means schedule into delayed branch slots if supported. */ 63918334Speter 64018334Speterint flag_delayed_branch; 64118334Speter 64218334Speter/* Nonzero if we are compiling pure (sharable) code. 64318334Speter Value is 1 if we are doing reasonable (i.e. simple 64418334Speter offset into offset table) pic. Value is 2 if we can 64518334Speter only perform register offsets. */ 64618334Speter 64718334Speterint flag_pic; 64818334Speter 64950615Sobrien/* Nonzero means generate extra code for exception handling and enable 65050615Sobrien exception handling. */ 65118334Speter 65250615Sobrienint flag_exceptions; 65350615Sobrien 65450615Sobrien/* Nonzero means use the new model for exception handling. Replaces 65550615Sobrien -DNEW_EH_MODEL as a compile option. */ 65650615Sobrien 65750615Sobrienint flag_new_exceptions = 0; 65850615Sobrien 65950615Sobrien/* Nonzero means don't place uninitialized global data in common storage 66050615Sobrien by default. */ 66150615Sobrien 66218334Speterint flag_no_common; 66318334Speter 66418334Speter/* Nonzero means pretend it is OK to examine bits of target floats, 66518334Speter even if that isn't true. The resulting code will have incorrect constants, 66618334Speter but the same series of instructions that the native compiler would make. */ 66718334Speter 66818334Speterint flag_pretend_float; 66918334Speter 67018334Speter/* Nonzero means change certain warnings into errors. 67118334Speter Usually these are warnings about failure to conform to some standard. */ 67218334Speter 67318334Speterint flag_pedantic_errors = 0; 67418334Speter 67518334Speter/* flag_schedule_insns means schedule insns within basic blocks (before 67618334Speter local_alloc). 67718334Speter flag_schedule_insns_after_reload means schedule insns after 67818334Speter global_alloc. */ 67918334Speter 68018334Speterint flag_schedule_insns = 0; 68118334Speterint flag_schedule_insns_after_reload = 0; 68218334Speter 68350615Sobrien#ifdef HAIFA 68450615Sobrien/* The following flags have effect only for scheduling before register 68550615Sobrien allocation: 68650615Sobrien 68750615Sobrien flag_schedule_interblock means schedule insns accross basic blocks. 68850615Sobrien flag_schedule_speculative means allow speculative motion of non-load insns. 68950615Sobrien flag_schedule_speculative_load means allow speculative motion of some 69050615Sobrien load insns. 69150615Sobrien flag_schedule_speculative_load_dangerous allows speculative motion of more 69250615Sobrien load insns. */ 69350615Sobrien 69450615Sobrienint flag_schedule_interblock = 1; 69550615Sobrienint flag_schedule_speculative = 1; 69650615Sobrienint flag_schedule_speculative_load = 0; 69750615Sobrienint flag_schedule_speculative_load_dangerous = 0; 69852558Sobrien#endif /* HAIFA */ 69950615Sobrien 70050615Sobrien/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple 70150615Sobrien by a cheaper branch, on a count register. */ 70250615Sobrienint flag_branch_on_count_reg; 70350615Sobrien 70418334Speter/* -finhibit-size-directive inhibits output of .size for ELF. 70518334Speter This is used only for compiling crtstuff.c, 70618334Speter and it may be extended to other effects 70718334Speter needed for crtstuff.c on other systems. */ 70818334Speterint flag_inhibit_size_directive = 0; 70918334Speter 71018334Speter/* -fverbose-asm causes extra commentary information to be produced in 71118334Speter the generated assembly code (to make it more readable). This option 71218334Speter is generally only of use to those who actually need to read the 71350615Sobrien generated assembly code (perhaps while debugging the compiler itself). 71450615Sobrien -fno-verbose-asm, the default, causes the extra information 71550615Sobrien to be omitted and is useful when comparing two assembler files. */ 71618334Speter 71718334Speterint flag_verbose_asm = 0; 71818334Speter 71950615Sobrien/* -dA causes debug commentary information to be produced in 72050615Sobrien the generated assembly code (to make it more readable). This option 72150615Sobrien is generally only of use to those who actually need to read the 72250615Sobrien generated assembly code (perhaps while debugging the compiler itself). 72350615Sobrien Currently, this switch is only used by dwarfout.c; however, it is intended 72450615Sobrien to be a catchall for printing debug information in the assembler file. */ 72550615Sobrien 72650615Sobrienint flag_debug_asm = 0; 72750615Sobrien 72818334Speter/* -fgnu-linker specifies use of the GNU linker for initializations. 72918334Speter (Or, more generally, a linker that handles initializations.) 73018334Speter -fno-gnu-linker says that collect2 will be used. */ 73118334Speter#ifdef USE_COLLECT2 73218334Speterint flag_gnu_linker = 0; 73318334Speter#else 73418334Speterint flag_gnu_linker = 1; 73518334Speter#endif 73618334Speter 73718334Speter/* Tag all structures with __attribute__(packed) */ 73818334Speterint flag_pack_struct = 0; 73918334Speter 74038510Sbde/* Nonzero means that -Wformat accepts certain system-dependent formats. */ 74138510Sbdeint flag_format_extensions = 0; 74238510Sbde 74350615Sobrien/* Emit code to check for stack overflow; also may cause large objects 74450615Sobrien to be allocated dynamically. */ 74550615Sobrienint flag_stack_check; 74650615Sobrien 74750615Sobrien/* -fcheck-memory-usage causes extra code to be generated in order to check 74850615Sobrien memory accesses. This is used by a detector of bad memory accesses such 74950615Sobrien as Checker. */ 75050615Sobrienint flag_check_memory_usage = 0; 75150615Sobrien 75250615Sobrien/* -fprefix-function-name causes function name to be prefixed. This 75350615Sobrien can be used with -fcheck-memory-usage to isolate code compiled with 75450615Sobrien -fcheck-memory-usage. */ 75550615Sobrienint flag_prefix_function_name = 0; 75650615Sobrien 75750615Sobrien/* 0 if pointer arguments may alias each other. True in C. 75850615Sobrien 1 if pointer arguments may not alias each other but may alias 75950615Sobrien global variables. 76050615Sobrien 2 if pointer arguments may not alias each other and may not 76150615Sobrien alias global variables. True in Fortran. 76250615Sobrien This defaults to 0 for C. */ 76350615Sobrienint flag_argument_noalias = 0; 76450615Sobrien 76550615Sobrien/* Nonzero if we should do (language-dependent) alias analysis. 76650615Sobrien Typically, this analysis will assume that expressions of certain 76750615Sobrien types do not alias expressions of certain other types. Only used 76850615Sobrien if alias analysis (in general) is enabled. */ 76950615Sobrienint flag_strict_aliasing = 0; 77050615Sobrien 77152558Sobrien/* Instrument functions with calls at entry and exit, for profiling. */ 77252558Sobrienint flag_instrument_function_entry_exit = 0; 77350615Sobrien 77452558Sobrien/* Nonzero means ignore `#ident' directives. 0 means handle them. 77552558Sobrien On SVR4 targets, it also controls whether or not to emit a 77652558Sobrien string identifying the compiler. */ 77750615Sobrien 77852558Sobrienint flag_no_ident = 0; 77952558Sobrien 78050615Sobrien/* Table of supported debugging formats. */ 78150615Sobrienstatic struct 78250615Sobrien{ 78352558Sobrien const char * arg; 78450615Sobrien /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a 78550615Sobrien constant expression, we use NO_DEBUG in its place. */ 78650615Sobrien enum debug_info_type debug_type; 78750615Sobrien int use_extensions_p; 78852558Sobrien const char * description; 78950615Sobrien} *da, 79050615Sobriendebug_args[] = 79150615Sobrien{ 79250615Sobrien { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS, 79350615Sobrien "Generate default debug format output" }, 79450615Sobrien { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" }, 79550615Sobrien#ifdef DBX_DEBUGGING_INFO 79650615Sobrien { "gstabs", DBX_DEBUG, 0, "Generate STABS format debug output" }, 79750615Sobrien { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" }, 79850615Sobrien#endif 79950615Sobrien#ifdef DWARF_DEBUGGING_INFO 80050615Sobrien { "gdwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"}, 80150615Sobrien { "gdwarf+", DWARF_DEBUG, 1, 80250615Sobrien "Generated extended DWARF-1 format debug output" }, 80350615Sobrien#endif 80450615Sobrien#ifdef DWARF2_DEBUGGING_INFO 80550615Sobrien { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" }, 80650615Sobrien#endif 80750615Sobrien#ifdef XCOFF_DEBUGGING_INFO 80850615Sobrien { "gxcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" }, 80950615Sobrien { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" }, 81050615Sobrien#endif 81150615Sobrien#ifdef SDB_DEBUGGING_INFO 81250615Sobrien { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" }, 81350615Sobrien#endif 81452558Sobrien { 0, 0, 0, 0 } 81550615Sobrien}; 81650615Sobrien 81750615Sobrientypedef struct 81850615Sobrien{ 81952558Sobrien const char * string; 82050615Sobrien int * variable; 82150615Sobrien int on_value; 82252558Sobrien const char * description; 82350615Sobrien} 82450615Sobrienlang_independent_options; 82550615Sobrien 82652558Sobrien/* Add or remove a leading underscore from user symbols. */ 82752558Sobrienint flag_leading_underscore = -1; 82852558Sobrien 82952558Sobrien/* The user symbol prefix after having resolved same. */ 83052558Sobrienconst char *user_label_prefix; 83152558Sobrien 83252558Sobrien/* A default for same. */ 83352558Sobrien#ifndef USER_LABEL_PREFIX 83452558Sobrien#define USER_LABEL_PREFIX "" 83552558Sobrien#endif 83652558Sobrien 83718334Speter/* Table of language-independent -f options. 83818334Speter STRING is the option name. VARIABLE is the address of the variable. 83918334Speter ON_VALUE is the value to store in VARIABLE 84018334Speter if `-fSTRING' is seen as an option. 84118334Speter (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ 84218334Speter 84350615Sobrienlang_independent_options f_options[] = 84418334Speter{ 84550615Sobrien {"float-store", &flag_float_store, 1, 84650615Sobrien "Do not store floats in registers" }, 84750615Sobrien {"volatile", &flag_volatile, 1, 84850615Sobrien "Consider all mem refs through pointers as volatile"}, 84950615Sobrien {"volatile-global", &flag_volatile_global, 1, 85050615Sobrien "Consider all mem refs to global data to be volatile" }, 85152558Sobrien {"volatile-static", &flag_volatile_static, 1, 85252558Sobrien "Consider all mem refs to static data to be volatile" }, 85350615Sobrien {"defer-pop", &flag_defer_pop, 1, 85450615Sobrien "Defer popping functions args from stack until later" }, 85550615Sobrien {"omit-frame-pointer", &flag_omit_frame_pointer, 1, 85650615Sobrien "When possible do not generate stack frames"}, 85750615Sobrien {"cse-follow-jumps", &flag_cse_follow_jumps, 1, 85850615Sobrien "When running CSE, follow jumps to their targets" }, 85950615Sobrien {"cse-skip-blocks", &flag_cse_skip_blocks, 1, 86050615Sobrien "When running CSE, follow conditional jumps" }, 86150615Sobrien {"expensive-optimizations", &flag_expensive_optimizations, 1, 86250615Sobrien "Perform a number of minor, expensive optimisations" }, 86350615Sobrien {"thread-jumps", &flag_thread_jumps, 1, 86450615Sobrien "Perform jump threading optimisations"}, 86550615Sobrien {"strength-reduce", &flag_strength_reduce, 1, 86650615Sobrien "Perform strength reduction optimisations" }, 86750615Sobrien {"unroll-loops", &flag_unroll_loops, 1, 86852558Sobrien "Perform loop unrolling when iteration count is known" }, 86950615Sobrien {"unroll-all-loops", &flag_unroll_all_loops, 1, 87052558Sobrien "Perform loop unrolling for all loops" }, 87150615Sobrien {"move-all-movables", &flag_move_all_movables, 1, 87250615Sobrien "Force all loop invariant computations out of loops" }, 87350615Sobrien {"reduce-all-givs", &flag_reduce_all_givs, 1, 87450615Sobrien "Strength reduce all loop general induction variables" }, 87550615Sobrien {"writable-strings", &flag_writable_strings, 1, 87650615Sobrien "Store strings in writable data section" }, 87750615Sobrien {"peephole", &flag_no_peephole, 0, 87850615Sobrien "Enable machine specific peephole optimisations" }, 87950615Sobrien {"force-mem", &flag_force_mem, 1, 88050615Sobrien "Copy memory operands into registers before using" }, 88150615Sobrien {"force-addr", &flag_force_addr, 1, 88250615Sobrien "Copy memory address constants into regs before using" }, 88350615Sobrien {"function-cse", &flag_no_function_cse, 0, 88450615Sobrien "Allow function addresses to be held in registers" }, 88550615Sobrien {"inline-functions", &flag_inline_functions, 1, 88650615Sobrien "Integrate simple functions into their callers" }, 88750615Sobrien {"keep-inline-functions", &flag_keep_inline_functions, 1, 88850615Sobrien "Generate code for funcs even if they are fully inlined" }, 88950615Sobrien {"inline", &flag_no_inline, 0, 89050615Sobrien "Pay attention to the 'inline' keyword"}, 89150615Sobrien {"keep-static-consts", &flag_keep_static_consts, 1, 89250615Sobrien "Emit static const variables even if they are not used" }, 89350615Sobrien {"syntax-only", &flag_syntax_only, 1, 89450615Sobrien "Check for syntax errors, then stop" }, 89550615Sobrien {"shared-data", &flag_shared_data, 1, 89650615Sobrien "Mark data as shared rather than private" }, 89750615Sobrien {"caller-saves", &flag_caller_saves, 1, 89850615Sobrien "Enable saving registers around function calls" }, 89950615Sobrien {"pcc-struct-return", &flag_pcc_struct_return, 1, 90050615Sobrien "Return 'short' aggregates in memory, not registers" }, 90150615Sobrien {"reg-struct-return", &flag_pcc_struct_return, 0, 90250615Sobrien "Return 'short' aggregates in registers" }, 90350615Sobrien {"delayed-branch", &flag_delayed_branch, 1, 90450615Sobrien "Attempt to fill delay slots of branch instructions" }, 90550615Sobrien {"gcse", &flag_gcse, 1, 90650615Sobrien "Perform the global common subexpression elimination" }, 90750615Sobrien {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1, 90850615Sobrien "Run CSE pass after loop optimisations"}, 90950615Sobrien {"rerun-loop-opt", &flag_rerun_loop_opt, 1, 91050615Sobrien "Run the loop optimiser twice"}, 91150615Sobrien {"pretend-float", &flag_pretend_float, 1, 91250615Sobrien "Pretend that host and target use the same FP format"}, 91350615Sobrien {"schedule-insns", &flag_schedule_insns, 1, 91450615Sobrien "Reschedule instructions to avoid pipeline stalls"}, 91550615Sobrien {"schedule-insns2", &flag_schedule_insns_after_reload, 1, 91650615Sobrien "Run two passes of the instruction scheduler"}, 91750615Sobrien#ifdef HAIFA 91850615Sobrien {"sched-interblock",&flag_schedule_interblock, 1, 91950615Sobrien "Enable scheduling across basic blocks" }, 92050615Sobrien {"sched-spec",&flag_schedule_speculative, 1, 92150615Sobrien "Allow speculative motion of non-loads" }, 92250615Sobrien {"sched-spec-load",&flag_schedule_speculative_load, 1, 92350615Sobrien "Allow speculative motion of some loads" }, 92450615Sobrien {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1, 92550615Sobrien "Allow speculative motion of more loads" }, 92652558Sobrien#endif /* HAIFA */ 92750615Sobrien {"branch-count-reg",&flag_branch_on_count_reg, 1, 92850615Sobrien "Replace add,compare,branch with branch on count reg"}, 92950615Sobrien {"pic", &flag_pic, 1, 93050615Sobrien "Generate position independent code, if possible"}, 93150615Sobrien {"PIC", &flag_pic, 2, ""}, 93250615Sobrien {"exceptions", &flag_exceptions, 1, 93350615Sobrien "Enable exception handling" }, 93450615Sobrien {"new-exceptions", &flag_new_exceptions, 1, 93550615Sobrien "Use the new model for exception handling" }, 93650615Sobrien {"sjlj-exceptions", &exceptions_via_longjmp, 1, 93750615Sobrien "Use setjmp/longjmp to handle exceptions" }, 93850615Sobrien {"asynchronous-exceptions", &asynchronous_exceptions, 1, 93950615Sobrien "Support asynchronous exceptions" }, 94050615Sobrien {"profile-arcs", &profile_arc_flag, 1, 94150615Sobrien "Insert arc based program profiling code" }, 94250615Sobrien {"test-coverage", &flag_test_coverage, 1, 94350615Sobrien "Create data files needed by gcov" }, 94450615Sobrien {"branch-probabilities", &flag_branch_probabilities, 1, 94552558Sobrien "Use profiling information for branch probabilities" }, 94650615Sobrien {"fast-math", &flag_fast_math, 1, 94750615Sobrien "Improve FP speed by violating ANSI & IEEE rules" }, 94850615Sobrien {"common", &flag_no_common, 0, 94950615Sobrien "Do not put unitialised globals in the common section" }, 95050615Sobrien {"inhibit-size-directive", &flag_inhibit_size_directive, 1, 95150615Sobrien "Do not generate .size directives" }, 95250615Sobrien {"function-sections", &flag_function_sections, 1, 95350615Sobrien "place each function into its own section" }, 95452558Sobrien {"data-sections", &flag_data_sections, 1, 95552558Sobrien "place data items into their own section" }, 95650615Sobrien {"verbose-asm", &flag_verbose_asm, 1, 95750615Sobrien "Add extra commentry to assembler output"}, 95850615Sobrien {"gnu-linker", &flag_gnu_linker, 1, 95950615Sobrien "Output GNU ld formatted global initialisers"}, 96050615Sobrien {"regmove", &flag_regmove, 1, 96152558Sobrien "Enables a register move optimisation"}, 96252558Sobrien {"optimize-register-move", &flag_regmove, 1, 96352558Sobrien "Do the full regmove optimization pass"}, 96450615Sobrien {"pack-struct", &flag_pack_struct, 1, 96550615Sobrien "Pack structure members together without holes" }, 96650615Sobrien {"format-extensions", &flag_format_extensions, 1, 96750615Sobrien "-Wformat accepts certain FreeBSD system-dependent formats" }, 96850615Sobrien {"stack-check", &flag_stack_check, 1, 96950615Sobrien "Insert stack checking code into the program" }, 97050615Sobrien {"argument-alias", &flag_argument_noalias, 0, 97150615Sobrien "Specify that arguments may alias each other & globals"}, 97250615Sobrien {"argument-noalias", &flag_argument_noalias, 1, 97350615Sobrien "Assume arguments may alias globals but not each other"}, 97450615Sobrien {"argument-noalias-global", &flag_argument_noalias, 2, 97550615Sobrien "Assume arguments do not alias each other or globals" }, 97650615Sobrien {"strict-aliasing", &flag_strict_aliasing, 1, 97750615Sobrien "Assume strict aliasing rules apply" }, 97850615Sobrien {"check-memory-usage", &flag_check_memory_usage, 1, 97950615Sobrien "Generate code to check every memory access" }, 98050615Sobrien {"prefix-function-name", &flag_prefix_function_name, 1, 98150615Sobrien "Add a prefix to all function names" }, 98252558Sobrien {"dump-unnumbered", &flag_dump_unnumbered, 1, 98352558Sobrien "Suppress output of instruction numbers and line number notes in debugging dumps"}, 98452558Sobrien {"instrument-functions", &flag_instrument_function_entry_exit, 1, 98552558Sobrien "Instrument function entry/exit with profiling calls"}, 98652558Sobrien {"leading-underscore", &flag_leading_underscore, 1, 98752558Sobrien "External symbols have a leading underscore" }, 98852558Sobrien {"ident", &flag_no_ident, 0, 98952558Sobrien "Process #ident directives"} 99018334Speter}; 99118334Speter 99250615Sobrien#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0])) 99350615Sobrien 99418334Speter/* Table of language-specific options. */ 99518334Speter 99650615Sobrienstatic struct lang_opt 99718334Speter{ 99852558Sobrien const char * option; 99952558Sobrien const char * description; 100050615Sobrien} 100150615Sobriendocumented_lang_options[] = 100250615Sobrien{ 100350615Sobrien /* In order not to overload the --help output, the convention 100450615Sobrien used here is to only describe those options which are not 100550615Sobrien enabled by default. */ 100618334Speter 100750615Sobrien { "-ansi", "Compile just for ANSI C" }, 100850615Sobrien { "-fallow-single-precision", 100950615Sobrien "Do not promote floats to double if using -traditional" }, 101052558Sobrien { "-std= ", "Determine language standard"}, 101118334Speter 101250615Sobrien { "-fsigned-bitfields", "" }, 101350615Sobrien { "-funsigned-bitfields","Make bitfields by unsigned by default" }, 101450615Sobrien { "-fno-signed-bitfields", "" }, 101550615Sobrien { "-fno-unsigned-bitfields","" }, 101650615Sobrien { "-fsigned-char", "Make 'char' be signed by default"}, 101750615Sobrien { "-funsigned-char", "Make 'char' be unsigned by default"}, 101850615Sobrien { "-fno-signed-char", "" }, 101950615Sobrien { "-fno-unsigned-char", "" }, 102018334Speter 102150615Sobrien { "-ftraditional", "" }, 102250615Sobrien { "-traditional", "Attempt to support traditional K&R style C"}, 102350615Sobrien { "-fnotraditional", "" }, 102450615Sobrien { "-fno-traditional", "" }, 102518334Speter 102650615Sobrien { "-fasm", "" }, 102750615Sobrien { "-fno-asm", "Do not recognise the 'asm' keyword" }, 102850615Sobrien { "-fbuiltin", "" }, 102950615Sobrien { "-fno-builtin", "Do not recognise any built in functions" }, 103050615Sobrien { "-fhosted", "Assume normal C execution environment" }, 103150615Sobrien { "-fno-hosted", "" }, 103250615Sobrien { "-ffreestanding", 103350615Sobrien "Assume that standard libraries & main might not exist" }, 103450615Sobrien { "-fno-freestanding", "" }, 103550615Sobrien { "-fcond-mismatch", "Allow different types as args of ? operator"}, 103650615Sobrien { "-fno-cond-mismatch", "" }, 103752558Sobrien { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" }, 103850615Sobrien { "-fno-dollars-in-identifiers", "" }, 103950615Sobrien { "-fshort-double", "Use the same size for double as for float" }, 104050615Sobrien { "-fno-short-double", "" }, 104150615Sobrien { "-fshort-enums", "Use the smallest fitting integer to hold enums"}, 104250615Sobrien { "-fno-short-enums", "" }, 104318334Speter 104450615Sobrien { "-Wall", "Enable most warning messages" }, 104550615Sobrien { "-Wbad-function-cast", 104650615Sobrien "Warn about casting functions to incompatible types" }, 104750615Sobrien { "-Wno-bad-function-cast", "" }, 104852558Sobrien { "-Wmissing-noreturn", 104952558Sobrien "Warn about functions which might be candidates for attribute noreturn" }, 105052558Sobrien { "-Wno-missing-noreturn", "" }, 105150615Sobrien { "-Wcast-qual", "Warn about casts which discard qualifiers"}, 105250615Sobrien { "-Wno-cast-qual", "" }, 105352558Sobrien { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"}, 105450615Sobrien { "-Wno-char-subscripts", "" }, 105550615Sobrien { "-Wcomment", "Warn if nested comments are detected" }, 105652558Sobrien { "-Wno-comment", "" }, 105752558Sobrien { "-Wcomments", "Warn if nested comments are detected" }, 105852558Sobrien { "-Wno-comments", "" }, 105950615Sobrien { "-Wconversion", "Warn about possibly confusing type conversions" }, 106050615Sobrien { "-Wno-conversion", "" }, 106150615Sobrien { "-Wformat", "Warn about printf format anomalies" }, 106250615Sobrien { "-Wno-format", "" }, 106350615Sobrien { "-Wimplicit-function-declaration", 106450615Sobrien "Warn about implicit function declarations" }, 106550615Sobrien { "-Wno-implicit-function-declaration", "" }, 106650615Sobrien { "-Werror-implicit-function-declaration", "" }, 106750615Sobrien { "-Wimplicit-int", "Warn when a declaration does not specify a type" }, 106850615Sobrien { "-Wno-implicit-int", "" }, 106950615Sobrien { "-Wimplicit", "" }, 107050615Sobrien { "-Wno-implicit", "" }, 107150615Sobrien { "-Wimport", "Warn about the use of the #import directive" }, 107250615Sobrien { "-Wno-import", "" }, 107350615Sobrien { "-Wlong-long","" }, 107450615Sobrien { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" }, 107550615Sobrien { "-Wmain", "Warn about suspicious declarations of main" }, 107650615Sobrien { "-Wno-main", "" }, 107750615Sobrien { "-Wmissing-braces", 107850615Sobrien "Warn about possibly missing braces around initialisers" }, 107950615Sobrien { "-Wno-missing-braces", "" }, 108050615Sobrien { "-Wmissing-declarations", 108150615Sobrien "Warn about global funcs without previous declarations"}, 108250615Sobrien { "-Wno-missing-declarations", "" }, 108350615Sobrien { "-Wmissing-prototypes", "Warn about global funcs without prototypes" }, 108450615Sobrien { "-Wno-missing-prototypes", "" }, 108550615Sobrien { "-Wmultichar", "Warn about use of multicharacter literals"}, 108650615Sobrien { "-Wno-multichar", "" }, 108750615Sobrien { "-Wnested-externs", "Warn about externs not at file scope level" }, 108850615Sobrien { "-Wno-nested-externs", "" }, 108950615Sobrien { "-Wparentheses", "Warn about possible missing parentheses" }, 109050615Sobrien { "-Wno-parentheses", "" }, 109150615Sobrien { "-Wpointer-arith", "Warn about function pointer arithmetic" }, 109250615Sobrien { "-Wno-pointer-arith", "" }, 109350615Sobrien { "-Wredundant-decls", 109450615Sobrien "Warn about multiple declarations of the same object" }, 109550615Sobrien { "-Wno-redundant-decls", "" }, 109650615Sobrien { "-Wsign-compare", "Warn about signed/unsigned comparisons" }, 109750615Sobrien { "-Wno-sign-compare", "" }, 109850615Sobrien { "-Wunknown-pragmas", "Warn about unrecognised pragmas" }, 109950615Sobrien { "-Wno-unknown-pragmas", "" }, 110050615Sobrien { "-Wstrict-prototypes", "Warn about non-prototyped function decls" }, 110150615Sobrien { "-Wno-strict-prototypes", "" }, 110252558Sobrien { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"}, 110350615Sobrien { "-Wno-traditional", "" }, 110450615Sobrien { "-Wtrigraphs", "Warn when trigraphs are encountered" }, 110550615Sobrien { "-Wno-trigraphs", "" }, 110650615Sobrien { "-Wundef", "" }, 110750615Sobrien { "-Wno-undef", "" }, 110850615Sobrien { "-Wwrite-strings", "Mark strings as 'const char *'"}, 110950615Sobrien { "-Wno-write-strings", "" }, 111018334Speter 111150615Sobrien /* These are for languages with USE_CPPLIB. */ 111250615Sobrien /* These options are already documented in cpplib.c */ 111350615Sobrien { "--help", "" }, 111450615Sobrien { "-A", "" }, 111550615Sobrien { "-D", "" }, 111650615Sobrien { "-I", "" }, 111752558Sobrien#if USE_CPPLIB 111852558Sobrien { "-MD", "Print dependencies to FILE.d" }, 111952558Sobrien { "-MMD", "Print dependencies to FILE.d" }, 112052558Sobrien { "-M", "Print dependencies to stdout" }, 112152558Sobrien { "-MM", "Print dependencies to stdout" }, 112252558Sobrien#endif /* USE_CPPLIB */ 112350615Sobrien { "-U", "" }, 112452558Sobrien { "-H", "" }, 112550615Sobrien { "-idirafter", "" }, 112652558Sobrien { "-imacros", "" }, 112752558Sobrien { "-include", "" }, 112850615Sobrien { "-iprefix", "" }, 112950615Sobrien { "-isystem", "" }, 113052558Sobrien { "-iwithprefix", "" }, 113152558Sobrien { "-iwithprefixbefore", "" }, 113250615Sobrien { "-lang-c", "" }, 113350615Sobrien { "-lang-c89", "" }, 113450615Sobrien { "-lang-c++", "" }, 113552558Sobrien { "-remap", "" }, 113650615Sobrien { "-nostdinc", "" }, 113750615Sobrien { "-nostdinc++", "" }, 113850615Sobrien { "-trigraphs", "" }, 113950615Sobrien { "-undef", "" }, 114050615Sobrien 114150615Sobrien#define DEFINE_LANG_NAME(NAME) { NULL, NAME }, 114250615Sobrien 114350615Sobrien /* These are for obj c. */ 114450615Sobrien DEFINE_LANG_NAME ("Objective C") 114550615Sobrien 114650615Sobrien { "-lang-objc", "" }, 114750615Sobrien { "-gen-decls", "Dump decls to a .decl file" }, 114852558Sobrien { "-fgnu-runtime", "Generate code for GNU runtime environment" }, 114950615Sobrien { "-fno-gnu-runtime", "" }, 115050615Sobrien { "-fnext-runtime", "Generate code for NeXT runtime environment" }, 115150615Sobrien { "-fno-next-runtime", "" }, 115250615Sobrien { "-Wselector", "Warn if a selector has multiple methods" }, 115350615Sobrien { "-Wno-selector", "" }, 115450615Sobrien { "-Wprotocol", "" }, 115550615Sobrien { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"}, 115650615Sobrien { "-print-objc-runtime-info", 115750615Sobrien "Generate C header of platform specific features" }, 115850615Sobrien 115918334Speter#include "options.h" 116050615Sobrien 116118334Speter}; 116250615Sobrien 116350615Sobrien/* Here is a table, controlled by the tm.h file, listing each -m switch 116450615Sobrien and which bits in `target_switches' it should set or clear. 116550615Sobrien If VALUE is positive, it is bits to set. 116650615Sobrien If VALUE is negative, -VALUE is bits to clear. 116750615Sobrien (The sign bit is not used so there is no confusion.) */ 116850615Sobrien 116950615Sobrienstruct 117050615Sobrien{ 117152558Sobrien const char * name; 117250615Sobrien int value; 117352558Sobrien const char * description; 117450615Sobrien} 117550615Sobrientarget_switches [] = TARGET_SWITCHES; 117650615Sobrien 117750615Sobrien/* This table is similar, but allows the switch to have a value. */ 117850615Sobrien 117950615Sobrien#ifdef TARGET_OPTIONS 118050615Sobrienstruct 118150615Sobrien{ 118252558Sobrien const char * prefix; 118352558Sobrien const char ** variable; 118452558Sobrien const char * description; 118550615Sobrien} 118650615Sobrientarget_options [] = TARGET_OPTIONS; 118750615Sobrien#endif 118818334Speter 118918334Speter/* Options controlling warnings */ 119018334Speter 119118334Speter/* Don't print warning messages. -w. */ 119218334Speter 119318334Speterint inhibit_warnings = 0; 119418334Speter 119518334Speter/* Print various extra warnings. -W. */ 119618334Speter 119718334Speterint extra_warnings = 0; 119818334Speter 119918334Speter/* Treat warnings as errors. -Werror. */ 120018334Speter 120118334Speterint warnings_are_errors = 0; 120218334Speter 120318334Speter/* Nonzero to warn about unused local variables. */ 120418334Speter 120518334Speterint warn_unused; 120618334Speter 120718334Speter/* Nonzero to warn about variables used before they are initialized. */ 120818334Speter 120918334Speterint warn_uninitialized; 121018334Speter 121118334Speter/* Nonzero means warn about all declarations which shadow others. */ 121218334Speter 121318334Speterint warn_shadow; 121418334Speter 121518334Speter/* Warn if a switch on an enum fails to have a case for every enum value. */ 121618334Speter 121718334Speterint warn_switch; 121818334Speter 121918334Speter/* Nonzero means warn about function definitions that default the return type 122018334Speter or that use a null return and have a return-type other than void. */ 122118334Speter 122218334Speterint warn_return_type; 122318334Speter 122418334Speter/* Nonzero means warn about pointer casts that increase the required 122518334Speter alignment of the target type (and might therefore lead to a crash 122618334Speter due to a misaligned access). */ 122718334Speter 122818334Speterint warn_cast_align; 122918334Speter 123018334Speter/* Nonzero means warn about any identifiers that match in the first N 123118334Speter characters. The value N is in `id_clash_len'. */ 123218334Speter 123318334Speterint warn_id_clash; 123418334Speterunsigned id_clash_len; 123518334Speter 123618334Speter/* Nonzero means warn about any objects definitions whose size is larger 123718334Speter than N bytes. Also want about function definitions whose returned 123818334Speter values are larger than N bytes. The value N is in `larger_than_size'. */ 123918334Speter 124018334Speterint warn_larger_than; 124118334Speterunsigned larger_than_size; 124218334Speter 124318334Speter/* Nonzero means warn if inline function is too large. */ 124418334Speter 124518334Speterint warn_inline; 124618334Speter 124718334Speter/* Warn if a function returns an aggregate, 124818334Speter since there are often incompatible calling conventions for doing this. */ 124918334Speter 125018334Speterint warn_aggregate_return; 125118334Speter 125218334Speter/* Likewise for -W. */ 125318334Speter 125450615Sobrienlang_independent_options W_options[] = 125518334Speter{ 125650615Sobrien {"unused", &warn_unused, 1, "Warn when a variable is unused" }, 125750615Sobrien {"error", &warnings_are_errors, 1, ""}, 125850615Sobrien {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" }, 125950615Sobrien {"switch", &warn_switch, 1, 126050615Sobrien "Warn about enumerated switches missing a specific case" }, 126150615Sobrien {"aggregate-return", &warn_aggregate_return, 1, 126250615Sobrien "Warn about returning structures, unions or arrays" }, 126350615Sobrien {"cast-align", &warn_cast_align, 1, 126450615Sobrien "Warn about pointer casts which increase alignment" }, 126550615Sobrien {"uninitialized", &warn_uninitialized, 1, 126650615Sobrien "Warn about unitialized automatic variables"}, 126750615Sobrien {"inline", &warn_inline, 1, 126850615Sobrien "Warn when an inlined function cannot be inlined"} 126918334Speter}; 127018334Speter 127118334Speter/* Output files for assembler code (real compiler output) 127218334Speter and debugging dumps. */ 127318334Speter 127418334SpeterFILE *asm_out_file; 127518334SpeterFILE *aux_info_file; 127650615SobrienFILE *rtl_dump_file = NULL; 127718334Speter 127852558Sobrien/* Decode the string P as an integral parameter. 127952558Sobrien If the string is indeed an integer return its numeric value else 128052558Sobrien issue an Invalid Option error for the option PNAME and return DEFVAL. 128152558Sobrien If PNAME is zero just return DEFVAL, do not call error. */ 128252558Sobrien 128352558Sobrienint 128452558Sobrienread_integral_parameter (p, pname, defval) 128552558Sobrien const char *p; 128652558Sobrien const char *pname; 128752558Sobrien const int defval; 128852558Sobrien{ 128952558Sobrien const char *endp = p; 129052558Sobrien 129152558Sobrien while (*endp) 129252558Sobrien { 129352558Sobrien if (*endp >= '0' && *endp <= '9') 129452558Sobrien endp++; 129552558Sobrien else 129652558Sobrien break; 129752558Sobrien } 129852558Sobrien 129952558Sobrien if (*endp != 0) 130052558Sobrien { 130152558Sobrien if (pname != 0) 130252558Sobrien error ("Invalid option `%s'", pname); 130352558Sobrien return defval; 130452558Sobrien } 130552558Sobrien 130652558Sobrien return atoi (p); 130752558Sobrien} 130852558Sobrien 130952558Sobrien 131018334Speter/* Time accumulators, to count the total time spent in various passes. */ 131118334Speter 131218334Speterint parse_time; 131318334Speterint varconst_time; 131418334Speterint integration_time; 131518334Speterint jump_time; 131618334Speterint cse_time; 131750615Sobrienint gcse_time; 131818334Speterint loop_time; 131918334Speterint cse2_time; 132050615Sobrienint branch_prob_time; 132118334Speterint flow_time; 132218334Speterint combine_time; 132350615Sobrienint regmove_time; 132418334Speterint sched_time; 132518334Speterint local_alloc_time; 132618334Speterint global_alloc_time; 132752558Sobrienint flow2_time; 132818334Speterint sched2_time; 132950615Sobrien#ifdef DELAY_SLOTS 133018334Speterint dbr_sched_time; 133150615Sobrien#endif 133218334Speterint shorten_branch_time; 133318334Speterint stack_reg_time; 133418334Speterint final_time; 133518334Speterint symout_time; 133618334Speterint dump_time; 133718334Speter 133818334Speter/* Return time used so far, in microseconds. */ 133918334Speter 134052558Sobrienlong 134118334Speterget_run_time () 134218334Speter{ 134318334Speter if (quiet_flag) 134418334Speter return 0; 134550615Sobrien 134650615Sobrien#ifdef __BEOS__ 134750615Sobrien return 0; 134850615Sobrien#else /* not BeOS */ 134952558Sobrien#if defined (_WIN32) && !defined (__CYGWIN__) 135018334Speter if (clock() < 0) 135118334Speter return 0; 135218334Speter else 135318334Speter return (clock() * 1000); 135418334Speter#else /* not _WIN32 */ 135550615Sobrien#ifdef _SC_CLK_TCK 135650615Sobrien { 135750615Sobrien static int tick; 135850615Sobrien struct tms tms; 135950615Sobrien if (tick == 0) 136050615Sobrien tick = 1000000 / sysconf(_SC_CLK_TCK); 136150615Sobrien times (&tms); 136250615Sobrien return (tms.tms_utime + tms.tms_stime) * tick; 136350615Sobrien } 136450615Sobrien#else 136518334Speter#ifdef USG 136650615Sobrien { 136750615Sobrien struct tms tms; 136850615Sobrien# if HAVE_SYSCONF && defined _SC_CLK_TCK 136950615Sobrien# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */ 137050615Sobrien# else 137150615Sobrien# ifdef CLK_TCK 137250615Sobrien# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */ 137350615Sobrien# else 137450615Sobrien# define TICKS_PER_SECOND HZ /* traditional UNIX */ 137550615Sobrien# endif 137650615Sobrien# endif 137750615Sobrien times (&tms); 137850615Sobrien return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND); 137950615Sobrien } 138018334Speter#else 138118334Speter#ifndef VMS 138250615Sobrien { 138350615Sobrien struct rusage rusage; 138450615Sobrien getrusage (0, &rusage); 138550615Sobrien return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec 138650615Sobrien + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); 138750615Sobrien } 138818334Speter#else /* VMS */ 138950615Sobrien { 139050615Sobrien struct 139150615Sobrien { 139250615Sobrien int proc_user_time; 139350615Sobrien int proc_system_time; 139450615Sobrien int child_user_time; 139550615Sobrien int child_system_time; 139650615Sobrien } vms_times; 139750615Sobrien times ((void *) &vms_times); 139850615Sobrien return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; 139950615Sobrien } 140050615Sobrien#endif /* VMS */ 140150615Sobrien#endif /* USG */ 140250615Sobrien#endif /* _SC_CLK_TCK */ 140350615Sobrien#endif /* _WIN32 */ 140450615Sobrien#endif /* __BEOS__ */ 140518334Speter} 140618334Speter 140718334Speter#define TIMEVAR(VAR, BODY) \ 140818334Speterdo { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0) 140918334Speter 141018334Spetervoid 141118334Speterprint_time (str, total) 141252558Sobrien const char *str; 141318334Speter int total; 141418334Speter{ 141518334Speter fprintf (stderr, 141618334Speter "time in %s: %d.%06d\n", 141718334Speter str, total / 1000000, total % 1000000); 141818334Speter} 141918334Speter 142018334Speter/* Count an error or warning. Return 1 if the message should be printed. */ 142118334Speter 142218334Speterint 142318334Spetercount_error (warningp) 142418334Speter int warningp; 142518334Speter{ 142618334Speter if (warningp && inhibit_warnings) 142718334Speter return 0; 142818334Speter 142918334Speter if (warningp && !warnings_are_errors) 143018334Speter warningcount++; 143118334Speter else 143218334Speter { 143318334Speter static int warning_message = 0; 143418334Speter 143518334Speter if (warningp && !warning_message) 143618334Speter { 143752558Sobrien notice ("%s: warnings being treated as errors\n", progname); 143818334Speter warning_message = 1; 143918334Speter } 144018334Speter errorcount++; 144118334Speter } 144218334Speter 144318334Speter return 1; 144418334Speter} 144518334Speter 144618334Speter/* Print a fatal error message. NAME is the text. 144718334Speter Also include a system error message based on `errno'. */ 144818334Speter 144918334Spetervoid 145018334Speterpfatal_with_name (name) 145152558Sobrien const char *name; 145218334Speter{ 145318334Speter fprintf (stderr, "%s: ", progname); 145418334Speter perror (name); 145518334Speter exit (FATAL_EXIT_CODE); 145618334Speter} 145718334Speter 145818334Spetervoid 145918334Speterfatal_io_error (name) 146052558Sobrien const char *name; 146118334Speter{ 146252558Sobrien notice ("%s: %s: I/O error\n", progname, name); 146318334Speter exit (FATAL_EXIT_CODE); 146418334Speter} 146518334Speter 146618334Speter/* Called to give a better error message for a bad insn rather than 146718334Speter just calling abort(). */ 146818334Speter 146918334Spetervoid 147052558Sobrienfatal_insn VPROTO((const char *msgid, rtx insn, ...)) 147118334Speter{ 147252558Sobrien#ifndef ANSI_PROTOTYPES 147352558Sobrien const char *msgid; 147452558Sobrien rtx insn; 147552558Sobrien#endif 147652558Sobrien va_list ap; 147752558Sobrien 147852558Sobrien VA_START (ap, insn); 147952558Sobrien 148052558Sobrien#ifndef ANSI_PROTOTYPES 148152558Sobrien msgid = va_arg (ap, const char *); 148252558Sobrien insn = va_arg (ap, rtx); 148352558Sobrien#endif 148452558Sobrien 148552558Sobrien verror (msgid, ap); 148650615Sobrien debug_rtx (insn); 148752558Sobrien exit (FATAL_EXIT_CODE); 148818334Speter} 148918334Speter 149018334Speter/* Called to give a better error message when we don't have an insn to match 149118334Speter what we are looking for or if the insn's constraints aren't satisfied, 149218334Speter rather than just calling abort(). */ 149318334Speter 149418334Spetervoid 149518334Speterfatal_insn_not_found (insn) 149618334Speter rtx insn; 149718334Speter{ 149818334Speter if (INSN_CODE (insn) < 0) 149918334Speter fatal_insn ("internal error--unrecognizable insn:", insn); 150018334Speter else 150118334Speter fatal_insn ("internal error--insn does not satisfy its constraints:", insn); 150218334Speter} 150318334Speter 150418334Speter/* This is the default decl_printable_name function. */ 150518334Speter 150618334Speterstatic char * 150750615Sobriendecl_name (decl, verbosity) 150818334Speter tree decl; 150952558Sobrien int verbosity ATTRIBUTE_UNUSED; 151018334Speter{ 151118334Speter return IDENTIFIER_POINTER (DECL_NAME (decl)); 151218334Speter} 151318334Speter 151418334Speterstatic int need_error_newline; 151518334Speter 151618334Speter/* Function of last error message; 151718334Speter more generally, function such that if next error message is in it 151818334Speter then we don't have to mention the function name. */ 151918334Speterstatic tree last_error_function = NULL; 152018334Speter 152118334Speter/* Used to detect when input_file_stack has changed since last described. */ 152218334Speterstatic int last_error_tick; 152318334Speter 152418334Speter/* Called when the start of a function definition is parsed, 152518334Speter this function prints on stderr the name of the function. */ 152618334Speter 152718334Spetervoid 152818334Speterannounce_function (decl) 152918334Speter tree decl; 153018334Speter{ 153118334Speter if (! quiet_flag) 153218334Speter { 153318334Speter if (rtl_dump_and_exit) 153418334Speter fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl))); 153518334Speter else 153650615Sobrien fprintf (stderr, " %s", (*decl_printable_name) (decl, 2)); 153718334Speter fflush (stderr); 153818334Speter need_error_newline = 1; 153918334Speter last_error_function = current_function_decl; 154018334Speter } 154118334Speter} 154218334Speter 154318334Speter/* The default function to print out name of current function that caused 154418334Speter an error. */ 154518334Speter 154618334Spetervoid 154718334Speterdefault_print_error_function (file) 154852558Sobrien const char *file; 154918334Speter{ 155018334Speter if (last_error_function != current_function_decl) 155118334Speter { 155218334Speter if (file) 155318334Speter fprintf (stderr, "%s: ", file); 155418334Speter 155518334Speter if (current_function_decl == NULL) 155652558Sobrien notice ("At top level:\n"); 155718334Speter else 155852558Sobrien notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE 155952558Sobrien ? "In method `%s':\n" 156052558Sobrien : "In function `%s':\n"), 156152558Sobrien (*decl_printable_name) (current_function_decl, 2)); 156218334Speter 156318334Speter last_error_function = current_function_decl; 156418334Speter } 156518334Speter} 156618334Speter 156718334Speter/* Called by report_error_function to print out function name. 156850615Sobrien * Default may be overridden by language front-ends. */ 156918334Speter 157052558Sobrienvoid (*print_error_function) PROTO((const char *)) = 157152558Sobrien default_print_error_function; 157218334Speter 157318334Speter/* Prints out, if necessary, the name of the current function 157452558Sobrien that caused an error. Called from all error and warning functions. 157552558Sobrien We ignore the FILE parameter, as it cannot be relied upon. */ 157618334Speter 157718334Spetervoid 157818334Speterreport_error_function (file) 157952558Sobrien const char *file ATTRIBUTE_UNUSED; 158018334Speter{ 158118334Speter struct file_stack *p; 158218334Speter 158318334Speter if (need_error_newline) 158418334Speter { 158518334Speter fprintf (stderr, "\n"); 158618334Speter need_error_newline = 0; 158718334Speter } 158818334Speter 158918334Speter if (input_file_stack && input_file_stack->next != 0 159052558Sobrien && input_file_stack_tick != last_error_tick) 159118334Speter { 159218334Speter for (p = input_file_stack->next; p; p = p->next) 159352558Sobrien notice ((p == input_file_stack->next 159452558Sobrien ? "In file included from %s:%d" 159552558Sobrien : ",\n from %s:%d"), 159652558Sobrien p->name, p->line); 159718334Speter fprintf (stderr, ":\n"); 159818334Speter last_error_tick = input_file_stack_tick; 159918334Speter } 160052558Sobrien 160152558Sobrien (*print_error_function) (input_filename); 160218334Speter} 160318334Speter 160418334Speter/* Print a message. */ 160518334Speter 160618334Speterstatic void 160752558Sobrienvnotice (file, msgid, ap) 160852558Sobrien FILE *file; 160952558Sobrien char *msgid; 161018334Speter va_list ap; 161118334Speter{ 161252558Sobrien vfprintf (file, _(msgid), ap); 161352558Sobrien} 161418334Speter 161552558Sobrienvoid 161652558Sobriennotice VPROTO((const char *msgid, ...)) 161752558Sobrien{ 161852558Sobrien#ifndef ANSI_PROTOTYPES 161952558Sobrien char *msgid; 162052558Sobrien#endif 162152558Sobrien va_list ap; 162252558Sobrien 162352558Sobrien VA_START (ap, msgid); 162452558Sobrien 162552558Sobrien#ifndef ANSI_PROTOTYPES 162652558Sobrien msgid = va_arg (ap, char *); 162752558Sobrien#endif 162852558Sobrien 162952558Sobrien vnotice (stderr, msgid, ap); 163052558Sobrien va_end (ap); 163118334Speter} 163218334Speter 163352558Sobrienvoid 163452558Sobrienfnotice VPROTO((FILE *file, const char *msgid, ...)) 163552558Sobrien{ 163652558Sobrien#ifndef ANSI_PROTOTYPES 163752558Sobrien FILE *file; 163852558Sobrien const char *msgid; 163952558Sobrien#endif 164052558Sobrien va_list ap; 164118334Speter 164252558Sobrien VA_START (ap, msgid); 164352558Sobrien 164452558Sobrien#ifndef ANSI_PROTOTYPES 164552558Sobrien file = va_arg (ap, FILE *); 164652558Sobrien msgid = va_arg (ap, const char *); 164752558Sobrien#endif 164852558Sobrien 164952558Sobrien vnotice (file, msgid, ap); 165052558Sobrien va_end (ap); 165152558Sobrien} 165252558Sobrien 165352558Sobrien/* Report FILE and LINE (or program name), and optionally just WARN. */ 165452558Sobrien 165518334Speterstatic void 165652558Sobrienreport_file_and_line (file, line, warn) 165718334Speter char *file; 165818334Speter int line; 165952558Sobrien int warn; 166018334Speter{ 166118334Speter if (file) 166218334Speter fprintf (stderr, "%s:%d: ", file, line); 166318334Speter else 166418334Speter fprintf (stderr, "%s: ", progname); 166518334Speter 166652558Sobrien if (warn) 166752558Sobrien notice ("warning: "); 166852558Sobrien} 166952558Sobrien 167052558Sobrien/* Print a message. */ 167152558Sobrien 167252558Sobrienstatic void 167352558Sobrienvmessage (prefix, msgid, ap) 167452558Sobrien const char *prefix; 167552558Sobrien const char *msgid; 167652558Sobrien va_list ap; 167752558Sobrien{ 167852558Sobrien if (prefix) 167952558Sobrien fprintf (stderr, "%s: ", prefix); 168052558Sobrien 168152558Sobrien vfprintf (stderr, msgid, ap); 168252558Sobrien} 168352558Sobrien 168452558Sobrien/* Print a message relevant to line LINE of file FILE. */ 168552558Sobrien 168652558Sobrienstatic void 168752558Sobrienv_message_with_file_and_line (file, line, warn, msgid, ap) 168852558Sobrien const char *file; 168952558Sobrien int line; 169052558Sobrien int warn; 169152558Sobrien const char *msgid; 169252558Sobrien va_list ap; 169352558Sobrien{ 169452558Sobrien report_file_and_line (file, line, warn); 169552558Sobrien vnotice (stderr, msgid, ap); 169618334Speter fputc ('\n', stderr); 169718334Speter} 169818334Speter 169918334Speter/* Print a message relevant to the given DECL. */ 170018334Speter 170118334Speterstatic void 170252558Sobrienv_message_with_decl (decl, warn, msgid, ap) 170318334Speter tree decl; 170452558Sobrien int warn; 170552558Sobrien const char *msgid; 170618334Speter va_list ap; 170718334Speter{ 170852558Sobrien const char *p; 170918334Speter 171052558Sobrien report_file_and_line (DECL_SOURCE_FILE (decl), 171152558Sobrien DECL_SOURCE_LINE (decl), warn); 171218334Speter 171318334Speter /* Do magic to get around lack of varargs support for insertion 171418334Speter of arguments into existing list. We know that the decl is first; 171518334Speter we ass_u_me that it will be printed with "%s". */ 171618334Speter 171752558Sobrien for (p = _(msgid); *p; ++p) 171818334Speter { 171918334Speter if (*p == '%') 172018334Speter { 172118334Speter if (*(p + 1) == '%') 172218334Speter ++p; 172352558Sobrien else if (*(p + 1) != 's') 172452558Sobrien abort (); 172518334Speter else 172618334Speter break; 172718334Speter } 172818334Speter } 172918334Speter 173052558Sobrien if (p > _(msgid)) /* Print the left-hand substring. */ 173118334Speter { 173218334Speter char fmt[sizeof "%.255s"]; 173352558Sobrien long width = p - _(msgid); 173418334Speter 173518334Speter if (width > 255L) width = 255L; /* arbitrary */ 173618334Speter sprintf (fmt, "%%.%lds", width); 173752558Sobrien fprintf (stderr, fmt, _(msgid)); 173818334Speter } 173918334Speter 174018334Speter if (*p == '%') /* Print the name. */ 174118334Speter { 174252558Sobrien const char *n = (DECL_NAME (decl) 174350615Sobrien ? (*decl_printable_name) (decl, 2) 174418334Speter : "((anonymous))"); 174518334Speter fputs (n, stderr); 174618334Speter while (*p) 174718334Speter { 174818334Speter ++p; 174950615Sobrien if (ISALPHA (*(p - 1) & 0xFF)) 175018334Speter break; 175118334Speter } 175218334Speter } 175318334Speter 175418334Speter if (*p) /* Print the rest of the message. */ 175518334Speter vmessage ((char *)NULL, p, ap); 175618334Speter 175718334Speter fputc ('\n', stderr); 175818334Speter} 175918334Speter 176018334Speter/* Figure file and line of the given INSN. */ 176118334Speter 176218334Speterstatic void 176318334Speterfile_and_line_for_asm (insn, pfile, pline) 176418334Speter rtx insn; 176518334Speter char **pfile; 176618334Speter int *pline; 176718334Speter{ 176818334Speter rtx body = PATTERN (insn); 176918334Speter rtx asmop; 177018334Speter 177118334Speter /* Find the (or one of the) ASM_OPERANDS in the insn. */ 177218334Speter if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) 177318334Speter asmop = SET_SRC (body); 177418334Speter else if (GET_CODE (body) == ASM_OPERANDS) 177518334Speter asmop = body; 177618334Speter else if (GET_CODE (body) == PARALLEL 177718334Speter && GET_CODE (XVECEXP (body, 0, 0)) == SET) 177818334Speter asmop = SET_SRC (XVECEXP (body, 0, 0)); 177918334Speter else if (GET_CODE (body) == PARALLEL 178018334Speter && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) 178118334Speter asmop = XVECEXP (body, 0, 0); 178218334Speter else 178318334Speter asmop = NULL; 178418334Speter 178518334Speter if (asmop) 178618334Speter { 178718334Speter *pfile = ASM_OPERANDS_SOURCE_FILE (asmop); 178818334Speter *pline = ASM_OPERANDS_SOURCE_LINE (asmop); 178918334Speter } 179018334Speter else 179118334Speter { 179218334Speter *pfile = input_filename; 179318334Speter *pline = lineno; 179418334Speter } 179518334Speter} 179618334Speter 179718334Speter/* Report an error at line LINE of file FILE. */ 179818334Speter 179918334Speterstatic void 180052558Sobrienv_error_with_file_and_line (file, line, msgid, ap) 180152558Sobrien const char *file; 180218334Speter int line; 180352558Sobrien const char *msgid; 180418334Speter va_list ap; 180518334Speter{ 180618334Speter count_error (0); 180718334Speter report_error_function (file); 180852558Sobrien v_message_with_file_and_line (file, line, 0, msgid, ap); 180918334Speter} 181018334Speter 181118334Spetervoid 181252558Sobrienerror_with_file_and_line VPROTO((const char *file, int line, 181352558Sobrien const char *msgid, ...)) 181418334Speter{ 181552558Sobrien#ifndef ANSI_PROTOTYPES 181652558Sobrien const char *file; 181718334Speter int line; 181852558Sobrien const char *msgid; 181918334Speter#endif 182018334Speter va_list ap; 182118334Speter 182252558Sobrien VA_START (ap, msgid); 182318334Speter 182452558Sobrien#ifndef ANSI_PROTOTYPES 182552558Sobrien file = va_arg (ap, const char *); 182618334Speter line = va_arg (ap, int); 182752558Sobrien msgid = va_arg (ap, const char *); 182818334Speter#endif 182918334Speter 183052558Sobrien v_error_with_file_and_line (file, line, msgid, ap); 183118334Speter va_end (ap); 183218334Speter} 183318334Speter 183418334Speter/* Report an error at the declaration DECL. 183552558Sobrien MSGID is a format string which uses %s to substitute the declaration 183618334Speter name; subsequent substitutions are a la printf. */ 183718334Speter 183818334Speterstatic void 183952558Sobrienv_error_with_decl (decl, msgid, ap) 184018334Speter tree decl; 184152558Sobrien const char *msgid; 184218334Speter va_list ap; 184318334Speter{ 184418334Speter count_error (0); 184518334Speter report_error_function (DECL_SOURCE_FILE (decl)); 184652558Sobrien v_message_with_decl (decl, 0, msgid, ap); 184718334Speter} 184818334Speter 184918334Spetervoid 185052558Sobrienerror_with_decl VPROTO((tree decl, const char *msgid, ...)) 185118334Speter{ 185252558Sobrien#ifndef ANSI_PROTOTYPES 185318334Speter tree decl; 185452558Sobrien const char *msgid; 185518334Speter#endif 185618334Speter va_list ap; 185718334Speter 185852558Sobrien VA_START (ap, msgid); 185918334Speter 186052558Sobrien#ifndef ANSI_PROTOTYPES 186118334Speter decl = va_arg (ap, tree); 186252558Sobrien msgid = va_arg (ap, const char *); 186318334Speter#endif 186418334Speter 186552558Sobrien v_error_with_decl (decl, msgid, ap); 186618334Speter va_end (ap); 186718334Speter} 186818334Speter 186918334Speter/* Report an error at the line number of the insn INSN. 187018334Speter This is used only when INSN is an `asm' with operands, 187118334Speter and each ASM_OPERANDS records its own source file and line. */ 187218334Speter 187318334Speterstatic void 187452558Sobrienv_error_for_asm (insn, msgid, ap) 187518334Speter rtx insn; 187652558Sobrien const char *msgid; 187718334Speter va_list ap; 187818334Speter{ 187918334Speter char *file; 188018334Speter int line; 188118334Speter 188218334Speter count_error (0); 188318334Speter file_and_line_for_asm (insn, &file, &line); 188418334Speter report_error_function (file); 188552558Sobrien v_message_with_file_and_line (file, line, 0, msgid, ap); 188618334Speter} 188718334Speter 188818334Spetervoid 188952558Sobrienerror_for_asm VPROTO((rtx insn, const char *msgid, ...)) 189018334Speter{ 189152558Sobrien#ifndef ANSI_PROTOTYPES 189218334Speter rtx insn; 189352558Sobrien const char *msgid; 189418334Speter#endif 189518334Speter va_list ap; 189618334Speter 189752558Sobrien VA_START (ap, msgid); 189818334Speter 189952558Sobrien#ifndef ANSI_PROTOTYPES 190018334Speter insn = va_arg (ap, rtx); 190152558Sobrien msgid = va_arg (ap, const char *); 190218334Speter#endif 190318334Speter 190452558Sobrien v_error_for_asm (insn, msgid, ap); 190518334Speter va_end (ap); 190618334Speter} 190718334Speter 190818334Speter/* Report an error at the current line number. */ 190918334Speter 191018334Speterstatic void 191152558Sobrienverror (msgid, ap) 191252558Sobrien const char *msgid; 191318334Speter va_list ap; 191418334Speter{ 191552558Sobrien v_error_with_file_and_line (input_filename, lineno, msgid, ap); 191618334Speter} 191718334Speter 191818334Spetervoid 191952558Sobrienerror VPROTO((const char *msgid, ...)) 192018334Speter{ 192152558Sobrien#ifndef ANSI_PROTOTYPES 192252558Sobrien const char *msgid; 192318334Speter#endif 192418334Speter va_list ap; 192518334Speter 192652558Sobrien VA_START (ap, msgid); 192718334Speter 192852558Sobrien#ifndef ANSI_PROTOTYPES 192952558Sobrien msgid = va_arg (ap, const char *); 193018334Speter#endif 193118334Speter 193252558Sobrien verror (msgid, ap); 193318334Speter va_end (ap); 193418334Speter} 193518334Speter 193618334Speter/* Report a fatal error at the current line number. */ 193718334Speter 193818334Speterstatic void 193952558Sobrienvfatal (msgid, ap) 194052558Sobrien const char *msgid; 194118334Speter va_list ap; 194218334Speter{ 194352558Sobrien verror (msgid, ap); 194418334Speter exit (FATAL_EXIT_CODE); 194518334Speter} 194618334Speter 194718334Spetervoid 194852558Sobrienfatal VPROTO((const char *msgid, ...)) 194918334Speter{ 195052558Sobrien#ifndef ANSI_PROTOTYPES 195152558Sobrien const char *msgid; 195218334Speter#endif 195318334Speter va_list ap; 195418334Speter 195552558Sobrien VA_START (ap, msgid); 195618334Speter 195752558Sobrien#ifndef ANSI_PROTOTYPES 195852558Sobrien msgid = va_arg (ap, const char *); 195918334Speter#endif 196018334Speter 196152558Sobrien vfatal (msgid, ap); 196218334Speter va_end (ap); 196318334Speter} 196418334Speter 196518334Speter/* Report a warning at line LINE of file FILE. */ 196618334Speter 196718334Speterstatic void 196852558Sobrienv_warning_with_file_and_line (file, line, msgid, ap) 196952558Sobrien const char *file; 197018334Speter int line; 197152558Sobrien const char *msgid; 197218334Speter va_list ap; 197318334Speter{ 197418334Speter if (count_error (1)) 197518334Speter { 197618334Speter report_error_function (file); 197752558Sobrien v_message_with_file_and_line (file, line, 1, msgid, ap); 197818334Speter } 197918334Speter} 198018334Speter 198118334Spetervoid 198252558Sobrienwarning_with_file_and_line VPROTO((const char *file, int line, 198352558Sobrien const char *msgid, ...)) 198418334Speter{ 198552558Sobrien#ifndef ANSI_PROTOTYPES 198652558Sobrien const char *file; 198718334Speter int line; 198852558Sobrien const char *msgid; 198918334Speter#endif 199018334Speter va_list ap; 199118334Speter 199252558Sobrien VA_START (ap, msgid); 199318334Speter 199452558Sobrien#ifndef ANSI_PROTOTYPES 199552558Sobrien file = va_arg (ap, const char *); 199618334Speter line = va_arg (ap, int); 199752558Sobrien msgid = va_arg (ap, const char *); 199818334Speter#endif 199918334Speter 200052558Sobrien v_warning_with_file_and_line (file, line, msgid, ap); 200118334Speter va_end (ap); 200218334Speter} 200318334Speter 200418334Speter/* Report a warning at the declaration DECL. 200552558Sobrien MSGID is a format string which uses %s to substitute the declaration 200618334Speter name; subsequent substitutions are a la printf. */ 200718334Speter 200818334Speterstatic void 200952558Sobrienv_warning_with_decl (decl, msgid, ap) 201018334Speter tree decl; 201152558Sobrien const char *msgid; 201218334Speter va_list ap; 201318334Speter{ 201418334Speter if (count_error (1)) 201518334Speter { 201618334Speter report_error_function (DECL_SOURCE_FILE (decl)); 201752558Sobrien v_message_with_decl (decl, 1, msgid, ap); 201818334Speter } 201918334Speter} 202018334Speter 202118334Spetervoid 202252558Sobrienwarning_with_decl VPROTO((tree decl, const char *msgid, ...)) 202318334Speter{ 202452558Sobrien#ifndef ANSI_PROTOTYPES 202518334Speter tree decl; 202652558Sobrien const char *msgid; 202718334Speter#endif 202818334Speter va_list ap; 202918334Speter 203052558Sobrien VA_START (ap, msgid); 203118334Speter 203252558Sobrien#ifndef ANSI_PROTOTYPES 203318334Speter decl = va_arg (ap, tree); 203452558Sobrien msgid = va_arg (ap, const char *); 203518334Speter#endif 203618334Speter 203752558Sobrien v_warning_with_decl (decl, msgid, ap); 203818334Speter va_end (ap); 203918334Speter} 204018334Speter 204118334Speter/* Report a warning at the line number of the insn INSN. 204218334Speter This is used only when INSN is an `asm' with operands, 204318334Speter and each ASM_OPERANDS records its own source file and line. */ 204418334Speter 204518334Speterstatic void 204652558Sobrienv_warning_for_asm (insn, msgid, ap) 204718334Speter rtx insn; 204852558Sobrien const char *msgid; 204918334Speter va_list ap; 205018334Speter{ 205118334Speter if (count_error (1)) 205218334Speter { 205318334Speter char *file; 205418334Speter int line; 205518334Speter 205618334Speter file_and_line_for_asm (insn, &file, &line); 205718334Speter report_error_function (file); 205852558Sobrien v_message_with_file_and_line (file, line, 1, msgid, ap); 205918334Speter } 206018334Speter} 206118334Speter 206218334Spetervoid 206352558Sobrienwarning_for_asm VPROTO((rtx insn, const char *msgid, ...)) 206418334Speter{ 206552558Sobrien#ifndef ANSI_PROTOTYPES 206618334Speter rtx insn; 206752558Sobrien const char *msgid; 206818334Speter#endif 206918334Speter va_list ap; 207018334Speter 207152558Sobrien VA_START (ap, msgid); 207218334Speter 207352558Sobrien#ifndef ANSI_PROTOTYPES 207418334Speter insn = va_arg (ap, rtx); 207552558Sobrien msgid = va_arg (ap, const char *); 207618334Speter#endif 207718334Speter 207852558Sobrien v_warning_for_asm (insn, msgid, ap); 207918334Speter va_end (ap); 208018334Speter} 208118334Speter 208218334Speter/* Report a warning at the current line number. */ 208318334Speter 208418334Speterstatic void 208552558Sobrienvwarning (msgid, ap) 208652558Sobrien const char *msgid; 208718334Speter va_list ap; 208818334Speter{ 208952558Sobrien v_warning_with_file_and_line (input_filename, lineno, msgid, ap); 209018334Speter} 209118334Speter 209218334Spetervoid 209352558Sobrienwarning VPROTO((const char *msgid, ...)) 209418334Speter{ 209552558Sobrien#ifndef ANSI_PROTOTYPES 209652558Sobrien const char *msgid; 209718334Speter#endif 209818334Speter va_list ap; 209918334Speter 210052558Sobrien VA_START (ap, msgid); 210118334Speter 210252558Sobrien#ifndef ANSI_PROTOTYPES 210352558Sobrien msgid = va_arg (ap, const char *); 210418334Speter#endif 210518334Speter 210652558Sobrien vwarning (msgid, ap); 210718334Speter va_end (ap); 210818334Speter} 210918334Speter 211018334Speter/* These functions issue either warnings or errors depending on 211118334Speter -pedantic-errors. */ 211218334Speter 211318334Speterstatic void 211452558Sobrienvpedwarn (msgid, ap) 211552558Sobrien const char *msgid; 211618334Speter va_list ap; 211718334Speter{ 211818334Speter if (flag_pedantic_errors) 211952558Sobrien verror (msgid, ap); 212018334Speter else 212152558Sobrien vwarning (msgid, ap); 212218334Speter} 212318334Speter 212418334Spetervoid 212552558Sobrienpedwarn VPROTO((const char *msgid, ...)) 212618334Speter{ 212752558Sobrien#ifndef ANSI_PROTOTYPES 212852558Sobrien const char *msgid; 212918334Speter#endif 213018334Speter va_list ap; 213118334Speter 213252558Sobrien VA_START (ap, msgid); 213318334Speter 213452558Sobrien#ifndef ANSI_PROTOTYPES 213552558Sobrien msgid = va_arg (ap, const char *); 213618334Speter#endif 213718334Speter 213852558Sobrien vpedwarn (msgid, ap); 213918334Speter va_end (ap); 214018334Speter} 214118334Speter 214218334Speterstatic void 214352558Sobrienv_pedwarn_with_decl (decl, msgid, ap) 214418334Speter tree decl; 214552558Sobrien const char *msgid; 214618334Speter va_list ap; 214718334Speter{ 214818334Speter /* We don't want -pedantic-errors to cause the compilation to fail from 214918334Speter "errors" in system header files. Sometimes fixincludes can't fix what's 215018334Speter broken (eg: unsigned char bitfields - fixing it may change the alignment 215118334Speter which will cause programs to mysteriously fail because the C library 215218334Speter or kernel uses the original layout). There's no point in issuing a 215318334Speter warning either, it's just unnecessary noise. */ 215418334Speter 215518334Speter if (! DECL_IN_SYSTEM_HEADER (decl)) 215618334Speter { 215718334Speter if (flag_pedantic_errors) 215852558Sobrien v_error_with_decl (decl, msgid, ap); 215918334Speter else 216052558Sobrien v_warning_with_decl (decl, msgid, ap); 216118334Speter } 216218334Speter} 216318334Speter 216418334Spetervoid 216552558Sobrienpedwarn_with_decl VPROTO((tree decl, const char *msgid, ...)) 216618334Speter{ 216752558Sobrien#ifndef ANSI_PROTOTYPES 216818334Speter tree decl; 216952558Sobrien const char *msgid; 217018334Speter#endif 217118334Speter va_list ap; 217218334Speter 217352558Sobrien VA_START (ap, msgid); 217418334Speter 217552558Sobrien#ifndef ANSI_PROTOTYPES 217618334Speter decl = va_arg (ap, tree); 217752558Sobrien msgid = va_arg (ap, const char *); 217818334Speter#endif 217918334Speter 218052558Sobrien v_pedwarn_with_decl (decl, msgid, ap); 218118334Speter va_end (ap); 218218334Speter} 218318334Speter 218418334Speterstatic void 218552558Sobrienv_pedwarn_with_file_and_line (file, line, msgid, ap) 218652558Sobrien const char *file; 218718334Speter int line; 218852558Sobrien const char *msgid; 218918334Speter va_list ap; 219018334Speter{ 219118334Speter if (flag_pedantic_errors) 219252558Sobrien v_error_with_file_and_line (file, line, msgid, ap); 219318334Speter else 219452558Sobrien v_warning_with_file_and_line (file, line, msgid, ap); 219518334Speter} 219618334Speter 219718334Spetervoid 219852558Sobrienpedwarn_with_file_and_line VPROTO((const char *file, int line, 219952558Sobrien const char *msgid, ...)) 220018334Speter{ 220152558Sobrien#ifndef ANSI_PROTOTYPES 220252558Sobrien const char *file; 220318334Speter int line; 220452558Sobrien const char *msgid; 220518334Speter#endif 220618334Speter va_list ap; 220718334Speter 220852558Sobrien VA_START (ap, msgid); 220918334Speter 221052558Sobrien#ifndef ANSI_PROTOTYPES 221152558Sobrien file = va_arg (ap, const char *); 221218334Speter line = va_arg (ap, int); 221352558Sobrien msgid = va_arg (ap, const char *); 221418334Speter#endif 221518334Speter 221652558Sobrien v_pedwarn_with_file_and_line (file, line, msgid, ap); 221718334Speter va_end (ap); 221818334Speter} 221918334Speter 222018334Speter/* Apologize for not implementing some feature. */ 222118334Speter 222218334Speterstatic void 222352558Sobrienvsorry (msgid, ap) 222452558Sobrien const char *msgid; 222518334Speter va_list ap; 222618334Speter{ 222718334Speter sorrycount++; 222818334Speter if (input_filename) 222918334Speter fprintf (stderr, "%s:%d: ", input_filename, lineno); 223018334Speter else 223118334Speter fprintf (stderr, "%s: ", progname); 223252558Sobrien notice ("sorry, not implemented: "); 223352558Sobrien vnotice (stderr, msgid, ap); 223418334Speter fputc ('\n', stderr); 223518334Speter} 223618334Speter 223718334Spetervoid 223852558Sobriensorry VPROTO((const char *msgid, ...)) 223918334Speter{ 224052558Sobrien#ifndef ANSI_PROTOTYPES 224152558Sobrien const char *msgid; 224218334Speter#endif 224318334Speter va_list ap; 224418334Speter 224552558Sobrien VA_START (ap, msgid); 224618334Speter 224752558Sobrien#ifndef ANSI_PROTOTYPES 224852558Sobrien msgid = va_arg (ap, const char *); 224918334Speter#endif 225018334Speter 225152558Sobrien vsorry (msgid, ap); 225218334Speter va_end (ap); 225318334Speter} 225452558Sobrien 225552558Sobrien/* Given a partial pathname as input, return another pathname that shares 225652558Sobrien no elements with the pathname of __FILE__. This is used by abort() to 225752558Sobrien print `Internal compiler error in expr.c' instead of `Internal compiler 225852558Sobrien error in ../../egcs/gcc/expr.c'. */ 225952558Sobrienconst char * 226052558Sobrientrim_filename (name) 226152558Sobrien const char *name; 226218334Speter{ 226352558Sobrien static const char *this_file = __FILE__; 226452558Sobrien const char *p = name, *q = this_file; 226518334Speter 226652558Sobrien while (*p == *q && *p != 0 && *q != 0) p++, q++; 226752558Sobrien while (p > name && p[-1] != DIR_SEPARATOR 226852558Sobrien#ifdef DIR_SEPARATOR_2 226952558Sobrien && p[-1] != DIR_SEPARATOR_2 227018334Speter#endif 227152558Sobrien ) 227252558Sobrien p--; 227318334Speter 227452558Sobrien return p; 227552558Sobrien} 227618334Speter 227718334Speter/* More 'friendly' abort that prints the line and file. 227818334Speter config.h can #define abort fancy_abort if you like that sort of thing. 227918334Speter 228018334Speter I don't think this is actually a good idea. 228118334Speter Other sorts of crashes will look a certain way. 228218334Speter It is a good thing if crashes from calling abort look the same way. 228318334Speter -- RMS */ 228418334Speter 228518334Spetervoid 228618334Speterfancy_abort () 228718334Speter{ 228818334Speter fatal ("internal gcc abort"); 228918334Speter} 229018334Speter 229118334Speter/* This calls abort and is used to avoid problems when abort if a macro. 229218334Speter It is used when we need to pass the address of abort. */ 229318334Speter 229418334Spetervoid 229518334Speterdo_abort () 229618334Speter{ 229718334Speter abort (); 229818334Speter} 229918334Speter 230018334Speter/* When `malloc.c' is compiled with `rcheck' defined, 230118334Speter it calls this function to report clobberage. */ 230218334Speter 230318334Spetervoid 230418334Speterbotch (s) 230552558Sobrien const char * s ATTRIBUTE_UNUSED; 230618334Speter{ 230718334Speter abort (); 230818334Speter} 230918334Speter 231018334Speter/* Same as `malloc' but report error if no memory available. */ 231118334Speter 231252558SobrienPTR 231318334Speterxmalloc (size) 231452558Sobrien size_t size; 231518334Speter{ 231652558Sobrien register PTR value; 231750615Sobrien 231850615Sobrien if (size == 0) 231950615Sobrien size = 1; 232050615Sobrien 232152558Sobrien value = (PTR) malloc (size); 232218334Speter if (value == 0) 232318334Speter fatal ("virtual memory exhausted"); 232418334Speter return value; 232518334Speter} 232618334Speter 232750615Sobrien/* Same as `calloc' but report error if no memory available. */ 232818334Speter 232952558SobrienPTR 233050615Sobrienxcalloc (size1, size2) 233152558Sobrien size_t size1, size2; 233250615Sobrien{ 233352558Sobrien register PTR value; 233450615Sobrien 233550615Sobrien if (size1 == 0 || size2 == 0) 233650615Sobrien size1 = size2 = 1; 233750615Sobrien 233852558Sobrien value = (PTR) calloc (size1, size2); 233950615Sobrien if (value == 0) 234050615Sobrien fatal ("virtual memory exhausted"); 234150615Sobrien return value; 234250615Sobrien} 234350615Sobrien 234450615Sobrien 234550615Sobrien/* Same as `realloc' but report error if no memory available. 234650615Sobrien Also handle null PTR even if the vendor realloc gets it wrong. */ 234750615Sobrien 234852558SobrienPTR 234918334Speterxrealloc (ptr, size) 235052558Sobrien PTR ptr; 235152558Sobrien size_t size; 235218334Speter{ 235352558Sobrien register PTR result; 235450615Sobrien 235550615Sobrien if (size == 0) 235650615Sobrien size = 1; 235750615Sobrien 235852558Sobrien result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size)); 235950615Sobrien 236018334Speter if (!result) 236118334Speter fatal ("virtual memory exhausted"); 236250615Sobrien 236318334Speter return result; 236418334Speter} 236550615Sobrien 236650615Sobrien/* Same as `strdup' but report error if no memory available. */ 236750615Sobrien 236850615Sobrienchar * 236950615Sobrienxstrdup (s) 237052558Sobrien register const char *s; 237150615Sobrien{ 237250615Sobrien register char *result = (char *) malloc (strlen (s) + 1); 237350615Sobrien 237450615Sobrien if (! result) 237550615Sobrien fatal ("virtual memory exhausted"); 237650615Sobrien strcpy (result, s); 237750615Sobrien return result; 237850615Sobrien} 237918334Speter 238018334Speter/* Return the logarithm of X, base 2, considering X unsigned, 238118334Speter if X is a power of 2. Otherwise, returns -1. 238218334Speter 238318334Speter This should be used via the `exact_log2' macro. */ 238418334Speter 238518334Speterint 238618334Speterexact_log2_wide (x) 238718334Speter register unsigned HOST_WIDE_INT x; 238818334Speter{ 238918334Speter register int log = 0; 239018334Speter /* Test for 0 or a power of 2. */ 239118334Speter if (x == 0 || x != (x & -x)) 239218334Speter return -1; 239318334Speter while ((x >>= 1) != 0) 239418334Speter log++; 239518334Speter return log; 239618334Speter} 239718334Speter 239818334Speter/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. 239918334Speter If X is 0, return -1. 240018334Speter 240118334Speter This should be used via the floor_log2 macro. */ 240218334Speter 240318334Speterint 240418334Speterfloor_log2_wide (x) 240518334Speter register unsigned HOST_WIDE_INT x; 240618334Speter{ 240718334Speter register int log = -1; 240818334Speter while (x != 0) 240918334Speter log++, 241018334Speter x >>= 1; 241118334Speter return log; 241218334Speter} 241318334Speter 241450615Sobrienstatic int float_handler_set; 241518334Speterint float_handled; 241618334Speterjmp_buf float_handler; 241718334Speter 241850615Sobrien/* Signals actually come here. */ 241950615Sobrien 242050615Sobrienstatic void 242150615Sobrienfloat_signal (signo) 242250615Sobrien /* If this is missing, some compilers complain. */ 242350615Sobrien int signo ATTRIBUTE_UNUSED; 242450615Sobrien{ 242550615Sobrien if (float_handled == 0) 242650615Sobrien abort (); 242750615Sobrien#if defined (USG) || defined (hpux) 242850615Sobrien signal (SIGFPE, float_signal); /* re-enable the signal catcher */ 242950615Sobrien#endif 243050615Sobrien float_handled = 0; 243150615Sobrien signal (SIGFPE, float_signal); 243250615Sobrien longjmp (float_handler, 1); 243350615Sobrien} 243450615Sobrien 243518334Speter/* Specify where to longjmp to when a floating arithmetic error happens. 243618334Speter If HANDLER is 0, it means don't handle the errors any more. */ 243718334Speter 243818334Spetervoid 243918334Speterset_float_handler (handler) 244018334Speter jmp_buf handler; 244118334Speter{ 244218334Speter float_handled = (handler != 0); 244318334Speter if (handler) 244418334Speter bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler)); 244550615Sobrien 244650615Sobrien if (float_handled && ! float_handler_set) 244750615Sobrien { 244850615Sobrien signal (SIGFPE, float_signal); 244950615Sobrien float_handler_set = 1; 245050615Sobrien } 245118334Speter} 245218334Speter 245352558Sobrien/* This is a wrapper function for code which might elicit an 245452558Sobrien arithmetic exception. That code should be passed in as a function 245552558Sobrien pointer FN, and one argument DATA. DATA is usually a struct which 245652558Sobrien contains the real input and output for function FN. This function 245752558Sobrien returns 0 (failure) if longjmp was called (i.e. an exception 245852558Sobrien occured.) It returns 1 (success) otherwise. */ 245952558Sobrien 246052558Sobrienint 246152558Sobriendo_float_handler (fn, data) 246252558Sobrien void (*fn) PROTO ((PTR)); 246352558Sobrien PTR data; 246452558Sobrien{ 246552558Sobrien jmp_buf buf; 246652558Sobrien 246752558Sobrien if (setjmp (buf)) 246852558Sobrien { 246952558Sobrien /* We got here via longjmp() caused by an exception in function fn() */ 247052558Sobrien set_float_handler (NULL); 247152558Sobrien return 0; 247252558Sobrien } 247352558Sobrien 247452558Sobrien set_float_handler (buf); 247552558Sobrien (*fn)(data); 247652558Sobrien set_float_handler (NULL); 247752558Sobrien return 1; 247852558Sobrien} 247952558Sobrien 248018334Speter/* Specify, in HANDLER, where to longjmp to when a floating arithmetic 248118334Speter error happens, pushing the previous specification into OLD_HANDLER. 248218334Speter Return an indication of whether there was a previous handler in effect. */ 248318334Speter 248418334Speterint 248518334Speterpush_float_handler (handler, old_handler) 248618334Speter jmp_buf handler, old_handler; 248718334Speter{ 248818334Speter int was_handled = float_handled; 248918334Speter 249018334Speter float_handled = 1; 249118334Speter if (was_handled) 249252558Sobrien memcpy ((char *) old_handler, (char *) float_handler, 249318334Speter sizeof (float_handler)); 249418334Speter 249552558Sobrien memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler)); 249618334Speter return was_handled; 249718334Speter} 249818334Speter 249918334Speter/* Restore the previous specification of whether and where to longjmp to 250018334Speter when a floating arithmetic error happens. */ 250118334Speter 250218334Spetervoid 250318334Speterpop_float_handler (handled, handler) 250418334Speter int handled; 250518334Speter jmp_buf handler; 250618334Speter{ 250718334Speter float_handled = handled; 250818334Speter if (handled) 250918334Speter bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler)); 251018334Speter} 251118334Speter 251218334Speter/* Handler for SIGPIPE. */ 251318334Speter 251418334Speterstatic void 251518334Speterpipe_closed (signo) 251618334Speter /* If this is missing, some compilers complain. */ 251750615Sobrien int signo ATTRIBUTE_UNUSED; 251818334Speter{ 251918334Speter fatal ("output pipe has been closed"); 252018334Speter} 252118334Speter 252218334Speter/* Strip off a legitimate source ending from the input string NAME of 252318334Speter length LEN. Rather than having to know the names used by all of 252450615Sobrien our front ends, we strip off an ending of a period followed by 252550615Sobrien up to five characters. (Java uses ".class".) */ 252618334Speter 252718334Spetervoid 252818334Speterstrip_off_ending (name, len) 252918334Speter char *name; 253018334Speter int len; 253118334Speter{ 253250615Sobrien int i; 253350615Sobrien for (i = 2; i < 6 && len > i; i++) 253450615Sobrien { 253550615Sobrien if (name[len - i] == '.') 253650615Sobrien { 253750615Sobrien name[len - i] = '\0'; 253850615Sobrien break; 253950615Sobrien } 254050615Sobrien } 254118334Speter} 254218334Speter 254318334Speter/* Output a quoted string. */ 254450615Sobrien 254518334Spetervoid 254618334Speteroutput_quoted_string (asm_file, string) 254718334Speter FILE *asm_file; 254852558Sobrien const char *string; 254918334Speter{ 255050615Sobrien#ifdef OUTPUT_QUOTED_STRING 255150615Sobrien OUTPUT_QUOTED_STRING (asm_file, string); 255250615Sobrien#else 255318334Speter char c; 255418334Speter 255518334Speter putc ('\"', asm_file); 255618334Speter while ((c = *string++) != 0) 255718334Speter { 255818334Speter if (c == '\"' || c == '\\') 255918334Speter putc ('\\', asm_file); 256018334Speter putc (c, asm_file); 256118334Speter } 256218334Speter putc ('\"', asm_file); 256350615Sobrien#endif 256418334Speter} 256518334Speter 256618334Speter/* Output a file name in the form wanted by System V. */ 256718334Speter 256818334Spetervoid 256918334Speteroutput_file_directive (asm_file, input_name) 257018334Speter FILE *asm_file; 257152558Sobrien const char *input_name; 257218334Speter{ 257318334Speter int len = strlen (input_name); 257452558Sobrien const char *na = input_name + len; 257518334Speter 257618334Speter /* NA gets INPUT_NAME sans directory names. */ 257718334Speter while (na > input_name) 257818334Speter { 257918334Speter if (na[-1] == '/') 258018334Speter break; 258152558Sobrien#ifdef DIR_SEPARATOR 258252558Sobrien if (na[-1] == DIR_SEPARATOR) 258352558Sobrien break; 258452558Sobrien#endif 258518334Speter na--; 258618334Speter } 258718334Speter 258818334Speter#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME 258918334Speter ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na); 259018334Speter#else 259118334Speter#ifdef ASM_OUTPUT_SOURCE_FILENAME 259218334Speter ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); 259318334Speter#else 259418334Speter fprintf (asm_file, "\t.file\t"); 259518334Speter output_quoted_string (asm_file, na); 259618334Speter fputc ('\n', asm_file); 259718334Speter#endif 259818334Speter#endif 259918334Speter} 260018334Speter 260152558Sobrien#ifdef ASM_IDENTIFY_LANGUAGE 260250615Sobrien/* Routine to build language identifier for object file. */ 260318334Speterstatic void 260418334Speteroutput_lang_identify (asm_out_file) 260518334Speter FILE *asm_out_file; 260618334Speter{ 260718334Speter int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1; 260818334Speter char *s = (char *) alloca (len); 260918334Speter sprintf (s, "__gnu_compiled_%s", lang_identify ()); 261018334Speter ASM_OUTPUT_LABEL (asm_out_file, s); 261118334Speter} 261252558Sobrien#endif 261318334Speter 261418334Speter/* Routine to open a dump file. */ 261550615Sobrienstatic void 261650615Sobrienopen_dump_file (suffix, function_name) 261752558Sobrien const char *suffix; 261852558Sobrien const char *function_name; 261918334Speter{ 262050615Sobrien char *dumpname; 262118334Speter 262250615Sobrien TIMEVAR 262350615Sobrien (dump_time, 262450615Sobrien { 262550615Sobrien dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1); 262650615Sobrien 262750615Sobrien if (rtl_dump_file != NULL) 262850615Sobrien fclose (rtl_dump_file); 262950615Sobrien 263050615Sobrien strcpy (dumpname, dump_base_name); 263150615Sobrien strcat (dumpname, suffix); 263250615Sobrien 263350615Sobrien rtl_dump_file = fopen (dumpname, "a"); 263450615Sobrien 263550615Sobrien if (rtl_dump_file == NULL) 263650615Sobrien pfatal_with_name (dumpname); 263750615Sobrien 263850615Sobrien free (dumpname); 263950615Sobrien 264050615Sobrien if (function_name) 264150615Sobrien fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name); 264250615Sobrien }); 264350615Sobrien 264450615Sobrien return; 264550615Sobrien} 264650615Sobrien 264750615Sobrien/* Routine to close a dump file. */ 264850615Sobrienstatic void 264950615Sobrienclose_dump_file (func, insns) 265050615Sobrien void (*func) PROTO ((FILE *, rtx)); 265150615Sobrien rtx insns; 265250615Sobrien{ 265350615Sobrien TIMEVAR 265450615Sobrien (dump_time, 265550615Sobrien { 265650615Sobrien if (func) 265750615Sobrien func (rtl_dump_file, insns); 265850615Sobrien 265950615Sobrien fflush (rtl_dump_file); 266050615Sobrien fclose (rtl_dump_file); 266150615Sobrien 266250615Sobrien rtl_dump_file = NULL; 266350615Sobrien }); 266450615Sobrien 266550615Sobrien return; 266650615Sobrien} 266750615Sobrien 266850615Sobrien/* Routine to dump rtl into a file. */ 266950615Sobrienstatic void 267050615Sobriendump_rtl (suffix, decl, func, insns) 267152558Sobrien const char *suffix; 267250615Sobrien tree decl; 267350615Sobrien void (*func) PROTO ((FILE *, rtx)); 267450615Sobrien rtx insns; 267550615Sobrien{ 267650615Sobrien open_dump_file (suffix, decl_printable_name (decl, 2)); 267750615Sobrien close_dump_file (func, insns); 267850615Sobrien} 267950615Sobrien 268050615Sobrien/* Routine to empty a dump file. */ 268150615Sobrienstatic void 268250615Sobrienclean_dump_file (suffix) 268352558Sobrien const char *suffix; 268450615Sobrien{ 268552558Sobrien char *dumpname; 268650615Sobrien 268750615Sobrien dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1); 268850615Sobrien 268950615Sobrien strcpy (dumpname, dump_base_name); 269018334Speter strcat (dumpname, suffix); 269150615Sobrien 269250615Sobrien rtl_dump_file = fopen (dumpname, "w"); 269350615Sobrien 269450615Sobrien if (rtl_dump_file == NULL) 269550615Sobrien pfatal_with_name (dumpname); 269650615Sobrien 269750615Sobrien free (dumpname); 269850615Sobrien 269950615Sobrien fclose (rtl_dump_file); 270050615Sobrien rtl_dump_file = NULL; 270150615Sobrien 270250615Sobrien return; 270318334Speter} 270418334Speter 270552558Sobrien/* Do any final processing required for the declarations in VEC, of 270652558Sobrien which there are LEN. We write out inline functions and variables 270752558Sobrien that have been deferred until this point, but which are required. 270852558Sobrien Returns non-zero if anything was put out. */ 270952558Sobrienint 271052558Sobrienwrapup_global_declarations (vec, len) 271152558Sobrien tree *vec; 271252558Sobrien int len; 271352558Sobrien{ 271452558Sobrien tree decl; 271552558Sobrien int i; 271652558Sobrien int reconsider; 271752558Sobrien int output_something = 0; 271850615Sobrien 271952558Sobrien for (i = 0; i < len; i++) 272052558Sobrien { 272152558Sobrien decl = vec[i]; 272252558Sobrien 272352558Sobrien /* We're not deferring this any longer. */ 272452558Sobrien DECL_DEFER_OUTPUT (decl) = 0; 272552558Sobrien 272652558Sobrien if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0 272752558Sobrien && incomplete_decl_finalize_hook != 0) 272852558Sobrien (*incomplete_decl_finalize_hook) (decl); 272952558Sobrien } 273052558Sobrien 273152558Sobrien /* Now emit any global variables or functions that we have been 273252558Sobrien putting off. We need to loop in case one of the things emitted 273352558Sobrien here references another one which comes earlier in the list. */ 273452558Sobrien do 273552558Sobrien { 273652558Sobrien reconsider = 0; 273752558Sobrien for (i = 0; i < len; i++) 273852558Sobrien { 273952558Sobrien decl = vec[i]; 274052558Sobrien 274152558Sobrien if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl)) 274252558Sobrien continue; 274352558Sobrien 274452558Sobrien /* Don't write out static consts, unless we still need them. 274552558Sobrien 274652558Sobrien We also keep static consts if not optimizing (for debugging), 274752558Sobrien unless the user specified -fno-keep-static-consts. 274852558Sobrien ??? They might be better written into the debug information. 274952558Sobrien This is possible when using DWARF. 275052558Sobrien 275152558Sobrien A language processor that wants static constants to be always 275252558Sobrien written out (even if it is not used) is responsible for 275352558Sobrien calling rest_of_decl_compilation itself. E.g. the C front-end 275452558Sobrien calls rest_of_decl_compilation from finish_decl. 275552558Sobrien One motivation for this is that is conventional in some 275652558Sobrien environments to write things like: 275752558Sobrien static const char rcsid[] = "... version string ..."; 275852558Sobrien intending to force the string to be in the executable. 275952558Sobrien 276052558Sobrien A language processor that would prefer to have unneeded 276152558Sobrien static constants "optimized away" would just defer writing 276252558Sobrien them out until here. E.g. C++ does this, because static 276352558Sobrien constants are often defined in header files. 276452558Sobrien 276552558Sobrien ??? A tempting alternative (for both C and C++) would be 276652558Sobrien to force a constant to be written if and only if it is 276752558Sobrien defined in a main file, as opposed to an include file. */ 276852558Sobrien 276952558Sobrien if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) 277052558Sobrien && (! TREE_READONLY (decl) 277152558Sobrien || TREE_PUBLIC (decl) 277252558Sobrien || (!optimize && flag_keep_static_consts) 277352558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 277452558Sobrien { 277552558Sobrien reconsider = 1; 277652558Sobrien rest_of_decl_compilation (decl, NULL_PTR, 1, 1); 277752558Sobrien } 277852558Sobrien 277952558Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 278052558Sobrien && DECL_INITIAL (decl) != 0 278152558Sobrien && DECL_SAVED_INSNS (decl) != 0 278252558Sobrien && (flag_keep_inline_functions 278352558Sobrien || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) 278452558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 278552558Sobrien { 278652558Sobrien reconsider = 1; 278752558Sobrien temporary_allocation (); 278852558Sobrien output_inline_function (decl); 278952558Sobrien permanent_allocation (1); 279052558Sobrien } 279152558Sobrien } 279252558Sobrien 279352558Sobrien if (reconsider) 279452558Sobrien output_something = 1; 279552558Sobrien } 279652558Sobrien while (reconsider); 279752558Sobrien 279852558Sobrien return output_something; 279952558Sobrien} 280052558Sobrien 280152558Sobrien/* Issue appropriate warnings for the global declarations in VEC (of 280252558Sobrien which there are LEN). Output debugging information for them. */ 280352558Sobrienvoid 280452558Sobriencheck_global_declarations (vec, len) 280552558Sobrien tree *vec; 280652558Sobrien int len; 280752558Sobrien{ 280852558Sobrien tree decl; 280952558Sobrien int i; 281052558Sobrien 281152558Sobrien for (i = 0; i < len; i++) 281252558Sobrien { 281352558Sobrien decl = vec[i]; 281452558Sobrien 281552558Sobrien if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) 281652558Sobrien && ! TREE_ASM_WRITTEN (decl)) 281752558Sobrien /* Cancel the RTL for this decl so that, if debugging info 281852558Sobrien output for global variables is still to come, 281952558Sobrien this one will be omitted. */ 282052558Sobrien DECL_RTL (decl) = NULL; 282152558Sobrien 282252558Sobrien /* Warn about any function 282352558Sobrien declared static but not defined. 282452558Sobrien We don't warn about variables, 282552558Sobrien because many programs have static variables 282652558Sobrien that exist only to get some text into the object file. */ 282752558Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 282852558Sobrien && (warn_unused 282952558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 283052558Sobrien && DECL_INITIAL (decl) == 0 283152558Sobrien && DECL_EXTERNAL (decl) 283252558Sobrien && ! DECL_ARTIFICIAL (decl) 283352558Sobrien && ! TREE_PUBLIC (decl)) 283452558Sobrien { 283552558Sobrien if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 283652558Sobrien pedwarn_with_decl (decl, 283752558Sobrien "`%s' used but never defined"); 283852558Sobrien else 283952558Sobrien warning_with_decl (decl, 284052558Sobrien "`%s' declared `static' but never defined"); 284152558Sobrien /* This symbol is effectively an "extern" declaration now. */ 284252558Sobrien TREE_PUBLIC (decl) = 1; 284352558Sobrien assemble_external (decl); 284452558Sobrien } 284552558Sobrien 284652558Sobrien /* Warn about static fns or vars defined but not used, 284752558Sobrien but not about inline functions or static consts 284852558Sobrien since defining those in header files is normal practice. */ 284952558Sobrien if (warn_unused 285052558Sobrien && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl)) 285152558Sobrien || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) 285252558Sobrien && ! DECL_IN_SYSTEM_HEADER (decl) 285352558Sobrien && ! DECL_EXTERNAL (decl) 285452558Sobrien && ! TREE_PUBLIC (decl) 285552558Sobrien && ! TREE_USED (decl) 285652558Sobrien && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) 285752558Sobrien /* The TREE_USED bit for file-scope decls 285852558Sobrien is kept in the identifier, to handle multiple 285952558Sobrien external decls in different scopes. */ 286052558Sobrien && ! TREE_USED (DECL_NAME (decl))) 286152558Sobrien warning_with_decl (decl, "`%s' defined but not used"); 286252558Sobrien 286352558Sobrien#ifdef SDB_DEBUGGING_INFO 286452558Sobrien /* The COFF linker can move initialized global vars to the end. 286552558Sobrien And that can screw up the symbol ordering. 286652558Sobrien By putting the symbols in that order to begin with, 286752558Sobrien we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */ 286852558Sobrien if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL 286952558Sobrien && TREE_PUBLIC (decl) && DECL_INITIAL (decl) 287052558Sobrien && ! DECL_EXTERNAL (decl) 287152558Sobrien && DECL_RTL (decl) != 0) 287252558Sobrien TIMEVAR (symout_time, sdbout_symbol (decl, 0)); 287352558Sobrien 287452558Sobrien /* Output COFF information for non-global 287552558Sobrien file-scope initialized variables. */ 287652558Sobrien if (write_symbols == SDB_DEBUG 287752558Sobrien && TREE_CODE (decl) == VAR_DECL 287852558Sobrien && DECL_INITIAL (decl) 287952558Sobrien && ! DECL_EXTERNAL (decl) 288052558Sobrien && DECL_RTL (decl) != 0 288152558Sobrien && GET_CODE (DECL_RTL (decl)) == MEM) 288252558Sobrien TIMEVAR (symout_time, sdbout_toplevel_data (decl)); 288352558Sobrien#endif /* SDB_DEBUGGING_INFO */ 288452558Sobrien#ifdef DWARF_DEBUGGING_INFO 288552558Sobrien /* Output DWARF information for file-scope tentative data object 288652558Sobrien declarations, file-scope (extern) function declarations (which 288752558Sobrien had no corresponding body) and file-scope tagged type declarations 288852558Sobrien and definitions which have not yet been forced out. */ 288952558Sobrien 289052558Sobrien if (write_symbols == DWARF_DEBUG 289152558Sobrien && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) 289252558Sobrien TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1)); 289352558Sobrien#endif 289452558Sobrien#ifdef DWARF2_DEBUGGING_INFO 289552558Sobrien /* Output DWARF2 information for file-scope tentative data object 289652558Sobrien declarations, file-scope (extern) function declarations (which 289752558Sobrien had no corresponding body) and file-scope tagged type declarations 289852558Sobrien and definitions which have not yet been forced out. */ 289952558Sobrien 290052558Sobrien if (write_symbols == DWARF2_DEBUG 290152558Sobrien && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))) 290252558Sobrien TIMEVAR (symout_time, dwarf2out_decl (decl)); 290352558Sobrien#endif 290452558Sobrien } 290552558Sobrien} 290652558Sobrien 290718334Speter/* Compile an entire file of output from cpp, named NAME. 290818334Speter Write a file of assembly output and various debugging dumps. */ 290918334Speter 291018334Speterstatic void 291118334Spetercompile_file (name) 291218334Speter char *name; 291318334Speter{ 291418334Speter tree globals; 291518334Speter int start_time; 291618334Speter 291718334Speter int name_specified = name != 0; 291818334Speter 291918334Speter if (dump_base_name == 0) 292018334Speter dump_base_name = name ? name : "gccdump"; 292118334Speter 292218334Speter parse_time = 0; 292318334Speter varconst_time = 0; 292418334Speter integration_time = 0; 292518334Speter jump_time = 0; 292618334Speter cse_time = 0; 292750615Sobrien gcse_time = 0; 292818334Speter loop_time = 0; 292918334Speter cse2_time = 0; 293050615Sobrien branch_prob_time = 0; 293118334Speter flow_time = 0; 293218334Speter combine_time = 0; 293350615Sobrien regmove_time = 0; 293418334Speter sched_time = 0; 293518334Speter local_alloc_time = 0; 293618334Speter global_alloc_time = 0; 293752558Sobrien flow2_time = 0; 293818334Speter sched2_time = 0; 293950615Sobrien#ifdef DELAY_SLOTS 294018334Speter dbr_sched_time = 0; 294150615Sobrien#endif 294218334Speter shorten_branch_time = 0; 294318334Speter stack_reg_time = 0; 294418334Speter final_time = 0; 294518334Speter symout_time = 0; 294618334Speter dump_time = 0; 294718334Speter 294818334Speter /* Initialize data in various passes. */ 294918334Speter 295018334Speter init_obstacks (); 295118334Speter init_tree_codes (); 295250615Sobrien name = init_parse (name); 295318334Speter init_rtl (); 295418334Speter init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL 295550615Sobrien || debug_info_level == DINFO_LEVEL_VERBOSE 295650615Sobrien || flag_test_coverage); 295718334Speter init_regs (); 295818334Speter init_decl_processing (); 295918334Speter init_optabs (); 296018334Speter init_stmt (); 296118334Speter init_expmed (); 296218334Speter init_expr_once (); 296318334Speter init_loop (); 296418334Speter init_reload (); 296550615Sobrien init_alias_once (); 296618334Speter 296718334Speter if (flag_caller_saves) 296818334Speter init_caller_save (); 296918334Speter 297018334Speter /* If auxiliary info generation is desired, open the output file. 297118334Speter This goes in the same directory as the source file--unlike 297218334Speter all the other output files. */ 297318334Speter if (flag_gen_aux_info) 297418334Speter { 297518334Speter aux_info_file = fopen (aux_info_file_name, "w"); 297618334Speter if (aux_info_file == 0) 297718334Speter pfatal_with_name (aux_info_file_name); 297818334Speter } 297918334Speter 298052558Sobrien /* Clear the dump files. */ 298118334Speter if (rtl_dump) 298250615Sobrien clean_dump_file (".rtl"); 298318334Speter if (jump_opt_dump) 298452558Sobrien { 298552558Sobrien clean_dump_file (".jump"); 298652558Sobrien if (graph_dump_format != no_graph) 298752558Sobrien clean_graph_dump_file (dump_base_name, ".jump"); 298852558Sobrien } 298950615Sobrien if (addressof_dump) 299052558Sobrien { 299152558Sobrien clean_dump_file (".addressof"); 299252558Sobrien if (graph_dump_format != no_graph) 299352558Sobrien clean_graph_dump_file (dump_base_name, ".addressof"); 299452558Sobrien } 299518334Speter if (cse_dump) 299652558Sobrien { 299752558Sobrien clean_dump_file (".cse"); 299852558Sobrien if (graph_dump_format != no_graph) 299952558Sobrien clean_graph_dump_file (dump_base_name, ".cse"); 300052558Sobrien } 300118334Speter if (loop_dump) 300252558Sobrien { 300352558Sobrien clean_dump_file (".loop"); 300452558Sobrien if (graph_dump_format != no_graph) 300552558Sobrien clean_graph_dump_file (dump_base_name, ".loop"); 300652558Sobrien } 300718334Speter if (cse2_dump) 300852558Sobrien { 300952558Sobrien clean_dump_file (".cse2"); 301052558Sobrien if (graph_dump_format != no_graph) 301152558Sobrien clean_graph_dump_file (dump_base_name, ".cse2"); 301252558Sobrien } 301350615Sobrien if (branch_prob_dump) 301452558Sobrien { 301552558Sobrien clean_dump_file (".bp"); 301652558Sobrien if (graph_dump_format != no_graph) 301752558Sobrien clean_graph_dump_file (dump_base_name, ".bp"); 301852558Sobrien } 301918334Speter if (flow_dump) 302052558Sobrien { 302152558Sobrien clean_dump_file (".flow"); 302252558Sobrien if (graph_dump_format != no_graph) 302352558Sobrien clean_graph_dump_file (dump_base_name, ".flow"); 302452558Sobrien } 302518334Speter if (combine_dump) 302652558Sobrien { 302752558Sobrien clean_dump_file (".combine"); 302852558Sobrien if (graph_dump_format != no_graph) 302952558Sobrien clean_graph_dump_file (dump_base_name, ".combine"); 303052558Sobrien } 303150615Sobrien if (regmove_dump) 303252558Sobrien { 303352558Sobrien clean_dump_file (".regmove"); 303452558Sobrien if (graph_dump_format != no_graph) 303552558Sobrien clean_graph_dump_file (dump_base_name, ".regmove"); 303652558Sobrien } 303718334Speter if (sched_dump) 303852558Sobrien { 303952558Sobrien clean_dump_file (".sched"); 304052558Sobrien if (graph_dump_format != no_graph) 304152558Sobrien clean_graph_dump_file (dump_base_name, ".sched"); 304252558Sobrien } 304318334Speter if (local_reg_dump) 304452558Sobrien { 304552558Sobrien clean_dump_file (".lreg"); 304652558Sobrien if (graph_dump_format != no_graph) 304752558Sobrien clean_graph_dump_file (dump_base_name, ".lreg"); 304852558Sobrien } 304918334Speter if (global_reg_dump) 305052558Sobrien { 305152558Sobrien clean_dump_file (".greg"); 305252558Sobrien if (graph_dump_format != no_graph) 305352558Sobrien clean_graph_dump_file (dump_base_name, ".greg"); 305452558Sobrien } 305552558Sobrien if (flow2_dump) 305652558Sobrien { 305752558Sobrien clean_dump_file (".flow2"); 305852558Sobrien if (graph_dump_format != no_graph) 305952558Sobrien clean_graph_dump_file (dump_base_name, ".flow2"); 306052558Sobrien } 306118334Speter if (sched2_dump) 306252558Sobrien { 306352558Sobrien clean_dump_file (".sched2"); 306452558Sobrien if (graph_dump_format != no_graph) 306552558Sobrien clean_graph_dump_file (dump_base_name, ".sched2"); 306652558Sobrien } 306718334Speter if (jump2_opt_dump) 306852558Sobrien { 306952558Sobrien clean_dump_file (".jump2"); 307052558Sobrien if (graph_dump_format != no_graph) 307152558Sobrien clean_graph_dump_file (dump_base_name, ".jump2"); 307252558Sobrien } 307350615Sobrien#ifdef DELAY_SLOTS 307418334Speter if (dbr_sched_dump) 307552558Sobrien { 307652558Sobrien clean_dump_file (".dbr"); 307752558Sobrien if (graph_dump_format != no_graph) 307852558Sobrien clean_graph_dump_file (dump_base_name, ".dbr"); 307952558Sobrien } 308050615Sobrien#endif 308150615Sobrien if (gcse_dump) 308252558Sobrien { 308352558Sobrien clean_dump_file (".gcse"); 308452558Sobrien if (graph_dump_format != no_graph) 308552558Sobrien clean_graph_dump_file (dump_base_name, ".gcse"); 308652558Sobrien } 308718334Speter#ifdef STACK_REGS 308818334Speter if (stack_reg_dump) 308952558Sobrien { 309052558Sobrien clean_dump_file (".stack"); 309152558Sobrien if (graph_dump_format != no_graph) 309252558Sobrien clean_graph_dump_file (dump_base_name, ".stack"); 309352558Sobrien } 309418334Speter#endif 309550615Sobrien#ifdef MACHINE_DEPENDENT_REORG 309650615Sobrien if (mach_dep_reorg_dump) 309752558Sobrien { 309852558Sobrien clean_dump_file (".mach"); 309952558Sobrien if (graph_dump_format != no_graph) 310052558Sobrien clean_graph_dump_file (dump_base_name, ".mach"); 310152558Sobrien } 310250615Sobrien#endif 310318334Speter 310418334Speter /* Open assembler code output file. */ 310518334Speter 310652558Sobrien if (flag_syntax_only) 310752558Sobrien asm_out_file = NULL; 310818334Speter else 310918334Speter { 311052558Sobrien if (! name_specified && asm_file_name == 0) 311152558Sobrien asm_out_file = stdout; 311252558Sobrien else 311318334Speter { 311452558Sobrien int len = strlen (dump_base_name); 311552558Sobrien register char *dumpname = (char *) xmalloc (len + 6); 311652558Sobrien strcpy (dumpname, dump_base_name); 311752558Sobrien strip_off_ending (dumpname, len); 311852558Sobrien strcat (dumpname, ".s"); 311952558Sobrien if (asm_file_name == 0) 312052558Sobrien { 312152558Sobrien asm_file_name = (char *) xmalloc (strlen (dumpname) + 1); 312252558Sobrien strcpy (asm_file_name, dumpname); 312352558Sobrien } 312452558Sobrien if (!strcmp (asm_file_name, "-")) 312552558Sobrien asm_out_file = stdout; 312652558Sobrien else 312752558Sobrien asm_out_file = fopen (asm_file_name, "w"); 312852558Sobrien if (asm_out_file == 0) 312952558Sobrien pfatal_with_name (asm_file_name); 313018334Speter } 313118334Speter 313218334Speter#ifdef IO_BUFFER_SIZE 313352558Sobrien setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), 313452558Sobrien _IOFBF, IO_BUFFER_SIZE); 313518334Speter#endif 313652558Sobrien } 313718334Speter 313818334Speter input_filename = name; 313918334Speter 314018334Speter /* Put an entry on the input file stack for the main input file. */ 314118334Speter input_file_stack 314218334Speter = (struct file_stack *) xmalloc (sizeof (struct file_stack)); 314318334Speter input_file_stack->next = 0; 314418334Speter input_file_stack->name = input_filename; 314518334Speter 314618334Speter /* Perform language-specific initialization. 314718334Speter This may set main_input_filename. */ 314818334Speter lang_init (); 314918334Speter 315018334Speter /* If the input doesn't start with a #line, use the input name 315118334Speter as the official input file name. */ 315218334Speter if (main_input_filename == 0) 315318334Speter main_input_filename = name; 315418334Speter 315552558Sobrien if (flag_syntax_only) 315652558Sobrien { 315752558Sobrien write_symbols = NO_DEBUG; 315852558Sobrien profile_flag = 0; 315952558Sobrien profile_block_flag = 0; 316052558Sobrien } 316152558Sobrien else 316252558Sobrien { 316352558Sobrien ASM_FILE_START (asm_out_file); 316450615Sobrien 316550615Sobrien#ifdef ASM_COMMENT_START 316652558Sobrien if (flag_verbose_asm) 316752558Sobrien { 316852558Sobrien /* Print the list of options in effect. */ 316952558Sobrien print_version (asm_out_file, ASM_COMMENT_START); 317052558Sobrien print_switch_values (asm_out_file, 0, MAX_LINE, 317150615Sobrien ASM_COMMENT_START, " ", "\n"); 317252558Sobrien /* Add a blank line here so it appears in assembler output but not 317352558Sobrien screen output. */ 317452558Sobrien fprintf (asm_out_file, "\n"); 317552558Sobrien } 317650615Sobrien#endif 317718334Speter 317852558Sobrien /* Output something to inform GDB that this compilation was by GCC. */ 317918334Speter#ifndef ASM_IDENTIFY_GCC 318052558Sobrien fprintf (asm_out_file, "gcc2_compiled.:\n"); 318118334Speter#else 318252558Sobrien ASM_IDENTIFY_GCC (asm_out_file); 318318334Speter#endif 318418334Speter 318550615Sobrien /* Output something to identify which front-end produced this file. */ 318618334Speter#ifdef ASM_IDENTIFY_LANGUAGE 318752558Sobrien ASM_IDENTIFY_LANGUAGE (asm_out_file); 318818334Speter#endif 318952558Sobrien } /* ! flag_syntax_only */ 319018334Speter 319150615Sobrien#ifndef ASM_OUTPUT_SECTION_NAME 319250615Sobrien if (flag_function_sections) 319318334Speter { 319450615Sobrien warning ("-ffunction-sections not supported for this target."); 319550615Sobrien flag_function_sections = 0; 319618334Speter } 319752558Sobrien if (flag_data_sections) 319852558Sobrien { 319952558Sobrien warning ("-fdata-sections not supported for this target."); 320052558Sobrien flag_data_sections = 0; 320152558Sobrien } 320250615Sobrien#endif 320350615Sobrien 320450615Sobrien if (flag_function_sections 320550615Sobrien && (profile_flag || profile_block_flag)) 320618334Speter { 320750615Sobrien warning ("-ffunction-sections disabled; it makes profiling impossible."); 320850615Sobrien flag_function_sections = 0; 320950615Sobrien } 321050615Sobrien 321152558Sobrien#ifndef OBJECT_FORMAT_ELF 321250615Sobrien if (flag_function_sections && write_symbols != NO_DEBUG) 321350615Sobrien warning ("-ffunction-sections may affect debugging on some targets."); 321452558Sobrien#endif 321550615Sobrien 321650615Sobrien /* ??? Note: There used to be a conditional here 321750615Sobrien to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined. 321850615Sobrien This was to guarantee separation between gcc_compiled. and 321950615Sobrien the first function, for the sake of dbx on Suns. 322050615Sobrien However, having the extra zero here confused the Emacs 322150615Sobrien code for unexec, and might confuse other programs too. 322250615Sobrien Therefore, I took out that change. 322350615Sobrien In future versions we should find another way to solve 322450615Sobrien that dbx problem. -- rms, 23 May 93. */ 322518334Speter 322650615Sobrien /* Don't let the first function fall at the same address 322750615Sobrien as gcc_compiled., if profiling. */ 322850615Sobrien if (profile_flag || profile_block_flag) 322950615Sobrien { 323050615Sobrien /* It's best if we can write a nop here since some 323150615Sobrien assemblers don't tolerate zeros in the text section. */ 323250615Sobrien if (insn_template[CODE_FOR_nop] != 0) 323350615Sobrien output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR); 323450615Sobrien else 323518334Speter assemble_zeros (UNITS_PER_WORD); 323618334Speter } 323718334Speter 323818334Speter /* If dbx symbol table desired, initialize writing it 323918334Speter and output the predefined types. */ 324018334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 324118334Speter if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 324218334Speter TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename, 324318334Speter getdecls ())); 324418334Speter#endif 324518334Speter#ifdef SDB_DEBUGGING_INFO 324618334Speter if (write_symbols == SDB_DEBUG) 324718334Speter TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename, 324818334Speter getdecls ())); 324918334Speter#endif 325018334Speter#ifdef DWARF_DEBUGGING_INFO 325118334Speter if (write_symbols == DWARF_DEBUG) 325218334Speter TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename)); 325318334Speter#endif 325450615Sobrien#ifdef DWARF2_UNWIND_INFO 325550615Sobrien if (dwarf2out_do_frame ()) 325650615Sobrien dwarf2out_frame_init (); 325750615Sobrien#endif 325850615Sobrien#ifdef DWARF2_DEBUGGING_INFO 325950615Sobrien if (write_symbols == DWARF2_DEBUG) 326050615Sobrien TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename)); 326150615Sobrien#endif 326218334Speter 326318334Speter /* Initialize yet another pass. */ 326418334Speter 326550615Sobrien init_final (main_input_filename); 326650615Sobrien init_branch_prob (dump_base_name); 326718334Speter 326818334Speter start_time = get_run_time (); 326918334Speter 327018334Speter /* Call the parser, which parses the entire file 327118334Speter (calling rest_of_compilation for each function). */ 327218334Speter 327318334Speter if (yyparse () != 0) 327418334Speter { 327518334Speter if (errorcount == 0) 327652558Sobrien notice ("Errors detected in input file (your bison.simple is out of date)\n"); 327718334Speter 327818334Speter /* In case there were missing closebraces, 327918334Speter get us back to the global binding level. */ 328018334Speter while (! global_bindings_p ()) 328118334Speter poplevel (0, 0, 0); 328218334Speter } 328318334Speter 328418334Speter /* Compilation is now finished except for writing 328518334Speter what's left of the symbol table output. */ 328618334Speter 328718334Speter parse_time += get_run_time () - start_time; 328818334Speter 328918334Speter parse_time -= integration_time; 329018334Speter parse_time -= varconst_time; 329118334Speter 329252558Sobrien if (flag_syntax_only) 329352558Sobrien goto finish_syntax; 329452558Sobrien 329518334Speter globals = getdecls (); 329618334Speter 329718334Speter /* Really define vars that have had only a tentative definition. 329818334Speter Really output inline functions that must actually be callable 329918334Speter and have not been output so far. */ 330018334Speter 330118334Speter { 330218334Speter int len = list_length (globals); 330318334Speter tree *vec = (tree *) alloca (sizeof (tree) * len); 330418334Speter int i; 330518334Speter tree decl; 330618334Speter 330718334Speter /* Process the decls in reverse order--earliest first. 330818334Speter Put them into VEC from back to front, then take out from front. */ 330918334Speter 331018334Speter for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) 331118334Speter vec[len - i - 1] = decl; 331218334Speter 331352558Sobrien wrapup_global_declarations (vec, len); 331418334Speter 331552558Sobrien /* This must occur after the loop to output deferred functions. Else 331652558Sobrien the profiler initializer would not be emitted if all the functions 331752558Sobrien in this compilation unit were deferred. 331818334Speter 331952558Sobrien output_func_start_profiler can not cause any additional functions or 332052558Sobrien data to need to be output, so it need not be in the deferred function 332152558Sobrien loop above. */ 332252558Sobrien output_func_start_profiler (); 332318334Speter 332450615Sobrien /* Now that all possible functions have been output, we can dump 332550615Sobrien the exception table. */ 332650615Sobrien 332750615Sobrien output_exception_table (); 332850615Sobrien 332952558Sobrien check_global_declarations (vec, len); 333018334Speter } 333118334Speter 333218334Speter /* Write out any pending weak symbol declarations. */ 333318334Speter 333418334Speter weak_finish (); 333518334Speter 333618334Speter /* Do dbx symbols */ 333718334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 333818334Speter if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 333918334Speter TIMEVAR (symout_time, 334018334Speter { 334118334Speter dbxout_finish (asm_out_file, main_input_filename); 334218334Speter }); 334318334Speter#endif 334418334Speter 334518334Speter#ifdef DWARF_DEBUGGING_INFO 334618334Speter if (write_symbols == DWARF_DEBUG) 334718334Speter TIMEVAR (symout_time, 334818334Speter { 334918334Speter dwarfout_finish (); 335018334Speter }); 335118334Speter#endif 335218334Speter 335350615Sobrien#ifdef DWARF2_UNWIND_INFO 335450615Sobrien if (dwarf2out_do_frame ()) 335550615Sobrien dwarf2out_frame_finish (); 335650615Sobrien#endif 335750615Sobrien 335850615Sobrien#ifdef DWARF2_DEBUGGING_INFO 335950615Sobrien if (write_symbols == DWARF2_DEBUG) 336050615Sobrien TIMEVAR (symout_time, 336150615Sobrien { 336250615Sobrien dwarf2out_finish (); 336350615Sobrien }); 336450615Sobrien#endif 336550615Sobrien 336618334Speter /* Output some stuff at end of file if nec. */ 336718334Speter 336850615Sobrien end_final (dump_base_name); 336950615Sobrien 337050615Sobrien if (branch_prob_dump) 337150615Sobrien open_dump_file (".bp", NULL); 337250615Sobrien 337350615Sobrien TIMEVAR (dump_time, end_branch_prob (rtl_dump_file)); 337450615Sobrien 337550615Sobrien if (branch_prob_dump) 337650615Sobrien close_dump_file (NULL, NULL_RTX); 337750615Sobrien 337818334Speter#ifdef ASM_FILE_END 337950615Sobrien ASM_FILE_END (asm_out_file); 338018334Speter#endif 338118334Speter 338252558Sobrien 338318334Speter /* Language-specific end of compilation actions. */ 338452558Sobrien finish_syntax: 338518334Speter lang_finish (); 338618334Speter 338718334Speter /* Close the dump files. */ 338818334Speter 338918334Speter if (flag_gen_aux_info) 339018334Speter { 339118334Speter fclose (aux_info_file); 339218334Speter if (errorcount) 339318334Speter unlink (aux_info_file_name); 339418334Speter } 339518334Speter 339618334Speter if (combine_dump) 339718334Speter { 339850615Sobrien open_dump_file (".combine", NULL); 339950615Sobrien TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file)); 340050615Sobrien close_dump_file (NULL, NULL_RTX); 340118334Speter } 340218334Speter 340318334Speter /* Close non-debugging input and output files. Take special care to note 340418334Speter whether fclose returns an error, since the pages might still be on the 340518334Speter buffer chain while the file is open. */ 340618334Speter 340750615Sobrien finish_parse (); 340850615Sobrien 340952558Sobrien if (! flag_syntax_only 341052558Sobrien && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)) 341118334Speter fatal_io_error (asm_file_name); 341218334Speter 341352558Sobrien /* Do whatever is necessary to finish printing the graphs. */ 341452558Sobrien if (graph_dump_format != no_graph) 341552558Sobrien { 341652558Sobrien if (jump_opt_dump) 341752558Sobrien finish_graph_dump_file (dump_base_name, ".jump"); 341852558Sobrien if (addressof_dump) 341952558Sobrien finish_graph_dump_file (dump_base_name, ".addressof"); 342052558Sobrien if (cse_dump) 342152558Sobrien finish_graph_dump_file (dump_base_name, ".cse"); 342252558Sobrien if (loop_dump) 342352558Sobrien finish_graph_dump_file (dump_base_name, ".loop"); 342452558Sobrien if (cse2_dump) 342552558Sobrien finish_graph_dump_file (dump_base_name, ".cse2"); 342652558Sobrien if (branch_prob_dump) 342752558Sobrien finish_graph_dump_file (dump_base_name, ".bp"); 342852558Sobrien if (flow_dump) 342952558Sobrien finish_graph_dump_file (dump_base_name, ".flow"); 343052558Sobrien if (combine_dump) 343152558Sobrien finish_graph_dump_file (dump_base_name, ".combine"); 343252558Sobrien if (regmove_dump) 343352558Sobrien finish_graph_dump_file (dump_base_name, ".regmove"); 343452558Sobrien if (sched_dump) 343552558Sobrien finish_graph_dump_file (dump_base_name, ".sched"); 343652558Sobrien if (local_reg_dump) 343752558Sobrien finish_graph_dump_file (dump_base_name, ".lreg"); 343852558Sobrien if (global_reg_dump) 343952558Sobrien finish_graph_dump_file (dump_base_name, ".greg"); 344052558Sobrien if (flow2_dump) 344152558Sobrien finish_graph_dump_file (dump_base_name, ".flow2"); 344252558Sobrien if (sched2_dump) 344352558Sobrien finish_graph_dump_file (dump_base_name, ".sched2"); 344452558Sobrien if (jump2_opt_dump) 344552558Sobrien finish_graph_dump_file (dump_base_name, ".jump2"); 344652558Sobrien#ifdef DELAY_SLOTS 344752558Sobrien if (dbr_sched_dump) 344852558Sobrien finish_graph_dump_file (dump_base_name, ".dbr"); 344952558Sobrien#endif 345052558Sobrien if (gcse_dump) 345152558Sobrien finish_graph_dump_file (dump_base_name, ".gcse"); 345252558Sobrien#ifdef STACK_REGS 345352558Sobrien if (stack_reg_dump) 345452558Sobrien finish_graph_dump_file (dump_base_name, ".stack"); 345552558Sobrien#endif 345652558Sobrien#ifdef MACHINE_DEPENDENT_REORG 345752558Sobrien if (mach_dep_reorg_dump) 345852558Sobrien finish_graph_dump_file (dump_base_name, ".mach"); 345952558Sobrien#endif 346052558Sobrien } 346152558Sobrien 346252558Sobrien /* Free up memory for the benefit of leak detectors. */ 346352558Sobrien free_reg_info (); 346452558Sobrien 346518334Speter /* Print the times. */ 346618334Speter 346718334Speter if (! quiet_flag) 346818334Speter { 346918334Speter fprintf (stderr,"\n"); 347018334Speter print_time ("parse", parse_time); 347118334Speter 347250615Sobrien print_time ("integration", integration_time); 347350615Sobrien print_time ("jump", jump_time); 347450615Sobrien print_time ("cse", cse_time); 347550615Sobrien print_time ("gcse", gcse_time); 347650615Sobrien print_time ("loop", loop_time); 347750615Sobrien print_time ("cse2", cse2_time); 347850615Sobrien print_time ("branch-prob", branch_prob_time); 347950615Sobrien print_time ("flow", flow_time); 348050615Sobrien print_time ("combine", combine_time); 348150615Sobrien print_time ("regmove", regmove_time); 348250615Sobrien print_time ("sched", sched_time); 348350615Sobrien print_time ("local-alloc", local_alloc_time); 348450615Sobrien print_time ("global-alloc", global_alloc_time); 348552558Sobrien print_time ("flow2", flow2_time); 348650615Sobrien print_time ("sched2", sched2_time); 348750615Sobrien#ifdef DELAY_SLOTS 348850615Sobrien print_time ("dbranch", dbr_sched_time); 348950615Sobrien#endif 349050615Sobrien print_time ("shorten-branch", shorten_branch_time); 349150615Sobrien print_time ("stack-reg", stack_reg_time); 349250615Sobrien print_time ("final", final_time); 349350615Sobrien print_time ("varconst", varconst_time); 349450615Sobrien print_time ("symout", symout_time); 349550615Sobrien print_time ("dump", dump_time); 349618334Speter } 349718334Speter} 349818334Speter 349918334Speter/* This is called from various places for FUNCTION_DECL, VAR_DECL, 350018334Speter and TYPE_DECL nodes. 350118334Speter 350218334Speter This does nothing for local (non-static) variables. 350318334Speter Otherwise, it sets up the RTL and outputs any assembler code 350418334Speter (label definition, storage allocation and initialization). 350518334Speter 350618334Speter DECL is the declaration. If ASMSPEC is nonzero, it specifies 350718334Speter the assembler symbol name to be used. TOP_LEVEL is nonzero 350818334Speter if this declaration is not within a function. */ 350918334Speter 351018334Spetervoid 351118334Speterrest_of_decl_compilation (decl, asmspec, top_level, at_end) 351218334Speter tree decl; 351352558Sobrien const char *asmspec; 351418334Speter int top_level; 351518334Speter int at_end; 351618334Speter{ 351718334Speter /* Declarations of variables, and of functions defined elsewhere. */ 351818334Speter 351918334Speter/* The most obvious approach, to put an #ifndef around where 352018334Speter this macro is used, doesn't work since it's inside a macro call. */ 352118334Speter#ifndef ASM_FINISH_DECLARE_OBJECT 352218334Speter#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END) 352318334Speter#endif 352418334Speter 352518334Speter /* Forward declarations for nested functions are not "external", 352618334Speter but we need to treat them as if they were. */ 352718334Speter if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) 352818334Speter || TREE_CODE (decl) == FUNCTION_DECL) 352918334Speter TIMEVAR (varconst_time, 353018334Speter { 353118334Speter make_decl_rtl (decl, asmspec, top_level); 353218334Speter /* Initialized extern variable exists to be replaced 353318334Speter with its value, or represents something that will be 353418334Speter output in another file. */ 353518334Speter if (! (TREE_CODE (decl) == VAR_DECL 353618334Speter && DECL_EXTERNAL (decl) && TREE_READONLY (decl) 353718334Speter && DECL_INITIAL (decl) != 0 353818334Speter && DECL_INITIAL (decl) != error_mark_node)) 353918334Speter /* Don't output anything 354018334Speter when a tentative file-scope definition is seen. 354118334Speter But at end of compilation, do output code for them. */ 354218334Speter if (! (! at_end && top_level 354318334Speter && (DECL_INITIAL (decl) == 0 354418334Speter || DECL_INITIAL (decl) == error_mark_node))) 354518334Speter assemble_variable (decl, top_level, at_end, 0); 354618334Speter if (decl == last_assemble_variable_decl) 354718334Speter { 354818334Speter ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, 354918334Speter top_level, at_end); 355018334Speter } 355118334Speter }); 355218334Speter else if (DECL_REGISTER (decl) && asmspec != 0) 355318334Speter { 355418334Speter if (decode_reg_name (asmspec) >= 0) 355518334Speter { 355618334Speter DECL_RTL (decl) = 0; 355718334Speter make_decl_rtl (decl, asmspec, top_level); 355818334Speter } 355918334Speter else 356018334Speter error ("invalid register name `%s' for register variable", asmspec); 356118334Speter } 356218334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 356318334Speter else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 356418334Speter && TREE_CODE (decl) == TYPE_DECL) 356518334Speter TIMEVAR (symout_time, dbxout_symbol (decl, 0)); 356618334Speter#endif 356718334Speter#ifdef SDB_DEBUGGING_INFO 356818334Speter else if (write_symbols == SDB_DEBUG && top_level 356918334Speter && TREE_CODE (decl) == TYPE_DECL) 357018334Speter TIMEVAR (symout_time, sdbout_symbol (decl, 0)); 357118334Speter#endif 357218334Speter} 357318334Speter 357418334Speter/* Called after finishing a record, union or enumeral type. */ 357518334Speter 357618334Spetervoid 357718334Speterrest_of_type_compilation (type, toplev) 357852558Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO) 357918334Speter tree type; 358018334Speter int toplev; 358152558Sobrien#else 358252558Sobrien tree type ATTRIBUTE_UNUSED; 358352558Sobrien int toplev ATTRIBUTE_UNUSED; 358452558Sobrien#endif 358518334Speter{ 358618334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 358718334Speter if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 358818334Speter TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev)); 358918334Speter#endif 359018334Speter#ifdef SDB_DEBUGGING_INFO 359118334Speter if (write_symbols == SDB_DEBUG) 359218334Speter TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev)); 359318334Speter#endif 359418334Speter} 359518334Speter 359618334Speter/* This is called from finish_function (within yyparse) 359718334Speter after each top-level definition is parsed. 359818334Speter It is supposed to compile that function or variable 359918334Speter and output the assembler code for it. 360018334Speter After we return, the tree storage is freed. */ 360118334Speter 360218334Spetervoid 360318334Speterrest_of_compilation (decl) 360418334Speter tree decl; 360518334Speter{ 360618334Speter register rtx insns; 360718334Speter int start_time = get_run_time (); 360818334Speter int tem; 360918334Speter /* Nonzero if we have saved the original DECL_INITIAL of the function, 361018334Speter to be restored after we finish compiling the function 361118334Speter (for use when compiling inline calls to this function). */ 361218334Speter tree saved_block_tree = 0; 361318334Speter /* Likewise, for DECL_ARGUMENTS. */ 361418334Speter tree saved_arguments = 0; 361518334Speter int failure = 0; 361652558Sobrien int rebuild_label_notes_after_reload; 361718334Speter 361818334Speter /* If we are reconsidering an inline function 361918334Speter at the end of compilation, skip the stuff for making it inline. */ 362018334Speter 362118334Speter if (DECL_SAVED_INSNS (decl) == 0) 362218334Speter { 362350615Sobrien int inlinable = 0; 362452558Sobrien const char *lose; 362518334Speter 362618334Speter /* If requested, consider whether to make this function inline. */ 362750615Sobrien if (DECL_INLINE (decl) || flag_inline_functions) 362818334Speter TIMEVAR (integration_time, 362918334Speter { 363018334Speter lose = function_cannot_inline_p (decl); 363118334Speter if (lose || ! optimize) 363218334Speter { 363350615Sobrien if (warn_inline && DECL_INLINE (decl)) 363418334Speter warning_with_decl (decl, lose); 363518334Speter DECL_ABSTRACT_ORIGIN (decl) = 0; 363618334Speter /* Don't really compile an extern inline function. 363718334Speter If we can't make it inline, pretend 363818334Speter it was only declared. */ 363918334Speter if (DECL_EXTERNAL (decl)) 364018334Speter { 364118334Speter DECL_INITIAL (decl) = 0; 364218334Speter goto exit_rest_of_compilation; 364318334Speter } 364418334Speter } 364518334Speter else 364650615Sobrien /* ??? Note that this has the effect of making it look 364750615Sobrien like "inline" was specified for a function if we choose 364850615Sobrien to inline it. This isn't quite right, but it's 364950615Sobrien probably not worth the trouble to fix. */ 365050615Sobrien inlinable = DECL_INLINE (decl) = 1; 365118334Speter }); 365218334Speter 365318334Speter insns = get_insns (); 365418334Speter 365518334Speter /* Dump the rtl code if we are dumping rtl. */ 365618334Speter 365718334Speter if (rtl_dump) 365850615Sobrien { 365950615Sobrien open_dump_file (".rtl", decl_printable_name (decl, 2)); 366050615Sobrien 366150615Sobrien if (DECL_SAVED_INSNS (decl)) 366250615Sobrien fprintf (rtl_dump_file, ";; (integrable)\n\n"); 366350615Sobrien 366450615Sobrien close_dump_file (print_rtl, insns); 366550615Sobrien } 366618334Speter 366750615Sobrien /* If we can, defer compiling inlines until EOF. 366850615Sobrien save_for_inline_copying can be extremely expensive. */ 366950615Sobrien if (inlinable && ! decl_function_context (decl)) 367050615Sobrien DECL_DEFER_OUTPUT (decl) = 1; 367150615Sobrien 367218334Speter /* If function is inline, and we don't yet know whether to 367318334Speter compile it by itself, defer decision till end of compilation. 367418334Speter finish_compilation will call rest_of_compilation again 367518334Speter for those functions that need to be output. Also defer those 367650615Sobrien functions that we are supposed to defer. We cannot defer 367750615Sobrien functions containing nested functions since the nested function 367850615Sobrien data is in our non-saved obstack. We cannot defer nested 367950615Sobrien functions for the same reason. */ 368018334Speter 368150615Sobrien /* If this is a nested inline, remove ADDRESSOF now so we can 368250615Sobrien finish compiling ourselves. Otherwise, wait until EOF. 368350615Sobrien We have to do this because the purge_addressof transformation 368450615Sobrien changes the DECL_RTL for many variables, which confuses integrate. */ 368550615Sobrien if (inlinable) 368618334Speter { 368750615Sobrien if (decl_function_context (decl)) 368850615Sobrien purge_addressof (insns); 368950615Sobrien else 369050615Sobrien DECL_DEFER_OUTPUT (decl) = 1; 369150615Sobrien } 369250615Sobrien 369350615Sobrien if (! current_function_contains_functions 369450615Sobrien && (DECL_DEFER_OUTPUT (decl) 369550615Sobrien || (DECL_INLINE (decl) 369650615Sobrien && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) 369750615Sobrien && ! flag_keep_inline_functions) 369850615Sobrien || DECL_EXTERNAL (decl))))) 369950615Sobrien { 370018334Speter DECL_DEFER_OUTPUT (decl) = 1; 370118334Speter 370250615Sobrien /* If -Wreturn-type, we have to do a bit of compilation. 370350615Sobrien However, if we just fall through we will call 370450615Sobrien save_for_inline_copying() which results in excessive 370550615Sobrien memory use. Instead, we just want to call 370650615Sobrien jump_optimize() to figure out whether or not we can fall 370750615Sobrien off the end of the function; we do the minimum amount of 370850615Sobrien work necessary to make that safe. And, we set optimize 370950615Sobrien to zero to keep jump_optimize from working too hard. */ 371050615Sobrien if (warn_return_type) 371118334Speter { 371250615Sobrien int saved_optimize = optimize; 371350615Sobrien optimize = 0; 371450615Sobrien find_exception_handler_labels (); 371550615Sobrien jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES, 371650615Sobrien !JUMP_AFTER_REGSCAN); 371750615Sobrien optimize = saved_optimize; 371850615Sobrien } 371950615Sobrien 372018334Speter#ifdef DWARF_DEBUGGING_INFO 372150615Sobrien /* Generate the DWARF info for the "abstract" instance 372250615Sobrien of a function which we may later generate inlined and/or 372350615Sobrien out-of-line instances of. */ 372450615Sobrien if (write_symbols == DWARF_DEBUG) 372550615Sobrien { 372650615Sobrien set_decl_abstract_flags (decl, 1); 372750615Sobrien TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); 372850615Sobrien set_decl_abstract_flags (decl, 0); 372950615Sobrien } 373018334Speter#endif 373150615Sobrien#ifdef DWARF2_DEBUGGING_INFO 373250615Sobrien /* Generate the DWARF2 info for the "abstract" instance 373350615Sobrien of a function which we may later generate inlined and/or 373450615Sobrien out-of-line instances of. */ 373550615Sobrien if (write_symbols == DWARF2_DEBUG) 373650615Sobrien { 373750615Sobrien set_decl_abstract_flags (decl, 1); 373850615Sobrien TIMEVAR (symout_time, dwarf2out_decl (decl)); 373950615Sobrien set_decl_abstract_flags (decl, 0); 374018334Speter } 374150615Sobrien#endif 374250615Sobrien TIMEVAR (integration_time, save_for_inline_nocopy (decl)); 374350615Sobrien RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable; 374450615Sobrien goto exit_rest_of_compilation; 374518334Speter } 374618334Speter 374718334Speter /* If we have to compile the function now, save its rtl and subdecls 374818334Speter so that its compilation will not affect what others get. */ 374950615Sobrien if (inlinable || DECL_DEFER_OUTPUT (decl)) 375018334Speter { 375118334Speter#ifdef DWARF_DEBUGGING_INFO 375218334Speter /* Generate the DWARF info for the "abstract" instance of 375318334Speter a function which we will generate an out-of-line instance 375418334Speter of almost immediately (and which we may also later generate 375518334Speter various inlined instances of). */ 375618334Speter if (write_symbols == DWARF_DEBUG) 375718334Speter { 375818334Speter set_decl_abstract_flags (decl, 1); 375918334Speter TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); 376018334Speter set_decl_abstract_flags (decl, 0); 376118334Speter } 376218334Speter#endif 376350615Sobrien#ifdef DWARF2_DEBUGGING_INFO 376450615Sobrien /* Generate the DWARF2 info for the "abstract" instance of 376550615Sobrien a function which we will generate an out-of-line instance 376650615Sobrien of almost immediately (and which we may also later generate 376750615Sobrien various inlined instances of). */ 376850615Sobrien if (write_symbols == DWARF2_DEBUG) 376950615Sobrien { 377050615Sobrien set_decl_abstract_flags (decl, 1); 377150615Sobrien TIMEVAR (symout_time, dwarf2out_decl (decl)); 377250615Sobrien set_decl_abstract_flags (decl, 0); 377350615Sobrien } 377450615Sobrien#endif 377518334Speter saved_block_tree = DECL_INITIAL (decl); 377618334Speter saved_arguments = DECL_ARGUMENTS (decl); 377718334Speter TIMEVAR (integration_time, save_for_inline_copying (decl)); 377850615Sobrien RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable; 377918334Speter } 378018334Speter 378118334Speter /* If specified extern inline but we aren't inlining it, we are 378252558Sobrien done. This goes for anything that gets here with DECL_EXTERNAL 378352558Sobrien set, not just things with DECL_INLINE. */ 378452558Sobrien if (DECL_EXTERNAL (decl)) 378518334Speter goto exit_rest_of_compilation; 378618334Speter } 378718334Speter 378818334Speter if (! DECL_DEFER_OUTPUT (decl)) 378918334Speter TREE_ASM_WRITTEN (decl) = 1; 379018334Speter 379118334Speter /* Now that integrate will no longer see our rtl, we need not distinguish 379218334Speter between the return value of this function and the return value of called 379318334Speter functions. */ 379418334Speter rtx_equal_function_value_matters = 0; 379518334Speter 379618334Speter /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */ 379718334Speter if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) 379818334Speter { 379918334Speter goto exit_rest_of_compilation; 380018334Speter } 380118334Speter 380250615Sobrien /* Emit code to get eh context, if needed. */ 380350615Sobrien emit_eh_context (); 380418334Speter 380518334Speter#ifdef FINALIZE_PIC 380618334Speter /* If we are doing position-independent code generation, now 380718334Speter is the time to output special prologues and epilogues. 380818334Speter We do not want to do this earlier, because it just clutters 380918334Speter up inline functions with meaningless insns. */ 381018334Speter if (flag_pic) 381118334Speter FINALIZE_PIC; 381218334Speter#endif 381318334Speter 381450615Sobrien /* From now on, allocate rtl in current_obstack, not in saveable_obstack. 381550615Sobrien Note that that may have been done above, in save_for_inline_copying. 381650615Sobrien The call to resume_temporary_allocation near the end of this function 381750615Sobrien goes back to the usual state of affairs. This must be done after 381850615Sobrien we've built up any unwinders for exception handling, and done 381950615Sobrien the FINALIZE_PIC work, if necessary. */ 382050615Sobrien 382150615Sobrien rtl_in_current_obstack (); 382250615Sobrien 382318334Speter insns = get_insns (); 382418334Speter 382518334Speter /* Copy any shared structure that should not be shared. */ 382618334Speter 382772566Sobrien unshare_all_rtl (current_function_decl, insns); 382818334Speter 382950615Sobrien#ifdef SETJMP_VIA_SAVE_AREA 383050615Sobrien /* This must be performed before virutal register instantiation. */ 383150615Sobrien if (current_function_calls_alloca) 383250615Sobrien optimize_save_area_alloca (insns); 383350615Sobrien#endif 383450615Sobrien 383518334Speter /* Instantiate all virtual registers. */ 383618334Speter 383718334Speter instantiate_virtual_regs (current_function_decl, get_insns ()); 383818334Speter 383918334Speter /* See if we have allocated stack slots that are not directly addressable. 384018334Speter If so, scan all the insns and create explicit address computation 384118334Speter for all references to such slots. */ 384218334Speter/* fixup_stack_slots (); */ 384318334Speter 384450615Sobrien /* Find all the EH handlers. */ 384550615Sobrien find_exception_handler_labels (); 384618334Speter 384750615Sobrien /* Always do one jump optimization pass to ensure that JUMP_LABEL fields 384850615Sobrien are initialized and to compute whether control can drop off the end 384950615Sobrien of the function. */ 385050615Sobrien TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); 385150615Sobrien TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES, 385250615Sobrien JUMP_AFTER_REGSCAN)); 385318334Speter 385418334Speter /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ 385518334Speter if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl)) 385618334Speter goto exit_rest_of_compilation; 385718334Speter 385818334Speter /* Dump rtl code after jump, if we are doing that. */ 385918334Speter 386050615Sobrien if (jump_opt_dump) 386150615Sobrien dump_rtl (".jump", decl, print_rtl, insns); 386218334Speter 386318334Speter /* Perform common subexpression elimination. 386418334Speter Nonzero value from `cse_main' means that jumps were simplified 386518334Speter and some code may now be unreachable, so do 386618334Speter jump optimization again. */ 386718334Speter 386818334Speter if (optimize > 0) 386918334Speter { 387050615Sobrien if (cse_dump) 387150615Sobrien open_dump_file (".cse", decl_printable_name (decl, 2)); 387250615Sobrien 387318334Speter TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1)); 387418334Speter 387518334Speter if (flag_thread_jumps) 387618334Speter /* Hacks by tiemann & kenner. */ 387718334Speter TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1)); 387818334Speter 387918334Speter TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (), 388050615Sobrien 0, rtl_dump_file)); 388118334Speter if (tem || optimize > 1) 388250615Sobrien TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 388350615Sobrien !JUMP_NOOP_MOVES, 388450615Sobrien !JUMP_AFTER_REGSCAN)); 388550615Sobrien 388656392Sobrien /* Run this after jump optmizations remove all the unreachable code 388756392Sobrien so that unreachable code will not keep values live. */ 388856392Sobrien TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ())); 388956392Sobrien 389050615Sobrien /* Dump rtl code after cse, if we are doing that. */ 389152558Sobrien 389250615Sobrien if (cse_dump) 389352558Sobrien { 389452558Sobrien close_dump_file (print_rtl, insns); 389552558Sobrien if (graph_dump_format != no_graph) 389652558Sobrien print_rtl_graph_with_bb (dump_base_name, ".cse", insns); 389752558Sobrien } 389818334Speter } 389918334Speter 390050615Sobrien purge_addressof (insns); 390150615Sobrien reg_scan (insns, max_reg_num (), 1); 390218334Speter 390350615Sobrien if (addressof_dump) 390452558Sobrien { 390552558Sobrien dump_rtl (".addressof", decl, print_rtl, insns); 390652558Sobrien if (graph_dump_format != no_graph) 390752558Sobrien print_rtl_graph_with_bb (dump_base_name, ".addressof", insns); 390852558Sobrien } 390952558Sobrien 391050615Sobrien /* Perform global cse. */ 391118334Speter 391250615Sobrien if (optimize > 0 && flag_gcse) 391350615Sobrien { 391450615Sobrien if (gcse_dump) 391550615Sobrien open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl))); 391618334Speter 391752558Sobrien TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file)); 391852558Sobrien 391952558Sobrien /* If gcse altered any jumps, rerun jump optimizations to clean 392052558Sobrien things up. */ 392152558Sobrien if (tem) 392252558Sobrien { 392352558Sobrien TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 392452558Sobrien !JUMP_NOOP_MOVES, 392552558Sobrien !JUMP_AFTER_REGSCAN)); 392652558Sobrien } 392752558Sobrien 392850615Sobrien if (gcse_dump) 392952558Sobrien { 393052558Sobrien close_dump_file (print_rtl, insns); 393152558Sobrien if (graph_dump_format != no_graph) 393252558Sobrien print_rtl_graph_with_bb (dump_base_name, ".gcse", insns); 393352558Sobrien } 393450615Sobrien } 393518334Speter /* Move constant computations out of loops. */ 393618334Speter 393718334Speter if (optimize > 0) 393818334Speter { 393950615Sobrien if (loop_dump) 394050615Sobrien open_dump_file (".loop", decl_printable_name (decl, 2)); 394150615Sobrien 394250615Sobrien TIMEVAR 394350615Sobrien (loop_time, 394450615Sobrien { 394550615Sobrien if (flag_rerun_loop_opt) 394618334Speter { 394750615Sobrien /* We only want to perform unrolling once. */ 394850615Sobrien 394952558Sobrien loop_optimize (insns, rtl_dump_file, 0, 0); 395050615Sobrien 395150615Sobrien 395250615Sobrien /* The first call to loop_optimize makes some instructions 395350615Sobrien trivially dead. We delete those instructions now in the 395450615Sobrien hope that doing so will make the heuristics in loop work 395550615Sobrien better and possibly speed up compilation. */ 395650615Sobrien delete_trivially_dead_insns (insns, max_reg_num ()); 395718334Speter 395850615Sobrien /* The regscan pass is currently necessary as the alias 395950615Sobrien analysis code depends on this information. */ 396050615Sobrien reg_scan (insns, max_reg_num (), 1); 396150615Sobrien } 396252558Sobrien loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1); 396350615Sobrien }); 396452558Sobrien 396550615Sobrien /* Dump rtl code after loop opt, if we are doing that. */ 396652558Sobrien 396750615Sobrien if (loop_dump) 396852558Sobrien { 396952558Sobrien close_dump_file (print_rtl, insns); 397052558Sobrien if (graph_dump_format != no_graph) 397152558Sobrien print_rtl_graph_with_bb (dump_base_name, ".loop", insns); 397252558Sobrien } 397350615Sobrien } 397418334Speter 397550615Sobrien if (optimize > 0) 397618334Speter { 397750615Sobrien if (cse2_dump) 397850615Sobrien open_dump_file (".cse2", decl_printable_name (decl, 2)); 397952558Sobrien 398050615Sobrien if (flag_rerun_cse_after_loop) 398150615Sobrien { 398250615Sobrien /* Running another jump optimization pass before the second 398350615Sobrien cse pass sometimes simplifies the RTL enough to allow 398450615Sobrien the second CSE pass to do a better job. Jump_optimize can change 398550615Sobrien max_reg_num so we must rerun reg_scan afterwards. 398650615Sobrien ??? Rework to not call reg_scan so often. */ 398750615Sobrien TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); 398850615Sobrien TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 398950615Sobrien !JUMP_NOOP_MOVES, 399050615Sobrien JUMP_AFTER_REGSCAN)); 399150615Sobrien 399250615Sobrien TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0)); 399350615Sobrien TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (), 399450615Sobrien 1, rtl_dump_file)); 399550615Sobrien if (tem) 399650615Sobrien TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, 399750615Sobrien !JUMP_NOOP_MOVES, 399850615Sobrien !JUMP_AFTER_REGSCAN)); 399950615Sobrien } 400018334Speter 400150615Sobrien if (flag_thread_jumps) 400250615Sobrien { 400350615Sobrien /* This pass of jump threading straightens out code 400450615Sobrien that was kinked by loop optimization. */ 400550615Sobrien TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0)); 400650615Sobrien TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0)); 400750615Sobrien } 400852558Sobrien 400950615Sobrien /* Dump rtl code after cse, if we are doing that. */ 401052558Sobrien 401150615Sobrien if (cse2_dump) 401252558Sobrien { 401352558Sobrien close_dump_file (print_rtl, insns); 401452558Sobrien if (graph_dump_format != no_graph) 401552558Sobrien print_rtl_graph_with_bb (dump_base_name, ".cse2", insns); 401652558Sobrien } 401718334Speter } 401852558Sobrien 401950615Sobrien if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) 402050615Sobrien { 402150615Sobrien if (branch_prob_dump) 402250615Sobrien open_dump_file (".bp", decl_printable_name (decl, 2)); 402352558Sobrien 402450615Sobrien TIMEVAR 402550615Sobrien (branch_prob_time, 402650615Sobrien { 402750615Sobrien branch_prob (insns, rtl_dump_file); 402850615Sobrien }); 402952558Sobrien 403050615Sobrien if (branch_prob_dump) 403152558Sobrien { 403252558Sobrien close_dump_file (print_rtl, insns); 403352558Sobrien if (graph_dump_format != no_graph) 403452558Sobrien print_rtl_graph_with_bb (dump_base_name, ".bp", insns); 403552558Sobrien } 403650615Sobrien } 403752558Sobrien 403818334Speter /* We are no longer anticipating cse in this function, at least. */ 403918334Speter 404018334Speter cse_not_expected = 1; 404118334Speter 404218334Speter /* Now we choose between stupid (pcc-like) register allocation 404318334Speter (if we got the -noreg switch and not -opt) 404418334Speter and smart register allocation. */ 404518334Speter 404652558Sobrien if (optimize > 0) /* Stupid allocation probably won't work */ 404718334Speter obey_regdecls = 0; /* if optimizations being done. */ 404818334Speter 404918334Speter regclass_init (); 405018334Speter 405118334Speter /* Print function header into flow dump now 405218334Speter because doing the flow analysis makes some of the dump. */ 405318334Speter 405418334Speter if (flow_dump) 405550615Sobrien open_dump_file (".flow", decl_printable_name (decl, 2)); 405650615Sobrien 405718334Speter if (obey_regdecls) 405818334Speter { 405918334Speter TIMEVAR (flow_time, 406018334Speter { 406118334Speter regclass (insns, max_reg_num ()); 406218334Speter stupid_life_analysis (insns, max_reg_num (), 406350615Sobrien rtl_dump_file); 406418334Speter }); 406518334Speter } 406618334Speter else 406718334Speter { 406818334Speter /* Do control and data flow analysis, 406918334Speter and write some of the results to dump file. */ 407018334Speter 407150615Sobrien TIMEVAR 407250615Sobrien (flow_time, 407350615Sobrien { 407450615Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1); 407552558Sobrien life_analysis (insns, max_reg_num (), rtl_dump_file, 1); 407650615Sobrien }); 407750615Sobrien 407818334Speter if (warn_uninitialized) 407918334Speter { 408018334Speter uninitialized_vars_warning (DECL_INITIAL (decl)); 408118334Speter setjmp_args_warning (); 408218334Speter } 408318334Speter } 408418334Speter 408518334Speter /* Dump rtl after flow analysis. */ 408618334Speter 408718334Speter if (flow_dump) 408852558Sobrien { 408952558Sobrien close_dump_file (print_rtl_with_bb, insns); 409052558Sobrien if (graph_dump_format != no_graph) 409152558Sobrien print_rtl_graph_with_bb (dump_base_name, ".flow", insns); 409252558Sobrien } 409352558Sobrien 409452558Sobrien /* The first life analysis pass has finished. From now on we can not 409552558Sobrien generate any new pseudos. */ 409652558Sobrien no_new_pseudos = 1; 409752558Sobrien 409818334Speter /* If -opt, try combining insns through substitution. */ 409918334Speter 410018334Speter if (optimize > 0) 410150615Sobrien { 410250615Sobrien TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ())); 410352558Sobrien 410450615Sobrien /* Dump rtl code after insn combination. */ 410552558Sobrien 410650615Sobrien if (combine_dump) 410752558Sobrien { 410852558Sobrien dump_rtl (".combine", decl, print_rtl_with_bb, insns); 410952558Sobrien if (graph_dump_format != no_graph) 411052558Sobrien print_rtl_graph_with_bb (dump_base_name, ".combine", insns); 411152558Sobrien } 411250615Sobrien } 411318334Speter 411450615Sobrien /* Register allocation pre-pass, to reduce number of moves 411550615Sobrien necessary for two-address machines. */ 411650615Sobrien if (optimize > 0 && (flag_regmove || flag_expensive_optimizations)) 411750615Sobrien { 411850615Sobrien if (regmove_dump) 411950615Sobrien open_dump_file (".regmove", decl_printable_name (decl, 2)); 412052558Sobrien 412150615Sobrien TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (), 412250615Sobrien rtl_dump_file)); 412352558Sobrien 412450615Sobrien if (regmove_dump) 412552558Sobrien { 412652558Sobrien close_dump_file (print_rtl_with_bb, insns); 412752558Sobrien if (graph_dump_format != no_graph) 412852558Sobrien print_rtl_graph_with_bb (dump_base_name, ".regmove", insns); 412952558Sobrien } 413050615Sobrien } 413118334Speter 413218334Speter /* Print function header into sched dump now 413318334Speter because doing the sched analysis makes some of the dump. */ 413418334Speter 413518334Speter if (optimize > 0 && flag_schedule_insns) 413618334Speter { 413750615Sobrien if (sched_dump) 413850615Sobrien open_dump_file (".sched", decl_printable_name (decl, 2)); 413952558Sobrien 414018334Speter /* Do control and data sched analysis, 414118334Speter and write some of the results to dump file. */ 414218334Speter 414350615Sobrien TIMEVAR (sched_time, schedule_insns (rtl_dump_file)); 414452558Sobrien 414550615Sobrien /* Dump rtl after instruction scheduling. */ 414652558Sobrien 414750615Sobrien if (sched_dump) 414852558Sobrien { 414952558Sobrien close_dump_file (print_rtl_with_bb, insns); 415052558Sobrien if (graph_dump_format != no_graph) 415152558Sobrien print_rtl_graph_with_bb (dump_base_name, ".sched", insns); 415252558Sobrien } 415318334Speter } 415418334Speter 415552558Sobrien /* Determine if the current function is a leaf before running reload 415652558Sobrien since this can impact optimizations done by the prologue and 415752558Sobrien epilogue thus changing register elimination offsets. */ 415852558Sobrien current_function_is_leaf = leaf_function_p (); 415952558Sobrien 416018334Speter /* Unless we did stupid register allocation, 416152558Sobrien allocate pseudo-regs that are used only within 1 basic block. 416218334Speter 416352558Sobrien RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the 416452558Sobrien jump optimizer after register allocation and reloading are finished. */ 416552558Sobrien 416618334Speter if (!obey_regdecls) 416718334Speter TIMEVAR (local_alloc_time, 416818334Speter { 416952558Sobrien recompute_reg_usage (insns, ! optimize_size); 417018334Speter regclass (insns, max_reg_num ()); 417152558Sobrien rebuild_label_notes_after_reload = local_alloc (); 417218334Speter }); 417352558Sobrien else 417452558Sobrien rebuild_label_notes_after_reload = 0; 417518334Speter 417618334Speter /* Dump rtl code after allocating regs within basic blocks. */ 417718334Speter 417818334Speter if (local_reg_dump) 417950615Sobrien { 418050615Sobrien open_dump_file (".lreg", decl_printable_name (decl, 2)); 418152558Sobrien 418250615Sobrien TIMEVAR (dump_time, dump_flow_info (rtl_dump_file)); 418350615Sobrien TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file)); 418452558Sobrien 418550615Sobrien close_dump_file (print_rtl_with_bb, insns); 418652558Sobrien if (graph_dump_format != no_graph) 418752558Sobrien print_rtl_graph_with_bb (dump_base_name, ".lreg", insns); 418850615Sobrien } 418918334Speter 419018334Speter if (global_reg_dump) 419150615Sobrien open_dump_file (".greg", decl_printable_name (decl, 2)); 419218334Speter 419318334Speter /* Unless we did stupid register allocation, 419418334Speter allocate remaining pseudo-regs, then do the reload pass 419518334Speter fixing up any insns that are invalid. */ 419618334Speter 419718334Speter TIMEVAR (global_alloc_time, 419818334Speter { 419918334Speter if (!obey_regdecls) 420050615Sobrien failure = global_alloc (rtl_dump_file); 420118334Speter else 420250615Sobrien failure = reload (insns, 0, rtl_dump_file); 420318334Speter }); 420418334Speter 420518334Speter 420618334Speter if (failure) 420718334Speter goto exit_rest_of_compilation; 420818334Speter 420950615Sobrien /* Do a very simple CSE pass over just the hard registers. */ 421050615Sobrien if (optimize > 0) 421150615Sobrien reload_cse_regs (insns); 421250615Sobrien 421352558Sobrien /* Register allocation and reloading may have turned an indirect jump into 421452558Sobrien a direct jump. If so, we must rebuild the JUMP_LABEL fields of 421552558Sobrien jumping instructions. */ 421652558Sobrien if (rebuild_label_notes_after_reload) 421752558Sobrien TIMEVAR (jump_time, rebuild_jump_labels (insns)); 421852558Sobrien 421952558Sobrien /* If optimizing and we are performing instruction scheduling after 422052558Sobrien reload, then go ahead and split insns now since we are about to 422152558Sobrien recompute flow information anyway. 422252558Sobrien 422352558Sobrien reload_cse_regs may expose more splitting opportunities, expecially 422452558Sobrien for double-word operations. */ 422552558Sobrien if (optimize > 0 && flag_schedule_insns_after_reload) 422652558Sobrien { 422752558Sobrien rtx insn; 422852558Sobrien 422952558Sobrien for (insn = insns; insn; insn = NEXT_INSN (insn)) 423052558Sobrien { 423152558Sobrien rtx last; 423252558Sobrien 423352558Sobrien if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') 423452558Sobrien continue; 423552558Sobrien 423652558Sobrien last = try_split (PATTERN (insn), insn, 1); 423752558Sobrien 423852558Sobrien if (last != insn) 423952558Sobrien { 424052558Sobrien PUT_CODE (insn, NOTE); 424152558Sobrien NOTE_SOURCE_FILE (insn) = 0; 424252558Sobrien NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 424352558Sobrien } 424452558Sobrien } 424552558Sobrien } 424652558Sobrien 424752558Sobrien if (global_reg_dump) 424852558Sobrien { 424952558Sobrien TIMEVAR (dump_time, dump_global_regs (rtl_dump_file)); 425052558Sobrien close_dump_file (print_rtl_with_bb, insns); 425152558Sobrien if (graph_dump_format != no_graph) 425252558Sobrien print_rtl_graph_with_bb (dump_base_name, ".greg", insns); 425352558Sobrien } 425452558Sobrien 425552558Sobrien /* Re-create the death notes which were deleted during reload. */ 425652558Sobrien if (flow2_dump) 425752558Sobrien open_dump_file (".flow2", decl_printable_name (decl, 2)); 425852558Sobrien 425952558Sobrien if (optimize) 426052558Sobrien { 426152558Sobrien TIMEVAR 426252558Sobrien (flow2_time, 426352558Sobrien { 426452558Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1); 426552558Sobrien life_analysis (insns, max_reg_num (), rtl_dump_file, 1); 426652558Sobrien }); 426752558Sobrien } 426852558Sobrien 426952558Sobrien flow2_completed = 1; 427052558Sobrien 427118334Speter /* On some machines, the prologue and epilogue code, or parts thereof, 427218334Speter can be represented as RTL. Doing so lets us schedule insns between 427318334Speter it and the rest of the code and also allows delayed branch 427418334Speter scheduling to operate in the epilogue. */ 427518334Speter 427618334Speter thread_prologue_and_epilogue_insns (insns); 427718334Speter 427852558Sobrien if (flow2_dump) 427950615Sobrien { 428050615Sobrien close_dump_file (print_rtl_with_bb, insns); 428152558Sobrien if (graph_dump_format != no_graph) 428252558Sobrien print_rtl_graph_with_bb (dump_base_name, ".flow2", insns); 428350615Sobrien } 428452558Sobrien 428518334Speter if (optimize > 0 && flag_schedule_insns_after_reload) 428618334Speter { 428718334Speter if (sched2_dump) 428850615Sobrien open_dump_file (".sched2", decl_printable_name (decl, 2)); 428918334Speter 429018334Speter /* Do control and data sched analysis again, 429118334Speter and write some more of the results to dump file. */ 429218334Speter 429350615Sobrien TIMEVAR (sched2_time, schedule_insns (rtl_dump_file)); 429418334Speter 429518334Speter /* Dump rtl after post-reorder instruction scheduling. */ 429618334Speter 429718334Speter if (sched2_dump) 429852558Sobrien { 429952558Sobrien close_dump_file (print_rtl_with_bb, insns); 430052558Sobrien if (graph_dump_format != no_graph) 430152558Sobrien print_rtl_graph_with_bb (dump_base_name, ".sched2", insns); 430252558Sobrien } 430318334Speter } 430418334Speter 430518334Speter#ifdef LEAF_REGISTERS 430652558Sobrien current_function_uses_only_leaf_regs 430752558Sobrien = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); 430818334Speter#endif 430918334Speter 431018334Speter /* One more attempt to remove jumps to .+1 431118334Speter left by dead-store-elimination. 431218334Speter Also do cross-jumping this time 431318334Speter and delete no-op move insns. */ 431418334Speter 431518334Speter if (optimize > 0) 431618334Speter { 431750615Sobrien TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP, 431850615Sobrien JUMP_NOOP_MOVES, 431950615Sobrien !JUMP_AFTER_REGSCAN)); 432052558Sobrien 432150615Sobrien /* Dump rtl code after jump, if we are doing that. */ 432250615Sobrien 432350615Sobrien if (jump2_opt_dump) 432452558Sobrien { 432552558Sobrien dump_rtl (".jump2", decl, print_rtl_with_bb, insns); 432652558Sobrien if (graph_dump_format != no_graph) 432752558Sobrien print_rtl_graph_with_bb (dump_base_name, ".jump2", insns); 432852558Sobrien } 432918334Speter } 433018334Speter 433118334Speter /* If a machine dependent reorganization is needed, call it. */ 433218334Speter#ifdef MACHINE_DEPENDENT_REORG 433318334Speter MACHINE_DEPENDENT_REORG (insns); 433450615Sobrien 433550615Sobrien if (mach_dep_reorg_dump) 433652558Sobrien { 433752558Sobrien dump_rtl (".mach", decl, print_rtl_with_bb, insns); 433852558Sobrien if (graph_dump_format != no_graph) 433952558Sobrien print_rtl_graph_with_bb (dump_base_name, ".mach", insns); 434052558Sobrien } 434118334Speter#endif 434218334Speter 434318334Speter /* If a scheduling pass for delayed branches is to be done, 434450615Sobrien call the scheduling code. */ 434518334Speter 434618334Speter#ifdef DELAY_SLOTS 434718334Speter if (optimize > 0 && flag_delayed_branch) 434818334Speter { 434952558Sobrien if (dbr_sched_dump) 435052558Sobrien open_dump_file (".dbr", decl_printable_name (decl, 2)); 435152558Sobrien 435250615Sobrien TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file)); 435352558Sobrien 435418334Speter if (dbr_sched_dump) 435552558Sobrien { 435652558Sobrien close_dump_file (print_rtl_with_bb, insns); 435752558Sobrien if (graph_dump_format != no_graph) 435852558Sobrien print_rtl_graph_with_bb (dump_base_name, ".dbr", insns); 435952558Sobrien } 436018334Speter } 436118334Speter#endif 436218334Speter 436318334Speter /* Shorten branches. */ 436418334Speter TIMEVAR (shorten_branch_time, 436518334Speter { 436618334Speter shorten_branches (get_insns ()); 436718334Speter }); 436818334Speter 436918334Speter#ifdef STACK_REGS 437052558Sobrien if (stack_reg_dump) 437152558Sobrien open_dump_file (".stack", decl_printable_name (decl, 2)); 437252558Sobrien 437350615Sobrien TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file)); 437450615Sobrien 437518334Speter if (stack_reg_dump) 437652558Sobrien { 437752558Sobrien dump_rtl (".stack", decl, print_rtl_with_bb, insns); 437852558Sobrien if (graph_dump_format != no_graph) 437952558Sobrien print_rtl_graph_with_bb (dump_base_name, ".stack", insns); 438052558Sobrien } 438118334Speter#endif 438218334Speter 438318334Speter /* Now turn the rtl into assembler code. */ 438418334Speter 438518334Speter TIMEVAR (final_time, 438618334Speter { 438718334Speter rtx x; 438818334Speter char *fnname; 438918334Speter 439018334Speter /* Get the function's name, as described by its RTL. 439118334Speter This may be different from the DECL_NAME name used 439218334Speter in the source file. */ 439318334Speter 439418334Speter x = DECL_RTL (decl); 439518334Speter if (GET_CODE (x) != MEM) 439618334Speter abort (); 439718334Speter x = XEXP (x, 0); 439818334Speter if (GET_CODE (x) != SYMBOL_REF) 439918334Speter abort (); 440018334Speter fnname = XSTR (x, 0); 440118334Speter 440218334Speter assemble_start_function (decl, fnname); 440318334Speter final_start_function (insns, asm_out_file, optimize); 440418334Speter final (insns, asm_out_file, optimize, 0); 440518334Speter final_end_function (insns, asm_out_file, optimize); 440618334Speter assemble_end_function (decl, fnname); 440750615Sobrien if (! quiet_flag) 440850615Sobrien fflush (asm_out_file); 440950615Sobrien 441052558Sobrien /* Release all memory allocated by flow. */ 441152558Sobrien free_basic_block_vars (0); 441252558Sobrien 441350615Sobrien /* Release all memory held by regsets now */ 441450615Sobrien regset_release_memory (); 441518334Speter }); 441618334Speter 441718334Speter /* Write DBX symbols if requested */ 441818334Speter 441918334Speter /* Note that for those inline functions where we don't initially 442018334Speter know for certain that we will be generating an out-of-line copy, 442118334Speter the first invocation of this routine (rest_of_compilation) will 442218334Speter skip over this code by doing a `goto exit_rest_of_compilation;'. 442318334Speter Later on, finish_compilation will call rest_of_compilation again 442418334Speter for those inline functions that need to have out-of-line copies 442518334Speter generated. During that call, we *will* be routed past here. */ 442618334Speter 442718334Speter#ifdef DBX_DEBUGGING_INFO 442818334Speter if (write_symbols == DBX_DEBUG) 442918334Speter TIMEVAR (symout_time, dbxout_function (decl)); 443018334Speter#endif 443118334Speter 443218334Speter#ifdef DWARF_DEBUGGING_INFO 443318334Speter if (write_symbols == DWARF_DEBUG) 443418334Speter TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0)); 443518334Speter#endif 443618334Speter 443750615Sobrien#ifdef DWARF2_DEBUGGING_INFO 443850615Sobrien if (write_symbols == DWARF2_DEBUG) 443950615Sobrien TIMEVAR (symout_time, dwarf2out_decl (decl)); 444050615Sobrien#endif 444150615Sobrien 444218334Speter exit_rest_of_compilation: 444318334Speter 444452558Sobrien free_bb_mem (); 444552558Sobrien 444618334Speter /* In case the function was not output, 444718334Speter don't leave any temporary anonymous types 444818334Speter queued up for sdb output. */ 444918334Speter#ifdef SDB_DEBUGGING_INFO 445018334Speter if (write_symbols == SDB_DEBUG) 445118334Speter sdbout_types (NULL_TREE); 445218334Speter#endif 445318334Speter 445418334Speter /* Put back the tree of subblocks and list of arguments 445518334Speter from before we copied them. 445618334Speter Code generation and the output of debugging info may have modified 445718334Speter the copy, but the original is unchanged. */ 445818334Speter 445918334Speter if (saved_block_tree != 0) 446050615Sobrien { 446150615Sobrien DECL_INITIAL (decl) = saved_block_tree; 446250615Sobrien DECL_ARGUMENTS (decl) = saved_arguments; 446350615Sobrien DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE; 446450615Sobrien } 446518334Speter 446618334Speter reload_completed = 0; 446752558Sobrien flow2_completed = 0; 446852558Sobrien no_new_pseudos = 0; 446918334Speter 447050615Sobrien TIMEVAR (final_time, 447150615Sobrien { 447250615Sobrien /* Clear out the insn_length contents now that they are no 447350615Sobrien longer valid. */ 447450615Sobrien init_insn_lengths (); 447518334Speter 447650615Sobrien /* Clear out the real_constant_chain before some of the rtx's 447750615Sobrien it runs through become garbage. */ 447850615Sobrien clear_const_double_mem (); 447918334Speter 448050615Sobrien /* Cancel the effect of rtl_in_current_obstack. */ 448150615Sobrien resume_temporary_allocation (); 448218334Speter 448350615Sobrien /* Show no temporary slots allocated. */ 448450615Sobrien init_temp_slots (); 448550615Sobrien }); 448618334Speter 448750615Sobrien /* Make sure volatile mem refs aren't considered valid operands for 448850615Sobrien arithmetic insns. We must call this here if this is a nested inline 448950615Sobrien function, since the above code leaves us in the init_recog state 449050615Sobrien (from final.c), and the function context push/pop code does not 449150615Sobrien save/restore volatile_ok. 449218334Speter 449350615Sobrien ??? Maybe it isn't necessary for expand_start_function to call this 449450615Sobrien anymore if we do it here? */ 449550615Sobrien 449650615Sobrien init_recog_no_volatile (); 449750615Sobrien 449818334Speter /* The parsing time is all the time spent in yyparse 449918334Speter *except* what is spent in this function. */ 450018334Speter 450118334Speter parse_time -= get_run_time () - start_time; 450252558Sobrien 450352558Sobrien /* Reset global variables. */ 450452558Sobrien free_basic_block_vars (0); 450518334Speter} 450618334Speter 450750615Sobrienstatic void 450850615Sobriendisplay_help () 450950615Sobrien{ 451050615Sobrien int undoc; 451152558Sobrien unsigned long i; 451252558Sobrien const char * lang; 451352558Sobrien 451452558Sobrien#ifndef USE_CPPLIB 451550615Sobrien printf ("Usage: %s input [switches]\n", progname); 451650615Sobrien printf ("Switches:\n"); 451750615Sobrien#endif 451850615Sobrien printf (" -ffixed-<register> Mark <register> as being unavailable to the compiler\n"); 451950615Sobrien printf (" -fcall-used-<register> Mark <register> as being corrupted by function calls\n"); 452050615Sobrien printf (" -fcall-saved-<register> Mark <register> as being preserved across functions\n"); 452152558Sobrien printf (" -finline-limit-<number> Limits the size of inlined functions to <number>\n"); 452250615Sobrien 452350615Sobrien for (i = NUM_ELEM (f_options); i--;) 452450615Sobrien { 452552558Sobrien const char * description = f_options[i].description; 452650615Sobrien 452750615Sobrien if (description != NULL && * description != 0) 452850615Sobrien printf (" -f%-21s %s\n", 452950615Sobrien f_options[i].string, description); 453050615Sobrien } 453150615Sobrien 453250615Sobrien printf (" -O[number] Set optimisation level to [number]\n"); 453350615Sobrien printf (" -Os Optimise for space rather than speed\n"); 453450615Sobrien printf (" -pedantic Issue warnings needed by strict compliance to ANSI C\n"); 453550615Sobrien printf (" -pedantic-errors Like -pedantic except that errors are produced\n"); 453650615Sobrien printf (" -w Suppress warnings\n"); 453750615Sobrien printf (" -W Enable extra warnings\n"); 453850615Sobrien 453950615Sobrien for (i = NUM_ELEM (W_options); i--;) 454050615Sobrien { 454152558Sobrien const char * description = W_options[i].description; 454250615Sobrien 454350615Sobrien if (description != NULL && * description != 0) 454450615Sobrien printf (" -W%-21s %s\n", 454550615Sobrien W_options[i].string, description); 454650615Sobrien } 454750615Sobrien 454850615Sobrien printf (" -Wid-clash-<num> Warn if 2 identifiers have the same first <num> chars\n"); 454950615Sobrien printf (" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"); 455050615Sobrien printf (" -p Enable function profiling\n"); 455150615Sobrien#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) 455250615Sobrien printf (" -a Enable block profiling \n"); 455350615Sobrien#endif 455450615Sobrien#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT 455550615Sobrien printf (" -ax Enable jump profiling \n"); 455650615Sobrien#endif 455750615Sobrien printf (" -o <file> Place output into <file> \n"); 455850615Sobrien printf (" -G <number> Put global and static data smaller than <number>\n"); 455950615Sobrien printf (" bytes into a special section (on some targets)\n"); 456050615Sobrien 456150615Sobrien for (i = NUM_ELEM (debug_args); i--;) 456250615Sobrien { 456350615Sobrien if (debug_args[i].description != NULL) 456450615Sobrien printf (" -%-22s %s\n", debug_args[i].arg, debug_args[i].description); 456550615Sobrien } 456650615Sobrien 456750615Sobrien printf (" -aux-info <file> Emit declaration info into <file>.X\n"); 456850615Sobrien printf (" -quiet Do not display functions compiled or elapsed time\n"); 456950615Sobrien printf (" -version Display the compiler's version\n"); 457050615Sobrien printf (" -d[letters] Enable dumps from specific passes of the compiler\n"); 457150615Sobrien printf (" -dumpbase <file> Base name to be used for dumps from specific passes\n"); 457250615Sobrien#if defined HAIFA || defined INSN_SCHEDULING 457350615Sobrien printf (" -sched-verbose-<number> Set the verbosity level of the scheduler\n"); 457450615Sobrien#endif 457550615Sobrien printf (" --help Display this information\n"); 457650615Sobrien 457750615Sobrien undoc = 0; 457850615Sobrien lang = "language"; 457950615Sobrien 458050615Sobrien /* Display descriptions of language specific options. 458150615Sobrien If there is no description, note that there is an undocumented option. 458250615Sobrien If the description is empty, do not display anything. (This allows 458350615Sobrien options to be deliberately undocumented, for whatever reason). 458450615Sobrien If the option string is missing, then this is a marker, indicating 458552558Sobrien that the description string is in fact the name of a language, whose 458650615Sobrien language specific options are to follow. */ 458750615Sobrien 458850615Sobrien if (NUM_ELEM (documented_lang_options) > 1) 458950615Sobrien { 459050615Sobrien printf ("\nLanguage specific options:\n"); 459150615Sobrien 459250615Sobrien for (i = 0; i < NUM_ELEM (documented_lang_options); i++) 459350615Sobrien { 459452558Sobrien const char * description = documented_lang_options[i].description; 459552558Sobrien const char * option = documented_lang_options[i].option; 459650615Sobrien 459750615Sobrien if (description == NULL) 459852558Sobrien { 459952558Sobrien undoc = 1; 460052558Sobrien 460152558Sobrien if (extra_warnings) 460252558Sobrien printf (" %-23.23s [undocumented]\n", option); 460352558Sobrien } 460450615Sobrien else if (* description == 0) 460550615Sobrien continue; 460650615Sobrien else if (option == NULL) 460750615Sobrien { 460850615Sobrien if (undoc) 460950615Sobrien printf 461050615Sobrien ("\nThere are undocumented %s specific options as well.\n", 461150615Sobrien lang); 461250615Sobrien undoc = 0; 461350615Sobrien 461450615Sobrien printf ("\n Options for %s:\n", description); 461550615Sobrien 461650615Sobrien lang = description; 461750615Sobrien } 461850615Sobrien else 461950615Sobrien printf (" %-23.23s %s\n", option, description); 462050615Sobrien } 462150615Sobrien } 462250615Sobrien 462350615Sobrien if (undoc) 462450615Sobrien printf ("\nThere are undocumented %s specific options as well.\n", lang); 462550615Sobrien 462650615Sobrien if (NUM_ELEM (target_switches) > 1 462750615Sobrien#ifdef TARGET_OPTIONS 462850615Sobrien || NUM_ELEM (target_options) > 1 462950615Sobrien#endif 463050615Sobrien ) 463150615Sobrien { 463250615Sobrien int doc = 0; 463350615Sobrien 463450615Sobrien undoc = 0; 463550615Sobrien 463650615Sobrien printf ("\nTarget specific options:\n"); 463750615Sobrien 463850615Sobrien for (i = NUM_ELEM (target_switches); i--;) 463950615Sobrien { 464052558Sobrien const char * option = target_switches[i].name; 464152558Sobrien const char * description = target_switches[i].description; 464250615Sobrien 464352558Sobrien if (option == NULL || * option == 0) 464450615Sobrien continue; 464550615Sobrien else if (description == NULL) 464652558Sobrien { 464752558Sobrien undoc = 1; 464852558Sobrien 464952558Sobrien if (extra_warnings) 465052558Sobrien printf (" -m%-21.21s [undocumented]\n", option); 465152558Sobrien } 465250615Sobrien else if (* description != 0) 465352558Sobrien doc += printf (" -m%-21.21s %s\n", option, description); 465450615Sobrien } 465550615Sobrien 465650615Sobrien#ifdef TARGET_OPTIONS 465750615Sobrien for (i = NUM_ELEM (target_options); i--;) 465850615Sobrien { 465952558Sobrien const char * option = target_options[i].prefix; 466052558Sobrien const char * description = target_options[i].description; 466150615Sobrien 466252558Sobrien if (option == NULL || * option == 0) 466350615Sobrien continue; 466450615Sobrien else if (description == NULL) 466552558Sobrien { 466652558Sobrien undoc = 1; 466752558Sobrien 466852558Sobrien if (extra_warnings) 466952558Sobrien printf (" -m%-21.21s [undocumented]\n", option); 467052558Sobrien } 467150615Sobrien else if (* description != 0) 467252558Sobrien doc += printf (" -m%-21.21s %s\n", option, description); 467350615Sobrien } 467450615Sobrien#endif 467550615Sobrien if (undoc) 467652558Sobrien { 467752558Sobrien if (doc) 467852558Sobrien printf ("\nThere are undocumented target specific options as well.\n"); 467952558Sobrien else 468052558Sobrien printf (" They exist, but they are not documented.\n"); 468152558Sobrien } 468250615Sobrien } 468350615Sobrien} 468450615Sobrien 468550615Sobrien/* Compare the user specified 'option' with the language 468650615Sobrien specific 'lang_option'. Return true if they match, or 468750615Sobrien if 'option' is a viable prefix of 'lang_option'. */ 468850615Sobrien 468950615Sobrienstatic int 469050615Sobriencheck_lang_option (option, lang_option) 469150615Sobrien char * option; 469250615Sobrien char * lang_option; 469350615Sobrien{ 469450615Sobrien lang_independent_options * indep_options; 469550615Sobrien int len; 469670640Sobrien int numopts; 469770640Sobrien long k; 469852558Sobrien char * space; 469952558Sobrien 470050615Sobrien /* Ignore NULL entries. */ 470150615Sobrien if (option == NULL || lang_option == NULL) 470250615Sobrien return 0; 470350615Sobrien 470452558Sobrien if ((space = strchr (lang_option, ' ')) != NULL) 470552558Sobrien len = space - lang_option; 470652558Sobrien else 470752558Sobrien len = strlen (lang_option); 470852558Sobrien 470950615Sobrien /* If they do not match to the first n characters then fail. */ 471050615Sobrien if (strncmp (option, lang_option, len) != 0) 471150615Sobrien return 0; 471252558Sobrien 471350615Sobrien /* Do not accept a lang option, if it matches a normal -f or -W 471450615Sobrien option. Chill defines a -fpack, but we want to support 471550615Sobrien -fpack-struct. */ 471652558Sobrien 471750615Sobrien /* An exact match is OK */ 471852558Sobrien if ((int) strlen (option) == len) 471950615Sobrien return 1; 472052558Sobrien 472150615Sobrien /* If it is not an -f or -W option allow the match */ 472250615Sobrien if (option[0] != '-') 472350615Sobrien return 1; 472452558Sobrien 472550615Sobrien switch (option[1]) 472650615Sobrien { 472770640Sobrien case 'f': 472870640Sobrien indep_options = f_options; 472970640Sobrien numopts = NUM_ELEM (f_options); 473070640Sobrien break; 473170640Sobrien case 'W': 473270640Sobrien indep_options = W_options; 473370640Sobrien numopts = NUM_ELEM (W_options); 473470640Sobrien break; 473550615Sobrien default: return 1; 473650615Sobrien } 473752558Sobrien 473850615Sobrien /* The option is a -f or -W option. 473950615Sobrien Skip past the prefix and search for the remainder in the 474050615Sobrien appropriate table of options. */ 474150615Sobrien option += 2; 474252558Sobrien 474350615Sobrien if (option[0] == 'n' && option[1] == 'o' && option[2] == '-') 474450615Sobrien option += 3; 474552558Sobrien 474670640Sobrien for (k = numopts; k--;) 474750615Sobrien { 474850615Sobrien if (!strcmp (option, indep_options[k].string)) 474950615Sobrien { 475050615Sobrien /* The option matched a language independent option, 475150615Sobrien do not allow the language specific match. */ 475252558Sobrien 475350615Sobrien return 0; 475450615Sobrien } 475550615Sobrien } 475652558Sobrien 475750615Sobrien /* The option matches the start of the langauge specific option 475850615Sobrien and it is not an exact match for a language independent option. */ 475950615Sobrien return 1; 476050615Sobrien} 476150615Sobrien 476218334Speter/* Entry point of cc1/c++. Decode command args, then call compile_file. 476318334Speter Exit code is 35 if can't open files, 34 if fatal error, 476418334Speter 33 if had nonfatal errors, else success. */ 476518334Speter 476618334Speterint 476752558Sobrienmain (argc, argv) 476818334Speter int argc; 476918334Speter char **argv; 477018334Speter{ 477118334Speter register int i; 477218334Speter char *filename = 0; 477318334Speter int flag_print_mem = 0; 477418334Speter int version_flag = 0; 477518334Speter char *p; 477618334Speter 477718334Speter /* save in case md file wants to emit args as a comment. */ 477818334Speter save_argc = argc; 477918334Speter save_argv = argv; 478018334Speter 478118334Speter p = argv[0] + strlen (argv[0]); 478218334Speter while (p != argv[0] && p[-1] != '/' 478318334Speter#ifdef DIR_SEPARATOR 478418334Speter && p[-1] != DIR_SEPARATOR 478518334Speter#endif 478618334Speter ) 478718334Speter --p; 478818334Speter progname = p; 478918334Speter 479050615Sobrien#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT) 479118334Speter /* Get rid of any avoidable limit on stack size. */ 479218334Speter { 479318334Speter struct rlimit rlim; 479418334Speter 479550615Sobrien /* Set the stack limit huge so that alloca does not fail. */ 479618334Speter getrlimit (RLIMIT_STACK, &rlim); 479718334Speter rlim.rlim_cur = rlim.rlim_max; 479818334Speter setrlimit (RLIMIT_STACK, &rlim); 479918334Speter } 480050615Sobrien#endif 480118334Speter 480252558Sobrien#ifdef HAVE_LC_MESSAGES 480352558Sobrien setlocale (LC_MESSAGES, ""); 480452558Sobrien#endif 480552558Sobrien (void) bindtextdomain (PACKAGE, localedir); 480652558Sobrien (void) textdomain (PACKAGE); 480752558Sobrien 480818334Speter signal (SIGFPE, float_signal); 480918334Speter 481018334Speter#ifdef SIGPIPE 481118334Speter signal (SIGPIPE, pipe_closed); 481218334Speter#endif 481318334Speter 481418334Speter decl_printable_name = decl_name; 481552558Sobrien lang_expand_expr = (lang_expand_expr_t) do_abort; 481618334Speter 481718334Speter /* Initialize whether `char' is signed. */ 481818334Speter flag_signed_char = DEFAULT_SIGNED_CHAR; 481918334Speter#ifdef DEFAULT_SHORT_ENUMS 482018334Speter /* Initialize how much space enums occupy, by default. */ 482118334Speter flag_short_enums = DEFAULT_SHORT_ENUMS; 482218334Speter#endif 482318334Speter 482450615Sobrien /* Perform language-specific options intialization. */ 482550615Sobrien lang_init_options (); 482650615Sobrien 482718334Speter /* Scan to see what optimization level has been specified. That will 482818334Speter determine the default value of many flags. */ 482918334Speter for (i = 1; i < argc; i++) 483018334Speter { 483118334Speter if (!strcmp (argv[i], "-O")) 483218334Speter { 483318334Speter optimize = 1; 483452558Sobrien optimize_size = 0; 483518334Speter } 483618334Speter else if (argv[i][0] == '-' && argv[i][1] == 'O') 483718334Speter { 483850615Sobrien /* Handle -Os, -O2, -O3, -O69, ... */ 483918334Speter char *p = &argv[i][2]; 484050615Sobrien 484150615Sobrien if ((p[0] == 's') && (p[1] == 0)) 484252558Sobrien { 484352558Sobrien optimize_size = 1; 484452558Sobrien 484552558Sobrien /* Optimizing for size forces optimize to be 2. */ 484652558Sobrien optimize = 2; 484752558Sobrien } 484850615Sobrien else 484950615Sobrien { 485052558Sobrien const int optimize_val = read_integral_parameter (p, p - 2, -1); 485152558Sobrien if (optimize_val != -1) 485252558Sobrien { 485352558Sobrien optimize = optimize_val; 485458599Sobrien#ifdef __alpha__ 485558599Sobrien if (optimize > 1) 485658599Sobrien { 485758599Sobrien #ifdef FORCE_OPTIMIZATION_DOWNGRADE 485858599Sobrien optimize = 1; 485958599Sobrien warning ("\n***\n***\t-O%d converted to \"-O1\" due to optimizer bugs on this platform\n***\n", 486058599Sobrien optimize_val); 486158599Sobrien #else 486258599Sobrien warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***\n", 486358599Sobrien optimize_val); 486458599Sobrien #endif 486558599Sobrien } 486669460Sobrien#endif /*__alpha__*/ 486752558Sobrien optimize_size = 0; 486852558Sobrien } 486950615Sobrien } 487018334Speter } 487118334Speter } 487218334Speter 487318334Speter obey_regdecls = (optimize == 0); 487418334Speter 487518334Speter if (optimize >= 1) 487618334Speter { 487718334Speter flag_defer_pop = 1; 487818334Speter flag_thread_jumps = 1; 487918334Speter#ifdef DELAY_SLOTS 488018334Speter flag_delayed_branch = 1; 488118334Speter#endif 488218334Speter#ifdef CAN_DEBUG_WITHOUT_FP 488318334Speter flag_omit_frame_pointer = 1; 488418334Speter#endif 488518334Speter } 488618334Speter 488718334Speter if (optimize >= 2) 488818334Speter { 488918334Speter flag_cse_follow_jumps = 1; 489018334Speter flag_cse_skip_blocks = 1; 489150615Sobrien flag_gcse = 1; 489218334Speter flag_expensive_optimizations = 1; 489318334Speter flag_strength_reduce = 1; 489418334Speter flag_rerun_cse_after_loop = 1; 489550615Sobrien flag_rerun_loop_opt = 1; 489618334Speter flag_caller_saves = 1; 489718334Speter flag_force_mem = 1; 489818334Speter#ifdef INSN_SCHEDULING 489918334Speter flag_schedule_insns = 1; 490018334Speter flag_schedule_insns_after_reload = 1; 490118334Speter#endif 490250615Sobrien flag_regmove = 1; 490318334Speter } 490418334Speter 490518334Speter if (optimize >= 3) 490618334Speter { 490718334Speter flag_inline_functions = 1; 490818334Speter } 490918334Speter 491050615Sobrien /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can 491150615Sobrien modify it. */ 491250615Sobrien target_flags = 0; 491350615Sobrien set_target_switch (""); 491450615Sobrien 491518334Speter#ifdef OPTIMIZATION_OPTIONS 491618334Speter /* Allow default optimizations to be specified on a per-machine basis. */ 491750615Sobrien OPTIMIZATION_OPTIONS (optimize, optimize_size); 491818334Speter#endif 491918334Speter 492018334Speter /* Initialize register usage now so switches may override. */ 492118334Speter init_reg_sets (); 492218334Speter 492318334Speter for (i = 1; i < argc; i++) 492418334Speter { 492550615Sobrien size_t j; 492650615Sobrien 492718334Speter /* If this is a language-specific option, 492818334Speter decode it in a language-specific way. */ 492950615Sobrien for (j = NUM_ELEM (documented_lang_options); j--;) 493050615Sobrien if (check_lang_option (argv[i], documented_lang_options[j].option)) 493118334Speter break; 493250615Sobrien 493352558Sobrien if (j != (size_t)-1) 493450615Sobrien { 493550615Sobrien /* If the option is valid for *some* language, 493650615Sobrien treat it as valid even if this language doesn't understand it. */ 493750615Sobrien int strings_processed = lang_decode_option (argc - i, argv + i); 493850615Sobrien 493950615Sobrien if (!strcmp (argv[i], "--help")) 494050615Sobrien { 494150615Sobrien display_help (); 494250615Sobrien exit (0); 494350615Sobrien } 494450615Sobrien 494550615Sobrien if (strings_processed != 0) 494650615Sobrien i += strings_processed - 1; 494750615Sobrien } 494818334Speter else if (argv[i][0] == '-' && argv[i][1] != 0) 494918334Speter { 495018334Speter register char *str = argv[i] + 1; 495118334Speter if (str[0] == 'Y') 495218334Speter str++; 495318334Speter 495418334Speter if (str[0] == 'm') 495518334Speter set_target_switch (&str[1]); 495618334Speter else if (!strcmp (str, "dumpbase")) 495718334Speter { 495818334Speter dump_base_name = argv[++i]; 495918334Speter } 496018334Speter else if (str[0] == 'd') 496118334Speter { 496218334Speter register char *p = &str[1]; 496318334Speter while (*p) 496418334Speter switch (*p++) 496518334Speter { 496618334Speter case 'a': 496750615Sobrien branch_prob_dump = 1; 496818334Speter combine_dump = 1; 496950615Sobrien#ifdef DELAY_SLOTS 497018334Speter dbr_sched_dump = 1; 497150615Sobrien#endif 497218334Speter flow_dump = 1; 497352558Sobrien flow2_dump = 1; 497418334Speter global_reg_dump = 1; 497518334Speter jump_opt_dump = 1; 497650615Sobrien addressof_dump = 1; 497718334Speter jump2_opt_dump = 1; 497818334Speter local_reg_dump = 1; 497918334Speter loop_dump = 1; 498050615Sobrien regmove_dump = 1; 498118334Speter rtl_dump = 1; 498218334Speter cse_dump = 1, cse2_dump = 1; 498350615Sobrien gcse_dump = 1; 498418334Speter sched_dump = 1; 498518334Speter sched2_dump = 1; 498650615Sobrien#ifdef STACK_REGS 498718334Speter stack_reg_dump = 1; 498850615Sobrien#endif 498950615Sobrien#ifdef MACHINE_DEPENDENT_REORG 499050615Sobrien mach_dep_reorg_dump = 1; 499150615Sobrien#endif 499218334Speter break; 499350615Sobrien case 'A': 499450615Sobrien flag_debug_asm = 1; 499518334Speter break; 499650615Sobrien case 'b': 499750615Sobrien branch_prob_dump = 1; 499850615Sobrien break; 499918334Speter case 'c': 500018334Speter combine_dump = 1; 500118334Speter break; 500250615Sobrien#ifdef DELAY_SLOTS 500318334Speter case 'd': 500418334Speter dbr_sched_dump = 1; 500518334Speter break; 500650615Sobrien#endif 500718334Speter case 'f': 500818334Speter flow_dump = 1; 500918334Speter break; 501050615Sobrien case 'F': 501150615Sobrien addressof_dump = 1; 501250615Sobrien break; 501318334Speter case 'g': 501418334Speter global_reg_dump = 1; 501518334Speter break; 501650615Sobrien case 'G': 501750615Sobrien gcse_dump = 1; 501850615Sobrien break; 501918334Speter case 'j': 502018334Speter jump_opt_dump = 1; 502118334Speter break; 502218334Speter case 'J': 502318334Speter jump2_opt_dump = 1; 502418334Speter break; 502550615Sobrien#ifdef STACK_REGS 502650615Sobrien case 'k': 502750615Sobrien stack_reg_dump = 1; 502850615Sobrien break; 502950615Sobrien#endif 503018334Speter case 'l': 503118334Speter local_reg_dump = 1; 503218334Speter break; 503318334Speter case 'L': 503418334Speter loop_dump = 1; 503518334Speter break; 503618334Speter case 'm': 503718334Speter flag_print_mem = 1; 503818334Speter break; 503950615Sobrien#ifdef MACHINE_DEPENDENT_REORG 504050615Sobrien case 'M': 504150615Sobrien mach_dep_reorg_dump = 1; 504250615Sobrien break; 504350615Sobrien#endif 504418334Speter case 'p': 504518334Speter flag_print_asm_name = 1; 504618334Speter break; 504718334Speter case 'r': 504818334Speter rtl_dump = 1; 504918334Speter break; 505050615Sobrien case 'R': 505150615Sobrien sched2_dump = 1; 505250615Sobrien break; 505318334Speter case 's': 505418334Speter cse_dump = 1; 505518334Speter break; 505650615Sobrien case 'S': 505750615Sobrien sched_dump = 1; 505850615Sobrien break; 505918334Speter case 't': 506018334Speter cse2_dump = 1; 506118334Speter break; 506250615Sobrien case 'N': 506350615Sobrien regmove_dump = 1; 506418334Speter break; 506552558Sobrien case 'v': 506652558Sobrien graph_dump_format = vcg; 506752558Sobrien break; 506852558Sobrien case 'w': 506952558Sobrien flow2_dump = 1; 507052558Sobrien break; 507118334Speter case 'y': 507218334Speter set_yydebug (1); 507318334Speter break; 507418334Speter case 'x': 507518334Speter rtl_dump_and_exit = 1; 507618334Speter break; 507752558Sobrien case 'D': /* these are handled by the preprocessor */ 507852558Sobrien case 'I': 507952558Sobrien break; 508050615Sobrien default: 508150615Sobrien warning ("unrecognised gcc debugging option: %c", p[-1]); 508250615Sobrien break; 508318334Speter } 508418334Speter } 508518334Speter else if (str[0] == 'f') 508618334Speter { 508718334Speter register char *p = &str[1]; 508818334Speter int found = 0; 508918334Speter 509018334Speter /* Some kind of -f option. 509118334Speter P's value is the option sans `-f'. 509218334Speter Search for it in the table of options. */ 509318334Speter 509418334Speter for (j = 0; 509518334Speter !found && j < sizeof (f_options) / sizeof (f_options[0]); 509618334Speter j++) 509718334Speter { 509818334Speter if (!strcmp (p, f_options[j].string)) 509918334Speter { 510018334Speter *f_options[j].variable = f_options[j].on_value; 510118334Speter /* A goto here would be cleaner, 510218334Speter but breaks the vax pcc. */ 510318334Speter found = 1; 510418334Speter } 510518334Speter if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' 510618334Speter && ! strcmp (p+3, f_options[j].string)) 510718334Speter { 510818334Speter *f_options[j].variable = ! f_options[j].on_value; 510918334Speter found = 1; 511018334Speter } 511118334Speter } 511218334Speter 511318334Speter if (found) 511418334Speter ; 511552558Sobrien else if (!strncmp (p, "inline-limit-", 13)) 511652558Sobrien inline_max_insns = 511752558Sobrien read_integral_parameter (p + 13, p - 2, inline_max_insns); 511850615Sobrien#ifdef HAIFA 511950615Sobrien#ifdef INSN_SCHEDULING 512050615Sobrien else if (!strncmp (p, "sched-verbose-",14)) 512150615Sobrien fix_sched_param("verbose",&p[14]); 512250615Sobrien#endif 512350615Sobrien#endif /* HAIFA */ 512418334Speter else if (!strncmp (p, "fixed-", 6)) 512518334Speter fix_register (&p[6], 1, 1); 512618334Speter else if (!strncmp (p, "call-used-", 10)) 512718334Speter fix_register (&p[10], 0, 1); 512818334Speter else if (!strncmp (p, "call-saved-", 11)) 512918334Speter fix_register (&p[11], 0, 0); 513018334Speter else 513118334Speter error ("Invalid option `%s'", argv[i]); 513218334Speter } 513318334Speter else if (str[0] == 'O') 513418334Speter { 513552558Sobrien /* Already been treated above. Do nothing. */ 513618334Speter } 513718334Speter else if (!strcmp (str, "pedantic")) 513818334Speter pedantic = 1; 513918334Speter else if (!strcmp (str, "pedantic-errors")) 514018334Speter flag_pedantic_errors = pedantic = 1; 514118334Speter else if (!strcmp (str, "quiet")) 514218334Speter quiet_flag = 1; 514318334Speter else if (!strcmp (str, "version")) 514418334Speter version_flag = 1; 514518334Speter else if (!strcmp (str, "w")) 514618334Speter inhibit_warnings = 1; 514718334Speter else if (!strcmp (str, "W")) 514818334Speter { 514918334Speter extra_warnings = 1; 515018334Speter /* We save the value of warn_uninitialized, since if they put 515118334Speter -Wuninitialized on the command line, we need to generate a 515218334Speter warning about not using it without also specifying -O. */ 515318334Speter if (warn_uninitialized != 1) 515418334Speter warn_uninitialized = 2; 515518334Speter } 515618334Speter else if (str[0] == 'W') 515718334Speter { 515818334Speter register char *p = &str[1]; 515918334Speter int found = 0; 516018334Speter 516118334Speter /* Some kind of -W option. 516218334Speter P's value is the option sans `-W'. 516318334Speter Search for it in the table of options. */ 516418334Speter 516518334Speter for (j = 0; 516618334Speter !found && j < sizeof (W_options) / sizeof (W_options[0]); 516718334Speter j++) 516818334Speter { 516918334Speter if (!strcmp (p, W_options[j].string)) 517018334Speter { 517118334Speter *W_options[j].variable = W_options[j].on_value; 517218334Speter /* A goto here would be cleaner, 517318334Speter but breaks the vax pcc. */ 517418334Speter found = 1; 517518334Speter } 517618334Speter if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' 517718334Speter && ! strcmp (p+3, W_options[j].string)) 517818334Speter { 517918334Speter *W_options[j].variable = ! W_options[j].on_value; 518018334Speter found = 1; 518118334Speter } 518218334Speter } 518318334Speter 518418334Speter if (found) 518518334Speter ; 518618334Speter else if (!strncmp (p, "id-clash-", 9)) 518718334Speter { 518852558Sobrien const int id_clash_val 518952558Sobrien = read_integral_parameter (p + 9, p - 2, -1); 519052558Sobrien if (id_clash_val != -1) 519118334Speter { 519252558Sobrien id_clash_len = id_clash_val; 519352558Sobrien warn_id_clash = 1; 519418334Speter } 519518334Speter } 519618334Speter else if (!strncmp (p, "larger-than-", 12)) 519718334Speter { 519852558Sobrien const int larger_than_val 519952558Sobrien = read_integral_parameter (p + 12, p - 2, -1); 520052558Sobrien if (larger_than_val != -1) 520118334Speter { 520252558Sobrien larger_than_size = larger_than_val; 520352558Sobrien warn_larger_than = 1; 520418334Speter } 520518334Speter } 520618334Speter else 520718334Speter error ("Invalid option `%s'", argv[i]); 520818334Speter } 520918334Speter else if (!strcmp (str, "p")) 521018334Speter { 521150615Sobrien profile_flag = 1; 521218334Speter } 521318334Speter else if (!strcmp (str, "a")) 521418334Speter { 521518334Speter#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER) 521618334Speter warning ("`-a' option (basic block profile) not supported"); 521718334Speter#else 521850615Sobrien profile_block_flag = (profile_block_flag < 2) ? 1 : 3; 521918334Speter#endif 522018334Speter } 522150615Sobrien else if (!strcmp (str, "ax")) 522250615Sobrien { 522350615Sobrien#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER) 522450615Sobrien warning ("`-ax' option (jump profiling) not supported"); 522550615Sobrien#else 522650615Sobrien profile_block_flag = (!profile_block_flag 522750615Sobrien || profile_block_flag == 2) ? 2 : 3; 522850615Sobrien#endif 522950615Sobrien } 523018334Speter else if (str[0] == 'g') 523118334Speter { 523218334Speter unsigned level; 523350615Sobrien /* A lot of code assumes write_symbols == NO_DEBUG if the 523450615Sobrien debugging level is 0 (thus -gstabs1 -gstabs0 would lose track 523550615Sobrien of what debugging type has been selected). This records the 523650615Sobrien selected type. It is an error to specify more than one 523750615Sobrien debugging type. */ 523850615Sobrien static enum debug_info_type selected_debug_type = NO_DEBUG; 523950615Sobrien /* Non-zero if debugging format has been explicitly set. 524050615Sobrien -g and -ggdb don't explicitly set the debugging format so 524150615Sobrien -gdwarf -g3 is equivalent to -gdwarf3. */ 524250615Sobrien static int type_explicitly_set_p = 0; 524350615Sobrien /* Indexed by enum debug_info_type. */ 524452558Sobrien static const char *debug_type_names[] = 524550615Sobrien { 524650615Sobrien "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff" 524750615Sobrien }; 524818334Speter 524952558Sobrien /* The maximum admissible debug level value. */ 525052558Sobrien static const unsigned max_debug_level = 3; 525152558Sobrien 525250615Sobrien /* Look up STR in the table. */ 525350615Sobrien for (da = debug_args; da->arg; da++) 525418334Speter { 525552558Sobrien const int da_len = strlen (da->arg); 525652558Sobrien 525752558Sobrien if (! strncmp (str, da->arg, da_len)) 525850615Sobrien { 525950615Sobrien enum debug_info_type type = da->debug_type; 526052558Sobrien const char *p = str + da_len; 526118334Speter 526250615Sobrien if (*p && (*p < '0' || *p > '9')) 526350615Sobrien continue; 526452558Sobrien 526552558Sobrien /* A debug flag without a level defaults to level 2. 526652558Sobrien Note we do not want to call read_integral_parameter 526752558Sobrien for that case since it will call atoi which 526852558Sobrien will return zero. 526952558Sobrien 527052558Sobrien ??? We may want to generalize the interface to 527152558Sobrien read_integral_parameter to better handle this case 527252558Sobrien if this case shows up often. */ 527350615Sobrien if (*p) 527452558Sobrien level = read_integral_parameter (p, 0, 527552558Sobrien max_debug_level + 1); 527652558Sobrien else 527752558Sobrien level = 2; 527852558Sobrien 527952558Sobrien if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len)) 528050615Sobrien { 528152558Sobrien error ("use -gdwarf -g%d for DWARF v1, level %d", 528252558Sobrien level, level); 528352558Sobrien if (level == 2) 528452558Sobrien error ("use -gdwarf-2 for DWARF v2"); 528550615Sobrien } 528652558Sobrien 528752558Sobrien if (level > max_debug_level) 528850615Sobrien { 528952558Sobrien warning ("ignoring option `%s' due to invalid debug level specification", 529052558Sobrien str - 1); 529152558Sobrien level = debug_info_level; 529250615Sobrien } 529350615Sobrien 529450615Sobrien if (type == NO_DEBUG) 529550615Sobrien { 529650615Sobrien type = PREFERRED_DEBUGGING_TYPE; 529752558Sobrien if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0) 529850615Sobrien { 529950615Sobrien#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2) 530050615Sobrien type = DWARF2_DEBUG; 530150615Sobrien#else 530218334Speter#ifdef DBX_DEBUGGING_INFO 530350615Sobrien type = DBX_DEBUG; 530450615Sobrien#endif 530550615Sobrien#endif 530650615Sobrien } 530750615Sobrien } 530818334Speter 530950615Sobrien if (type == NO_DEBUG) 531050615Sobrien warning ("`-%s' not supported by this configuration of GCC", 531150615Sobrien str); 531218334Speter 531350615Sobrien /* Does it conflict with an already selected type? */ 531450615Sobrien if (type_explicitly_set_p 531550615Sobrien /* -g/-ggdb don't conflict with anything */ 531650615Sobrien && da->debug_type != NO_DEBUG 531750615Sobrien && type != selected_debug_type) 531850615Sobrien warning ("`-%s' ignored, conflicts with `-g%s'", 531950615Sobrien str, debug_type_names[(int) selected_debug_type]); 532050615Sobrien else 532150615Sobrien { 532250615Sobrien /* If the format has already been set, -g/-ggdb 532350615Sobrien only change the debug level. */ 532450615Sobrien if (type_explicitly_set_p 532550615Sobrien && da->debug_type == NO_DEBUG) 532650615Sobrien ; /* don't change debugging type */ 532750615Sobrien else 532850615Sobrien { 532950615Sobrien selected_debug_type = type; 533050615Sobrien type_explicitly_set_p = da->debug_type != NO_DEBUG; 533150615Sobrien } 533250615Sobrien write_symbols = (level == 0 533350615Sobrien ? NO_DEBUG 533450615Sobrien : selected_debug_type); 533550615Sobrien use_gnu_debug_info_extensions = da->use_extensions_p; 533650615Sobrien debug_info_level = (enum debug_info_level) level; 533750615Sobrien } 533850615Sobrien break; 533950615Sobrien } 534050615Sobrien } 534150615Sobrien if (! da->arg) 534218334Speter warning ("`-%s' not supported by this configuration of GCC", 534318334Speter str); 534418334Speter } 534518334Speter else if (!strcmp (str, "o")) 534618334Speter { 534718334Speter asm_file_name = argv[++i]; 534818334Speter } 534918334Speter else if (str[0] == 'G') 535018334Speter { 535152558Sobrien const int g_switch_val = (str[1] != '\0') ? 535252558Sobrien read_integral_parameter(str + 1, 0, -1) : 535352558Sobrien read_integral_parameter(argv[++i], 0, -1); 535452558Sobrien 535552558Sobrien if (g_switch_val != -1) 535652558Sobrien { 535752558Sobrien g_switch_set = TRUE; 535852558Sobrien g_switch_value = g_switch_val; 535952558Sobrien } 536052558Sobrien else 536152558Sobrien { 536252558Sobrien error("Invalid option `-%s'",str); 536352558Sobrien } 536418334Speter } 536518334Speter else if (!strncmp (str, "aux-info", 8)) 536618334Speter { 536718334Speter flag_gen_aux_info = 1; 536818334Speter aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]); 536918334Speter } 537050615Sobrien else if (!strcmp (str, "-help")) 537150615Sobrien { 537250615Sobrien display_help (); 537350615Sobrien exit (0); 537450615Sobrien } 537518334Speter else 537618334Speter error ("Invalid option `%s'", argv[i]); 537718334Speter } 537818334Speter else if (argv[i][0] == '+') 537918334Speter error ("Invalid option `%s'", argv[i]); 538018334Speter else 538118334Speter filename = argv[i]; 538218334Speter } 538318334Speter 538450615Sobrien /* Checker uses the frame pointer. */ 538550615Sobrien if (flag_check_memory_usage) 538650615Sobrien flag_omit_frame_pointer = 0; 538718334Speter 538818334Speter if (optimize == 0) 538918334Speter { 539018334Speter /* Inlining does not work if not optimizing, 539118334Speter so force it not to be done. */ 539218334Speter flag_no_inline = 1; 539318334Speter warn_inline = 0; 539418334Speter 539518334Speter /* The c_decode_option and lang_decode_option functions set 539618334Speter this to `2' if -Wall is used, so we can avoid giving out 539718334Speter lots of errors for people who don't realize what -Wall does. */ 539818334Speter if (warn_uninitialized == 1) 539918334Speter warning ("-Wuninitialized is not supported without -O"); 540018334Speter } 540118334Speter 540218334Speter#ifdef OVERRIDE_OPTIONS 540318334Speter /* Some machines may reject certain combinations of options. */ 540418334Speter OVERRIDE_OPTIONS; 540518334Speter#endif 540618334Speter 540750615Sobrien if (exceptions_via_longjmp == 2) 540850615Sobrien { 540950615Sobrien#ifdef DWARF2_UNWIND_INFO 541050615Sobrien exceptions_via_longjmp = ! DWARF2_UNWIND_INFO; 541150615Sobrien#else 541250615Sobrien exceptions_via_longjmp = 1; 541350615Sobrien#endif 541450615Sobrien } 541550615Sobrien 541650615Sobrien if (profile_block_flag == 3) 541750615Sobrien { 541850615Sobrien warning ("`-ax' and `-a' are conflicting options. `-a' ignored."); 541950615Sobrien profile_block_flag = 2; 542050615Sobrien } 542150615Sobrien 542218334Speter /* Unrolling all loops implies that standard loop unrolling must also 542318334Speter be done. */ 542418334Speter if (flag_unroll_all_loops) 542518334Speter flag_unroll_loops = 1; 542618334Speter /* Loop unrolling requires that strength_reduction be on also. Silently 542718334Speter turn on strength reduction here if it isn't already on. Also, the loop 542818334Speter unrolling code assumes that cse will be run after loop, so that must 542918334Speter be turned on also. */ 543018334Speter if (flag_unroll_loops) 543118334Speter { 543218334Speter flag_strength_reduce = 1; 543318334Speter flag_rerun_cse_after_loop = 1; 543418334Speter } 543518334Speter 543618334Speter /* Warn about options that are not supported on this machine. */ 543718334Speter#ifndef INSN_SCHEDULING 543818334Speter if (flag_schedule_insns || flag_schedule_insns_after_reload) 543918334Speter warning ("instruction scheduling not supported on this target machine"); 544018334Speter#endif 544118334Speter#ifndef DELAY_SLOTS 544218334Speter if (flag_delayed_branch) 544318334Speter warning ("this target machine does not have delayed branches"); 544418334Speter#endif 544518334Speter 544652558Sobrien user_label_prefix = USER_LABEL_PREFIX; 544752558Sobrien if (flag_leading_underscore != -1) 544852558Sobrien { 544952558Sobrien /* If the default prefix is more complicated than "" or "_", 545052558Sobrien issue a warning and ignore this option. */ 545152558Sobrien if (user_label_prefix[0] == 0 || 545252558Sobrien (user_label_prefix[0] == '_' && user_label_prefix[1] == 0)) 545352558Sobrien { 545452558Sobrien user_label_prefix = flag_leading_underscore ? "_" : ""; 545552558Sobrien } 545652558Sobrien else 545752558Sobrien warning ("-f%sleading-underscore not supported on this target machine", 545852558Sobrien flag_leading_underscore ? "" : "no-"); 545952558Sobrien } 546052558Sobrien 546118334Speter /* If we are in verbose mode, write out the version and maybe all the 546218334Speter option flags in use. */ 546318334Speter if (version_flag) 546418334Speter { 546550615Sobrien print_version (stderr, ""); 546618334Speter if (! quiet_flag) 546750615Sobrien print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n"); 546818334Speter } 546918334Speter 547018334Speter compile_file (filename); 547118334Speter 547252558Sobrien#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX) 547318334Speter if (flag_print_mem) 547418334Speter { 547518334Speter char *lim = (char *) sbrk (0); 547618334Speter 547752558Sobrien notice ("Data size %ld.\n", (long) (lim - (char *) &environ)); 547818334Speter fflush (stderr); 547918334Speter 548050615Sobrien#ifndef __MSDOS__ 548118334Speter#ifdef USG 548218334Speter system ("ps -l 1>&2"); 548318334Speter#else /* not USG */ 548418334Speter system ("ps v"); 548518334Speter#endif /* not USG */ 548650615Sobrien#endif 548718334Speter } 548852558Sobrien#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */ 548918334Speter 549018334Speter if (errorcount) 549118334Speter exit (FATAL_EXIT_CODE); 549218334Speter if (sorrycount) 549318334Speter exit (FATAL_EXIT_CODE); 549418334Speter exit (SUCCESS_EXIT_CODE); 549518334Speter return 0; 549618334Speter} 549718334Speter 549818334Speter/* Decode -m switches. */ 549918334Speter/* Decode the switch -mNAME. */ 550018334Speter 550152558Sobrienstatic void 550218334Speterset_target_switch (name) 550352558Sobrien const char *name; 550418334Speter{ 550550615Sobrien register size_t j; 550652558Sobrien int valid_target_option = 0; 550718334Speter 550818334Speter for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) 550918334Speter if (!strcmp (target_switches[j].name, name)) 551018334Speter { 551118334Speter if (target_switches[j].value < 0) 551218334Speter target_flags &= ~-target_switches[j].value; 551318334Speter else 551418334Speter target_flags |= target_switches[j].value; 551552558Sobrien valid_target_option = 1; 551618334Speter } 551718334Speter 551818334Speter#ifdef TARGET_OPTIONS 551952558Sobrien if (!valid_target_option) 552018334Speter for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++) 552118334Speter { 552218334Speter int len = strlen (target_options[j].prefix); 552318334Speter if (!strncmp (target_options[j].prefix, name, len)) 552418334Speter { 552518334Speter *target_options[j].variable = name + len; 552652558Sobrien valid_target_option = 1; 552718334Speter } 552818334Speter } 552918334Speter#endif 553018334Speter 553152558Sobrien if (!valid_target_option) 553218334Speter error ("Invalid option `%s'", name); 553318334Speter} 553418334Speter 553550615Sobrien/* Print version information to FILE. 553650615Sobrien Each line begins with INDENT (for the case where FILE is the 553750615Sobrien assembler output file). */ 553818334Speter 553952558Sobrienstatic void 554050615Sobrienprint_version (file, indent) 554150615Sobrien FILE *file; 554252558Sobrien const char *indent; 554350615Sobrien{ 554450615Sobrien#ifndef __VERSION__ 554552558Sobrien#define __VERSION__ "[?]" 554650615Sobrien#endif 554752558Sobrien fnotice (file, 554852558Sobrien#ifdef __GNUC__ 554952558Sobrien "%s%s%s version %s (%s) compiled by GNU C version %s.\n" 555050615Sobrien#else 555152558Sobrien "%s%s%s version %s (%s) compiled by CC.\n" 555250615Sobrien#endif 555352558Sobrien , indent, *indent != 0 ? " " : "", 555452558Sobrien language_string, version_string, TARGET_NAME, __VERSION__); 555550615Sobrien} 555618334Speter 555750615Sobrien/* Print an option value and return the adjusted position in the line. 555850615Sobrien ??? We don't handle error returns from fprintf (disk full); presumably 555950615Sobrien other code will catch a disk full though. */ 556018334Speter 556152558Sobrienstatic int 556250615Sobrienprint_single_switch (file, pos, max, indent, sep, term, type, name) 556350615Sobrien FILE *file; 556450615Sobrien int pos, max; 556552558Sobrien const char *indent, *sep, *term, *type, *name; 556618334Speter{ 556750615Sobrien /* The ultrix fprintf returns 0 on success, so compute the result we want 556850615Sobrien here since we need it for the following test. */ 556950615Sobrien int len = strlen (sep) + strlen (type) + strlen (name); 557018334Speter 557150615Sobrien if (pos != 0 557250615Sobrien && pos + len > max) 557318334Speter { 557450615Sobrien fprintf (file, "%s", term); 557550615Sobrien pos = 0; 557618334Speter } 557750615Sobrien if (pos == 0) 557850615Sobrien { 557950615Sobrien fprintf (file, "%s", indent); 558050615Sobrien pos = strlen (indent); 558150615Sobrien } 558250615Sobrien fprintf (file, "%s%s%s", sep, type, name); 558350615Sobrien pos += len; 558450615Sobrien return pos; 558518334Speter} 558618334Speter 558750615Sobrien/* Print active target switches to FILE. 558850615Sobrien POS is the current cursor position and MAX is the size of a "line". 558950615Sobrien Each line begins with INDENT and ends with TERM. 559050615Sobrien Each switch is separated from the next by SEP. */ 559118334Speter 559252558Sobrienstatic void 559350615Sobrienprint_switch_values (file, pos, max, indent, sep, term) 559450615Sobrien FILE *file; 559550615Sobrien int pos, max; 559652558Sobrien const char *indent, *sep, *term; 559718334Speter{ 559850615Sobrien size_t j; 559950615Sobrien char **p; 560018334Speter 560150615Sobrien /* Print the options as passed. */ 560218334Speter 560350615Sobrien pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term, 560452558Sobrien _("options passed: "), ""); 560550615Sobrien 560650615Sobrien for (p = &save_argv[1]; *p != NULL; p++) 560750615Sobrien if (**p == '-') 560850615Sobrien { 560950615Sobrien /* Ignore these. */ 561050615Sobrien if (strcmp (*p, "-o") == 0) 561150615Sobrien { 561250615Sobrien if (p[1] != NULL) 561350615Sobrien p++; 561450615Sobrien continue; 561550615Sobrien } 561650615Sobrien if (strcmp (*p, "-quiet") == 0) 561750615Sobrien continue; 561850615Sobrien if (strcmp (*p, "-version") == 0) 561950615Sobrien continue; 562050615Sobrien if ((*p)[1] == 'd') 562150615Sobrien continue; 562250615Sobrien 562350615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, *p, ""); 562450615Sobrien } 562550615Sobrien if (pos > 0) 562650615Sobrien fprintf (file, "%s", term); 562750615Sobrien 562850615Sobrien /* Print the -f and -m options that have been enabled. 562950615Sobrien We don't handle language specific options but printing argv 563050615Sobrien should suffice. */ 563150615Sobrien 563250615Sobrien pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term, 563352558Sobrien _("options enabled: "), ""); 563450615Sobrien 563518334Speter for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++) 563618334Speter if (*f_options[j].variable == f_options[j].on_value) 563750615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 563850615Sobrien "-f", f_options[j].string); 563918334Speter 564050615Sobrien /* Print target specific options. */ 564118334Speter 564218334Speter for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) 564318334Speter if (target_switches[j].name[0] != '\0' 564418334Speter && target_switches[j].value > 0 564518334Speter && ((target_switches[j].value & target_flags) 564618334Speter == target_switches[j].value)) 564750615Sobrien { 564850615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 564950615Sobrien "-m", target_switches[j].name); 565050615Sobrien } 565118334Speter 565250615Sobrien#ifdef TARGET_OPTIONS 565350615Sobrien for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++) 565450615Sobrien if (*target_options[j].variable != NULL) 565550615Sobrien { 565650615Sobrien char prefix[256]; 565750615Sobrien sprintf (prefix, "-m%s", target_options[j].prefix); 565850615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 565950615Sobrien prefix, *target_options[j].variable); 566050615Sobrien } 566150615Sobrien#endif 566250615Sobrien 566350615Sobrien fprintf (file, "%s", term); 566418334Speter} 566550615Sobrien 566650615Sobrien/* Record the beginning of a new source file, named FILENAME. */ 566750615Sobrien 566850615Sobrienvoid 566950615Sobriendebug_start_source_file (filename) 567052558Sobrien register char *filename ATTRIBUTE_UNUSED; 567150615Sobrien{ 567250615Sobrien#ifdef DBX_DEBUGGING_INFO 567350615Sobrien if (write_symbols == DBX_DEBUG) 567450615Sobrien dbxout_start_new_source_file (filename); 567550615Sobrien#endif 567650615Sobrien#ifdef DWARF_DEBUGGING_INFO 567750615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 567850615Sobrien && write_symbols == DWARF_DEBUG) 567950615Sobrien dwarfout_start_new_source_file (filename); 568050615Sobrien#endif /* DWARF_DEBUGGING_INFO */ 568150615Sobrien#ifdef DWARF2_DEBUGGING_INFO 568250615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 568350615Sobrien && write_symbols == DWARF2_DEBUG) 568450615Sobrien dwarf2out_start_source_file (filename); 568550615Sobrien#endif /* DWARF2_DEBUGGING_INFO */ 568650615Sobrien#ifdef SDB_DEBUGGING_INFO 568750615Sobrien if (write_symbols == SDB_DEBUG) 568850615Sobrien sdbout_start_new_source_file (filename); 568950615Sobrien#endif 569050615Sobrien} 569150615Sobrien 569250615Sobrien/* Record the resumption of a source file. LINENO is the line number in 569350615Sobrien the source file we are returning to. */ 569450615Sobrien 569550615Sobrienvoid 569650615Sobriendebug_end_source_file (lineno) 569752558Sobrien register unsigned lineno ATTRIBUTE_UNUSED; 569850615Sobrien{ 569950615Sobrien#ifdef DBX_DEBUGGING_INFO 570050615Sobrien if (write_symbols == DBX_DEBUG) 570150615Sobrien dbxout_resume_previous_source_file (); 570250615Sobrien#endif 570350615Sobrien#ifdef DWARF_DEBUGGING_INFO 570450615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 570550615Sobrien && write_symbols == DWARF_DEBUG) 570650615Sobrien dwarfout_resume_previous_source_file (lineno); 570750615Sobrien#endif /* DWARF_DEBUGGING_INFO */ 570850615Sobrien#ifdef DWARF2_DEBUGGING_INFO 570950615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 571050615Sobrien && write_symbols == DWARF2_DEBUG) 571150615Sobrien dwarf2out_end_source_file (); 571250615Sobrien#endif /* DWARF2_DEBUGGING_INFO */ 571350615Sobrien#ifdef SDB_DEBUGGING_INFO 571450615Sobrien if (write_symbols == SDB_DEBUG) 571550615Sobrien sdbout_resume_previous_source_file (); 571650615Sobrien#endif 571750615Sobrien} 571850615Sobrien 571950615Sobrien/* Called from check_newline in c-parse.y. The `buffer' parameter contains 572050615Sobrien the tail part of the directive line, i.e. the part which is past the 572150615Sobrien initial whitespace, #, whitespace, directive-name, whitespace part. */ 572250615Sobrien 572350615Sobrienvoid 572450615Sobriendebug_define (lineno, buffer) 572552558Sobrien register unsigned lineno ATTRIBUTE_UNUSED; 572652558Sobrien register char *buffer ATTRIBUTE_UNUSED; 572750615Sobrien{ 572850615Sobrien#ifdef DWARF_DEBUGGING_INFO 572950615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 573050615Sobrien && write_symbols == DWARF_DEBUG) 573150615Sobrien dwarfout_define (lineno, buffer); 573250615Sobrien#endif /* DWARF_DEBUGGING_INFO */ 573350615Sobrien#ifdef DWARF2_DEBUGGING_INFO 573450615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 573550615Sobrien && write_symbols == DWARF2_DEBUG) 573650615Sobrien dwarf2out_define (lineno, buffer); 573750615Sobrien#endif /* DWARF2_DEBUGGING_INFO */ 573850615Sobrien} 573950615Sobrien 574050615Sobrien/* Called from check_newline in c-parse.y. The `buffer' parameter contains 574150615Sobrien the tail part of the directive line, i.e. the part which is past the 574250615Sobrien initial whitespace, #, whitespace, directive-name, whitespace part. */ 574350615Sobrien 574450615Sobrienvoid 574550615Sobriendebug_undef (lineno, buffer) 574652558Sobrien register unsigned lineno ATTRIBUTE_UNUSED; 574752558Sobrien register char *buffer ATTRIBUTE_UNUSED; 574850615Sobrien{ 574950615Sobrien#ifdef DWARF_DEBUGGING_INFO 575050615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 575150615Sobrien && write_symbols == DWARF_DEBUG) 575250615Sobrien dwarfout_undef (lineno, buffer); 575350615Sobrien#endif /* DWARF_DEBUGGING_INFO */ 575450615Sobrien#ifdef DWARF2_DEBUGGING_INFO 575550615Sobrien if (debug_info_level == DINFO_LEVEL_VERBOSE 575650615Sobrien && write_symbols == DWARF2_DEBUG) 575750615Sobrien dwarf2out_undef (lineno, buffer); 575850615Sobrien#endif /* DWARF2_DEBUGGING_INFO */ 575950615Sobrien} 5760