toplev.c revision 104765
118334Speter/* Top level of GNU C compiler 272566Sobrien Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 390282Sobrien 1999, 2000, 2001, 2002 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 104765 2002-10-10 04:51:11Z 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#include <setjmp.h> 3518334Speter 3650615Sobrien#ifdef HAVE_SYS_RESOURCE_H 3750615Sobrien# include <sys/resource.h> 3818334Speter#endif 3950615Sobrien 4050615Sobrien#ifdef HAVE_SYS_TIMES_H 4150615Sobrien# include <sys/times.h> 4218334Speter#endif 4318334Speter 4418334Speter#include "input.h" 4518334Speter#include "tree.h" 4618334Speter#include "rtl.h" 4790282Sobrien#include "tm_p.h" 4818334Speter#include "flags.h" 4918334Speter#include "insn-attr.h" 5050615Sobrien#include "insn-config.h" 5190282Sobrien#include "insn-flags.h" 5290282Sobrien#include "hard-reg-set.h" 5350615Sobrien#include "recog.h" 5418334Speter#include "output.h" 5550615Sobrien#include "except.h" 5690282Sobrien#include "function.h" 5750615Sobrien#include "toplev.h" 5852558Sobrien#include "expr.h" 5952558Sobrien#include "basic-block.h" 6052558Sobrien#include "intl.h" 6190282Sobrien#include "ggc.h" 6290282Sobrien#include "graph.h" 6390282Sobrien#include "loop.h" 6490282Sobrien#include "regs.h" 6590282Sobrien#include "timevar.h" 6690282Sobrien#include "diagnostic.h" 6790282Sobrien#include "ssa.h" 6890282Sobrien#include "params.h" 6990282Sobrien#include "reload.h" 7090282Sobrien#include "dwarf2asm.h" 7190282Sobrien#include "integrate.h" 7290282Sobrien#include "debug.h" 7390282Sobrien#include "target.h" 7490282Sobrien#include "langhooks.h" 7518334Speter 7650615Sobrien#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) 7750615Sobrien#include "dwarf2out.h" 7850615Sobrien#endif 7950615Sobrien 8050615Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) 8150615Sobrien#include "dbxout.h" 8250615Sobrien#endif 8350615Sobrien 8450615Sobrien#ifdef SDB_DEBUGGING_INFO 8550615Sobrien#include "sdbout.h" 8650615Sobrien#endif 8750615Sobrien 8818334Speter#ifdef XCOFF_DEBUGGING_INFO 8990282Sobrien#include "xcoffout.h" /* Needed for external data 9090282Sobrien declarations for e.g. AIX 4.x. */ 9118334Speter#endif 9290282Sobrien 9390282Sobrien#ifdef HALF_PIC_DEBUG 9490282Sobrien#include "halfpic.h" 9590282Sobrien#endif 9618334Speter 9718334Speter/* Carry information from ASM_DECLARE_OBJECT_NAME 9818334Speter to ASM_FINISH_DECLARE_OBJECT. */ 9918334Speter 10018334Speterextern int size_directive_output; 10118334Speterextern tree last_assemble_variable_decl; 10218334Speter 10390282Sobrienstatic void general_init PARAMS ((char *)); 10490282Sobrienstatic void parse_options_and_default_flags PARAMS ((int, char **)); 10590282Sobrienstatic void do_compile PARAMS ((void)); 10690282Sobrienstatic void process_options PARAMS ((void)); 10790282Sobrienstatic void lang_independent_init PARAMS ((void)); 10890282Sobrienstatic int lang_dependent_init PARAMS ((const char *)); 10990282Sobrienstatic void init_asm_output PARAMS ((const char *)); 11090282Sobrienstatic void finalize PARAMS ((void)); 11118334Speter 11290282Sobrienstatic void set_target_switch PARAMS ((const char *)); 11390282Sobrienstatic const char *decl_name PARAMS ((tree, int)); 11450615Sobrien 11590282Sobrienstatic void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN; 11690282Sobrienstatic void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN; 11790282Sobrienstatic void set_float_handler PARAMS ((jmp_buf)); 11890282Sobrienstatic void compile_file PARAMS ((void)); 11990282Sobrienstatic void display_help PARAMS ((void)); 12090282Sobrienstatic void display_target_options PARAMS ((void)); 12118334Speter 12290282Sobrienstatic void decode_d_option PARAMS ((const char *)); 12390282Sobrienstatic int decode_f_option PARAMS ((const char *)); 12490282Sobrienstatic int decode_W_option PARAMS ((const char *)); 12590282Sobrienstatic int decode_g_option PARAMS ((const char *)); 12690282Sobrienstatic unsigned int independent_decode_option PARAMS ((int, char **)); 12790282Sobrien 12890282Sobrienstatic void print_version PARAMS ((FILE *, const char *)); 12990282Sobrienstatic int print_single_switch PARAMS ((FILE *, int, int, const char *, 13052558Sobrien const char *, const char *, 13152558Sobrien const char *, const char *)); 13290282Sobrienstatic void print_switch_values PARAMS ((FILE *, int, int, const char *, 13352558Sobrien const char *, const char *)); 13452558Sobrien 13550615Sobrien/* Length of line when printing switch values. */ 13650615Sobrien#define MAX_LINE 75 13718334Speter 13818334Speter/* Name of program invoked, sans directories. */ 13918334Speter 14090282Sobrienconst char *progname; 14118334Speter 14290282Sobrien/* Copy of arguments to toplev_main. */ 14318334Speterint save_argc; 14418334Speterchar **save_argv; 14518334Speter 14618334Speter/* Name of current original source file (what was input to cpp). 14718334Speter This comes from each #-command in the actual input. */ 14818334Speter 14990282Sobrienconst char *input_filename; 15018334Speter 15118334Speter/* Name of top-level original source file (what was input to cpp). 15218334Speter This comes from the #-command at the beginning of the actual input. 15318334Speter If there isn't any there, then this is the cc1 input file name. */ 15418334Speter 15590282Sobrienconst char *main_input_filename; 15618334Speter 15718334Speter/* Current line number in real source file. */ 15818334Speter 15918334Speterint lineno; 16018334Speter 16152558Sobrien/* Nonzero if it is unsafe to create any new pseudo registers. */ 16252558Sobrienint no_new_pseudos; 16352558Sobrien 16418334Speter/* Stack of currently pending input files. */ 16518334Speter 16618334Speterstruct file_stack *input_file_stack; 16718334Speter 16818334Speter/* Incremented on each change to input_file_stack. */ 16918334Speterint input_file_stack_tick; 17018334Speter 17118334Speter/* Name to use as base of names for dump output files. */ 17218334Speter 17352558Sobrienconst char *dump_base_name; 17418334Speter 17590282Sobrien/* Format to use to print dumpfile index value */ 17690282Sobrien#ifndef DUMPFILE_FORMAT 17790282Sobrien#define DUMPFILE_FORMAT ".%02d." 17890282Sobrien#endif 17990282Sobrien 18018334Speter/* Bit flags that specify the machine subtype we are compiling for. 18118334Speter Bits are tested using macros TARGET_... defined in the tm.h file 18218334Speter and set by `-m...' switches. Must be defined in rtlanal.c. */ 18318334Speter 18418334Speterextern int target_flags; 18518334Speter 18690282Sobrien/* Debug hooks - dependent upon command line options. */ 18718334Speter 18890282Sobrienstruct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; 18990282Sobrien 19090282Sobrien/* Describes a dump file. */ 19190282Sobrien 19290282Sobrienstruct dump_file_info 19390282Sobrien{ 19490282Sobrien /* The unique extension to apply, e.g. ".jump". */ 19590282Sobrien const char *const extension; 19690282Sobrien 19790282Sobrien /* The -d<c> character that enables this dump file. */ 19890282Sobrien char const debug_switch; 19990282Sobrien 20090282Sobrien /* True if there is a corresponding graph dump file. */ 20190282Sobrien char const graph_dump_p; 20290282Sobrien 20390282Sobrien /* True if the user selected this dump. */ 20490282Sobrien char enabled; 20590282Sobrien 20690282Sobrien /* True if the files have been initialized (ie truncated). */ 20790282Sobrien char initialized; 20890282Sobrien}; 20990282Sobrien 21090282Sobrien/* Enumerate the extant dump files. */ 21190282Sobrien 21290282Sobrienenum dump_file_index 21390282Sobrien{ 21490282Sobrien DFI_rtl, 21590282Sobrien DFI_sibling, 21690282Sobrien DFI_eh, 21790282Sobrien DFI_jump, 21890282Sobrien DFI_ssa, 21990282Sobrien DFI_ssa_ccp, 22090282Sobrien DFI_ssa_dce, 22190282Sobrien DFI_ussa, 22290282Sobrien DFI_cse, 22390282Sobrien DFI_addressof, 22490282Sobrien DFI_gcse, 22590282Sobrien DFI_loop, 22690282Sobrien DFI_cse2, 22790282Sobrien DFI_cfg, 22890282Sobrien DFI_bp, 22990282Sobrien DFI_life, 23090282Sobrien DFI_combine, 23190282Sobrien DFI_ce, 23290282Sobrien DFI_regmove, 23390282Sobrien DFI_sched, 23490282Sobrien DFI_lreg, 23590282Sobrien DFI_greg, 23690282Sobrien DFI_postreload, 23790282Sobrien DFI_flow2, 23890282Sobrien DFI_peephole2, 23990282Sobrien DFI_rnreg, 24090282Sobrien DFI_ce2, 24190282Sobrien DFI_sched2, 24290282Sobrien DFI_stack, 24390282Sobrien DFI_bbro, 24490282Sobrien DFI_mach, 24590282Sobrien DFI_dbr, 24690282Sobrien DFI_MAX 24790282Sobrien}; 24890282Sobrien 24990282Sobrien/* Describes all the dump files. Should be kept in order of the 25090282Sobrien pass and in sync with dump_file_index above. 25190282Sobrien 25290282Sobrien Remaining -d letters: 25390282Sobrien 25490282Sobrien " o q u " 25590282Sobrien " H JK OPQ TUV YZ" 25690282Sobrien*/ 25790282Sobrien 25890282Sobrienstatic struct dump_file_info dump_file[DFI_MAX] = 25990282Sobrien{ 26090282Sobrien { "rtl", 'r', 0, 0, 0 }, 26190282Sobrien { "sibling", 'i', 0, 0, 0 }, 26290282Sobrien { "eh", 'h', 0, 0, 0 }, 26390282Sobrien { "jump", 'j', 0, 0, 0 }, 26490282Sobrien { "ssa", 'e', 1, 0, 0 }, 26590282Sobrien { "ssaccp", 'W', 1, 0, 0 }, 26690282Sobrien { "ssadce", 'X', 1, 0, 0 }, 26790282Sobrien { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */ 26890282Sobrien { "cse", 's', 0, 0, 0 }, 26990282Sobrien { "addressof", 'F', 0, 0, 0 }, 27090282Sobrien { "gcse", 'G', 1, 0, 0 }, 27190282Sobrien { "loop", 'L', 1, 0, 0 }, 27290282Sobrien { "cse2", 't', 1, 0, 0 }, 27390282Sobrien { "cfg", 'f', 1, 0, 0 }, 27490282Sobrien { "bp", 'b', 1, 0, 0 }, 27590282Sobrien { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */ 27690282Sobrien { "combine", 'c', 1, 0, 0 }, 27790282Sobrien { "ce", 'C', 1, 0, 0 }, 27890282Sobrien { "regmove", 'N', 1, 0, 0 }, 27990282Sobrien { "sched", 'S', 1, 0, 0 }, 28090282Sobrien { "lreg", 'l', 1, 0, 0 }, 28190282Sobrien { "greg", 'g', 1, 0, 0 }, 28290282Sobrien { "postreload", 'o', 1, 0, 0 }, 28390282Sobrien { "flow2", 'w', 1, 0, 0 }, 28490282Sobrien { "peephole2", 'z', 1, 0, 0 }, 28590282Sobrien { "rnreg", 'n', 1, 0, 0 }, 28690282Sobrien { "ce2", 'E', 1, 0, 0 }, 28790282Sobrien { "sched2", 'R', 1, 0, 0 }, 28890282Sobrien { "stack", 'k', 1, 0, 0 }, 28990282Sobrien { "bbro", 'B', 1, 0, 0 }, 29090282Sobrien { "mach", 'M', 1, 0, 0 }, 29190282Sobrien { "dbr", 'd', 0, 0, 0 }, 29290282Sobrien}; 29390282Sobrien 29490282Sobrienstatic int open_dump_file PARAMS ((enum dump_file_index, tree)); 29590282Sobrienstatic void close_dump_file PARAMS ((enum dump_file_index, 29690282Sobrien void (*) (FILE *, rtx), rtx)); 29790282Sobrien 29890282Sobrien/* Other flags saying which kinds of debugging dump have been requested. */ 29990282Sobrien 30090282Sobrienint rtl_dump_and_exit; 30190282Sobrienint flag_print_asm_name; 30290282Sobrienstatic int version_flag; 30390282Sobrienstatic char *filename; 30452558Sobrienenum graph_dump_types graph_dump_format; 30518334Speter 30618334Speter/* Name for output file of assembly code, specified with -o. */ 30718334Speter 30818334Speterchar *asm_file_name; 30918334Speter 31018334Speter/* Value of the -G xx switch, and whether it was passed or not. */ 31118334Speterint g_switch_value; 31218334Speterint g_switch_set; 31318334Speter 31418334Speter/* Type(s) of debugging information we are producing (if any). 31518334Speter See flags.h for the definitions of the different possible 31618334Speter types of debugging information. */ 31718334Speterenum debug_info_type write_symbols = NO_DEBUG; 31818334Speter 31918334Speter/* Level of debugging information we are producing. See flags.h 32018334Speter for the definitions of the different possible levels. */ 32118334Speterenum debug_info_level debug_info_level = DINFO_LEVEL_NONE; 32218334Speter 32318334Speter/* Nonzero means use GNU-only extensions in the generated symbolic 32418334Speter debugging information. */ 32518334Speter/* Currently, this only has an effect when write_symbols is set to 32618334Speter DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */ 32718334Speterint use_gnu_debug_info_extensions = 0; 32818334Speter 32918334Speter/* Nonzero means do optimizations. -O. 33018334Speter Particular numeric values stand for particular amounts of optimization; 33118334Speter thus, -O2 stores 2 here. However, the optimizations beyond the basic 33218334Speter ones are not controlled directly by this variable. Instead, they are 33318334Speter controlled by individual `flag_...' variables that are defaulted 33418334Speter based on this variable. */ 33518334Speter 33618334Speterint optimize = 0; 33718334Speter 33850615Sobrien/* Nonzero means optimize for size. -Os. 33950615Sobrien The only valid values are zero and non-zero. When optimize_size is 34050615Sobrien non-zero, optimize defaults to 2, but certain individual code 34150615Sobrien bloating optimizations are disabled. */ 34250615Sobrien 34350615Sobrienint optimize_size = 0; 34450615Sobrien 34590282Sobrien/* Nonzero if we should exit after parsing options. */ 34690282Sobrienstatic int exit_after_options = 0; 34718334Speter 34890282Sobrien/* The FUNCTION_DECL for the function currently being compiled, 34990282Sobrien or 0 if between functions. */ 35090282Sobrientree current_function_decl; 35118334Speter 35290282Sobrien/* Set to the FUNC_BEGIN label of the current function, or NULL_TREE 35390282Sobrien if none. */ 35490282Sobrientree current_function_func_begin_label; 35590282Sobrien 35650615Sobrien/* Pointer to function to compute the name to use to print a declaration. 35750615Sobrien DECL is the declaration in question. 35850615Sobrien VERBOSITY determines what information will be printed: 35950615Sobrien 0: DECL_NAME, demangled as necessary. 36050615Sobrien 1: and scope information. 36150615Sobrien 2: and any other information that might be interesting, such as function 36250615Sobrien parameter types in C++. */ 36318334Speter 36490282Sobrienconst char *(*decl_printable_name) PARAMS ((tree, int)); 36518334Speter 36618334Speter/* Pointer to function to compute rtl for a language-specific tree code. */ 36718334Speter 36852558Sobrientypedef rtx (*lang_expand_expr_t) 36990282Sobrien PARAMS ((union tree_node *, rtx, enum machine_mode, 37052558Sobrien enum expand_modifier modifier)); 37118334Speter 37252558Sobrienlang_expand_expr_t lang_expand_expr = 0; 37352558Sobrien 37418334Speter/* Pointer to function to finish handling an incomplete decl at the 37518334Speter end of compilation. */ 37618334Speter 37790282Sobrienvoid (*incomplete_decl_finalize_hook) PARAMS ((tree)) = 0; 37818334Speter 37990282Sobrien/* Nonzero if doing dwarf2 duplicate elimination. */ 38090282Sobrien 38190282Sobrienint flag_eliminate_dwarf2_dups = 0; 38290282Sobrien 38318334Speter/* Nonzero if generating code to do profiling. */ 38418334Speter 38518334Speterint profile_flag = 0; 38618334Speter 38750615Sobrien/* Nonzero if generating code to profile program flow graph arcs. */ 38850615Sobrien 38950615Sobrienint profile_arc_flag = 0; 39050615Sobrien 39150615Sobrien/* Nonzero if generating info for gcov to calculate line test coverage. */ 39250615Sobrien 39350615Sobrienint flag_test_coverage = 0; 39450615Sobrien 39550615Sobrien/* Nonzero indicates that branch taken probabilities should be calculated. */ 39650615Sobrien 39750615Sobrienint flag_branch_probabilities = 0; 39850615Sobrien 39990282Sobrien/* Nonzero if basic blocks should be reordered. */ 40090282Sobrien 40190282Sobrienint flag_reorder_blocks = 0; 40290282Sobrien 40390282Sobrien/* Nonzero if registers should be renamed. */ 40490282Sobrien 40590282Sobrienint flag_rename_registers = 0; 40690282Sobrienint flag_cprop_registers = 0; 40790282Sobrien 40818334Speter/* Nonzero for -pedantic switch: warn about anything 40918334Speter that standard spec forbids. */ 41018334Speter 41118334Speterint pedantic = 0; 41218334Speter 41318334Speter/* Temporarily suppress certain warnings. 41418334Speter This is set while reading code from a system header file. */ 41518334Speter 41618334Speterint in_system_header = 0; 41718334Speter 41890282Sobrien/* Don't print functions as they are compiled. -quiet. */ 41918334Speter 42090282Sobrienint quiet_flag = 0; 42118334Speter 42290282Sobrien/* Print times taken by the various passes. -ftime-report. */ 42318334Speter 42490282Sobrienint time_report = 0; 42590282Sobrien 42690282Sobrien/* Print memory still in use at end of compilation (which may have little 42790282Sobrien to do with peak memory consumption). -fmem-report. */ 42890282Sobrien 42990282Sobrienint mem_report = 0; 43090282Sobrien 43190282Sobrien/* Non-zero means to collect statistics which might be expensive 43290282Sobrien and to print them when we are done. */ 43390282Sobrienint flag_detailed_statistics = 0; 43490282Sobrien 43518334Speter 43618334Speter/* -f flags. */ 43718334Speter 43818334Speter/* Nonzero means `char' should be signed. */ 43918334Speter 44018334Speterint flag_signed_char; 44118334Speter 44218334Speter/* Nonzero means give an enum type only as many bytes as it needs. */ 44318334Speter 44418334Speterint flag_short_enums; 44518334Speter 44618334Speter/* Nonzero for -fcaller-saves: allocate values in regs that need to 44718334Speter be saved across function calls, if that produces overall better code. 44818334Speter Optional now, so people can test it. */ 44918334Speter 45018334Speter#ifdef DEFAULT_CALLER_SAVES 45118334Speterint flag_caller_saves = 1; 45218334Speter#else 45318334Speterint flag_caller_saves = 0; 45418334Speter#endif 45518334Speter 45618334Speter/* Nonzero if structures and unions should be returned in memory. 45718334Speter 45818334Speter This should only be defined if compatibility with another compiler or 45918334Speter with an ABI is needed, because it results in slower code. */ 46018334Speter 46118334Speter#ifndef DEFAULT_PCC_STRUCT_RETURN 46218334Speter#define DEFAULT_PCC_STRUCT_RETURN 1 46318334Speter#endif 46418334Speter 46518334Speter/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ 46618334Speter 46718334Speterint flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; 46818334Speter 46918334Speter/* Nonzero for -fforce-mem: load memory value into a register 47018334Speter before arithmetic on it. This makes better cse but slower compilation. */ 47118334Speter 47218334Speterint flag_force_mem = 0; 47318334Speter 47418334Speter/* Nonzero for -fforce-addr: load memory address into a register before 47518334Speter reference to memory. This makes better cse but slower compilation. */ 47618334Speter 47718334Speterint flag_force_addr = 0; 47818334Speter 47918334Speter/* Nonzero for -fdefer-pop: don't pop args after each function call; 48018334Speter instead save them up to pop many calls' args with one insns. */ 48118334Speter 48218334Speterint flag_defer_pop = 0; 48318334Speter 48418334Speter/* Nonzero for -ffloat-store: don't allocate floats and doubles 48518334Speter in extended-precision registers. */ 48618334Speter 48718334Speterint flag_float_store = 0; 48818334Speter 48918334Speter/* Nonzero for -fcse-follow-jumps: 49018334Speter have cse follow jumps to do a more extensive job. */ 49118334Speter 49218334Speterint flag_cse_follow_jumps; 49318334Speter 49418334Speter/* Nonzero for -fcse-skip-blocks: 49518334Speter have cse follow a branch around a block. */ 49618334Speterint flag_cse_skip_blocks; 49718334Speter 49818334Speter/* Nonzero for -fexpensive-optimizations: 49918334Speter perform miscellaneous relatively-expensive optimizations. */ 50018334Speterint flag_expensive_optimizations; 50118334Speter 50218334Speter/* Nonzero for -fthread-jumps: 50318334Speter have jump optimize output of loop. */ 50418334Speter 50518334Speterint flag_thread_jumps; 50618334Speter 50718334Speter/* Nonzero enables strength-reduction in loop.c. */ 50818334Speter 50918334Speterint flag_strength_reduce = 0; 51018334Speter 51118334Speter/* Nonzero enables loop unrolling in unroll.c. Only loops for which the 51218334Speter number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, 51318334Speter UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are 51418334Speter unrolled. */ 51518334Speter 51618334Speterint flag_unroll_loops; 51718334Speter 51818334Speter/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. 51918334Speter This is generally not a win. */ 52018334Speter 52118334Speterint flag_unroll_all_loops; 52218334Speter 52390282Sobrien/* Nonzero enables prefetch optimizations for arrays in loops. */ 52490282Sobrien 52590282Sobrienint flag_prefetch_loop_arrays; 52690282Sobrien 52750615Sobrien/* Nonzero forces all invariant computations in loops to be moved 52890282Sobrien outside the loop. */ 52950615Sobrien 53050615Sobrienint flag_move_all_movables = 0; 53150615Sobrien 53250615Sobrien/* Nonzero forces all general induction variables in loops to be 53390282Sobrien strength reduced. */ 53450615Sobrien 53550615Sobrienint flag_reduce_all_givs = 0; 53650615Sobrien 53750615Sobrien/* Nonzero to perform full register move optimization passes. This is the 53850615Sobrien default for -O2. */ 53950615Sobrien 54050615Sobrienint flag_regmove = 0; 54150615Sobrien 54218334Speter/* Nonzero for -fwritable-strings: 54318334Speter store string constants in data segment and don't uniquize them. */ 54418334Speter 54518334Speterint flag_writable_strings = 0; 54618334Speter 54718334Speter/* Nonzero means don't put addresses of constant functions in registers. 54818334Speter Used for compiling the Unix kernel, where strange substitutions are 54918334Speter done on the assembly output. */ 55018334Speter 55118334Speterint flag_no_function_cse = 0; 55218334Speter 55318334Speter/* Nonzero for -fomit-frame-pointer: 55418334Speter don't make a frame pointer in simple functions that don't require one. */ 55518334Speter 55618334Speterint flag_omit_frame_pointer = 0; 55718334Speter 55850615Sobrien/* Nonzero means place each function into its own section on those platforms 55950615Sobrien which support arbitrary section names and unlimited numbers of sections. */ 56050615Sobrien 56150615Sobrienint flag_function_sections = 0; 56250615Sobrien 56352558Sobrien/* ... and similar for data. */ 56490282Sobrien 56552558Sobrienint flag_data_sections = 0; 56652558Sobrien 56718334Speter/* Nonzero to inhibit use of define_optimization peephole opts. */ 56818334Speter 56918334Speterint flag_no_peephole = 0; 57018334Speter 57190282Sobrien/* Nonzero allows GCC to optimize sibling and tail recursive calls. */ 57218334Speter 57390282Sobrienint flag_optimize_sibling_calls = 0; 57418334Speter 57552558Sobrien/* Nonzero means the front end generally wants `errno' maintained by math 57690282Sobrien operations, like built-in SQRT. */ 57752558Sobrien 57852558Sobrienint flag_errno_math = 1; 57952558Sobrien 58090282Sobrien/* Nonzero means that unsafe floating-point math optimizations are allowed 58190282Sobrien for the sake of speed. IEEE compliance is not guaranteed, and operations 58290282Sobrien are allowed to assume that their arguments and results are "normal" 58390282Sobrien (e.g., nonnegative for SQRT). */ 58490282Sobrien 58590282Sobrienint flag_unsafe_math_optimizations = 0; 58690282Sobrien 58790282Sobrien/* Zero means that floating-point math operations cannot generate a 58890282Sobrien (user-visible) trap. This is the case, for example, in nonstop 58990282Sobrien IEEE 754 arithmetic. */ 59090282Sobrien 59190282Sobrienint flag_trapping_math = 1; 59290282Sobrien 59352558Sobrien/* 0 means straightforward implementation of complex divide acceptable. 59452558Sobrien 1 means wide ranges of inputs must work for complex divide. 59590282Sobrien 2 means C99-like requirements for complex divide (not yet implemented). */ 59652558Sobrien 59752558Sobrienint flag_complex_divide_method = 0; 59852558Sobrien 59918334Speter/* Nonzero means all references through pointers are volatile. */ 60018334Speter 60118334Speterint flag_volatile; 60218334Speter 60352558Sobrien/* Nonzero means treat all global and extern variables as volatile. */ 60418334Speter 60518334Speterint flag_volatile_global; 60618334Speter 60752558Sobrien/* Nonzero means treat all static variables as volatile. */ 60852558Sobrien 60952558Sobrienint flag_volatile_static; 61052558Sobrien 61118334Speter/* Nonzero means just do syntax checking; don't output anything. */ 61218334Speter 61318334Speterint flag_syntax_only = 0; 61418334Speter 61550615Sobrien/* Nonzero means perform global cse. */ 61650615Sobrien 61750615Sobrienstatic int flag_gcse; 61850615Sobrien 61990282Sobrien/* Nonzero means to use global dataflow analysis to eliminate 62090282Sobrien useless null pointer tests. */ 62190282Sobrien 62290282Sobrienstatic int flag_delete_null_pointer_checks; 62390282Sobrien 62490282Sobrien/* Nonzero means to do the enhanced load motion during gcse, which trys 62590282Sobrien to hoist loads by not killing them when a store to the same location 62690282Sobrien is seen. */ 62790282Sobrien 62890282Sobrienint flag_gcse_lm = 1; 62990282Sobrien 63090282Sobrien/* Nonzero means to perform store motion after gcse, which will try to 63190282Sobrien move stores closer to the exit block. Its not very effective without 63290282Sobrien flag_gcse_lm. */ 63390282Sobrien 63490282Sobrienint flag_gcse_sm = 1; 63590282Sobrien 63618334Speter/* Nonzero means to rerun cse after loop optimization. This increases 63718334Speter compilation time about 20% and picks up a few more common expressions. */ 63818334Speter 63918334Speterstatic int flag_rerun_cse_after_loop; 64018334Speter 64150615Sobrien/* Nonzero means to run loop optimizations twice. */ 64250615Sobrien 64350615Sobrienint flag_rerun_loop_opt; 64450615Sobrien 64518334Speter/* Nonzero for -finline-functions: ok to inline functions that look like 64618334Speter good inline candidates. */ 64718334Speter 64818334Speterint flag_inline_functions; 64918334Speter 65018334Speter/* Nonzero for -fkeep-inline-functions: even if we make a function 65118334Speter go inline everywhere, keep its definition around for debugging 65218334Speter purposes. */ 65318334Speter 65418334Speterint flag_keep_inline_functions; 65518334Speter 65618334Speter/* Nonzero means that functions will not be inlined. */ 65718334Speter 65896289Sobrienint flag_no_inline = 2; 65918334Speter 66096289Sobrien/* Nonzero means that we don't want inlining by virtue of -fno-inline, 66196289Sobrien not just because the tree inliner turned us off. */ 66296289Sobrien 66396289Sobrienint flag_really_no_inline = 2; 66496289Sobrien 66550615Sobrien/* Nonzero means that we should emit static const variables 66650615Sobrien regardless of whether or not optimization is turned on. */ 66750615Sobrien 66850615Sobrienint flag_keep_static_consts = 1; 66950615Sobrien 67018334Speter/* Nonzero means we should be saving declaration info into a .X file. */ 67118334Speter 67218334Speterint flag_gen_aux_info = 0; 67318334Speter 67418334Speter/* Specified name of aux-info file. */ 67518334Speter 67618334Speterstatic char *aux_info_file_name; 67718334Speter 67818334Speter/* Nonzero means make the text shared if supported. */ 67918334Speter 68018334Speterint flag_shared_data; 68118334Speter 68218334Speter/* Nonzero means schedule into delayed branch slots if supported. */ 68318334Speter 68418334Speterint flag_delayed_branch; 68518334Speter 68618334Speter/* Nonzero if we are compiling pure (sharable) code. 68718334Speter Value is 1 if we are doing reasonable (i.e. simple 68818334Speter offset into offset table) pic. Value is 2 if we can 68918334Speter only perform register offsets. */ 69018334Speter 69118334Speterint flag_pic; 69218334Speter 69350615Sobrien/* Nonzero means generate extra code for exception handling and enable 69450615Sobrien exception handling. */ 69518334Speter 69650615Sobrienint flag_exceptions; 69750615Sobrien 69890282Sobrien/* Nonzero means generate frame unwind info table when supported. */ 69950615Sobrien 70090282Sobrienint flag_unwind_tables = 0; 70150615Sobrien 70290282Sobrien/* Nonzero means generate frame unwind info table exact at each insn boundary */ 70390282Sobrien 70490282Sobrienint flag_asynchronous_unwind_tables = 0; 70590282Sobrien 70650615Sobrien/* Nonzero means don't place uninitialized global data in common storage 70750615Sobrien by default. */ 70850615Sobrien 70918334Speterint flag_no_common; 71018334Speter 71118334Speter/* Nonzero means pretend it is OK to examine bits of target floats, 71218334Speter even if that isn't true. The resulting code will have incorrect constants, 71318334Speter but the same series of instructions that the native compiler would make. */ 71418334Speter 71518334Speterint flag_pretend_float; 71618334Speter 71718334Speter/* Nonzero means change certain warnings into errors. 71818334Speter Usually these are warnings about failure to conform to some standard. */ 71918334Speter 72018334Speterint flag_pedantic_errors = 0; 72118334Speter 72218334Speter/* flag_schedule_insns means schedule insns within basic blocks (before 72318334Speter local_alloc). 72418334Speter flag_schedule_insns_after_reload means schedule insns after 72518334Speter global_alloc. */ 72618334Speter 72718334Speterint flag_schedule_insns = 0; 72818334Speterint flag_schedule_insns_after_reload = 0; 72918334Speter 73050615Sobrien/* The following flags have effect only for scheduling before register 73150615Sobrien allocation: 73250615Sobrien 73350615Sobrien flag_schedule_interblock means schedule insns accross basic blocks. 73450615Sobrien flag_schedule_speculative means allow speculative motion of non-load insns. 73550615Sobrien flag_schedule_speculative_load means allow speculative motion of some 73650615Sobrien load insns. 73750615Sobrien flag_schedule_speculative_load_dangerous allows speculative motion of more 73850615Sobrien load insns. */ 73950615Sobrien 74050615Sobrienint flag_schedule_interblock = 1; 74150615Sobrienint flag_schedule_speculative = 1; 74250615Sobrienint flag_schedule_speculative_load = 0; 74350615Sobrienint flag_schedule_speculative_load_dangerous = 0; 74450615Sobrien 74590282Sobrienint flag_single_precision_constant; 74650615Sobrien 74790282Sobrien/* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple 74890282Sobrien by a cheaper branch on a count register. */ 74990282Sobrienint flag_branch_on_count_reg = 1; 75090282Sobrien 75118334Speter/* -finhibit-size-directive inhibits output of .size for ELF. 75290282Sobrien This is used only for compiling crtstuff.c, 75318334Speter and it may be extended to other effects 75418334Speter needed for crtstuff.c on other systems. */ 75518334Speterint flag_inhibit_size_directive = 0; 75618334Speter 75718334Speter/* -fverbose-asm causes extra commentary information to be produced in 75818334Speter the generated assembly code (to make it more readable). This option 75918334Speter is generally only of use to those who actually need to read the 76050615Sobrien generated assembly code (perhaps while debugging the compiler itself). 76150615Sobrien -fno-verbose-asm, the default, causes the extra information 76250615Sobrien to be omitted and is useful when comparing two assembler files. */ 76318334Speter 76418334Speterint flag_verbose_asm = 0; 76518334Speter 76650615Sobrien/* -dA causes debug commentary information to be produced in 76750615Sobrien the generated assembly code (to make it more readable). This option 76850615Sobrien is generally only of use to those who actually need to read the 76950615Sobrien generated assembly code (perhaps while debugging the compiler itself). 77050615Sobrien Currently, this switch is only used by dwarfout.c; however, it is intended 77150615Sobrien to be a catchall for printing debug information in the assembler file. */ 77250615Sobrien 77350615Sobrienint flag_debug_asm = 0; 77450615Sobrien 77590282Sobrien/* -dP causes the rtl to be emitted as a comment in assembly. */ 77690282Sobrien 77790282Sobrienint flag_dump_rtl_in_asm = 0; 77890282Sobrien 77918334Speter/* -fgnu-linker specifies use of the GNU linker for initializations. 78018334Speter (Or, more generally, a linker that handles initializations.) 78118334Speter -fno-gnu-linker says that collect2 will be used. */ 78218334Speter#ifdef USE_COLLECT2 78318334Speterint flag_gnu_linker = 0; 78418334Speter#else 78518334Speterint flag_gnu_linker = 1; 78618334Speter#endif 78718334Speter 78890282Sobrien/* Enable SSA. */ 78990282Sobrienint flag_ssa = 0; 79090282Sobrien 79190282Sobrien/* Enable ssa conditional constant propagation. */ 79290282Sobrienint flag_ssa_ccp = 0; 79390282Sobrien 79490282Sobrien/* Enable ssa aggressive dead code elimination. */ 79590282Sobrienint flag_ssa_dce = 0; 79690282Sobrien 79790282Sobrien/* Tag all structures with __attribute__(packed). */ 79818334Speterint flag_pack_struct = 0; 79918334Speter 80038510Sbde/* Nonzero means that -Wformat accepts certain system-dependent formats. */ 80138510Sbdeint flag_format_extensions = 0; 80238510Sbde 80350615Sobrien/* Emit code to check for stack overflow; also may cause large objects 80450615Sobrien to be allocated dynamically. */ 80550615Sobrienint flag_stack_check; 80650615Sobrien 80790282Sobrien/* When non-NULL, indicates that whenever space is allocated on the 80890282Sobrien stack, the resulting stack pointer must not pass this 80990282Sobrien address---that is, for stacks that grow downward, the stack pointer 81090282Sobrien must always be greater than or equal to this address; for stacks 81190282Sobrien that grow upward, the stack pointer must be less than this address. 81290282Sobrien At present, the rtx may be either a REG or a SYMBOL_REF, although 81390282Sobrien the support provided depends on the backend. */ 81490282Sobrienrtx stack_limit_rtx; 81550615Sobrien 81650615Sobrien/* 0 if pointer arguments may alias each other. True in C. 81750615Sobrien 1 if pointer arguments may not alias each other but may alias 81850615Sobrien global variables. 81950615Sobrien 2 if pointer arguments may not alias each other and may not 82050615Sobrien alias global variables. True in Fortran. 82150615Sobrien This defaults to 0 for C. */ 82250615Sobrienint flag_argument_noalias = 0; 82350615Sobrien 82450615Sobrien/* Nonzero if we should do (language-dependent) alias analysis. 82550615Sobrien Typically, this analysis will assume that expressions of certain 82650615Sobrien types do not alias expressions of certain other types. Only used 82750615Sobrien if alias analysis (in general) is enabled. */ 82850615Sobrienint flag_strict_aliasing = 0; 82950615Sobrien 83052558Sobrien/* Instrument functions with calls at entry and exit, for profiling. */ 83152558Sobrienint flag_instrument_function_entry_exit = 0; 83250615Sobrien 83352558Sobrien/* Nonzero means ignore `#ident' directives. 0 means handle them. 83452558Sobrien On SVR4 targets, it also controls whether or not to emit a 83552558Sobrien string identifying the compiler. */ 83650615Sobrien 83752558Sobrienint flag_no_ident = 0; 83852558Sobrien 83990282Sobrien/* This will perform a peephole pass before sched2. */ 84090282Sobrienint flag_peephole2 = 0; 84190282Sobrien 84290282Sobrien/* This will try to guess branch probabilities. */ 84390282Sobrienint flag_guess_branch_prob = 0; 84490282Sobrien 84590282Sobrien/* -fbounded-pointers causes gcc to compile pointers as composite 84690282Sobrien objects occupying three words: the pointer value, the base address 84790282Sobrien of the referent object, and the address immediately beyond the end 84890282Sobrien of the referent object. The base and extent allow us to perform 84990282Sobrien runtime bounds checking. -fbounded-pointers implies -fcheck-bounds. */ 85090282Sobrienint flag_bounded_pointers = 0; 85190282Sobrien 85290282Sobrien/* -fcheck-bounds causes gcc to generate array bounds checks. 85390282Sobrien For C, C++: defaults to value of flag_bounded_pointers. 85490282Sobrien For ObjC: defaults to off. 85590282Sobrien For Java: defaults to on. 85690282Sobrien For Fortran: defaults to off. 85790282Sobrien For CHILL: defaults to off. */ 85890282Sobrienint flag_bounds_check = 0; 85990282Sobrien 86090282Sobrien/* This will attempt to merge constant section constants, if 1 only 86190282Sobrien string constants and constants from constant pool, if 2 also constant 86290282Sobrien variables. */ 86390282Sobrienint flag_merge_constants = 1; 86490282Sobrien 86590282Sobrien/* If one, renumber instruction UIDs to reduce the number of 86690282Sobrien unused UIDs if there are a lot of instructions. If greater than 86790282Sobrien one, unconditionally renumber instruction UIDs. */ 86890282Sobrienint flag_renumber_insns = 1; 86990282Sobrien 87090282Sobrien/* Values of the -falign-* flags: how much to align labels in code. 87190282Sobrien 0 means `use default', 1 means `don't align'. 87290282Sobrien For each variable, there is an _log variant which is the power 87390282Sobrien of two not less than the variable, for .align output. */ 87490282Sobrien 87590282Sobrienint align_loops; 87690282Sobrienint align_loops_log; 87790282Sobrienint align_loops_max_skip; 87890282Sobrienint align_jumps; 87990282Sobrienint align_jumps_log; 88090282Sobrienint align_jumps_max_skip; 88190282Sobrienint align_labels; 88290282Sobrienint align_labels_log; 88390282Sobrienint align_labels_max_skip; 88490282Sobrienint align_functions; 88590282Sobrienint align_functions_log; 88690282Sobrien 887104765Skan/* Like align_functions_log above, but used by front-ends to force the 888104765Skan minimum function alignment. Zero means no alignment is forced. */ 889104765Skanint force_align_functions_log; 890104765Skan 89150615Sobrien/* Table of supported debugging formats. */ 89290282Sobrienstatic const struct 89350615Sobrien{ 89490282Sobrien const char *const arg; 89550615Sobrien /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a 89650615Sobrien constant expression, we use NO_DEBUG in its place. */ 89790282Sobrien const enum debug_info_type debug_type; 89890282Sobrien const int use_extensions_p; 89990282Sobrien const char *const description; 90050615Sobrien} *da, 90150615Sobriendebug_args[] = 90250615Sobrien{ 90390282Sobrien { "", NO_DEBUG, DEFAULT_GDB_EXTENSIONS, 90490282Sobrien N_("Generate debugging info in default format") }, 90590282Sobrien { "gdb", NO_DEBUG, 1, N_("Generate debugging info in default extended format") }, 90650615Sobrien#ifdef DBX_DEBUGGING_INFO 90790282Sobrien { "stabs", DBX_DEBUG, 0, N_("Generate STABS format debug info") }, 90890282Sobrien { "stabs+", DBX_DEBUG, 1, N_("Generate extended STABS format debug info") }, 90950615Sobrien#endif 91050615Sobrien#ifdef DWARF_DEBUGGING_INFO 91190282Sobrien { "dwarf", DWARF_DEBUG, 0, N_("Generate DWARF-1 format debug info") }, 91290282Sobrien { "dwarf+", DWARF_DEBUG, 1, 91390282Sobrien N_("Generate extended DWARF-1 format debug info") }, 91450615Sobrien#endif 91550615Sobrien#ifdef DWARF2_DEBUGGING_INFO 91690282Sobrien { "dwarf-2", DWARF2_DEBUG, 0, N_("Generate DWARF-2 debug info") }, 91750615Sobrien#endif 91850615Sobrien#ifdef XCOFF_DEBUGGING_INFO 91990282Sobrien { "xcoff", XCOFF_DEBUG, 0, N_("Generate XCOFF format debug info") }, 92090282Sobrien { "xcoff+", XCOFF_DEBUG, 1, N_("Generate extended XCOFF format debug info") }, 92150615Sobrien#endif 92250615Sobrien#ifdef SDB_DEBUGGING_INFO 92390282Sobrien { "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") }, 92450615Sobrien#endif 92596289Sobrien#ifdef VMS_DEBUGGING_INFO 92696289Sobrien { "vms", VMS_DEBUG, 0, N_("Generate VMS format debug info") }, 92796289Sobrien#endif 92852558Sobrien { 0, 0, 0, 0 } 92950615Sobrien}; 93050615Sobrien 93150615Sobrientypedef struct 93250615Sobrien{ 93390282Sobrien const char *const string; 93490282Sobrien int *const variable; 93590282Sobrien const int on_value; 93690282Sobrien const char *const description; 93750615Sobrien} 93850615Sobrienlang_independent_options; 93950615Sobrien 94090282Sobrienint flag_trapv = 0; 94190282Sobrien 94252558Sobrien/* Add or remove a leading underscore from user symbols. */ 94352558Sobrienint flag_leading_underscore = -1; 94452558Sobrien 94552558Sobrien/* The user symbol prefix after having resolved same. */ 94652558Sobrienconst char *user_label_prefix; 94752558Sobrien 94890282Sobrienstatic const param_info lang_independent_params[] = { 94990282Sobrien#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT) \ 95090282Sobrien { OPTION, DEFAULT, HELP }, 95190282Sobrien#include "params.def" 95290282Sobrien#undef DEFPARAM 95390282Sobrien { NULL, 0, NULL } 95490282Sobrien}; 95590282Sobrien 95652558Sobrien/* A default for same. */ 95752558Sobrien#ifndef USER_LABEL_PREFIX 95852558Sobrien#define USER_LABEL_PREFIX "" 95952558Sobrien#endif 96052558Sobrien 96118334Speter/* Table of language-independent -f options. 96218334Speter STRING is the option name. VARIABLE is the address of the variable. 96318334Speter ON_VALUE is the value to store in VARIABLE 96418334Speter if `-fSTRING' is seen as an option. 96518334Speter (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ 96618334Speter 96790282Sobrienstatic const lang_independent_options f_options[] = 96818334Speter{ 96990282Sobrien {"format-extensions", &flag_format_extensions, 1, 97090282Sobrien N_("-Wformat accepts certain FreeBSD system-dependent formats") }, 97190282Sobrien {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1, 97290282Sobrien N_("Perform DWARF2 duplicate elimination") }, 97350615Sobrien {"float-store", &flag_float_store, 1, 97490282Sobrien N_("Do not store floats in registers") }, 97550615Sobrien {"volatile", &flag_volatile, 1, 97690282Sobrien N_("Consider all mem refs through pointers as volatile") }, 97750615Sobrien {"volatile-global", &flag_volatile_global, 1, 97890282Sobrien N_("Consider all mem refs to global data to be volatile") }, 97952558Sobrien {"volatile-static", &flag_volatile_static, 1, 98090282Sobrien N_("Consider all mem refs to static data to be volatile") }, 98150615Sobrien {"defer-pop", &flag_defer_pop, 1, 98290282Sobrien N_("Defer popping functions args from stack until later") }, 98350615Sobrien {"omit-frame-pointer", &flag_omit_frame_pointer, 1, 98490282Sobrien N_("When possible do not generate stack frames") }, 98590282Sobrien {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1, 98690282Sobrien N_("Optimize sibling and tail recursive calls") }, 98750615Sobrien {"cse-follow-jumps", &flag_cse_follow_jumps, 1, 98890282Sobrien N_("When running CSE, follow jumps to their targets") }, 98950615Sobrien {"cse-skip-blocks", &flag_cse_skip_blocks, 1, 99090282Sobrien N_("When running CSE, follow conditional jumps") }, 99150615Sobrien {"expensive-optimizations", &flag_expensive_optimizations, 1, 99290282Sobrien N_("Perform a number of minor, expensive optimizations") }, 99350615Sobrien {"thread-jumps", &flag_thread_jumps, 1, 99490282Sobrien N_("Perform jump threading optimizations") }, 99550615Sobrien {"strength-reduce", &flag_strength_reduce, 1, 99690282Sobrien N_("Perform strength reduction optimizations") }, 99750615Sobrien {"unroll-loops", &flag_unroll_loops, 1, 99890282Sobrien N_("Perform loop unrolling when iteration count is known") }, 99950615Sobrien {"unroll-all-loops", &flag_unroll_all_loops, 1, 100090282Sobrien N_("Perform loop unrolling for all loops") }, 100190282Sobrien {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1, 100290282Sobrien N_("Generate prefetch instructions, if available, for arrays in loops") }, 100350615Sobrien {"move-all-movables", &flag_move_all_movables, 1, 100490282Sobrien N_("Force all loop invariant computations out of loops") }, 100550615Sobrien {"reduce-all-givs", &flag_reduce_all_givs, 1, 100690282Sobrien N_("Strength reduce all loop general induction variables") }, 100750615Sobrien {"writable-strings", &flag_writable_strings, 1, 100890282Sobrien N_("Store strings in writable data section") }, 100950615Sobrien {"peephole", &flag_no_peephole, 0, 101090282Sobrien N_("Enable machine specific peephole optimizations") }, 101150615Sobrien {"force-mem", &flag_force_mem, 1, 101290282Sobrien N_("Copy memory operands into registers before using") }, 101350615Sobrien {"force-addr", &flag_force_addr, 1, 101490282Sobrien N_("Copy memory address constants into regs before using") }, 101550615Sobrien {"function-cse", &flag_no_function_cse, 0, 101690282Sobrien N_("Allow function addresses to be held in registers") }, 101750615Sobrien {"inline-functions", &flag_inline_functions, 1, 101890282Sobrien N_("Integrate simple functions into their callers") }, 101950615Sobrien {"keep-inline-functions", &flag_keep_inline_functions, 1, 102090282Sobrien N_("Generate code for funcs even if they are fully inlined") }, 102150615Sobrien {"inline", &flag_no_inline, 0, 102290282Sobrien N_("Pay attention to the 'inline' keyword") }, 102350615Sobrien {"keep-static-consts", &flag_keep_static_consts, 1, 102490282Sobrien N_("Emit static const variables even if they are not used") }, 102550615Sobrien {"syntax-only", &flag_syntax_only, 1, 102690282Sobrien N_("Check for syntax errors, then stop") }, 102750615Sobrien {"shared-data", &flag_shared_data, 1, 102890282Sobrien N_("Mark data as shared rather than private") }, 102950615Sobrien {"caller-saves", &flag_caller_saves, 1, 103090282Sobrien N_("Enable saving registers around function calls") }, 103150615Sobrien {"pcc-struct-return", &flag_pcc_struct_return, 1, 103290282Sobrien N_("Return 'short' aggregates in memory, not registers") }, 103350615Sobrien {"reg-struct-return", &flag_pcc_struct_return, 0, 103490282Sobrien N_("Return 'short' aggregates in registers") }, 103550615Sobrien {"delayed-branch", &flag_delayed_branch, 1, 103690282Sobrien N_("Attempt to fill delay slots of branch instructions") }, 103750615Sobrien {"gcse", &flag_gcse, 1, 103890282Sobrien N_("Perform the global common subexpression elimination") }, 103990282Sobrien {"gcse-lm", &flag_gcse_lm, 1, 104090282Sobrien N_("Perform enhanced load motion during global subexpression elimination") }, 104190282Sobrien {"gcse-sm", &flag_gcse_sm, 1, 104290282Sobrien N_("Perform store motion after global subexpression elimination") }, 104350615Sobrien {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1, 104490282Sobrien N_("Run CSE pass after loop optimizations") }, 104550615Sobrien {"rerun-loop-opt", &flag_rerun_loop_opt, 1, 104690282Sobrien N_("Run the loop optimizer twice") }, 104790282Sobrien {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1, 104890282Sobrien N_("Delete useless null pointer checks") }, 104950615Sobrien {"pretend-float", &flag_pretend_float, 1, 105090282Sobrien N_("Pretend that host and target use the same FP format") }, 105150615Sobrien {"schedule-insns", &flag_schedule_insns, 1, 105290282Sobrien N_("Reschedule instructions before register allocation") }, 105350615Sobrien {"schedule-insns2", &flag_schedule_insns_after_reload, 1, 105490282Sobrien N_("Reschedule instructions after register allocation") }, 105550615Sobrien {"sched-interblock",&flag_schedule_interblock, 1, 105690282Sobrien N_("Enable scheduling across basic blocks") }, 105750615Sobrien {"sched-spec",&flag_schedule_speculative, 1, 105890282Sobrien N_("Allow speculative motion of non-loads") }, 105950615Sobrien {"sched-spec-load",&flag_schedule_speculative_load, 1, 106090282Sobrien N_("Allow speculative motion of some loads") }, 106150615Sobrien {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1, 106290282Sobrien N_("Allow speculative motion of more loads") }, 106350615Sobrien {"branch-count-reg",&flag_branch_on_count_reg, 1, 106490282Sobrien N_("Replace add,compare,branch with branch on count reg") }, 106550615Sobrien {"pic", &flag_pic, 1, 106690282Sobrien N_("Generate position independent code, if possible") }, 106750615Sobrien {"PIC", &flag_pic, 2, ""}, 106850615Sobrien {"exceptions", &flag_exceptions, 1, 106990282Sobrien N_("Enable exception handling") }, 107090282Sobrien {"unwind-tables", &flag_unwind_tables, 1, 107190282Sobrien N_("Just generate unwind tables for exception handling") }, 107290282Sobrien {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1, 107390282Sobrien N_("Generate unwind tables exact at each instruction boundary") }, 107490282Sobrien {"non-call-exceptions", &flag_non_call_exceptions, 1, 107590282Sobrien N_("Support synchronous non-call exceptions") }, 107650615Sobrien {"profile-arcs", &profile_arc_flag, 1, 107790282Sobrien N_("Insert arc based program profiling code") }, 107850615Sobrien {"test-coverage", &flag_test_coverage, 1, 107990282Sobrien N_("Create data files needed by gcov") }, 108050615Sobrien {"branch-probabilities", &flag_branch_probabilities, 1, 108190282Sobrien N_("Use profiling information for branch probabilities") }, 108290282Sobrien {"reorder-blocks", &flag_reorder_blocks, 1, 108390282Sobrien N_("Reorder basic blocks to improve code placement") }, 108490282Sobrien {"rename-registers", &flag_rename_registers, 1, 108590282Sobrien N_("Do the register renaming optimization pass") }, 108690282Sobrien {"cprop-registers", &flag_cprop_registers, 1, 108790282Sobrien N_("Do the register copy-propagation optimization pass") }, 108850615Sobrien {"common", &flag_no_common, 0, 108990282Sobrien N_("Do not put uninitialized globals in the common section") }, 109050615Sobrien {"inhibit-size-directive", &flag_inhibit_size_directive, 1, 109190282Sobrien N_("Do not generate .size directives") }, 109250615Sobrien {"function-sections", &flag_function_sections, 1, 109390282Sobrien N_("place each function into its own section") }, 109452558Sobrien {"data-sections", &flag_data_sections, 1, 109590282Sobrien N_("place data items into their own section") }, 109650615Sobrien {"verbose-asm", &flag_verbose_asm, 1, 109790282Sobrien N_("Add extra commentry to assembler output") }, 109850615Sobrien {"gnu-linker", &flag_gnu_linker, 1, 109990282Sobrien N_("Output GNU ld formatted global initializers") }, 110050615Sobrien {"regmove", &flag_regmove, 1, 110190282Sobrien N_("Enables a register move optimization") }, 110252558Sobrien {"optimize-register-move", &flag_regmove, 1, 110390282Sobrien N_("Do the full regmove optimization pass") }, 110450615Sobrien {"pack-struct", &flag_pack_struct, 1, 110590282Sobrien N_("Pack structure members together without holes") }, 110650615Sobrien {"stack-check", &flag_stack_check, 1, 110790282Sobrien N_("Insert stack checking code into the program") }, 110850615Sobrien {"argument-alias", &flag_argument_noalias, 0, 110990282Sobrien N_("Specify that arguments may alias each other & globals") }, 111050615Sobrien {"argument-noalias", &flag_argument_noalias, 1, 111190282Sobrien N_("Assume arguments may alias globals but not each other") }, 111250615Sobrien {"argument-noalias-global", &flag_argument_noalias, 2, 111390282Sobrien N_("Assume arguments do not alias each other or globals") }, 111450615Sobrien {"strict-aliasing", &flag_strict_aliasing, 1, 111590282Sobrien N_("Assume strict aliasing rules apply") }, 111690282Sobrien {"align-loops", &align_loops, 0, 111790282Sobrien N_("Align the start of loops") }, 111890282Sobrien {"align-jumps", &align_jumps, 0, 111990282Sobrien N_("Align labels which are only reached by jumping") }, 112090282Sobrien {"align-labels", &align_labels, 0, 112190282Sobrien N_("Align all labels") }, 112290282Sobrien {"align-functions", &align_functions, 0, 112390282Sobrien N_("Align the start of functions") }, 112490282Sobrien {"merge-constants", &flag_merge_constants, 1, 112590282Sobrien N_("Attempt to merge identical constants accross compilation units") }, 112690282Sobrien {"merge-all-constants", &flag_merge_constants, 2, 112790282Sobrien N_("Attempt to merge identical constants and constant variables") }, 112852558Sobrien {"dump-unnumbered", &flag_dump_unnumbered, 1, 112990282Sobrien N_("Suppress output of instruction numbers and line number notes in debugging dumps") }, 113052558Sobrien {"instrument-functions", &flag_instrument_function_entry_exit, 1, 113190282Sobrien N_("Instrument function entry/exit with profiling calls") }, 113290282Sobrien {"ssa", &flag_ssa, 1, 113390282Sobrien N_("Enable SSA optimizations") }, 113490282Sobrien {"ssa-ccp", &flag_ssa_ccp, 1, 113590282Sobrien N_("Enable SSA conditional constant propagation") }, 113690282Sobrien {"ssa-dce", &flag_ssa_dce, 1, 113790282Sobrien N_("Enable aggressive SSA dead code elimination") }, 113852558Sobrien {"leading-underscore", &flag_leading_underscore, 1, 113990282Sobrien N_("External symbols have a leading underscore") }, 114052558Sobrien {"ident", &flag_no_ident, 0, 114190282Sobrien N_("Process #ident directives") }, 114290282Sobrien { "peephole2", &flag_peephole2, 1, 114390282Sobrien N_("Enables an rtl peephole pass run before sched2") }, 114490282Sobrien { "guess-branch-probability", &flag_guess_branch_prob, 1, 114590282Sobrien N_("Enables guessing of branch probabilities") }, 114690282Sobrien {"math-errno", &flag_errno_math, 1, 114790282Sobrien N_("Set errno after built-in math functions") }, 114890282Sobrien {"trapping-math", &flag_trapping_math, 1, 114990282Sobrien N_("Floating-point operations can trap") }, 115090282Sobrien {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1, 115190282Sobrien N_("Allow math optimizations that may violate IEEE or ANSI standards") }, 115290282Sobrien {"bounded-pointers", &flag_bounded_pointers, 1, 115390282Sobrien N_("Compile pointers as triples: value, base & end") }, 115490282Sobrien {"bounds-check", &flag_bounds_check, 1, 115590282Sobrien N_("Generate code to check bounds before dereferencing pointers and arrays") }, 115690282Sobrien {"single-precision-constant", &flag_single_precision_constant, 1, 115790282Sobrien N_("Convert floating point constant to single precision constant") }, 115890282Sobrien {"time-report", &time_report, 1, 115990282Sobrien N_("Report time taken by each compiler pass at end of run") }, 116090282Sobrien {"mem-report", &mem_report, 1, 116190282Sobrien N_("Report on permanent memory allocation at end of run") }, 116290282Sobrien { "trapv", &flag_trapv, 1, 116390282Sobrien N_("Trap for signed overflow in addition / subtraction / multiplication") }, 116418334Speter}; 116518334Speter 116618334Speter/* Table of language-specific options. */ 116718334Speter 116890282Sobrienstatic const struct lang_opt 116918334Speter{ 117090282Sobrien const char *const option; 117190282Sobrien const char *const description; 117250615Sobrien} 117350615Sobriendocumented_lang_options[] = 117450615Sobrien{ 117550615Sobrien /* In order not to overload the --help output, the convention 117650615Sobrien used here is to only describe those options which are not 117750615Sobrien enabled by default. */ 117818334Speter 117990282Sobrien { "-ansi", 118090282Sobrien N_("Compile just for ISO C89") }, 118150615Sobrien { "-fallow-single-precision", 118290282Sobrien N_("Do not promote floats to double if using -traditional") }, 118390282Sobrien { "-std= ", 118490282Sobrien N_("Determine language standard") }, 118518334Speter 118650615Sobrien { "-fsigned-bitfields", "" }, 118790282Sobrien { "-funsigned-bitfields", 118890282Sobrien N_("Make bit-fields by unsigned by default") }, 118950615Sobrien { "-fno-signed-bitfields", "" }, 119050615Sobrien { "-fno-unsigned-bitfields","" }, 119190282Sobrien { "-fsigned-char", 119290282Sobrien N_("Make 'char' be signed by default") }, 119390282Sobrien { "-funsigned-char", 119490282Sobrien N_("Make 'char' be unsigned by default") }, 119550615Sobrien { "-fno-signed-char", "" }, 119650615Sobrien { "-fno-unsigned-char", "" }, 119718334Speter 119850615Sobrien { "-ftraditional", "" }, 119990282Sobrien { "-traditional", 120090282Sobrien N_("Attempt to support traditional K&R style C") }, 120150615Sobrien { "-fnotraditional", "" }, 120250615Sobrien { "-fno-traditional", "" }, 120318334Speter 120450615Sobrien { "-fasm", "" }, 120590282Sobrien { "-fno-asm", 120690282Sobrien N_("Do not recognize the 'asm' keyword") }, 120750615Sobrien { "-fbuiltin", "" }, 120890282Sobrien { "-fno-builtin", 120990282Sobrien N_("Do not recognize any built in functions") }, 121090282Sobrien { "-fhosted", 121190282Sobrien N_("Assume normal C execution environment") }, 121250615Sobrien { "-fno-hosted", "" }, 121350615Sobrien { "-ffreestanding", 121490282Sobrien N_("Assume that standard libraries & main might not exist") }, 121550615Sobrien { "-fno-freestanding", "" }, 121690282Sobrien { "-fcond-mismatch", 121790282Sobrien N_("Allow different types as args of ? operator") }, 121850615Sobrien { "-fno-cond-mismatch", "" }, 121990282Sobrien { "-fdollars-in-identifiers", 122090282Sobrien N_("Allow the use of $ inside identifiers") }, 122150615Sobrien { "-fno-dollars-in-identifiers", "" }, 122290282Sobrien { "-fpreprocessed", "" }, 122390282Sobrien { "-fno-preprocessed", "" }, 122490282Sobrien { "-fshort-double", 122590282Sobrien N_("Use the same size for double as for float") }, 122650615Sobrien { "-fno-short-double", "" }, 122790282Sobrien { "-fshort-enums", 122890282Sobrien N_("Use the smallest fitting integer to hold enums") }, 122950615Sobrien { "-fno-short-enums", "" }, 123090282Sobrien { "-fshort-wchar", 123190282Sobrien N_("Override the underlying type for wchar_t to `unsigned short'") }, 123290282Sobrien { "-fno-short-wchar", "" }, 123318334Speter 123490282Sobrien { "-Wall", 123590282Sobrien N_("Enable most warning messages") }, 123650615Sobrien { "-Wbad-function-cast", 123790282Sobrien N_("Warn about casting functions to incompatible types") }, 123850615Sobrien { "-Wno-bad-function-cast", "" }, 123952558Sobrien { "-Wno-missing-noreturn", "" }, 124090282Sobrien { "-Wmissing-format-attribute", 124190282Sobrien N_("Warn about functions which might be candidates for format attributes") }, 124290282Sobrien { "-Wno-missing-format-attribute", "" }, 124390282Sobrien { "-Wcast-qual", 124490282Sobrien N_("Warn about casts which discard qualifiers") }, 124550615Sobrien { "-Wno-cast-qual", "" }, 124690282Sobrien { "-Wchar-subscripts", 124790282Sobrien N_("Warn about subscripts whose type is 'char'") }, 124850615Sobrien { "-Wno-char-subscripts", "" }, 124990282Sobrien { "-Wcomment", 125090282Sobrien N_("Warn if nested comments are detected") }, 125152558Sobrien { "-Wno-comment", "" }, 125290282Sobrien { "-Wcomments", 125390282Sobrien N_("Warn if nested comments are detected") }, 125452558Sobrien { "-Wno-comments", "" }, 125590282Sobrien { "-Wconversion", 125690282Sobrien N_("Warn about possibly confusing type conversions") }, 125750615Sobrien { "-Wno-conversion", "" }, 125890282Sobrien { "-Wformat", 125990282Sobrien N_("Warn about printf/scanf/strftime/strfmon format anomalies") }, 126050615Sobrien { "-Wno-format", "" }, 126190282Sobrien { "-Wformat-y2k", "" }, 126290282Sobrien { "-Wno-format-y2k", 126390282Sobrien N_("Don't warn about strftime formats yielding 2 digit years") }, 126490282Sobrien { "-Wformat-extra-args", "" }, 126590282Sobrien { "-Wno-format-extra-args", 126690282Sobrien N_("Don't warn about too many arguments to format functions") }, 126790282Sobrien { "-Wformat-nonliteral", 126890282Sobrien N_("Warn about non-string-literal format strings") }, 126990282Sobrien { "-Wno-format-nonliteral", "" }, 127090282Sobrien { "-Wformat-security", 127190282Sobrien N_("Warn about possible security problems with format functions") }, 127290282Sobrien { "-Wno-format-security", "" }, 127350615Sobrien { "-Wimplicit-function-declaration", 127490282Sobrien N_("Warn about implicit function declarations") }, 127550615Sobrien { "-Wno-implicit-function-declaration", "" }, 127650615Sobrien { "-Werror-implicit-function-declaration", "" }, 127790282Sobrien { "-Wimplicit-int", 127890282Sobrien N_("Warn when a declaration does not specify a type") }, 127950615Sobrien { "-Wno-implicit-int", "" }, 128050615Sobrien { "-Wimplicit", "" }, 128150615Sobrien { "-Wno-implicit", "" }, 128290282Sobrien { "-Wimport", 128390282Sobrien N_("Warn about the use of the #import directive") }, 128450615Sobrien { "-Wno-import", "" }, 128550615Sobrien { "-Wlong-long","" }, 128690282Sobrien { "-Wno-long-long", 128790282Sobrien N_("Do not warn about using 'long long' when -pedantic") }, 128890282Sobrien { "-Wmain", 128990282Sobrien N_("Warn about suspicious declarations of main") }, 129050615Sobrien { "-Wno-main", "" }, 129150615Sobrien { "-Wmissing-braces", 129290282Sobrien N_("Warn about possibly missing braces around initializers") }, 129350615Sobrien { "-Wno-missing-braces", "" }, 129450615Sobrien { "-Wmissing-declarations", 129590282Sobrien N_("Warn about global funcs without previous declarations") }, 129650615Sobrien { "-Wno-missing-declarations", "" }, 129790282Sobrien { "-Wmissing-prototypes", 129890282Sobrien N_("Warn about global funcs without prototypes") }, 129950615Sobrien { "-Wno-missing-prototypes", "" }, 130090282Sobrien { "-Wmultichar", 130190282Sobrien N_("Warn about use of multicharacter literals") }, 130250615Sobrien { "-Wno-multichar", "" }, 130390282Sobrien { "-Wnested-externs", 130490282Sobrien N_("Warn about externs not at file scope level") }, 130550615Sobrien { "-Wno-nested-externs", "" }, 130690282Sobrien { "-Wparentheses", 130790282Sobrien N_("Warn about possible missing parentheses") }, 130850615Sobrien { "-Wno-parentheses", "" }, 130990282Sobrien { "-Wsequence-point", 131090282Sobrien N_("Warn about possible violations of sequence point rules") }, 131190282Sobrien { "-Wno-sequence-point", "" }, 131290282Sobrien { "-Wpointer-arith", 131390282Sobrien N_("Warn about function pointer arithmetic") }, 131450615Sobrien { "-Wno-pointer-arith", "" }, 131550615Sobrien { "-Wredundant-decls", 131690282Sobrien N_("Warn about multiple declarations of the same object") }, 131750615Sobrien { "-Wno-redundant-decls", "" }, 131890282Sobrien { "-Wsign-compare", 131990282Sobrien N_("Warn about signed/unsigned comparisons") }, 132050615Sobrien { "-Wno-sign-compare", "" }, 132190282Sobrien { "-Wfloat-equal", 132290282Sobrien N_("Warn about testing equality of floating point numbers") }, 132390282Sobrien { "-Wno-float-equal", "" }, 132490282Sobrien { "-Wunknown-pragmas", 132590282Sobrien N_("Warn about unrecognized pragmas") }, 132650615Sobrien { "-Wno-unknown-pragmas", "" }, 132790282Sobrien { "-Wstrict-prototypes", 132890282Sobrien N_("Warn about non-prototyped function decls") }, 132950615Sobrien { "-Wno-strict-prototypes", "" }, 133090282Sobrien { "-Wtraditional", 133190282Sobrien N_("Warn about constructs whose meaning change in ISO C") }, 133250615Sobrien { "-Wno-traditional", "" }, 133390282Sobrien { "-Wtrigraphs", 133490282Sobrien N_("Warn when trigraphs are encountered") }, 133550615Sobrien { "-Wno-trigraphs", "" }, 133650615Sobrien { "-Wundef", "" }, 133750615Sobrien { "-Wno-undef", "" }, 133890282Sobrien { "-Wwrite-strings", 133990282Sobrien N_("Mark strings as 'const char *'") }, 134050615Sobrien { "-Wno-write-strings", "" }, 134118334Speter 134250615Sobrien#define DEFINE_LANG_NAME(NAME) { NULL, NAME }, 134350615Sobrien 134418334Speter#include "options.h" 134590282Sobrien 134618334Speter}; 134750615Sobrien 134850615Sobrien/* Here is a table, controlled by the tm.h file, listing each -m switch 134950615Sobrien and which bits in `target_switches' it should set or clear. 135050615Sobrien If VALUE is positive, it is bits to set. 135150615Sobrien If VALUE is negative, -VALUE is bits to clear. 135250615Sobrien (The sign bit is not used so there is no confusion.) */ 135350615Sobrien 135490282Sobrienstatic const struct 135550615Sobrien{ 135690282Sobrien const char *const name; 135790282Sobrien const int value; 135890282Sobrien const char *const description; 135950615Sobrien} 136050615Sobrientarget_switches [] = TARGET_SWITCHES; 136150615Sobrien 136250615Sobrien/* This table is similar, but allows the switch to have a value. */ 136350615Sobrien 136450615Sobrien#ifdef TARGET_OPTIONS 136590282Sobrienstatic const struct 136650615Sobrien{ 136790282Sobrien const char *const prefix; 136890282Sobrien const char **const variable; 136990282Sobrien const char *const description; 137050615Sobrien} 137150615Sobrientarget_options [] = TARGET_OPTIONS; 137250615Sobrien#endif 137318334Speter 137490282Sobrien/* Options controlling warnings. */ 137518334Speter 137618334Speter/* Don't print warning messages. -w. */ 137718334Speter 137818334Speterint inhibit_warnings = 0; 137918334Speter 138090282Sobrien/* Don't suppress warnings from system headers. -Wsystem-headers. */ 138190282Sobrien 138290282Sobrienint warn_system_headers = 0; 138390282Sobrien 138418334Speter/* Print various extra warnings. -W. */ 138518334Speter 138618334Speterint extra_warnings = 0; 138718334Speter 138818334Speter/* Treat warnings as errors. -Werror. */ 138918334Speter 139018334Speterint warnings_are_errors = 0; 139118334Speter 139290282Sobrien/* Nonzero to warn about unused variables, functions et.al. */ 139318334Speter 139490282Sobrienint warn_unused_function; 139590282Sobrienint warn_unused_label; 139690282Sobrienint warn_unused_parameter; 139790282Sobrienint warn_unused_variable; 139890282Sobrienint warn_unused_value; 139918334Speter 140090282Sobrien/* Nonzero to warn about code which is never reached. */ 140190282Sobrien 140290282Sobrienint warn_notreached; 140390282Sobrien 140418334Speter/* Nonzero to warn about variables used before they are initialized. */ 140518334Speter 140618334Speterint warn_uninitialized; 140718334Speter 140890282Sobrien/* Nonzero means warn about all declarations which shadow others. */ 140918334Speter 141018334Speterint warn_shadow; 141118334Speter 141218334Speter/* Warn if a switch on an enum fails to have a case for every enum value. */ 141318334Speter 141418334Speterint warn_switch; 141518334Speter 141618334Speter/* Nonzero means warn about function definitions that default the return type 141718334Speter or that use a null return and have a return-type other than void. */ 141818334Speter 141918334Speterint warn_return_type; 142018334Speter 142118334Speter/* Nonzero means warn about pointer casts that increase the required 142218334Speter alignment of the target type (and might therefore lead to a crash 142318334Speter due to a misaligned access). */ 142418334Speter 142518334Speterint warn_cast_align; 142618334Speter 142718334Speter/* Nonzero means warn about any objects definitions whose size is larger 142818334Speter than N bytes. Also want about function definitions whose returned 142918334Speter values are larger than N bytes. The value N is in `larger_than_size'. */ 143090282Sobrien 143118334Speterint warn_larger_than; 143290282SobrienHOST_WIDE_INT larger_than_size; 143318334Speter 143418334Speter/* Nonzero means warn if inline function is too large. */ 143518334Speter 143618334Speterint warn_inline; 143718334Speter 143818334Speter/* Warn if a function returns an aggregate, 143918334Speter since there are often incompatible calling conventions for doing this. */ 144018334Speter 144118334Speterint warn_aggregate_return; 144218334Speter 144390282Sobrien/* Warn if packed attribute on struct is unnecessary and inefficient. */ 144490282Sobrien 144590282Sobrienint warn_packed; 144690282Sobrien 144790282Sobrien/* Warn when gcc pads a structure to an alignment boundary. */ 144890282Sobrien 144990282Sobrienint warn_padded; 145090282Sobrien 145190282Sobrien/* Warn when an optimization pass is disabled. */ 145290282Sobrien 145390282Sobrienint warn_disabled_optimization; 145490282Sobrien 145590282Sobrien/* Warn about functions which might be candidates for attribute noreturn. */ 145690282Sobrien 145790282Sobrienint warn_missing_noreturn; 145890282Sobrien 145990282Sobrien/* Nonzero means warn about uses of __attribute__((deprecated)) 146090282Sobrien declarations. */ 146190282Sobrien 146290282Sobrienint warn_deprecated_decl = 1; 146390282Sobrien 146418334Speter/* Likewise for -W. */ 146518334Speter 146690282Sobrienstatic const lang_independent_options W_options[] = 146718334Speter{ 146890282Sobrien {"unused-function", &warn_unused_function, 1, 146990282Sobrien N_("Warn when a function is unused") }, 147090282Sobrien {"unused-label", &warn_unused_label, 1, 147190282Sobrien N_("Warn when a label is unused") }, 147290282Sobrien {"unused-parameter", &warn_unused_parameter, 1, 147390282Sobrien N_("Warn when a function parameter is unused") }, 147490282Sobrien {"unused-variable", &warn_unused_variable, 1, 147590282Sobrien N_("Warn when a variable is unused") }, 147690282Sobrien {"unused-value", &warn_unused_value, 1, 147790282Sobrien N_("Warn when an expression value is unused") }, 147890282Sobrien {"system-headers", &warn_system_headers, 1, 147990282Sobrien N_("Do not suppress warnings from system headers") }, 148090282Sobrien {"error", &warnings_are_errors, 1, 148190282Sobrien N_("Treat all warnings as errors") }, 148290282Sobrien {"shadow", &warn_shadow, 1, 148390282Sobrien N_("Warn when one local variable shadows another") }, 148450615Sobrien {"switch", &warn_switch, 1, 148590282Sobrien N_("Warn about enumerated switches missing a specific case") }, 148650615Sobrien {"aggregate-return", &warn_aggregate_return, 1, 148790282Sobrien N_("Warn about returning structures, unions or arrays") }, 148850615Sobrien {"cast-align", &warn_cast_align, 1, 148990282Sobrien N_("Warn about pointer casts which increase alignment") }, 149090282Sobrien {"unreachable-code", &warn_notreached, 1, 149190282Sobrien N_("Warn about code that will never be executed") }, 149250615Sobrien {"uninitialized", &warn_uninitialized, 1, 149390282Sobrien N_("Warn about uninitialized automatic variables") }, 149450615Sobrien {"inline", &warn_inline, 1, 149590282Sobrien N_("Warn when an inlined function cannot be inlined") }, 149690282Sobrien {"packed", &warn_packed, 1, 149790282Sobrien N_("Warn when the packed attribute has no effect on struct layout") }, 149890282Sobrien {"padded", &warn_padded, 1, 149990282Sobrien N_("Warn when padding is required to align struct members") }, 150090282Sobrien {"disabled-optimization", &warn_disabled_optimization, 1, 150190282Sobrien N_("Warn when an optimization pass is disabled") }, 150290282Sobrien {"deprecated-declarations", &warn_deprecated_decl, 1, 150390282Sobrien N_("Warn about uses of __attribute__((deprecated)) declarations") }, 150490282Sobrien {"missing-noreturn", &warn_missing_noreturn, 1, 150590282Sobrien N_("Warn about functions which might be candidates for attribute noreturn") } 150618334Speter}; 150790282Sobrien 150890282Sobrienvoid 150990282Sobrienset_Wunused (setting) 151090282Sobrien int setting; 151190282Sobrien{ 151290282Sobrien warn_unused_function = setting; 151390282Sobrien warn_unused_label = setting; 151490282Sobrien /* Unused function parameter warnings are reported when either ``-W 151590282Sobrien -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate 151690282Sobrien -Wunused by setting WARN_UNUSED_PARAMETER to -1. */ 151790282Sobrien if (!setting) 151890282Sobrien warn_unused_parameter = 0; 151990282Sobrien else if (!warn_unused_parameter) 152090282Sobrien warn_unused_parameter = -1; 152190282Sobrien warn_unused_variable = setting; 152290282Sobrien warn_unused_value = setting; 152390282Sobrien} 152490282Sobrien 152590282Sobrien/* The following routines are useful in setting all the flags that 152690282Sobrien -ffast-math and -fno-fast-math imply. */ 152790282Sobrien 152890282Sobrienvoid 152990282Sobrienset_fast_math_flags () 153090282Sobrien{ 153190282Sobrien flag_trapping_math = 0; 153290282Sobrien flag_unsafe_math_optimizations = 1; 153390282Sobrien flag_errno_math = 0; 153490282Sobrien} 153590282Sobrien 153690282Sobrienvoid 153790282Sobrienset_no_fast_math_flags () 153890282Sobrien{ 153990282Sobrien flag_trapping_math = 1; 154090282Sobrien flag_unsafe_math_optimizations = 0; 154190282Sobrien flag_errno_math = 1; 154290282Sobrien} 154390282Sobrien 154418334Speter 154518334Speter/* Output files for assembler code (real compiler output) 154618334Speter and debugging dumps. */ 154718334Speter 154818334SpeterFILE *asm_out_file; 154918334SpeterFILE *aux_info_file; 155050615SobrienFILE *rtl_dump_file = NULL; 155118334Speter 155252558Sobrien/* Decode the string P as an integral parameter. 155352558Sobrien If the string is indeed an integer return its numeric value else 155452558Sobrien issue an Invalid Option error for the option PNAME and return DEFVAL. 155590282Sobrien If PNAME is zero just return DEFVAL, do not call error. */ 155690282Sobrien 155752558Sobrienint 155852558Sobrienread_integral_parameter (p, pname, defval) 155952558Sobrien const char *p; 156052558Sobrien const char *pname; 156152558Sobrien const int defval; 156252558Sobrien{ 156352558Sobrien const char *endp = p; 156452558Sobrien 156552558Sobrien while (*endp) 156652558Sobrien { 156790282Sobrien if (ISDIGIT (*endp)) 156852558Sobrien endp++; 156952558Sobrien else 157052558Sobrien break; 157152558Sobrien } 157252558Sobrien 157352558Sobrien if (*endp != 0) 157452558Sobrien { 157552558Sobrien if (pname != 0) 157690282Sobrien error ("invalid option `%s'", pname); 157752558Sobrien return defval; 157852558Sobrien } 157952558Sobrien 158052558Sobrien return atoi (p); 158152558Sobrien} 158252558Sobrien 158318334Speter 158418334Speter/* This is the default decl_printable_name function. */ 158518334Speter 158690282Sobrienstatic const char * 158750615Sobriendecl_name (decl, verbosity) 158818334Speter tree decl; 158952558Sobrien int verbosity ATTRIBUTE_UNUSED; 159018334Speter{ 159118334Speter return IDENTIFIER_POINTER (DECL_NAME (decl)); 159218334Speter} 159318334Speter 159418334Speter 159518334Speter/* This calls abort and is used to avoid problems when abort if a macro. 159618334Speter It is used when we need to pass the address of abort. */ 159718334Speter 159818334Spetervoid 159918334Speterdo_abort () 160018334Speter{ 160118334Speter abort (); 160218334Speter} 160318334Speter 160418334Speter/* When `malloc.c' is compiled with `rcheck' defined, 160518334Speter it calls this function to report clobberage. */ 160618334Speter 160718334Spetervoid 160818334Speterbotch (s) 160990282Sobrien const char *s ATTRIBUTE_UNUSED; 161018334Speter{ 161118334Speter abort (); 161218334Speter} 161318334Speter 161418334Speter/* Return the logarithm of X, base 2, considering X unsigned, 161518334Speter if X is a power of 2. Otherwise, returns -1. 161618334Speter 161718334Speter This should be used via the `exact_log2' macro. */ 161818334Speter 161918334Speterint 162018334Speterexact_log2_wide (x) 162190282Sobrien unsigned HOST_WIDE_INT x; 162218334Speter{ 162390282Sobrien int log = 0; 162418334Speter /* Test for 0 or a power of 2. */ 162518334Speter if (x == 0 || x != (x & -x)) 162618334Speter return -1; 162718334Speter while ((x >>= 1) != 0) 162818334Speter log++; 162918334Speter return log; 163018334Speter} 163118334Speter 163218334Speter/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. 163318334Speter If X is 0, return -1. 163418334Speter 163518334Speter This should be used via the floor_log2 macro. */ 163618334Speter 163718334Speterint 163818334Speterfloor_log2_wide (x) 163990282Sobrien unsigned HOST_WIDE_INT x; 164018334Speter{ 164190282Sobrien int log = -1; 164218334Speter while (x != 0) 164318334Speter log++, 164418334Speter x >>= 1; 164518334Speter return log; 164618334Speter} 164718334Speter 164850615Sobrienstatic int float_handler_set; 164918334Speterint float_handled; 165018334Speterjmp_buf float_handler; 165118334Speter 165250615Sobrien/* Signals actually come here. */ 165350615Sobrien 165450615Sobrienstatic void 165550615Sobrienfloat_signal (signo) 165650615Sobrien /* If this is missing, some compilers complain. */ 165750615Sobrien int signo ATTRIBUTE_UNUSED; 165850615Sobrien{ 165950615Sobrien if (float_handled == 0) 166090282Sobrien crash_signal (signo); 166150615Sobrien float_handled = 0; 166290282Sobrien 166390282Sobrien /* On System-V derived systems, we must reinstall the signal handler. 166490282Sobrien This is harmless on BSD-derived systems. */ 166550615Sobrien signal (SIGFPE, float_signal); 166650615Sobrien longjmp (float_handler, 1); 166750615Sobrien} 166850615Sobrien 166918334Speter/* Specify where to longjmp to when a floating arithmetic error happens. 167018334Speter If HANDLER is 0, it means don't handle the errors any more. */ 167118334Speter 167290282Sobrienstatic void 167318334Speterset_float_handler (handler) 167418334Speter jmp_buf handler; 167518334Speter{ 167618334Speter float_handled = (handler != 0); 167718334Speter if (handler) 167890282Sobrien memcpy (float_handler, handler, sizeof (float_handler)); 167950615Sobrien 168050615Sobrien if (float_handled && ! float_handler_set) 168150615Sobrien { 168250615Sobrien signal (SIGFPE, float_signal); 168350615Sobrien float_handler_set = 1; 168450615Sobrien } 168518334Speter} 168618334Speter 168752558Sobrien/* This is a wrapper function for code which might elicit an 168852558Sobrien arithmetic exception. That code should be passed in as a function 168952558Sobrien pointer FN, and one argument DATA. DATA is usually a struct which 169052558Sobrien contains the real input and output for function FN. This function 169152558Sobrien returns 0 (failure) if longjmp was called (i.e. an exception 169290282Sobrien occurred.) It returns 1 (success) otherwise. */ 169352558Sobrien 169452558Sobrienint 169552558Sobriendo_float_handler (fn, data) 169690282Sobrien void (*fn) PARAMS ((PTR)); 169790282Sobrien PTR data; 169852558Sobrien{ 169952558Sobrien jmp_buf buf; 170052558Sobrien 170152558Sobrien if (setjmp (buf)) 170252558Sobrien { 170390282Sobrien /* We got here via longjmp () caused by an exception in function 170490282Sobrien fn (). */ 170552558Sobrien set_float_handler (NULL); 170652558Sobrien return 0; 170752558Sobrien } 170852558Sobrien 170952558Sobrien set_float_handler (buf); 171052558Sobrien (*fn)(data); 171152558Sobrien set_float_handler (NULL); 171252558Sobrien return 1; 171352558Sobrien} 171452558Sobrien 171590282Sobrien/* Handler for fatal signals, such as SIGSEGV. These are transformed 171690282Sobrien into ICE messages, which is much more user friendly. */ 171718334Speter 171818334Speterstatic void 171990282Sobriencrash_signal (signo) 172090282Sobrien int signo; 172118334Speter{ 172290282Sobrien internal_error ("internal error: %s", strsignal (signo)); 172318334Speter} 172418334Speter 172518334Speter/* Strip off a legitimate source ending from the input string NAME of 172618334Speter length LEN. Rather than having to know the names used by all of 172750615Sobrien our front ends, we strip off an ending of a period followed by 172890282Sobrien up to five characters. (Java uses ".class".) */ 172918334Speter 173018334Spetervoid 173118334Speterstrip_off_ending (name, len) 173218334Speter char *name; 173318334Speter int len; 173418334Speter{ 173550615Sobrien int i; 173650615Sobrien for (i = 2; i < 6 && len > i; i++) 173750615Sobrien { 173850615Sobrien if (name[len - i] == '.') 173950615Sobrien { 174050615Sobrien name[len - i] = '\0'; 174150615Sobrien break; 174250615Sobrien } 174350615Sobrien } 174418334Speter} 174518334Speter 174618334Speter/* Output a quoted string. */ 174750615Sobrien 174818334Spetervoid 174918334Speteroutput_quoted_string (asm_file, string) 175018334Speter FILE *asm_file; 175152558Sobrien const char *string; 175218334Speter{ 175350615Sobrien#ifdef OUTPUT_QUOTED_STRING 175450615Sobrien OUTPUT_QUOTED_STRING (asm_file, string); 175550615Sobrien#else 175618334Speter char c; 175718334Speter 175818334Speter putc ('\"', asm_file); 175918334Speter while ((c = *string++) != 0) 176018334Speter { 176196289Sobrien if (ISPRINT (c)) 176296289Sobrien { 176396289Sobrien if (c == '\"' || c == '\\') 176496289Sobrien putc ('\\', asm_file); 176596289Sobrien putc (c, asm_file); 176696289Sobrien } 176796289Sobrien else 176896289Sobrien fprintf (asm_file, "\\%03o", c); 176918334Speter } 177018334Speter putc ('\"', asm_file); 177150615Sobrien#endif 177218334Speter} 177318334Speter 177418334Speter/* Output a file name in the form wanted by System V. */ 177518334Speter 177618334Spetervoid 177718334Speteroutput_file_directive (asm_file, input_name) 177818334Speter FILE *asm_file; 177952558Sobrien const char *input_name; 178018334Speter{ 178118334Speter int len = strlen (input_name); 178252558Sobrien const char *na = input_name + len; 178318334Speter 178418334Speter /* NA gets INPUT_NAME sans directory names. */ 178518334Speter while (na > input_name) 178618334Speter { 178790282Sobrien if (IS_DIR_SEPARATOR (na[-1])) 178890282Sobrien break; 178918334Speter na--; 179018334Speter } 179118334Speter 179218334Speter#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME 179318334Speter ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na); 179418334Speter#else 179518334Speter#ifdef ASM_OUTPUT_SOURCE_FILENAME 179618334Speter ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); 179718334Speter#else 179818334Speter fprintf (asm_file, "\t.file\t"); 179918334Speter output_quoted_string (asm_file, na); 180018334Speter fputc ('\n', asm_file); 180118334Speter#endif 180218334Speter#endif 180318334Speter} 180418334Speter 180590282Sobrien/* Routine to open a dump file. Return true if the dump file is enabled. */ 180618334Speter 180790282Sobrienstatic int 180890282Sobrienopen_dump_file (index, decl) 180990282Sobrien enum dump_file_index index; 181090282Sobrien tree decl; 181118334Speter{ 181290282Sobrien char *dump_name; 181390282Sobrien const char *open_arg; 181490282Sobrien char seq[16]; 181518334Speter 181690282Sobrien if (! dump_file[index].enabled) 181790282Sobrien return 0; 181850615Sobrien 181990282Sobrien timevar_push (TV_DUMP); 182090282Sobrien if (rtl_dump_file != NULL) 182190282Sobrien fclose (rtl_dump_file); 182250615Sobrien 182390282Sobrien sprintf (seq, DUMPFILE_FORMAT, index); 182450615Sobrien 182590282Sobrien if (! dump_file[index].initialized) 182690282Sobrien { 182790282Sobrien /* If we've not initialized the files, do so now. */ 182890282Sobrien if (graph_dump_format != no_graph 182990282Sobrien && dump_file[index].graph_dump_p) 183090282Sobrien { 183190282Sobrien dump_name = concat (seq, dump_file[index].extension, NULL); 183290282Sobrien clean_graph_dump_file (dump_base_name, dump_name); 183390282Sobrien free (dump_name); 183490282Sobrien } 183590282Sobrien dump_file[index].initialized = 1; 183690282Sobrien open_arg = "w"; 183790282Sobrien } 183890282Sobrien else 183990282Sobrien open_arg = "a"; 184050615Sobrien 184190282Sobrien dump_name = concat (dump_base_name, seq, 184290282Sobrien dump_file[index].extension, NULL); 184350615Sobrien 184490282Sobrien rtl_dump_file = fopen (dump_name, open_arg); 184590282Sobrien if (rtl_dump_file == NULL) 184690282Sobrien fatal_io_error ("can't open %s", dump_name); 184790282Sobrien 184890282Sobrien free (dump_name); 184990282Sobrien 185090282Sobrien if (decl) 185190282Sobrien fprintf (rtl_dump_file, "\n;; Function %s\n\n", 185290282Sobrien decl_printable_name (decl, 2)); 185390282Sobrien 185490282Sobrien timevar_pop (TV_DUMP); 185590282Sobrien return 1; 185650615Sobrien} 185750615Sobrien 185890282Sobrien/* Routine to close a dump file. */ 185990282Sobrien 186050615Sobrienstatic void 186190282Sobrienclose_dump_file (index, func, insns) 186290282Sobrien enum dump_file_index index; 186390282Sobrien void (*func) PARAMS ((FILE *, rtx)); 186490282Sobrien rtx insns; 186550615Sobrien{ 186690282Sobrien if (! rtl_dump_file) 186790282Sobrien return; 186850615Sobrien 186990282Sobrien timevar_push (TV_DUMP); 187090282Sobrien if (insns 187190282Sobrien && graph_dump_format != no_graph 187290282Sobrien && dump_file[index].graph_dump_p) 187390282Sobrien { 187490282Sobrien char seq[16]; 187590282Sobrien char *suffix; 187650615Sobrien 187790282Sobrien sprintf (seq, DUMPFILE_FORMAT, index); 187890282Sobrien suffix = concat (seq, dump_file[index].extension, NULL); 187990282Sobrien print_rtl_graph_with_bb (dump_base_name, suffix, insns); 188090282Sobrien free (suffix); 188190282Sobrien } 188250615Sobrien 188390282Sobrien if (func && insns) 188490282Sobrien func (rtl_dump_file, insns); 188550615Sobrien 188690282Sobrien fflush (rtl_dump_file); 188790282Sobrien fclose (rtl_dump_file); 188850615Sobrien 188950615Sobrien rtl_dump_file = NULL; 189090282Sobrien timevar_pop (TV_DUMP); 189118334Speter} 189218334Speter 189352558Sobrien/* Do any final processing required for the declarations in VEC, of 189452558Sobrien which there are LEN. We write out inline functions and variables 189552558Sobrien that have been deferred until this point, but which are required. 189690282Sobrien Returns non-zero if anything was put out. */ 189790282Sobrien 189852558Sobrienint 189952558Sobrienwrapup_global_declarations (vec, len) 190052558Sobrien tree *vec; 190152558Sobrien int len; 190252558Sobrien{ 190352558Sobrien tree decl; 190452558Sobrien int i; 190552558Sobrien int reconsider; 190652558Sobrien int output_something = 0; 190750615Sobrien 190852558Sobrien for (i = 0; i < len; i++) 190952558Sobrien { 191052558Sobrien decl = vec[i]; 191190282Sobrien 191252558Sobrien /* We're not deferring this any longer. */ 191352558Sobrien DECL_DEFER_OUTPUT (decl) = 0; 191490282Sobrien 191552558Sobrien if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0 191652558Sobrien && incomplete_decl_finalize_hook != 0) 191752558Sobrien (*incomplete_decl_finalize_hook) (decl); 191852558Sobrien } 191952558Sobrien 192052558Sobrien /* Now emit any global variables or functions that we have been 192152558Sobrien putting off. We need to loop in case one of the things emitted 192252558Sobrien here references another one which comes earlier in the list. */ 192352558Sobrien do 192452558Sobrien { 192552558Sobrien reconsider = 0; 192652558Sobrien for (i = 0; i < len; i++) 192752558Sobrien { 192852558Sobrien decl = vec[i]; 192952558Sobrien 193052558Sobrien if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl)) 193152558Sobrien continue; 193252558Sobrien 193352558Sobrien /* Don't write out static consts, unless we still need them. 193452558Sobrien 193552558Sobrien We also keep static consts if not optimizing (for debugging), 193652558Sobrien unless the user specified -fno-keep-static-consts. 193752558Sobrien ??? They might be better written into the debug information. 193852558Sobrien This is possible when using DWARF. 193952558Sobrien 194052558Sobrien A language processor that wants static constants to be always 194152558Sobrien written out (even if it is not used) is responsible for 194252558Sobrien calling rest_of_decl_compilation itself. E.g. the C front-end 194352558Sobrien calls rest_of_decl_compilation from finish_decl. 194452558Sobrien One motivation for this is that is conventional in some 194552558Sobrien environments to write things like: 194652558Sobrien static const char rcsid[] = "... version string ..."; 194752558Sobrien intending to force the string to be in the executable. 194852558Sobrien 194952558Sobrien A language processor that would prefer to have unneeded 195052558Sobrien static constants "optimized away" would just defer writing 195152558Sobrien them out until here. E.g. C++ does this, because static 195252558Sobrien constants are often defined in header files. 195352558Sobrien 195452558Sobrien ??? A tempting alternative (for both C and C++) would be 195552558Sobrien to force a constant to be written if and only if it is 195652558Sobrien defined in a main file, as opposed to an include file. */ 195752558Sobrien 195896289Sobrien if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) 195952558Sobrien { 196096289Sobrien bool needed = 1; 196196289Sobrien 196296289Sobrien if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 196396289Sobrien /* needed */; 196496289Sobrien else if (DECL_COMDAT (decl)) 196596289Sobrien needed = 0; 196696289Sobrien else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) 196796289Sobrien && (optimize || !flag_keep_static_consts 196896289Sobrien || DECL_ARTIFICIAL (decl))) 196996289Sobrien needed = 0; 197096289Sobrien 197196289Sobrien if (needed) 197296289Sobrien { 197396289Sobrien reconsider = 1; 197496289Sobrien rest_of_decl_compilation (decl, NULL, 1, 1); 197596289Sobrien } 197652558Sobrien } 197752558Sobrien 197852558Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 197952558Sobrien && DECL_INITIAL (decl) != 0 198052558Sobrien && DECL_SAVED_INSNS (decl) != 0 198152558Sobrien && (flag_keep_inline_functions 198252558Sobrien || (TREE_PUBLIC (decl) && !DECL_COMDAT (decl)) 198352558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) 198452558Sobrien { 198552558Sobrien reconsider = 1; 198652558Sobrien output_inline_function (decl); 198752558Sobrien } 198852558Sobrien } 198952558Sobrien 199052558Sobrien if (reconsider) 199152558Sobrien output_something = 1; 199252558Sobrien } 199352558Sobrien while (reconsider); 199452558Sobrien 199552558Sobrien return output_something; 199652558Sobrien} 199752558Sobrien 199852558Sobrien/* Issue appropriate warnings for the global declarations in VEC (of 199952558Sobrien which there are LEN). Output debugging information for them. */ 200090282Sobrien 200152558Sobrienvoid 200252558Sobriencheck_global_declarations (vec, len) 200352558Sobrien tree *vec; 200452558Sobrien int len; 200552558Sobrien{ 200652558Sobrien tree decl; 200752558Sobrien int i; 200852558Sobrien 200952558Sobrien for (i = 0; i < len; i++) 201052558Sobrien { 201152558Sobrien decl = vec[i]; 201252558Sobrien 201352558Sobrien if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) 201452558Sobrien && ! TREE_ASM_WRITTEN (decl)) 201552558Sobrien /* Cancel the RTL for this decl so that, if debugging info 201652558Sobrien output for global variables is still to come, 201752558Sobrien this one will be omitted. */ 201890282Sobrien SET_DECL_RTL (decl, NULL_RTX); 201952558Sobrien 202052558Sobrien /* Warn about any function 202152558Sobrien declared static but not defined. 202252558Sobrien We don't warn about variables, 202352558Sobrien because many programs have static variables 202452558Sobrien that exist only to get some text into the object file. */ 202552558Sobrien if (TREE_CODE (decl) == FUNCTION_DECL 202690282Sobrien && (warn_unused_function 202752558Sobrien || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 202852558Sobrien && DECL_INITIAL (decl) == 0 202952558Sobrien && DECL_EXTERNAL (decl) 203052558Sobrien && ! DECL_ARTIFICIAL (decl) 203152558Sobrien && ! TREE_PUBLIC (decl)) 203252558Sobrien { 203352558Sobrien if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 203452558Sobrien pedwarn_with_decl (decl, 203552558Sobrien "`%s' used but never defined"); 203652558Sobrien else 203752558Sobrien warning_with_decl (decl, 203852558Sobrien "`%s' declared `static' but never defined"); 203952558Sobrien /* This symbol is effectively an "extern" declaration now. */ 204052558Sobrien TREE_PUBLIC (decl) = 1; 204152558Sobrien assemble_external (decl); 204252558Sobrien } 204352558Sobrien 204452558Sobrien /* Warn about static fns or vars defined but not used, 204552558Sobrien but not about inline functions or static consts 204652558Sobrien since defining those in header files is normal practice. */ 204790282Sobrien if (((warn_unused_function 204890282Sobrien && TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl)) 204990282Sobrien || (warn_unused_variable 205090282Sobrien && TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) 205152558Sobrien && ! DECL_IN_SYSTEM_HEADER (decl) 205252558Sobrien && ! DECL_EXTERNAL (decl) 205352558Sobrien && ! TREE_PUBLIC (decl) 205452558Sobrien && ! TREE_USED (decl) 205552558Sobrien && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) 205652558Sobrien /* The TREE_USED bit for file-scope decls 205752558Sobrien is kept in the identifier, to handle multiple 205852558Sobrien external decls in different scopes. */ 205952558Sobrien && ! TREE_USED (DECL_NAME (decl))) 206052558Sobrien warning_with_decl (decl, "`%s' defined but not used"); 206152558Sobrien 206290282Sobrien timevar_push (TV_SYMOUT); 206390282Sobrien (*debug_hooks->global_decl) (decl); 206490282Sobrien timevar_pop (TV_SYMOUT); 206552558Sobrien } 206652558Sobrien} 206752558Sobrien 206890282Sobrien/* Save the current INPUT_FILENAME and LINENO on the top entry in the 206990282Sobrien INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the 207090282Sobrien INPUT_FILENAME and LINENO accordingly. */ 207118334Speter 207290282Sobrienvoid 207390282Sobrienpush_srcloc (file, line) 207490282Sobrien const char *file; 207590282Sobrien int line; 207618334Speter{ 207790282Sobrien struct file_stack *fs; 207818334Speter 207990282Sobrien if (input_file_stack) 208018334Speter { 208190282Sobrien input_file_stack->name = input_filename; 208290282Sobrien input_file_stack->line = lineno; 208318334Speter } 208418334Speter 208590282Sobrien fs = (struct file_stack *) xmalloc (sizeof (struct file_stack)); 208690282Sobrien fs->name = input_filename = file; 208790282Sobrien fs->line = lineno = line; 208890282Sobrien fs->indent_level = 0; 208990282Sobrien fs->next = input_file_stack; 209090282Sobrien input_file_stack = fs; 209190282Sobrien input_file_stack_tick++; 209290282Sobrien} 209318334Speter 209490282Sobrien/* Pop the top entry off the stack of presently open source files. 209590282Sobrien Restore the INPUT_FILENAME and LINENO from the new topmost entry on 209690282Sobrien the stack. */ 209718334Speter 209890282Sobrienvoid 209990282Sobrienpop_srcloc () 210090282Sobrien{ 210190282Sobrien struct file_stack *fs; 210218334Speter 210390282Sobrien fs = input_file_stack; 210490282Sobrien input_file_stack = fs->next; 210590282Sobrien free (fs); 210690282Sobrien input_file_stack_tick++; 210790282Sobrien /* The initial source file is never popped. */ 210890282Sobrien if (!input_file_stack) 210990282Sobrien abort (); 211090282Sobrien input_filename = input_file_stack->name; 211190282Sobrien lineno = input_file_stack->line; 211290282Sobrien} 211318334Speter 211490282Sobrien/* Compile an entire translation unit. Write a file of assembly 211590282Sobrien output and various debugging dumps. */ 211618334Speter 211790282Sobrienstatic void 211890282Sobriencompile_file () 211990282Sobrien{ 212090282Sobrien tree globals; 212118334Speter 212218334Speter /* Initialize yet another pass. */ 212318334Speter 212450615Sobrien init_final (main_input_filename); 212550615Sobrien init_branch_prob (dump_base_name); 212618334Speter 212790282Sobrien timevar_push (TV_PARSE); 212818334Speter 212918334Speter /* Call the parser, which parses the entire file 213018334Speter (calling rest_of_compilation for each function). */ 213190282Sobrien yyparse (); 213218334Speter 213390282Sobrien /* In case there were missing block closers, 213490282Sobrien get us back to the global binding level. */ 213590282Sobrien (*lang_hooks.clear_binding_stack) (); 213618334Speter 213718334Speter /* Compilation is now finished except for writing 213818334Speter what's left of the symbol table output. */ 213918334Speter 214090282Sobrien timevar_pop (TV_PARSE); 214118334Speter 214252558Sobrien if (flag_syntax_only) 214390282Sobrien return; 214452558Sobrien 214518334Speter globals = getdecls (); 214618334Speter 214718334Speter /* Really define vars that have had only a tentative definition. 214818334Speter Really output inline functions that must actually be callable 214918334Speter and have not been output so far. */ 215018334Speter 215118334Speter { 215218334Speter int len = list_length (globals); 215390282Sobrien tree *vec = (tree *) xmalloc (sizeof (tree) * len); 215418334Speter int i; 215518334Speter tree decl; 215618334Speter 215718334Speter /* Process the decls in reverse order--earliest first. 215818334Speter Put them into VEC from back to front, then take out from front. */ 215918334Speter 216018334Speter for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl)) 216118334Speter vec[len - i - 1] = decl; 216218334Speter 216352558Sobrien wrapup_global_declarations (vec, len); 216418334Speter 216552558Sobrien /* This must occur after the loop to output deferred functions. Else 216652558Sobrien the profiler initializer would not be emitted if all the functions 216752558Sobrien in this compilation unit were deferred. 216818334Speter 216952558Sobrien output_func_start_profiler can not cause any additional functions or 217052558Sobrien data to need to be output, so it need not be in the deferred function 217152558Sobrien loop above. */ 217252558Sobrien output_func_start_profiler (); 217318334Speter 217490282Sobrien check_global_declarations (vec, len); 217550615Sobrien 217690282Sobrien /* Clean up. */ 217790282Sobrien free (vec); 217818334Speter } 217918334Speter 218018334Speter /* Write out any pending weak symbol declarations. */ 218118334Speter 218218334Speter weak_finish (); 218318334Speter 218490282Sobrien /* Do dbx symbols. */ 218590282Sobrien timevar_push (TV_SYMOUT); 218618334Speter 218750615Sobrien#ifdef DWARF2_UNWIND_INFO 218850615Sobrien if (dwarf2out_do_frame ()) 218950615Sobrien dwarf2out_frame_finish (); 219050615Sobrien#endif 219150615Sobrien 219290282Sobrien (*debug_hooks->finish) (main_input_filename); 219390282Sobrien timevar_pop (TV_SYMOUT); 219450615Sobrien 219518334Speter /* Output some stuff at end of file if nec. */ 219618334Speter 219790282Sobrien dw2_output_indirect_constants (); 219890282Sobrien 219950615Sobrien end_final (dump_base_name); 220018334Speter 220190282Sobrien if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) 220290282Sobrien { 220390282Sobrien timevar_push (TV_DUMP); 220490282Sobrien open_dump_file (DFI_bp, NULL); 220552558Sobrien 220690282Sobrien end_branch_prob (); 220718334Speter 220890282Sobrien close_dump_file (DFI_bp, NULL, NULL_RTX); 220990282Sobrien timevar_pop (TV_DUMP); 221018334Speter } 221118334Speter 221290282Sobrien#ifdef ASM_FILE_END 221390282Sobrien ASM_FILE_END (asm_out_file); 221490282Sobrien#endif 221518334Speter 221690282Sobrien /* Attach a special .ident directive to the end of the file to identify 221790282Sobrien the version of GCC which compiled this code. The format of the .ident 221890282Sobrien string is patterned after the ones produced by native SVR4 compilers. */ 221990282Sobrien#ifdef IDENT_ASM_OP 222090282Sobrien if (!flag_no_ident) 222190282Sobrien fprintf (asm_out_file, "%s\"GCC: (GNU) %s\"\n", 222290282Sobrien IDENT_ASM_OP, version_string); 222352558Sobrien#endif 222452558Sobrien 222590282Sobrien if (optimize > 0 && open_dump_file (DFI_combine, NULL)) 222618334Speter { 222790282Sobrien timevar_push (TV_DUMP); 222890282Sobrien dump_combine_total_stats (rtl_dump_file); 222990282Sobrien close_dump_file (DFI_combine, NULL, NULL_RTX); 223090282Sobrien timevar_pop (TV_DUMP); 223118334Speter } 223218334Speter} 223318334Speter 223418334Speter/* This is called from various places for FUNCTION_DECL, VAR_DECL, 223518334Speter and TYPE_DECL nodes. 223618334Speter 223790282Sobrien This does nothing for local (non-static) variables, unless the 223890282Sobrien variable is a register variable with an ASMSPEC. In that case, or 223990282Sobrien if the variable is not an automatic, it sets up the RTL and 224090282Sobrien outputs any assembler code (label definition, storage allocation 224190282Sobrien and initialization). 224218334Speter 224318334Speter DECL is the declaration. If ASMSPEC is nonzero, it specifies 224418334Speter the assembler symbol name to be used. TOP_LEVEL is nonzero 224518334Speter if this declaration is not within a function. */ 224618334Speter 224718334Spetervoid 224818334Speterrest_of_decl_compilation (decl, asmspec, top_level, at_end) 224918334Speter tree decl; 225052558Sobrien const char *asmspec; 225118334Speter int top_level; 225218334Speter int at_end; 225318334Speter{ 225418334Speter /* Declarations of variables, and of functions defined elsewhere. */ 225518334Speter 225618334Speter/* The most obvious approach, to put an #ifndef around where 225718334Speter this macro is used, doesn't work since it's inside a macro call. */ 225818334Speter#ifndef ASM_FINISH_DECLARE_OBJECT 225918334Speter#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END) 226018334Speter#endif 226118334Speter 2262102796Skan /* We deferred calling assemble_alias so that we could collect 2263102796Skan other attributes such as visibility. Emit the alias now. */ 2264102796Skan { 2265102796Skan tree alias; 2266102796Skan alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)); 2267102796Skan if (alias) 2268102796Skan { 2269102796Skan alias = TREE_VALUE (TREE_VALUE (alias)); 2270102796Skan alias = get_identifier (TREE_STRING_POINTER (alias)); 2271102796Skan assemble_alias (decl, alias); 2272102796Skan } 2273102796Skan } 2274102796Skan 227518334Speter /* Forward declarations for nested functions are not "external", 227618334Speter but we need to treat them as if they were. */ 227718334Speter if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) 227818334Speter || TREE_CODE (decl) == FUNCTION_DECL) 227990282Sobrien { 228090282Sobrien timevar_push (TV_VARCONST); 228190282Sobrien if (asmspec) 228290282Sobrien make_decl_rtl (decl, asmspec); 228390282Sobrien /* Don't output anything 228490282Sobrien when a tentative file-scope definition is seen. 228590282Sobrien But at end of compilation, do output code for them. */ 228690282Sobrien if (at_end || !DECL_DEFER_OUTPUT (decl)) 228790282Sobrien assemble_variable (decl, top_level, at_end, 0); 228890282Sobrien if (decl == last_assemble_variable_decl) 228990282Sobrien { 229090282Sobrien ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, 229190282Sobrien top_level, at_end); 229290282Sobrien } 229390282Sobrien timevar_pop (TV_VARCONST); 229490282Sobrien } 229518334Speter else if (DECL_REGISTER (decl) && asmspec != 0) 229618334Speter { 229718334Speter if (decode_reg_name (asmspec) >= 0) 229818334Speter { 229990282Sobrien SET_DECL_RTL (decl, NULL_RTX); 230090282Sobrien make_decl_rtl (decl, asmspec); 230118334Speter } 230218334Speter else 230390282Sobrien { 230490282Sobrien error ("invalid register name `%s' for register variable", asmspec); 230590282Sobrien DECL_REGISTER (decl) = 0; 230690282Sobrien if (!top_level) 230790282Sobrien expand_decl (decl); 230890282Sobrien } 230918334Speter } 231018334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 231118334Speter else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 231218334Speter && TREE_CODE (decl) == TYPE_DECL) 231390282Sobrien { 231490282Sobrien timevar_push (TV_SYMOUT); 231590282Sobrien dbxout_symbol (decl, 0); 231690282Sobrien timevar_pop (TV_SYMOUT); 231790282Sobrien } 231818334Speter#endif 231918334Speter#ifdef SDB_DEBUGGING_INFO 232018334Speter else if (write_symbols == SDB_DEBUG && top_level 232118334Speter && TREE_CODE (decl) == TYPE_DECL) 232290282Sobrien { 232390282Sobrien timevar_push (TV_SYMOUT); 232490282Sobrien sdbout_symbol (decl, 0); 232590282Sobrien timevar_pop (TV_SYMOUT); 232690282Sobrien } 232718334Speter#endif 232818334Speter} 232918334Speter 233018334Speter/* Called after finishing a record, union or enumeral type. */ 233118334Speter 233218334Spetervoid 233318334Speterrest_of_type_compilation (type, toplev) 233452558Sobrien#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO) 233518334Speter tree type; 233618334Speter int toplev; 233752558Sobrien#else 233852558Sobrien tree type ATTRIBUTE_UNUSED; 233952558Sobrien int toplev ATTRIBUTE_UNUSED; 234052558Sobrien#endif 234118334Speter{ 234290282Sobrien timevar_push (TV_SYMOUT); 234318334Speter#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 234418334Speter if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) 234590282Sobrien dbxout_symbol (TYPE_STUB_DECL (type), !toplev); 234618334Speter#endif 234718334Speter#ifdef SDB_DEBUGGING_INFO 234818334Speter if (write_symbols == SDB_DEBUG) 234990282Sobrien sdbout_symbol (TYPE_STUB_DECL (type), !toplev); 235018334Speter#endif 235190282Sobrien#ifdef DWARF2_DEBUGGING_INFO 235290282Sobrien if ((write_symbols == DWARF2_DEBUG 235390282Sobrien || write_symbols == VMS_AND_DWARF2_DEBUG) 235490282Sobrien && toplev) 235590282Sobrien dwarf2out_decl (TYPE_STUB_DECL (type)); 235690282Sobrien#endif 235790282Sobrien timevar_pop (TV_SYMOUT); 235818334Speter} 235918334Speter 236018334Speter/* This is called from finish_function (within yyparse) 236118334Speter after each top-level definition is parsed. 236218334Speter It is supposed to compile that function or variable 236318334Speter and output the assembler code for it. 236418334Speter After we return, the tree storage is freed. */ 236518334Speter 236618334Spetervoid 236718334Speterrest_of_compilation (decl) 236818334Speter tree decl; 236918334Speter{ 237090282Sobrien rtx insns; 237118334Speter int tem; 237218334Speter int failure = 0; 237352558Sobrien int rebuild_label_notes_after_reload; 237490282Sobrien int register_life_up_to_date; 237596289Sobrien int cleanup_crossjump; 237618334Speter 237790282Sobrien timevar_push (TV_REST_OF_COMPILATION); 237890282Sobrien 237990282Sobrien /* Now that we're out of the frontend, we shouldn't have any more 238090282Sobrien CONCATs anywhere. */ 238190282Sobrien generating_concat_p = 0; 238290282Sobrien 238390282Sobrien /* When processing delayed functions, prepare_function_start() won't 238490282Sobrien have been run to re-initialize it. */ 238590282Sobrien cse_not_expected = ! optimize; 238690282Sobrien 238790282Sobrien /* First, make sure that NOTE_BLOCK is set correctly for each 238890282Sobrien NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */ 238990282Sobrien if (!cfun->x_whole_function_mode_p) 239090282Sobrien identify_blocks (); 239190282Sobrien 239290282Sobrien /* In function-at-a-time mode, we do not attempt to keep the BLOCK 239390282Sobrien tree in sensible shape. So, we just recalculate it here. */ 239490282Sobrien if (cfun->x_whole_function_mode_p) 239590282Sobrien reorder_blocks (); 239690282Sobrien 239790282Sobrien init_flow (); 239890282Sobrien 239918334Speter /* If we are reconsidering an inline function 240018334Speter at the end of compilation, skip the stuff for making it inline. */ 240118334Speter 240218334Speter if (DECL_SAVED_INSNS (decl) == 0) 240318334Speter { 240450615Sobrien int inlinable = 0; 240590282Sobrien tree parent; 240652558Sobrien const char *lose; 240718334Speter 240890282Sobrien /* If this is nested inside an inlined external function, pretend 240990282Sobrien it was only declared. Since we cannot inline such functions, 241090282Sobrien generating code for this one is not only not necessary but will 241190282Sobrien confuse some debugging output writers. */ 241290282Sobrien for (parent = DECL_CONTEXT (current_function_decl); 241390282Sobrien parent != NULL_TREE; 241490282Sobrien parent = get_containing_scope (parent)) 241590282Sobrien if (TREE_CODE (parent) == FUNCTION_DECL 241690282Sobrien && DECL_INLINE (parent) && DECL_EXTERNAL (parent)) 241790282Sobrien { 241890282Sobrien DECL_INITIAL (decl) = 0; 241990282Sobrien goto exit_rest_of_compilation; 242090282Sobrien } 242190282Sobrien 242218334Speter /* If requested, consider whether to make this function inline. */ 242390282Sobrien if ((DECL_INLINE (decl) && !flag_no_inline) 242490282Sobrien || flag_inline_functions) 242590282Sobrien { 242690282Sobrien timevar_push (TV_INTEGRATION); 242790282Sobrien lose = function_cannot_inline_p (decl); 242890282Sobrien timevar_pop (TV_INTEGRATION); 242990282Sobrien if (lose || ! optimize) 243090282Sobrien { 243190282Sobrien if (warn_inline && DECL_INLINE (decl)) 243290282Sobrien warning_with_decl (decl, lose); 243390282Sobrien DECL_ABSTRACT_ORIGIN (decl) = 0; 243490282Sobrien /* Don't really compile an extern inline function. 243590282Sobrien If we can't make it inline, pretend 243690282Sobrien it was only declared. */ 243790282Sobrien if (DECL_EXTERNAL (decl)) 243890282Sobrien { 243990282Sobrien DECL_INITIAL (decl) = 0; 244090282Sobrien goto exit_rest_of_compilation; 244190282Sobrien } 244290282Sobrien } 244390282Sobrien else 244490282Sobrien /* ??? Note that this has the effect of making it look 244590282Sobrien like "inline" was specified for a function if we choose 244690282Sobrien to inline it. This isn't quite right, but it's 244790282Sobrien probably not worth the trouble to fix. */ 244890282Sobrien inlinable = DECL_INLINE (decl) = 1; 244990282Sobrien } 245018334Speter 245118334Speter insns = get_insns (); 245218334Speter 245318334Speter /* Dump the rtl code if we are dumping rtl. */ 245418334Speter 245590282Sobrien if (open_dump_file (DFI_rtl, decl)) 245650615Sobrien { 245750615Sobrien if (DECL_SAVED_INSNS (decl)) 245850615Sobrien fprintf (rtl_dump_file, ";; (integrable)\n\n"); 245990282Sobrien close_dump_file (DFI_rtl, print_rtl, insns); 246050615Sobrien } 246118334Speter 246290282Sobrien /* Convert from NOTE_INSN_EH_REGION style notes, and do other 246390282Sobrien sorts of eh initialization. Delay this until after the 246490282Sobrien initial rtl dump so that we can see the original nesting. */ 246590282Sobrien convert_from_eh_region_ranges (); 246650615Sobrien 246718334Speter /* If function is inline, and we don't yet know whether to 246818334Speter compile it by itself, defer decision till end of compilation. 246918334Speter finish_compilation will call rest_of_compilation again 247018334Speter for those functions that need to be output. Also defer those 247190282Sobrien functions that we are supposed to defer. */ 247218334Speter 247390282Sobrien if (inlinable 247490282Sobrien || (DECL_INLINE (decl) 247590282Sobrien && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) 247696289Sobrien && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) 247790282Sobrien && ! flag_keep_inline_functions) 247890282Sobrien || DECL_EXTERNAL (decl)))) 247990282Sobrien DECL_DEFER_OUTPUT (decl) = 1; 248050615Sobrien 248190282Sobrien if (DECL_INLINE (decl)) 248290282Sobrien /* DWARF wants separate debugging info for abstract and 248390282Sobrien concrete instances of all inline functions, including those 248490282Sobrien declared inline but not inlined, and those inlined even 248590282Sobrien though they weren't declared inline. Conveniently, that's 248690282Sobrien what DECL_INLINE means at this point. */ 248790282Sobrien (*debug_hooks->deferred_inline_function) (decl); 248890282Sobrien 248990282Sobrien if (DECL_DEFER_OUTPUT (decl)) 249050615Sobrien { 249190282Sobrien /* If -Wreturn-type, we have to do a bit of compilation. We just 249290282Sobrien want to call cleanup the cfg to figure out whether or not we can 249390282Sobrien fall off the end of the function; we do the minimum amount of 249490282Sobrien work necessary to make that safe. */ 249550615Sobrien if (warn_return_type) 249618334Speter { 249750615Sobrien int saved_optimize = optimize; 249890282Sobrien 249950615Sobrien optimize = 0; 250090282Sobrien rebuild_jump_labels (insns); 250150615Sobrien find_exception_handler_labels (); 250290282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 250390282Sobrien cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP); 250450615Sobrien optimize = saved_optimize; 250590282Sobrien 250690282Sobrien /* CFG is no longer maintained up-to-date. */ 250790282Sobrien free_bb_for_insn (); 250850615Sobrien } 250950615Sobrien 251090282Sobrien current_function_nothrow = nothrow_function_p (); 251190282Sobrien if (current_function_nothrow) 251290282Sobrien /* Now we know that this can't throw; set the flag for the benefit 251390282Sobrien of other functions later in this translation unit. */ 251490282Sobrien TREE_NOTHROW (current_function_decl) = 1; 251590282Sobrien 251690282Sobrien timevar_push (TV_INTEGRATION); 251790282Sobrien save_for_inline (decl); 251890282Sobrien timevar_pop (TV_INTEGRATION); 251990282Sobrien DECL_SAVED_INSNS (decl)->inlinable = inlinable; 252050615Sobrien goto exit_rest_of_compilation; 252118334Speter } 252218334Speter 252318334Speter /* If specified extern inline but we aren't inlining it, we are 252452558Sobrien done. This goes for anything that gets here with DECL_EXTERNAL 252552558Sobrien set, not just things with DECL_INLINE. */ 252652558Sobrien if (DECL_EXTERNAL (decl)) 252718334Speter goto exit_rest_of_compilation; 252818334Speter } 252918334Speter 253090282Sobrien /* If we're emitting a nested function, make sure its parent gets 253190282Sobrien emitted as well. Doing otherwise confuses debug info. */ 253290282Sobrien { 253390282Sobrien tree parent; 253490282Sobrien for (parent = DECL_CONTEXT (current_function_decl); 253590282Sobrien parent != NULL_TREE; 253690282Sobrien parent = get_containing_scope (parent)) 253790282Sobrien if (TREE_CODE (parent) == FUNCTION_DECL) 253890282Sobrien TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1; 253990282Sobrien } 254090282Sobrien 254190282Sobrien /* We are now committed to emitting code for this function. Do any 254290282Sobrien preparation, such as emitting abstract debug info for the inline 254390282Sobrien before it gets mangled by optimization. */ 254490282Sobrien if (DECL_INLINE (decl)) 254590282Sobrien (*debug_hooks->outlining_inline_function) (decl); 254690282Sobrien 254790282Sobrien /* Remove any notes we don't need. That will make iterating 254890282Sobrien over the instruction sequence faster, and allow the garbage 254990282Sobrien collector to reclaim the memory used by the notes. */ 255090282Sobrien remove_unnecessary_notes (); 255190282Sobrien reorder_blocks (); 255290282Sobrien 255390282Sobrien ggc_collect (); 255490282Sobrien 255590282Sobrien /* Initialize some variables used by the optimizers. */ 255690282Sobrien init_function_for_compilation (); 255790282Sobrien 255818334Speter if (! DECL_DEFER_OUTPUT (decl)) 255918334Speter TREE_ASM_WRITTEN (decl) = 1; 256018334Speter 256190282Sobrien /* Now that integrate will no longer see our rtl, we need not 256290282Sobrien distinguish between the return value of this function and the 256390282Sobrien return value of called functions. Also, we can remove all SETs 256490282Sobrien of subregs of hard registers; they are only here because of 256590282Sobrien integrate. Also, we can now initialize pseudos intended to 256690282Sobrien carry magic hard reg data throughout the function. */ 256718334Speter rtx_equal_function_value_matters = 0; 256890282Sobrien purge_hard_subreg_sets (get_insns ()); 256918334Speter 257096289Sobrien /* Early return if there were errors. We can run afoul of our 257196289Sobrien consistency checks, and there's not really much point in fixing them. 257296289Sobrien Don't return yet if -Wreturn-type; we need to do cleanup_cfg. */ 257396289Sobrien if (((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) 257496289Sobrien || errorcount || sorrycount) 257590282Sobrien goto exit_rest_of_compilation; 257690282Sobrien 257790282Sobrien /* We may have potential sibling or tail recursion sites. Select one 257890282Sobrien (of possibly multiple) methods of performing the call. */ 257990282Sobrien if (flag_optimize_sibling_calls) 258018334Speter { 258190282Sobrien timevar_push (TV_JUMP); 258290282Sobrien open_dump_file (DFI_sibling, decl); 258390282Sobrien 258490282Sobrien optimize_sibling_and_tail_recursive_calls (); 258590282Sobrien 258690282Sobrien close_dump_file (DFI_sibling, print_rtl, get_insns ()); 258790282Sobrien timevar_pop (TV_JUMP); 258818334Speter } 258918334Speter 259090282Sobrien /* Complete generation of exception handling code. */ 259190282Sobrien find_exception_handler_labels (); 259290282Sobrien if (doing_eh (0)) 259390282Sobrien { 259490282Sobrien timevar_push (TV_JUMP); 259590282Sobrien open_dump_file (DFI_eh, decl); 259618334Speter 259790282Sobrien finish_eh_generation (); 259890282Sobrien 259990282Sobrien close_dump_file (DFI_eh, print_rtl, get_insns ()); 260090282Sobrien timevar_pop (TV_JUMP); 260190282Sobrien } 260290282Sobrien 260396289Sobrien /* Delay emitting hard_reg_initial_value sets until after EH landing pad 260496289Sobrien generation, which might create new sets. */ 260596289Sobrien emit_initial_value_sets (); 260696289Sobrien 260718334Speter#ifdef FINALIZE_PIC 260818334Speter /* If we are doing position-independent code generation, now 260918334Speter is the time to output special prologues and epilogues. 261018334Speter We do not want to do this earlier, because it just clutters 261118334Speter up inline functions with meaningless insns. */ 261218334Speter if (flag_pic) 261318334Speter FINALIZE_PIC; 261418334Speter#endif 261518334Speter 261618334Speter insns = get_insns (); 261718334Speter 261818334Speter /* Copy any shared structure that should not be shared. */ 261972566Sobrien unshare_all_rtl (current_function_decl, insns); 262018334Speter 262150615Sobrien#ifdef SETJMP_VIA_SAVE_AREA 262290282Sobrien /* This must be performed before virtual register instantiation. */ 262350615Sobrien if (current_function_calls_alloca) 262450615Sobrien optimize_save_area_alloca (insns); 262550615Sobrien#endif 262650615Sobrien 262718334Speter /* Instantiate all virtual registers. */ 262890282Sobrien instantiate_virtual_regs (current_function_decl, insns); 262918334Speter 263090282Sobrien open_dump_file (DFI_jump, decl); 263118334Speter 263250615Sobrien /* Always do one jump optimization pass to ensure that JUMP_LABEL fields 263350615Sobrien are initialized and to compute whether control can drop off the end 263450615Sobrien of the function. */ 263518334Speter 263690282Sobrien timevar_push (TV_JUMP); 263790282Sobrien /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this 263890282Sobrien before jump optimization switches branch directions. */ 263990282Sobrien expected_value_to_br_prob (); 264090282Sobrien 264190282Sobrien reg_scan (insns, max_reg_num (), 0); 264290282Sobrien rebuild_jump_labels (insns); 264390282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 264490282Sobrien cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP); 264590282Sobrien 264690282Sobrien /* CFG is no longer maintained up-to-date. */ 264790282Sobrien free_bb_for_insn (); 264890282Sobrien copy_loop_headers (insns); 264990282Sobrien purge_line_number_notes (insns); 265090282Sobrien 265190282Sobrien timevar_pop (TV_JUMP); 265290282Sobrien 265318334Speter /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ 265418334Speter if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl)) 265590282Sobrien { 265690282Sobrien close_dump_file (DFI_jump, print_rtl, insns); 265790282Sobrien goto exit_rest_of_compilation; 265890282Sobrien } 265918334Speter 266090282Sobrien /* Long term, this should probably move before the jump optimizer too, 266190282Sobrien but I didn't want to disturb the rtl_dump_and_exit and related 266290282Sobrien stuff at this time. */ 266390282Sobrien if (optimize > 0 && flag_ssa) 266490282Sobrien { 266590282Sobrien /* Convert to SSA form. */ 266618334Speter 266790282Sobrien timevar_push (TV_TO_SSA); 266890282Sobrien open_dump_file (DFI_ssa, decl); 266918334Speter 267090282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 267190282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 267290282Sobrien convert_to_ssa (); 267390282Sobrien 267490282Sobrien close_dump_file (DFI_ssa, print_rtl_with_bb, insns); 267590282Sobrien timevar_pop (TV_TO_SSA); 267690282Sobrien 267790282Sobrien /* Perform sparse conditional constant propagation, if requested. */ 267890282Sobrien if (flag_ssa_ccp) 267990282Sobrien { 268090282Sobrien timevar_push (TV_SSA_CCP); 268190282Sobrien open_dump_file (DFI_ssa_ccp, decl); 268290282Sobrien 268390282Sobrien ssa_const_prop (); 268490282Sobrien 268590282Sobrien close_dump_file (DFI_ssa_ccp, print_rtl_with_bb, get_insns ()); 268690282Sobrien timevar_pop (TV_SSA_CCP); 268790282Sobrien } 268890282Sobrien 268990282Sobrien /* It would be useful to cleanup the CFG at this point, but block 269090282Sobrien merging and possibly other transformations might leave a PHI 269190282Sobrien node in the middle of a basic block, which is a strict no-no. */ 269290282Sobrien 269390282Sobrien /* The SSA implementation uses basic block numbers in its phi 269490282Sobrien nodes. Thus, changing the control-flow graph or the basic 269590282Sobrien blocks, e.g., calling find_basic_blocks () or cleanup_cfg (), 269690282Sobrien may cause problems. */ 269790282Sobrien 269890282Sobrien if (flag_ssa_dce) 269990282Sobrien { 270090282Sobrien /* Remove dead code. */ 270190282Sobrien 270290282Sobrien timevar_push (TV_SSA_DCE); 270390282Sobrien open_dump_file (DFI_ssa_dce, decl); 270490282Sobrien 270590282Sobrien insns = get_insns (); 270690282Sobrien ssa_eliminate_dead_code(); 270790282Sobrien 270890282Sobrien close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns); 270990282Sobrien timevar_pop (TV_SSA_DCE); 271090282Sobrien } 271190282Sobrien 271290282Sobrien /* Convert from SSA form. */ 271390282Sobrien 271490282Sobrien timevar_push (TV_FROM_SSA); 271590282Sobrien open_dump_file (DFI_ussa, decl); 271690282Sobrien 271790282Sobrien convert_from_ssa (); 271890282Sobrien /* New registers have been created. Rescan their usage. */ 271990282Sobrien reg_scan (insns, max_reg_num (), 1); 272090282Sobrien 272190282Sobrien close_dump_file (DFI_ussa, print_rtl_with_bb, insns); 272290282Sobrien timevar_pop (TV_FROM_SSA); 272390282Sobrien 272490282Sobrien ggc_collect (); 272590282Sobrien /* CFG is no longer maintained up-to-date. */ 272690282Sobrien free_bb_for_insn (); 272790282Sobrien } 272890282Sobrien 272990282Sobrien timevar_push (TV_JUMP); 273090282Sobrien 273190282Sobrien if (optimize > 0) 273290282Sobrien { 273390282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 273490282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP 273590282Sobrien | (flag_thread_jumps ? CLEANUP_THREADING : 0)); 273690282Sobrien 273790282Sobrien /* ??? Run if-conversion before delete_null_pointer_checks, 273890282Sobrien since the later does not preserve the CFG. This should 273990282Sobrien be changed -- no since converting if's that are going to 274090282Sobrien be deleted. */ 274190282Sobrien timevar_push (TV_IFCVT); 274290282Sobrien if_convert (0); 274390282Sobrien timevar_pop (TV_IFCVT); 274490282Sobrien 274590282Sobrien /* CFG is no longer maintained up-to-date. */ 274690282Sobrien free_bb_for_insn (); 274790282Sobrien /* Try to identify useless null pointer tests and delete them. */ 274890282Sobrien if (flag_delete_null_pointer_checks) 274990282Sobrien delete_null_pointer_checks (insns); 275090282Sobrien } 275190282Sobrien 275290282Sobrien /* Jump optimization, and the removal of NULL pointer checks, may 275390282Sobrien have reduced the number of instructions substantially. CSE, and 275490282Sobrien future passes, allocate arrays whose dimensions involve the 275590282Sobrien maximum instruction UID, so if we can reduce the maximum UID 275690282Sobrien we'll save big on memory. */ 275790282Sobrien renumber_insns (rtl_dump_file); 275890282Sobrien timevar_pop (TV_JUMP); 275990282Sobrien 276090282Sobrien close_dump_file (DFI_jump, print_rtl, insns); 276190282Sobrien 276290282Sobrien ggc_collect (); 276390282Sobrien 276418334Speter /* Perform common subexpression elimination. 276518334Speter Nonzero value from `cse_main' means that jumps were simplified 276618334Speter and some code may now be unreachable, so do 276718334Speter jump optimization again. */ 276818334Speter 276918334Speter if (optimize > 0) 277018334Speter { 277190282Sobrien open_dump_file (DFI_cse, decl); 277290282Sobrien timevar_push (TV_CSE); 277350615Sobrien 277490282Sobrien reg_scan (insns, max_reg_num (), 1); 277518334Speter 277690282Sobrien tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file); 277718334Speter 277890282Sobrien /* If we are not running more CSE passes, then we are no longer 277990282Sobrien expecting CSE to be run. But always rerun it in a cheap mode. */ 278090282Sobrien cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; 278190282Sobrien 278218334Speter if (tem || optimize > 1) 278390282Sobrien { 278490282Sobrien timevar_push (TV_JUMP); 278590282Sobrien rebuild_jump_labels (insns); 278690282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 278790282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 278890282Sobrien timevar_pop (TV_JUMP); 278990282Sobrien /* CFG is no longer maintained up-to-date. */ 279090282Sobrien free_bb_for_insn (); 279190282Sobrien } 279250615Sobrien 279356392Sobrien /* Run this after jump optmizations remove all the unreachable code 279456392Sobrien so that unreachable code will not keep values live. */ 279590282Sobrien delete_trivially_dead_insns (insns, max_reg_num (), 0); 279656392Sobrien 279790282Sobrien /* Try to identify useless null pointer tests and delete them. */ 279890282Sobrien if (flag_delete_null_pointer_checks || flag_thread_jumps) 279990282Sobrien { 280090282Sobrien timevar_push (TV_JUMP); 280190282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 280252558Sobrien 280390282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP 280490282Sobrien | (flag_thread_jumps ? CLEANUP_THREADING : 0)); 280590282Sobrien 280690282Sobrien if (flag_delete_null_pointer_checks) 280790282Sobrien delete_null_pointer_checks (insns); 280890282Sobrien /* CFG is no longer maintained up-to-date. */ 280990282Sobrien free_bb_for_insn (); 281090282Sobrien timevar_pop (TV_JUMP); 281152558Sobrien } 281290282Sobrien 281390282Sobrien /* The second pass of jump optimization is likely to have 281490282Sobrien removed a bunch more instructions. */ 281590282Sobrien renumber_insns (rtl_dump_file); 281690282Sobrien 281790282Sobrien timevar_pop (TV_CSE); 281890282Sobrien close_dump_file (DFI_cse, print_rtl, insns); 281918334Speter } 282018334Speter 282190282Sobrien open_dump_file (DFI_addressof, decl); 282290282Sobrien 282350615Sobrien purge_addressof (insns); 282450615Sobrien reg_scan (insns, max_reg_num (), 1); 282518334Speter 282690282Sobrien close_dump_file (DFI_addressof, print_rtl, insns); 282752558Sobrien 282890282Sobrien ggc_collect (); 282990282Sobrien 283050615Sobrien /* Perform global cse. */ 283118334Speter 283250615Sobrien if (optimize > 0 && flag_gcse) 283350615Sobrien { 283490282Sobrien int save_csb, save_cfj; 283590282Sobrien int tem2 = 0; 283618334Speter 283790282Sobrien timevar_push (TV_GCSE); 283890282Sobrien open_dump_file (DFI_gcse, decl); 283952558Sobrien 284090282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 284190282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 284290282Sobrien tem = gcse_main (insns, rtl_dump_file); 284390282Sobrien rebuild_jump_labels (insns); 284490282Sobrien 284590282Sobrien save_csb = flag_cse_skip_blocks; 284690282Sobrien save_cfj = flag_cse_follow_jumps; 284790282Sobrien flag_cse_skip_blocks = flag_cse_follow_jumps = 0; 284890282Sobrien 284990282Sobrien /* CFG is no longer maintained up-to-date. */ 285090282Sobrien free_bb_for_insn (); 285190282Sobrien /* If -fexpensive-optimizations, re-run CSE to clean up things done 285290282Sobrien by gcse. */ 285390282Sobrien if (flag_expensive_optimizations) 285452558Sobrien { 285590282Sobrien timevar_push (TV_CSE); 285690282Sobrien reg_scan (insns, max_reg_num (), 1); 285790282Sobrien tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); 285890282Sobrien timevar_pop (TV_CSE); 285990282Sobrien cse_not_expected = !flag_rerun_cse_after_loop; 286090282Sobrien } 286152558Sobrien 286290282Sobrien /* If gcse or cse altered any jumps, rerun jump optimizations to clean 286390282Sobrien things up. Then possibly re-run CSE again. */ 286490282Sobrien while (tem || tem2) 286552558Sobrien { 286690282Sobrien tem = tem2 = 0; 286790282Sobrien timevar_push (TV_JUMP); 286890282Sobrien rebuild_jump_labels (insns); 286990282Sobrien delete_trivially_dead_insns (insns, max_reg_num (), 0); 287090282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 287190282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); 287290282Sobrien /* CFG is no longer maintained up-to-date. */ 287390282Sobrien free_bb_for_insn (); 287490282Sobrien timevar_pop (TV_JUMP); 287590282Sobrien 287690282Sobrien if (flag_expensive_optimizations) 287790282Sobrien { 287890282Sobrien timevar_push (TV_CSE); 287990282Sobrien reg_scan (insns, max_reg_num (), 1); 288090282Sobrien tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); 288190282Sobrien timevar_pop (TV_CSE); 288290282Sobrien } 288352558Sobrien } 288490282Sobrien 288590282Sobrien close_dump_file (DFI_gcse, print_rtl, insns); 288690282Sobrien timevar_pop (TV_GCSE); 288790282Sobrien 288890282Sobrien ggc_collect (); 288990282Sobrien flag_cse_skip_blocks = save_csb; 289090282Sobrien flag_cse_follow_jumps = save_cfj; 289150615Sobrien } 289290282Sobrien 289318334Speter /* Move constant computations out of loops. */ 289418334Speter 289518334Speter if (optimize > 0) 289618334Speter { 289790282Sobrien timevar_push (TV_LOOP); 289890282Sobrien open_dump_file (DFI_loop, decl); 289990282Sobrien free_bb_for_insn (); 290018334Speter 290190282Sobrien if (flag_rerun_loop_opt) 290290282Sobrien { 290390282Sobrien cleanup_barriers (); 290490282Sobrien 290590282Sobrien /* We only want to perform unrolling once. */ 290696289Sobrien loop_optimize (insns, rtl_dump_file, LOOP_FIRST_PASS); 290790282Sobrien 290890282Sobrien /* The first call to loop_optimize makes some instructions 290990282Sobrien trivially dead. We delete those instructions now in the 291090282Sobrien hope that doing so will make the heuristics in loop work 291190282Sobrien better and possibly speed up compilation. */ 291290282Sobrien delete_trivially_dead_insns (insns, max_reg_num (), 0); 291390282Sobrien 291490282Sobrien /* The regscan pass is currently necessary as the alias 291550615Sobrien analysis code depends on this information. */ 291690282Sobrien reg_scan (insns, max_reg_num (), 1); 291790282Sobrien } 291890282Sobrien cleanup_barriers (); 291990282Sobrien loop_optimize (insns, rtl_dump_file, 292090282Sobrien (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT 292190282Sobrien | (flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0)); 292252558Sobrien 292390282Sobrien close_dump_file (DFI_loop, print_rtl, insns); 292490282Sobrien timevar_pop (TV_LOOP); 292552558Sobrien 292690282Sobrien ggc_collect (); 292750615Sobrien } 292818334Speter 292950615Sobrien if (optimize > 0) 293018334Speter { 293190282Sobrien timevar_push (TV_CSE2); 293290282Sobrien open_dump_file (DFI_cse2, decl); 293352558Sobrien 293450615Sobrien if (flag_rerun_cse_after_loop) 293550615Sobrien { 293650615Sobrien /* Running another jump optimization pass before the second 293750615Sobrien cse pass sometimes simplifies the RTL enough to allow 293850615Sobrien the second CSE pass to do a better job. Jump_optimize can change 293950615Sobrien max_reg_num so we must rerun reg_scan afterwards. 294050615Sobrien ??? Rework to not call reg_scan so often. */ 294190282Sobrien timevar_push (TV_JUMP); 294290282Sobrien 294390282Sobrien /* The previous call to loop_optimize makes some instructions 294490282Sobrien trivially dead. We delete those instructions now in the 294590282Sobrien hope that doing so will make the heuristics in jump work 294690282Sobrien better and possibly speed up compilation. */ 294790282Sobrien delete_trivially_dead_insns (insns, max_reg_num (), 0); 294890282Sobrien 294990282Sobrien reg_scan (insns, max_reg_num (), 0); 295090282Sobrien 295190282Sobrien timevar_push (TV_IFCVT); 295290282Sobrien 295390282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 295490282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE); 295590282Sobrien if_convert (0); 295690282Sobrien 295790282Sobrien timevar_pop(TV_IFCVT); 295890282Sobrien 295990282Sobrien timevar_pop (TV_JUMP); 296090282Sobrien 296190282Sobrien /* CFG is no longer maintained up-to-date. */ 296290282Sobrien free_bb_for_insn (); 296390282Sobrien reg_scan (insns, max_reg_num (), 0); 296490282Sobrien tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file); 296590282Sobrien 296650615Sobrien if (tem) 296790282Sobrien { 296890282Sobrien timevar_push (TV_JUMP); 296990282Sobrien rebuild_jump_labels (insns); 297090282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 297190282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE); 297290282Sobrien /* CFG is no longer maintained up-to-date. */ 297390282Sobrien free_bb_for_insn (); 297490282Sobrien timevar_pop (TV_JUMP); 297590282Sobrien } 297650615Sobrien } 297718334Speter 297890282Sobrien close_dump_file (DFI_cse2, print_rtl, insns); 297990282Sobrien timevar_pop (TV_CSE2); 298052558Sobrien 298190282Sobrien ggc_collect (); 298218334Speter } 298352558Sobrien 298490282Sobrien cse_not_expected = 1; 298590282Sobrien 298690282Sobrien regclass_init (); 298790282Sobrien 298890282Sobrien /* Do control and data flow analysis; wrote some of the results to 298990282Sobrien the dump file. */ 299090282Sobrien 299190282Sobrien timevar_push (TV_FLOW); 299290282Sobrien open_dump_file (DFI_cfg, decl); 299390282Sobrien 299490282Sobrien find_basic_blocks (insns, max_reg_num (), rtl_dump_file); 299590282Sobrien cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) 299690282Sobrien | (flag_thread_jumps ? CLEANUP_THREADING : 0)); 299790282Sobrien check_function_return_warnings (); 299890282Sobrien 299990282Sobrien /* It may make more sense to mark constant functions after dead code is 300090282Sobrien eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs 300190282Sobrien may insert code making function non-constant, but we still must consider 300290282Sobrien it as constant, otherwise -fbranch-probabilities will not read data back. 300390282Sobrien 300490282Sobrien life_analyzis rarely eliminates modification of external memory. 300590282Sobrien */ 300690282Sobrien mark_constant_function (); 300790282Sobrien 300890282Sobrien close_dump_file (DFI_cfg, print_rtl_with_bb, insns); 300990282Sobrien 301050615Sobrien if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) 301150615Sobrien { 301290282Sobrien timevar_push (TV_BRANCH_PROB); 301390282Sobrien open_dump_file (DFI_bp, decl); 301452558Sobrien 301590282Sobrien branch_prob (); 301652558Sobrien 301790282Sobrien close_dump_file (DFI_bp, print_rtl_with_bb, insns); 301890282Sobrien timevar_pop (TV_BRANCH_PROB); 301950615Sobrien } 302052558Sobrien 302190282Sobrien open_dump_file (DFI_life, decl); 302290282Sobrien if (optimize) 302390282Sobrien { 302490282Sobrien struct loops loops; 302518334Speter 302690282Sobrien /* Discover and record the loop depth at the head of each basic 302790282Sobrien block. The loop infrastructure does the real job for us. */ 302890282Sobrien flow_loops_find (&loops, LOOP_TREE); 302918334Speter 3030104765Skan if (rtl_dump_file) 3031104765Skan flow_loops_dump (&loops, rtl_dump_file, NULL, 0); 3032104765Skan 303390282Sobrien /* Estimate using heuristics if no profiling info is available. */ 303490282Sobrien if (flag_guess_branch_prob) 303590282Sobrien estimate_probability (&loops); 303618334Speter 303790282Sobrien flow_loops_free (&loops); 303890282Sobrien } 303990282Sobrien life_analysis (insns, rtl_dump_file, PROP_FINAL); 304090282Sobrien timevar_pop (TV_FLOW); 304118334Speter 304290282Sobrien no_new_pseudos = 1; 304318334Speter 304490282Sobrien if (warn_uninitialized || extra_warnings) 304518334Speter { 304690282Sobrien uninitialized_vars_warning (DECL_INITIAL (decl)); 304790282Sobrien if (extra_warnings) 304890282Sobrien setjmp_args_warning (); 304918334Speter } 305090282Sobrien 305190282Sobrien if (optimize) 305218334Speter { 305390282Sobrien if (initialize_uninitialized_subregs ()) 305418334Speter { 305590282Sobrien /* Insns were inserted, so things might look a bit different. */ 305690282Sobrien insns = get_insns (); 305790282Sobrien life_analysis (insns, rtl_dump_file, 305890282Sobrien (PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES)); 305918334Speter } 306018334Speter } 306118334Speter 306290282Sobrien close_dump_file (DFI_life, print_rtl_with_bb, insns); 306318334Speter 306490282Sobrien ggc_collect (); 306552558Sobrien 306618334Speter /* If -opt, try combining insns through substitution. */ 306718334Speter 306818334Speter if (optimize > 0) 306950615Sobrien { 307090282Sobrien int rebuild_jump_labels_after_combine = 0; 307152558Sobrien 307290282Sobrien timevar_push (TV_COMBINE); 307390282Sobrien open_dump_file (DFI_combine, decl); 307452558Sobrien 307590282Sobrien rebuild_jump_labels_after_combine 307690282Sobrien = combine_instructions (insns, max_reg_num ()); 307790282Sobrien 307890282Sobrien /* Always purge dead edges, as we may eliminate an insn throwing 307990282Sobrien exception. */ 308090282Sobrien rebuild_jump_labels_after_combine |= purge_all_dead_edges (true); 308190282Sobrien 308290282Sobrien /* Combining insns may have turned an indirect jump into a 308390282Sobrien direct jump. Rebuid the JUMP_LABEL fields of jumping 308490282Sobrien instructions. */ 308590282Sobrien if (rebuild_jump_labels_after_combine) 308652558Sobrien { 308790282Sobrien timevar_push (TV_JUMP); 308890282Sobrien rebuild_jump_labels (insns); 308990282Sobrien timevar_pop (TV_JUMP); 309090282Sobrien 309190282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); 309252558Sobrien } 309390282Sobrien 309490282Sobrien close_dump_file (DFI_combine, print_rtl_with_bb, insns); 309590282Sobrien timevar_pop (TV_COMBINE); 309690282Sobrien 309790282Sobrien ggc_collect (); 309850615Sobrien } 309918334Speter 310090282Sobrien /* Rerun if-conversion, as combine may have simplified things enough to 310190282Sobrien now meet sequence length restrictions. */ 310290282Sobrien if (optimize > 0) 310390282Sobrien { 310490282Sobrien timevar_push (TV_IFCVT); 310590282Sobrien open_dump_file (DFI_ce, decl); 310690282Sobrien 310790282Sobrien no_new_pseudos = 0; 310890282Sobrien if_convert (1); 310990282Sobrien no_new_pseudos = 1; 311090282Sobrien 311190282Sobrien close_dump_file (DFI_ce, print_rtl_with_bb, insns); 311290282Sobrien timevar_pop (TV_IFCVT); 311390282Sobrien } 311490282Sobrien 311550615Sobrien /* Register allocation pre-pass, to reduce number of moves 311650615Sobrien necessary for two-address machines. */ 311750615Sobrien if (optimize > 0 && (flag_regmove || flag_expensive_optimizations)) 311850615Sobrien { 311990282Sobrien timevar_push (TV_REGMOVE); 312090282Sobrien open_dump_file (DFI_regmove, decl); 312152558Sobrien 312290282Sobrien regmove_optimize (insns, max_reg_num (), rtl_dump_file); 312352558Sobrien 312490282Sobrien close_dump_file (DFI_regmove, print_rtl_with_bb, insns); 312590282Sobrien timevar_pop (TV_REGMOVE); 312690282Sobrien 312790282Sobrien ggc_collect (); 312850615Sobrien } 312918334Speter 313090282Sobrien /* Do unconditional splitting before register allocation to allow machine 313190282Sobrien description to add extra information not needed previously. */ 313290282Sobrien split_all_insns (1); 313390282Sobrien 313490282Sobrien /* Any of the several passes since flow1 will have munged register 313590282Sobrien lifetime data a bit. */ 313690282Sobrien register_life_up_to_date = 0; 313790282Sobrien 313890282Sobrien#ifdef OPTIMIZE_MODE_SWITCHING 313990282Sobrien timevar_push (TV_MODE_SWITCH); 314090282Sobrien 314190282Sobrien no_new_pseudos = 0; 314290282Sobrien if (optimize_mode_switching (NULL)) 314390282Sobrien { 314490282Sobrien /* We did work, and so had to regenerate global life information. 314590282Sobrien Take advantage of this and don't re-recompute register life 314690282Sobrien information below. */ 314790282Sobrien register_life_up_to_date = 1; 314890282Sobrien } 314990282Sobrien no_new_pseudos = 1; 315090282Sobrien 315190282Sobrien timevar_pop (TV_MODE_SWITCH); 315290282Sobrien#endif 315390282Sobrien 315490282Sobrien timevar_push (TV_SCHED); 315590282Sobrien 315690282Sobrien#ifdef INSN_SCHEDULING 315790282Sobrien 315818334Speter /* Print function header into sched dump now 315918334Speter because doing the sched analysis makes some of the dump. */ 316018334Speter if (optimize > 0 && flag_schedule_insns) 316118334Speter { 316290282Sobrien open_dump_file (DFI_sched, decl); 316352558Sobrien 316418334Speter /* Do control and data sched analysis, 316518334Speter and write some of the results to dump file. */ 316618334Speter 316790282Sobrien schedule_insns (rtl_dump_file); 316852558Sobrien 316990282Sobrien close_dump_file (DFI_sched, print_rtl_with_bb, insns); 317052558Sobrien 317190282Sobrien /* Register lifetime information was updated as part of verifying 317290282Sobrien the schedule. */ 317390282Sobrien register_life_up_to_date = 1; 317418334Speter } 317590282Sobrien#endif 317690282Sobrien timevar_pop (TV_SCHED); 317718334Speter 317890282Sobrien ggc_collect (); 317990282Sobrien 318052558Sobrien /* Determine if the current function is a leaf before running reload 318152558Sobrien since this can impact optimizations done by the prologue and 318252558Sobrien epilogue thus changing register elimination offsets. */ 318352558Sobrien current_function_is_leaf = leaf_function_p (); 318452558Sobrien 318590282Sobrien timevar_push (TV_LOCAL_ALLOC); 318690282Sobrien open_dump_file (DFI_lreg, decl); 318718334Speter 318890282Sobrien /* Allocate pseudo-regs that are used only within 1 basic block. 318990282Sobrien 319052558Sobrien RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the 319152558Sobrien jump optimizer after register allocation and reloading are finished. */ 319252558Sobrien 319390282Sobrien if (! register_life_up_to_date) 319490282Sobrien recompute_reg_usage (insns, ! optimize_size); 319518334Speter 319690282Sobrien /* Allocate the reg_renumber array. */ 319790282Sobrien allocate_reg_info (max_regno, FALSE, TRUE); 319818334Speter 319990282Sobrien /* And the reg_equiv_memory_loc array. */ 320090282Sobrien reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx)); 320190282Sobrien 320290282Sobrien allocate_initial_values (reg_equiv_memory_loc); 320390282Sobrien 320490282Sobrien regclass (insns, max_reg_num (), rtl_dump_file); 320590282Sobrien rebuild_label_notes_after_reload = local_alloc (); 320690282Sobrien 320790282Sobrien timevar_pop (TV_LOCAL_ALLOC); 320890282Sobrien 320990282Sobrien if (dump_file[DFI_lreg].enabled) 321050615Sobrien { 321190282Sobrien timevar_push (TV_DUMP); 321252558Sobrien 321390282Sobrien dump_flow_info (rtl_dump_file); 321490282Sobrien dump_local_alloc (rtl_dump_file); 321552558Sobrien 321690282Sobrien close_dump_file (DFI_lreg, print_rtl_with_bb, insns); 321790282Sobrien timevar_pop (TV_DUMP); 321850615Sobrien } 321918334Speter 322090282Sobrien ggc_collect (); 322118334Speter 322290282Sobrien timevar_push (TV_GLOBAL_ALLOC); 322390282Sobrien open_dump_file (DFI_greg, decl); 322418334Speter 322590282Sobrien /* If optimizing, allocate remaining pseudo-regs. Do the reload 322690282Sobrien pass fixing up any insns that are invalid. */ 322718334Speter 322890282Sobrien if (optimize) 322990282Sobrien failure = global_alloc (rtl_dump_file); 323090282Sobrien else 323190282Sobrien { 323290282Sobrien build_insn_chain (insns); 323390282Sobrien failure = reload (insns, 0); 323490282Sobrien } 323518334Speter 323690282Sobrien timevar_pop (TV_GLOBAL_ALLOC); 323790282Sobrien 323890282Sobrien if (dump_file[DFI_greg].enabled) 323990282Sobrien { 324090282Sobrien timevar_push (TV_DUMP); 324190282Sobrien 324290282Sobrien dump_global_regs (rtl_dump_file); 324390282Sobrien 324490282Sobrien close_dump_file (DFI_greg, print_rtl_with_bb, insns); 324590282Sobrien timevar_pop (TV_DUMP); 324690282Sobrien } 324790282Sobrien 324818334Speter if (failure) 324918334Speter goto exit_rest_of_compilation; 325018334Speter 325190282Sobrien ggc_collect (); 325290282Sobrien 325390282Sobrien open_dump_file (DFI_postreload, decl); 325490282Sobrien 325550615Sobrien /* Do a very simple CSE pass over just the hard registers. */ 325650615Sobrien if (optimize > 0) 325790282Sobrien { 325890282Sobrien timevar_push (TV_RELOAD_CSE_REGS); 325990282Sobrien reload_cse_regs (insns); 326090282Sobrien timevar_pop (TV_RELOAD_CSE_REGS); 326190282Sobrien } 326250615Sobrien 326352558Sobrien /* Register allocation and reloading may have turned an indirect jump into 326452558Sobrien a direct jump. If so, we must rebuild the JUMP_LABEL fields of 326552558Sobrien jumping instructions. */ 326652558Sobrien if (rebuild_label_notes_after_reload) 326790282Sobrien { 326890282Sobrien timevar_push (TV_JUMP); 326952558Sobrien 327090282Sobrien rebuild_jump_labels (insns); 327152558Sobrien 327290282Sobrien timevar_pop (TV_JUMP); 327390282Sobrien } 327452558Sobrien 327590282Sobrien close_dump_file (DFI_postreload, print_rtl_with_bb, insns); 327652558Sobrien 327790282Sobrien /* Re-create the death notes which were deleted during reload. */ 327890282Sobrien timevar_push (TV_FLOW2); 327990282Sobrien open_dump_file (DFI_flow2, decl); 328052558Sobrien 328190282Sobrien#ifdef ENABLE_CHECKING 328290282Sobrien verify_flow_info (); 328390282Sobrien#endif 328452558Sobrien 328590282Sobrien /* If optimizing, then go ahead and split insns now. */ 328690282Sobrien if (optimize > 0) 328790282Sobrien split_all_insns (0); 328852558Sobrien 328990282Sobrien cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0); 329052558Sobrien 329190282Sobrien /* On some machines, the prologue and epilogue code, or parts thereof, 329290282Sobrien can be represented as RTL. Doing so lets us schedule insns between 329390282Sobrien it and the rest of the code and also allows delayed branch 329490282Sobrien scheduling to operate in the epilogue. */ 329590282Sobrien thread_prologue_and_epilogue_insns (insns); 329690282Sobrien 329796289Sobrien /* Cross-jumping is O(N^3) on the number of edges, thus trying to 329896289Sobrien perform cross-jumping on flow graphs which have a high connectivity 329996289Sobrien will take a long time. This is similar to the test to disable GCSE. */ 330096289Sobrien cleanup_crossjump = CLEANUP_CROSSJUMP; 330196289Sobrien if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20) 330296289Sobrien { 330396289Sobrien if (optimize && warn_disabled_optimization) 330496289Sobrien warning ("crossjump disabled: %d > 1000 basic blocks and %d >= 20 edges/basic block", 330596289Sobrien n_basic_blocks, n_edges / n_basic_blocks); 330696289Sobrien cleanup_crossjump = 0; 330796289Sobrien } 330896289Sobrien 330952558Sobrien if (optimize) 331052558Sobrien { 331196289Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | cleanup_crossjump); 331290282Sobrien life_analysis (insns, rtl_dump_file, PROP_FINAL); 331390282Sobrien 331490282Sobrien /* This is kind of a heuristic. We need to run combine_stack_adjustments 331590282Sobrien even for machines with possibly nonzero RETURN_POPS_ARGS 331690282Sobrien and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having 331790282Sobrien push instructions will have popping returns. */ 331890282Sobrien#ifndef PUSH_ROUNDING 331990282Sobrien if (!ACCUMULATE_OUTGOING_ARGS) 332090282Sobrien#endif 332190282Sobrien combine_stack_adjustments (); 332290282Sobrien 332390282Sobrien ggc_collect (); 332452558Sobrien } 332552558Sobrien 332652558Sobrien flow2_completed = 1; 332752558Sobrien 332890282Sobrien close_dump_file (DFI_flow2, print_rtl_with_bb, insns); 332990282Sobrien timevar_pop (TV_FLOW2); 333018334Speter 333190282Sobrien#ifdef HAVE_peephole2 333290282Sobrien if (optimize > 0 && flag_peephole2) 333390282Sobrien { 333490282Sobrien timevar_push (TV_PEEPHOLE2); 333590282Sobrien open_dump_file (DFI_peephole2, decl); 333618334Speter 333790282Sobrien peephole2_optimize (rtl_dump_file); 333890282Sobrien 333990282Sobrien close_dump_file (DFI_peephole2, print_rtl_with_bb, insns); 334090282Sobrien timevar_pop (TV_PEEPHOLE2); 334190282Sobrien } 334290282Sobrien#endif 334390282Sobrien 334496289Sobrien if (optimize > 0 && (flag_rename_registers || flag_cprop_registers)) 334550615Sobrien { 334690282Sobrien timevar_push (TV_RENAME_REGISTERS); 334790282Sobrien open_dump_file (DFI_rnreg, decl); 334890282Sobrien 334990282Sobrien if (flag_rename_registers) 335090282Sobrien regrename_optimize (); 335190282Sobrien if (flag_cprop_registers) 335290282Sobrien copyprop_hardreg_forward (); 335390282Sobrien 335490282Sobrien close_dump_file (DFI_rnreg, print_rtl_with_bb, insns); 335590282Sobrien timevar_pop (TV_RENAME_REGISTERS); 335650615Sobrien } 335752558Sobrien 335890282Sobrien if (optimize > 0) 335990282Sobrien { 336090282Sobrien timevar_push (TV_IFCVT2); 336190282Sobrien open_dump_file (DFI_ce2, decl); 336290282Sobrien 336390282Sobrien if_convert (1); 336490282Sobrien 336590282Sobrien close_dump_file (DFI_ce2, print_rtl_with_bb, insns); 336690282Sobrien timevar_pop (TV_IFCVT2); 336790282Sobrien } 336890282Sobrien#ifdef STACK_REGS 336990282Sobrien if (optimize) 337090282Sobrien split_all_insns (1); 337190282Sobrien#endif 337290282Sobrien 337390282Sobrien#ifdef INSN_SCHEDULING 337418334Speter if (optimize > 0 && flag_schedule_insns_after_reload) 337518334Speter { 337690282Sobrien timevar_push (TV_SCHED2); 337790282Sobrien open_dump_file (DFI_sched2, decl); 337818334Speter 337918334Speter /* Do control and data sched analysis again, 338018334Speter and write some more of the results to dump file. */ 338118334Speter 338290282Sobrien split_all_insns (1); 338318334Speter 338490282Sobrien schedule_insns (rtl_dump_file); 338518334Speter 338690282Sobrien close_dump_file (DFI_sched2, print_rtl_with_bb, insns); 338790282Sobrien timevar_pop (TV_SCHED2); 338890282Sobrien 338990282Sobrien ggc_collect (); 339018334Speter } 339190282Sobrien#endif 339218334Speter 339318334Speter#ifdef LEAF_REGISTERS 339452558Sobrien current_function_uses_only_leaf_regs 339552558Sobrien = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); 339618334Speter#endif 339718334Speter 339890282Sobrien#ifdef STACK_REGS 339990282Sobrien timevar_push (TV_REG_STACK); 340090282Sobrien open_dump_file (DFI_stack, decl); 340118334Speter 340290282Sobrien reg_to_stack (insns, rtl_dump_file); 340390282Sobrien 340490282Sobrien close_dump_file (DFI_stack, print_rtl_with_bb, insns); 340590282Sobrien timevar_pop (TV_REG_STACK); 340690282Sobrien 340790282Sobrien ggc_collect (); 340890282Sobrien#endif 340918334Speter if (optimize > 0) 341018334Speter { 341190282Sobrien timevar_push (TV_REORDER_BLOCKS); 341290282Sobrien open_dump_file (DFI_bbro, decl); 341352558Sobrien 341496289Sobrien /* Last attempt to optimize CFG, as life analysis possibly removed 341596289Sobrien some instructions. Note that we can't rerun crossjump at this 341696289Sobrien point, because it can turn a switch into a direct branch, which 341796289Sobrien can leave the tablejump address calculation in the code, which 341896289Sobrien can lead to referencing an undefined label. */ 341996289Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK); 342090282Sobrien if (flag_reorder_blocks) 342152558Sobrien { 342290282Sobrien reorder_basic_blocks (); 342390282Sobrien cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK); 342452558Sobrien } 342590282Sobrien 342690282Sobrien close_dump_file (DFI_bbro, print_rtl_with_bb, insns); 342790282Sobrien timevar_pop (TV_REORDER_BLOCKS); 342818334Speter } 342990282Sobrien compute_alignments (); 343018334Speter 343190282Sobrien /* CFG is no longer maintained up-to-date. */ 343290282Sobrien free_bb_for_insn (); 343390282Sobrien 343418334Speter /* If a machine dependent reorganization is needed, call it. */ 343518334Speter#ifdef MACHINE_DEPENDENT_REORG 343690282Sobrien timevar_push (TV_MACH_DEP); 343790282Sobrien open_dump_file (DFI_mach, decl); 343850615Sobrien 343990282Sobrien MACHINE_DEPENDENT_REORG (insns); 344090282Sobrien 344190282Sobrien close_dump_file (DFI_mach, print_rtl, insns); 344290282Sobrien timevar_pop (TV_MACH_DEP); 344390282Sobrien 344490282Sobrien ggc_collect (); 344518334Speter#endif 344618334Speter 344790282Sobrien purge_line_number_notes (insns); 344890282Sobrien cleanup_barriers (); 344990282Sobrien 345018334Speter /* If a scheduling pass for delayed branches is to be done, 345150615Sobrien call the scheduling code. */ 345218334Speter 345318334Speter#ifdef DELAY_SLOTS 345418334Speter if (optimize > 0 && flag_delayed_branch) 345518334Speter { 345690282Sobrien timevar_push (TV_DBR_SCHED); 345790282Sobrien open_dump_file (DFI_dbr, decl); 345852558Sobrien 345990282Sobrien dbr_schedule (insns, rtl_dump_file); 346052558Sobrien 346190282Sobrien close_dump_file (DFI_dbr, print_rtl, insns); 346290282Sobrien timevar_pop (TV_DBR_SCHED); 346390282Sobrien 346490282Sobrien ggc_collect (); 346518334Speter } 346618334Speter#endif 346718334Speter 346890282Sobrien#if defined (HAVE_ATTR_length) && !defined (STACK_REGS) 346990282Sobrien timevar_push (TV_SHORTEN_BRANCH); 347090282Sobrien split_all_insns_noflow (); 347190282Sobrien timevar_pop (TV_SHORTEN_BRANCH); 347290282Sobrien#endif 347390282Sobrien 347490282Sobrien convert_to_eh_region_ranges (); 347590282Sobrien 347618334Speter /* Shorten branches. */ 347790282Sobrien timevar_push (TV_SHORTEN_BRANCH); 347890282Sobrien shorten_branches (get_insns ()); 347990282Sobrien timevar_pop (TV_SHORTEN_BRANCH); 348018334Speter 348190282Sobrien current_function_nothrow = nothrow_function_p (); 348290282Sobrien if (current_function_nothrow) 348390282Sobrien /* Now we know that this can't throw; set the flag for the benefit 348490282Sobrien of other functions later in this translation unit. */ 348590282Sobrien TREE_NOTHROW (current_function_decl) = 1; 348652558Sobrien 348790282Sobrien /* Now turn the rtl into assembler code. */ 348850615Sobrien 348990282Sobrien timevar_push (TV_FINAL); 349090282Sobrien { 349190282Sobrien rtx x; 349290282Sobrien const char *fnname; 349390282Sobrien 349490282Sobrien /* Get the function's name, as described by its RTL. This may be 349590282Sobrien different from the DECL_NAME name used in the source file. */ 349690282Sobrien 349790282Sobrien x = DECL_RTL (decl); 349890282Sobrien if (GET_CODE (x) != MEM) 349990282Sobrien abort (); 350090282Sobrien x = XEXP (x, 0); 350190282Sobrien if (GET_CODE (x) != SYMBOL_REF) 350290282Sobrien abort (); 350390282Sobrien fnname = XSTR (x, 0); 350490282Sobrien 350590282Sobrien assemble_start_function (decl, fnname); 350690282Sobrien final_start_function (insns, asm_out_file, optimize); 350790282Sobrien final (insns, asm_out_file, optimize, 0); 350890282Sobrien final_end_function (); 350990282Sobrien 351090282Sobrien#ifdef IA64_UNWIND_INFO 351190282Sobrien /* ??? The IA-64 ".handlerdata" directive must be issued before 351290282Sobrien the ".endp" directive that closes the procedure descriptor. */ 351390282Sobrien output_function_exception_table (); 351418334Speter#endif 351518334Speter 351690282Sobrien assemble_end_function (decl, fnname); 351718334Speter 351890282Sobrien#ifndef IA64_UNWIND_INFO 351990282Sobrien /* Otherwise, it feels unclean to switch sections in the middle. */ 352090282Sobrien output_function_exception_table (); 352190282Sobrien#endif 352218334Speter 352390282Sobrien if (! quiet_flag) 352490282Sobrien fflush (asm_out_file); 352518334Speter 352690282Sobrien /* Release all memory allocated by flow. */ 352790282Sobrien free_basic_block_vars (0); 352818334Speter 352990282Sobrien /* Release all memory held by regsets now. */ 353090282Sobrien regset_release_memory (); 353190282Sobrien } 353290282Sobrien timevar_pop (TV_FINAL); 353350615Sobrien 353490282Sobrien ggc_collect (); 353552558Sobrien 353690282Sobrien /* Write DBX symbols if requested. */ 353718334Speter 353818334Speter /* Note that for those inline functions where we don't initially 353918334Speter know for certain that we will be generating an out-of-line copy, 354018334Speter the first invocation of this routine (rest_of_compilation) will 354118334Speter skip over this code by doing a `goto exit_rest_of_compilation;'. 354218334Speter Later on, finish_compilation will call rest_of_compilation again 354318334Speter for those inline functions that need to have out-of-line copies 354418334Speter generated. During that call, we *will* be routed past here. */ 354518334Speter 354690282Sobrien timevar_push (TV_SYMOUT); 354790282Sobrien (*debug_hooks->function_decl) (decl); 354890282Sobrien timevar_pop (TV_SYMOUT); 354918334Speter 355018334Speter exit_rest_of_compilation: 355118334Speter 355218334Speter /* In case the function was not output, 355318334Speter don't leave any temporary anonymous types 355418334Speter queued up for sdb output. */ 355518334Speter#ifdef SDB_DEBUGGING_INFO 355618334Speter if (write_symbols == SDB_DEBUG) 355718334Speter sdbout_types (NULL_TREE); 355818334Speter#endif 355918334Speter 356018334Speter reload_completed = 0; 356152558Sobrien flow2_completed = 0; 356252558Sobrien no_new_pseudos = 0; 356318334Speter 356490282Sobrien timevar_push (TV_FINAL); 356518334Speter 356690282Sobrien /* Clear out the insn_length contents now that they are no 356790282Sobrien longer valid. */ 356890282Sobrien init_insn_lengths (); 356918334Speter 357090282Sobrien /* Clear out the real_constant_chain before some of the rtx's 357190282Sobrien it runs through become garbage. */ 357290282Sobrien clear_const_double_mem (); 357318334Speter 357490282Sobrien /* Show no temporary slots allocated. */ 357590282Sobrien init_temp_slots (); 357618334Speter 357790282Sobrien free_basic_block_vars (0); 357890282Sobrien free_bb_for_insn (); 357990282Sobrien 358090282Sobrien timevar_pop (TV_FINAL); 358190282Sobrien 358250615Sobrien /* Make sure volatile mem refs aren't considered valid operands for 358350615Sobrien arithmetic insns. We must call this here if this is a nested inline 358450615Sobrien function, since the above code leaves us in the init_recog state 358550615Sobrien (from final.c), and the function context push/pop code does not 358650615Sobrien save/restore volatile_ok. 358718334Speter 358850615Sobrien ??? Maybe it isn't necessary for expand_start_function to call this 358950615Sobrien anymore if we do it here? */ 359050615Sobrien 359150615Sobrien init_recog_no_volatile (); 359250615Sobrien 359390282Sobrien /* We're done with this function. Free up memory if we can. */ 359490282Sobrien free_after_parsing (cfun); 359590282Sobrien if (! DECL_DEFER_OUTPUT (decl)) 359690282Sobrien { 359790282Sobrien free_after_compilation (cfun); 359818334Speter 359990282Sobrien /* Clear integrate.c's pointer to the cfun structure we just 360090282Sobrien destroyed. */ 360190282Sobrien DECL_SAVED_INSNS (decl) = 0; 360290282Sobrien } 360390282Sobrien cfun = 0; 360452558Sobrien 360590282Sobrien ggc_collect (); 360690282Sobrien 360790282Sobrien timevar_pop (TV_REST_OF_COMPILATION); 360818334Speter} 360918334Speter 361050615Sobrienstatic void 361150615Sobriendisplay_help () 361250615Sobrien{ 361390282Sobrien int undoc; 361490282Sobrien unsigned long i; 361590282Sobrien const char *lang; 361650615Sobrien 361790282Sobrien printf (_(" -ffixed-<register> Mark <register> as being unavailable to the compiler\n")); 361890282Sobrien printf (_(" -fcall-used-<register> Mark <register> as being corrupted by function calls\n")); 361990282Sobrien printf (_(" -fcall-saved-<register> Mark <register> as being preserved across functions\n")); 362090282Sobrien printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n")); 362190282Sobrien printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n")); 362290282Sobrien 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")); 362390282Sobrien 362490282Sobrien for (i = ARRAY_SIZE (f_options); i--;) 362550615Sobrien { 362690282Sobrien const char *description = f_options[i].description; 362790282Sobrien 362850615Sobrien if (description != NULL && * description != 0) 362950615Sobrien printf (" -f%-21s %s\n", 363090282Sobrien f_options[i].string, _(description)); 363150615Sobrien } 363290282Sobrien 363390282Sobrien printf (_(" -O[number] Set optimization level to [number]\n")); 363490282Sobrien printf (_(" -Os Optimize for space rather than speed\n")); 363590282Sobrien for (i = LAST_PARAM; i--;) 363650615Sobrien { 363790282Sobrien const char *description = compiler_params[i].help; 363890282Sobrien const int length = 21-strlen(compiler_params[i].option); 363990282Sobrien 364050615Sobrien if (description != NULL && * description != 0) 364190282Sobrien printf (" --param %s=<value>%.*s%s\n", 364290282Sobrien compiler_params[i].option, 364390282Sobrien length > 0 ? length : 1, " ", 364490282Sobrien _(description)); 364590282Sobrien } 364690282Sobrien printf (_(" -pedantic Issue warnings needed by strict compliance to ISO C\n")); 364790282Sobrien printf (_(" -pedantic-errors Like -pedantic except that errors are produced\n")); 364890282Sobrien printf (_(" -w Suppress warnings\n")); 364990282Sobrien printf (_(" -W Enable extra warnings\n")); 365090282Sobrien 365190282Sobrien for (i = ARRAY_SIZE (W_options); i--;) 365290282Sobrien { 365390282Sobrien const char *description = W_options[i].description; 365490282Sobrien 365590282Sobrien if (description != NULL && * description != 0) 365650615Sobrien printf (" -W%-21s %s\n", 365790282Sobrien W_options[i].string, _(description)); 365850615Sobrien } 365990282Sobrien 366090282Sobrien printf (_(" -Wunused Enable unused warnings\n")); 366190282Sobrien printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n")); 366290282Sobrien printf (_(" -p Enable function profiling\n")); 366390282Sobrien printf (_(" -o <file> Place output into <file> \n")); 366490282Sobrien printf (_("\ 366590282Sobrien -G <number> Put global and static data smaller than <number>\n\ 366690282Sobrien bytes into a special section (on some targets)\n")); 366790282Sobrien 366890282Sobrien for (i = ARRAY_SIZE (debug_args); i--;) 366950615Sobrien { 367050615Sobrien if (debug_args[i].description != NULL) 367190282Sobrien printf (" -g%-21s %s\n", 367290282Sobrien debug_args[i].arg, _(debug_args[i].description)); 367350615Sobrien } 367490282Sobrien 367590282Sobrien printf (_(" -aux-info <file> Emit declaration info into <file>\n")); 367690282Sobrien printf (_(" -quiet Do not display functions compiled or elapsed time\n")); 367790282Sobrien printf (_(" -version Display the compiler's version\n")); 367890282Sobrien printf (_(" -d[letters] Enable dumps from specific passes of the compiler\n")); 367990282Sobrien printf (_(" -dumpbase <file> Base name to be used for dumps from specific passes\n")); 368090282Sobrien#if defined INSN_SCHEDULING 368190282Sobrien printf (_(" -fsched-verbose=<number> Set the verbosity level of the scheduler\n")); 368250615Sobrien#endif 368390282Sobrien printf (_(" --help Display this information\n")); 368450615Sobrien 368550615Sobrien undoc = 0; 368650615Sobrien lang = "language"; 368790282Sobrien 368850615Sobrien /* Display descriptions of language specific options. 368950615Sobrien If there is no description, note that there is an undocumented option. 369050615Sobrien If the description is empty, do not display anything. (This allows 369150615Sobrien options to be deliberately undocumented, for whatever reason). 369250615Sobrien If the option string is missing, then this is a marker, indicating 369352558Sobrien that the description string is in fact the name of a language, whose 369450615Sobrien language specific options are to follow. */ 369590282Sobrien 369690282Sobrien if (ARRAY_SIZE (documented_lang_options) > 1) 369750615Sobrien { 369890282Sobrien printf (_("\nLanguage specific options:\n")); 369950615Sobrien 370090282Sobrien for (i = 0; i < ARRAY_SIZE (documented_lang_options); i++) 370150615Sobrien { 370290282Sobrien const char *description = documented_lang_options[i].description; 370390282Sobrien const char *option = documented_lang_options[i].option; 370450615Sobrien 370550615Sobrien if (description == NULL) 370652558Sobrien { 370752558Sobrien undoc = 1; 370852558Sobrien 370952558Sobrien if (extra_warnings) 371090282Sobrien printf (_(" %-23.23s [undocumented]\n"), option); 371152558Sobrien } 371290282Sobrien else if (*description == 0) 371350615Sobrien continue; 371450615Sobrien else if (option == NULL) 371550615Sobrien { 371650615Sobrien if (undoc) 371750615Sobrien printf 371890282Sobrien (_("\nThere are undocumented %s specific options as well.\n"), 371950615Sobrien lang); 372050615Sobrien undoc = 0; 372150615Sobrien 372290282Sobrien printf (_("\n Options for %s:\n"), description); 372390282Sobrien 372450615Sobrien lang = description; 372550615Sobrien } 372650615Sobrien else 372790282Sobrien printf (" %-23.23s %s\n", option, _(description)); 372850615Sobrien } 372950615Sobrien } 373050615Sobrien 373150615Sobrien if (undoc) 373290282Sobrien printf (_("\nThere are undocumented %s specific options as well.\n"), 373390282Sobrien lang); 373450615Sobrien 373590282Sobrien display_target_options (); 373690282Sobrien} 373790282Sobrien 373890282Sobrienstatic void 373990282Sobriendisplay_target_options () 374090282Sobrien{ 374190282Sobrien int undoc, i; 374290282Sobrien static bool displayed = false; 374390282Sobrien 374490282Sobrien /* Avoid double printing for --help --target-help. */ 374590282Sobrien if (displayed) 374690282Sobrien return; 374790282Sobrien displayed = true; 374890282Sobrien 374990282Sobrien if (ARRAY_SIZE (target_switches) > 1 375050615Sobrien#ifdef TARGET_OPTIONS 375190282Sobrien || ARRAY_SIZE (target_options) > 1 375250615Sobrien#endif 375350615Sobrien ) 375450615Sobrien { 375550615Sobrien int doc = 0; 375690282Sobrien 375750615Sobrien undoc = 0; 375850615Sobrien 375990282Sobrien printf (_("\nTarget specific options:\n")); 376090282Sobrien 376190282Sobrien for (i = ARRAY_SIZE (target_switches); i--;) 376250615Sobrien { 376390282Sobrien const char *option = target_switches[i].name; 376490282Sobrien const char *description = target_switches[i].description; 376550615Sobrien 376690282Sobrien if (option == NULL || *option == 0) 376750615Sobrien continue; 376850615Sobrien else if (description == NULL) 376952558Sobrien { 377052558Sobrien undoc = 1; 377190282Sobrien 377252558Sobrien if (extra_warnings) 377390282Sobrien printf (_(" -m%-23.23s [undocumented]\n"), option); 377452558Sobrien } 377550615Sobrien else if (* description != 0) 377690282Sobrien doc += printf (" -m%-23.23s %s\n", option, _(description)); 377750615Sobrien } 377890282Sobrien 377990282Sobrien#ifdef TARGET_OPTIONS 378090282Sobrien for (i = ARRAY_SIZE (target_options); i--;) 378150615Sobrien { 378290282Sobrien const char *option = target_options[i].prefix; 378390282Sobrien const char *description = target_options[i].description; 378450615Sobrien 378590282Sobrien if (option == NULL || *option == 0) 378650615Sobrien continue; 378750615Sobrien else if (description == NULL) 378852558Sobrien { 378952558Sobrien undoc = 1; 379090282Sobrien 379152558Sobrien if (extra_warnings) 379290282Sobrien printf (_(" -m%-23.23s [undocumented]\n"), option); 379352558Sobrien } 379450615Sobrien else if (* description != 0) 379590282Sobrien doc += printf (" -m%-23.23s %s\n", option, _(description)); 379650615Sobrien } 379750615Sobrien#endif 379850615Sobrien if (undoc) 379952558Sobrien { 380052558Sobrien if (doc) 380190282Sobrien printf (_("\nThere are undocumented target specific options as well.\n")); 380252558Sobrien else 380390282Sobrien printf (_(" They exist, but they are not documented.\n")); 380452558Sobrien } 380550615Sobrien } 380650615Sobrien} 380790282Sobrien 380890282Sobrien/* Parse a -d... command line switch. */ 380950615Sobrien 381090282Sobrienstatic void 381190282Sobriendecode_d_option (arg) 381290282Sobrien const char *arg; 381390282Sobrien{ 381490282Sobrien int i, c, matched; 381550615Sobrien 381690282Sobrien while (*arg) 381790282Sobrien switch (c = *arg++) 381890282Sobrien { 381990282Sobrien case 'a': 382090282Sobrien for (i = 0; i < (int) DFI_MAX; ++i) 382190282Sobrien dump_file[i].enabled = 1; 382290282Sobrien break; 382390282Sobrien case 'A': 382490282Sobrien flag_debug_asm = 1; 382590282Sobrien break; 382690282Sobrien case 'p': 382790282Sobrien flag_print_asm_name = 1; 382890282Sobrien break; 382990282Sobrien case 'P': 383090282Sobrien flag_dump_rtl_in_asm = 1; 383190282Sobrien flag_print_asm_name = 1; 383290282Sobrien break; 383390282Sobrien case 'v': 383490282Sobrien graph_dump_format = vcg; 383590282Sobrien break; 383690282Sobrien case 'x': 383790282Sobrien rtl_dump_and_exit = 1; 383890282Sobrien break; 383990282Sobrien case 'y': 384090282Sobrien (*lang_hooks.set_yydebug) (1); 384190282Sobrien break; 384290282Sobrien case 'D': /* These are handled by the preprocessor. */ 384390282Sobrien case 'I': 384490282Sobrien break; 384590282Sobrien 384690282Sobrien default: 384790282Sobrien matched = 0; 384890282Sobrien for (i = 0; i < (int) DFI_MAX; ++i) 384990282Sobrien if (c == dump_file[i].debug_switch) 385090282Sobrien { 385190282Sobrien dump_file[i].enabled = 1; 385290282Sobrien matched = 1; 385390282Sobrien } 385490282Sobrien 385590282Sobrien if (! matched) 385690282Sobrien warning ("unrecognized gcc debugging option: %c", c); 385790282Sobrien break; 385890282Sobrien } 385990282Sobrien} 386090282Sobrien 386190282Sobrien/* Parse a -f... command line switch. ARG is the value after the -f. 386290282Sobrien It is safe to access 'ARG - 2' to generate the full switch name. 386390282Sobrien Return the number of strings consumed. */ 386490282Sobrien 386550615Sobrienstatic int 386690282Sobriendecode_f_option (arg) 386790282Sobrien const char *arg; 386850615Sobrien{ 386990282Sobrien int j; 387090282Sobrien const char *option_value = NULL; 387150615Sobrien 387290282Sobrien /* Search for the option in the table of binary f options. */ 387390282Sobrien for (j = ARRAY_SIZE (f_options); j--;) 387450615Sobrien { 387590282Sobrien if (!strcmp (arg, f_options[j].string)) 387650615Sobrien { 387790282Sobrien *f_options[j].variable = f_options[j].on_value; 387890282Sobrien return 1; 387950615Sobrien } 388090282Sobrien 388190282Sobrien if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-' 388290282Sobrien && ! strcmp (arg + 3, f_options[j].string)) 388390282Sobrien { 388490282Sobrien *f_options[j].variable = ! f_options[j].on_value; 388590282Sobrien return 1; 388690282Sobrien } 388750615Sobrien } 388818334Speter 388990282Sobrien if (!strcmp (arg, "fast-math")) 389090282Sobrien set_fast_math_flags (); 389190282Sobrien else if (!strcmp (arg, "no-fast-math")) 389290282Sobrien set_no_fast_math_flags (); 389390282Sobrien else if ((option_value = skip_leading_substring (arg, "inline-limit-")) 389490282Sobrien || (option_value = skip_leading_substring (arg, "inline-limit="))) 389590282Sobrien { 389690282Sobrien int val = 389790282Sobrien read_integral_parameter (option_value, arg - 2, 389890282Sobrien MAX_INLINE_INSNS); 389990282Sobrien set_param_value ("max-inline-insns", val); 390090282Sobrien } 390190282Sobrien#ifdef INSN_SCHEDULING 390290282Sobrien else if ((option_value = skip_leading_substring (arg, "sched-verbose="))) 390390282Sobrien fix_sched_param ("verbose", option_value); 390418334Speter#endif 390590282Sobrien else if ((option_value = skip_leading_substring (arg, "fixed-"))) 390690282Sobrien fix_register (option_value, 1, 1); 390790282Sobrien else if ((option_value = skip_leading_substring (arg, "call-used-"))) 390890282Sobrien fix_register (option_value, 0, 1); 390990282Sobrien else if ((option_value = skip_leading_substring (arg, "call-saved-"))) 391090282Sobrien fix_register (option_value, 0, 0); 391190282Sobrien else if ((option_value = skip_leading_substring (arg, "align-loops="))) 391290282Sobrien align_loops = read_integral_parameter (option_value, arg - 2, align_loops); 391390282Sobrien else if ((option_value = skip_leading_substring (arg, "align-functions="))) 391490282Sobrien align_functions 391590282Sobrien = read_integral_parameter (option_value, arg - 2, align_functions); 391690282Sobrien else if ((option_value = skip_leading_substring (arg, "align-jumps="))) 391790282Sobrien align_jumps = read_integral_parameter (option_value, arg - 2, align_jumps); 391890282Sobrien else if ((option_value = skip_leading_substring (arg, "align-labels="))) 391990282Sobrien align_labels 392090282Sobrien = read_integral_parameter (option_value, arg - 2, align_labels); 392190282Sobrien else if ((option_value 392290282Sobrien = skip_leading_substring (arg, "stack-limit-register="))) 392390282Sobrien { 392490282Sobrien int reg = decode_reg_name (option_value); 392590282Sobrien if (reg < 0) 392690282Sobrien error ("unrecognized register name `%s'", option_value); 392790282Sobrien else 392890282Sobrien stack_limit_rtx = gen_rtx_REG (Pmode, reg); 392990282Sobrien } 393090282Sobrien else if ((option_value 393190282Sobrien = skip_leading_substring (arg, "stack-limit-symbol="))) 393290282Sobrien { 393390282Sobrien const char *nm; 393490282Sobrien nm = ggc_strdup (option_value); 393590282Sobrien stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm); 393690282Sobrien } 393790282Sobrien else if ((option_value 393890282Sobrien = skip_leading_substring (arg, "message-length="))) 393990282Sobrien output_set_maximum_length 394090282Sobrien (&global_dc->buffer, read_integral_parameter 394190282Sobrien (option_value, arg - 2, diagnostic_line_cutoff (global_dc))); 394290282Sobrien else if ((option_value 394390282Sobrien = skip_leading_substring (arg, "diagnostics-show-location="))) 394490282Sobrien { 394590282Sobrien if (!strcmp (option_value, "once")) 394690282Sobrien diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE; 394790282Sobrien else if (!strcmp (option_value, "every-line")) 394890282Sobrien diagnostic_prefixing_rule (global_dc) 394990282Sobrien = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; 395090282Sobrien else 395190282Sobrien error ("unrecognized option `%s'", arg - 2); 395290282Sobrien } 395390282Sobrien else if (!strcmp (arg, "no-stack-limit")) 395490282Sobrien stack_limit_rtx = NULL_RTX; 395590282Sobrien else if (!strcmp (arg, "preprocessed")) 395690282Sobrien /* Recognise this switch but do nothing. This prevents warnings 395790282Sobrien about an unrecognized switch if cpplib has not been linked in. */ 395890282Sobrien ; 395990282Sobrien else 396090282Sobrien return 0; 396118334Speter 396290282Sobrien return 1; 396390282Sobrien} 396418334Speter 396590282Sobrien/* Parse a -W... command line switch. ARG is the value after the -W. 396690282Sobrien It is safe to access 'ARG - 2' to generate the full switch name. 396790282Sobrien Return the number of strings consumed. */ 396818334Speter 396990282Sobrienstatic int 397090282Sobriendecode_W_option (arg) 397190282Sobrien const char *arg; 397290282Sobrien{ 397390282Sobrien const char *option_value = NULL; 397490282Sobrien int j; 397552558Sobrien 397690282Sobrien /* Search for the option in the table of binary W options. */ 397718334Speter 397890282Sobrien for (j = ARRAY_SIZE (W_options); j--;) 397918334Speter { 398090282Sobrien if (!strcmp (arg, W_options[j].string)) 398118334Speter { 398290282Sobrien *W_options[j].variable = W_options[j].on_value; 398390282Sobrien return 1; 398418334Speter } 398590282Sobrien 398690282Sobrien if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-' 398790282Sobrien && ! strcmp (arg + 3, W_options[j].string)) 398818334Speter { 398990282Sobrien *W_options[j].variable = ! W_options[j].on_value; 399090282Sobrien return 1; 399118334Speter } 399218334Speter } 399318334Speter 399490282Sobrien if ((option_value = skip_leading_substring (arg, "id-clash-"))) 399590282Sobrien warning ("-Wid-clash-LEN is no longer supported"); 399690282Sobrien else if ((option_value = skip_leading_substring (arg, "larger-than-"))) 399790282Sobrien { 399890282Sobrien larger_than_size = read_integral_parameter (option_value, arg - 2, -1); 399918334Speter 400090282Sobrien warn_larger_than = larger_than_size != -1; 400118334Speter } 400290282Sobrien else if (!strcmp (arg, "unused")) 400318334Speter { 400490282Sobrien set_Wunused (1); 400518334Speter } 400690282Sobrien else if (!strcmp (arg, "no-unused")) 400718334Speter { 400890282Sobrien set_Wunused (0); 400918334Speter } 401090282Sobrien else 401190282Sobrien return 0; 401218334Speter 401390282Sobrien return 1; 401490282Sobrien} 401550615Sobrien 401690282Sobrien/* Parse a -g... command line switch. ARG is the value after the -g. 401790282Sobrien It is safe to access 'ARG - 2' to generate the full switch name. 401890282Sobrien Return the number of strings consumed. */ 401918334Speter 402090282Sobrienstatic int 402190282Sobriendecode_g_option (arg) 402290282Sobrien const char *arg; 402390282Sobrien{ 402490282Sobrien static unsigned level=0; 402590282Sobrien /* A lot of code assumes write_symbols == NO_DEBUG if the 402690282Sobrien debugging level is 0 (thus -gstabs1 -gstabs0 would lose track 402790282Sobrien of what debugging type has been selected). This records the 402890282Sobrien selected type. It is an error to specify more than one 402990282Sobrien debugging type. */ 403090282Sobrien static enum debug_info_type selected_debug_type = NO_DEBUG; 403190282Sobrien /* Non-zero if debugging format has been explicitly set. 403290282Sobrien -g and -ggdb don't explicitly set the debugging format so 403390282Sobrien -gdwarf -g3 is equivalent to -gdwarf3. */ 403490282Sobrien static int type_explicitly_set_p = 0; 403590282Sobrien /* Indexed by enum debug_info_type. */ 403690282Sobrien static const char *const debug_type_names[] = 403790282Sobrien { 403890282Sobrien "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms" 403990282Sobrien }; 404018334Speter 404190282Sobrien /* The maximum admissible debug level value. */ 404290282Sobrien static const unsigned max_debug_level = 3; 404390282Sobrien 404490282Sobrien /* Look up ARG in the table. */ 404590282Sobrien for (da = debug_args; da->arg; da++) 404618334Speter { 404790282Sobrien const int da_len = strlen (da->arg); 404890282Sobrien 404990282Sobrien if (da_len == 0 || ! strncmp (arg, da->arg, da_len)) 405050615Sobrien { 405190282Sobrien enum debug_info_type type = da->debug_type; 405290282Sobrien const char *p = arg + da_len; 405318334Speter 405490282Sobrien if (*p && ! ISDIGIT (*p)) 405590282Sobrien continue; 405618334Speter 405790282Sobrien /* A debug flag without a level defaults to level 2. 405890282Sobrien Note we do not want to call read_integral_parameter 405990282Sobrien for that case since it will call atoi which 406090282Sobrien will return zero. 406118334Speter 406290282Sobrien ??? We may want to generalize the interface to 406390282Sobrien read_integral_parameter to better handle this case 406490282Sobrien if this case shows up often. */ 406590282Sobrien if (*p) 406690282Sobrien level = read_integral_parameter (p, 0, max_debug_level + 1); 406790282Sobrien else 406890282Sobrien level = (level == 0) ? 2 : level; 406918334Speter 407090282Sobrien if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len)) 407118334Speter { 407290282Sobrien error ("use -gdwarf -g%d for DWARF v1, level %d", 407390282Sobrien level, level); 407490282Sobrien if (level == 2) 407590282Sobrien error ("use -gdwarf-2 for DWARF v2"); 407618334Speter } 407790282Sobrien 407890282Sobrien if (level > max_debug_level) 407918334Speter { 408090282Sobrien warning ("\ 408190282Sobrienignoring option `%s' due to invalid debug level specification", 408290282Sobrien arg - 2); 408390282Sobrien level = debug_info_level; 408418334Speter } 408518334Speter 408690282Sobrien if (type == NO_DEBUG) 408718334Speter { 408890282Sobrien type = PREFERRED_DEBUGGING_TYPE; 408918334Speter 409090282Sobrien if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0) 409118334Speter { 409296289Sobrien#ifdef DWARF2_DEBUGGING_INFO 409390282Sobrien type = DWARF2_DEBUG; 409450615Sobrien#else 409518334Speter#ifdef DBX_DEBUGGING_INFO 409690282Sobrien type = DBX_DEBUG; 409750615Sobrien#endif 409850615Sobrien#endif 409990282Sobrien } 410090282Sobrien } 410118334Speter 410290282Sobrien if (type == NO_DEBUG) 410390282Sobrien warning ("`%s': unknown or unsupported -g option", arg - 2); 410418334Speter 410590282Sobrien /* Does it conflict with an already selected type? */ 410690282Sobrien if (type_explicitly_set_p 410790282Sobrien /* -g/-ggdb don't conflict with anything. */ 410890282Sobrien && da->debug_type != NO_DEBUG 410990282Sobrien && type != selected_debug_type) 411090282Sobrien warning ("`%s' ignored, conflicts with `-g%s'", 411190282Sobrien arg - 2, debug_type_names[(int) selected_debug_type]); 411290282Sobrien else 411318334Speter { 411490282Sobrien /* If the format has already been set, -g/-ggdb 411590282Sobrien only change the debug level. */ 411690282Sobrien if (type_explicitly_set_p && da->debug_type == NO_DEBUG) 411790282Sobrien /* Don't change debugging type. */ 411890282Sobrien ; 411952558Sobrien else 412090282Sobrien { 412190282Sobrien selected_debug_type = type; 412290282Sobrien type_explicitly_set_p = da->debug_type != NO_DEBUG; 412352558Sobrien } 412490282Sobrien 412590282Sobrien write_symbols = (level == 0 412690282Sobrien ? NO_DEBUG 412790282Sobrien : selected_debug_type); 412890282Sobrien use_gnu_debug_info_extensions = da->use_extensions_p; 412990282Sobrien debug_info_level = (enum debug_info_level) level; 413018334Speter } 413190282Sobrien 413290282Sobrien break; 413318334Speter } 413418334Speter } 413518334Speter 413690282Sobrien if (! da->arg) 413790282Sobrien return 0; 413818334Speter 413990282Sobrien return 1; 414090282Sobrien} 414190282Sobrien 414290282Sobrien/* Decode the first argument in the argv as a language-independent option. 414390282Sobrien Return the number of strings consumed. */ 414490282Sobrien 414590282Sobrienstatic unsigned int 414690282Sobrienindependent_decode_option (argc, argv) 414790282Sobrien int argc; 414890282Sobrien char **argv; 414990282Sobrien{ 415090282Sobrien char *arg = argv[0]; 415190282Sobrien 415290282Sobrien if (arg[0] != '-' || arg[1] == 0) 415318334Speter { 415490282Sobrien if (arg[0] == '+') 415590282Sobrien return 0; 415618334Speter 415790282Sobrien filename = arg; 415890282Sobrien 415990282Sobrien return 1; 416018334Speter } 416118334Speter 416290282Sobrien arg++; 416318334Speter 416490282Sobrien if (!strcmp (arg, "-help")) 416550615Sobrien { 416690282Sobrien display_help (); 416790282Sobrien exit_after_options = 1; 416850615Sobrien } 416950615Sobrien 417090282Sobrien if (!strcmp (arg, "-target-help")) 417150615Sobrien { 417290282Sobrien display_target_options (); 417390282Sobrien exit_after_options = 1; 417450615Sobrien } 417550615Sobrien 417690282Sobrien if (!strcmp (arg, "-version")) 417718334Speter { 417890282Sobrien print_version (stderr, ""); 417990282Sobrien exit_after_options = 1; 418018334Speter } 418118334Speter 418290282Sobrien /* Handle '--param <name>=<value>'. */ 418390282Sobrien if (strcmp (arg, "-param") == 0) 418490282Sobrien { 418590282Sobrien char *equal; 418618334Speter 418790282Sobrien if (argc == 1) 418852558Sobrien { 418990282Sobrien error ("-param option missing argument"); 419090282Sobrien return 1; 419152558Sobrien } 419290282Sobrien 419390282Sobrien /* Get the '<name>=<value>' parameter. */ 419490282Sobrien arg = argv[1]; 419590282Sobrien /* Look for the `='. */ 419690282Sobrien equal = strchr (arg, '='); 419790282Sobrien if (!equal) 419890282Sobrien error ("invalid --param option: %s", arg); 419952558Sobrien else 420090282Sobrien { 420190282Sobrien int val; 420252558Sobrien 420390282Sobrien /* Zero out the `=' sign so that we get two separate strings. */ 420490282Sobrien *equal = '\0'; 420590282Sobrien /* Figure out what value is specified. */ 420690282Sobrien val = read_integral_parameter (equal + 1, NULL, INVALID_PARAM_VAL); 420790282Sobrien if (val != INVALID_PARAM_VAL) 420890282Sobrien set_param_value (arg, val); 420990282Sobrien else 421090282Sobrien error ("invalid parameter value `%s'", equal + 1); 421190282Sobrien } 421290282Sobrien 421390282Sobrien return 2; 421418334Speter } 421518334Speter 421690282Sobrien if (*arg == 'Y') 421790282Sobrien arg++; 421818334Speter 421990282Sobrien switch (*arg) 422018334Speter { 422190282Sobrien default: 422290282Sobrien return 0; 422318334Speter 422490282Sobrien case 'O': 422590282Sobrien /* Already been treated in main (). Do nothing. */ 422690282Sobrien break; 422718334Speter 422890282Sobrien case 'm': 422990282Sobrien set_target_switch (arg + 1); 423090282Sobrien break; 423190282Sobrien 423290282Sobrien case 'f': 423390282Sobrien return decode_f_option (arg + 1); 423490282Sobrien 423590282Sobrien case 'g': 423690282Sobrien return decode_g_option (arg + 1); 423790282Sobrien 423890282Sobrien case 'd': 423990282Sobrien if (!strcmp (arg, "dumpbase")) 424090282Sobrien { 424190282Sobrien if (argc == 1) 424290282Sobrien return 0; 424390282Sobrien 424490282Sobrien dump_base_name = argv[1]; 424590282Sobrien return 2; 424690282Sobrien } 424790282Sobrien else 424890282Sobrien decode_d_option (arg + 1); 424990282Sobrien break; 425090282Sobrien 425190282Sobrien case 'p': 425290282Sobrien if (!strcmp (arg, "pedantic")) 425390282Sobrien pedantic = 1; 425490282Sobrien else if (!strcmp (arg, "pedantic-errors")) 425590282Sobrien flag_pedantic_errors = pedantic = 1; 425690282Sobrien else if (arg[1] == 0) 425790282Sobrien profile_flag = 1; 425890282Sobrien else 425990282Sobrien return 0; 426090282Sobrien break; 426190282Sobrien 426290282Sobrien case 'q': 426390282Sobrien if (!strcmp (arg, "quiet")) 426490282Sobrien quiet_flag = 1; 426590282Sobrien else 426690282Sobrien return 0; 426790282Sobrien break; 426890282Sobrien 426990282Sobrien case 'v': 427090282Sobrien if (!strcmp (arg, "version")) 427190282Sobrien version_flag = 1; 427290282Sobrien else 427390282Sobrien return 0; 427490282Sobrien break; 427590282Sobrien 427690282Sobrien case 'w': 427790282Sobrien if (arg[1] == 0) 427890282Sobrien inhibit_warnings = 1; 427990282Sobrien else 428090282Sobrien return 0; 428190282Sobrien break; 428290282Sobrien 428390282Sobrien case 'W': 428490282Sobrien if (arg[1] == 0) 428590282Sobrien { 428690282Sobrien extra_warnings = 1; 428790282Sobrien /* We save the value of warn_uninitialized, since if they put 428890282Sobrien -Wuninitialized on the command line, we need to generate a 428990282Sobrien warning about not using it without also specifying -O. */ 429090282Sobrien if (warn_uninitialized != 1) 429190282Sobrien warn_uninitialized = 2; 429290282Sobrien } 429390282Sobrien else 429490282Sobrien return decode_W_option (arg + 1); 429590282Sobrien break; 429690282Sobrien 429790282Sobrien case 'a': 429890282Sobrien if (!strncmp (arg, "aux-info", 8)) 429990282Sobrien { 430090282Sobrien if (arg[8] == '\0') 430190282Sobrien { 430290282Sobrien if (argc == 1) 430390282Sobrien return 0; 430490282Sobrien 430590282Sobrien aux_info_file_name = argv[1]; 430690282Sobrien flag_gen_aux_info = 1; 430790282Sobrien return 2; 430890282Sobrien } 430990282Sobrien else if (arg[8] == '=') 431090282Sobrien { 431190282Sobrien aux_info_file_name = arg + 9; 431290282Sobrien flag_gen_aux_info = 1; 431390282Sobrien } 431490282Sobrien else 431590282Sobrien return 0; 431690282Sobrien } 431790282Sobrien else 431890282Sobrien return 0; 431990282Sobrien break; 432090282Sobrien 432190282Sobrien case 'o': 432290282Sobrien if (arg[1] == 0) 432390282Sobrien { 432490282Sobrien if (argc == 1) 432590282Sobrien return 0; 432690282Sobrien 432790282Sobrien asm_file_name = argv[1]; 432890282Sobrien return 2; 432990282Sobrien } 433090282Sobrien return 0; 433190282Sobrien 433290282Sobrien case 'G': 433390282Sobrien { 433490282Sobrien int g_switch_val; 433590282Sobrien int return_val; 433690282Sobrien 433790282Sobrien if (arg[1] == 0) 433890282Sobrien { 433990282Sobrien if (argc == 1) 434090282Sobrien return 0; 434190282Sobrien 434290282Sobrien g_switch_val = read_integral_parameter (argv[1], 0, -1); 434390282Sobrien return_val = 2; 434490282Sobrien } 434590282Sobrien else 434690282Sobrien { 434790282Sobrien g_switch_val = read_integral_parameter (arg + 1, 0, -1); 434890282Sobrien return_val = 1; 434990282Sobrien } 435090282Sobrien 435190282Sobrien if (g_switch_val == -1) 435290282Sobrien return_val = 0; 435390282Sobrien else 435490282Sobrien { 435590282Sobrien g_switch_set = TRUE; 435690282Sobrien g_switch_value = g_switch_val; 435790282Sobrien } 435890282Sobrien 435990282Sobrien return return_val; 436090282Sobrien } 436118334Speter } 436218334Speter 436390282Sobrien return 1; 436418334Speter} 436518334Speter 436618334Speter/* Decode -m switches. */ 436718334Speter/* Decode the switch -mNAME. */ 436818334Speter 436952558Sobrienstatic void 437018334Speterset_target_switch (name) 437190282Sobrien const char *name; 437218334Speter{ 437390282Sobrien size_t j; 437452558Sobrien int valid_target_option = 0; 437518334Speter 437690282Sobrien for (j = 0; j < ARRAY_SIZE (target_switches); j++) 437718334Speter if (!strcmp (target_switches[j].name, name)) 437818334Speter { 437918334Speter if (target_switches[j].value < 0) 438018334Speter target_flags &= ~-target_switches[j].value; 438118334Speter else 438218334Speter target_flags |= target_switches[j].value; 438352558Sobrien valid_target_option = 1; 438418334Speter } 438518334Speter 438618334Speter#ifdef TARGET_OPTIONS 438752558Sobrien if (!valid_target_option) 438890282Sobrien for (j = 0; j < ARRAY_SIZE (target_options); j++) 438918334Speter { 439018334Speter int len = strlen (target_options[j].prefix); 439118334Speter if (!strncmp (target_options[j].prefix, name, len)) 439218334Speter { 439318334Speter *target_options[j].variable = name + len; 439452558Sobrien valid_target_option = 1; 439518334Speter } 439618334Speter } 439718334Speter#endif 439818334Speter 439952558Sobrien if (!valid_target_option) 440090282Sobrien error ("invalid option `%s'", name); 440118334Speter} 440218334Speter 440350615Sobrien/* Print version information to FILE. 440450615Sobrien Each line begins with INDENT (for the case where FILE is the 440550615Sobrien assembler output file). */ 440618334Speter 440752558Sobrienstatic void 440850615Sobrienprint_version (file, indent) 440950615Sobrien FILE *file; 441052558Sobrien const char *indent; 441150615Sobrien{ 441250615Sobrien#ifndef __VERSION__ 441352558Sobrien#define __VERSION__ "[?]" 441450615Sobrien#endif 441552558Sobrien fnotice (file, 441652558Sobrien#ifdef __GNUC__ 441790282Sobrien "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n" 441850615Sobrien#else 441952558Sobrien "%s%s%s version %s (%s) compiled by CC.\n" 442050615Sobrien#endif 442152558Sobrien , indent, *indent != 0 ? " " : "", 442290282Sobrien lang_hooks.name, version_string, TARGET_NAME, 442390282Sobrien indent, __VERSION__); 442450615Sobrien} 442518334Speter 442650615Sobrien/* Print an option value and return the adjusted position in the line. 442750615Sobrien ??? We don't handle error returns from fprintf (disk full); presumably 442850615Sobrien other code will catch a disk full though. */ 442918334Speter 443052558Sobrienstatic int 443150615Sobrienprint_single_switch (file, pos, max, indent, sep, term, type, name) 443250615Sobrien FILE *file; 443350615Sobrien int pos, max; 443452558Sobrien const char *indent, *sep, *term, *type, *name; 443518334Speter{ 443650615Sobrien /* The ultrix fprintf returns 0 on success, so compute the result we want 443750615Sobrien here since we need it for the following test. */ 443850615Sobrien int len = strlen (sep) + strlen (type) + strlen (name); 443918334Speter 444050615Sobrien if (pos != 0 444150615Sobrien && pos + len > max) 444218334Speter { 444350615Sobrien fprintf (file, "%s", term); 444450615Sobrien pos = 0; 444518334Speter } 444650615Sobrien if (pos == 0) 444750615Sobrien { 444850615Sobrien fprintf (file, "%s", indent); 444950615Sobrien pos = strlen (indent); 445050615Sobrien } 445150615Sobrien fprintf (file, "%s%s%s", sep, type, name); 445250615Sobrien pos += len; 445350615Sobrien return pos; 445418334Speter} 445590282Sobrien 445650615Sobrien/* Print active target switches to FILE. 445750615Sobrien POS is the current cursor position and MAX is the size of a "line". 445850615Sobrien Each line begins with INDENT and ends with TERM. 445950615Sobrien Each switch is separated from the next by SEP. */ 446018334Speter 446152558Sobrienstatic void 446250615Sobrienprint_switch_values (file, pos, max, indent, sep, term) 446350615Sobrien FILE *file; 446450615Sobrien int pos, max; 446552558Sobrien const char *indent, *sep, *term; 446618334Speter{ 446750615Sobrien size_t j; 446850615Sobrien char **p; 446918334Speter 447050615Sobrien /* Print the options as passed. */ 447118334Speter 447250615Sobrien pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term, 447352558Sobrien _("options passed: "), ""); 447450615Sobrien 447550615Sobrien for (p = &save_argv[1]; *p != NULL; p++) 447650615Sobrien if (**p == '-') 447750615Sobrien { 447850615Sobrien /* Ignore these. */ 447950615Sobrien if (strcmp (*p, "-o") == 0) 448050615Sobrien { 448150615Sobrien if (p[1] != NULL) 448250615Sobrien p++; 448350615Sobrien continue; 448450615Sobrien } 448550615Sobrien if (strcmp (*p, "-quiet") == 0) 448650615Sobrien continue; 448750615Sobrien if (strcmp (*p, "-version") == 0) 448850615Sobrien continue; 448950615Sobrien if ((*p)[1] == 'd') 449050615Sobrien continue; 449150615Sobrien 449250615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, *p, ""); 449350615Sobrien } 449450615Sobrien if (pos > 0) 449550615Sobrien fprintf (file, "%s", term); 449650615Sobrien 449750615Sobrien /* Print the -f and -m options that have been enabled. 449850615Sobrien We don't handle language specific options but printing argv 449950615Sobrien should suffice. */ 450050615Sobrien 450150615Sobrien pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term, 450252558Sobrien _("options enabled: "), ""); 450350615Sobrien 450490282Sobrien for (j = 0; j < ARRAY_SIZE (f_options); j++) 450518334Speter if (*f_options[j].variable == f_options[j].on_value) 450650615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 450750615Sobrien "-f", f_options[j].string); 450818334Speter 450950615Sobrien /* Print target specific options. */ 451018334Speter 451190282Sobrien for (j = 0; j < ARRAY_SIZE (target_switches); j++) 451218334Speter if (target_switches[j].name[0] != '\0' 451318334Speter && target_switches[j].value > 0 451418334Speter && ((target_switches[j].value & target_flags) 451518334Speter == target_switches[j].value)) 451650615Sobrien { 451750615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 451850615Sobrien "-m", target_switches[j].name); 451950615Sobrien } 452018334Speter 452150615Sobrien#ifdef TARGET_OPTIONS 452290282Sobrien for (j = 0; j < ARRAY_SIZE (target_options); j++) 452350615Sobrien if (*target_options[j].variable != NULL) 452450615Sobrien { 452550615Sobrien char prefix[256]; 452650615Sobrien sprintf (prefix, "-m%s", target_options[j].prefix); 452750615Sobrien pos = print_single_switch (file, pos, max, indent, sep, term, 452850615Sobrien prefix, *target_options[j].variable); 452950615Sobrien } 453050615Sobrien#endif 453150615Sobrien 453250615Sobrien fprintf (file, "%s", term); 453318334Speter} 453490282Sobrien 453590282Sobrien/* Open assembly code output file. Do this even if -fsyntax-only is 453690282Sobrien on, because then the driver will have provided the name of a 453790282Sobrien temporary file or bit bucket for us. NAME is the file specified on 453890282Sobrien the command line, possibly NULL. */ 453990282Sobrienstatic void 454090282Sobrieninit_asm_output (name) 454190282Sobrien const char *name; 454290282Sobrien{ 454390282Sobrien if (name == NULL && asm_file_name == 0) 454490282Sobrien asm_out_file = stdout; 454590282Sobrien else 454690282Sobrien { 454790282Sobrien if (asm_file_name == 0) 454890282Sobrien { 454990282Sobrien int len = strlen (dump_base_name); 455090282Sobrien char *dumpname = (char *) xmalloc (len + 6); 455190282Sobrien memcpy (dumpname, dump_base_name, len + 1); 455290282Sobrien strip_off_ending (dumpname, len); 455390282Sobrien strcat (dumpname, ".s"); 455490282Sobrien asm_file_name = dumpname; 455590282Sobrien } 455690282Sobrien if (!strcmp (asm_file_name, "-")) 455790282Sobrien asm_out_file = stdout; 455890282Sobrien else 455990282Sobrien asm_out_file = fopen (asm_file_name, "w"); 456090282Sobrien if (asm_out_file == 0) 456190282Sobrien fatal_io_error ("can't open %s for writing", asm_file_name); 456290282Sobrien } 456350615Sobrien 456490282Sobrien#ifdef IO_BUFFER_SIZE 456590282Sobrien setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), 456690282Sobrien _IOFBF, IO_BUFFER_SIZE); 456790282Sobrien#endif 456850615Sobrien 456990282Sobrien if (!flag_syntax_only) 457090282Sobrien { 457190282Sobrien#ifdef ASM_FILE_START 457290282Sobrien ASM_FILE_START (asm_out_file); 457390282Sobrien#endif 457490282Sobrien 457590282Sobrien#ifdef ASM_COMMENT_START 457690282Sobrien if (flag_verbose_asm) 457790282Sobrien { 457890282Sobrien /* Print the list of options in effect. */ 457990282Sobrien print_version (asm_out_file, ASM_COMMENT_START); 458090282Sobrien print_switch_values (asm_out_file, 0, MAX_LINE, 458190282Sobrien ASM_COMMENT_START, " ", "\n"); 458290282Sobrien /* Add a blank line here so it appears in assembler output but not 458390282Sobrien screen output. */ 458490282Sobrien fprintf (asm_out_file, "\n"); 458590282Sobrien } 458690282Sobrien#endif 458790282Sobrien } 458890282Sobrien} 458990282Sobrien 459090282Sobrien/* Initialization of the front end environment, before command line 459190282Sobrien options are parsed. Signal handlers, internationalization etc. 459290282Sobrien ARGV0 is main's argv[0]. */ 459390282Sobrienstatic void 459490282Sobriengeneral_init (argv0) 459590282Sobrien char *argv0; 459650615Sobrien{ 459790282Sobrien char *p; 459890282Sobrien 459990282Sobrien p = argv0 + strlen (argv0); 460090282Sobrien while (p != argv0 && !IS_DIR_SEPARATOR (p[-1])) 460190282Sobrien --p; 460290282Sobrien progname = p; 460390282Sobrien 460490282Sobrien xmalloc_set_program_name (progname); 460590282Sobrien 460690282Sobrien gcc_init_libintl (); 460790282Sobrien 460890282Sobrien /* Install handler for SIGFPE, which may be received while we do 460990282Sobrien compile-time floating point arithmetic. */ 461090282Sobrien signal (SIGFPE, float_signal); 461190282Sobrien 461290282Sobrien /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */ 461390282Sobrien#ifdef SIGSEGV 461490282Sobrien signal (SIGSEGV, crash_signal); 461550615Sobrien#endif 461690282Sobrien#ifdef SIGILL 461790282Sobrien signal (SIGILL, crash_signal); 461850615Sobrien#endif 461990282Sobrien#ifdef SIGBUS 462090282Sobrien signal (SIGBUS, crash_signal); 462190282Sobrien#endif 462290282Sobrien#ifdef SIGABRT 462390282Sobrien signal (SIGABRT, crash_signal); 462490282Sobrien#endif 462590282Sobrien#if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT) 462690282Sobrien signal (SIGIOT, crash_signal); 462790282Sobrien#endif 462890282Sobrien 462990282Sobrien /* Initialize the diagnostics reporting machinery, so option parsing 463090282Sobrien can give warnings and errors. */ 463190282Sobrien diagnostic_initialize (global_dc); 463250615Sobrien} 463390282Sobrien 463490282Sobrien/* Parse command line options and set default flag values, called 463590282Sobrien after language-independent option-independent initialization. Do 463690282Sobrien minimal options processing. Outputting diagnostics is OK, but GC 463790282Sobrien and identifier hashtables etc. are not initialized yet. */ 463890282Sobrienstatic void 463990282Sobrienparse_options_and_default_flags (argc, argv) 464090282Sobrien int argc; 464190282Sobrien char **argv; 464290282Sobrien{ 464390282Sobrien int i; 464450615Sobrien 464590282Sobrien /* Save in case md file wants to emit args as a comment. */ 464690282Sobrien save_argc = argc; 464790282Sobrien save_argv = argv; 464850615Sobrien 464990282Sobrien /* Initialize register usage now so switches may override. */ 465090282Sobrien init_reg_sets (); 465190282Sobrien 465290282Sobrien /* Register the language-independent parameters. */ 465390282Sobrien add_params (lang_independent_params, LAST_PARAM); 465490282Sobrien 465590282Sobrien /* Perform language-specific options initialization. */ 465690282Sobrien (*lang_hooks.init_options) (); 465790282Sobrien 465890282Sobrien /* Scan to see what optimization level has been specified. That will 465990282Sobrien determine the default value of many flags. */ 466090282Sobrien for (i = 1; i < argc; i++) 466190282Sobrien { 466290282Sobrien if (!strcmp (argv[i], "-O")) 466390282Sobrien { 466490282Sobrien optimize = 1; 466590282Sobrien optimize_size = 0; 466690282Sobrien } 466790282Sobrien else if (argv[i][0] == '-' && argv[i][1] == 'O') 466890282Sobrien { 466990282Sobrien /* Handle -Os, -O2, -O3, -O69, ... */ 467090282Sobrien char *p = &argv[i][2]; 467190282Sobrien 467290282Sobrien if ((p[0] == 's') && (p[1] == 0)) 467390282Sobrien { 467490282Sobrien optimize_size = 1; 467590282Sobrien 467690282Sobrien /* Optimizing for size forces optimize to be 2. */ 467790282Sobrien optimize = 2; 467890282Sobrien } 467990282Sobrien else 468090282Sobrien { 468190282Sobrien const int optimize_val = read_integral_parameter (p, p - 2, -1); 468290282Sobrien if (optimize_val != -1) 468390282Sobrien { 468490282Sobrien optimize = optimize_val; 468590282Sobrien 468690282Sobrien#ifdef FORCE_OPTIMIZATION_DOWNGRADE 468790282Sobrien#warning FORCE_OPTIMIZATION_DOWNGRADE 468890282Sobrien if (optimize > FORCE_OPTIMIZATION_DOWNGRADE) 468990282Sobrien { 469090282Sobrien optimize = FORCE_OPTIMIZATION_DOWNGRADE; 469196289Sobrien warning ("\n***\n***\t-O%d converted to \"-O%d\" due to optimizer bugs on this platform\n***", 469290282Sobrien optimize_val, 469390282Sobrien FORCE_OPTIMIZATION_DOWNGRADE); 469490282Sobrien 469590282Sobrien } 469690282Sobrien#endif /*FORCE_OPTIMIZATION_DOWNGRADE*/ 469790282Sobrien 4698103792Sobrien#if defined(TRY_WITHOUT_THIS__alpha__) 469990282Sobrien if (optimize > 1) 470090282Sobrien { 470196289Sobrien warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***", 470290282Sobrien optimize_val); 470390282Sobrien } 470490282Sobrien#endif /*__alpha__*/ 470590282Sobrien 470690282Sobrien optimize_size = 0; 470790282Sobrien } 470890282Sobrien } 470990282Sobrien } 471090282Sobrien } 471190282Sobrien 471290282Sobrien if (!optimize) 471390282Sobrien { 471490282Sobrien flag_merge_constants = 0; 471590282Sobrien } 471690282Sobrien 471790282Sobrien if (optimize >= 1) 471890282Sobrien { 471990282Sobrien flag_defer_pop = 1; 472090282Sobrien flag_thread_jumps = 1; 472190282Sobrien#ifdef DELAY_SLOTS 472290282Sobrien flag_delayed_branch = 1; 472390282Sobrien#endif 472490282Sobrien#ifdef CAN_DEBUG_WITHOUT_FP 472590282Sobrien flag_omit_frame_pointer = 1; 472690282Sobrien#endif 472790282Sobrien flag_guess_branch_prob = 1; 472890282Sobrien flag_cprop_registers = 1; 472990282Sobrien } 473090282Sobrien 473190282Sobrien if (optimize >= 2) 473290282Sobrien { 473390282Sobrien flag_optimize_sibling_calls = 1; 473490282Sobrien flag_cse_follow_jumps = 1; 473590282Sobrien flag_cse_skip_blocks = 1; 473690282Sobrien flag_gcse = 1; 473790282Sobrien flag_expensive_optimizations = 1; 473890282Sobrien flag_strength_reduce = 1; 473990282Sobrien flag_rerun_cse_after_loop = 1; 474090282Sobrien flag_rerun_loop_opt = 1; 474190282Sobrien flag_caller_saves = 1; 474290282Sobrien flag_force_mem = 1; 474390282Sobrien flag_peephole2 = 1; 474490282Sobrien#ifdef INSN_SCHEDULING 474590282Sobrien flag_schedule_insns = 1; 474690282Sobrien flag_schedule_insns_after_reload = 1; 474790282Sobrien#endif 474890282Sobrien flag_regmove = 1; 474990282Sobrien flag_strict_aliasing = 1; 475090282Sobrien flag_delete_null_pointer_checks = 1; 475190282Sobrien flag_reorder_blocks = 1; 475290282Sobrien } 475390282Sobrien 475490282Sobrien if (optimize >= 3) 475590282Sobrien { 475690282Sobrien flag_inline_functions = 1; 475790282Sobrien flag_rename_registers = 1; 475890282Sobrien } 475990282Sobrien 476098573Sobrien if (optimize_size) 476190282Sobrien { 476290282Sobrien align_loops = 1; 476390282Sobrien align_jumps = 1; 476490282Sobrien align_labels = 1; 476590282Sobrien align_functions = 1; 476690282Sobrien } 476790282Sobrien 476890282Sobrien /* Initialize whether `char' is signed. */ 476990282Sobrien flag_signed_char = DEFAULT_SIGNED_CHAR; 477090282Sobrien#ifdef DEFAULT_SHORT_ENUMS 477190282Sobrien /* Initialize how much space enums occupy, by default. */ 477290282Sobrien flag_short_enums = DEFAULT_SHORT_ENUMS; 477390282Sobrien#endif 477490282Sobrien 477590282Sobrien /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can 477690282Sobrien modify it. */ 477790282Sobrien target_flags = 0; 477890282Sobrien set_target_switch (""); 477990282Sobrien 478090282Sobrien /* Unwind tables are always present in an ABI-conformant IA-64 478190282Sobrien object file, so the default should be ON. */ 478290282Sobrien#ifdef IA64_UNWIND_INFO 478390282Sobrien flag_unwind_tables = IA64_UNWIND_INFO; 478490282Sobrien#endif 478590282Sobrien 478690282Sobrien#ifdef OPTIMIZATION_OPTIONS 478790282Sobrien /* Allow default optimizations to be specified on a per-machine basis. */ 478890282Sobrien OPTIMIZATION_OPTIONS (optimize, optimize_size); 478990282Sobrien#endif 479090282Sobrien 479190282Sobrien /* Perform normal command line switch decoding. */ 479290282Sobrien for (i = 1; i < argc;) 479390282Sobrien { 479490282Sobrien int lang_processed; 479590282Sobrien int indep_processed; 479690282Sobrien 479790282Sobrien /* Give the language a chance to decode the option for itself. */ 479890282Sobrien lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i); 479990282Sobrien 480090282Sobrien if (lang_processed >= 0) 480190282Sobrien /* Now see if the option also has a language independent meaning. 480290282Sobrien Some options are both language specific and language independent, 480390282Sobrien eg --help. */ 480490282Sobrien indep_processed = independent_decode_option (argc - i, argv + i); 480590282Sobrien else 480690282Sobrien { 480790282Sobrien lang_processed = -lang_processed; 480890282Sobrien indep_processed = 0; 480990282Sobrien } 481090282Sobrien 481190282Sobrien if (lang_processed || indep_processed) 481290282Sobrien i += MAX (lang_processed, indep_processed); 481390282Sobrien else 481490282Sobrien { 481590282Sobrien const char *option = NULL; 481690282Sobrien const char *lang = NULL; 481790282Sobrien unsigned int j; 481890282Sobrien 481990282Sobrien /* It is possible that the command line switch is not valid for the 482090282Sobrien current language, but it is valid for another language. In order 482190282Sobrien to be compatible with previous versions of the compiler (which 482290282Sobrien did not issue an error message in this case) we check for this 482390282Sobrien possibility here. If we do find a match, then if extra_warnings 482490282Sobrien is set we generate a warning message, otherwise we will just 482590282Sobrien ignore the option. */ 482690282Sobrien for (j = 0; j < ARRAY_SIZE (documented_lang_options); j++) 482790282Sobrien { 482890282Sobrien option = documented_lang_options[j].option; 482990282Sobrien 483090282Sobrien if (option == NULL) 483190282Sobrien lang = documented_lang_options[j].description; 483290282Sobrien else if (! strncmp (argv[i], option, strlen (option))) 483390282Sobrien break; 483490282Sobrien } 483590282Sobrien 483690282Sobrien if (j != ARRAY_SIZE (documented_lang_options)) 483790282Sobrien { 483890282Sobrien if (extra_warnings) 483990282Sobrien { 484090282Sobrien warning ("ignoring command line option '%s'", argv[i]); 484190282Sobrien if (lang) 484290282Sobrien warning 484390282Sobrien ("(it is valid for %s but not the selected language)", 484490282Sobrien lang); 484590282Sobrien } 484690282Sobrien } 484790282Sobrien else if (argv[i][0] == '-' && argv[i][1] == 'g') 484890282Sobrien warning ("`%s': unknown or unsupported -g option", &argv[i][2]); 484990282Sobrien else 485090282Sobrien error ("unrecognized option `%s'", argv[i]); 485190282Sobrien 485290282Sobrien i++; 485390282Sobrien } 485490282Sobrien } 485590282Sobrien 485696289Sobrien if (flag_no_inline == 2) 485796289Sobrien flag_no_inline = 0; 485896289Sobrien else 485996289Sobrien flag_really_no_inline = flag_no_inline; 486096289Sobrien 486190282Sobrien /* Set flag_no_inline before the post_options () hook. The C front 486290282Sobrien ends use it to determine tree inlining defaults. FIXME: such 486390282Sobrien code should be lang-independent when all front ends use tree 486490282Sobrien inlining, in which case it, and this condition, should be moved 486590282Sobrien to the top of process_options() instead. */ 486690282Sobrien if (optimize == 0) 486790282Sobrien { 486890282Sobrien /* Inlining does not work if not optimizing, 486990282Sobrien so force it not to be done. */ 487090282Sobrien flag_no_inline = 1; 487190282Sobrien warn_inline = 0; 487290282Sobrien 487390282Sobrien /* The c_decode_option function and decode_option hook set 487490282Sobrien this to `2' if -Wall is used, so we can avoid giving out 487590282Sobrien lots of errors for people who don't realize what -Wall does. */ 487690282Sobrien if (warn_uninitialized == 1) 487790282Sobrien warning ("-Wuninitialized is not supported without -O"); 487890282Sobrien } 487990282Sobrien 488096289Sobrien if (flag_really_no_inline == 2) 488196289Sobrien flag_really_no_inline = flag_no_inline; 488296289Sobrien 488390282Sobrien /* All command line options have been parsed; allow the front end to 488490282Sobrien perform consistency checks, etc. */ 488590282Sobrien (*lang_hooks.post_options) (); 488690282Sobrien} 488790282Sobrien 488890282Sobrien/* Process the options that have been parsed. */ 488990282Sobrienstatic void 489090282Sobrienprocess_options () 489150615Sobrien{ 489290282Sobrien#ifdef OVERRIDE_OPTIONS 489390282Sobrien /* Some machines may reject certain combinations of options. */ 489490282Sobrien OVERRIDE_OPTIONS; 489590282Sobrien#endif 489690282Sobrien 489790282Sobrien /* Set up the align_*_log variables, defaulting them to 1 if they 489890282Sobrien were still unset. */ 489990282Sobrien if (align_loops <= 0) align_loops = 1; 490090282Sobrien if (align_loops_max_skip > align_loops || !align_loops) 490190282Sobrien align_loops_max_skip = align_loops - 1; 490290282Sobrien align_loops_log = floor_log2 (align_loops * 2 - 1); 490390282Sobrien if (align_jumps <= 0) align_jumps = 1; 490490282Sobrien if (align_jumps_max_skip > align_jumps || !align_jumps) 490590282Sobrien align_jumps_max_skip = align_jumps - 1; 490690282Sobrien align_jumps_log = floor_log2 (align_jumps * 2 - 1); 490790282Sobrien if (align_labels <= 0) align_labels = 1; 490890282Sobrien align_labels_log = floor_log2 (align_labels * 2 - 1); 490990282Sobrien if (align_labels_max_skip > align_labels || !align_labels) 491090282Sobrien align_labels_max_skip = align_labels - 1; 491190282Sobrien if (align_functions <= 0) align_functions = 1; 491290282Sobrien align_functions_log = floor_log2 (align_functions * 2 - 1); 491390282Sobrien 491490282Sobrien /* Unrolling all loops implies that standard loop unrolling must also 491590282Sobrien be done. */ 491690282Sobrien if (flag_unroll_all_loops) 491790282Sobrien flag_unroll_loops = 1; 491890282Sobrien /* Loop unrolling requires that strength_reduction be on also. Silently 491990282Sobrien turn on strength reduction here if it isn't already on. Also, the loop 492090282Sobrien unrolling code assumes that cse will be run after loop, so that must 492190282Sobrien be turned on also. */ 492290282Sobrien if (flag_unroll_loops) 492390282Sobrien { 492490282Sobrien flag_strength_reduce = 1; 492590282Sobrien flag_rerun_cse_after_loop = 1; 492690282Sobrien } 492790282Sobrien 492890282Sobrien if (flag_non_call_exceptions) 492990282Sobrien flag_asynchronous_unwind_tables = 1; 493090282Sobrien if (flag_asynchronous_unwind_tables) 493190282Sobrien flag_unwind_tables = 1; 493290282Sobrien 493390282Sobrien /* Warn about options that are not supported on this machine. */ 493490282Sobrien#ifndef INSN_SCHEDULING 493590282Sobrien if (flag_schedule_insns || flag_schedule_insns_after_reload) 493690282Sobrien warning ("instruction scheduling not supported on this target machine"); 493790282Sobrien#endif 493890282Sobrien#ifndef DELAY_SLOTS 493990282Sobrien if (flag_delayed_branch) 494090282Sobrien warning ("this target machine does not have delayed branches"); 494190282Sobrien#endif 494290282Sobrien 494390282Sobrien /* Some operating systems do not allow profiling without a frame 494490282Sobrien pointer. */ 494590282Sobrien if (!TARGET_ALLOWS_PROFILING_WITHOUT_FRAME_POINTER 494690282Sobrien && profile_flag 494790282Sobrien && flag_omit_frame_pointer) 494890282Sobrien { 494990282Sobrien error ("profiling does not work without a frame pointer"); 495090282Sobrien flag_omit_frame_pointer = 0; 495190282Sobrien } 495290282Sobrien 495390282Sobrien user_label_prefix = USER_LABEL_PREFIX; 495490282Sobrien if (flag_leading_underscore != -1) 495590282Sobrien { 495690282Sobrien /* If the default prefix is more complicated than "" or "_", 495790282Sobrien issue a warning and ignore this option. */ 495890282Sobrien if (user_label_prefix[0] == 0 || 495990282Sobrien (user_label_prefix[0] == '_' && user_label_prefix[1] == 0)) 496090282Sobrien { 496190282Sobrien user_label_prefix = flag_leading_underscore ? "_" : ""; 496290282Sobrien } 496390282Sobrien else 496490282Sobrien warning ("-f%sleading-underscore not supported on this target machine", 496590282Sobrien flag_leading_underscore ? "" : "no-"); 496690282Sobrien } 496790282Sobrien 496890282Sobrien /* If we are in verbose mode, write out the version and maybe all the 496990282Sobrien option flags in use. */ 497090282Sobrien if (version_flag) 497190282Sobrien { 497290282Sobrien print_version (stderr, ""); 497390282Sobrien if (! quiet_flag) 497490282Sobrien print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n"); 497590282Sobrien } 497690282Sobrien 497790282Sobrien if (! quiet_flag) 497890282Sobrien time_report = 1; 497990282Sobrien 498090282Sobrien if (flag_syntax_only) 498190282Sobrien { 498290282Sobrien write_symbols = NO_DEBUG; 498390282Sobrien profile_flag = 0; 498490282Sobrien } 498590282Sobrien 498690282Sobrien /* Now we know write_symbols, set up the debug hooks based on it. 498790282Sobrien By default we do nothing for debug output. */ 498890282Sobrien#if defined(DBX_DEBUGGING_INFO) 498950615Sobrien if (write_symbols == DBX_DEBUG) 499090282Sobrien debug_hooks = &dbx_debug_hooks; 499150615Sobrien#endif 499290282Sobrien#if defined(XCOFF_DEBUGGING_INFO) 499390282Sobrien if (write_symbols == XCOFF_DEBUG) 499490282Sobrien debug_hooks = &xcoff_debug_hooks; 499590282Sobrien#endif 499650615Sobrien#ifdef SDB_DEBUGGING_INFO 499750615Sobrien if (write_symbols == SDB_DEBUG) 499890282Sobrien debug_hooks = &sdb_debug_hooks; 499950615Sobrien#endif 500090282Sobrien#ifdef DWARF_DEBUGGING_INFO 500190282Sobrien if (write_symbols == DWARF_DEBUG) 500290282Sobrien debug_hooks = &dwarf_debug_hooks; 500390282Sobrien#endif 500490282Sobrien#ifdef DWARF2_DEBUGGING_INFO 500590282Sobrien if (write_symbols == DWARF2_DEBUG) 500690282Sobrien debug_hooks = &dwarf2_debug_hooks; 500790282Sobrien#endif 500890282Sobrien#ifdef VMS_DEBUGGING_INFO 500990282Sobrien if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) 501090282Sobrien debug_hooks = &vmsdbg_debug_hooks; 501190282Sobrien#endif 501290282Sobrien 501390282Sobrien /* If auxiliary info generation is desired, open the output file. 501490282Sobrien This goes in the same directory as the source file--unlike 501590282Sobrien all the other output files. */ 501690282Sobrien if (flag_gen_aux_info) 501790282Sobrien { 501890282Sobrien aux_info_file = fopen (aux_info_file_name, "w"); 501990282Sobrien if (aux_info_file == 0) 502090282Sobrien fatal_io_error ("can't open %s", aux_info_file_name); 502190282Sobrien } 502290282Sobrien 502390282Sobrien if (! targetm.have_named_sections) 502490282Sobrien { 502590282Sobrien if (flag_function_sections) 502690282Sobrien { 502790282Sobrien warning ("-ffunction-sections not supported for this target"); 502890282Sobrien flag_function_sections = 0; 502990282Sobrien } 503090282Sobrien if (flag_data_sections) 503190282Sobrien { 503290282Sobrien warning ("-fdata-sections not supported for this target"); 503390282Sobrien flag_data_sections = 0; 503490282Sobrien } 503590282Sobrien } 503690282Sobrien 503790282Sobrien if (flag_function_sections && profile_flag) 503890282Sobrien { 503990282Sobrien warning ("-ffunction-sections disabled; it makes profiling impossible"); 504090282Sobrien flag_function_sections = 0; 504190282Sobrien } 504290282Sobrien 504390282Sobrien#ifndef HAVE_prefetch 504490282Sobrien if (flag_prefetch_loop_arrays) 504590282Sobrien { 504690282Sobrien warning ("-fprefetch-loop-arrays not supported for this target"); 504790282Sobrien flag_prefetch_loop_arrays = 0; 504890282Sobrien } 504990282Sobrien#else 505090282Sobrien if (flag_prefetch_loop_arrays && !HAVE_prefetch) 505190282Sobrien { 505290282Sobrien warning ("-fprefetch-loop-arrays not supported for this target (try -march switches)"); 505390282Sobrien flag_prefetch_loop_arrays = 0; 505490282Sobrien } 505590282Sobrien#endif 505690282Sobrien 505790282Sobrien /* This combination of options isn't handled for i386 targets and doesn't 505890282Sobrien make much sense anyway, so don't allow it. */ 505990282Sobrien if (flag_prefetch_loop_arrays && optimize_size) 506090282Sobrien { 506190282Sobrien warning ("-fprefetch-loop-arrays is not supported with -Os"); 506290282Sobrien flag_prefetch_loop_arrays = 0; 506390282Sobrien } 506490282Sobrien 506590282Sobrien#ifndef OBJECT_FORMAT_ELF 506690282Sobrien if (flag_function_sections && write_symbols != NO_DEBUG) 506790282Sobrien warning ("-ffunction-sections may affect debugging on some targets"); 506890282Sobrien#endif 506950615Sobrien} 507090282Sobrien 507190282Sobrien/* Language-independent initialization, before language-dependent 507290282Sobrien initialization. */ 507390282Sobrienstatic void 507490282Sobrienlang_independent_init () 507590282Sobrien{ 507690282Sobrien decl_printable_name = decl_name; 507790282Sobrien lang_expand_expr = (lang_expand_expr_t) do_abort; 507850615Sobrien 507990282Sobrien /* Set the language-dependent identifier size. */ 508090282Sobrien tree_code_length[(int) IDENTIFIER_NODE] 508190282Sobrien = ((lang_hooks.identifier_size - sizeof (struct tree_common) 508290282Sobrien + sizeof (tree) - 1) / sizeof (tree)); 508350615Sobrien 508490282Sobrien /* Initialize the garbage-collector, and string pools. */ 508590282Sobrien init_ggc (); 508690282Sobrien ggc_add_rtx_root (&stack_limit_rtx, 1); 508790282Sobrien ggc_add_tree_root (¤t_function_decl, 1); 508890282Sobrien ggc_add_tree_root (¤t_function_func_begin_label, 1); 508990282Sobrien 509090282Sobrien init_stringpool (); 509190282Sobrien init_obstacks (); 509290282Sobrien 509390282Sobrien init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL 509490282Sobrien || debug_info_level == DINFO_LEVEL_VERBOSE 509590282Sobrien#ifdef VMS_DEBUGGING_INFO 509690282Sobrien /* Enable line number info for traceback */ 509790282Sobrien || debug_info_level > DINFO_LEVEL_NONE 509890282Sobrien#endif 509990282Sobrien || flag_test_coverage 510090282Sobrien || warn_notreached); 510190282Sobrien init_regs (); 510290282Sobrien init_alias_once (); 510390282Sobrien init_stmt (); 510490282Sobrien init_loop (); 510590282Sobrien init_reload (); 510690282Sobrien init_function_once (); 510790282Sobrien init_stor_layout_once (); 510890282Sobrien init_varasm_once (); 510990282Sobrien init_EXPR_INSN_LIST_cache (); 511090282Sobrien 511190282Sobrien /* The following initialization functions need to generate rtl, so 511290282Sobrien provide a dummy function context for them. */ 511390282Sobrien init_dummy_function_start (); 511490282Sobrien init_expmed (); 511590282Sobrien init_expr_once (); 511690282Sobrien if (flag_caller_saves) 511790282Sobrien init_caller_save (); 511890282Sobrien expand_dummy_function_end (); 511990282Sobrien} 512090282Sobrien 512190282Sobrien/* Language-dependent initialization. Returns non-zero on success. */ 512290282Sobrienstatic int 512390282Sobrienlang_dependent_init (name) 512490282Sobrien const char *name; 512550615Sobrien{ 512690282Sobrien if (dump_base_name == 0) 512790282Sobrien dump_base_name = name ? name : "gccdump"; 512890282Sobrien 512990282Sobrien /* Front-end initialization. This hook can assume that GC, 513090282Sobrien identifier hashes etc. are set up, but debug initialization is 513190282Sobrien not done yet. This routine must return the original filename 513290282Sobrien (e.g. foo.i -> foo.c) so can correctly initialize debug output. */ 513390282Sobrien name = (*lang_hooks.init) (name); 513490282Sobrien if (name == NULL) 513590282Sobrien return 0; 513690282Sobrien 513790282Sobrien /* Is this duplication necessary? */ 513890282Sobrien name = ggc_strdup (name); 513990282Sobrien main_input_filename = input_filename = name; 514090282Sobrien init_asm_output (name); 514190282Sobrien 514290282Sobrien /* These create various _DECL nodes, so need to be called after the 514390282Sobrien front end is initialized. */ 514490282Sobrien init_eh (); 514590282Sobrien init_optabs (); 514690282Sobrien 514790282Sobrien /* Put an entry on the input file stack for the main input file. */ 514890282Sobrien push_srcloc (input_filename, 0); 514990282Sobrien 515090282Sobrien /* If dbx symbol table desired, initialize writing it and output the 515190282Sobrien predefined types. */ 515290282Sobrien timevar_push (TV_SYMOUT); 515390282Sobrien 515490282Sobrien#ifdef DWARF2_UNWIND_INFO 515590282Sobrien if (dwarf2out_do_frame ()) 515690282Sobrien dwarf2out_frame_init (); 515790282Sobrien#endif 515890282Sobrien 515990282Sobrien /* Now we have the correct original filename, we can initialize 516090282Sobrien debug output. */ 516190282Sobrien (*debug_hooks->init) (name); 516290282Sobrien 516390282Sobrien timevar_pop (TV_SYMOUT); 516490282Sobrien 516590282Sobrien return 1; 516650615Sobrien} 516790282Sobrien 516890282Sobrien/* Clean up: close opened files, etc. */ 516950615Sobrien 517090282Sobrienstatic void 517190282Sobrienfinalize () 517290282Sobrien{ 517390282Sobrien /* Close the dump files. */ 517490282Sobrien if (flag_gen_aux_info) 517590282Sobrien { 517690282Sobrien fclose (aux_info_file); 517790282Sobrien if (errorcount) 517890282Sobrien unlink (aux_info_file_name); 517990282Sobrien } 518050615Sobrien 518190282Sobrien /* Close non-debugging input and output files. Take special care to note 518290282Sobrien whether fclose returns an error, since the pages might still be on the 518390282Sobrien buffer chain while the file is open. */ 518490282Sobrien 518590282Sobrien if (asm_out_file) 518690282Sobrien { 518790282Sobrien if (ferror (asm_out_file) != 0) 518890282Sobrien fatal_io_error ("error writing to %s", asm_file_name); 518990282Sobrien if (fclose (asm_out_file) != 0) 519090282Sobrien fatal_io_error ("error closing %s", asm_file_name); 519190282Sobrien } 519290282Sobrien 519390282Sobrien /* Do whatever is necessary to finish printing the graphs. */ 519490282Sobrien if (graph_dump_format != no_graph) 519590282Sobrien { 519690282Sobrien int i; 519790282Sobrien 519890282Sobrien for (i = 0; i < (int) DFI_MAX; ++i) 519990282Sobrien if (dump_file[i].initialized && dump_file[i].graph_dump_p) 520090282Sobrien { 520190282Sobrien char seq[16]; 520290282Sobrien char *suffix; 520390282Sobrien 520490282Sobrien sprintf (seq, DUMPFILE_FORMAT, i); 520590282Sobrien suffix = concat (seq, dump_file[i].extension, NULL); 520690282Sobrien finish_graph_dump_file (dump_base_name, suffix); 520790282Sobrien free (suffix); 520890282Sobrien } 520990282Sobrien } 521090282Sobrien 521190282Sobrien if (mem_report) 521290282Sobrien { 521390282Sobrien ggc_print_statistics (); 521490282Sobrien stringpool_statistics (); 521590282Sobrien dump_tree_statistics (); 521690282Sobrien } 521790282Sobrien 521890282Sobrien /* Free up memory for the benefit of leak detectors. */ 521990282Sobrien free_reg_info (); 522090282Sobrien 522190282Sobrien /* Language-specific end of compilation actions. */ 522290282Sobrien (*lang_hooks.finish) (); 522390282Sobrien} 522490282Sobrien 522590282Sobrien/* Initialize the compiler, and compile the input file. */ 522690282Sobrienstatic void 522790282Sobriendo_compile () 522850615Sobrien{ 522990282Sobrien /* The bulk of command line switch processing. */ 523090282Sobrien process_options (); 523190282Sobrien 523290282Sobrien /* We cannot start timing until after options are processed since that 523390282Sobrien says if we run timers or not. */ 523490282Sobrien init_timevar (); 523590282Sobrien timevar_start (TV_TOTAL); 523690282Sobrien 523790282Sobrien /* Language-independent initialization. Also sets up GC, identifier 523890282Sobrien hashes etc. */ 523990282Sobrien lang_independent_init (); 524090282Sobrien 524190282Sobrien /* Language-dependent initialization. Returns true on success. */ 524290282Sobrien if (lang_dependent_init (filename)) 524390282Sobrien compile_file (); 524490282Sobrien 524590282Sobrien finalize (); 524690282Sobrien 524790282Sobrien /* Stop timing and print the times. */ 524890282Sobrien timevar_stop (TV_TOTAL); 524990282Sobrien timevar_print (stderr); 525050615Sobrien} 525190282Sobrien 525290282Sobrien/* Entry point of cc1, cc1plus, jc1, f771, etc. 525390282Sobrien Decode command args, then call compile_file. 525490282Sobrien Exit code is FATAL_EXIT_CODE if can't open files or if there were 525590282Sobrien any errors, or SUCCESS_EXIT_CODE if compilation succeeded. 525690282Sobrien 525790282Sobrien It is not safe to call this function more than once. */ 525890282Sobrien 525990282Sobrienint 526090282Sobrientoplev_main (argc, argv) 526190282Sobrien int argc; 526290282Sobrien char **argv; 526390282Sobrien{ 526490282Sobrien hex_init (); 526590282Sobrien 526690282Sobrien /* Initialization of GCC's environment, and diagnostics. */ 526790282Sobrien general_init (argv [0]); 526890282Sobrien 526990282Sobrien /* Parse the options and do minimal processing; basically just 527090282Sobrien enough to default flags appropriately. */ 527190282Sobrien parse_options_and_default_flags (argc, argv); 527290282Sobrien 527390282Sobrien /* Exit early if we can (e.g. -help). */ 5274102796Skan if (!errorcount && !exit_after_options) 527590282Sobrien do_compile (); 527690282Sobrien 527790282Sobrien if (errorcount || sorrycount) 527890282Sobrien return (FATAL_EXIT_CODE); 527990282Sobrien 528090282Sobrien return (SUCCESS_EXIT_CODE); 528190282Sobrien} 5282