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