toplev.c revision 117414
118334Speter/* Top level of GNU C compiler 272566Sobrien Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3117414Skan 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 418334Speter 590282SobrienThis file is part of GCC. 618334Speter 790282SobrienGCC is free software; you can redistribute it and/or modify it under 890282Sobrienthe terms of the GNU General Public License as published by the Free 990282SobrienSoftware Foundation; either version 2, or (at your option) any later 1090282Sobrienversion. 1118334Speter 1290282SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390282SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490282SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590282Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890282Sobrienalong with GCC; see the file COPYING. If not, write to the Free 1990282SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2090282Sobrien02111-1307, USA. */ 2118334Speter 2252558Sobrien/* $FreeBSD: head/contrib/gcc/toplev.c 117414 2003-07-11 04:48:05Z kan $ */ 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 3550615Sobrien#ifdef HAVE_SYS_RESOURCE_H 3650615Sobrien# include <sys/resource.h> 3718334Speter#endif 3850615Sobrien 3950615Sobrien#ifdef HAVE_SYS_TIMES_H 4050615Sobrien# include <sys/times.h> 4118334Speter#endif 4218334Speter 4318334Speter#include "input.h" 4418334Speter#include "tree.h" 4518334Speter#include "rtl.h" 4690282Sobrien#include "tm_p.h" 4718334Speter#include "flags.h" 4818334Speter#include "insn-attr.h" 4950615Sobrien#include "insn-config.h" 5090282Sobrien#include "insn-flags.h" 5190282Sobrien#include "hard-reg-set.h" 5250615Sobrien#include "recog.h" 5318334Speter#include "output.h" 5450615Sobrien#include "except.h" 5590282Sobrien#include "function.h" 5650615Sobrien#include "toplev.h" 5752558Sobrien#include "expr.h" 5852558Sobrien#include "basic-block.h" 5952558Sobrien#include "intl.h" 6090282Sobrien#include "ggc.h" 6190282Sobrien#include "graph.h" 6290282Sobrien#include "loop.h" 6390282Sobrien#include "regs.h" 6490282Sobrien#include "timevar.h" 6590282Sobrien#include "diagnostic.h" 6690282Sobrien#include "ssa.h" 6790282Sobrien#include "params.h" 6890282Sobrien#include "reload.h" 6990282Sobrien#include "dwarf2asm.h" 7090282Sobrien#include "integrate.h" 71117414Skan#include "real.h" 7290282Sobrien#include "debug.h" 7390282Sobrien#include "target.h" 7490282Sobrien#include "langhooks.h" 75117414Skan#include "cfglayout.h" 7618334Speter 7750615Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) 7850615Sobrien#include "dwarf2out.h" 7950615Sobrien#endif 8050615Sobrien 8150615Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) 8250615Sobrien#include "dbxout.h" 8350615Sobrien#endif 8450615Sobrien 8550615Sobrien#ifdef SDB_DEBUGGING_INFO 8650615Sobrien#include "sdbout.h" 8750615Sobrien#endif 8850615Sobrien 8918334Speter#ifdef XCOFF_DEBUGGING_INFO 9090282Sobrien#include "xcoffout.h" /* Needed for external data 9190282Sobrien declarations for e.g. AIX 4.x. */ 9218334Speter#endif 9318334Speter 9418334Speter/* Carry information from ASM_DECLARE_OBJECT_NAME 9518334Speter to ASM_FINISH_DECLARE_OBJECT. */ 9618334Speter 9718334Speterextern int size_directive_output; 9818334Speterextern tree last_assemble_variable_decl; 9918334Speter 100117414Skanextern void reg_alloc PARAMS ((void)); 101117414Skan 10290282Sobrienstatic void general_init PARAMS ((char *)); 10390282Sobrienstatic void parse_options_and_default_flags PARAMS ((int, char **)); 10490282Sobrienstatic void do_compile PARAMS ((void)); 10590282Sobrienstatic void process_options PARAMS ((void)); 106117414Skanstatic void backend_init PARAMS ((void)); 10790282Sobrienstatic int lang_dependent_init PARAMS ((const char *)); 10890282Sobrienstatic void init_asm_output PARAMS ((const char *)); 10990282Sobrienstatic void finalize PARAMS ((void)); 11018334Speter 11190282Sobrienstatic void set_target_switch PARAMS ((const char *)); 11250615Sobrien 11390282Sobrienstatic void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN; 11490282Sobrienstatic void compile_file PARAMS ((void)); 11590282Sobrienstatic void display_help PARAMS ((void)); 11690282Sobrienstatic void display_target_options PARAMS ((void)); 11718334Speter 11890282Sobrienstatic void decode_d_option PARAMS ((const char *)); 11990282Sobrienstatic int decode_f_option PARAMS ((const char *)); 12090282Sobrienstatic int decode_W_option PARAMS ((const char *)); 12190282Sobrienstatic int decode_g_option PARAMS ((const char *)); 12290282Sobrienstatic unsigned int independent_decode_option PARAMS ((int, char **)); 12390282Sobrien 12490282Sobrienstatic void print_version PARAMS ((FILE *, const char *)); 12590282Sobrienstatic int print_single_switch PARAMS ((FILE *, int, int, const char *, 12652558Sobrien const char *, const char *, 12752558Sobrien const char *, const char *)); 12890282Sobrienstatic void print_switch_values PARAMS ((FILE *, int, int, const char *, 12952558Sobrien const char *, const char *)); 13052558Sobrien 131117414Skan/* Nonzero to dump debug info whilst parsing (-dy option). */ 132117414Skanstatic int set_yydebug; 133117414Skan 13450615Sobrien/* Length of line when printing switch values. */ 13550615Sobrien#define MAX_LINE 75 13618334Speter 13718334Speter/* Name of program invoked, sans directories. */ 13818334Speter 13990282Sobrienconst char *progname; 14018334Speter 14190282Sobrien/* Copy of arguments to toplev_main. */ 14218334Speterint save_argc; 14318334Speterchar **save_argv; 14418334Speter 14518334Speter/* Name of current original source file (what was input to cpp). 14618334Speter This comes from each #-command in the actual input. */ 14718334Speter 14890282Sobrienconst char *input_filename; 14918334Speter 15018334Speter/* Name of top-level original source file (what was input to cpp). 15118334Speter This comes from the #-command at the beginning of the actual input. 15218334Speter If there isn't any there, then this is the cc1 input file name. */ 15318334Speter 15490282Sobrienconst char *main_input_filename; 15518334Speter 15618334Speter/* Current line number in real source file. */ 15718334Speter 15818334Speterint lineno; 15918334Speter 16052558Sobrien/* Nonzero if it is unsafe to create any new pseudo registers. */ 16152558Sobrienint no_new_pseudos; 16252558Sobrien 16318334Speter/* Stack of currently pending input files. */ 16418334Speter 16518334Speterstruct file_stack *input_file_stack; 16618334Speter 16718334Speter/* Incremented on each change to input_file_stack. */ 16818334Speterint input_file_stack_tick; 16918334Speter 17018334Speter/* Name to use as base of names for dump output files. */ 17118334Speter 17252558Sobrienconst char *dump_base_name; 17318334Speter 174117414Skan/* Name to use as a base for auxiliary output files. */ 175117414Skan 176117414Skanconst char *aux_base_name; 177117414Skan 17890282Sobrien/* Format to use to print dumpfile index value */ 17990282Sobrien#ifndef DUMPFILE_FORMAT 18090282Sobrien#define DUMPFILE_FORMAT ".%02d." 18190282Sobrien#endif 18290282Sobrien 18318334Speter/* Bit flags that specify the machine subtype we are compiling for. 18418334Speter Bits are tested using macros TARGET_... defined in the tm.h file 18518334Speter and set by `-m...' switches. Must be defined in rtlanal.c. */ 18618334Speter 18718334Speterextern int target_flags; 18818334Speter 189117414Skan/* A mask of target_flags that includes bit X if X was set or cleared 190117414Skan on the command line. */ 191117414Skan 192117414Skanint target_flags_explicit; 193117414Skan 19490282Sobrien/* Debug hooks - dependent upon command line options. */ 19518334Speter 196117414Skanconst struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; 19790282Sobrien 19890282Sobrien/* Describes a dump file. */ 19990282Sobrien 20090282Sobrienstruct dump_file_info 20190282Sobrien{ 20290282Sobrien /* The unique extension to apply, e.g. ".jump". */ 20390282Sobrien const char *const extension; 20490282Sobrien 20590282Sobrien /* The -d<c> character that enables this dump file. */ 20690282Sobrien char const debug_switch; 20790282Sobrien 20890282Sobrien /* True if there is a corresponding graph dump file. */ 20990282Sobrien char const graph_dump_p; 21090282Sobrien 21190282Sobrien /* True if the user selected this dump. */ 21290282Sobrien char enabled; 21390282Sobrien 21490282Sobrien /* True if the files have been initialized (ie truncated). */ 21590282Sobrien char initialized; 21690282Sobrien}; 21790282Sobrien 21890282Sobrien/* Enumerate the extant dump files. */ 21990282Sobrien 22090282Sobrienenum dump_file_index 22190282Sobrien{ 22290282Sobrien DFI_rtl, 22390282Sobrien DFI_sibling, 22490282Sobrien DFI_eh, 22590282Sobrien DFI_jump, 22690282Sobrien DFI_ssa, 22790282Sobrien DFI_ssa_ccp, 22890282Sobrien DFI_ssa_dce, 22990282Sobrien DFI_ussa, 230117414Skan DFI_null, 23190282Sobrien DFI_cse, 23290282Sobrien DFI_addressof, 23390282Sobrien DFI_gcse, 23490282Sobrien DFI_loop, 23590282Sobrien DFI_cfg, 23690282Sobrien DFI_bp, 237117414Skan DFI_ce1, 238117414Skan DFI_tracer, 239117414Skan DFI_cse2, 24090282Sobrien DFI_life, 24190282Sobrien DFI_combine, 242117414Skan DFI_ce2, 24390282Sobrien DFI_regmove, 24490282Sobrien DFI_sched, 24590282Sobrien DFI_lreg, 24690282Sobrien DFI_greg, 24790282Sobrien DFI_postreload, 24890282Sobrien DFI_flow2, 24990282Sobrien DFI_peephole2, 25090282Sobrien DFI_rnreg, 251117414Skan DFI_ce3, 25290282Sobrien DFI_sched2, 25390282Sobrien DFI_stack, 25490282Sobrien DFI_bbro, 25590282Sobrien DFI_mach, 25690282Sobrien DFI_dbr, 25790282Sobrien DFI_MAX 25890282Sobrien}; 25990282Sobrien 26090282Sobrien/* Describes all the dump files. Should be kept in order of the 26190282Sobrien pass and in sync with dump_file_index above. 26290282Sobrien 26390282Sobrien Remaining -d letters: 26490282Sobrien 265117414Skan " o q " 26690282Sobrien " H JK OPQ TUV YZ" 26790282Sobrien*/ 26890282Sobrien 26990282Sobrienstatic struct dump_file_info dump_file[DFI_MAX] = 27090282Sobrien{ 27190282Sobrien { "rtl", 'r', 0, 0, 0 }, 27290282Sobrien { "sibling", 'i', 0, 0, 0 }, 27390282Sobrien { "eh", 'h', 0, 0, 0 }, 27490282Sobrien { "jump", 'j', 0, 0, 0 }, 27590282Sobrien { "ssa", 'e', 1, 0, 0 }, 27690282Sobrien { "ssaccp", 'W', 1, 0, 0 }, 27790282Sobrien { "ssadce", 'X', 1, 0, 0 }, 27890282Sobrien { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */ 279117414Skan { "null", 'u', 0, 0, 0 }, 28090282Sobrien { "cse", 's', 0, 0, 0 }, 28190282Sobrien { "addressof", 'F', 0, 0, 0 }, 28290282Sobrien { "gcse", 'G', 1, 0, 0 }, 28390282Sobrien { "loop", 'L', 1, 0, 0 }, 28490282Sobrien { "cfg", 'f', 1, 0, 0 }, 28590282Sobrien { "bp", 'b', 1, 0, 0 }, 286117414Skan { "ce1", 'C', 1, 0, 0 }, 287117414Skan { "tracer", 'T', 1, 0, 0 }, 288117414Skan { "cse2", 't', 1, 0, 0 }, 28990282Sobrien { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */ 29090282Sobrien { "combine", 'c', 1, 0, 0 }, 291117414Skan { "ce2", 'C', 1, 0, 0 }, 29290282Sobrien { "regmove", 'N', 1, 0, 0 }, 29390282Sobrien { "sched", 'S', 1, 0, 0 }, 29490282Sobrien { "lreg", 'l', 1, 0, 0 }, 29590282Sobrien { "greg", 'g', 1, 0, 0 }, 29690282Sobrien { "postreload", 'o', 1, 0, 0 }, 29790282Sobrien { "flow2", 'w', 1, 0, 0 }, 29890282Sobrien { "peephole2", 'z', 1, 0, 0 }, 29990282Sobrien { "rnreg", 'n', 1, 0, 0 }, 300117414Skan { "ce3", 'E', 1, 0, 0 }, 30190282Sobrien { "sched2", 'R', 1, 0, 0 }, 30290282Sobrien { "stack", 'k', 1, 0, 0 }, 30390282Sobrien { "bbro", 'B', 1, 0, 0 }, 30490282Sobrien { "mach", 'M', 1, 0, 0 }, 30590282Sobrien { "dbr", 'd', 0, 0, 0 }, 30690282Sobrien}; 30790282Sobrien 30890282Sobrienstatic int open_dump_file PARAMS ((enum dump_file_index, tree)); 30990282Sobrienstatic void close_dump_file PARAMS ((enum dump_file_index, 31090282Sobrien void (*) (FILE *, rtx), rtx)); 31190282Sobrien 31290282Sobrien/* Other flags saying which kinds of debugging dump have been requested. */ 31390282Sobrien 31490282Sobrienint rtl_dump_and_exit; 31590282Sobrienint flag_print_asm_name; 31690282Sobrienstatic int version_flag; 31790282Sobrienstatic char *filename; 31852558Sobrienenum graph_dump_types graph_dump_format; 31918334Speter 32018334Speter/* Name for output file of assembly code, specified with -o. */ 32118334Speter 32218334Speterchar *asm_file_name; 32318334Speter 32418334Speter/* Value of the -G xx switch, and whether it was passed or not. */ 32518334Speterint g_switch_value; 32618334Speterint g_switch_set; 32718334Speter 32818334Speter/* Type(s) of debugging information we are producing (if any). 32918334Speter See flags.h for the definitions of the different possible 33018334Speter types of debugging information. */ 33118334Speterenum debug_info_type write_symbols = NO_DEBUG; 33218334Speter 33318334Speter/* Level of debugging information we are producing. See flags.h 33418334Speter for the definitions of the different possible levels. */ 33518334Speterenum debug_info_level debug_info_level = DINFO_LEVEL_NONE; 33618334Speter 33718334Speter/* Nonzero means use GNU-only extensions in the generated symbolic 33818334Speter debugging information. */ 33918334Speter/* Currently, this only has an effect when write_symbols is set to 34018334Speter DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ 34118334Speterint use_gnu_debug_info_extensions = 0; 34218334Speter 34318334Speter/* Nonzero means do optimizations. -O. 34418334Speter Particular numeric values stand for particular amounts of optimization; 34518334Speter thus, -O2 stores 2 here. However, the optimizations beyond the basic 34618334Speter ones are not controlled directly by this variable. Instead, they are 34718334Speter controlled by individual `flag_...' variables that are defaulted 34818334Speter based on this variable. */ 34918334Speter 35018334Speterint optimize = 0; 35118334Speter 35250615Sobrien/* Nonzero means optimize for size. -Os. 353117414Skan The only valid values are zero and nonzero. When optimize_size is 354117414Skan nonzero, optimize defaults to 2, but certain individual code 35550615Sobrien bloating optimizations are disabled. */ 35650615Sobrien 35750615Sobrienint optimize_size = 0; 35850615Sobrien 35990282Sobrien/* Nonzero if we should exit after parsing options. */ 36090282Sobrienstatic int exit_after_options = 0; 36118334Speter 36290282Sobrien/* The FUNCTION_DECL for the function currently being compiled, 36390282Sobrien or 0 if between functions. */ 36490282Sobrientree current_function_decl; 36518334Speter 36690282Sobrien/* Set to the FUNC_BEGIN label of the current function, or NULL_TREE 36790282Sobrien if none. */ 36890282Sobrientree current_function_func_begin_label; 36990282Sobrien 37090282Sobrien/* Nonzero if doing dwarf2 duplicate elimination. */ 37190282Sobrien 37290282Sobrienint flag_eliminate_dwarf2_dups = 0; 37390282Sobrien 37418334Speter/* Nonzero if generating code to do profiling. */ 37518334Speter 37618334Speterint profile_flag = 0; 37718334Speter 37850615Sobrien/* Nonzero if generating code to profile program flow graph arcs. */ 37950615Sobrien 38050615Sobrienint profile_arc_flag = 0; 38150615Sobrien 38250615Sobrien/* Nonzero if generating info for gcov to calculate line test coverage. */ 38350615Sobrien 38450615Sobrienint flag_test_coverage = 0; 38550615Sobrien 38650615Sobrien/* Nonzero indicates that branch taken probabilities should be calculated. */ 38750615Sobrien 38850615Sobrienint flag_branch_probabilities = 0; 38950615Sobrien 39090282Sobrien/* Nonzero if basic blocks should be reordered. */ 39190282Sobrien 39290282Sobrienint flag_reorder_blocks = 0; 39390282Sobrien 394117414Skan/* Nonzero if functions should be reordered. */ 395117414Skan 396117414Skanint flag_reorder_functions = 0; 397117414Skan 39890282Sobrien/* Nonzero if registers should be renamed. */ 39990282Sobrien 40090282Sobrienint flag_rename_registers = 0; 40190282Sobrienint flag_cprop_registers = 0; 40290282Sobrien 40318334Speter/* Nonzero for -pedantic switch: warn about anything 40418334Speter that standard spec forbids. */ 40518334Speter 40618334Speterint pedantic = 0; 40718334Speter 40818334Speter/* Temporarily suppress certain warnings. 40918334Speter This is set while reading code from a system header file. */ 41018334Speter 41118334Speterint in_system_header = 0; 41218334Speter 41390282Sobrien/* Don't print functions as they are compiled. -quiet. */ 41418334Speter 41590282Sobrienint quiet_flag = 0; 41618334Speter 41790282Sobrien/* Print times taken by the various passes. -ftime-report. */ 41818334Speter 41990282Sobrienint time_report = 0; 42090282Sobrien 42190282Sobrien/* Print memory still in use at end of compilation (which may have little 42290282Sobrien to do with peak memory consumption). -fmem-report. */ 42390282Sobrien 42490282Sobrienint mem_report = 0; 42590282Sobrien 42690282Sobrien/* Non-zero means to collect statistics which might be expensive 42790282Sobrien and to print them when we are done. */ 42890282Sobrienint flag_detailed_statistics = 0; 42990282Sobrien 43018334Speter 43118334Speter/* -f flags. */ 43218334Speter 43318334Speter/* Nonzero means `char' should be signed. */ 43418334Speter 43518334Speterint flag_signed_char; 43618334Speter 43718334Speter/* Nonzero means give an enum type only as many bytes as it needs. */ 43818334Speter 43918334Speterint flag_short_enums; 44018334Speter 44118334Speter/* Nonzero for -fcaller-saves: allocate values in regs that need to 44218334Speter be saved across function calls, if that produces overall better code. 44318334Speter Optional now, so people can test it. */ 44418334Speter 44518334Speter#ifdef DEFAULT_CALLER_SAVES 44618334Speterint flag_caller_saves = 1; 44718334Speter#else 44818334Speterint flag_caller_saves = 0; 44918334Speter#endif 45018334Speter 45118334Speter/* Nonzero if structures and unions should be returned in memory. 45218334Speter 45318334Speter This should only be defined if compatibility with another compiler or 45418334Speter with an ABI is needed, because it results in slower code. */ 45518334Speter 45618334Speter#ifndef DEFAULT_PCC_STRUCT_RETURN 45718334Speter#define DEFAULT_PCC_STRUCT_RETURN 1 45818334Speter#endif 45918334Speter 46018334Speter/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ 46118334Speter 46218334Speterint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; 46318334Speter 46418334Speter/* Nonzero for -fforce-mem: load memory value into a register 46518334Speter before arithmetic on it. This makes better cse but slower compilation. */ 46618334Speter 46718334Speterint flag_force_mem = 0; 46818334Speter 46918334Speter/* Nonzero for -fforce-addr: load memory address into a register before 47018334Speter reference to memory. This makes better cse but slower compilation. */ 47118334Speter 47218334Speterint flag_force_addr = 0; 47318334Speter 47418334Speter/* Nonzero for -fdefer-pop: don't pop args after each function call; 47518334Speter instead save them up to pop many calls' args with one insns. */ 47618334Speter 47718334Speterint flag_defer_pop = 0; 47818334Speter 47918334Speter/* Nonzero for -ffloat-store: don't allocate floats and doubles 48018334Speter in extended-precision registers. */ 48118334Speter 48218334Speterint flag_float_store = 0; 48318334Speter 48418334Speter/* Nonzero for -fcse-follow-jumps: 48518334Speter have cse follow jumps to do a more extensive job. */ 48618334Speter 48718334Speterint flag_cse_follow_jumps; 48818334Speter 48918334Speter/* Nonzero for -fcse-skip-blocks: 49018334Speter have cse follow a branch around a block. */ 49118334Speterint flag_cse_skip_blocks; 49218334Speter 49318334Speter/* Nonzero for -fexpensive-optimizations: 49418334Speter perform miscellaneous relatively-expensive optimizations. */ 49518334Speterint flag_expensive_optimizations; 49618334Speter 49718334Speter/* Nonzero for -fthread-jumps: 49818334Speter have jump optimize output of loop. */ 49918334Speter 50018334Speterint flag_thread_jumps; 50118334Speter 50218334Speter/* Nonzero enables strength-reduction in loop.c. */ 50318334Speter 50418334Speterint flag_strength_reduce = 0; 50518334Speter 50618334Speter/* Nonzero enables loop unrolling in unroll.c. Only loops for which the 50718334Speter number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, 50818334Speter UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are 50918334Speter unrolled. */ 51018334Speter 51118334Speterint flag_unroll_loops; 51218334Speter 51318334Speter/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. 51418334Speter This is generally not a win. */ 51518334Speter 51618334Speterint flag_unroll_all_loops; 51718334Speter 51890282Sobrien/* Nonzero enables prefetch optimizations for arrays in loops. */ 51990282Sobrien 52090282Sobrienint flag_prefetch_loop_arrays; 52190282Sobrien 52250615Sobrien/* Nonzero forces all invariant computations in loops to be moved 52390282Sobrien outside the loop. */ 52450615Sobrien 52550615Sobrienint flag_move_all_movables = 0; 52650615Sobrien 52750615Sobrien/* Nonzero forces all general induction variables in loops to be 52890282Sobrien strength reduced. */ 52950615Sobrien 53050615Sobrienint flag_reduce_all_givs = 0; 53150615Sobrien 53250615Sobrien/* Nonzero to perform full register move optimization passes. This is the 53350615Sobrien default for -O2. */ 53450615Sobrien 53550615Sobrienint flag_regmove = 0; 53650615Sobrien 53718334Speter/* Nonzero for -fwritable-strings: 53818334Speter store string constants in data segment and don't uniquize them. */ 53918334Speter 54018334Speterint flag_writable_strings = 0; 54118334Speter 54218334Speter/* Nonzero means don't put addresses of constant functions in registers. 54318334Speter Used for compiling the Unix kernel, where strange substitutions are 54418334Speter done on the assembly output. */ 54518334Speter 54618334Speterint flag_no_function_cse = 0; 54718334Speter 54818334Speter/* Nonzero for -fomit-frame-pointer: 54918334Speter don't make a frame pointer in simple functions that don't require one. */ 55018334Speter 55118334Speterint flag_omit_frame_pointer = 0; 55218334Speter 55350615Sobrien/* Nonzero means place each function into its own section on those platforms 55450615Sobrien which support arbitrary section names and unlimited numbers of sections. */ 55550615Sobrien 55650615Sobrienint flag_function_sections = 0; 55750615Sobrien 55852558Sobrien/* ... and similar for data. */ 55990282Sobrien 56052558Sobrienint flag_data_sections = 0; 56152558Sobrien 56218334Speter/* Nonzero to inhibit use of define_optimization peephole opts. */ 56318334Speter 56418334Speterint flag_no_peephole = 0; 56518334Speter 56690282Sobrien/* Nonzero allows GCC to optimize sibling and tail recursive calls. */ 56718334Speter 56890282Sobrienint flag_optimize_sibling_calls = 0; 56918334Speter 57052558Sobrien/* Nonzero means the front end generally wants `errno' maintained by math 57190282Sobrien operations, like built-in SQRT. */ 57252558Sobrien 57352558Sobrienint flag_errno_math = 1; 57452558Sobrien 57590282Sobrien/* Nonzero means that unsafe floating-point math optimizations are allowed 57690282Sobrien for the sake of speed. IEEE compliance is not guaranteed, and operations 57790282Sobrien are allowed to assume that their arguments and results are "normal" 57890282Sobrien (e.g., nonnegative for SQRT). */ 57990282Sobrien 58090282Sobrienint flag_unsafe_math_optimizations = 0; 58190282Sobrien 582117414Skan/* Nonzero means that no NaNs or +-Infs are expected. */ 583117414Skan 584117414Skanint flag_finite_math_only = 0; 585117414Skan 58690282Sobrien/* Zero means that floating-point math operations cannot generate a 58790282Sobrien (user-visible) trap. This is the case, for example, in nonstop 588117414Skan IEEE 754 arithmetic. Trapping conditions include division by zero, 589117414Skan overflow, underflow, invalid and inexact, but does not include 590117414Skan operations on signaling NaNs (see below). */ 59190282Sobrien 59290282Sobrienint flag_trapping_math = 1; 59390282Sobrien 594117414Skan/* Nonzero means disable transformations observable by signaling NaNs. 595117414Skan This option implies that any operation on a IEEE signaling NaN can 596117414Skan generate a (user-visible) trap. */ 597117414Skan 598117414Skanint flag_signaling_nans = 0; 599117414Skan 60052558Sobrien/* 0 means straightforward implementation of complex divide acceptable. 60152558Sobrien 1 means wide ranges of inputs must work for complex divide. 60290282Sobrien 2 means C99-like requirements for complex divide (not yet implemented). */ 60352558Sobrien 60452558Sobrienint flag_complex_divide_method = 0; 60552558Sobrien 60618334Speter/* Nonzero means all references through pointers are volatile. */ 60718334Speter 60818334Speterint flag_volatile; 60918334Speter 61052558Sobrien/* Nonzero means treat all global and extern variables as volatile. */ 61118334Speter 61218334Speterint flag_volatile_global; 61318334Speter 61452558Sobrien/* Nonzero means treat all static variables as volatile. */ 61552558Sobrien 61652558Sobrienint flag_volatile_static; 61752558Sobrien 61818334Speter/* Nonzero means just do syntax checking; don't output anything. */ 61918334Speter 62018334Speterint flag_syntax_only = 0; 62118334Speter 62250615Sobrien/* Nonzero means perform global cse. */ 62350615Sobrien 62450615Sobrienstatic int flag_gcse; 62550615Sobrien 626117414Skan/* Nonzero means perform loop optimizer. */ 627117414Skan 628117414Skanstatic int flag_loop_optimize; 629117414Skan 630117414Skan/* Nonzero means perform crossjumping. */ 631117414Skan 632117414Skanstatic int flag_crossjumping; 633117414Skan 634117414Skan/* Nonzero means perform if conversion. */ 635117414Skan 636117414Skanstatic int flag_if_conversion; 637117414Skan 638117414Skan/* Nonzero means perform if conversion after reload. */ 639117414Skan 640117414Skanstatic int flag_if_conversion2; 641117414Skan 64290282Sobrien/* Nonzero means to use global dataflow analysis to eliminate 64390282Sobrien useless null pointer tests. */ 64490282Sobrien 64590282Sobrienstatic int flag_delete_null_pointer_checks; 64690282Sobrien 64790282Sobrien/* Nonzero means to do the enhanced load motion during gcse, which trys 64890282Sobrien to hoist loads by not killing them when a store to the same location 64990282Sobrien is seen. */ 65090282Sobrien 65190282Sobrienint flag_gcse_lm = 1; 65290282Sobrien 65390282Sobrien/* Nonzero means to perform store motion after gcse, which will try to 65490282Sobrien move stores closer to the exit block. Its not very effective without 65590282Sobrien flag_gcse_lm. */ 65690282Sobrien 65790282Sobrienint flag_gcse_sm = 1; 65890282Sobrien 65918334Speter/* Nonzero means to rerun cse after loop optimization. This increases 66018334Speter compilation time about 20% and picks up a few more common expressions. */ 66118334Speter 66218334Speterstatic int flag_rerun_cse_after_loop; 66318334Speter 66450615Sobrien/* Nonzero means to run loop optimizations twice. */ 66550615Sobrien 66650615Sobrienint flag_rerun_loop_opt; 66750615Sobrien 66818334Speter/* Nonzero for -finline-functions: ok to inline functions that look like 66918334Speter good inline candidates. */ 67018334Speter 67118334Speterint flag_inline_functions; 67218334Speter 67318334Speter/* Nonzero for -fkeep-inline-functions: even if we make a function 67418334Speter go inline everywhere, keep its definition around for debugging 67518334Speter purposes. */ 67618334Speter 67718334Speterint flag_keep_inline_functions; 67818334Speter 67918334Speter/* Nonzero means that functions will not be inlined. */ 68018334Speter 68196289Sobrienint flag_no_inline = 2; 68218334Speter 68396289Sobrien/* Nonzero means that we don't want inlining by virtue of -fno-inline, 68496289Sobrien not just because the tree inliner turned us off. */ 68596289Sobrien 68696289Sobrienint flag_really_no_inline = 2; 68796289Sobrien 68850615Sobrien/* Nonzero means that we should emit static const variables 68950615Sobrien regardless of whether or not optimization is turned on. */ 69050615Sobrien 69150615Sobrienint flag_keep_static_consts = 1; 69250615Sobrien 69318334Speter/* Nonzero means we should be saving declaration info into a .X file. */ 69418334Speter 69518334Speterint flag_gen_aux_info = 0; 69618334Speter 69718334Speter/* Specified name of aux-info file. */ 69818334Speter 69918334Speterstatic char *aux_info_file_name; 70018334Speter 70118334Speter/* Nonzero means make the text shared if supported. */ 70218334Speter 70318334Speterint flag_shared_data; 70418334Speter 70518334Speter/* Nonzero means schedule into delayed branch slots if supported. */ 70618334Speter 70718334Speterint flag_delayed_branch; 70818334Speter 70918334Speter/* Nonzero if we are compiling pure (sharable) code. 710117414Skan Value is 1 if we are doing "small" pic; value is 2 if we're doing 711117414Skan "large" pic. */ 71218334Speter 71318334Speterint flag_pic; 71418334Speter 715117414Skan/* Set to the default thread-local storage (tls) model to use. */ 716117414Skan 717117414Skanenum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC; 718117414Skan 71950615Sobrien/* Nonzero means generate extra code for exception handling and enable 72050615Sobrien exception handling. */ 72118334Speter 72250615Sobrienint flag_exceptions; 72350615Sobrien 72490282Sobrien/* Nonzero means generate frame unwind info table when supported. */ 72550615Sobrien 72690282Sobrienint flag_unwind_tables = 0; 72750615Sobrien 72890282Sobrien/* Nonzero means generate frame unwind info table exact at each insn boundary */ 72990282Sobrien 73090282Sobrienint flag_asynchronous_unwind_tables = 0; 73190282Sobrien 73250615Sobrien/* Nonzero means don't place uninitialized global data in common storage 73350615Sobrien by default. */ 73450615Sobrien 73518334Speterint flag_no_common; 73618334Speter 73718334Speter/* Nonzero means change certain warnings into errors. 73818334Speter Usually these are warnings about failure to conform to some standard. */ 73918334Speter 74018334Speterint flag_pedantic_errors = 0; 74118334Speter 74218334Speter/* flag_schedule_insns means schedule insns within basic blocks (before 74318334Speter local_alloc). 74418334Speter flag_schedule_insns_after_reload means schedule insns after 74518334Speter global_alloc. */ 74618334Speter 74718334Speterint flag_schedule_insns = 0; 74818334Speterint flag_schedule_insns_after_reload = 0; 74918334Speter 75050615Sobrien/* The following flags have effect only for scheduling before register 75150615Sobrien allocation: 75250615Sobrien 75350615Sobrien flag_schedule_interblock means schedule insns accross basic blocks. 75450615Sobrien flag_schedule_speculative means allow speculative motion of non-load insns. 75550615Sobrien flag_schedule_speculative_load means allow speculative motion of some 75650615Sobrien load insns. 75750615Sobrien flag_schedule_speculative_load_dangerous allows speculative motion of more 75850615Sobrien load insns. */ 75950615Sobrien 76050615Sobrienint flag_schedule_interblock = 1; 76150615Sobrienint flag_schedule_speculative = 1; 76250615Sobrienint flag_schedule_speculative_load = 0; 76350615Sobrienint flag_schedule_speculative_load_dangerous = 0; 76450615Sobrien 76590282Sobrienint flag_single_precision_constant; 76650615Sobrien 76790282Sobrien/* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple 76890282Sobrien by a cheaper branch on a count register. */ 76990282Sobrienint flag_branch_on_count_reg = 1; 77090282Sobrien 77118334Speter/* -finhibit-size-directive inhibits output of .size for ELF. 77290282Sobrien This is used only for compiling crtstuff.c, 77318334Speter and it may be extended to other effects 77418334Speter needed for crtstuff.c on other systems. */ 77518334Speterint flag_inhibit_size_directive = 0; 77618334Speter 77718334Speter/* -fverbose-asm causes extra commentary information to be produced in 77818334Speter the generated assembly code (to make it more readable). This option 77918334Speter is generally only of use to those who actually need to read the 78050615Sobrien generated assembly code (perhaps while debugging the compiler itself). 78150615Sobrien -fno-verbose-asm, the default, causes the extra information 78250615Sobrien to be omitted and is useful when comparing two assembler files. */ 78318334Speter 78418334Speterint flag_verbose_asm = 0; 78518334Speter 78650615Sobrien/* -dA causes debug commentary information to be produced in 78750615Sobrien the generated assembly code (to make it more readable). This option 78850615Sobrien is generally only of use to those who actually need to read the 78950615Sobrien generated assembly code (perhaps while debugging the compiler itself). 79050615Sobrien Currently, this switch is only used by dwarfout.c; however, it is intended 79150615Sobrien to be a catchall for printing debug information in the assembler file. */ 79250615Sobrien 79350615Sobrienint flag_debug_asm = 0; 79450615Sobrien 79590282Sobrien/* -dP causes the rtl to be emitted as a comment in assembly. */ 79690282Sobrien 79790282Sobrienint flag_dump_rtl_in_asm = 0; 79890282Sobrien 79918334Speter/* -fgnu-linker specifies use of the GNU linker for initializations. 80018334Speter (Or, more generally, a linker that handles initializations.) 80118334Speter -fno-gnu-linker says that collect2 will be used. */ 80218334Speter#ifdef USE_COLLECT2 80318334Speterint flag_gnu_linker = 0; 80418334Speter#else 80518334Speterint flag_gnu_linker = 1; 80618334Speter#endif 80718334Speter 808117414Skan/* Nonzero means put zero initialized data in the bss section. */ 809117414Skanint flag_zero_initialized_in_bss = 1; 810117414Skan 81190282Sobrien/* Enable SSA. */ 81290282Sobrienint flag_ssa = 0; 81390282Sobrien 81490282Sobrien/* Enable ssa conditional constant propagation. */ 81590282Sobrienint flag_ssa_ccp = 0; 81690282Sobrien 81790282Sobrien/* Enable ssa aggressive dead code elimination. */ 81890282Sobrienint flag_ssa_dce = 0; 81990282Sobrien 82090282Sobrien/* Tag all structures with __attribute__(packed). */ 82118334Speterint flag_pack_struct = 0; 82218334Speter 82338510Sbde/* Nonzero means that -Wformat accepts certain system-dependent formats. */ 82438510Sbdeint flag_format_extensions = 0; 82538510Sbde 82650615Sobrien/* Emit code to check for stack overflow; also may cause large objects 82750615Sobrien to be allocated dynamically. */ 82850615Sobrienint flag_stack_check; 82950615Sobrien 83090282Sobrien/* When non-NULL, indicates that whenever space is allocated on the 83190282Sobrien stack, the resulting stack pointer must not pass this 83290282Sobrien address---that is, for stacks that grow downward, the stack pointer 83390282Sobrien must always be greater than or equal to this address; for stacks 83490282Sobrien that grow upward, the stack pointer must be less than this address. 83590282Sobrien At present, the rtx may be either a REG or a SYMBOL_REF, although 83690282Sobrien the support provided depends on the backend. */ 83790282Sobrienrtx stack_limit_rtx; 83850615Sobrien 83950615Sobrien/* 0 if pointer arguments may alias each other. True in C. 84050615Sobrien 1 if pointer arguments may not alias each other but may alias 84150615Sobrien global variables. 84250615Sobrien 2 if pointer arguments may not alias each other and may not 84350615Sobrien alias global variables. True in Fortran. 84450615Sobrien This defaults to 0 for C. */ 84550615Sobrienint flag_argument_noalias = 0; 84650615Sobrien 84750615Sobrien/* Nonzero if we should do (language-dependent) alias analysis. 84850615Sobrien Typically, this analysis will assume that expressions of certain 84950615Sobrien types do not alias expressions of certain other types. Only used 85050615Sobrien if alias analysis (in general) is enabled. */ 85150615Sobrienint flag_strict_aliasing = 0; 85250615Sobrien 85352558Sobrien/* Instrument functions with calls at entry and exit, for profiling. */ 85452558Sobrienint flag_instrument_function_entry_exit = 0; 85550615Sobrien 85652558Sobrien/* Nonzero means ignore `#ident' directives. 0 means handle them. 85752558Sobrien On SVR4 targets, it also controls whether or not to emit a 85852558Sobrien string identifying the compiler. */ 85950615Sobrien 86052558Sobrienint flag_no_ident = 0; 86152558Sobrien 86290282Sobrien/* This will perform a peephole pass before sched2. */ 86390282Sobrienint flag_peephole2 = 0; 86490282Sobrien 86590282Sobrien/* This will try to guess branch probabilities. */ 86690282Sobrienint flag_guess_branch_prob = 0; 86790282Sobrien 86890282Sobrien/* -fcheck-bounds causes gcc to generate array bounds checks. 869117414Skan For C, C++, ObjC: defaults to off. 87090282Sobrien For Java: defaults to on. 871117414Skan For Fortran: defaults to off. */ 87290282Sobrienint flag_bounds_check = 0; 87390282Sobrien 87490282Sobrien/* This will attempt to merge constant section constants, if 1 only 87590282Sobrien string constants and constants from constant pool, if 2 also constant 87690282Sobrien variables. */ 87790282Sobrienint flag_merge_constants = 1; 87890282Sobrien 87990282Sobrien/* If one, renumber instruction UIDs to reduce the number of 88090282Sobrien unused UIDs if there are a lot of instructions. If greater than 88190282Sobrien one, unconditionally renumber instruction UIDs. */ 88290282Sobrienint flag_renumber_insns = 1; 88390282Sobrien 884117414Skan/* If nonzero, use the graph coloring register allocator. */ 885117414Skanint flag_new_regalloc = 0; 886117414Skan 887117414Skan/* Nonzero if we perform superblock formation. */ 888117414Skan 889117414Skanint flag_tracer = 0; 890117414Skan 89190282Sobrien/* Values of the -falign-* flags: how much to align labels in code. 89290282Sobrien 0 means `use default', 1 means `don't align'. 89390282Sobrien For each variable, there is an _log variant which is the power 89490282Sobrien of two not less than the variable, for .align output. */ 89590282Sobrien 89690282Sobrienint align_loops; 89790282Sobrienint align_loops_log; 89890282Sobrienint align_loops_max_skip; 89990282Sobrienint align_jumps; 90090282Sobrienint align_jumps_log; 90190282Sobrienint align_jumps_max_skip; 90290282Sobrienint align_labels; 90390282Sobrienint align_labels_log; 90490282Sobrienint align_labels_max_skip; 90590282Sobrienint align_functions; 90690282Sobrienint align_functions_log; 90790282Sobrien 908104765Skan/* Like align_functions_log above, but used by front-ends to force the 909104765Skan minimum function alignment. Zero means no alignment is forced. */ 910104765Skanint force_align_functions_log; 911104765Skan 91250615Sobrien/* Table of supported debugging formats. */ 91390282Sobrienstatic const struct 91450615Sobrien{ 91590282Sobrien const char *const arg; 91650615Sobrien /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a 91750615Sobrien constant expression, we use NO_DEBUG in its place. */ 91890282Sobrien const enum debug_info_type debug_type; 91990282Sobrien const int use_extensions_p; 92090282Sobrien const char *const description; 92150615Sobrien} *da, 92250615Sobriendebug_args[] = 92350615Sobrien{ 92490282Sobrien { "", NO_DEBUG, DEFAULT_GDB_EXTENSIONS, 92590282Sobrien N_("Generate debugging info in default format") }, 92690282Sobrien { "gdb", NO_DEBUG, 1, N_("Generate debugging info in default extended format") }, 92750615Sobrien#ifdef DBX_DEBUGGING_INFO 92890282Sobrien { "stabs", DBX_DEBUG, 0, N_("Generate STABS format debug info") }, 92990282Sobrien { "stabs+", DBX_DEBUG, 1, N_("Generate extended STABS format debug info") }, 93050615Sobrien#endif 93150615Sobrien#ifdef DWARF_DEBUGGING_INFO 93290282Sobrien { "dwarf", DWARF_DEBUG, 0, N_("Generate DWARF-1 format debug info") }, 93390282Sobrien { "dwarf+", DWARF_DEBUG, 1, 93490282Sobrien N_("Generate extended DWARF-1 format debug info") }, 93550615Sobrien#endif 93650615Sobrien#ifdef DWARF2_DEBUGGING_INFO 93790282Sobrien { "dwarf-2", DWARF2_DEBUG, 0, N_("Generate DWARF-2 debug info") }, 93850615Sobrien#endif 93950615Sobrien#ifdef XCOFF_DEBUGGING_INFO 94090282Sobrien { "xcoff", XCOFF_DEBUG, 0, N_("Generate XCOFF format debug info") }, 94190282Sobrien { "xcoff+", XCOFF_DEBUG, 1, N_("Generate extended XCOFF format debug info") }, 94250615Sobrien#endif 94350615Sobrien#ifdef SDB_DEBUGGING_INFO 94490282Sobrien { "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") }, 94550615Sobrien#endif 94696289Sobrien#ifdef VMS_DEBUGGING_INFO 94796289Sobrien { "vms", VMS_DEBUG, 0, N_("Generate VMS format debug info") }, 94896289Sobrien#endif 94952558Sobrien { 0, 0, 0, 0 } 95050615Sobrien}; 95150615Sobrien 95250615Sobrientypedef struct 95350615Sobrien{ 95490282Sobrien const char *const string; 95590282Sobrien int *const variable; 95690282Sobrien const int on_value; 95790282Sobrien const char *const description; 95850615Sobrien} 95950615Sobrienlang_independent_options; 96050615Sobrien 96190282Sobrienint flag_trapv = 0; 96290282Sobrien 96352558Sobrien/* Add or remove a leading underscore from user symbols. */ 96452558Sobrienint flag_leading_underscore = -1; 96552558Sobrien 96652558Sobrien/* The user symbol prefix after having resolved same. */ 96752558Sobrienconst char *user_label_prefix; 96852558Sobrien 96990282Sobrienstatic const param_info lang_independent_params[] = { 97090282Sobrien#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT) \ 97190282Sobrien { OPTION, DEFAULT, HELP }, 97290282Sobrien#include "params.def" 97390282Sobrien#undef DEFPARAM 97490282Sobrien { NULL, 0, NULL } 97590282Sobrien}; 97690282Sobrien 97718334Speter/* Table of language-independent -f options. 97818334Speter STRING is the option name. VARIABLE is the address of the variable. 97918334Speter ON_VALUE is the value to store in VARIABLE 98018334Speter if `-fSTRING' is seen as an option. 98118334Speter (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ 98218334Speter 98390282Sobrienstatic const lang_independent_options f_options[] = 98418334Speter{ 98590282Sobrien {"format-extensions", &flag_format_extensions, 1, 98690282Sobrien N_("-Wformat accepts certain FreeBSD system-dependent formats") }, 98790282Sobrien {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1, 98890282Sobrien N_("Perform DWARF2 duplicate elimination") }, 98950615Sobrien {"float-store", &flag_float_store, 1, 99090282Sobrien N_("Do not store floats in registers") }, 99150615Sobrien {"volatile", &flag_volatile, 1, 99290282Sobrien N_("Consider all mem refs through pointers as volatile") }, 99350615Sobrien {"volatile-global", &flag_volatile_global, 1, 99490282Sobrien N_("Consider all mem refs to global data to be volatile") }, 99552558Sobrien {"volatile-static", &flag_volatile_static, 1, 99690282Sobrien N_("Consider all mem refs to static data to be volatile") }, 99750615Sobrien {"defer-pop", &flag_defer_pop, 1, 99890282Sobrien N_("Defer popping functions args from stack until later") }, 99950615Sobrien {"omit-frame-pointer", &flag_omit_frame_pointer, 1, 100090282Sobrien N_("When possible do not generate stack frames") }, 100190282Sobrien {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1, 100290282Sobrien N_("Optimize sibling and tail recursive calls") }, 1003117414Skan {"tracer", &flag_tracer, 1, 1004117414Skan N_("Perform superblock formation via tail duplication") }, 100550615Sobrien {"cse-follow-jumps", &flag_cse_follow_jumps, 1, 100690282Sobrien N_("When running CSE, follow jumps to their targets") }, 100750615Sobrien {"cse-skip-blocks", &flag_cse_skip_blocks, 1, 100890282Sobrien N_("When running CSE, follow conditional jumps") }, 100950615Sobrien {"expensive-optimizations", &flag_expensive_optimizations, 1, 101090282Sobrien N_("Perform a number of minor, expensive optimizations") }, 101150615Sobrien {"thread-jumps", &flag_thread_jumps, 1, 101290282Sobrien N_("Perform jump threading optimizations") }, 101350615Sobrien {"strength-reduce", &flag_strength_reduce, 1, 101490282Sobrien N_("Perform strength reduction optimizations") }, 101550615Sobrien {"unroll-loops", &flag_unroll_loops, 1, 101690282Sobrien N_("Perform loop unrolling when iteration count is known") }, 101750615Sobrien {"unroll-all-loops", &flag_unroll_all_loops, 1, 101890282Sobrien N_("Perform loop unrolling for all loops") }, 101990282Sobrien {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1, 102090282Sobrien N_("Generate prefetch instructions, if available, for arrays in loops") }, 102150615Sobrien {"move-all-movables", &flag_move_all_movables, 1, 102290282Sobrien N_("Force all loop invariant computations out of loops") }, 102350615Sobrien {"reduce-all-givs", &flag_reduce_all_givs, 1, 102490282Sobrien N_("Strength reduce all loop general induction variables") }, 102550615Sobrien {"writable-strings", &flag_writable_strings, 1, 102690282Sobrien N_("Store strings in writable data section") }, 102750615Sobrien {"peephole", &flag_no_peephole, 0, 102890282Sobrien N_("Enable machine specific peephole optimizations") }, 102950615Sobrien {"force-mem", &flag_force_mem, 1, 103090282Sobrien N_("Copy memory operands into registers before using") }, 103150615Sobrien {"force-addr", &flag_force_addr, 1, 103290282Sobrien N_("Copy memory address constants into regs before using") }, 103350615Sobrien {"function-cse", &flag_no_function_cse, 0, 103490282Sobrien N_("Allow function addresses to be held in registers") }, 103550615Sobrien {"inline-functions", &flag_inline_functions, 1, 103690282Sobrien N_("Integrate simple functions into their callers") }, 103750615Sobrien {"keep-inline-functions", &flag_keep_inline_functions, 1, 103890282Sobrien N_("Generate code for funcs even if they are fully inlined") }, 103950615Sobrien {"inline", &flag_no_inline, 0, 104090282Sobrien N_("Pay attention to the 'inline' keyword") }, 104150615Sobrien {"keep-static-consts", &flag_keep_static_consts, 1, 104290282Sobrien N_("Emit static const variables even if they are not used") }, 104350615Sobrien {"syntax-only", &flag_syntax_only, 1, 104490282Sobrien N_("Check for syntax errors, then stop") }, 104550615Sobrien {"shared-data", &flag_shared_data, 1, 104690282Sobrien N_("Mark data as shared rather than private") }, 104750615Sobrien {"caller-saves", &flag_caller_saves, 1, 104890282Sobrien N_("Enable saving registers around function calls") }, 104950615Sobrien {"pcc-struct-return", &flag_pcc_struct_return, 1, 105090282Sobrien N_("Return 'short' aggregates in memory, not registers") }, 105150615Sobrien {"reg-struct-return", &flag_pcc_struct_return, 0, 105290282Sobrien N_("Return 'short' aggregates in registers") }, 105350615Sobrien {"delayed-branch", &flag_delayed_branch, 1, 105490282Sobrien N_("Attempt to fill delay slots of branch instructions") }, 105550615Sobrien {"gcse", &flag_gcse, 1, 105690282Sobrien N_("Perform the global common subexpression elimination") }, 105790282Sobrien {"gcse-lm", &flag_gcse_lm, 1, 105890282Sobrien N_("Perform enhanced load motion during global subexpression elimination") }, 105990282Sobrien {"gcse-sm", &flag_gcse_sm, 1, 106090282Sobrien N_("Perform store motion after global subexpression elimination") }, 1061117414Skan {"loop-optimize", &flag_loop_optimize, 1, 1062117414Skan N_("Perform the loop optimizations") }, 1063117414Skan {"crossjumping", &flag_crossjumping, 1, 1064117414Skan N_("Perform cross-jumping optimization") }, 1065117414Skan {"if-conversion", &flag_if_conversion, 1, 1066117414Skan N_("Perform conversion of conditional jumps to branchless equivalents") }, 1067117414Skan {"if-conversion2", &flag_if_conversion2, 1, 1068117414Skan N_("Perform conversion of conditional jumps to conditional execution") }, 106950615Sobrien {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1, 107090282Sobrien N_("Run CSE pass after loop optimizations") }, 107150615Sobrien {"rerun-loop-opt", &flag_rerun_loop_opt, 1, 107290282Sobrien N_("Run the loop optimizer twice") }, 107390282Sobrien {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1, 107490282Sobrien N_("Delete useless null pointer checks") }, 107550615Sobrien {"schedule-insns", &flag_schedule_insns, 1, 107690282Sobrien N_("Reschedule instructions before register allocation") }, 107750615Sobrien {"schedule-insns2", &flag_schedule_insns_after_reload, 1, 107890282Sobrien N_("Reschedule instructions after register allocation") }, 107950615Sobrien {"sched-interblock",&flag_schedule_interblock, 1, 108090282Sobrien N_("Enable scheduling across basic blocks") }, 108150615Sobrien {"sched-spec",&flag_schedule_speculative, 1, 108290282Sobrien N_("Allow speculative motion of non-loads") }, 108350615Sobrien {"sched-spec-load",&flag_schedule_speculative_load, 1, 108490282Sobrien N_("Allow speculative motion of some loads") }, 108550615Sobrien {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1, 108690282Sobrien N_("Allow speculative motion of more loads") }, 108750615Sobrien {"branch-count-reg",&flag_branch_on_count_reg, 1, 108890282Sobrien N_("Replace add,compare,branch with branch on count reg") }, 108950615Sobrien {"pic", &flag_pic, 1, 109090282Sobrien N_("Generate position independent code, if possible") }, 109150615Sobrien {"PIC", &flag_pic, 2, ""}, 109250615Sobrien {"exceptions", &flag_exceptions, 1, 109390282Sobrien N_("Enable exception handling") }, 109490282Sobrien {"unwind-tables", &flag_unwind_tables, 1, 109590282Sobrien N_("Just generate unwind tables for exception handling") }, 109690282Sobrien {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1, 109790282Sobrien N_("Generate unwind tables exact at each instruction boundary") }, 109890282Sobrien {"non-call-exceptions", &flag_non_call_exceptions, 1, 109990282Sobrien N_("Support synchronous non-call exceptions") }, 110050615Sobrien {"profile-arcs", &profile_arc_flag, 1, 110190282Sobrien N_("Insert arc based program profiling code") }, 110250615Sobrien {"test-coverage", &flag_test_coverage, 1, 110390282Sobrien N_("Create data files needed by gcov") }, 110450615Sobrien {"branch-probabilities", &flag_branch_probabilities, 1, 110590282Sobrien N_("Use profiling information for branch probabilities") }, 1106117414Skan {"profile", &profile_flag, 1, 1107117414Skan N_("Enable basic program profiling code") }, 110890282Sobrien {"reorder-blocks", &flag_reorder_blocks, 1, 110990282Sobrien N_("Reorder basic blocks to improve code placement") }, 1110117414Skan {"reorder-functions", &flag_reorder_functions, 1, 1111117414Skan N_("Reorder functions to improve code placement") }, 111290282Sobrien {"rename-registers", &flag_rename_registers, 1, 111390282Sobrien N_("Do the register renaming optimization pass") }, 111490282Sobrien {"cprop-registers", &flag_cprop_registers, 1, 111590282Sobrien N_("Do the register copy-propagation optimization pass") }, 111650615Sobrien {"common", &flag_no_common, 0, 111790282Sobrien N_("Do not put uninitialized globals in the common section") }, 111850615Sobrien {"inhibit-size-directive", &flag_inhibit_size_directive, 1, 111990282Sobrien N_("Do not generate .size directives") }, 112050615Sobrien {"function-sections", &flag_function_sections, 1, 112190282Sobrien N_("place each function into its own section") }, 112252558Sobrien {"data-sections", &flag_data_sections, 1, 112390282Sobrien N_("place data items into their own section") }, 112450615Sobrien {"verbose-asm", &flag_verbose_asm, 1, 1125117414Skan N_("Add extra commentary to assembler output") }, 112650615Sobrien {"gnu-linker", &flag_gnu_linker, 1, 112790282Sobrien N_("Output GNU ld formatted global initializers") }, 112850615Sobrien {"regmove", &flag_regmove, 1, 112990282Sobrien N_("Enables a register move optimization") }, 113052558Sobrien {"optimize-register-move", &flag_regmove, 1, 113190282Sobrien N_("Do the full regmove optimization pass") }, 113250615Sobrien {"pack-struct", &flag_pack_struct, 1, 113390282Sobrien N_("Pack structure members together without holes") }, 113450615Sobrien {"stack-check", &flag_stack_check, 1, 113590282Sobrien N_("Insert stack checking code into the program") }, 113650615Sobrien {"argument-alias", &flag_argument_noalias, 0, 113790282Sobrien N_("Specify that arguments may alias each other & globals") }, 113850615Sobrien {"argument-noalias", &flag_argument_noalias, 1, 113990282Sobrien N_("Assume arguments may alias globals but not each other") }, 114050615Sobrien {"argument-noalias-global", &flag_argument_noalias, 2, 114190282Sobrien N_("Assume arguments do not alias each other or globals") }, 114250615Sobrien {"strict-aliasing", &flag_strict_aliasing, 1, 114390282Sobrien N_("Assume strict aliasing rules apply") }, 114490282Sobrien {"align-loops", &align_loops, 0, 114590282Sobrien N_("Align the start of loops") }, 114690282Sobrien {"align-jumps", &align_jumps, 0, 114790282Sobrien N_("Align labels which are only reached by jumping") }, 114890282Sobrien {"align-labels", &align_labels, 0, 114990282Sobrien N_("Align all labels") }, 115090282Sobrien {"align-functions", &align_functions, 0, 115190282Sobrien N_("Align the start of functions") }, 115290282Sobrien {"merge-constants", &flag_merge_constants, 1, 1153117414Skan N_("Attempt to merge identical constants across compilation units") }, 115490282Sobrien {"merge-all-constants", &flag_merge_constants, 2, 115590282Sobrien N_("Attempt to merge identical constants and constant variables") }, 115652558Sobrien {"dump-unnumbered", &flag_dump_unnumbered, 1, 115790282Sobrien N_("Suppress output of instruction numbers and line number notes in debugging dumps") }, 115852558Sobrien {"instrument-functions", &flag_instrument_function_entry_exit, 1, 115990282Sobrien N_("Instrument function entry/exit with profiling calls") }, 1160117414Skan {"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1, 1161117414Skan N_("Put zero initialized data in the bss section") }, 116290282Sobrien {"ssa", &flag_ssa, 1, 116390282Sobrien N_("Enable SSA optimizations") }, 116490282Sobrien {"ssa-ccp", &flag_ssa_ccp, 1, 116590282Sobrien N_("Enable SSA conditional constant propagation") }, 116690282Sobrien {"ssa-dce", &flag_ssa_dce, 1, 116790282Sobrien N_("Enable aggressive SSA dead code elimination") }, 116852558Sobrien {"leading-underscore", &flag_leading_underscore, 1, 116990282Sobrien N_("External symbols have a leading underscore") }, 117052558Sobrien {"ident", &flag_no_ident, 0, 117190282Sobrien N_("Process #ident directives") }, 117290282Sobrien { "peephole2", &flag_peephole2, 1, 117390282Sobrien N_("Enables an rtl peephole pass run before sched2") }, 1174117414Skan {"finite-math-only", &flag_finite_math_only, 1, 1175117414Skan N_("Assume no NaNs or +-Infs are generated") }, 117690282Sobrien { "guess-branch-probability", &flag_guess_branch_prob, 1, 117790282Sobrien N_("Enables guessing of branch probabilities") }, 117890282Sobrien {"math-errno", &flag_errno_math, 1, 117990282Sobrien N_("Set errno after built-in math functions") }, 118090282Sobrien {"trapping-math", &flag_trapping_math, 1, 118190282Sobrien N_("Floating-point operations can trap") }, 118290282Sobrien {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1, 118390282Sobrien N_("Allow math optimizations that may violate IEEE or ANSI standards") }, 1184117414Skan {"signaling-nans", &flag_signaling_nans, 1, 1185117414Skan N_("Disable optimizations observable by IEEE signaling NaNs") }, 118690282Sobrien {"bounds-check", &flag_bounds_check, 1, 1187117414Skan N_("Generate code to check bounds before indexing arrays") }, 118890282Sobrien {"single-precision-constant", &flag_single_precision_constant, 1, 118990282Sobrien N_("Convert floating point constant to single precision constant") }, 119090282Sobrien {"time-report", &time_report, 1, 119190282Sobrien N_("Report time taken by each compiler pass at end of run") }, 119290282Sobrien {"mem-report", &mem_report, 1, 119390282Sobrien N_("Report on permanent memory allocation at end of run") }, 119490282Sobrien { "trapv", &flag_trapv, 1, 119590282Sobrien N_("Trap for signed overflow in addition / subtraction / multiplication") }, 1196117414Skan { "new-ra", &flag_new_regalloc, 1, 1197117414Skan N_("Use graph coloring register allocation.") }, 119818334Speter}; 119918334Speter 120018334Speter/* Table of language-specific options. */ 120118334Speter 120290282Sobrienstatic const struct lang_opt 120318334Speter{ 120490282Sobrien const char *const option; 120590282Sobrien const char *const description; 120650615Sobrien} 120750615Sobriendocumented_lang_options[] = 120850615Sobrien{ 120950615Sobrien /* In order not to overload the --help output, the convention 121050615Sobrien used here is to only describe those options which are not 121150615Sobrien enabled by default. */ 121218334Speter 1213117414Skan { "-ansi", 1214117414Skan N_("Compile just for ISO C90") }, 1215117414Skan { "-std= ", 121690282Sobrien N_("Determine language standard") }, 121718334Speter 121850615Sobrien { "-fsigned-bitfields", "" }, 121990282Sobrien { "-funsigned-bitfields", 122090282Sobrien N_("Make bit-fields by unsigned by default") }, 122150615Sobrien { "-fno-signed-bitfields", "" }, 122250615Sobrien { "-fno-unsigned-bitfields","" }, 1223117414Skan { "-fsigned-char", 122490282Sobrien N_("Make 'char' be signed by default") }, 1225117414Skan { "-funsigned-char", 122690282Sobrien N_("Make 'char' be unsigned by default") }, 122750615Sobrien { "-fno-signed-char", "" }, 122850615Sobrien { "-fno-unsigned-char", "" }, 122918334Speter 123050615Sobrien { "-fasm", "" }, 1231117414Skan { "-fno-asm", 123290282Sobrien N_("Do not recognize the 'asm' keyword") }, 123350615Sobrien { "-fbuiltin", "" }, 1234117414Skan { "-fno-builtin", 123590282Sobrien N_("Do not recognize any built in functions") }, 1236117414Skan { "-fhosted", 123790282Sobrien N_("Assume normal C execution environment") }, 123850615Sobrien { "-fno-hosted", "" }, 123950615Sobrien { "-ffreestanding", 124090282Sobrien N_("Assume that standard libraries & main might not exist") }, 124150615Sobrien { "-fno-freestanding", "" }, 1242117414Skan { "-fcond-mismatch", 124390282Sobrien N_("Allow different types as args of ? operator") }, 124450615Sobrien { "-fno-cond-mismatch", "" }, 1245117414Skan { "-fdollars-in-identifiers", 124690282Sobrien N_("Allow the use of $ inside identifiers") }, 124750615Sobrien { "-fno-dollars-in-identifiers", "" }, 124890282Sobrien { "-fpreprocessed", "" }, 124990282Sobrien { "-fno-preprocessed", "" }, 1250117414Skan { "-fshort-double", 125190282Sobrien N_("Use the same size for double as for float") }, 125250615Sobrien { "-fno-short-double", "" }, 1253117414Skan { "-fshort-enums", 125490282Sobrien N_("Use the smallest fitting integer to hold enums") }, 125550615Sobrien { "-fno-short-enums", "" }, 1256117414Skan { "-fshort-wchar", 125790282Sobrien N_("Override the underlying type for wchar_t to `unsigned short'") }, 125890282Sobrien { "-fno-short-wchar", "" }, 125918334Speter 1260117414Skan { "-Wall", 126190282Sobrien N_("Enable most warning messages") }, 126250615Sobrien { "-Wbad-function-cast", 126390282Sobrien N_("Warn about casting functions to incompatible types") }, 126450615Sobrien { "-Wno-bad-function-cast", "" }, 126590282Sobrien { "-Wmissing-format-attribute", 126690282Sobrien N_("Warn about functions which might be candidates for format attributes") }, 126790282Sobrien { "-Wno-missing-format-attribute", "" }, 1268117414Skan { "-Wcast-qual", 126990282Sobrien N_("Warn about casts which discard qualifiers") }, 127050615Sobrien { "-Wno-cast-qual", "" }, 1271117414Skan { "-Wchar-subscripts", 127290282Sobrien N_("Warn about subscripts whose type is 'char'") }, 127350615Sobrien { "-Wno-char-subscripts", "" }, 1274117414Skan { "-Wcomment", 127590282Sobrien N_("Warn if nested comments are detected") }, 127652558Sobrien { "-Wno-comment", "" }, 1277117414Skan { "-Wcomments", 127890282Sobrien N_("Warn if nested comments are detected") }, 127952558Sobrien { "-Wno-comments", "" }, 1280117414Skan { "-Wconversion", 128190282Sobrien N_("Warn about possibly confusing type conversions") }, 128250615Sobrien { "-Wno-conversion", "" }, 1283117414Skan { "-Wdiv-by-zero", "" }, 1284117414Skan { "-Wno-div-by-zero", 1285117414Skan N_("Do not warn about compile-time integer division by zero") }, 1286117414Skan { "-Wfloat-equal", 1287117414Skan N_("Warn about testing equality of floating point numbers") }, 1288117414Skan { "-Wno-float-equal", "" }, 1289117414Skan { "-Wformat", 129090282Sobrien N_("Warn about printf/scanf/strftime/strfmon format anomalies") }, 129150615Sobrien { "-Wno-format", "" }, 129290282Sobrien { "-Wformat-extra-args", "" }, 129390282Sobrien { "-Wno-format-extra-args", 129490282Sobrien N_("Don't warn about too many arguments to format functions") }, 1295117414Skan { "-Wformat-nonliteral", 129690282Sobrien N_("Warn about non-string-literal format strings") }, 129790282Sobrien { "-Wno-format-nonliteral", "" }, 129890282Sobrien { "-Wformat-security", 129990282Sobrien N_("Warn about possible security problems with format functions") }, 130090282Sobrien { "-Wno-format-security", "" }, 1301117414Skan { "-Wformat-y2k", "" }, 1302117414Skan { "-Wno-format-y2k", 1303117414Skan N_("Don't warn about strftime formats yielding 2 digit years") }, 130450615Sobrien { "-Wimplicit-function-declaration", 130590282Sobrien N_("Warn about implicit function declarations") }, 130650615Sobrien { "-Wno-implicit-function-declaration", "" }, 130750615Sobrien { "-Werror-implicit-function-declaration", "" }, 1308117414Skan { "-Wimplicit-int", 130990282Sobrien N_("Warn when a declaration does not specify a type") }, 131050615Sobrien { "-Wno-implicit-int", "" }, 131150615Sobrien { "-Wimplicit", "" }, 131250615Sobrien { "-Wno-implicit", "" }, 1313117414Skan { "-Wimport", 131490282Sobrien N_("Warn about the use of the #import directive") }, 131550615Sobrien { "-Wno-import", "" }, 131650615Sobrien { "-Wlong-long","" }, 1317117414Skan { "-Wno-long-long", 131890282Sobrien N_("Do not warn about using 'long long' when -pedantic") }, 1319117414Skan { "-Wmain", 132090282Sobrien N_("Warn about suspicious declarations of main") }, 132150615Sobrien { "-Wno-main", "" }, 132250615Sobrien { "-Wmissing-braces", 132390282Sobrien N_("Warn about possibly missing braces around initializers") }, 132450615Sobrien { "-Wno-missing-braces", "" }, 132550615Sobrien { "-Wmissing-declarations", 132690282Sobrien N_("Warn about global funcs without previous declarations") }, 132750615Sobrien { "-Wno-missing-declarations", "" }, 1328117414Skan { "-Wmissing-prototypes", 132990282Sobrien N_("Warn about global funcs without prototypes") }, 133050615Sobrien { "-Wno-missing-prototypes", "" }, 1331117414Skan { "-Wmultichar", 133290282Sobrien N_("Warn about use of multicharacter literals") }, 133350615Sobrien { "-Wno-multichar", "" }, 1334117414Skan { "-Wnested-externs", 133590282Sobrien N_("Warn about externs not at file scope level") }, 133650615Sobrien { "-Wno-nested-externs", "" }, 1337117414Skan { "-Wparentheses", 133890282Sobrien N_("Warn about possible missing parentheses") }, 133950615Sobrien { "-Wno-parentheses", "" }, 1340117414Skan { "-Wpointer-arith", 134190282Sobrien N_("Warn about function pointer arithmetic") }, 134250615Sobrien { "-Wno-pointer-arith", "" }, 134350615Sobrien { "-Wredundant-decls", 134490282Sobrien N_("Warn about multiple declarations of the same object") }, 134550615Sobrien { "-Wno-redundant-decls", "" }, 1346117414Skan { "-Wreturn-type", 1347117414Skan N_("Warn whenever a function's return-type defaults to int") }, 1348117414Skan { "-Wno-return-type", "" }, 1349117414Skan { "-Wsequence-point", 1350117414Skan N_("Warn about possible violations of sequence point rules") }, 1351117414Skan { "-Wno-sequence-point", "" }, 1352117414Skan { "-Wsign-compare", 135390282Sobrien N_("Warn about signed/unsigned comparisons") }, 135450615Sobrien { "-Wno-sign-compare", "" }, 1355117414Skan { "-Wstrict-prototypes", 135690282Sobrien N_("Warn about non-prototyped function decls") }, 135750615Sobrien { "-Wno-strict-prototypes", "" }, 1358117414Skan { "-Wtraditional", 1359117414Skan N_("Warn about constructs whose meanings change in ISO C") }, 136050615Sobrien { "-Wno-traditional", "" }, 1361117414Skan { "-Wtrigraphs", 136290282Sobrien N_("Warn when trigraphs are encountered") }, 136350615Sobrien { "-Wno-trigraphs", "" }, 136450615Sobrien { "-Wundef", "" }, 136550615Sobrien { "-Wno-undef", "" }, 1366117414Skan { "-Wunknown-pragmas", 1367117414Skan N_("Warn about unrecognized pragmas") }, 1368117414Skan { "-Wno-unknown-pragmas", "" }, 1369117414Skan { "-Wwrite-strings", 137090282Sobrien N_("Mark strings as 'const char *'") }, 137150615Sobrien { "-Wno-write-strings", "" }, 137218334Speter 137350615Sobrien#define DEFINE_LANG_NAME(NAME) { NULL, NAME }, 137450615Sobrien 137518334Speter#include "options.h" 137690282Sobrien 137718334Speter}; 137850615Sobrien 137950615Sobrien/* Here is a table, controlled by the tm.h file, listing each -m switch 138050615Sobrien and which bits in `target_switches' it should set or clear. 138150615Sobrien If VALUE is positive, it is bits to set. 138250615Sobrien If VALUE is negative, -VALUE is bits to clear. 138350615Sobrien (The sign bit is not used so there is no confusion.) */ 138450615Sobrien 138590282Sobrienstatic const struct 138650615Sobrien{ 138790282Sobrien const char *const name; 138890282Sobrien const int value; 138990282Sobrien const char *const description; 139050615Sobrien} 1391117414Skantarget_switches[] = TARGET_SWITCHES; 139250615Sobrien 139350615Sobrien/* This table is similar, but allows the switch to have a value. */ 139450615Sobrien 139550615Sobrien#ifdef TARGET_OPTIONS 139690282Sobrienstatic const struct 139750615Sobrien{ 139890282Sobrien const char *const prefix; 139990282Sobrien const char **const variable; 140090282Sobrien const char *const description; 140150615Sobrien} 1402117414Skantarget_options[] = TARGET_OPTIONS; 140350615Sobrien#endif 140418334Speter 140590282Sobrien/* Options controlling warnings. */ 140618334Speter 140718334Speter/* Don't print warning messages. -w. */ 140818334Speter 140918334Speterint inhibit_warnings = 0; 141018334Speter 141190282Sobrien/* Don't suppress warnings from system headers. -Wsystem-headers. */ 141290282Sobrien 141390282Sobrienint warn_system_headers = 0; 141490282Sobrien 141518334Speter/* Print various extra warnings. -W. */ 141618334Speter 141718334Speterint extra_warnings = 0; 141818334Speter 141918334Speter/* Treat warnings as errors. -Werror. */ 142018334Speter 142118334Speterint warnings_are_errors = 0; 142218334Speter 142390282Sobrien/* Nonzero to warn about unused variables, functions et.al. */ 142418334Speter 142590282Sobrienint warn_unused_function; 142690282Sobrienint warn_unused_label; 142790282Sobrienint warn_unused_parameter; 142890282Sobrienint warn_unused_variable; 142990282Sobrienint warn_unused_value; 143018334Speter 143190282Sobrien/* Nonzero to warn about code which is never reached. */ 143290282Sobrien 143390282Sobrienint warn_notreached; 143490282Sobrien 143518334Speter/* Nonzero to warn about variables used before they are initialized. */ 143618334Speter 143718334Speterint warn_uninitialized; 143818334Speter 143990282Sobrien/* Nonzero means warn about all declarations which shadow others. */ 144018334Speter 144118334Speterint warn_shadow; 144218334Speter 1443117414Skan/* Warn if a switch on an enum, that does not have a default case, 1444117414Skan fails to have a case for every enum value. */ 144518334Speter 144618334Speterint warn_switch; 144718334Speter 1448117414Skan/* Warn if a switch does not have a default case. */ 1449117414Skan 1450117414Skanint warn_switch_default; 1451117414Skan 1452117414Skan/* Warn if a switch on an enum fails to have a case for every enum 1453117414Skan value (regardless of the presence or otherwise of a default case). */ 1454117414Skan 1455117414Skanint warn_switch_enum; 1456117414Skan 145718334Speter/* Nonzero means warn about function definitions that default the return type 145818334Speter or that use a null return and have a return-type other than void. */ 145918334Speter 146018334Speterint warn_return_type; 146118334Speter 146218334Speter/* Nonzero means warn about pointer casts that increase the required 146318334Speter alignment of the target type (and might therefore lead to a crash 146418334Speter due to a misaligned access). */ 146518334Speter 146618334Speterint warn_cast_align; 146718334Speter 146818334Speter/* Nonzero means warn about any objects definitions whose size is larger 146918334Speter than N bytes. Also want about function definitions whose returned 147018334Speter values are larger than N bytes. The value N is in `larger_than_size'. */ 147190282Sobrien 147218334Speterint warn_larger_than; 147390282SobrienHOST_WIDE_INT larger_than_size; 147418334Speter 147518334Speter/* Nonzero means warn if inline function is too large. */ 147618334Speter 147718334Speterint warn_inline; 147818334Speter 147918334Speter/* Warn if a function returns an aggregate, 148018334Speter since there are often incompatible calling conventions for doing this. */ 148118334Speter 148218334Speterint warn_aggregate_return; 148318334Speter 148490282Sobrien/* Warn if packed attribute on struct is unnecessary and inefficient. */ 148590282Sobrien 148690282Sobrienint warn_packed; 148790282Sobrien 148890282Sobrien/* Warn when gcc pads a structure to an alignment boundary. */ 148990282Sobrien 149090282Sobrienint warn_padded; 149190282Sobrien 149290282Sobrien/* Warn when an optimization pass is disabled. */ 149390282Sobrien 149490282Sobrienint warn_disabled_optimization; 149590282Sobrien 149690282Sobrien/* Warn about functions which might be candidates for attribute noreturn. */ 149790282Sobrien 149890282Sobrienint warn_missing_noreturn; 149990282Sobrien 1500117414Skan/* Nonzero means warn about uses of __attribute__((deprecated)) 150190282Sobrien declarations. */ 150290282Sobrien 150390282Sobrienint warn_deprecated_decl = 1; 150490282Sobrien 1505117414Skan/* Nonzero means warn about constructs which might not be 1506117414Skan strict-aliasing safe. */ 1507117414Skan 1508117414Skanint warn_strict_aliasing; 1509117414Skan 151018334Speter/* Likewise for -W. */ 151118334Speter 151290282Sobrienstatic const lang_independent_options W_options[] = 151318334Speter{ 151490282Sobrien {"unused-function", &warn_unused_function, 1, 151590282Sobrien N_("Warn when a function is unused") }, 151690282Sobrien {"unused-label", &warn_unused_label, 1, 151790282Sobrien N_("Warn when a label is unused") }, 151890282Sobrien {"unused-parameter", &warn_unused_parameter, 1, 151990282Sobrien N_("Warn when a function parameter is unused") }, 152090282Sobrien {"unused-variable", &warn_unused_variable, 1, 152190282Sobrien N_("Warn when a variable is unused") }, 152290282Sobrien {"unused-value", &warn_unused_value, 1, 152390282Sobrien N_("Warn when an expression value is unused") }, 152490282Sobrien {"system-headers", &warn_system_headers, 1, 152590282Sobrien N_("Do not suppress warnings from system headers") }, 152690282Sobrien {"error", &warnings_are_errors, 1, 152790282Sobrien N_("Treat all warnings as errors") }, 152890282Sobrien {"shadow", &warn_shadow, 1, 152990282Sobrien N_("Warn when one local variable shadows another") }, 153050615Sobrien {"switch", &warn_switch, 1, 1531117414Skan N_("Warn about enumerated switches, with no default, missing a case") }, 1532117414Skan {"switch-default", &warn_switch_default, 1, 1533117414Skan N_("Warn about enumerated switches missing a default case") }, 1534117414Skan {"switch-enum", &warn_switch_enum, 1, 1535117414Skan N_("Warn about all enumerated switches missing a specific case") }, 153650615Sobrien {"aggregate-return", &warn_aggregate_return, 1, 153790282Sobrien N_("Warn about returning structures, unions or arrays") }, 153850615Sobrien {"cast-align", &warn_cast_align, 1, 153990282Sobrien N_("Warn about pointer casts which increase alignment") }, 154090282Sobrien {"unreachable-code", &warn_notreached, 1, 154190282Sobrien N_("Warn about code that will never be executed") }, 154250615Sobrien {"uninitialized", &warn_uninitialized, 1, 154390282Sobrien N_("Warn about uninitialized automatic variables") }, 154450615Sobrien {"inline", &warn_inline, 1, 154590282Sobrien N_("Warn when an inlined function cannot be inlined") }, 154690282Sobrien {"packed", &warn_packed, 1, 154790282Sobrien N_("Warn when the packed attribute has no effect on struct layout") }, 154890282Sobrien {"padded", &warn_padded, 1, 154990282Sobrien N_("Warn when padding is required to align struct members") }, 155090282Sobrien {"disabled-optimization", &warn_disabled_optimization, 1, 155190282Sobrien N_("Warn when an optimization pass is disabled") }, 155290282Sobrien {"deprecated-declarations", &warn_deprecated_decl, 1, 155390282Sobrien N_("Warn about uses of __attribute__((deprecated)) declarations") }, 155490282Sobrien {"missing-noreturn", &warn_missing_noreturn, 1, 1555117414Skan N_("Warn about functions which might be candidates for attribute noreturn") }, 1556117414Skan {"strict-aliasing", &warn_strict_aliasing, 1, 1557117414Skan N_ ("Warn about code which might break the strict aliasing rules") } 155818334Speter}; 155990282Sobrien 156090282Sobrienvoid 156190282Sobrienset_Wunused (setting) 156290282Sobrien int setting; 156390282Sobrien{ 156490282Sobrien warn_unused_function = setting; 156590282Sobrien warn_unused_label = setting; 156690282Sobrien /* Unused function parameter warnings are reported when either ``-W 156790282Sobrien -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate 156890282Sobrien -Wunused by setting WARN_UNUSED_PARAMETER to -1. */ 156990282Sobrien if (!setting) 157090282Sobrien warn_unused_parameter = 0; 157190282Sobrien else if (!warn_unused_parameter) 157290282Sobrien warn_unused_parameter = -1; 157390282Sobrien warn_unused_variable = setting; 157490282Sobrien warn_unused_value = setting; 157590282Sobrien} 157690282Sobrien 157790282Sobrien/* The following routines are useful in setting all the flags that 157890282Sobrien -ffast-math and -fno-fast-math imply. */ 157990282Sobrien 158090282Sobrienvoid 1581117414Skanset_fast_math_flags (set) 1582117414Skan int set; 158390282Sobrien{ 1584117414Skan flag_trapping_math = !set; 1585117414Skan flag_unsafe_math_optimizations = set; 1586117414Skan flag_finite_math_only = set; 1587117414Skan flag_errno_math = !set; 1588117414Skan if (set) 1589117414Skan flag_signaling_nans = 0; 159090282Sobrien} 159190282Sobrien 1592117414Skan/* Return true iff flags are set as if -ffast-math. */ 1593117414Skanbool 1594117414Skanfast_math_flags_set_p () 159590282Sobrien{ 1596117414Skan return (!flag_trapping_math 1597117414Skan && flag_unsafe_math_optimizations 1598117414Skan && flag_finite_math_only 1599117414Skan && !flag_errno_math); 160090282Sobrien} 160190282Sobrien 160218334Speter 160318334Speter/* Output files for assembler code (real compiler output) 160418334Speter and debugging dumps. */ 160518334Speter 160618334SpeterFILE *asm_out_file; 160718334SpeterFILE *aux_info_file; 160850615SobrienFILE *rtl_dump_file = NULL; 160918334Speter 161052558Sobrien/* Decode the string P as an integral parameter. 161152558Sobrien If the string is indeed an integer return its numeric value else 161252558Sobrien issue an Invalid Option error for the option PNAME and return DEFVAL. 161390282Sobrien If PNAME is zero just return DEFVAL, do not call error. */ 161490282Sobrien 161552558Sobrienint 161652558Sobrienread_integral_parameter (p, pname, defval) 161752558Sobrien const char *p; 161852558Sobrien const char *pname; 161952558Sobrien const int defval; 162052558Sobrien{ 162152558Sobrien const char *endp = p; 162252558Sobrien 162352558Sobrien while (*endp) 162452558Sobrien { 162590282Sobrien if (ISDIGIT (*endp)) 162652558Sobrien endp++; 162752558Sobrien else 162852558Sobrien break; 162952558Sobrien } 163052558Sobrien 163152558Sobrien if (*endp != 0) 163252558Sobrien { 163352558Sobrien if (pname != 0) 163490282Sobrien error ("invalid option `%s'", pname); 163552558Sobrien return defval; 163652558Sobrien } 163752558Sobrien 163852558Sobrien return atoi (p); 163952558Sobrien} 164018334Speter 1641117414Skan/* This calls abort and is used to avoid problems when abort is a macro. 164218334Speter It is used when we need to pass the address of abort. */ 164318334Speter 164418334Spetervoid 164518334Speterdo_abort () 164618334Speter{ 164718334Speter abort (); 164818334Speter} 164918334Speter 165018334Speter/* When `malloc.c' is compiled with `rcheck' defined, 165118334Speter it calls this function to report clobberage. */ 165218334Speter 165318334Spetervoid 165418334Speterbotch (s) 165590282Sobrien const char *s ATTRIBUTE_UNUSED; 165618334Speter{ 165718334Speter abort (); 165818334Speter} 165918334Speter 166018334Speter/* Return the logarithm of X, base 2, considering X unsigned, 166118334Speter if X is a power of 2. Otherwise, returns -1. 166218334Speter 166318334Speter This should be used via the `exact_log2' macro. */ 166418334Speter 166518334Speterint 166618334Speterexact_log2_wide (x) 166790282Sobrien unsigned HOST_WIDE_INT x; 166818334Speter{ 166990282Sobrien int log = 0; 167018334Speter /* Test for 0 or a power of 2. */ 167118334Speter if (x == 0 || x != (x & -x)) 167218334Speter return -1; 167318334Speter while ((x >>= 1) != 0) 167418334Speter log++; 167518334Speter return log; 167618334Speter} 167718334Speter 167818334Speter/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. 167918334Speter If X is 0, return -1. 168018334Speter 168118334Speter This should be used via the floor_log2 macro. */ 168218334Speter 168318334Speterint 168418334Speterfloor_log2_wide (x) 168590282Sobrien unsigned HOST_WIDE_INT x; 168618334Speter{ 168790282Sobrien int log = -1; 168818334Speter while (x != 0) 168918334Speter log++, 169018334Speter x >>= 1; 169118334Speter return log; 169218334Speter} 169318334Speter 169490282Sobrien/* Handler for fatal signals, such as SIGSEGV. These are transformed 169590282Sobrien into ICE messages, which is much more user friendly. */ 169618334Speter 169718334Speterstatic void 169890282Sobriencrash_signal (signo) 169990282Sobrien int signo; 170018334Speter{ 1701117414Skan internal_error ("%s", strsignal (signo)); 170218334Speter} 170318334Speter 170418334Speter/* Strip off a legitimate source ending from the input string NAME of 170518334Speter length LEN. Rather than having to know the names used by all of 170650615Sobrien our front ends, we strip off an ending of a period followed by 170790282Sobrien up to five characters. (Java uses ".class".) */ 170818334Speter 170918334Spetervoid 171018334Speterstrip_off_ending (name, len) 171118334Speter char *name; 171218334Speter int len; 171318334Speter{ 171450615Sobrien int i; 1715117414Skan for (i = 2; i < 6 && len > i; i++) 171650615Sobrien { 171750615Sobrien if (name[len - i] == '.') 171850615Sobrien { 171950615Sobrien name[len - i] = '\0'; 172050615Sobrien break; 172150615Sobrien } 172250615Sobrien } 172318334Speter} 172418334Speter 172518334Speter/* Output a quoted string. */ 172650615Sobrien 172718334Spetervoid 172818334Speteroutput_quoted_string (asm_file, string) 172918334Speter FILE *asm_file; 173052558Sobrien const char *string; 173118334Speter{ 173250615Sobrien#ifdef OUTPUT_QUOTED_STRING 173350615Sobrien OUTPUT_QUOTED_STRING (asm_file, string); 173450615Sobrien#else 173518334Speter char c; 173618334Speter 173718334Speter putc ('\"', asm_file); 173818334Speter while ((c = *string++) != 0) 173918334Speter { 174096289Sobrien if (ISPRINT (c)) 174196289Sobrien { 174296289Sobrien if (c == '\"' || c == '\\') 174396289Sobrien putc ('\\', asm_file); 174496289Sobrien putc (c, asm_file); 174596289Sobrien } 174696289Sobrien else 1747117414Skan fprintf (asm_file, "\\%03o", (unsigned char) c); 174818334Speter } 174918334Speter putc ('\"', asm_file); 175050615Sobrien#endif 175118334Speter} 175218334Speter 1753117414Skan/* Output NAME into FILE after having turned it into something 1754117414Skan usable as an identifier in a target's assembly file. */ 1755117414Skanvoid 1756117414Skanoutput_clean_symbol_name (file, name) 1757117414Skan FILE *file; 1758117414Skan const char *name; 1759117414Skan{ 1760117414Skan /* Make a copy of NAME. */ 1761117414Skan char *id = xstrdup (name); 1762117414Skan 1763117414Skan /* Make it look like a valid identifier for an assembler. */ 1764117414Skan clean_symbol_name (id); 1765117414Skan 1766117414Skan fputs (id, file); 1767117414Skan free (id); 1768117414Skan} 1769117414Skan 1770117414Skan 177118334Speter/* Output a file name in the form wanted by System V. */ 177218334Speter 177318334Spetervoid 177418334Speteroutput_file_directive (asm_file, input_name) 177518334Speter FILE *asm_file; 177652558Sobrien const char *input_name; 177718334Speter{ 177818334Speter int len = strlen (input_name); 177952558Sobrien const char *na = input_name + len; 178018334Speter 178118334Speter /* NA gets INPUT_NAME sans directory names. */ 178218334Speter while (na > input_name) 178318334Speter { 178490282Sobrien if (IS_DIR_SEPARATOR (na[-1])) 1785117414Skan break; 178618334Speter na--; 178718334Speter } 178818334Speter 178918334Speter#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME 179018334Speter ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na); 179118334Speter#else 179218334Speter#ifdef ASM_OUTPUT_SOURCE_FILENAME 179318334Speter ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); 179418334Speter#else 179518334Speter fprintf (asm_file, "\t.file\t"); 179618334Speter output_quoted_string (asm_file, na); 179718334Speter fputc ('\n', asm_file); 179818334Speter#endif 179918334Speter#endif 180018334Speter} 180118334Speter 180290282Sobrien/* Routine to open a dump file. Return true if the dump file is enabled. */ 180318334Speter 180490282Sobrienstatic int 180590282Sobrienopen_dump_file (index, decl) 180690282Sobrien enum dump_file_index index; 180790282Sobrien tree decl; 180818334Speter{ 180990282Sobrien char *dump_name; 181090282Sobrien const char *open_arg; 181190282Sobrien char seq[16]; 181218334Speter 181390282Sobrien if (! dump_file[index].enabled) 181490282Sobrien return 0; 181550615Sobrien 181690282Sobrien timevar_push (TV_DUMP); 181790282Sobrien if (rtl_dump_file != NULL) 181890282Sobrien fclose (rtl_dump_file); 181950615Sobrien 182090282Sobrien sprintf (seq, DUMPFILE_FORMAT, index); 182150615Sobrien 182290282Sobrien if (! dump_file[index].initialized) 182390282Sobrien { 182490282Sobrien /* If we've not initialized the files, do so now. */ 182590282Sobrien if (graph_dump_format != no_graph 182690282Sobrien && dump_file[index].graph_dump_p) 182790282Sobrien { 182890282Sobrien dump_name = concat (seq, dump_file[index].extension, NULL); 182990282Sobrien clean_graph_dump_file (dump_base_name, dump_name); 183090282Sobrien free (dump_name); 183190282Sobrien } 183290282Sobrien dump_file[index].initialized = 1; 183390282Sobrien open_arg = "w"; 183490282Sobrien } 183590282Sobrien else 183690282Sobrien open_arg = "a"; 183750615Sobrien 183890282Sobrien dump_name = concat (dump_base_name, seq, 183990282Sobrien dump_file[index].extension, NULL); 184050615Sobrien 184190282Sobrien rtl_dump_file = fopen (dump_name, open_arg); 184290282Sobrien if (rtl_dump_file == NULL) 184390282Sobrien fatal_io_error ("can't open %s", dump_name); 184490282Sobrien 184590282Sobrien free (dump_name); 184690282Sobrien 184790282Sobrien if (decl) 1848117414Skan fprintf (rtl_dump_file, "\n;; Function %s%s\n\n", 1849117414Skan (*lang_hooks.decl_printable_name) (decl, 2), 1850117414Skan cfun->function_frequency == FUNCTION_FREQUENCY_HOT 1851117414Skan ? " (hot)" 1852117414Skan : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED 1853117414Skan ? " (unlikely executed)" 1854117414Skan : ""); 185590282Sobrien 185690282Sobrien timevar_pop (TV_DUMP); 185790282Sobrien return 1; 185850615Sobrien} 185950615Sobrien 186090282Sobrien/* Routine to close a dump file. */ 186190282Sobrien 186250615Sobrienstatic void 186390282Sobrienclose_dump_file (index, func, insns) 186490282Sobrien enum dump_file_index index; 186590282Sobrien void (*func) PARAMS ((FILE *, rtx)); 186690282Sobrien rtx insns; 186750615Sobrien{ 186890282Sobrien if (! rtl_dump_file) 186990282Sobrien return; 187050615Sobrien 187190282Sobrien timevar_push (TV_DUMP); 187290282Sobrien if (insns 187390282Sobrien && graph_dump_format != no_graph 187490282Sobrien && dump_file[index].graph_dump_p) 187590282Sobrien { 187690282Sobrien char seq[16]; 187790282Sobrien char *suffix; 187850615Sobrien 187990282Sobrien sprintf (seq, DUMPFILE_FORMAT, index); 188090282Sobrien suffix = concat (seq, dump_file[index].extension, NULL); 188190282Sobrien print_rtl_graph_with_bb (dump_base_name, suffix, insns); 188290282Sobrien free (suffix); 188390282Sobrien } 188450615Sobrien 188590282Sobrien if (func && insns) 188690282Sobrien func (rtl_dump_file, insns); 188750615Sobrien 188890282Sobrien fflush (rtl_dump_file); 188990282Sobrien fclose (rtl_dump_file); 189050615Sobrien 189150615Sobrien rtl_dump_file = NULL; 189290282Sobrien timevar_pop (TV_DUMP); 189318334Speter} 189418334Speter 189552558Sobrien/* Do any final processing required for the declarations in VEC, of 189652558Sobrien which there are LEN. We write out inline functions and variables 189752558Sobrien that have been deferred until this point, but which are required. 1898117414Skan Returns nonzero if anything was put out. */ 189990282Sobrien 190052558Sobrienint 190152558Sobrienwrapup_global_declarations (vec, len) 190252558Sobrien tree *vec; 190352558Sobrien int len; 190452558Sobrien{ 190552558Sobrien tree decl; 190652558Sobrien int i; 190752558Sobrien int reconsider; 190852558Sobrien int output_something = 0; 190950615Sobrien 191052558Sobrien for (i = 0; i < len; i++) 191152558Sobrien { 191252558Sobrien decl = vec[i]; 191390282Sobrien 1914117414Skan /* We're not deferring this any longer. Assignment is 1915117414Skan conditional to avoid needlessly dirtying PCH pages. */ 1916117414Skan if (DECL_DEFER_OUTPUT (decl) != 0) 1917117414Skan DECL_DEFER_OUTPUT (decl) = 0; 191890282Sobrien 1919117414Skan if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0) 1920117414Skan (*lang_hooks.finish_incomplete_decl) (decl); 192152558Sobrien } 192252558Sobrien 192352558Sobrien /* Now emit any global variables or functions that we have been 192452558Sobrien putting off. We need to loop in case one of the things emitted 192552558Sobrien here references another one which comes earlier in the list. */ 192652558Sobrien do 192752558Sobrien { 192852558Sobrien reconsider = 0; 192952558Sobrien for (i = 0; i < len; i++) 193052558Sobrien { 193152558Sobrien decl = vec[i]; 193252558Sobrien 193352558Sobrien if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl)) 193452558Sobrien continue; 193552558Sobrien 193652558Sobrien /* Don't write out static consts, unless we still need them. 193752558Sobrien 193852558Sobrien We also keep static consts if not optimizing (for debugging), 193952558Sobrien unless the user specified -fno-keep-static-consts. 194052558Sobrien ??? They might be better written into the debug information. 194152558Sobrien This is possible when using DWARF. 194252558Sobrien 194352558Sobrien A language processor that wants static constants to be always 194452558Sobrien written out (even if it is not used) is responsible for 194552558Sobrien calling rest_of_decl_compilation itself. E.g. the C front-end 194652558Sobrien calls rest_of_decl_compilation from finish_decl. 194752558Sobrien One motivation for this is that is conventional in some 194852558Sobrien environments to write things like: 194952558Sobrien static const char rcsid[] = "... version string ..."; 195052558Sobrien intending to force the string to be in the executable. 195152558Sobrien 195252558Sobrien A language processor that would prefer to have unneeded 195352558Sobrien static constants "optimized away" would just defer writing 195452558Sobrien them out until here. E.g. C++ does this, because static 195552558Sobrien constants are often defined in header files. 195652558Sobrien 195752558Sobrien ??? A tempting alternative (for both C and C++) would be 195852558Sobrien to force a constant to be written if and only if it is 195952558Sobrien defined in a main file, as opposed to an include file. */ 196052558Sobrien 196196289Sobrien if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) 196252558Sobrien { 196396289Sobrien bool needed = 1; 196496289Sobrien 196596289Sobrien if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 196696289Sobrien /* needed */; 196796289Sobrien else if (DECL_COMDAT (decl)) 196896289Sobrien needed = 0; 196996289Sobrien else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) 197096289Sobrien && (optimize || !flag_keep_static_consts 197196289Sobrien || DECL_ARTIFICIAL (decl))) 197296289Sobrien needed = 0; 197396289Sobrien 197496289Sobrien if (needed) 197596289Sobrien { 197696289Sobrien reconsider = 1; 197796289Sobrien rest_of_decl_compilation (decl, NULL, 1, 1); 197896289Sobrien } 197952558Sobrien } 198052558Sobrien 198152558Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 198252558Sobrien && DECL_INITIAL (decl) != 0 198352558Sobrien && DECL_SAVED_INSNS (decl) != 0 198452558Sobrien && (flag_keep_inline_functions 198552558Sobrien || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) 198652558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 198752558Sobrien { 198852558Sobrien reconsider = 1; 198952558Sobrien output_inline_function (decl); 199052558Sobrien } 199152558Sobrien } 199252558Sobrien 199352558Sobrien if (reconsider) 199452558Sobrien output_something = 1; 199552558Sobrien } 199652558Sobrien while (reconsider); 199752558Sobrien 199852558Sobrien return output_something; 199952558Sobrien} 200052558Sobrien 200152558Sobrien/* Issue appropriate warnings for the global declarations in VEC (of 200252558Sobrien which there are LEN). Output debugging information for them. */ 200390282Sobrien 200452558Sobrienvoid 200552558Sobriencheck_global_declarations (vec, len) 200652558Sobrien tree *vec; 200752558Sobrien int len; 200852558Sobrien{ 200952558Sobrien tree decl; 201052558Sobrien int i; 201152558Sobrien 201252558Sobrien for (i = 0; i < len; i++) 201352558Sobrien { 201452558Sobrien decl = vec[i]; 201552558Sobrien 201652558Sobrien if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) 201752558Sobrien && ! TREE_ASM_WRITTEN (decl)) 201852558Sobrien /* Cancel the RTL for this decl so that, if debugging info 201952558Sobrien output for global variables is still to come, 202052558Sobrien this one will be omitted. */ 202190282Sobrien SET_DECL_RTL (decl, NULL_RTX); 202252558Sobrien 202352558Sobrien /* Warn about any function 202452558Sobrien declared static but not defined. 202552558Sobrien We don't warn about variables, 202652558Sobrien because many programs have static variables 202752558Sobrien that exist only to get some text into the object file. */ 202852558Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 202990282Sobrien && (warn_unused_function 203052558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 203152558Sobrien && DECL_INITIAL (decl) == 0 203252558Sobrien && DECL_EXTERNAL (decl) 203352558Sobrien && ! DECL_ARTIFICIAL (decl) 203452558Sobrien && ! TREE_PUBLIC (decl)) 203552558Sobrien { 203652558Sobrien if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 203752558Sobrien pedwarn_with_decl (decl, 203852558Sobrien "`%s' used but never defined"); 203952558Sobrien else 204052558Sobrien warning_with_decl (decl, 204152558Sobrien "`%s' declared `static' but never defined"); 204252558Sobrien /* This symbol is effectively an "extern" declaration now. */ 204352558Sobrien TREE_PUBLIC (decl) = 1; 204452558Sobrien assemble_external (decl); 204552558Sobrien } 204652558Sobrien 2047117414Skan /* Warn about static fns or vars defined but not used. */ 2048117414Skan if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL) 2049117414Skan /* We don't warn about "static const" variables because the 2050117414Skan "rcs_id" idiom uses that construction. */ 205190282Sobrien || (warn_unused_variable 205290282Sobrien && TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) 205352558Sobrien && ! DECL_IN_SYSTEM_HEADER (decl) 2054117414Skan && ! TREE_USED (decl) 2055117414Skan /* The TREE_USED bit for file-scope decls is kept in the identifier, 2056117414Skan to handle multiple external decls in different scopes. */ 2057117414Skan && ! TREE_USED (DECL_NAME (decl)) 205852558Sobrien && ! DECL_EXTERNAL (decl) 205952558Sobrien && ! TREE_PUBLIC (decl) 2060117414Skan /* Global register variables must be declared to reserve them. */ 2061117414Skan && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) 2062117414Skan /* Otherwise, ask the language. */ 2063117414Skan && (*lang_hooks.decls.warn_unused_global) (decl)) 206452558Sobrien warning_with_decl (decl, "`%s' defined but not used"); 206552558Sobrien 2066117414Skan /* Avoid confusing the debug information machinery when there are 2067117414Skan errors. */ 2068117414Skan if (errorcount == 0 && sorrycount == 0) 2069117414Skan { 2070117414Skan timevar_push (TV_SYMOUT); 2071117414Skan (*debug_hooks->global_decl) (decl); 2072117414Skan timevar_pop (TV_SYMOUT); 2073117414Skan } 207452558Sobrien } 207552558Sobrien} 207652558Sobrien 207790282Sobrien/* Save the current INPUT_FILENAME and LINENO on the top entry in the 207890282Sobrien INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the 207990282Sobrien INPUT_FILENAME and LINENO accordingly. */ 208018334Speter 208190282Sobrienvoid 208290282Sobrienpush_srcloc (file, line) 208390282Sobrien const char *file; 208490282Sobrien int line; 208518334Speter{ 208690282Sobrien struct file_stack *fs; 208718334Speter 208890282Sobrien if (input_file_stack) 208918334Speter { 209090282Sobrien input_file_stack->name = input_filename; 209190282Sobrien input_file_stack->line = lineno; 209218334Speter } 209318334Speter 209490282Sobrien fs = (struct file_stack *) xmalloc (sizeof (struct file_stack)); 209590282Sobrien fs->name = input_filename = file; 209690282Sobrien fs->line = lineno = line; 209790282Sobrien fs->next = input_file_stack; 209890282Sobrien input_file_stack = fs; 209990282Sobrien input_file_stack_tick++; 210090282Sobrien} 210118334Speter 210290282Sobrien/* Pop the top entry off the stack of presently open source files. 210390282Sobrien Restore the INPUT_FILENAME and LINENO from the new topmost entry on 210490282Sobrien the stack. */ 210518334Speter 210690282Sobrienvoid 210790282Sobrienpop_srcloc () 210890282Sobrien{ 210990282Sobrien struct file_stack *fs; 211018334Speter 211190282Sobrien fs = input_file_stack; 211290282Sobrien input_file_stack = fs->next; 211390282Sobrien free (fs); 211490282Sobrien input_file_stack_tick++; 211590282Sobrien /* The initial source file is never popped. */ 211690282Sobrien if (!input_file_stack) 211790282Sobrien abort (); 211890282Sobrien input_filename = input_file_stack->name; 211990282Sobrien lineno = input_file_stack->line; 212090282Sobrien} 212118334Speter 212290282Sobrien/* Compile an entire translation unit. Write a file of assembly 212390282Sobrien output and various debugging dumps. */ 212418334Speter 212590282Sobrienstatic void 212690282Sobriencompile_file () 212790282Sobrien{ 212818334Speter /* Initialize yet another pass. */ 212918334Speter 213050615Sobrien init_final (main_input_filename); 2131117414Skan init_branch_prob (aux_base_name); 213218334Speter 213390282Sobrien timevar_push (TV_PARSE); 213418334Speter 2135117414Skan /* Call the parser, which parses the entire file (calling 2136117414Skan rest_of_compilation for each function). */ 2137117414Skan (*lang_hooks.parse_file) (set_yydebug); 213818334Speter 213990282Sobrien /* In case there were missing block closers, 214090282Sobrien get us back to the global binding level. */ 214190282Sobrien (*lang_hooks.clear_binding_stack) (); 214218334Speter 214318334Speter /* Compilation is now finished except for writing 214418334Speter what's left of the symbol table output. */ 214590282Sobrien timevar_pop (TV_PARSE); 214618334Speter 214752558Sobrien if (flag_syntax_only) 214890282Sobrien return; 214952558Sobrien 2150117414Skan (*lang_hooks.decls.final_write_globals)(); 215118334Speter 215252558Sobrien /* This must occur after the loop to output deferred functions. Else 215352558Sobrien the profiler initializer would not be emitted if all the functions 215452558Sobrien in this compilation unit were deferred. 215518334Speter 215652558Sobrien output_func_start_profiler can not cause any additional functions or 215752558Sobrien data to need to be output, so it need not be in the deferred function 215852558Sobrien loop above. */ 215952558Sobrien output_func_start_profiler (); 216018334Speter 216118334Speter /* Write out any pending weak symbol declarations. */ 216218334Speter 216318334Speter weak_finish (); 216418334Speter 216590282Sobrien /* Do dbx symbols. */ 216690282Sobrien timevar_push (TV_SYMOUT); 216718334Speter 216850615Sobrien#ifdef DWARF2_UNWIND_INFO 216950615Sobrien if (dwarf2out_do_frame ()) 217050615Sobrien dwarf2out_frame_finish (); 217150615Sobrien#endif 217250615Sobrien 217390282Sobrien (*debug_hooks->finish) (main_input_filename); 217490282Sobrien timevar_pop (TV_SYMOUT); 217550615Sobrien 217618334Speter /* Output some stuff at end of file if nec. */ 217718334Speter 217890282Sobrien dw2_output_indirect_constants (); 217990282Sobrien 2180117414Skan end_final (aux_base_name); 218118334Speter 218290282Sobrien if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) 218390282Sobrien { 218490282Sobrien timevar_push (TV_DUMP); 218590282Sobrien open_dump_file (DFI_bp, NULL); 218652558Sobrien 218790282Sobrien end_branch_prob (); 218818334Speter 218990282Sobrien close_dump_file (DFI_bp, NULL, NULL_RTX); 219090282Sobrien timevar_pop (TV_DUMP); 219118334Speter } 219218334Speter 219390282Sobrien#ifdef ASM_FILE_END 219490282Sobrien ASM_FILE_END (asm_out_file); 219590282Sobrien#endif 219618334Speter 219790282Sobrien /* Attach a special .ident directive to the end of the file to identify 219890282Sobrien the version of GCC which compiled this code. The format of the .ident 219990282Sobrien string is patterned after the ones produced by native SVR4 compilers. */ 220090282Sobrien#ifdef IDENT_ASM_OP 220190282Sobrien if (!flag_no_ident) 220290282Sobrien fprintf (asm_out_file, "%s\"GCC: (GNU) %s\"\n", 220390282Sobrien IDENT_ASM_OP, version_string); 220452558Sobrien#endif 220552558Sobrien 220690282Sobrien if (optimize > 0 && open_dump_file (DFI_combine, NULL)) 220718334Speter { 220890282Sobrien timevar_push (TV_DUMP); 220990282Sobrien dump_combine_total_stats (rtl_dump_file); 221090282Sobrien close_dump_file (DFI_combine, NULL, NULL_RTX); 221190282Sobrien timevar_pop (TV_DUMP); 221218334Speter } 221318334Speter} 221418334Speter 221518334Speter/* This is called from various places for FUNCTION_DECL, VAR_DECL, 221618334Speter and TYPE_DECL nodes. 221718334Speter 221890282Sobrien This does nothing for local (non-static) variables, unless the 221990282Sobrien variable is a register variable with an ASMSPEC. In that case, or 222090282Sobrien if the variable is not an automatic, it sets up the RTL and 222190282Sobrien outputs any assembler code (label definition, storage allocation 222290282Sobrien and initialization). 222318334Speter 222418334Speter DECL is the declaration. If ASMSPEC is nonzero, it specifies 222518334Speter the assembler symbol name to be used. TOP_LEVEL is nonzero 222618334Speter if this declaration is not within a function. */ 222718334Speter 222818334Spetervoid 222918334Speterrest_of_decl_compilation (decl, asmspec, top_level, at_end) 223018334Speter tree decl; 223152558Sobrien const char *asmspec; 223218334Speter int top_level; 223318334Speter int at_end; 223418334Speter{ 223518334Speter /* Declarations of variables, and of functions defined elsewhere. */ 223618334Speter 223718334Speter/* The most obvious approach, to put an #ifndef around where 223818334Speter this macro is used, doesn't work since it's inside a macro call. */ 223918334Speter#ifndef ASM_FINISH_DECLARE_OBJECT 224018334Speter#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END) 224118334Speter#endif 224218334Speter 2243102796Skan /* We deferred calling assemble_alias so that we could collect 2244102796Skan other attributes such as visibility. Emit the alias now. */ 2245102796Skan { 2246102796Skan tree alias; 2247102796Skan alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)); 2248102796Skan if (alias) 2249102796Skan { 2250102796Skan alias = TREE_VALUE (TREE_VALUE (alias)); 2251102796Skan alias = get_identifier (TREE_STRING_POINTER (alias)); 2252117414Skan assemble_alias (decl, alias); 2253102796Skan } 2254102796Skan } 2255102796Skan 225618334Speter /* Forward declarations for nested functions are not "external", 225718334Speter but we need to treat them as if they were. */ 225818334Speter if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) 225918334Speter || TREE_CODE (decl) == FUNCTION_DECL) 226090282Sobrien { 226190282Sobrien timevar_push (TV_VARCONST); 2262117414Skan 226390282Sobrien if (asmspec) 226490282Sobrien make_decl_rtl (decl, asmspec); 2265117414Skan 2266117414Skan /* Don't output anything when a tentative file-scope definition 2267117414Skan is seen. But at end of compilation, do output code for them. */ 226890282Sobrien if (at_end || !DECL_DEFER_OUTPUT (decl)) 226990282Sobrien assemble_variable (decl, top_level, at_end, 0); 227090282Sobrien if (decl == last_assemble_variable_decl) 227190282Sobrien { 227290282Sobrien ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, 227390282Sobrien top_level, at_end); 227490282Sobrien } 2275117414Skan 227690282Sobrien timevar_pop (TV_VARCONST); 227790282Sobrien } 227818334Speter else if (DECL_REGISTER (decl) && asmspec != 0) 227918334Speter { 228018334Speter if (decode_reg_name (asmspec) >= 0) 228118334Speter { 228290282Sobrien SET_DECL_RTL (decl, NULL_RTX); 228390282Sobrien make_decl_rtl (decl, asmspec); 228418334Speter } 228518334Speter else 228690282Sobrien { 228790282Sobrien error ("invalid register name `%s' for register variable", asmspec); 228890282Sobrien DECL_REGISTER (decl) = 0; 228990282Sobrien if (!top_level) 229090282Sobrien expand_decl (decl); 229190282Sobrien } 229218334Speter } 229318334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 229418334Speter else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 229518334Speter && TREE_CODE (decl) == TYPE_DECL) 229690282Sobrien { 229790282Sobrien timevar_push (TV_SYMOUT); 229890282Sobrien dbxout_symbol (decl, 0); 229990282Sobrien timevar_pop (TV_SYMOUT); 230090282Sobrien } 230118334Speter#endif 230218334Speter#ifdef SDB_DEBUGGING_INFO 230318334Speter else if (write_symbols == SDB_DEBUG && top_level 230418334Speter && TREE_CODE (decl) == TYPE_DECL) 230590282Sobrien { 230690282Sobrien timevar_push (TV_SYMOUT); 230790282Sobrien sdbout_symbol (decl, 0); 230890282Sobrien timevar_pop (TV_SYMOUT); 230990282Sobrien } 231018334Speter#endif 2311117414Skan#ifdef DWARF2_DEBUGGING_INFO 2312117414Skan else if ((write_symbols == DWARF2_DEBUG 2313117414Skan || write_symbols == VMS_AND_DWARF2_DEBUG) 2314117414Skan && top_level 2315117414Skan && TREE_CODE (decl) == TYPE_DECL) 2316117414Skan { 2317117414Skan timevar_push (TV_SYMOUT); 2318117414Skan dwarf2out_decl (decl); 2319117414Skan timevar_pop (TV_SYMOUT); 2320117414Skan } 2321117414Skan#endif 232218334Speter} 232318334Speter 232418334Speter/* Called after finishing a record, union or enumeral type. */ 232518334Speter 232618334Spetervoid 232718334Speterrest_of_type_compilation (type, toplev) 232852558Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO) 232918334Speter tree type; 233018334Speter int toplev; 233152558Sobrien#else 233252558Sobrien tree type ATTRIBUTE_UNUSED; 233352558Sobrien int toplev ATTRIBUTE_UNUSED; 233452558Sobrien#endif 233518334Speter{ 2336117414Skan /* Avoid confusing the debug information machinery when there are 2337117414Skan errors. */ 2338117414Skan if (errorcount != 0 || sorrycount != 0) 2339117414Skan return; 2340117414Skan 234190282Sobrien timevar_push (TV_SYMOUT); 234218334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 234318334Speter if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 234490282Sobrien dbxout_symbol (TYPE_STUB_DECL (type), !toplev); 234518334Speter#endif 234618334Speter#ifdef SDB_DEBUGGING_INFO 234718334Speter if (write_symbols == SDB_DEBUG) 234890282Sobrien sdbout_symbol (TYPE_STUB_DECL (type), !toplev); 234918334Speter#endif 235090282Sobrien#ifdef DWARF2_DEBUGGING_INFO 235190282Sobrien if ((write_symbols == DWARF2_DEBUG 235290282Sobrien || write_symbols == VMS_AND_DWARF2_DEBUG) 235390282Sobrien && toplev) 235490282Sobrien dwarf2out_decl (TYPE_STUB_DECL (type)); 235590282Sobrien#endif 235690282Sobrien timevar_pop (TV_SYMOUT); 235718334Speter} 235818334Speter 2359117414Skan/* This is called from finish_function (within langhooks.parse_file) 236018334Speter after each top-level definition is parsed. 236118334Speter It is supposed to compile that function or variable 236218334Speter and output the assembler code for it. 236318334Speter After we return, the tree storage is freed. */ 236418334Speter 236518334Spetervoid 236618334Speterrest_of_compilation (decl) 236718334Speter tree decl; 236818334Speter{ 236990282Sobrien rtx insns; 237018334Speter int tem; 237118334Speter int failure = 0; 237252558Sobrien int rebuild_label_notes_after_reload; 237390282Sobrien int register_life_up_to_date; 237418334Speter 237590282Sobrien timevar_push (TV_REST_OF_COMPILATION); 237690282Sobrien 237790282Sobrien /* Now that we're out of the frontend, we shouldn't have any more 237890282Sobrien CONCATs anywhere. */ 237990282Sobrien generating_concat_p = 0; 238090282Sobrien 238190282Sobrien /* When processing delayed functions, prepare_function_start() won't 238290282Sobrien have been run to re-initialize it. */ 238390282Sobrien cse_not_expected = ! optimize; 238490282Sobrien 238590282Sobrien /* First, make sure that NOTE_BLOCK is set correctly for each 238690282Sobrien NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */ 238790282Sobrien if (!cfun->x_whole_function_mode_p) 238890282Sobrien identify_blocks (); 238990282Sobrien 239090282Sobrien /* In function-at-a-time mode, we do not attempt to keep the BLOCK 239190282Sobrien tree in sensible shape. So, we just recalculate it here. */ 239290282Sobrien if (cfun->x_whole_function_mode_p) 239390282Sobrien reorder_blocks (); 239490282Sobrien 239590282Sobrien init_flow (); 239690282Sobrien 239718334Speter /* If we are reconsidering an inline function 239818334Speter at the end of compilation, skip the stuff for making it inline. */ 239918334Speter 240018334Speter if (DECL_SAVED_INSNS (decl) == 0) 240118334Speter { 240250615Sobrien int inlinable = 0; 240390282Sobrien tree parent; 240452558Sobrien const char *lose; 240518334Speter 240690282Sobrien /* If this is nested inside an inlined external function, pretend 240790282Sobrien it was only declared. Since we cannot inline such functions, 240890282Sobrien generating code for this one is not only not necessary but will 240990282Sobrien confuse some debugging output writers. */ 241090282Sobrien for (parent = DECL_CONTEXT (current_function_decl); 241190282Sobrien parent != NULL_TREE; 241290282Sobrien parent = get_containing_scope (parent)) 241390282Sobrien if (TREE_CODE (parent) == FUNCTION_DECL 241490282Sobrien && DECL_INLINE (parent) && DECL_EXTERNAL (parent)) 241590282Sobrien { 241690282Sobrien DECL_INITIAL (decl) = 0; 241790282Sobrien goto exit_rest_of_compilation; 241890282Sobrien } 2419107595Sobrien else if (TYPE_P (parent)) 2420107595Sobrien /* A function in a local class should be treated normally. */ 2421107595Sobrien break; 242290282Sobrien 242318334Speter /* If requested, consider whether to make this function inline. */ 242490282Sobrien if ((DECL_INLINE (decl) && !flag_no_inline) 242590282Sobrien || flag_inline_functions) 242690282Sobrien { 242790282Sobrien timevar_push (TV_INTEGRATION); 242890282Sobrien lose = function_cannot_inline_p (decl); 242990282Sobrien timevar_pop (TV_INTEGRATION); 243090282Sobrien if (lose || ! optimize) 243190282Sobrien { 243290282Sobrien if (warn_inline && DECL_INLINE (decl)) 243390282Sobrien warning_with_decl (decl, lose); 243490282Sobrien DECL_ABSTRACT_ORIGIN (decl) = 0; 243590282Sobrien /* Don't really compile an extern inline function. 243690282Sobrien If we can't make it inline, pretend 243790282Sobrien it was only declared. */ 243890282Sobrien if (DECL_EXTERNAL (decl)) 243990282Sobrien { 244090282Sobrien DECL_INITIAL (decl) = 0; 244190282Sobrien goto exit_rest_of_compilation; 244290282Sobrien } 244390282Sobrien } 2444117414Skan else 2445117414Skan { 2446117414Skan /* ??? Note that we used to just make it look like if 2447117414Skan the "inline" keyword was specified when we decide 2448117414Skan to inline it (because of -finline-functions). 2449117414Skan garloff at suse dot de, 2002-04-24: Add another flag to 2450117414Skan actually record this piece of information. */ 2451117414Skan if (!DECL_INLINE (decl)) 2452117414Skan DID_INLINE_FUNC (decl) = 1; 2453117414Skan inlinable = DECL_INLINE (decl) = 1; 2454117414Skan } 245590282Sobrien } 245618334Speter 245718334Speter insns = get_insns (); 245818334Speter 245918334Speter /* Dump the rtl code if we are dumping rtl. */ 246018334Speter 246190282Sobrien if (open_dump_file (DFI_rtl, decl)) 246250615Sobrien { 246350615Sobrien if (DECL_SAVED_INSNS (decl)) 246450615Sobrien fprintf (rtl_dump_file, ";; (integrable)\n\n"); 246590282Sobrien close_dump_file (DFI_rtl, print_rtl, insns); 246650615Sobrien } 246718334Speter 246890282Sobrien /* Convert from NOTE_INSN_EH_REGION style notes, and do other 246990282Sobrien sorts of eh initialization. Delay this until after the 247090282Sobrien initial rtl dump so that we can see the original nesting. */ 247190282Sobrien convert_from_eh_region_ranges (); 247250615Sobrien 247318334Speter /* If function is inline, and we don't yet know whether to 2474117414Skan compile it by itself, defer decision till end of compilation. 2475117414Skan wrapup_global_declarations will (indirectly) call 2476117414Skan rest_of_compilation again for those functions that need to 2477117414Skan be output. Also defer those functions that we are supposed 2478117414Skan to defer. */ 247918334Speter 248090282Sobrien if (inlinable 248190282Sobrien || (DECL_INLINE (decl) 248290282Sobrien && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) 248396289Sobrien && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) 248490282Sobrien && ! flag_keep_inline_functions) 248590282Sobrien || DECL_EXTERNAL (decl)))) 248690282Sobrien DECL_DEFER_OUTPUT (decl) = 1; 248750615Sobrien 248890282Sobrien if (DECL_INLINE (decl)) 248990282Sobrien /* DWARF wants separate debugging info for abstract and 249090282Sobrien concrete instances of all inline functions, including those 249190282Sobrien declared inline but not inlined, and those inlined even 249290282Sobrien though they weren't declared inline. Conveniently, that's 249390282Sobrien what DECL_INLINE means at this point. */ 249490282Sobrien (*debug_hooks->deferred_inline_function) (decl); 249590282Sobrien 249690282Sobrien if (DECL_DEFER_OUTPUT (decl)) 249750615Sobrien { 249890282Sobrien /* If -Wreturn-type, we have to do a bit of compilation. We just 249990282Sobrien want to call cleanup the cfg to figure out whether or not we can 250090282Sobrien fall off the end of the function; we do the minimum amount of 250190282Sobrien work necessary to make that safe. */ 250250615Sobrien if (warn_return_type) 250318334Speter { 250450615Sobrien int saved_optimize = optimize; 250590282Sobrien 250650615Sobrien optimize = 0; 250790282Sobrien rebuild_jump_labels (insns); 250850615Sobrien find_exception_handler_labels (); 250990282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 251090282Sobrien cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP); 251150615Sobrien optimize = saved_optimize; 251290282Sobrien 251390282Sobrien /* CFG is no longer maintained up-to-date. */ 251490282Sobrien free_bb_for_insn (); 251550615Sobrien } 251650615Sobrien 2517117414Skan set_nothrow_function_flags (); 251890282Sobrien if (current_function_nothrow) 251990282Sobrien /* Now we know that this can't throw; set the flag for the benefit 252090282Sobrien of other functions later in this translation unit. */ 252190282Sobrien TREE_NOTHROW (current_function_decl) = 1; 252290282Sobrien 252390282Sobrien timevar_push (TV_INTEGRATION); 252490282Sobrien save_for_inline (decl); 252590282Sobrien timevar_pop (TV_INTEGRATION); 252690282Sobrien DECL_SAVED_INSNS (decl)->inlinable = inlinable; 252750615Sobrien goto exit_rest_of_compilation; 252818334Speter } 252918334Speter 253018334Speter /* If specified extern inline but we aren't inlining it, we are 253152558Sobrien done. This goes for anything that gets here with DECL_EXTERNAL 253252558Sobrien set, not just things with DECL_INLINE. */ 253352558Sobrien if (DECL_EXTERNAL (decl)) 253418334Speter goto exit_rest_of_compilation; 253518334Speter } 253618334Speter 253790282Sobrien /* If we're emitting a nested function, make sure its parent gets 253890282Sobrien emitted as well. Doing otherwise confuses debug info. */ 253990282Sobrien { 254090282Sobrien tree parent; 254190282Sobrien for (parent = DECL_CONTEXT (current_function_decl); 254290282Sobrien parent != NULL_TREE; 254390282Sobrien parent = get_containing_scope (parent)) 254490282Sobrien if (TREE_CODE (parent) == FUNCTION_DECL) 254590282Sobrien TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1; 254690282Sobrien } 254790282Sobrien 254890282Sobrien /* We are now committed to emitting code for this function. Do any 254990282Sobrien preparation, such as emitting abstract debug info for the inline 255090282Sobrien before it gets mangled by optimization. */ 255190282Sobrien if (DECL_INLINE (decl)) 255290282Sobrien (*debug_hooks->outlining_inline_function) (decl); 255390282Sobrien 255490282Sobrien /* Remove any notes we don't need. That will make iterating 255590282Sobrien over the instruction sequence faster, and allow the garbage 255690282Sobrien collector to reclaim the memory used by the notes. */ 255790282Sobrien remove_unnecessary_notes (); 255890282Sobrien reorder_blocks (); 255990282Sobrien 256090282Sobrien ggc_collect (); 256190282Sobrien 256290282Sobrien /* Initialize some variables used by the optimizers. */ 256390282Sobrien init_function_for_compilation (); 256490282Sobrien 256518334Speter if (! DECL_DEFER_OUTPUT (decl)) 256618334Speter TREE_ASM_WRITTEN (decl) = 1; 256718334Speter 256890282Sobrien /* Now that integrate will no longer see our rtl, we need not 256990282Sobrien distinguish between the return value of this function and the 257090282Sobrien return value of called functions. Also, we can remove all SETs 257190282Sobrien of subregs of hard registers; they are only here because of 2572117414Skan integrate. Also, we can now initialize pseudos intended to 257390282Sobrien carry magic hard reg data throughout the function. */ 257418334Speter rtx_equal_function_value_matters = 0; 257590282Sobrien purge_hard_subreg_sets (get_insns ()); 257618334Speter 257796289Sobrien /* Early return if there were errors. We can run afoul of our 257896289Sobrien consistency checks, and there's not really much point in fixing them. 257996289Sobrien Don't return yet if -Wreturn-type; we need to do cleanup_cfg. */ 258096289Sobrien if (((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) 258196289Sobrien || errorcount || sorrycount) 258290282Sobrien goto exit_rest_of_compilation; 258390282Sobrien 2584117414Skan timevar_push (TV_JUMP); 2585117414Skan open_dump_file (DFI_sibling, decl); 2586117414Skan insns = get_insns (); 2587117414Skan rebuild_jump_labels (insns); 2588117414Skan find_exception_handler_labels (); 2589117414Skan find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 2590117414Skan 2591117414Skan delete_unreachable_blocks (); 2592117414Skan 2593117414Skan /* We have to issue these warnings now already, because CFG cleanups 2594117414Skan further down may destroy the required information. */ 2595117414Skan check_function_return_warnings (); 2596117414Skan 2597117414Skan /* Turn NOTE_INSN_PREDICTIONs into branch predictions. */ 2598117414Skan if (flag_guess_branch_prob) 2599117414Skan { 2600117414Skan timevar_push (TV_BRANCH_PROB); 2601117414Skan note_prediction_to_br_prob (); 2602117414Skan timevar_pop (TV_BRANCH_PROB); 2603117414Skan } 2604117414Skan 260590282Sobrien /* We may have potential sibling or tail recursion sites. Select one 260690282Sobrien (of possibly multiple) methods of performing the call. */ 260790282Sobrien if (flag_optimize_sibling_calls) 260818334Speter { 2609117414Skan rtx insn; 261090282Sobrien optimize_sibling_and_tail_recursive_calls (); 261190282Sobrien 2612117414Skan /* Recompute the CFG as sibling optimization clobbers it randomly. */ 2613117414Skan free_bb_for_insn (); 2614117414Skan find_exception_handler_labels (); 2615117414Skan rebuild_jump_labels (insns); 2616117414Skan find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 2617117414Skan 2618117414Skan /* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION 2619117414Skan notes before simplifying cfg and we must do lowering after sibcall 2620117414Skan that unhides parts of RTL chain and cleans up the CFG. 2621117414Skan 2622117414Skan Until sibcall is replaced by tree-level optimizer, lets just 2623117414Skan sweep away the NOTE_INSN_PREDICTION notes that leaked out. */ 2624117414Skan for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 2625117414Skan if (GET_CODE (insn) == NOTE 2626117414Skan && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION) 2627117414Skan delete_insn (insn); 262818334Speter } 2629117414Skan close_dump_file (DFI_sibling, print_rtl, get_insns ()); 2630117414Skan timevar_pop (TV_JUMP); 263118334Speter 2632117414Skan scope_to_insns_initialize (); 263390282Sobrien /* Complete generation of exception handling code. */ 263490282Sobrien if (doing_eh (0)) 263590282Sobrien { 263690282Sobrien timevar_push (TV_JUMP); 263790282Sobrien open_dump_file (DFI_eh, decl); 263818334Speter 263990282Sobrien finish_eh_generation (); 264090282Sobrien 264190282Sobrien close_dump_file (DFI_eh, print_rtl, get_insns ()); 264290282Sobrien timevar_pop (TV_JUMP); 264390282Sobrien } 264490282Sobrien 264596289Sobrien /* Delay emitting hard_reg_initial_value sets until after EH landing pad 264696289Sobrien generation, which might create new sets. */ 264796289Sobrien emit_initial_value_sets (); 264896289Sobrien 264918334Speter#ifdef FINALIZE_PIC 265018334Speter /* If we are doing position-independent code generation, now 265118334Speter is the time to output special prologues and epilogues. 265218334Speter We do not want to do this earlier, because it just clutters 265318334Speter up inline functions with meaningless insns. */ 265418334Speter if (flag_pic) 265518334Speter FINALIZE_PIC; 265618334Speter#endif 265718334Speter 265818334Speter insns = get_insns (); 265918334Speter 266018334Speter /* Copy any shared structure that should not be shared. */ 266172566Sobrien unshare_all_rtl (current_function_decl, insns); 266218334Speter 266350615Sobrien#ifdef SETJMP_VIA_SAVE_AREA 2664117414Skan /* This must be performed before virtual register instantiation. 2665117414Skan Please be aware the everything in the compiler that can look 2666117414Skan at the RTL up to this point must understand that REG_SAVE_AREA 2667117414Skan is just like a use of the REG contained inside. */ 266850615Sobrien if (current_function_calls_alloca) 266950615Sobrien optimize_save_area_alloca (insns); 267050615Sobrien#endif 267150615Sobrien 267218334Speter /* Instantiate all virtual registers. */ 267390282Sobrien instantiate_virtual_regs (current_function_decl, insns); 267418334Speter 267590282Sobrien open_dump_file (DFI_jump, decl); 267618334Speter 267750615Sobrien /* Always do one jump optimization pass to ensure that JUMP_LABEL fields 267850615Sobrien are initialized and to compute whether control can drop off the end 267950615Sobrien of the function. */ 268018334Speter 268190282Sobrien timevar_push (TV_JUMP); 268290282Sobrien /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this 268390282Sobrien before jump optimization switches branch directions. */ 2684117414Skan if (flag_guess_branch_prob) 2685117414Skan expected_value_to_br_prob (); 268690282Sobrien 268790282Sobrien reg_scan (insns, max_reg_num (), 0); 268890282Sobrien rebuild_jump_labels (insns); 268990282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 2690117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 2691117414Skan if (rtl_dump_file) 2692117414Skan dump_flow_info (rtl_dump_file); 2693117414Skan cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP 2694117414Skan | (flag_thread_jumps ? CLEANUP_THREADING : 0)); 269590282Sobrien 269690282Sobrien /* CFG is no longer maintained up-to-date. */ 2697117414Skan if (optimize) 2698117414Skan { 2699117414Skan free_bb_for_insn (); 2700117414Skan copy_loop_headers (insns); 2701117414Skan find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 2702117414Skan } 270390282Sobrien purge_line_number_notes (insns); 270490282Sobrien 270590282Sobrien timevar_pop (TV_JUMP); 2706117414Skan close_dump_file (DFI_jump, print_rtl, insns); 270790282Sobrien 270818334Speter /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ 270918334Speter if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl)) 271090282Sobrien { 271190282Sobrien goto exit_rest_of_compilation; 271290282Sobrien } 271318334Speter 271490282Sobrien /* Long term, this should probably move before the jump optimizer too, 271590282Sobrien but I didn't want to disturb the rtl_dump_and_exit and related 271690282Sobrien stuff at this time. */ 271790282Sobrien if (optimize > 0 && flag_ssa) 271890282Sobrien { 271990282Sobrien /* Convert to SSA form. */ 272018334Speter 272190282Sobrien timevar_push (TV_TO_SSA); 272290282Sobrien open_dump_file (DFI_ssa, decl); 272318334Speter 272490282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 272590282Sobrien convert_to_ssa (); 272690282Sobrien 272790282Sobrien close_dump_file (DFI_ssa, print_rtl_with_bb, insns); 272890282Sobrien timevar_pop (TV_TO_SSA); 272990282Sobrien 273090282Sobrien /* Perform sparse conditional constant propagation, if requested. */ 273190282Sobrien if (flag_ssa_ccp) 273290282Sobrien { 273390282Sobrien timevar_push (TV_SSA_CCP); 273490282Sobrien open_dump_file (DFI_ssa_ccp, decl); 273590282Sobrien 273690282Sobrien ssa_const_prop (); 273790282Sobrien 273890282Sobrien close_dump_file (DFI_ssa_ccp, print_rtl_with_bb, get_insns ()); 273990282Sobrien timevar_pop (TV_SSA_CCP); 274090282Sobrien } 274190282Sobrien 274290282Sobrien /* It would be useful to cleanup the CFG at this point, but block 274390282Sobrien merging and possibly other transformations might leave a PHI 274490282Sobrien node in the middle of a basic block, which is a strict no-no. */ 274590282Sobrien 274690282Sobrien /* The SSA implementation uses basic block numbers in its phi 274790282Sobrien nodes. Thus, changing the control-flow graph or the basic 274890282Sobrien blocks, e.g., calling find_basic_blocks () or cleanup_cfg (), 274990282Sobrien may cause problems. */ 275090282Sobrien 275190282Sobrien if (flag_ssa_dce) 275290282Sobrien { 275390282Sobrien /* Remove dead code. */ 275490282Sobrien 275590282Sobrien timevar_push (TV_SSA_DCE); 275690282Sobrien open_dump_file (DFI_ssa_dce, decl); 275790282Sobrien 275890282Sobrien insns = get_insns (); 2759117414Skan ssa_eliminate_dead_code (); 276090282Sobrien 276190282Sobrien close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns); 276290282Sobrien timevar_pop (TV_SSA_DCE); 276390282Sobrien } 276490282Sobrien 276590282Sobrien /* Convert from SSA form. */ 276690282Sobrien 276790282Sobrien timevar_push (TV_FROM_SSA); 276890282Sobrien open_dump_file (DFI_ussa, decl); 276990282Sobrien 277090282Sobrien convert_from_ssa (); 277190282Sobrien /* New registers have been created. Rescan their usage. */ 277290282Sobrien reg_scan (insns, max_reg_num (), 1); 277390282Sobrien 277490282Sobrien close_dump_file (DFI_ussa, print_rtl_with_bb, insns); 277590282Sobrien timevar_pop (TV_FROM_SSA); 277690282Sobrien 277790282Sobrien ggc_collect (); 277890282Sobrien } 277990282Sobrien 278090282Sobrien timevar_push (TV_JUMP); 2781117414Skan if (optimize) 2782117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 278390282Sobrien 2784117414Skan /* Try to identify useless null pointer tests and delete them. */ 2785117414Skan if (flag_delete_null_pointer_checks) 278690282Sobrien { 2787117414Skan open_dump_file (DFI_null, decl); 2788117414Skan if (rtl_dump_file) 2789117414Skan dump_flow_info (rtl_dump_file); 279090282Sobrien 2791117414Skan if (delete_null_pointer_checks (insns)) 2792117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 279390282Sobrien 2794117414Skan close_dump_file (DFI_null, print_rtl_with_bb, insns); 279590282Sobrien } 279690282Sobrien 279790282Sobrien /* Jump optimization, and the removal of NULL pointer checks, may 279890282Sobrien have reduced the number of instructions substantially. CSE, and 279990282Sobrien future passes, allocate arrays whose dimensions involve the 280090282Sobrien maximum instruction UID, so if we can reduce the maximum UID 280190282Sobrien we'll save big on memory. */ 280290282Sobrien renumber_insns (rtl_dump_file); 280390282Sobrien timevar_pop (TV_JUMP); 280490282Sobrien 2805117414Skan close_dump_file (DFI_jump, print_rtl_with_bb, insns); 280690282Sobrien 280790282Sobrien ggc_collect (); 280890282Sobrien 280918334Speter /* Perform common subexpression elimination. 281018334Speter Nonzero value from `cse_main' means that jumps were simplified 281118334Speter and some code may now be unreachable, so do 281218334Speter jump optimization again. */ 281318334Speter 281418334Speter if (optimize > 0) 281518334Speter { 281690282Sobrien open_dump_file (DFI_cse, decl); 2817117414Skan if (rtl_dump_file) 2818117414Skan dump_flow_info (rtl_dump_file); 281990282Sobrien timevar_push (TV_CSE); 282050615Sobrien 282190282Sobrien reg_scan (insns, max_reg_num (), 1); 282218334Speter 282390282Sobrien tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file); 2824117414Skan if (tem) 2825117414Skan rebuild_jump_labels (insns); 2826117414Skan purge_all_dead_edges (0); 282718334Speter 2828117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 2829117414Skan 283090282Sobrien /* If we are not running more CSE passes, then we are no longer 283190282Sobrien expecting CSE to be run. But always rerun it in a cheap mode. */ 283290282Sobrien cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; 283390282Sobrien 283418334Speter if (tem || optimize > 1) 2835117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 283690282Sobrien /* Try to identify useless null pointer tests and delete them. */ 2837117414Skan if (flag_delete_null_pointer_checks) 283890282Sobrien { 283990282Sobrien timevar_push (TV_JUMP); 284052558Sobrien 2841117414Skan if (delete_null_pointer_checks (insns)) 2842117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 284390282Sobrien timevar_pop (TV_JUMP); 284452558Sobrien } 284590282Sobrien 284690282Sobrien /* The second pass of jump optimization is likely to have 284790282Sobrien removed a bunch more instructions. */ 284890282Sobrien renumber_insns (rtl_dump_file); 284990282Sobrien 285090282Sobrien timevar_pop (TV_CSE); 2851117414Skan close_dump_file (DFI_cse, print_rtl_with_bb, insns); 285218334Speter } 285318334Speter 285490282Sobrien open_dump_file (DFI_addressof, decl); 285590282Sobrien 285650615Sobrien purge_addressof (insns); 2857117414Skan if (optimize) 2858117414Skan purge_all_dead_edges (0); 285950615Sobrien reg_scan (insns, max_reg_num (), 1); 286018334Speter 286190282Sobrien close_dump_file (DFI_addressof, print_rtl, insns); 286252558Sobrien 286390282Sobrien ggc_collect (); 286490282Sobrien 286550615Sobrien /* Perform global cse. */ 286618334Speter 286750615Sobrien if (optimize > 0 && flag_gcse) 286850615Sobrien { 286990282Sobrien int save_csb, save_cfj; 287090282Sobrien int tem2 = 0; 287118334Speter 287290282Sobrien timevar_push (TV_GCSE); 287390282Sobrien open_dump_file (DFI_gcse, decl); 287452558Sobrien 287590282Sobrien tem = gcse_main (insns, rtl_dump_file); 287690282Sobrien rebuild_jump_labels (insns); 2877117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 287890282Sobrien 287990282Sobrien save_csb = flag_cse_skip_blocks; 288090282Sobrien save_cfj = flag_cse_follow_jumps; 288190282Sobrien flag_cse_skip_blocks = flag_cse_follow_jumps = 0; 288290282Sobrien 288390282Sobrien /* If -fexpensive-optimizations, re-run CSE to clean up things done 288490282Sobrien by gcse. */ 288590282Sobrien if (flag_expensive_optimizations) 288652558Sobrien { 288790282Sobrien timevar_push (TV_CSE); 288890282Sobrien reg_scan (insns, max_reg_num (), 1); 288990282Sobrien tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); 2890117414Skan purge_all_dead_edges (0); 2891117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 289290282Sobrien timevar_pop (TV_CSE); 289390282Sobrien cse_not_expected = !flag_rerun_cse_after_loop; 289490282Sobrien } 289552558Sobrien 289690282Sobrien /* If gcse or cse altered any jumps, rerun jump optimizations to clean 289790282Sobrien things up. Then possibly re-run CSE again. */ 289890282Sobrien while (tem || tem2) 289952558Sobrien { 290090282Sobrien tem = tem2 = 0; 290190282Sobrien timevar_push (TV_JUMP); 290290282Sobrien rebuild_jump_labels (insns); 290390282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 290490282Sobrien timevar_pop (TV_JUMP); 290590282Sobrien 290690282Sobrien if (flag_expensive_optimizations) 290790282Sobrien { 290890282Sobrien timevar_push (TV_CSE); 290990282Sobrien reg_scan (insns, max_reg_num (), 1); 291090282Sobrien tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); 2911117414Skan purge_all_dead_edges (0); 2912117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 291390282Sobrien timevar_pop (TV_CSE); 291490282Sobrien } 291552558Sobrien } 291690282Sobrien 2917117414Skan close_dump_file (DFI_gcse, print_rtl_with_bb, insns); 291890282Sobrien timevar_pop (TV_GCSE); 291990282Sobrien 292090282Sobrien ggc_collect (); 292190282Sobrien flag_cse_skip_blocks = save_csb; 292290282Sobrien flag_cse_follow_jumps = save_cfj; 2923117414Skan#ifdef ENABLE_CHECKING 2924117414Skan verify_flow_info (); 2925117414Skan#endif 292650615Sobrien } 292790282Sobrien 292818334Speter /* Move constant computations out of loops. */ 292918334Speter 2930117414Skan if (optimize > 0 && flag_loop_optimize) 293118334Speter { 2932117414Skan int do_unroll, do_prefetch; 2933117414Skan 293490282Sobrien timevar_push (TV_LOOP); 2935117414Skan delete_dead_jumptables (); 2936117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 293790282Sobrien open_dump_file (DFI_loop, decl); 2938117414Skan /* CFG is no longer maintained up-to-date. */ 293990282Sobrien free_bb_for_insn (); 294018334Speter 2941117414Skan do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL; 2942117414Skan do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0; 294390282Sobrien if (flag_rerun_loop_opt) 294490282Sobrien { 294590282Sobrien cleanup_barriers (); 294690282Sobrien 294790282Sobrien /* We only want to perform unrolling once. */ 2948117414Skan loop_optimize (insns, rtl_dump_file, do_unroll); 2949117414Skan do_unroll = 0; 295090282Sobrien 295190282Sobrien /* The first call to loop_optimize makes some instructions 295290282Sobrien trivially dead. We delete those instructions now in the 295390282Sobrien hope that doing so will make the heuristics in loop work 295490282Sobrien better and possibly speed up compilation. */ 2955117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 295690282Sobrien 295790282Sobrien /* The regscan pass is currently necessary as the alias 295850615Sobrien analysis code depends on this information. */ 295990282Sobrien reg_scan (insns, max_reg_num (), 1); 296090282Sobrien } 296190282Sobrien cleanup_barriers (); 2962117414Skan loop_optimize (insns, rtl_dump_file, do_unroll | LOOP_BCT | do_prefetch); 296352558Sobrien 2964117414Skan /* Loop can create trivially dead instructions. */ 2965117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 296690282Sobrien close_dump_file (DFI_loop, print_rtl, insns); 296790282Sobrien timevar_pop (TV_LOOP); 2968117414Skan find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 296952558Sobrien 297090282Sobrien ggc_collect (); 297150615Sobrien } 297218334Speter 297390282Sobrien /* Do control and data flow analysis; wrote some of the results to 297490282Sobrien the dump file. */ 297590282Sobrien 297690282Sobrien timevar_push (TV_FLOW); 297790282Sobrien open_dump_file (DFI_cfg, decl); 2978117414Skan if (rtl_dump_file) 2979117414Skan dump_flow_info (rtl_dump_file); 2980117414Skan if (optimize) 2981117414Skan cleanup_cfg (CLEANUP_EXPENSIVE 2982117414Skan | (flag_thread_jumps ? CLEANUP_THREADING : 0)); 298390282Sobrien 298490282Sobrien /* It may make more sense to mark constant functions after dead code is 298590282Sobrien eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs 298690282Sobrien may insert code making function non-constant, but we still must consider 298790282Sobrien it as constant, otherwise -fbranch-probabilities will not read data back. 298890282Sobrien 298990282Sobrien life_analyzis rarely eliminates modification of external memory. 299090282Sobrien */ 2991117414Skan if (optimize) 2992117414Skan mark_constant_function (); 299390282Sobrien 299490282Sobrien close_dump_file (DFI_cfg, print_rtl_with_bb, insns); 299590282Sobrien 2996117414Skan /* Do branch profiling and static profile estimation passes. */ 2997117414Skan if (optimize > 0 || cfun->arc_profile || flag_branch_probabilities) 299850615Sobrien { 2999117414Skan struct loops loops; 3000117414Skan 300190282Sobrien timevar_push (TV_BRANCH_PROB); 300290282Sobrien open_dump_file (DFI_bp, decl); 3003117414Skan if (cfun->arc_profile || flag_branch_probabilities) 3004117414Skan branch_prob (); 300552558Sobrien 300690282Sobrien /* Discover and record the loop depth at the head of each basic 300790282Sobrien block. The loop infrastructure does the real job for us. */ 300890282Sobrien flow_loops_find (&loops, LOOP_TREE); 300918334Speter 3010104765Skan if (rtl_dump_file) 3011104765Skan flow_loops_dump (&loops, rtl_dump_file, NULL, 0); 3012104765Skan 301390282Sobrien /* Estimate using heuristics if no profiling info is available. */ 301490282Sobrien if (flag_guess_branch_prob) 301590282Sobrien estimate_probability (&loops); 301618334Speter 301790282Sobrien flow_loops_free (&loops); 3018117414Skan close_dump_file (DFI_bp, print_rtl_with_bb, insns); 3019117414Skan timevar_pop (TV_BRANCH_PROB); 302090282Sobrien } 3021117414Skan if (optimize > 0) 3022117414Skan { 3023117414Skan open_dump_file (DFI_ce1, decl); 3024117414Skan if (flag_if_conversion) 3025117414Skan { 3026117414Skan timevar_push (TV_IFCVT); 3027117414Skan if (rtl_dump_file) 3028117414Skan dump_flow_info (rtl_dump_file); 3029117414Skan cleanup_cfg (CLEANUP_EXPENSIVE); 3030117414Skan reg_scan (insns, max_reg_num (), 0); 3031117414Skan if_convert (0); 3032117414Skan timevar_pop (TV_IFCVT); 3033117414Skan } 3034117414Skan timevar_push (TV_JUMP); 3035117414Skan cleanup_cfg (CLEANUP_EXPENSIVE); 3036117414Skan reg_scan (insns, max_reg_num (), 0); 3037117414Skan timevar_pop (TV_JUMP); 3038117414Skan close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ()); 3039117414Skan } 3040117414Skan if (flag_tracer) 3041117414Skan { 3042117414Skan timevar_push (TV_TRACER); 3043117414Skan open_dump_file (DFI_tracer, decl); 3044117414Skan if (rtl_dump_file) 3045117414Skan dump_flow_info (rtl_dump_file); 3046117414Skan tracer (); 3047117414Skan cleanup_cfg (CLEANUP_EXPENSIVE); 3048117414Skan reg_scan (insns, max_reg_num (), 0); 3049117414Skan close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ()); 3050117414Skan timevar_pop (TV_TRACER); 3051117414Skan } 3052117414Skan 3053117414Skan if (flag_rerun_cse_after_loop) 3054117414Skan { 3055117414Skan timevar_push (TV_CSE2); 3056117414Skan open_dump_file (DFI_cse2, decl); 3057117414Skan if (rtl_dump_file) 3058117414Skan dump_flow_info (rtl_dump_file); 3059117414Skan /* CFG is no longer maintained up-to-date. */ 3060117414Skan tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file); 3061117414Skan purge_all_dead_edges (0); 3062117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 3063117414Skan 3064117414Skan if (tem) 3065117414Skan { 3066117414Skan timevar_push (TV_JUMP); 3067117414Skan rebuild_jump_labels (insns); 3068117414Skan cleanup_cfg (CLEANUP_EXPENSIVE); 3069117414Skan timevar_pop (TV_JUMP); 3070117414Skan } 3071117414Skan reg_scan (insns, max_reg_num (), 0); 3072117414Skan close_dump_file (DFI_cse2, print_rtl_with_bb, insns); 3073117414Skan ggc_collect (); 3074117414Skan timevar_pop (TV_CSE2); 3075117414Skan } 3076117414Skan 3077117414Skan cse_not_expected = 1; 3078117414Skan 3079117414Skan open_dump_file (DFI_life, decl); 3080117414Skan regclass_init (); 3081117414Skan 3082117414Skan#ifdef ENABLE_CHECKING 3083117414Skan verify_flow_info (); 3084117414Skan#endif 308590282Sobrien life_analysis (insns, rtl_dump_file, PROP_FINAL); 3086117414Skan if (optimize) 3087117414Skan cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE 3088117414Skan | (flag_thread_jumps ? CLEANUP_THREADING : 0)); 308990282Sobrien timevar_pop (TV_FLOW); 309018334Speter 309190282Sobrien if (warn_uninitialized || extra_warnings) 309218334Speter { 309390282Sobrien uninitialized_vars_warning (DECL_INITIAL (decl)); 309490282Sobrien if (extra_warnings) 309590282Sobrien setjmp_args_warning (); 309618334Speter } 309790282Sobrien 309890282Sobrien if (optimize) 309918334Speter { 3100117414Skan if (!flag_new_regalloc && initialize_uninitialized_subregs ()) 310118334Speter { 3102117414Skan /* Insns were inserted, and possibly pseudos created, so 3103117414Skan things might look a bit different. */ 310490282Sobrien insns = get_insns (); 3105117414Skan allocate_reg_life_data (); 3106117414Skan update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, 3107117414Skan PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES); 310818334Speter } 310918334Speter } 311018334Speter 3111117414Skan no_new_pseudos = 1; 3112117414Skan 311390282Sobrien close_dump_file (DFI_life, print_rtl_with_bb, insns); 311418334Speter 311590282Sobrien ggc_collect (); 311652558Sobrien 311718334Speter /* If -opt, try combining insns through substitution. */ 311818334Speter 311918334Speter if (optimize > 0) 312050615Sobrien { 312190282Sobrien int rebuild_jump_labels_after_combine = 0; 312252558Sobrien 312390282Sobrien timevar_push (TV_COMBINE); 312490282Sobrien open_dump_file (DFI_combine, decl); 312552558Sobrien 312690282Sobrien rebuild_jump_labels_after_combine 312790282Sobrien = combine_instructions (insns, max_reg_num ()); 312890282Sobrien 312990282Sobrien /* Combining insns may have turned an indirect jump into a 313090282Sobrien direct jump. Rebuid the JUMP_LABEL fields of jumping 313190282Sobrien instructions. */ 313290282Sobrien if (rebuild_jump_labels_after_combine) 313352558Sobrien { 313490282Sobrien timevar_push (TV_JUMP); 313590282Sobrien rebuild_jump_labels (insns); 313690282Sobrien timevar_pop (TV_JUMP); 313790282Sobrien 313890282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); 313952558Sobrien } 314090282Sobrien 314190282Sobrien close_dump_file (DFI_combine, print_rtl_with_bb, insns); 314290282Sobrien timevar_pop (TV_COMBINE); 314390282Sobrien 314490282Sobrien ggc_collect (); 314550615Sobrien } 314618334Speter 314790282Sobrien /* Rerun if-conversion, as combine may have simplified things enough to 314890282Sobrien now meet sequence length restrictions. */ 3149117414Skan if (flag_if_conversion) 315090282Sobrien { 315190282Sobrien timevar_push (TV_IFCVT); 3152117414Skan open_dump_file (DFI_ce2, decl); 315390282Sobrien 315490282Sobrien no_new_pseudos = 0; 315590282Sobrien if_convert (1); 315690282Sobrien no_new_pseudos = 1; 315790282Sobrien 3158117414Skan close_dump_file (DFI_ce2, print_rtl_with_bb, insns); 315990282Sobrien timevar_pop (TV_IFCVT); 316090282Sobrien } 316190282Sobrien 316250615Sobrien /* Register allocation pre-pass, to reduce number of moves 316350615Sobrien necessary for two-address machines. */ 316450615Sobrien if (optimize > 0 && (flag_regmove || flag_expensive_optimizations)) 316550615Sobrien { 316690282Sobrien timevar_push (TV_REGMOVE); 316790282Sobrien open_dump_file (DFI_regmove, decl); 316852558Sobrien 316990282Sobrien regmove_optimize (insns, max_reg_num (), rtl_dump_file); 317052558Sobrien 3171117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); 317290282Sobrien close_dump_file (DFI_regmove, print_rtl_with_bb, insns); 317390282Sobrien timevar_pop (TV_REGMOVE); 317490282Sobrien 317590282Sobrien ggc_collect (); 317650615Sobrien } 317718334Speter 317890282Sobrien /* Do unconditional splitting before register allocation to allow machine 317990282Sobrien description to add extra information not needed previously. */ 318090282Sobrien split_all_insns (1); 318190282Sobrien 318290282Sobrien /* Any of the several passes since flow1 will have munged register 318390282Sobrien lifetime data a bit. */ 318490282Sobrien register_life_up_to_date = 0; 318590282Sobrien 318690282Sobrien#ifdef OPTIMIZE_MODE_SWITCHING 318790282Sobrien timevar_push (TV_MODE_SWITCH); 318890282Sobrien 318990282Sobrien no_new_pseudos = 0; 3190117414Skan optimize_mode_switching (NULL); 319190282Sobrien no_new_pseudos = 1; 319290282Sobrien 319390282Sobrien timevar_pop (TV_MODE_SWITCH); 319490282Sobrien#endif 319590282Sobrien 319690282Sobrien timevar_push (TV_SCHED); 319790282Sobrien 319890282Sobrien#ifdef INSN_SCHEDULING 319990282Sobrien 320018334Speter /* Print function header into sched dump now 320118334Speter because doing the sched analysis makes some of the dump. */ 320218334Speter if (optimize > 0 && flag_schedule_insns) 320318334Speter { 320490282Sobrien open_dump_file (DFI_sched, decl); 320552558Sobrien 320618334Speter /* Do control and data sched analysis, 320718334Speter and write some of the results to dump file. */ 320818334Speter 320990282Sobrien schedule_insns (rtl_dump_file); 321052558Sobrien 321190282Sobrien close_dump_file (DFI_sched, print_rtl_with_bb, insns); 321252558Sobrien 321390282Sobrien /* Register lifetime information was updated as part of verifying 321490282Sobrien the schedule. */ 321590282Sobrien register_life_up_to_date = 1; 321618334Speter } 321790282Sobrien#endif 321890282Sobrien timevar_pop (TV_SCHED); 321918334Speter 322090282Sobrien ggc_collect (); 322190282Sobrien 322252558Sobrien /* Determine if the current function is a leaf before running reload 322352558Sobrien since this can impact optimizations done by the prologue and 322452558Sobrien epilogue thus changing register elimination offsets. */ 322552558Sobrien current_function_is_leaf = leaf_function_p (); 322652558Sobrien 322790282Sobrien timevar_push (TV_LOCAL_ALLOC); 322890282Sobrien open_dump_file (DFI_lreg, decl); 322918334Speter 323090282Sobrien /* Allocate pseudo-regs that are used only within 1 basic block. 323190282Sobrien 323252558Sobrien RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the 323352558Sobrien jump optimizer after register allocation and reloading are finished. */ 323452558Sobrien 323590282Sobrien if (! register_life_up_to_date) 323690282Sobrien recompute_reg_usage (insns, ! optimize_size); 323718334Speter 3238117414Skan if (flag_new_regalloc) 3239117414Skan { 3240117414Skan delete_trivially_dead_insns (insns, max_reg_num ()); 3241117414Skan reg_alloc (); 324218334Speter 3243117414Skan timevar_pop (TV_LOCAL_ALLOC); 3244117414Skan if (dump_file[DFI_lreg].enabled) 3245117414Skan { 3246117414Skan timevar_push (TV_DUMP); 324790282Sobrien 3248117414Skan close_dump_file (DFI_lreg, NULL, NULL); 3249117414Skan timevar_pop (TV_DUMP); 3250117414Skan } 325190282Sobrien 3252117414Skan /* XXX clean up the whole mess to bring live info in shape again. */ 3253117414Skan timevar_push (TV_GLOBAL_ALLOC); 3254117414Skan open_dump_file (DFI_greg, decl); 325590282Sobrien 3256117414Skan build_insn_chain (insns); 3257117414Skan failure = reload (insns, 0); 325890282Sobrien 3259117414Skan timevar_pop (TV_GLOBAL_ALLOC); 326052558Sobrien 3261117414Skan if (dump_file[DFI_greg].enabled) 3262117414Skan { 3263117414Skan timevar_push (TV_DUMP); 326452558Sobrien 3265117414Skan dump_global_regs (rtl_dump_file); 3266117414Skan 3267117414Skan close_dump_file (DFI_greg, print_rtl_with_bb, insns); 3268117414Skan timevar_pop (TV_DUMP); 3269117414Skan } 3270117414Skan 3271117414Skan if (failure) 3272117414Skan goto exit_rest_of_compilation; 3273117414Skan reload_completed = 1; 3274117414Skan rebuild_label_notes_after_reload = 0; 327550615Sobrien } 3276117414Skan else 3277117414Skan { 3278117414Skan /* Allocate the reg_renumber array. */ 3279117414Skan allocate_reg_info (max_regno, FALSE, TRUE); 328018334Speter 3281117414Skan /* And the reg_equiv_memory_loc array. */ 3282117414Skan reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx)); 328318334Speter 3284117414Skan allocate_initial_values (reg_equiv_memory_loc); 328518334Speter 3286117414Skan regclass (insns, max_reg_num (), rtl_dump_file); 3287117414Skan rebuild_label_notes_after_reload = local_alloc (); 328818334Speter 3289117414Skan timevar_pop (TV_LOCAL_ALLOC); 329018334Speter 3291117414Skan if (dump_file[DFI_lreg].enabled) 3292117414Skan { 3293117414Skan timevar_push (TV_DUMP); 329490282Sobrien 3295117414Skan dump_flow_info (rtl_dump_file); 3296117414Skan dump_local_alloc (rtl_dump_file); 329790282Sobrien 3298117414Skan close_dump_file (DFI_lreg, print_rtl_with_bb, insns); 3299117414Skan timevar_pop (TV_DUMP); 3300117414Skan } 330190282Sobrien 3302117414Skan ggc_collect (); 3303117414Skan 3304117414Skan timevar_push (TV_GLOBAL_ALLOC); 3305117414Skan open_dump_file (DFI_greg, decl); 3306117414Skan 3307117414Skan /* If optimizing, allocate remaining pseudo-regs. Do the reload 3308117414Skan pass fixing up any insns that are invalid. */ 3309117414Skan 3310117414Skan if (optimize) 3311117414Skan failure = global_alloc (rtl_dump_file); 3312117414Skan else 3313117414Skan { 3314117414Skan build_insn_chain (insns); 3315117414Skan failure = reload (insns, 0); 3316117414Skan } 3317117414Skan 3318117414Skan timevar_pop (TV_GLOBAL_ALLOC); 3319117414Skan 3320117414Skan if (dump_file[DFI_greg].enabled) 3321117414Skan { 3322117414Skan timevar_push (TV_DUMP); 3323117414Skan 3324117414Skan dump_global_regs (rtl_dump_file); 3325117414Skan 3326117414Skan close_dump_file (DFI_greg, print_rtl_with_bb, insns); 3327117414Skan timevar_pop (TV_DUMP); 3328117414Skan } 3329117414Skan 3330117414Skan if (failure) 3331117414Skan goto exit_rest_of_compilation; 333290282Sobrien } 333390282Sobrien 333490282Sobrien ggc_collect (); 333590282Sobrien 333690282Sobrien open_dump_file (DFI_postreload, decl); 333790282Sobrien 333850615Sobrien /* Do a very simple CSE pass over just the hard registers. */ 333950615Sobrien if (optimize > 0) 334090282Sobrien { 334190282Sobrien timevar_push (TV_RELOAD_CSE_REGS); 334290282Sobrien reload_cse_regs (insns); 334390282Sobrien timevar_pop (TV_RELOAD_CSE_REGS); 334490282Sobrien } 334550615Sobrien 334652558Sobrien /* Register allocation and reloading may have turned an indirect jump into 334752558Sobrien a direct jump. If so, we must rebuild the JUMP_LABEL fields of 334852558Sobrien jumping instructions. */ 334952558Sobrien if (rebuild_label_notes_after_reload) 335090282Sobrien { 335190282Sobrien timevar_push (TV_JUMP); 335252558Sobrien 335390282Sobrien rebuild_jump_labels (insns); 3354117414Skan purge_all_dead_edges (0); 335552558Sobrien 335690282Sobrien timevar_pop (TV_JUMP); 335790282Sobrien } 335852558Sobrien 335990282Sobrien close_dump_file (DFI_postreload, print_rtl_with_bb, insns); 336052558Sobrien 336190282Sobrien /* Re-create the death notes which were deleted during reload. */ 336290282Sobrien timevar_push (TV_FLOW2); 336390282Sobrien open_dump_file (DFI_flow2, decl); 336452558Sobrien 336590282Sobrien#ifdef ENABLE_CHECKING 336690282Sobrien verify_flow_info (); 336790282Sobrien#endif 336852558Sobrien 336990282Sobrien /* If optimizing, then go ahead and split insns now. */ 3370117414Skan#ifndef STACK_REGS 337190282Sobrien if (optimize > 0) 3372117414Skan#endif 337390282Sobrien split_all_insns (0); 337452558Sobrien 3375117414Skan if (optimize) 3376117414Skan cleanup_cfg (CLEANUP_EXPENSIVE); 337752558Sobrien 337890282Sobrien /* On some machines, the prologue and epilogue code, or parts thereof, 337990282Sobrien can be represented as RTL. Doing so lets us schedule insns between 338090282Sobrien it and the rest of the code and also allows delayed branch 338190282Sobrien scheduling to operate in the epilogue. */ 338290282Sobrien thread_prologue_and_epilogue_insns (insns); 338390282Sobrien 338452558Sobrien if (optimize) 338552558Sobrien { 338690282Sobrien life_analysis (insns, rtl_dump_file, PROP_FINAL); 3387117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE 3388117414Skan | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); 338990282Sobrien 339090282Sobrien /* This is kind of a heuristic. We need to run combine_stack_adjustments 339190282Sobrien even for machines with possibly nonzero RETURN_POPS_ARGS 339290282Sobrien and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having 339390282Sobrien push instructions will have popping returns. */ 339490282Sobrien#ifndef PUSH_ROUNDING 339590282Sobrien if (!ACCUMULATE_OUTGOING_ARGS) 339690282Sobrien#endif 339790282Sobrien combine_stack_adjustments (); 339890282Sobrien 339990282Sobrien ggc_collect (); 340052558Sobrien } 340152558Sobrien 340252558Sobrien flow2_completed = 1; 340352558Sobrien 340490282Sobrien close_dump_file (DFI_flow2, print_rtl_with_bb, insns); 340590282Sobrien timevar_pop (TV_FLOW2); 340618334Speter 340790282Sobrien#ifdef HAVE_peephole2 340890282Sobrien if (optimize > 0 && flag_peephole2) 340990282Sobrien { 341090282Sobrien timevar_push (TV_PEEPHOLE2); 341190282Sobrien open_dump_file (DFI_peephole2, decl); 341218334Speter 341390282Sobrien peephole2_optimize (rtl_dump_file); 341490282Sobrien 341590282Sobrien close_dump_file (DFI_peephole2, print_rtl_with_bb, insns); 341690282Sobrien timevar_pop (TV_PEEPHOLE2); 341790282Sobrien } 341890282Sobrien#endif 341990282Sobrien 342096289Sobrien if (optimize > 0 && (flag_rename_registers || flag_cprop_registers)) 342150615Sobrien { 342290282Sobrien timevar_push (TV_RENAME_REGISTERS); 342390282Sobrien open_dump_file (DFI_rnreg, decl); 342490282Sobrien 342590282Sobrien if (flag_rename_registers) 3426117414Skan regrename_optimize (); 342790282Sobrien if (flag_cprop_registers) 3428117414Skan copyprop_hardreg_forward (); 342990282Sobrien 343090282Sobrien close_dump_file (DFI_rnreg, print_rtl_with_bb, insns); 343190282Sobrien timevar_pop (TV_RENAME_REGISTERS); 343250615Sobrien } 343352558Sobrien 3434117414Skan if (flag_if_conversion2) 343590282Sobrien { 343690282Sobrien timevar_push (TV_IFCVT2); 3437117414Skan open_dump_file (DFI_ce3, decl); 343890282Sobrien 343990282Sobrien if_convert (1); 344090282Sobrien 3441117414Skan close_dump_file (DFI_ce3, print_rtl_with_bb, insns); 344290282Sobrien timevar_pop (TV_IFCVT2); 344390282Sobrien } 344490282Sobrien 344590282Sobrien#ifdef INSN_SCHEDULING 344618334Speter if (optimize > 0 && flag_schedule_insns_after_reload) 344718334Speter { 344890282Sobrien timevar_push (TV_SCHED2); 344990282Sobrien open_dump_file (DFI_sched2, decl); 345018334Speter 345118334Speter /* Do control and data sched analysis again, 345218334Speter and write some more of the results to dump file. */ 345318334Speter 345490282Sobrien split_all_insns (1); 345518334Speter 345690282Sobrien schedule_insns (rtl_dump_file); 345718334Speter 345890282Sobrien close_dump_file (DFI_sched2, print_rtl_with_bb, insns); 345990282Sobrien timevar_pop (TV_SCHED2); 346090282Sobrien 346190282Sobrien ggc_collect (); 346218334Speter } 346390282Sobrien#endif 346418334Speter 346518334Speter#ifdef LEAF_REGISTERS 346652558Sobrien current_function_uses_only_leaf_regs 346752558Sobrien = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); 346818334Speter#endif 346918334Speter 347090282Sobrien#ifdef STACK_REGS 347190282Sobrien timevar_push (TV_REG_STACK); 347290282Sobrien open_dump_file (DFI_stack, decl); 347318334Speter 347490282Sobrien reg_to_stack (insns, rtl_dump_file); 347590282Sobrien 347690282Sobrien close_dump_file (DFI_stack, print_rtl_with_bb, insns); 347790282Sobrien timevar_pop (TV_REG_STACK); 347890282Sobrien 347990282Sobrien ggc_collect (); 348090282Sobrien#endif 348118334Speter if (optimize > 0) 348218334Speter { 348390282Sobrien timevar_push (TV_REORDER_BLOCKS); 348490282Sobrien open_dump_file (DFI_bbro, decl); 348552558Sobrien 3486117414Skan /* Last attempt to optimize CFG, as scheduling, peepholing and insn 3487117414Skan splitting possibly introduced more crossjumping oppurtuntities. 3488117414Skan Except that we can't actually run crossjumping without running 3489117414Skan another DCE pass, which we can't do after reg-stack. */ 3490117414Skan cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK 3491117414Skan | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); 349290282Sobrien if (flag_reorder_blocks) 349352558Sobrien { 349490282Sobrien reorder_basic_blocks (); 349590282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK); 349652558Sobrien } 349790282Sobrien 349890282Sobrien close_dump_file (DFI_bbro, print_rtl_with_bb, insns); 349990282Sobrien timevar_pop (TV_REORDER_BLOCKS); 350018334Speter } 350190282Sobrien compute_alignments (); 350218334Speter 350390282Sobrien /* CFG is no longer maintained up-to-date. */ 350490282Sobrien free_bb_for_insn (); 350590282Sobrien 350618334Speter /* If a machine dependent reorganization is needed, call it. */ 350718334Speter#ifdef MACHINE_DEPENDENT_REORG 350890282Sobrien timevar_push (TV_MACH_DEP); 350990282Sobrien open_dump_file (DFI_mach, decl); 351050615Sobrien 351190282Sobrien MACHINE_DEPENDENT_REORG (insns); 351290282Sobrien 351390282Sobrien close_dump_file (DFI_mach, print_rtl, insns); 351490282Sobrien timevar_pop (TV_MACH_DEP); 351590282Sobrien 351690282Sobrien ggc_collect (); 351718334Speter#endif 351818334Speter 351990282Sobrien purge_line_number_notes (insns); 352090282Sobrien cleanup_barriers (); 352190282Sobrien 352218334Speter /* If a scheduling pass for delayed branches is to be done, 352350615Sobrien call the scheduling code. */ 352418334Speter 352518334Speter#ifdef DELAY_SLOTS 352618334Speter if (optimize > 0 && flag_delayed_branch) 352718334Speter { 352890282Sobrien timevar_push (TV_DBR_SCHED); 352990282Sobrien open_dump_file (DFI_dbr, decl); 353052558Sobrien 353190282Sobrien dbr_schedule (insns, rtl_dump_file); 353252558Sobrien 353390282Sobrien close_dump_file (DFI_dbr, print_rtl, insns); 353490282Sobrien timevar_pop (TV_DBR_SCHED); 353590282Sobrien 353690282Sobrien ggc_collect (); 353718334Speter } 353818334Speter#endif 353918334Speter 354090282Sobrien#if defined (HAVE_ATTR_length) && !defined (STACK_REGS) 354190282Sobrien timevar_push (TV_SHORTEN_BRANCH); 354290282Sobrien split_all_insns_noflow (); 354390282Sobrien timevar_pop (TV_SHORTEN_BRANCH); 354490282Sobrien#endif 354590282Sobrien 354690282Sobrien convert_to_eh_region_ranges (); 354790282Sobrien 354818334Speter /* Shorten branches. */ 354990282Sobrien timevar_push (TV_SHORTEN_BRANCH); 355090282Sobrien shorten_branches (get_insns ()); 355190282Sobrien timevar_pop (TV_SHORTEN_BRANCH); 355218334Speter 3553117414Skan set_nothrow_function_flags (); 355490282Sobrien if (current_function_nothrow) 355590282Sobrien /* Now we know that this can't throw; set the flag for the benefit 355690282Sobrien of other functions later in this translation unit. */ 355790282Sobrien TREE_NOTHROW (current_function_decl) = 1; 355852558Sobrien 355990282Sobrien /* Now turn the rtl into assembler code. */ 356050615Sobrien 356190282Sobrien timevar_push (TV_FINAL); 356290282Sobrien { 356390282Sobrien rtx x; 356490282Sobrien const char *fnname; 356590282Sobrien 356690282Sobrien /* Get the function's name, as described by its RTL. This may be 356790282Sobrien different from the DECL_NAME name used in the source file. */ 356890282Sobrien 356990282Sobrien x = DECL_RTL (decl); 357090282Sobrien if (GET_CODE (x) != MEM) 357190282Sobrien abort (); 357290282Sobrien x = XEXP (x, 0); 357390282Sobrien if (GET_CODE (x) != SYMBOL_REF) 357490282Sobrien abort (); 357590282Sobrien fnname = XSTR (x, 0); 357690282Sobrien 357790282Sobrien assemble_start_function (decl, fnname); 357890282Sobrien final_start_function (insns, asm_out_file, optimize); 357990282Sobrien final (insns, asm_out_file, optimize, 0); 358090282Sobrien final_end_function (); 358190282Sobrien 358290282Sobrien#ifdef IA64_UNWIND_INFO 358390282Sobrien /* ??? The IA-64 ".handlerdata" directive must be issued before 358490282Sobrien the ".endp" directive that closes the procedure descriptor. */ 358590282Sobrien output_function_exception_table (); 358618334Speter#endif 358718334Speter 358890282Sobrien assemble_end_function (decl, fnname); 358918334Speter 359090282Sobrien#ifndef IA64_UNWIND_INFO 359190282Sobrien /* Otherwise, it feels unclean to switch sections in the middle. */ 359290282Sobrien output_function_exception_table (); 359390282Sobrien#endif 359418334Speter 359590282Sobrien if (! quiet_flag) 359690282Sobrien fflush (asm_out_file); 359718334Speter 359890282Sobrien /* Release all memory allocated by flow. */ 359990282Sobrien free_basic_block_vars (0); 360018334Speter 360190282Sobrien /* Release all memory held by regsets now. */ 360290282Sobrien regset_release_memory (); 360390282Sobrien } 360490282Sobrien timevar_pop (TV_FINAL); 360550615Sobrien 360690282Sobrien ggc_collect (); 360752558Sobrien 360890282Sobrien /* Write DBX symbols if requested. */ 360918334Speter 361018334Speter /* Note that for those inline functions where we don't initially 361118334Speter know for certain that we will be generating an out-of-line copy, 361218334Speter the first invocation of this routine (rest_of_compilation) will 361318334Speter skip over this code by doing a `goto exit_rest_of_compilation;'. 3614117414Skan Later on, wrapup_global_declarations will (indirectly) call 3615117414Skan rest_of_compilation again for those inline functions that need 3616117414Skan to have out-of-line copies generated. During that call, we 3617117414Skan *will* be routed past here. */ 361818334Speter 361990282Sobrien timevar_push (TV_SYMOUT); 362090282Sobrien (*debug_hooks->function_decl) (decl); 362190282Sobrien timevar_pop (TV_SYMOUT); 362218334Speter 362318334Speter exit_rest_of_compilation: 362418334Speter 362518334Speter /* In case the function was not output, 362618334Speter don't leave any temporary anonymous types 362718334Speter queued up for sdb output. */ 362818334Speter#ifdef SDB_DEBUGGING_INFO 362918334Speter if (write_symbols == SDB_DEBUG) 363018334Speter sdbout_types (NULL_TREE); 363118334Speter#endif 363218334Speter 363318334Speter reload_completed = 0; 363452558Sobrien flow2_completed = 0; 363552558Sobrien no_new_pseudos = 0; 363618334Speter 363790282Sobrien timevar_push (TV_FINAL); 363818334Speter 363990282Sobrien /* Clear out the insn_length contents now that they are no 364090282Sobrien longer valid. */ 364190282Sobrien init_insn_lengths (); 364218334Speter 364390282Sobrien /* Show no temporary slots allocated. */ 364490282Sobrien init_temp_slots (); 364518334Speter 364690282Sobrien free_basic_block_vars (0); 364790282Sobrien free_bb_for_insn (); 364890282Sobrien 364990282Sobrien timevar_pop (TV_FINAL); 365090282Sobrien 365150615Sobrien /* Make sure volatile mem refs aren't considered valid operands for 365250615Sobrien arithmetic insns. We must call this here if this is a nested inline 365350615Sobrien function, since the above code leaves us in the init_recog state 365450615Sobrien (from final.c), and the function context push/pop code does not 365550615Sobrien save/restore volatile_ok. 365618334Speter 365750615Sobrien ??? Maybe it isn't necessary for expand_start_function to call this 365850615Sobrien anymore if we do it here? */ 365950615Sobrien 366050615Sobrien init_recog_no_volatile (); 366150615Sobrien 366290282Sobrien /* We're done with this function. Free up memory if we can. */ 366390282Sobrien free_after_parsing (cfun); 366490282Sobrien if (! DECL_DEFER_OUTPUT (decl)) 366590282Sobrien { 366690282Sobrien free_after_compilation (cfun); 366718334Speter 366890282Sobrien /* Clear integrate.c's pointer to the cfun structure we just 366990282Sobrien destroyed. */ 367090282Sobrien DECL_SAVED_INSNS (decl) = 0; 367190282Sobrien } 367290282Sobrien cfun = 0; 367352558Sobrien 367490282Sobrien ggc_collect (); 367590282Sobrien 367690282Sobrien timevar_pop (TV_REST_OF_COMPILATION); 367718334Speter} 367818334Speter 367950615Sobrienstatic void 368050615Sobriendisplay_help () 368150615Sobrien{ 368290282Sobrien int undoc; 368390282Sobrien unsigned long i; 368490282Sobrien const char *lang; 368550615Sobrien 368690282Sobrien printf (_(" -ffixed-<register> Mark <register> as being unavailable to the compiler\n")); 368790282Sobrien printf (_(" -fcall-used-<register> Mark <register> as being corrupted by function calls\n")); 368890282Sobrien printf (_(" -fcall-saved-<register> Mark <register> as being preserved across functions\n")); 368990282Sobrien printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n")); 369090282Sobrien printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n")); 369190282Sobrien printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n")); 3692117414Skan printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n")); 3693117414Skan printf (_(" -fstack-limit-register=<register> Trap if the stack goes past <register>\n")); 3694117414Skan printf (_(" -fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>\n")); 3695117414Skan printf (_(" -frandom-seed=<string> Make compile reproducible using <string>\n")); 3696117414Skan 369790282Sobrien 369890282Sobrien for (i = ARRAY_SIZE (f_options); i--;) 369950615Sobrien { 370090282Sobrien const char *description = f_options[i].description; 370190282Sobrien 3702117414Skan if (description != NULL && *description != 0) 370350615Sobrien printf (" -f%-21s %s\n", 370490282Sobrien f_options[i].string, _(description)); 370550615Sobrien } 370690282Sobrien 370790282Sobrien printf (_(" -O[number] Set optimization level to [number]\n")); 370890282Sobrien printf (_(" -Os Optimize for space rather than speed\n")); 370990282Sobrien for (i = LAST_PARAM; i--;) 371050615Sobrien { 371190282Sobrien const char *description = compiler_params[i].help; 3712117414Skan const int length = 21 - strlen (compiler_params[i].option); 371390282Sobrien 3714117414Skan if (description != NULL && *description != 0) 371590282Sobrien printf (" --param %s=<value>%.*s%s\n", 371690282Sobrien compiler_params[i].option, 371790282Sobrien length > 0 ? length : 1, " ", 371890282Sobrien _(description)); 371990282Sobrien } 372090282Sobrien printf (_(" -pedantic Issue warnings needed by strict compliance to ISO C\n")); 372190282Sobrien printf (_(" -pedantic-errors Like -pedantic except that errors are produced\n")); 372290282Sobrien printf (_(" -w Suppress warnings\n")); 372390282Sobrien printf (_(" -W Enable extra warnings\n")); 372490282Sobrien 372590282Sobrien for (i = ARRAY_SIZE (W_options); i--;) 372690282Sobrien { 372790282Sobrien const char *description = W_options[i].description; 372890282Sobrien 3729117414Skan if (description != NULL && *description != 0) 373050615Sobrien printf (" -W%-21s %s\n", 373190282Sobrien W_options[i].string, _(description)); 373250615Sobrien } 373390282Sobrien 373490282Sobrien printf (_(" -Wunused Enable unused warnings\n")); 373590282Sobrien printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n")); 373690282Sobrien printf (_(" -p Enable function profiling\n")); 373790282Sobrien printf (_(" -o <file> Place output into <file> \n")); 373890282Sobrien printf (_("\ 373990282Sobrien -G <number> Put global and static data smaller than <number>\n\ 374090282Sobrien bytes into a special section (on some targets)\n")); 374190282Sobrien 374290282Sobrien for (i = ARRAY_SIZE (debug_args); i--;) 374350615Sobrien { 374450615Sobrien if (debug_args[i].description != NULL) 374590282Sobrien printf (" -g%-21s %s\n", 374690282Sobrien debug_args[i].arg, _(debug_args[i].description)); 374750615Sobrien } 374890282Sobrien 374990282Sobrien printf (_(" -aux-info <file> Emit declaration info into <file>\n")); 375090282Sobrien printf (_(" -quiet Do not display functions compiled or elapsed time\n")); 375190282Sobrien printf (_(" -version Display the compiler's version\n")); 375290282Sobrien printf (_(" -d[letters] Enable dumps from specific passes of the compiler\n")); 375390282Sobrien printf (_(" -dumpbase <file> Base name to be used for dumps from specific passes\n")); 375490282Sobrien#if defined INSN_SCHEDULING 375590282Sobrien printf (_(" -fsched-verbose=<number> Set the verbosity level of the scheduler\n")); 375650615Sobrien#endif 375790282Sobrien printf (_(" --help Display this information\n")); 375850615Sobrien 375950615Sobrien undoc = 0; 376050615Sobrien lang = "language"; 376190282Sobrien 376250615Sobrien /* Display descriptions of language specific options. 376350615Sobrien If there is no description, note that there is an undocumented option. 376450615Sobrien If the description is empty, do not display anything. (This allows 376550615Sobrien options to be deliberately undocumented, for whatever reason). 376650615Sobrien If the option string is missing, then this is a marker, indicating 376752558Sobrien that the description string is in fact the name of a language, whose 376850615Sobrien language specific options are to follow. */ 376990282Sobrien 377090282Sobrien if (ARRAY_SIZE (documented_lang_options) > 1) 377150615Sobrien { 377290282Sobrien printf (_("\nLanguage specific options:\n")); 377350615Sobrien 377490282Sobrien for (i = 0; i < ARRAY_SIZE (documented_lang_options); i++) 377550615Sobrien { 377690282Sobrien const char *description = documented_lang_options[i].description; 377790282Sobrien const char *option = documented_lang_options[i].option; 377850615Sobrien 377950615Sobrien if (description == NULL) 378052558Sobrien { 378152558Sobrien undoc = 1; 378252558Sobrien 378352558Sobrien if (extra_warnings) 378490282Sobrien printf (_(" %-23.23s [undocumented]\n"), option); 378552558Sobrien } 378690282Sobrien else if (*description == 0) 378750615Sobrien continue; 378850615Sobrien else if (option == NULL) 378950615Sobrien { 379050615Sobrien if (undoc) 379150615Sobrien printf 379290282Sobrien (_("\nThere are undocumented %s specific options as well.\n"), 379350615Sobrien lang); 379450615Sobrien undoc = 0; 379550615Sobrien 379690282Sobrien printf (_("\n Options for %s:\n"), description); 379790282Sobrien 379850615Sobrien lang = description; 379950615Sobrien } 380050615Sobrien else 380190282Sobrien printf (" %-23.23s %s\n", option, _(description)); 380250615Sobrien } 380350615Sobrien } 380450615Sobrien 380550615Sobrien if (undoc) 380690282Sobrien printf (_("\nThere are undocumented %s specific options as well.\n"), 380790282Sobrien lang); 380850615Sobrien 380990282Sobrien display_target_options (); 381090282Sobrien} 381190282Sobrien 381290282Sobrienstatic void 381390282Sobriendisplay_target_options () 381490282Sobrien{ 381590282Sobrien int undoc, i; 381690282Sobrien static bool displayed = false; 381790282Sobrien 381890282Sobrien /* Avoid double printing for --help --target-help. */ 381990282Sobrien if (displayed) 382090282Sobrien return; 382190282Sobrien displayed = true; 382290282Sobrien 382390282Sobrien if (ARRAY_SIZE (target_switches) > 1 382450615Sobrien#ifdef TARGET_OPTIONS 382590282Sobrien || ARRAY_SIZE (target_options) > 1 382650615Sobrien#endif 382750615Sobrien ) 382850615Sobrien { 382950615Sobrien int doc = 0; 383090282Sobrien 383150615Sobrien undoc = 0; 383250615Sobrien 383390282Sobrien printf (_("\nTarget specific options:\n")); 383490282Sobrien 383590282Sobrien for (i = ARRAY_SIZE (target_switches); i--;) 383650615Sobrien { 383790282Sobrien const char *option = target_switches[i].name; 383890282Sobrien const char *description = target_switches[i].description; 383950615Sobrien 384090282Sobrien if (option == NULL || *option == 0) 384150615Sobrien continue; 384250615Sobrien else if (description == NULL) 384352558Sobrien { 384452558Sobrien undoc = 1; 384590282Sobrien 384652558Sobrien if (extra_warnings) 384790282Sobrien printf (_(" -m%-23.23s [undocumented]\n"), option); 384852558Sobrien } 3849117414Skan else if (*description != 0) 385090282Sobrien doc += printf (" -m%-23.23s %s\n", option, _(description)); 385150615Sobrien } 385290282Sobrien 385390282Sobrien#ifdef TARGET_OPTIONS 385490282Sobrien for (i = ARRAY_SIZE (target_options); i--;) 385550615Sobrien { 385690282Sobrien const char *option = target_options[i].prefix; 385790282Sobrien const char *description = target_options[i].description; 385850615Sobrien 385990282Sobrien if (option == NULL || *option == 0) 386050615Sobrien continue; 386150615Sobrien else if (description == NULL) 386252558Sobrien { 386352558Sobrien undoc = 1; 386490282Sobrien 386552558Sobrien if (extra_warnings) 386690282Sobrien printf (_(" -m%-23.23s [undocumented]\n"), option); 386752558Sobrien } 3868117414Skan else if (*description != 0) 386990282Sobrien doc += printf (" -m%-23.23s %s\n", option, _(description)); 387050615Sobrien } 387150615Sobrien#endif 387250615Sobrien if (undoc) 387352558Sobrien { 387452558Sobrien if (doc) 387590282Sobrien printf (_("\nThere are undocumented target specific options as well.\n")); 387652558Sobrien else 387790282Sobrien printf (_(" They exist, but they are not documented.\n")); 387852558Sobrien } 387950615Sobrien } 388050615Sobrien} 388190282Sobrien 388290282Sobrien/* Parse a -d... command line switch. */ 388350615Sobrien 388490282Sobrienstatic void 388590282Sobriendecode_d_option (arg) 388690282Sobrien const char *arg; 388790282Sobrien{ 388890282Sobrien int i, c, matched; 388950615Sobrien 389090282Sobrien while (*arg) 389190282Sobrien switch (c = *arg++) 389290282Sobrien { 389390282Sobrien case 'a': 389490282Sobrien for (i = 0; i < (int) DFI_MAX; ++i) 389590282Sobrien dump_file[i].enabled = 1; 389690282Sobrien break; 389790282Sobrien case 'A': 389890282Sobrien flag_debug_asm = 1; 389990282Sobrien break; 390090282Sobrien case 'p': 390190282Sobrien flag_print_asm_name = 1; 390290282Sobrien break; 390390282Sobrien case 'P': 3904117414Skan flag_dump_rtl_in_asm = 1; 3905117414Skan flag_print_asm_name = 1; 3906117414Skan break; 390790282Sobrien case 'v': 390890282Sobrien graph_dump_format = vcg; 390990282Sobrien break; 391090282Sobrien case 'x': 391190282Sobrien rtl_dump_and_exit = 1; 391290282Sobrien break; 391390282Sobrien case 'y': 3914117414Skan set_yydebug = 1; 391590282Sobrien break; 391690282Sobrien case 'D': /* These are handled by the preprocessor. */ 391790282Sobrien case 'I': 391890282Sobrien break; 391990282Sobrien 392090282Sobrien default: 392190282Sobrien matched = 0; 392290282Sobrien for (i = 0; i < (int) DFI_MAX; ++i) 392390282Sobrien if (c == dump_file[i].debug_switch) 392490282Sobrien { 392590282Sobrien dump_file[i].enabled = 1; 392690282Sobrien matched = 1; 392790282Sobrien } 392890282Sobrien 392990282Sobrien if (! matched) 393090282Sobrien warning ("unrecognized gcc debugging option: %c", c); 393190282Sobrien break; 393290282Sobrien } 393390282Sobrien} 393490282Sobrien 393590282Sobrien/* Parse a -f... command line switch. ARG is the value after the -f. 393690282Sobrien It is safe to access 'ARG - 2' to generate the full switch name. 393790282Sobrien Return the number of strings consumed. */ 393890282Sobrien 393950615Sobrienstatic int 394090282Sobriendecode_f_option (arg) 394190282Sobrien const char *arg; 394250615Sobrien{ 394390282Sobrien int j; 394490282Sobrien const char *option_value = NULL; 394550615Sobrien 394690282Sobrien /* Search for the option in the table of binary f options. */ 394790282Sobrien for (j = ARRAY_SIZE (f_options); j--;) 394850615Sobrien { 394990282Sobrien if (!strcmp (arg, f_options[j].string)) 395050615Sobrien { 395190282Sobrien *f_options[j].variable = f_options[j].on_value; 395290282Sobrien return 1; 395350615Sobrien } 395490282Sobrien 395590282Sobrien if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-' 395690282Sobrien && ! strcmp (arg + 3, f_options[j].string)) 395790282Sobrien { 395890282Sobrien *f_options[j].variable = ! f_options[j].on_value; 395990282Sobrien return 1; 396090282Sobrien } 396150615Sobrien } 396218334Speter 396390282Sobrien if (!strcmp (arg, "fast-math")) 3964117414Skan set_fast_math_flags (1); 396590282Sobrien else if (!strcmp (arg, "no-fast-math")) 3966117414Skan set_fast_math_flags (0); 396790282Sobrien else if ((option_value = skip_leading_substring (arg, "inline-limit-")) 396890282Sobrien || (option_value = skip_leading_substring (arg, "inline-limit="))) 396990282Sobrien { 397090282Sobrien int val = 397190282Sobrien read_integral_parameter (option_value, arg - 2, 397290282Sobrien MAX_INLINE_INSNS); 397390282Sobrien set_param_value ("max-inline-insns", val); 3974117414Skan set_param_value ("max-inline-insns-single", val/2); 3975117414Skan set_param_value ("max-inline-insns-auto", val/2); 3976117414Skan set_param_value ("max-inline-insns-rtl", val); 3977117414Skan if (val/4 < MIN_INLINE_INSNS) 3978117414Skan { 3979117414Skan if (val/4 > 10) 3980117414Skan set_param_value ("min-inline-insns", val/4); 3981117414Skan else 3982117414Skan set_param_value ("min-inline-insns", 10); 3983117414Skan } 398490282Sobrien } 3985117414Skan else if ((option_value = skip_leading_substring (arg, "tls-model="))) 3986117414Skan { 3987117414Skan if (strcmp (option_value, "global-dynamic") == 0) 3988117414Skan flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC; 3989117414Skan else if (strcmp (option_value, "local-dynamic") == 0) 3990117414Skan flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC; 3991117414Skan else if (strcmp (option_value, "initial-exec") == 0) 3992117414Skan flag_tls_default = TLS_MODEL_INITIAL_EXEC; 3993117414Skan else if (strcmp (option_value, "local-exec") == 0) 3994117414Skan flag_tls_default = TLS_MODEL_LOCAL_EXEC; 3995117414Skan else 3996117414Skan warning ("`%s': unknown tls-model option", arg - 2); 3997117414Skan } 399890282Sobrien#ifdef INSN_SCHEDULING 399990282Sobrien else if ((option_value = skip_leading_substring (arg, "sched-verbose="))) 400090282Sobrien fix_sched_param ("verbose", option_value); 400118334Speter#endif 400290282Sobrien else if ((option_value = skip_leading_substring (arg, "fixed-"))) 400390282Sobrien fix_register (option_value, 1, 1); 400490282Sobrien else if ((option_value = skip_leading_substring (arg, "call-used-"))) 400590282Sobrien fix_register (option_value, 0, 1); 400690282Sobrien else if ((option_value = skip_leading_substring (arg, "call-saved-"))) 400790282Sobrien fix_register (option_value, 0, 0); 400890282Sobrien else if ((option_value = skip_leading_substring (arg, "align-loops="))) 400990282Sobrien align_loops = read_integral_parameter (option_value, arg - 2, align_loops); 401090282Sobrien else if ((option_value = skip_leading_substring (arg, "align-functions="))) 401190282Sobrien align_functions 401290282Sobrien = read_integral_parameter (option_value, arg - 2, align_functions); 401390282Sobrien else if ((option_value = skip_leading_substring (arg, "align-jumps="))) 401490282Sobrien align_jumps = read_integral_parameter (option_value, arg - 2, align_jumps); 401590282Sobrien else if ((option_value = skip_leading_substring (arg, "align-labels="))) 401690282Sobrien align_labels 401790282Sobrien = read_integral_parameter (option_value, arg - 2, align_labels); 401890282Sobrien else if ((option_value 401990282Sobrien = skip_leading_substring (arg, "stack-limit-register="))) 402090282Sobrien { 402190282Sobrien int reg = decode_reg_name (option_value); 402290282Sobrien if (reg < 0) 402390282Sobrien error ("unrecognized register name `%s'", option_value); 402490282Sobrien else 402590282Sobrien stack_limit_rtx = gen_rtx_REG (Pmode, reg); 402690282Sobrien } 402790282Sobrien else if ((option_value 402890282Sobrien = skip_leading_substring (arg, "stack-limit-symbol="))) 402990282Sobrien { 403090282Sobrien const char *nm; 403190282Sobrien nm = ggc_strdup (option_value); 403290282Sobrien stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm); 403390282Sobrien } 403490282Sobrien else if ((option_value 4035117414Skan = skip_leading_substring (arg, "message-length="))) 403690282Sobrien output_set_maximum_length 403790282Sobrien (&global_dc->buffer, read_integral_parameter 403890282Sobrien (option_value, arg - 2, diagnostic_line_cutoff (global_dc))); 403990282Sobrien else if ((option_value 404090282Sobrien = skip_leading_substring (arg, "diagnostics-show-location="))) 404190282Sobrien { 404290282Sobrien if (!strcmp (option_value, "once")) 4043117414Skan diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE; 404490282Sobrien else if (!strcmp (option_value, "every-line")) 4045117414Skan diagnostic_prefixing_rule (global_dc) 4046117414Skan = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; 404790282Sobrien else 404890282Sobrien error ("unrecognized option `%s'", arg - 2); 404990282Sobrien } 405090282Sobrien else if (!strcmp (arg, "no-stack-limit")) 405190282Sobrien stack_limit_rtx = NULL_RTX; 4052117414Skan else if ((option_value = skip_leading_substring (arg, "random-seed="))) 4053117414Skan flag_random_seed = option_value; 4054117414Skan else if (!strcmp (arg, "no-random-seed")) 4055117414Skan flag_random_seed = NULL; 405690282Sobrien else if (!strcmp (arg, "preprocessed")) 4057117414Skan /* Recognize this switch but do nothing. This prevents warnings 405890282Sobrien about an unrecognized switch if cpplib has not been linked in. */ 405990282Sobrien ; 406090282Sobrien else 406190282Sobrien return 0; 406218334Speter 406390282Sobrien return 1; 406490282Sobrien} 406518334Speter 406690282Sobrien/* Parse a -W... command line switch. ARG is the value after the -W. 406790282Sobrien It is safe to access 'ARG - 2' to generate the full switch name. 406890282Sobrien Return the number of strings consumed. */ 406918334Speter 407090282Sobrienstatic int 407190282Sobriendecode_W_option (arg) 407290282Sobrien const char *arg; 407390282Sobrien{ 407490282Sobrien const char *option_value = NULL; 407590282Sobrien int j; 407652558Sobrien 407790282Sobrien /* Search for the option in the table of binary W options. */ 407818334Speter 407990282Sobrien for (j = ARRAY_SIZE (W_options); j--;) 408018334Speter { 408190282Sobrien if (!strcmp (arg, W_options[j].string)) 408218334Speter { 408390282Sobrien *W_options[j].variable = W_options[j].on_value; 408490282Sobrien return 1; 408518334Speter } 408690282Sobrien 408790282Sobrien if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-' 408890282Sobrien && ! strcmp (arg + 3, W_options[j].string)) 408918334Speter { 409090282Sobrien *W_options[j].variable = ! W_options[j].on_value; 409190282Sobrien return 1; 409218334Speter } 409318334Speter } 409418334Speter 409590282Sobrien if ((option_value = skip_leading_substring (arg, "id-clash-"))) 409690282Sobrien warning ("-Wid-clash-LEN is no longer supported"); 409790282Sobrien else if ((option_value = skip_leading_substring (arg, "larger-than-"))) 409890282Sobrien { 409990282Sobrien larger_than_size = read_integral_parameter (option_value, arg - 2, -1); 410018334Speter 410190282Sobrien warn_larger_than = larger_than_size != -1; 410218334Speter } 410390282Sobrien else if (!strcmp (arg, "unused")) 410418334Speter { 410590282Sobrien set_Wunused (1); 410618334Speter } 410790282Sobrien else if (!strcmp (arg, "no-unused")) 410818334Speter { 410990282Sobrien set_Wunused (0); 411018334Speter } 411190282Sobrien else 411290282Sobrien return 0; 411318334Speter 411490282Sobrien return 1; 411590282Sobrien} 411650615Sobrien 411790282Sobrien/* Parse a -g... command line switch. ARG is the value after the -g. 411890282Sobrien It is safe to access 'ARG - 2' to generate the full switch name. 411990282Sobrien Return the number of strings consumed. */ 412018334Speter 412190282Sobrienstatic int 412290282Sobriendecode_g_option (arg) 412390282Sobrien const char *arg; 412490282Sobrien{ 4125117414Skan static unsigned level = 0; 412690282Sobrien /* A lot of code assumes write_symbols == NO_DEBUG if the 412790282Sobrien debugging level is 0 (thus -gstabs1 -gstabs0 would lose track 412890282Sobrien of what debugging type has been selected). This records the 412990282Sobrien selected type. It is an error to specify more than one 413090282Sobrien debugging type. */ 413190282Sobrien static enum debug_info_type selected_debug_type = NO_DEBUG; 413290282Sobrien /* Non-zero if debugging format has been explicitly set. 413390282Sobrien -g and -ggdb don't explicitly set the debugging format so 413490282Sobrien -gdwarf -g3 is equivalent to -gdwarf3. */ 413590282Sobrien static int type_explicitly_set_p = 0; 413690282Sobrien /* Indexed by enum debug_info_type. */ 413790282Sobrien static const char *const debug_type_names[] = 413890282Sobrien { 413990282Sobrien "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms" 414090282Sobrien }; 414118334Speter 414290282Sobrien /* The maximum admissible debug level value. */ 414390282Sobrien static const unsigned max_debug_level = 3; 414490282Sobrien 414590282Sobrien /* Look up ARG in the table. */ 414690282Sobrien for (da = debug_args; da->arg; da++) 414718334Speter { 414890282Sobrien const int da_len = strlen (da->arg); 414990282Sobrien 415090282Sobrien if (da_len == 0 || ! strncmp (arg, da->arg, da_len)) 415150615Sobrien { 415290282Sobrien enum debug_info_type type = da->debug_type; 415390282Sobrien const char *p = arg + da_len; 415418334Speter 415590282Sobrien if (*p && ! ISDIGIT (*p)) 415690282Sobrien continue; 415718334Speter 415890282Sobrien /* A debug flag without a level defaults to level 2. 415990282Sobrien Note we do not want to call read_integral_parameter 416090282Sobrien for that case since it will call atoi which 416190282Sobrien will return zero. 416218334Speter 416390282Sobrien ??? We may want to generalize the interface to 416490282Sobrien read_integral_parameter to better handle this case 416590282Sobrien if this case shows up often. */ 416690282Sobrien if (*p) 416790282Sobrien level = read_integral_parameter (p, 0, max_debug_level + 1); 416890282Sobrien else 416990282Sobrien level = (level == 0) ? 2 : level; 417018334Speter 417190282Sobrien if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len)) 417218334Speter { 417390282Sobrien error ("use -gdwarf -g%d for DWARF v1, level %d", 417490282Sobrien level, level); 417590282Sobrien if (level == 2) 417690282Sobrien error ("use -gdwarf-2 for DWARF v2"); 417718334Speter } 417890282Sobrien 417990282Sobrien if (level > max_debug_level) 418018334Speter { 418190282Sobrien warning ("\ 418290282Sobrienignoring option `%s' due to invalid debug level specification", 418390282Sobrien arg - 2); 418490282Sobrien level = debug_info_level; 418518334Speter } 418618334Speter 418790282Sobrien if (type == NO_DEBUG) 418818334Speter { 418990282Sobrien type = PREFERRED_DEBUGGING_TYPE; 419018334Speter 419190282Sobrien if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0) 419218334Speter { 419396289Sobrien#ifdef DWARF2_DEBUGGING_INFO 419490282Sobrien type = DWARF2_DEBUG; 419550615Sobrien#else 419618334Speter#ifdef DBX_DEBUGGING_INFO 419790282Sobrien type = DBX_DEBUG; 419850615Sobrien#endif 419950615Sobrien#endif 420090282Sobrien } 420190282Sobrien } 420218334Speter 420390282Sobrien if (type == NO_DEBUG) 420490282Sobrien warning ("`%s': unknown or unsupported -g option", arg - 2); 420518334Speter 420690282Sobrien /* Does it conflict with an already selected type? */ 420790282Sobrien if (type_explicitly_set_p 420890282Sobrien /* -g/-ggdb don't conflict with anything. */ 420990282Sobrien && da->debug_type != NO_DEBUG 421090282Sobrien && type != selected_debug_type) 421190282Sobrien warning ("`%s' ignored, conflicts with `-g%s'", 421290282Sobrien arg - 2, debug_type_names[(int) selected_debug_type]); 421390282Sobrien else 421418334Speter { 421590282Sobrien /* If the format has already been set, -g/-ggdb 421690282Sobrien only change the debug level. */ 421790282Sobrien if (type_explicitly_set_p && da->debug_type == NO_DEBUG) 421890282Sobrien /* Don't change debugging type. */ 421990282Sobrien ; 422052558Sobrien else 422190282Sobrien { 422290282Sobrien selected_debug_type = type; 422390282Sobrien type_explicitly_set_p = da->debug_type != NO_DEBUG; 422452558Sobrien } 422590282Sobrien 422690282Sobrien write_symbols = (level == 0 422790282Sobrien ? NO_DEBUG 422890282Sobrien : selected_debug_type); 422990282Sobrien use_gnu_debug_info_extensions = da->use_extensions_p; 423090282Sobrien debug_info_level = (enum debug_info_level) level; 423118334Speter } 423290282Sobrien 423390282Sobrien break; 423418334Speter } 423518334Speter } 423618334Speter 423790282Sobrien if (! da->arg) 423890282Sobrien return 0; 423918334Speter 424090282Sobrien return 1; 424190282Sobrien} 424290282Sobrien 424390282Sobrien/* Decode the first argument in the argv as a language-independent option. 424490282Sobrien Return the number of strings consumed. */ 424590282Sobrien 424690282Sobrienstatic unsigned int 424790282Sobrienindependent_decode_option (argc, argv) 424890282Sobrien int argc; 424990282Sobrien char **argv; 425090282Sobrien{ 425190282Sobrien char *arg = argv[0]; 425290282Sobrien 425390282Sobrien if (arg[0] != '-' || arg[1] == 0) 425418334Speter { 425590282Sobrien if (arg[0] == '+') 425690282Sobrien return 0; 425718334Speter 425890282Sobrien filename = arg; 425990282Sobrien 426090282Sobrien return 1; 426118334Speter } 426218334Speter 426390282Sobrien arg++; 426418334Speter 426590282Sobrien if (!strcmp (arg, "-help")) 426650615Sobrien { 426790282Sobrien display_help (); 426890282Sobrien exit_after_options = 1; 4269117414Skan return 1; 427050615Sobrien } 427150615Sobrien 427290282Sobrien if (!strcmp (arg, "-target-help")) 427350615Sobrien { 427490282Sobrien display_target_options (); 427590282Sobrien exit_after_options = 1; 4276117414Skan return 1; 427750615Sobrien } 427850615Sobrien 427990282Sobrien if (!strcmp (arg, "-version")) 428018334Speter { 428190282Sobrien print_version (stderr, ""); 428290282Sobrien exit_after_options = 1; 4283117414Skan return 1; 428418334Speter } 428518334Speter 428690282Sobrien /* Handle '--param <name>=<value>'. */ 428790282Sobrien if (strcmp (arg, "-param") == 0) 428890282Sobrien { 428990282Sobrien char *equal; 429018334Speter 429190282Sobrien if (argc == 1) 429252558Sobrien { 429390282Sobrien error ("-param option missing argument"); 429490282Sobrien return 1; 429552558Sobrien } 429690282Sobrien 429790282Sobrien /* Get the '<name>=<value>' parameter. */ 429890282Sobrien arg = argv[1]; 429990282Sobrien /* Look for the `='. */ 430090282Sobrien equal = strchr (arg, '='); 430190282Sobrien if (!equal) 430290282Sobrien error ("invalid --param option: %s", arg); 430352558Sobrien else 430490282Sobrien { 430590282Sobrien int val; 430652558Sobrien 430790282Sobrien /* Zero out the `=' sign so that we get two separate strings. */ 430890282Sobrien *equal = '\0'; 430990282Sobrien /* Figure out what value is specified. */ 431090282Sobrien val = read_integral_parameter (equal + 1, NULL, INVALID_PARAM_VAL); 431190282Sobrien if (val != INVALID_PARAM_VAL) 431290282Sobrien set_param_value (arg, val); 431390282Sobrien else 431490282Sobrien error ("invalid parameter value `%s'", equal + 1); 431590282Sobrien } 431690282Sobrien 431790282Sobrien return 2; 431818334Speter } 431918334Speter 432090282Sobrien if (*arg == 'Y') 432190282Sobrien arg++; 432218334Speter 432390282Sobrien switch (*arg) 432418334Speter { 432590282Sobrien default: 432690282Sobrien return 0; 432718334Speter 432890282Sobrien case 'O': 432990282Sobrien /* Already been treated in main (). Do nothing. */ 433090282Sobrien break; 433118334Speter 433290282Sobrien case 'm': 433390282Sobrien set_target_switch (arg + 1); 433490282Sobrien break; 433590282Sobrien 433690282Sobrien case 'f': 433790282Sobrien return decode_f_option (arg + 1); 433890282Sobrien 433990282Sobrien case 'g': 434090282Sobrien return decode_g_option (arg + 1); 434190282Sobrien 434290282Sobrien case 'd': 434390282Sobrien if (!strcmp (arg, "dumpbase")) 434490282Sobrien { 434590282Sobrien if (argc == 1) 434690282Sobrien return 0; 434790282Sobrien 4348117414Skan if (argv[1][0]) 4349117414Skan dump_base_name = argv[1]; 4350117414Skan 435190282Sobrien return 2; 435290282Sobrien } 435390282Sobrien else 435490282Sobrien decode_d_option (arg + 1); 435590282Sobrien break; 435690282Sobrien 435790282Sobrien case 'p': 435890282Sobrien if (!strcmp (arg, "pedantic")) 435990282Sobrien pedantic = 1; 436090282Sobrien else if (!strcmp (arg, "pedantic-errors")) 436190282Sobrien flag_pedantic_errors = pedantic = 1; 436290282Sobrien else if (arg[1] == 0) 436390282Sobrien profile_flag = 1; 436490282Sobrien else 436590282Sobrien return 0; 436690282Sobrien break; 436790282Sobrien 436890282Sobrien case 'q': 436990282Sobrien if (!strcmp (arg, "quiet")) 437090282Sobrien quiet_flag = 1; 437190282Sobrien else 437290282Sobrien return 0; 437390282Sobrien break; 437490282Sobrien 437590282Sobrien case 'v': 437690282Sobrien if (!strcmp (arg, "version")) 437790282Sobrien version_flag = 1; 437890282Sobrien else 437990282Sobrien return 0; 438090282Sobrien break; 438190282Sobrien 438290282Sobrien case 'w': 438390282Sobrien if (arg[1] == 0) 438490282Sobrien inhibit_warnings = 1; 438590282Sobrien else 438690282Sobrien return 0; 438790282Sobrien break; 438890282Sobrien 438990282Sobrien case 'W': 439090282Sobrien if (arg[1] == 0) 439190282Sobrien { 439290282Sobrien extra_warnings = 1; 439390282Sobrien /* We save the value of warn_uninitialized, since if they put 439490282Sobrien -Wuninitialized on the command line, we need to generate a 439590282Sobrien warning about not using it without also specifying -O. */ 439690282Sobrien if (warn_uninitialized != 1) 439790282Sobrien warn_uninitialized = 2; 439890282Sobrien } 439990282Sobrien else 440090282Sobrien return decode_W_option (arg + 1); 440190282Sobrien break; 440290282Sobrien 440390282Sobrien case 'a': 440490282Sobrien if (!strncmp (arg, "aux-info", 8)) 440590282Sobrien { 440690282Sobrien if (arg[8] == '\0') 440790282Sobrien { 440890282Sobrien if (argc == 1) 440990282Sobrien return 0; 441090282Sobrien 441190282Sobrien aux_info_file_name = argv[1]; 441290282Sobrien flag_gen_aux_info = 1; 441390282Sobrien return 2; 441490282Sobrien } 441590282Sobrien else if (arg[8] == '=') 441690282Sobrien { 441790282Sobrien aux_info_file_name = arg + 9; 441890282Sobrien flag_gen_aux_info = 1; 441990282Sobrien } 442090282Sobrien else 442190282Sobrien return 0; 442290282Sobrien } 4423117414Skan else if (!strcmp (arg, "auxbase")) 4424117414Skan { 4425117414Skan if (argc == 1) 4426117414Skan return 0; 4427117414Skan 4428117414Skan if (argv[1][0]) 4429117414Skan aux_base_name = argv[1]; 4430117414Skan 4431117414Skan return 2; 4432117414Skan } 4433117414Skan else if (!strcmp (arg, "auxbase-strip")) 4434117414Skan { 4435117414Skan if (argc == 1) 4436117414Skan return 0; 4437117414Skan 4438117414Skan if (argv[1][0]) 4439117414Skan { 4440117414Skan strip_off_ending (argv[1], strlen (argv[1])); 4441117414Skan if (argv[1][0]) 4442117414Skan aux_base_name = argv[1]; 4443117414Skan } 4444117414Skan 4445117414Skan return 2; 4446117414Skan } 444790282Sobrien else 444890282Sobrien return 0; 444990282Sobrien break; 445090282Sobrien 445190282Sobrien case 'o': 445290282Sobrien if (arg[1] == 0) 445390282Sobrien { 445490282Sobrien if (argc == 1) 445590282Sobrien return 0; 445690282Sobrien 445790282Sobrien asm_file_name = argv[1]; 445890282Sobrien return 2; 445990282Sobrien } 446090282Sobrien return 0; 446190282Sobrien 446290282Sobrien case 'G': 446390282Sobrien { 446490282Sobrien int g_switch_val; 446590282Sobrien int return_val; 446690282Sobrien 446790282Sobrien if (arg[1] == 0) 446890282Sobrien { 446990282Sobrien if (argc == 1) 447090282Sobrien return 0; 447190282Sobrien 447290282Sobrien g_switch_val = read_integral_parameter (argv[1], 0, -1); 447390282Sobrien return_val = 2; 447490282Sobrien } 447590282Sobrien else 447690282Sobrien { 447790282Sobrien g_switch_val = read_integral_parameter (arg + 1, 0, -1); 447890282Sobrien return_val = 1; 447990282Sobrien } 448090282Sobrien 448190282Sobrien if (g_switch_val == -1) 448290282Sobrien return_val = 0; 448390282Sobrien else 448490282Sobrien { 448590282Sobrien g_switch_set = TRUE; 448690282Sobrien g_switch_value = g_switch_val; 448790282Sobrien } 448890282Sobrien 448990282Sobrien return return_val; 449090282Sobrien } 449118334Speter } 449218334Speter 449390282Sobrien return 1; 449418334Speter} 449518334Speter 449618334Speter/* Decode -m switches. */ 449718334Speter/* Decode the switch -mNAME. */ 449818334Speter 449952558Sobrienstatic void 450018334Speterset_target_switch (name) 450190282Sobrien const char *name; 450218334Speter{ 450390282Sobrien size_t j; 450452558Sobrien int valid_target_option = 0; 450518334Speter 450690282Sobrien for (j = 0; j < ARRAY_SIZE (target_switches); j++) 450718334Speter if (!strcmp (target_switches[j].name, name)) 450818334Speter { 450918334Speter if (target_switches[j].value < 0) 451018334Speter target_flags &= ~-target_switches[j].value; 451118334Speter else 451218334Speter target_flags |= target_switches[j].value; 4513117414Skan if (name[0] != 0) 4514117414Skan { 4515117414Skan if (target_switches[j].value < 0) 4516117414Skan target_flags_explicit |= -target_switches[j].value; 4517117414Skan else 4518117414Skan target_flags_explicit |= target_switches[j].value; 4519117414Skan } 452052558Sobrien valid_target_option = 1; 452118334Speter } 452218334Speter 452318334Speter#ifdef TARGET_OPTIONS 452452558Sobrien if (!valid_target_option) 452590282Sobrien for (j = 0; j < ARRAY_SIZE (target_options); j++) 452618334Speter { 452718334Speter int len = strlen (target_options[j].prefix); 452818334Speter if (!strncmp (target_options[j].prefix, name, len)) 452918334Speter { 453018334Speter *target_options[j].variable = name + len; 453152558Sobrien valid_target_option = 1; 453218334Speter } 453318334Speter } 453418334Speter#endif 453518334Speter 453652558Sobrien if (!valid_target_option) 453790282Sobrien error ("invalid option `%s'", name); 453818334Speter} 453918334Speter 454050615Sobrien/* Print version information to FILE. 454150615Sobrien Each line begins with INDENT (for the case where FILE is the 454250615Sobrien assembler output file). */ 454318334Speter 454452558Sobrienstatic void 454550615Sobrienprint_version (file, indent) 454650615Sobrien FILE *file; 454752558Sobrien const char *indent; 454850615Sobrien{ 454950615Sobrien#ifndef __VERSION__ 455052558Sobrien#define __VERSION__ "[?]" 455150615Sobrien#endif 455252558Sobrien fnotice (file, 455352558Sobrien#ifdef __GNUC__ 455490282Sobrien "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n" 455550615Sobrien#else 455652558Sobrien "%s%s%s version %s (%s) compiled by CC.\n" 455750615Sobrien#endif 455852558Sobrien , indent, *indent != 0 ? " " : "", 455990282Sobrien lang_hooks.name, version_string, TARGET_NAME, 456090282Sobrien indent, __VERSION__); 4561117414Skan fnotice (file, "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n", 4562117414Skan indent, *indent != 0 ? " " : "", 4563117414Skan PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE)); 456450615Sobrien} 456518334Speter 456650615Sobrien/* Print an option value and return the adjusted position in the line. 456750615Sobrien ??? We don't handle error returns from fprintf (disk full); presumably 456850615Sobrien other code will catch a disk full though. */ 456918334Speter 457052558Sobrienstatic int 457150615Sobrienprint_single_switch (file, pos, max, indent, sep, term, type, name) 457250615Sobrien FILE *file; 457350615Sobrien int pos, max; 457452558Sobrien const char *indent, *sep, *term, *type, *name; 457518334Speter{ 457650615Sobrien /* The ultrix fprintf returns 0 on success, so compute the result we want 457750615Sobrien here since we need it for the following test. */ 457850615Sobrien int len = strlen (sep) + strlen (type) + strlen (name); 457918334Speter 458050615Sobrien if (pos != 0 458150615Sobrien && pos + len > max) 458218334Speter { 458350615Sobrien fprintf (file, "%s", term); 458450615Sobrien pos = 0; 458518334Speter } 458650615Sobrien if (pos == 0) 458750615Sobrien { 458850615Sobrien fprintf (file, "%s", indent); 458950615Sobrien pos = strlen (indent); 459050615Sobrien } 459150615Sobrien fprintf (file, "%s%s%s", sep, type, name); 459250615Sobrien pos += len; 459350615Sobrien return pos; 459418334Speter} 459590282Sobrien 459650615Sobrien/* Print active target switches to FILE. 459750615Sobrien POS is the current cursor position and MAX is the size of a "line". 459850615Sobrien Each line begins with INDENT and ends with TERM. 459950615Sobrien Each switch is separated from the next by SEP. */ 460018334Speter 460152558Sobrienstatic void 460250615Sobrienprint_switch_values (file, pos, max, indent, sep, term) 460350615Sobrien FILE *file; 460450615Sobrien int pos, max; 460552558Sobrien const char *indent, *sep, *term; 460618334Speter{ 460750615Sobrien size_t j; 460850615Sobrien char **p; 460918334Speter 4610117414Skan /* Fill in the -frandom-seed option, if the user didn't pass it, so 4611117414Skan that it can be printed below. This helps reproducibility. Of 4612117414Skan course, the string may never be used, but we can't tell that at 4613117414Skan this point in the compile. */ 4614117414Skan default_flag_random_seed (); 4615117414Skan 461650615Sobrien /* Print the options as passed. */ 461718334Speter 461850615Sobrien pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term, 461952558Sobrien _("options passed: "), ""); 462050615Sobrien 462150615Sobrien for (p = &save_argv[1]; *p != NULL; p++) 462250615Sobrien if (**p == '-') 462350615Sobrien { 462450615Sobrien /* Ignore these. */ 462550615Sobrien if (strcmp (*p, "-o") == 0) 462650615Sobrien { 462750615Sobrien if (p[1] != NULL) 462850615Sobrien p++; 462950615Sobrien continue; 463050615Sobrien } 463150615Sobrien if (strcmp (*p, "-quiet") == 0) 463250615Sobrien continue; 463350615Sobrien if (strcmp (*p, "-version") == 0) 463450615Sobrien continue; 463550615Sobrien if ((*p)[1] == 'd') 463650615Sobrien continue; 463750615Sobrien 463850615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, *p, ""); 463950615Sobrien } 464050615Sobrien if (pos > 0) 464150615Sobrien fprintf (file, "%s", term); 464250615Sobrien 464350615Sobrien /* Print the -f and -m options that have been enabled. 464450615Sobrien We don't handle language specific options but printing argv 464550615Sobrien should suffice. */ 464650615Sobrien 464750615Sobrien pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term, 464852558Sobrien _("options enabled: "), ""); 464950615Sobrien 465090282Sobrien for (j = 0; j < ARRAY_SIZE (f_options); j++) 465118334Speter if (*f_options[j].variable == f_options[j].on_value) 465250615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 465350615Sobrien "-f", f_options[j].string); 465418334Speter 465550615Sobrien /* Print target specific options. */ 465618334Speter 465790282Sobrien for (j = 0; j < ARRAY_SIZE (target_switches); j++) 465818334Speter if (target_switches[j].name[0] != '\0' 465918334Speter && target_switches[j].value > 0 466018334Speter && ((target_switches[j].value & target_flags) 466118334Speter == target_switches[j].value)) 466250615Sobrien { 466350615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 466450615Sobrien "-m", target_switches[j].name); 466550615Sobrien } 466618334Speter 466750615Sobrien#ifdef TARGET_OPTIONS 466890282Sobrien for (j = 0; j < ARRAY_SIZE (target_options); j++) 466950615Sobrien if (*target_options[j].variable != NULL) 467050615Sobrien { 467150615Sobrien char prefix[256]; 467250615Sobrien sprintf (prefix, "-m%s", target_options[j].prefix); 467350615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 467450615Sobrien prefix, *target_options[j].variable); 467550615Sobrien } 467650615Sobrien#endif 467750615Sobrien 467850615Sobrien fprintf (file, "%s", term); 467918334Speter} 468090282Sobrien 468190282Sobrien/* Open assembly code output file. Do this even if -fsyntax-only is 468290282Sobrien on, because then the driver will have provided the name of a 468390282Sobrien temporary file or bit bucket for us. NAME is the file specified on 468490282Sobrien the command line, possibly NULL. */ 468590282Sobrienstatic void 468690282Sobrieninit_asm_output (name) 468790282Sobrien const char *name; 468890282Sobrien{ 468990282Sobrien if (name == NULL && asm_file_name == 0) 469090282Sobrien asm_out_file = stdout; 469190282Sobrien else 469290282Sobrien { 469390282Sobrien if (asm_file_name == 0) 4694117414Skan { 4695117414Skan int len = strlen (dump_base_name); 4696117414Skan char *dumpname = (char *) xmalloc (len + 6); 4697117414Skan memcpy (dumpname, dump_base_name, len + 1); 4698117414Skan strip_off_ending (dumpname, len); 4699117414Skan strcat (dumpname, ".s"); 4700117414Skan asm_file_name = dumpname; 4701117414Skan } 470290282Sobrien if (!strcmp (asm_file_name, "-")) 4703117414Skan asm_out_file = stdout; 470490282Sobrien else 4705117414Skan asm_out_file = fopen (asm_file_name, "w"); 470690282Sobrien if (asm_out_file == 0) 470790282Sobrien fatal_io_error ("can't open %s for writing", asm_file_name); 470890282Sobrien } 470950615Sobrien 471090282Sobrien#ifdef IO_BUFFER_SIZE 471190282Sobrien setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), 4712117414Skan _IOFBF, IO_BUFFER_SIZE); 471390282Sobrien#endif 471450615Sobrien 471590282Sobrien if (!flag_syntax_only) 471690282Sobrien { 471790282Sobrien#ifdef ASM_FILE_START 471890282Sobrien ASM_FILE_START (asm_out_file); 471990282Sobrien#endif 472090282Sobrien 472190282Sobrien#ifdef ASM_COMMENT_START 472290282Sobrien if (flag_verbose_asm) 472390282Sobrien { 472490282Sobrien /* Print the list of options in effect. */ 472590282Sobrien print_version (asm_out_file, ASM_COMMENT_START); 472690282Sobrien print_switch_values (asm_out_file, 0, MAX_LINE, 472790282Sobrien ASM_COMMENT_START, " ", "\n"); 472890282Sobrien /* Add a blank line here so it appears in assembler output but not 472990282Sobrien screen output. */ 473090282Sobrien fprintf (asm_out_file, "\n"); 473190282Sobrien } 473290282Sobrien#endif 473390282Sobrien } 473490282Sobrien} 473590282Sobrien 473690282Sobrien/* Initialization of the front end environment, before command line 473790282Sobrien options are parsed. Signal handlers, internationalization etc. 473890282Sobrien ARGV0 is main's argv[0]. */ 473990282Sobrienstatic void 474090282Sobriengeneral_init (argv0) 474190282Sobrien char *argv0; 474250615Sobrien{ 474390282Sobrien char *p; 474490282Sobrien 474590282Sobrien p = argv0 + strlen (argv0); 474690282Sobrien while (p != argv0 && !IS_DIR_SEPARATOR (p[-1])) 474790282Sobrien --p; 474890282Sobrien progname = p; 474990282Sobrien 475090282Sobrien xmalloc_set_program_name (progname); 475190282Sobrien 4752117414Skan hex_init (); 4753117414Skan 475490282Sobrien gcc_init_libintl (); 475590282Sobrien 475690282Sobrien /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */ 475790282Sobrien#ifdef SIGSEGV 475890282Sobrien signal (SIGSEGV, crash_signal); 475950615Sobrien#endif 476090282Sobrien#ifdef SIGILL 476190282Sobrien signal (SIGILL, crash_signal); 476250615Sobrien#endif 476390282Sobrien#ifdef SIGBUS 476490282Sobrien signal (SIGBUS, crash_signal); 476590282Sobrien#endif 476690282Sobrien#ifdef SIGABRT 476790282Sobrien signal (SIGABRT, crash_signal); 476890282Sobrien#endif 476990282Sobrien#if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT) 477090282Sobrien signal (SIGIOT, crash_signal); 477190282Sobrien#endif 4772117414Skan#ifdef SIGFPE 4773117414Skan signal (SIGFPE, crash_signal); 4774117414Skan#endif 477590282Sobrien 477690282Sobrien /* Initialize the diagnostics reporting machinery, so option parsing 477790282Sobrien can give warnings and errors. */ 477890282Sobrien diagnostic_initialize (global_dc); 4779117414Skan 4780117414Skan /* Initialize the garbage-collector, string pools and tree type hash 4781117414Skan table. */ 4782117414Skan init_ggc (); 4783117414Skan init_stringpool (); 4784117414Skan init_ttree (); 478550615Sobrien} 478690282Sobrien 478790282Sobrien/* Parse command line options and set default flag values, called 478890282Sobrien after language-independent option-independent initialization. Do 478990282Sobrien minimal options processing. Outputting diagnostics is OK, but GC 4790117414Skan and identifier hashtables etc. are not initialized yet. 4791117414Skan 4792117414Skan Return nonzero to suppress compiler back end initialization. */ 479390282Sobrienstatic void 479490282Sobrienparse_options_and_default_flags (argc, argv) 479590282Sobrien int argc; 479690282Sobrien char **argv; 479790282Sobrien{ 479890282Sobrien int i; 479950615Sobrien 480090282Sobrien /* Save in case md file wants to emit args as a comment. */ 480190282Sobrien save_argc = argc; 480290282Sobrien save_argv = argv; 480350615Sobrien 480490282Sobrien /* Initialize register usage now so switches may override. */ 480590282Sobrien init_reg_sets (); 480690282Sobrien 480790282Sobrien /* Register the language-independent parameters. */ 480890282Sobrien add_params (lang_independent_params, LAST_PARAM); 480990282Sobrien 4810117414Skan /* This must be done after add_params but before argument processing. */ 4811117414Skan init_ggc_heuristics(); 4812117414Skan 481390282Sobrien /* Perform language-specific options initialization. */ 481490282Sobrien (*lang_hooks.init_options) (); 481590282Sobrien 481690282Sobrien /* Scan to see what optimization level has been specified. That will 481790282Sobrien determine the default value of many flags. */ 481890282Sobrien for (i = 1; i < argc; i++) 481990282Sobrien { 482090282Sobrien if (!strcmp (argv[i], "-O")) 482190282Sobrien { 482290282Sobrien optimize = 1; 482390282Sobrien optimize_size = 0; 482490282Sobrien } 482590282Sobrien else if (argv[i][0] == '-' && argv[i][1] == 'O') 482690282Sobrien { 482790282Sobrien /* Handle -Os, -O2, -O3, -O69, ... */ 482890282Sobrien char *p = &argv[i][2]; 482990282Sobrien 483090282Sobrien if ((p[0] == 's') && (p[1] == 0)) 483190282Sobrien { 483290282Sobrien optimize_size = 1; 483390282Sobrien 483490282Sobrien /* Optimizing for size forces optimize to be 2. */ 483590282Sobrien optimize = 2; 483690282Sobrien } 483790282Sobrien else 483890282Sobrien { 483990282Sobrien const int optimize_val = read_integral_parameter (p, p - 2, -1); 484090282Sobrien if (optimize_val != -1) 484190282Sobrien { 484290282Sobrien optimize = optimize_val; 484390282Sobrien 484490282Sobrien#ifdef FORCE_OPTIMIZATION_DOWNGRADE 484590282Sobrien#warning FORCE_OPTIMIZATION_DOWNGRADE 484690282Sobrien if (optimize > FORCE_OPTIMIZATION_DOWNGRADE) 484790282Sobrien { 484890282Sobrien optimize = FORCE_OPTIMIZATION_DOWNGRADE; 484996289Sobrien warning ("\n***\n***\t-O%d converted to \"-O%d\" due to optimizer bugs on this platform\n***", 485090282Sobrien optimize_val, 485190282Sobrien FORCE_OPTIMIZATION_DOWNGRADE); 485290282Sobrien 485390282Sobrien } 485490282Sobrien#endif /*FORCE_OPTIMIZATION_DOWNGRADE*/ 485590282Sobrien 4856103792Sobrien#if defined(TRY_WITHOUT_THIS__alpha__) 485790282Sobrien if (optimize > 1) 485890282Sobrien { 485996289Sobrien warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***", 486090282Sobrien optimize_val); 486190282Sobrien } 486290282Sobrien#endif /*__alpha__*/ 486390282Sobrien 486490282Sobrien optimize_size = 0; 486590282Sobrien } 486690282Sobrien } 486790282Sobrien } 486890282Sobrien } 486990282Sobrien 487090282Sobrien if (!optimize) 487190282Sobrien { 487290282Sobrien flag_merge_constants = 0; 487390282Sobrien } 487490282Sobrien 487590282Sobrien if (optimize >= 1) 487690282Sobrien { 487790282Sobrien flag_defer_pop = 1; 487890282Sobrien flag_thread_jumps = 1; 487990282Sobrien#ifdef DELAY_SLOTS 488090282Sobrien flag_delayed_branch = 1; 488190282Sobrien#endif 488290282Sobrien#ifdef CAN_DEBUG_WITHOUT_FP 488390282Sobrien flag_omit_frame_pointer = 1; 488490282Sobrien#endif 488590282Sobrien flag_guess_branch_prob = 1; 488690282Sobrien flag_cprop_registers = 1; 4887117414Skan flag_loop_optimize = 1; 4888117414Skan flag_crossjumping = 1; 4889117414Skan flag_if_conversion = 1; 4890117414Skan flag_if_conversion2 = 1; 489190282Sobrien } 489290282Sobrien 489390282Sobrien if (optimize >= 2) 489490282Sobrien { 489590282Sobrien flag_optimize_sibling_calls = 1; 489690282Sobrien flag_cse_follow_jumps = 1; 489790282Sobrien flag_cse_skip_blocks = 1; 489890282Sobrien flag_gcse = 1; 489990282Sobrien flag_expensive_optimizations = 1; 490090282Sobrien flag_strength_reduce = 1; 490190282Sobrien flag_rerun_cse_after_loop = 1; 490290282Sobrien flag_rerun_loop_opt = 1; 490390282Sobrien flag_caller_saves = 1; 490490282Sobrien flag_force_mem = 1; 490590282Sobrien flag_peephole2 = 1; 490690282Sobrien#ifdef INSN_SCHEDULING 490790282Sobrien flag_schedule_insns = 1; 490890282Sobrien flag_schedule_insns_after_reload = 1; 490990282Sobrien#endif 491090282Sobrien flag_regmove = 1; 491190282Sobrien flag_strict_aliasing = 1; 491290282Sobrien flag_delete_null_pointer_checks = 1; 491390282Sobrien flag_reorder_blocks = 1; 4914117414Skan flag_reorder_functions = 1; 491590282Sobrien } 491690282Sobrien 491790282Sobrien if (optimize >= 3) 491890282Sobrien { 491990282Sobrien flag_inline_functions = 1; 492090282Sobrien flag_rename_registers = 1; 492190282Sobrien } 492290282Sobrien 492398573Sobrien if (optimize_size) 492490282Sobrien { 492590282Sobrien align_loops = 1; 492690282Sobrien align_jumps = 1; 492790282Sobrien align_labels = 1; 492890282Sobrien align_functions = 1; 4929117414Skan 4930117414Skan /* Don't reorder blocks when optimizing for size because extra 4931117414Skan jump insns may be created; also barrier may create extra padding. 4932117414Skan 4933117414Skan More correctly we should have a block reordering mode that tried 4934117414Skan to minimize the combined size of all the jumps. This would more 4935117414Skan or less automatically remove extra jumps, but would also try to 4936117414Skan use more short jumps instead of long jumps. */ 4937117414Skan flag_reorder_blocks = 0; 493890282Sobrien } 493990282Sobrien 494090282Sobrien /* Initialize whether `char' is signed. */ 494190282Sobrien flag_signed_char = DEFAULT_SIGNED_CHAR; 494290282Sobrien#ifdef DEFAULT_SHORT_ENUMS 494390282Sobrien /* Initialize how much space enums occupy, by default. */ 494490282Sobrien flag_short_enums = DEFAULT_SHORT_ENUMS; 494590282Sobrien#endif 494690282Sobrien 494790282Sobrien /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can 494890282Sobrien modify it. */ 494990282Sobrien target_flags = 0; 495090282Sobrien set_target_switch (""); 495190282Sobrien 495290282Sobrien /* Unwind tables are always present in an ABI-conformant IA-64 495390282Sobrien object file, so the default should be ON. */ 495490282Sobrien#ifdef IA64_UNWIND_INFO 495590282Sobrien flag_unwind_tables = IA64_UNWIND_INFO; 495690282Sobrien#endif 495790282Sobrien 495890282Sobrien#ifdef OPTIMIZATION_OPTIONS 495990282Sobrien /* Allow default optimizations to be specified on a per-machine basis. */ 496090282Sobrien OPTIMIZATION_OPTIONS (optimize, optimize_size); 496190282Sobrien#endif 496290282Sobrien 496390282Sobrien /* Perform normal command line switch decoding. */ 496490282Sobrien for (i = 1; i < argc;) 496590282Sobrien { 496690282Sobrien int lang_processed; 496790282Sobrien int indep_processed; 496890282Sobrien 496990282Sobrien /* Give the language a chance to decode the option for itself. */ 497090282Sobrien lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i); 497190282Sobrien 497290282Sobrien if (lang_processed >= 0) 497390282Sobrien /* Now see if the option also has a language independent meaning. 497490282Sobrien Some options are both language specific and language independent, 497590282Sobrien eg --help. */ 497690282Sobrien indep_processed = independent_decode_option (argc - i, argv + i); 497790282Sobrien else 497890282Sobrien { 497990282Sobrien lang_processed = -lang_processed; 498090282Sobrien indep_processed = 0; 498190282Sobrien } 498290282Sobrien 498390282Sobrien if (lang_processed || indep_processed) 498490282Sobrien i += MAX (lang_processed, indep_processed); 498590282Sobrien else 498690282Sobrien { 498790282Sobrien const char *option = NULL; 498890282Sobrien const char *lang = NULL; 498990282Sobrien unsigned int j; 499090282Sobrien 499190282Sobrien /* It is possible that the command line switch is not valid for the 499290282Sobrien current language, but it is valid for another language. In order 499390282Sobrien to be compatible with previous versions of the compiler (which 499490282Sobrien did not issue an error message in this case) we check for this 499590282Sobrien possibility here. If we do find a match, then if extra_warnings 499690282Sobrien is set we generate a warning message, otherwise we will just 499790282Sobrien ignore the option. */ 499890282Sobrien for (j = 0; j < ARRAY_SIZE (documented_lang_options); j++) 499990282Sobrien { 500090282Sobrien option = documented_lang_options[j].option; 500190282Sobrien 500290282Sobrien if (option == NULL) 500390282Sobrien lang = documented_lang_options[j].description; 500490282Sobrien else if (! strncmp (argv[i], option, strlen (option))) 500590282Sobrien break; 500690282Sobrien } 500790282Sobrien 500890282Sobrien if (j != ARRAY_SIZE (documented_lang_options)) 500990282Sobrien { 501090282Sobrien if (extra_warnings) 501190282Sobrien { 501290282Sobrien warning ("ignoring command line option '%s'", argv[i]); 501390282Sobrien if (lang) 501490282Sobrien warning 501590282Sobrien ("(it is valid for %s but not the selected language)", 501690282Sobrien lang); 501790282Sobrien } 501890282Sobrien } 501990282Sobrien else if (argv[i][0] == '-' && argv[i][1] == 'g') 502090282Sobrien warning ("`%s': unknown or unsupported -g option", &argv[i][2]); 502190282Sobrien else 502290282Sobrien error ("unrecognized option `%s'", argv[i]); 502390282Sobrien 502490282Sobrien i++; 502590282Sobrien } 502690282Sobrien } 502790282Sobrien 502896289Sobrien if (flag_no_inline == 2) 502996289Sobrien flag_no_inline = 0; 503096289Sobrien else 503196289Sobrien flag_really_no_inline = flag_no_inline; 503296289Sobrien 503390282Sobrien /* Set flag_no_inline before the post_options () hook. The C front 503490282Sobrien ends use it to determine tree inlining defaults. FIXME: such 503590282Sobrien code should be lang-independent when all front ends use tree 503690282Sobrien inlining, in which case it, and this condition, should be moved 503790282Sobrien to the top of process_options() instead. */ 503890282Sobrien if (optimize == 0) 503990282Sobrien { 504090282Sobrien /* Inlining does not work if not optimizing, 504190282Sobrien so force it not to be done. */ 504290282Sobrien flag_no_inline = 1; 504390282Sobrien warn_inline = 0; 504490282Sobrien 504590282Sobrien /* The c_decode_option function and decode_option hook set 504690282Sobrien this to `2' if -Wall is used, so we can avoid giving out 504790282Sobrien lots of errors for people who don't realize what -Wall does. */ 504890282Sobrien if (warn_uninitialized == 1) 504990282Sobrien warning ("-Wuninitialized is not supported without -O"); 505090282Sobrien } 505190282Sobrien 505296289Sobrien if (flag_really_no_inline == 2) 505396289Sobrien flag_really_no_inline = flag_no_inline; 505490282Sobrien} 505590282Sobrien 505690282Sobrien/* Process the options that have been parsed. */ 505790282Sobrienstatic void 505890282Sobrienprocess_options () 505950615Sobrien{ 506090282Sobrien#ifdef OVERRIDE_OPTIONS 506190282Sobrien /* Some machines may reject certain combinations of options. */ 506290282Sobrien OVERRIDE_OPTIONS; 506390282Sobrien#endif 506490282Sobrien 506590282Sobrien /* Set up the align_*_log variables, defaulting them to 1 if they 506690282Sobrien were still unset. */ 506790282Sobrien if (align_loops <= 0) align_loops = 1; 506890282Sobrien if (align_loops_max_skip > align_loops || !align_loops) 506990282Sobrien align_loops_max_skip = align_loops - 1; 507090282Sobrien align_loops_log = floor_log2 (align_loops * 2 - 1); 507190282Sobrien if (align_jumps <= 0) align_jumps = 1; 507290282Sobrien if (align_jumps_max_skip > align_jumps || !align_jumps) 507390282Sobrien align_jumps_max_skip = align_jumps - 1; 507490282Sobrien align_jumps_log = floor_log2 (align_jumps * 2 - 1); 507590282Sobrien if (align_labels <= 0) align_labels = 1; 507690282Sobrien align_labels_log = floor_log2 (align_labels * 2 - 1); 507790282Sobrien if (align_labels_max_skip > align_labels || !align_labels) 507890282Sobrien align_labels_max_skip = align_labels - 1; 507990282Sobrien if (align_functions <= 0) align_functions = 1; 508090282Sobrien align_functions_log = floor_log2 (align_functions * 2 - 1); 508190282Sobrien 508290282Sobrien /* Unrolling all loops implies that standard loop unrolling must also 508390282Sobrien be done. */ 508490282Sobrien if (flag_unroll_all_loops) 508590282Sobrien flag_unroll_loops = 1; 508690282Sobrien /* Loop unrolling requires that strength_reduction be on also. Silently 508790282Sobrien turn on strength reduction here if it isn't already on. Also, the loop 508890282Sobrien unrolling code assumes that cse will be run after loop, so that must 508990282Sobrien be turned on also. */ 509090282Sobrien if (flag_unroll_loops) 509190282Sobrien { 509290282Sobrien flag_strength_reduce = 1; 509390282Sobrien flag_rerun_cse_after_loop = 1; 509490282Sobrien } 509590282Sobrien 509690282Sobrien if (flag_non_call_exceptions) 509790282Sobrien flag_asynchronous_unwind_tables = 1; 509890282Sobrien if (flag_asynchronous_unwind_tables) 509990282Sobrien flag_unwind_tables = 1; 510090282Sobrien 510190282Sobrien /* Warn about options that are not supported on this machine. */ 510290282Sobrien#ifndef INSN_SCHEDULING 510390282Sobrien if (flag_schedule_insns || flag_schedule_insns_after_reload) 510490282Sobrien warning ("instruction scheduling not supported on this target machine"); 510590282Sobrien#endif 510690282Sobrien#ifndef DELAY_SLOTS 510790282Sobrien if (flag_delayed_branch) 510890282Sobrien warning ("this target machine does not have delayed branches"); 510990282Sobrien#endif 511090282Sobrien 511190282Sobrien user_label_prefix = USER_LABEL_PREFIX; 511290282Sobrien if (flag_leading_underscore != -1) 511390282Sobrien { 511490282Sobrien /* If the default prefix is more complicated than "" or "_", 511590282Sobrien issue a warning and ignore this option. */ 511690282Sobrien if (user_label_prefix[0] == 0 || 511790282Sobrien (user_label_prefix[0] == '_' && user_label_prefix[1] == 0)) 511890282Sobrien { 511990282Sobrien user_label_prefix = flag_leading_underscore ? "_" : ""; 512090282Sobrien } 512190282Sobrien else 512290282Sobrien warning ("-f%sleading-underscore not supported on this target machine", 512390282Sobrien flag_leading_underscore ? "" : "no-"); 512490282Sobrien } 512590282Sobrien 512690282Sobrien /* If we are in verbose mode, write out the version and maybe all the 512790282Sobrien option flags in use. */ 512890282Sobrien if (version_flag) 512990282Sobrien { 513090282Sobrien print_version (stderr, ""); 513190282Sobrien if (! quiet_flag) 513290282Sobrien print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n"); 513390282Sobrien } 513490282Sobrien 5135117414Skan if (! quiet_flag || flag_detailed_statistics) 513690282Sobrien time_report = 1; 513790282Sobrien 513890282Sobrien if (flag_syntax_only) 513990282Sobrien { 514090282Sobrien write_symbols = NO_DEBUG; 514190282Sobrien profile_flag = 0; 514290282Sobrien } 514390282Sobrien 514490282Sobrien /* Now we know write_symbols, set up the debug hooks based on it. 514590282Sobrien By default we do nothing for debug output. */ 514690282Sobrien#if defined(DBX_DEBUGGING_INFO) 514750615Sobrien if (write_symbols == DBX_DEBUG) 514890282Sobrien debug_hooks = &dbx_debug_hooks; 514950615Sobrien#endif 515090282Sobrien#if defined(XCOFF_DEBUGGING_INFO) 515190282Sobrien if (write_symbols == XCOFF_DEBUG) 515290282Sobrien debug_hooks = &xcoff_debug_hooks; 515390282Sobrien#endif 515450615Sobrien#ifdef SDB_DEBUGGING_INFO 515550615Sobrien if (write_symbols == SDB_DEBUG) 515690282Sobrien debug_hooks = &sdb_debug_hooks; 515750615Sobrien#endif 515890282Sobrien#ifdef DWARF_DEBUGGING_INFO 515990282Sobrien if (write_symbols == DWARF_DEBUG) 516090282Sobrien debug_hooks = &dwarf_debug_hooks; 516190282Sobrien#endif 516290282Sobrien#ifdef DWARF2_DEBUGGING_INFO 516390282Sobrien if (write_symbols == DWARF2_DEBUG) 516490282Sobrien debug_hooks = &dwarf2_debug_hooks; 516590282Sobrien#endif 516690282Sobrien#ifdef VMS_DEBUGGING_INFO 516790282Sobrien if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) 516890282Sobrien debug_hooks = &vmsdbg_debug_hooks; 516990282Sobrien#endif 517090282Sobrien 517190282Sobrien /* If auxiliary info generation is desired, open the output file. 517290282Sobrien This goes in the same directory as the source file--unlike 517390282Sobrien all the other output files. */ 517490282Sobrien if (flag_gen_aux_info) 517590282Sobrien { 517690282Sobrien aux_info_file = fopen (aux_info_file_name, "w"); 517790282Sobrien if (aux_info_file == 0) 517890282Sobrien fatal_io_error ("can't open %s", aux_info_file_name); 517990282Sobrien } 518090282Sobrien 518190282Sobrien if (! targetm.have_named_sections) 518290282Sobrien { 518390282Sobrien if (flag_function_sections) 518490282Sobrien { 518590282Sobrien warning ("-ffunction-sections not supported for this target"); 518690282Sobrien flag_function_sections = 0; 518790282Sobrien } 518890282Sobrien if (flag_data_sections) 518990282Sobrien { 519090282Sobrien warning ("-fdata-sections not supported for this target"); 519190282Sobrien flag_data_sections = 0; 519290282Sobrien } 519390282Sobrien } 519490282Sobrien 519590282Sobrien if (flag_function_sections && profile_flag) 519690282Sobrien { 519790282Sobrien warning ("-ffunction-sections disabled; it makes profiling impossible"); 519890282Sobrien flag_function_sections = 0; 519990282Sobrien } 520090282Sobrien 520190282Sobrien#ifndef HAVE_prefetch 520290282Sobrien if (flag_prefetch_loop_arrays) 520390282Sobrien { 520490282Sobrien warning ("-fprefetch-loop-arrays not supported for this target"); 520590282Sobrien flag_prefetch_loop_arrays = 0; 520690282Sobrien } 520790282Sobrien#else 520890282Sobrien if (flag_prefetch_loop_arrays && !HAVE_prefetch) 520990282Sobrien { 521090282Sobrien warning ("-fprefetch-loop-arrays not supported for this target (try -march switches)"); 521190282Sobrien flag_prefetch_loop_arrays = 0; 521290282Sobrien } 521390282Sobrien#endif 521490282Sobrien 521590282Sobrien /* This combination of options isn't handled for i386 targets and doesn't 521690282Sobrien make much sense anyway, so don't allow it. */ 521790282Sobrien if (flag_prefetch_loop_arrays && optimize_size) 521890282Sobrien { 521990282Sobrien warning ("-fprefetch-loop-arrays is not supported with -Os"); 522090282Sobrien flag_prefetch_loop_arrays = 0; 522190282Sobrien } 522290282Sobrien 522390282Sobrien#ifndef OBJECT_FORMAT_ELF 522490282Sobrien if (flag_function_sections && write_symbols != NO_DEBUG) 522590282Sobrien warning ("-ffunction-sections may affect debugging on some targets"); 522690282Sobrien#endif 5227117414Skan 5228117414Skan /* The presence of IEEE signaling NaNs, implies all math can trap. */ 5229117414Skan if (flag_signaling_nans) 5230117414Skan flag_trapping_math = 1; 523150615Sobrien} 523290282Sobrien 5233117414Skan/* Initialize the compiler back end. */ 523490282Sobrienstatic void 5235117414Skanbackend_init () 523690282Sobrien{ 5237117414Skan /* init_emit_once uses reg_raw_mode and therefore must be called 5238117414Skan after init_regs which initialized reg_raw_mode. */ 5239117414Skan init_regs (); 524090282Sobrien init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL 524190282Sobrien || debug_info_level == DINFO_LEVEL_VERBOSE 524290282Sobrien#ifdef VMS_DEBUGGING_INFO 524390282Sobrien /* Enable line number info for traceback */ 524490282Sobrien || debug_info_level > DINFO_LEVEL_NONE 524590282Sobrien#endif 524690282Sobrien || flag_test_coverage 524790282Sobrien || warn_notreached); 5248117414Skan init_fake_stack_mems (); 524990282Sobrien init_alias_once (); 525090282Sobrien init_loop (); 525190282Sobrien init_reload (); 525290282Sobrien init_function_once (); 525390282Sobrien init_varasm_once (); 525490282Sobrien 525590282Sobrien /* The following initialization functions need to generate rtl, so 525690282Sobrien provide a dummy function context for them. */ 525790282Sobrien init_dummy_function_start (); 525890282Sobrien init_expmed (); 525990282Sobrien if (flag_caller_saves) 526090282Sobrien init_caller_save (); 526190282Sobrien expand_dummy_function_end (); 526290282Sobrien} 526390282Sobrien 5264117414Skan/* Language-dependent initialization. Returns nonzero on success. */ 526590282Sobrienstatic int 526690282Sobrienlang_dependent_init (name) 526790282Sobrien const char *name; 526850615Sobrien{ 526990282Sobrien if (dump_base_name == 0) 527090282Sobrien dump_base_name = name ? name : "gccdump"; 5271117414Skan 527290282Sobrien /* Front-end initialization. This hook can assume that GC, 527390282Sobrien identifier hashes etc. are set up, but debug initialization is 527490282Sobrien not done yet. This routine must return the original filename 527590282Sobrien (e.g. foo.i -> foo.c) so can correctly initialize debug output. */ 527690282Sobrien name = (*lang_hooks.init) (name); 527790282Sobrien if (name == NULL) 527890282Sobrien return 0; 527990282Sobrien 528090282Sobrien /* Is this duplication necessary? */ 528190282Sobrien name = ggc_strdup (name); 528290282Sobrien main_input_filename = input_filename = name; 528390282Sobrien init_asm_output (name); 528490282Sobrien 528590282Sobrien /* These create various _DECL nodes, so need to be called after the 528690282Sobrien front end is initialized. */ 528790282Sobrien init_eh (); 528890282Sobrien init_optabs (); 528990282Sobrien 5290117414Skan /* The following initialization functions need to generate rtl, so 5291117414Skan provide a dummy function context for them. */ 5292117414Skan init_dummy_function_start (); 5293117414Skan init_expr_once (); 5294117414Skan expand_dummy_function_end (); 5295117414Skan 529690282Sobrien /* Put an entry on the input file stack for the main input file. */ 529790282Sobrien push_srcloc (input_filename, 0); 529890282Sobrien 529990282Sobrien /* If dbx symbol table desired, initialize writing it and output the 530090282Sobrien predefined types. */ 530190282Sobrien timevar_push (TV_SYMOUT); 530290282Sobrien 530390282Sobrien#ifdef DWARF2_UNWIND_INFO 530490282Sobrien if (dwarf2out_do_frame ()) 530590282Sobrien dwarf2out_frame_init (); 530690282Sobrien#endif 530790282Sobrien 530890282Sobrien /* Now we have the correct original filename, we can initialize 530990282Sobrien debug output. */ 531090282Sobrien (*debug_hooks->init) (name); 531190282Sobrien 531290282Sobrien timevar_pop (TV_SYMOUT); 531390282Sobrien 531490282Sobrien return 1; 531550615Sobrien} 531690282Sobrien 531790282Sobrien/* Clean up: close opened files, etc. */ 531850615Sobrien 531990282Sobrienstatic void 532090282Sobrienfinalize () 532190282Sobrien{ 532290282Sobrien /* Close the dump files. */ 532390282Sobrien if (flag_gen_aux_info) 532490282Sobrien { 532590282Sobrien fclose (aux_info_file); 532690282Sobrien if (errorcount) 532790282Sobrien unlink (aux_info_file_name); 532890282Sobrien } 532950615Sobrien 533090282Sobrien /* Close non-debugging input and output files. Take special care to note 533190282Sobrien whether fclose returns an error, since the pages might still be on the 533290282Sobrien buffer chain while the file is open. */ 533390282Sobrien 533490282Sobrien if (asm_out_file) 533590282Sobrien { 533690282Sobrien if (ferror (asm_out_file) != 0) 533790282Sobrien fatal_io_error ("error writing to %s", asm_file_name); 533890282Sobrien if (fclose (asm_out_file) != 0) 533990282Sobrien fatal_io_error ("error closing %s", asm_file_name); 534090282Sobrien } 534190282Sobrien 534290282Sobrien /* Do whatever is necessary to finish printing the graphs. */ 534390282Sobrien if (graph_dump_format != no_graph) 534490282Sobrien { 534590282Sobrien int i; 534690282Sobrien 534790282Sobrien for (i = 0; i < (int) DFI_MAX; ++i) 534890282Sobrien if (dump_file[i].initialized && dump_file[i].graph_dump_p) 534990282Sobrien { 535090282Sobrien char seq[16]; 535190282Sobrien char *suffix; 535290282Sobrien 535390282Sobrien sprintf (seq, DUMPFILE_FORMAT, i); 535490282Sobrien suffix = concat (seq, dump_file[i].extension, NULL); 535590282Sobrien finish_graph_dump_file (dump_base_name, suffix); 535690282Sobrien free (suffix); 535790282Sobrien } 535890282Sobrien } 535990282Sobrien 536090282Sobrien if (mem_report) 536190282Sobrien { 536290282Sobrien ggc_print_statistics (); 536390282Sobrien stringpool_statistics (); 536490282Sobrien dump_tree_statistics (); 536590282Sobrien } 536690282Sobrien 536790282Sobrien /* Free up memory for the benefit of leak detectors. */ 536890282Sobrien free_reg_info (); 536990282Sobrien 537090282Sobrien /* Language-specific end of compilation actions. */ 537190282Sobrien (*lang_hooks.finish) (); 537290282Sobrien} 537390282Sobrien 537490282Sobrien/* Initialize the compiler, and compile the input file. */ 537590282Sobrienstatic void 537690282Sobriendo_compile () 537750615Sobrien{ 5378117414Skan /* All command line options have been parsed; allow the front end to 5379117414Skan perform consistency checks, etc. */ 5380117414Skan bool no_backend = (*lang_hooks.post_options) (); 5381117414Skan 538290282Sobrien /* The bulk of command line switch processing. */ 538390282Sobrien process_options (); 538490282Sobrien 5385117414Skan /* If an error has already occurred, give up. */ 5386117414Skan if (errorcount) 5387117414Skan return; 5388117414Skan 5389117414Skan if (aux_base_name) 5390117414Skan /*NOP*/; 5391117414Skan else if (filename) 5392117414Skan { 5393117414Skan char *name = xstrdup (lbasename (filename)); 5394117414Skan 5395117414Skan aux_base_name = name; 5396117414Skan strip_off_ending (name, strlen (name)); 5397117414Skan } 5398117414Skan else 5399117414Skan aux_base_name = "gccaux"; 5400117414Skan 540190282Sobrien /* We cannot start timing until after options are processed since that 540290282Sobrien says if we run timers or not. */ 540390282Sobrien init_timevar (); 540490282Sobrien timevar_start (TV_TOTAL); 540590282Sobrien 5406117414Skan /* Set up the back-end if requested. */ 5407117414Skan if (!no_backend) 5408117414Skan backend_init (); 540990282Sobrien 541090282Sobrien /* Language-dependent initialization. Returns true on success. */ 541190282Sobrien if (lang_dependent_init (filename)) 541290282Sobrien compile_file (); 541390282Sobrien 541490282Sobrien finalize (); 541590282Sobrien 541690282Sobrien /* Stop timing and print the times. */ 541790282Sobrien timevar_stop (TV_TOTAL); 541890282Sobrien timevar_print (stderr); 541950615Sobrien} 542090282Sobrien 542190282Sobrien/* Entry point of cc1, cc1plus, jc1, f771, etc. 542290282Sobrien Decode command args, then call compile_file. 542390282Sobrien Exit code is FATAL_EXIT_CODE if can't open files or if there were 542490282Sobrien any errors, or SUCCESS_EXIT_CODE if compilation succeeded. 542590282Sobrien 542690282Sobrien It is not safe to call this function more than once. */ 542790282Sobrien 542890282Sobrienint 542990282Sobrientoplev_main (argc, argv) 543090282Sobrien int argc; 543190282Sobrien char **argv; 543290282Sobrien{ 543390282Sobrien /* Initialization of GCC's environment, and diagnostics. */ 5434117414Skan general_init (argv[0]); 543590282Sobrien 543690282Sobrien /* Parse the options and do minimal processing; basically just 543790282Sobrien enough to default flags appropriately. */ 543890282Sobrien parse_options_and_default_flags (argc, argv); 543990282Sobrien 544090282Sobrien /* Exit early if we can (e.g. -help). */ 5441117414Skan if (!exit_after_options) 544290282Sobrien do_compile (); 544390282Sobrien 544490282Sobrien if (errorcount || sorrycount) 544590282Sobrien return (FATAL_EXIT_CODE); 544690282Sobrien 544790282Sobrien return (SUCCESS_EXIT_CODE); 544890282Sobrien} 5449