#include "config.h"
#undef FLOAT
#undef FFS
#include "system.h"
#include <signal.h>
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
#include "input.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
#include "insn-attr.h"
#include "insn-config.h"
#include "insn-flags.h"
#include "hard-reg-set.h"
#include "recog.h"
#include "output.h"
#include "except.h"
#include "function.h"
#include "toplev.h"
#include "expr.h"
#include "basic-block.h"
#include "intl.h"
#include "ggc.h"
#include "graph.h"
#include "loop.h"
#include "regs.h"
#include "timevar.h"
#include "diagnostic.h"
#include "ssa.h"
#include "params.h"
#include "reload.h"
#include "dwarf2asm.h"
#include "integrate.h"
#include "real.h"
#include "debug.h"
#include "target.h"
#include "langhooks.h"
#include "cfglayout.h"
#include "hosthooks.h"
#include "genindex.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
#endif
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
#include "dbxout.h"
#endif
#ifdef SDB_DEBUGGING_INFO
#include "sdbout.h"
#endif
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
#endif
extern int size_directive_output;
extern tree last_assemble_variable_decl;
extern void reg_alloc PARAMS ((void));
static void general_init PARAMS ((char *));
static void parse_options_and_default_flags PARAMS ((int, char **));
static void do_compile PARAMS ((void));
static void process_options PARAMS ((void));
static void backend_init PARAMS ((void));
static int lang_dependent_init PARAMS ((const char *));
static void init_asm_output PARAMS ((const char *));
static void finalize PARAMS ((void));
void set_target_switch PARAMS ((const char *));
static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void setup_core_dumping PARAMS ((void));
static void interrupt_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void compile_file PARAMS ((void));
static void display_help PARAMS ((void));
static void display_target_options PARAMS ((void));
static void decode_d_option PARAMS ((const char *));
static int decode_f_option PARAMS ((const char *));
static int decode_W_option PARAMS ((const char *));
static int decode_g_option PARAMS ((const char *));
static unsigned int independent_decode_option PARAMS ((int, char **));
static void print_version PARAMS ((FILE *, const char *));
static int print_single_switch PARAMS ((FILE *, int, int, const char *,
const char *, const char *,
const char *, const char *));
static void print_switch_values PARAMS ((FILE *, int, int, const char *,
const char *, const char *));
static int set_yydebug;
#define MAX_LINE 75
const char *progname;
int save_argc;
char **save_argv;
const char *input_filename;
const char *main_input_filename;
static int arch_specified = 0;
int lineno;
int no_new_pseudos;
struct file_stack *input_file_stack;
int input_file_stack_tick;
int predictive_compilation = -1;
const char *dump_base_name;
const char *aux_base_name;
#ifndef DUMPFILE_FORMAT
#define DUMPFILE_FORMAT ".%02d."
#endif
extern int target_flags;
int target_flags_explicit;
const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
struct dump_file_info
{
const char *const extension;
char const debug_switch;
char const graph_dump_p;
char enabled;
char initialized;
};
enum dump_file_index
{
DFI_rtl,
DFI_sibling,
DFI_eh,
DFI_jump,
DFI_ssa,
DFI_ssa_ccp,
DFI_ssa_dce,
DFI_ussa,
DFI_null,
DFI_cse,
DFI_addressof,
DFI_gcse,
DFI_loop,
DFI_cfg,
DFI_bp,
DFI_ce1,
DFI_tracer,
DFI_cse2,
DFI_life,
DFI_combine,
DFI_ce2,
DFI_regmove,
DFI_sched,
DFI_lreg,
DFI_greg,
DFI_postreload,
DFI_flow2,
DFI_peephole2,
DFI_rnreg,
DFI_ce3,
DFI_sched2,
DFI_stack,
DFI_bbro,
DFI_mach,
DFI_dbr,
DFI_MAX
};
static struct dump_file_info dump_file[DFI_MAX] =
{
{ "rtl", 'r', 0, 0, 0 },
{ "sibling", 'i', 0, 0, 0 },
{ "eh", 'h', 0, 0, 0 },
{ "jump", 'j', 0, 0, 0 },
{ "ssa", 'e', 1, 0, 0 },
{ "ssaccp", 'W', 1, 0, 0 },
{ "ssadce", 'X', 1, 0, 0 },
{ "ussa", 'e', 1, 0, 0 },
{ "null", 'u', 0, 0, 0 },
{ "cse", 's', 0, 0, 0 },
{ "addressof", 'F', 0, 0, 0 },
{ "gcse", 'G', 1, 0, 0 },
{ "loop", 'L', 1, 0, 0 },
{ "cfg", 'f', 1, 0, 0 },
{ "bp", 'b', 1, 0, 0 },
{ "ce1", 'C', 1, 0, 0 },
{ "tracer", 'T', 1, 0, 0 },
{ "cse2", 't', 1, 0, 0 },
{ "life", 'f', 1, 0, 0 },
{ "combine", 'c', 1, 0, 0 },
{ "ce2", 'C', 1, 0, 0 },
{ "regmove", 'N', 1, 0, 0 },
{ "sched", 'S', 1, 0, 0 },
{ "lreg", 'l', 1, 0, 0 },
{ "greg", 'g', 1, 0, 0 },
{ "postreload", 'o', 1, 0, 0 },
{ "flow2", 'w', 1, 0, 0 },
{ "peephole2", 'z', 1, 0, 0 },
{ "rnreg", 'n', 1, 0, 0 },
{ "ce3", 'E', 1, 0, 0 },
{ "sched2", 'R', 1, 0, 0 },
{ "stack", 'k', 1, 0, 0 },
{ "bbro", 'B', 1, 0, 0 },
{ "mach", 'M', 1, 0, 0 },
{ "dbr", 'd', 0, 0, 0 },
};
static int open_dump_file PARAMS ((enum dump_file_index, tree));
static void close_dump_file PARAMS ((enum dump_file_index,
void (*) (FILE *, rtx), rtx));
int rtl_dump_and_exit;
int flag_print_asm_name;
static int version_flag;
static char *filename;
enum graph_dump_types graph_dump_format;
char *asm_file_name;
int g_switch_value;
int g_switch_set;
enum debug_info_type write_symbols = NO_DEBUG;
enum debug_info_type orig_write_symbols = NO_DEBUG;
int flag_grepository = 0;
enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
int use_gnu_debug_info_extensions = 0;
#ifdef DBX_ONLY_USED_SYMBOLS
int flag_debug_only_used_symbols = -1;
#endif
int optimize = 0;
int optimize_size = 0;
static int exit_after_options = 0;
tree current_function_decl;
tree current_function_func_begin_label;
int flag_eliminate_dwarf2_dups = 0;
int profile_flag = 0;
int profile_arc_flag = 0;
int flag_create_feedback = 0;
int flag_use_feedback = 0;
int flag_test_coverage = 0;
int flag_branch_probabilities = 0;
int flag_reorder_blocks = 0;
int flag_reorder_blocks_and_partition = 0;
int flag_ss_const_prop = 0;
int flag_reorder_functions = 0;
int flag_rename_registers = 0;
int flag_cprop_registers = 0;
int pedantic = 0;
int in_system_header = 0;
int quiet_flag = 0;
int time_report = 0;
int mem_report = 0;
int flag_slow_exit = 0;
int flag_branch_predictions = 1;
int flag_detailed_statistics = 0;
int flag_signed_char;
int flag_short_enums;
int flag_altivec;
int flag_constant_cfstrings;
int warn_nonportable_cfstrings;
#ifdef DEFAULT_CALLER_SAVES
int flag_caller_saves = 1;
#else
int flag_caller_saves = 0;
#endif
int flag_fppc = 0;
#ifndef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
#endif
int flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
int flag_force_mem = 0;
int flag_force_addr = 0;
int flag_defer_pop = 0;
int flag_float_store = 0;
int flag_cse_follow_jumps;
int flag_cse_skip_blocks;
int flag_expensive_optimizations;
int flag_thread_jumps;
int flag_strength_reduce = 0;
int flag_unroll_loops;
int flag_unroll_all_loops;
int flag_prefetch_loop_arrays;
int flag_move_all_movables = 0;
int flag_reduce_all_givs = 0;
int flag_regmove = 0;
int flag_writable_strings = 0;
int flag_no_function_cse = 0;
int flag_omit_frame_pointer = 0;
int flag_function_sections = 0;
int flag_data_sections = 0;
int flag_no_peephole = 0;
int flag_optimize_sibling_calls = 0;
int flag_errno_math = 1;
int flag_unsafe_math_optimizations = 0;
int flag_finite_math_only = 0;
int flag_trapping_math = 1;
int flag_signaling_nans = 0;
int flag_complex_divide_method = 0;
int flag_volatile;
int flag_volatile_global;
int flag_volatile_static;
int flag_syntax_only = 0;
static int flag_gcse;
static int flag_loop_optimize;
static int flag_crossjumping;
static int flag_if_conversion;
static int flag_if_conversion2;
static int flag_delete_null_pointer_checks;
int flag_gcse_lm = 1;
int flag_gcse_sm = 1;
static int flag_rerun_cse_after_loop;
int flag_rerun_loop_opt;
int flag_inline_functions;
int flag_obey_inline;
int flag_keep_inline_functions;
int flag_no_inline = 2;
int flag_really_no_inline = 2;
int flag_preprocessing = 0;
int flag_keep_static_consts = 1;
int flag_gen_aux_info = 0;
static char *aux_info_file_name;
int flag_shared_data;
int flag_delayed_branch;
int flag_pic;
enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
int flag_exceptions;
int flag_unwind_tables = 0;
int flag_asynchronous_unwind_tables = 0;
int flag_no_common;
int flag_pedantic_errors = 0;
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
int flag_schedule_interblock = 1;
int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;
int flag_single_precision_constant;
int flag_branch_on_count_reg = 1;
int flag_inhibit_size_directive = 0;
int flag_verbose_asm = 0;
int flag_debug_asm = 0;
int flag_dump_rtl_in_asm = 0;
#ifdef USE_COLLECT2
int flag_gnu_linker = 0;
#else
int flag_gnu_linker = 1;
#endif
int flag_zero_initialized_in_bss = 1;
int flag_ssa = 0;
int flag_ssa_ccp = 0;
int flag_ssa_dce = 0;
int flag_pack_struct = 0;
int flag_stack_check;
rtx stack_limit_rtx;
int flag_argument_noalias = 0;
int flag_strict_aliasing = 0;
int flag_instrument_function_entry_exit = 0;
int flag_no_ident = 0;
int flag_peephole2 = 0;
int flag_guess_branch_prob = 0;
int flag_bounds_check = 0;
int flag_merge_constants = 1;
int flag_renumber_insns = 1;
int flag_new_regalloc = 0;
int flag_tracer = 0;
int flag_fix_and_continue;
int flag_indirect_data;
int flag_pch_preprocess = 0;
int flag_loop_transpose = 0;
int align_loops;
int align_loops_log;
int align_loops_max_skip;
int align_jumps;
int align_jumps_log;
int align_jumps_max_skip;
int align_labels;
int align_labels_log;
int align_labels_max_skip;
int align_functions;
int align_functions_log;
int force_align_functions_log;
int flag_fast = 0;
static const struct
{
const char *const arg;
const enum debug_info_type debug_type;
const int use_extensions_p;
const char *const description;
} *da,
debug_args[] =
{
{ "", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
N_("Generate debugging info in default format") },
{ "gdb", NO_DEBUG, 1, N_("Generate debugging info in default extended format") },
#ifdef DBX_DEBUGGING_INFO
{ "stabs", DBX_DEBUG, 0, N_("Generate STABS format debug info") },
{ "stabs+", DBX_DEBUG, 1, N_("Generate extended STABS format debug info") },
#endif
#ifdef DWARF_DEBUGGING_INFO
{ "dwarf", DWARF_DEBUG, 0, N_("Generate DWARF-1 format debug info") },
{ "dwarf+", DWARF_DEBUG, 1,
N_("Generate extended DWARF-1 format debug info") },
#endif
#ifdef DWARF2_DEBUGGING_INFO
{ "dwarf-2", DWARF2_DEBUG, 0, N_("Generate DWARF-2 debug info") },
#endif
#ifdef XCOFF_DEBUGGING_INFO
{ "xcoff", XCOFF_DEBUG, 0, N_("Generate XCOFF format debug info") },
{ "xcoff+", XCOFF_DEBUG, 1, N_("Generate extended XCOFF format debug info") },
#endif
#ifdef SDB_DEBUGGING_INFO
{ "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") },
#endif
#ifdef VMS_DEBUGGING_INFO
{ "vms", VMS_DEBUG, 0, N_("Generate VMS format debug info") },
#endif
{ 0, 0, 0, 0 }
};
typedef struct
{
const char *const string;
int *const variable;
const int on_value;
const char *const description;
}
lang_independent_options;
int flag_trapv = 0;
int flag_leading_underscore = -1;
int flag_pascal_strings;
#if defined(APPLE_WEAK_SECTION_ATTRIBUTE) || defined(APPLE_WEAK_ASSEMBLER_DIRECTIVE)
#define COALESCE_BY_DEFAULT 1
#else
#define COALESCE_BY_DEFAULT 0
#endif
int flag_coalescing_enabled = COALESCE_BY_DEFAULT;
int flag_coalesce_templates = COALESCE_BY_DEFAULT;
int flag_weak_coalesced_definitions = COALESCE_BY_DEFAULT;
int flag_export_coalesced = 0;
const char *user_label_prefix;
static const param_info lang_independent_params[] = {
#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT) \
{ OPTION, DEFAULT, HELP },
#include "params.def"
#undef DEFPARAM
{ NULL, 0, NULL }
};
static const lang_independent_options f_options[] =
{
{"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
N_("Perform DWARF2 duplicate elimination") },
{"float-store", &flag_float_store, 1,
N_("Do not store floats in registers") },
{"volatile", &flag_volatile, 1,
N_("Consider all mem refs through pointers as volatile") },
{"volatile-global", &flag_volatile_global, 1,
N_("Consider all mem refs to global data to be volatile") },
{"volatile-static", &flag_volatile_static, 1,
N_("Consider all mem refs to static data to be volatile") },
{"defer-pop", &flag_defer_pop, 1,
N_("Defer popping functions args from stack until later") },
{"omit-frame-pointer", &flag_omit_frame_pointer, 1,
N_("When possible do not generate stack frames") },
{"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
N_("Optimize sibling and tail recursive calls") },
{"tracer", &flag_tracer, 1,
N_("Perform superblock formation via tail duplication") },
{"cse-follow-jumps", &flag_cse_follow_jumps, 1,
N_("When running CSE, follow jumps to their targets") },
{"cse-skip-blocks", &flag_cse_skip_blocks, 1,
N_("When running CSE, follow conditional jumps") },
{"expensive-optimizations", &flag_expensive_optimizations, 1,
N_("Perform a number of minor, expensive optimizations") },
{"thread-jumps", &flag_thread_jumps, 1,
N_("Perform jump threading optimizations") },
{"strength-reduce", &flag_strength_reduce, 1,
N_("Perform strength reduction optimizations") },
{"loop-transpose", &flag_loop_transpose, 1,
N_("Perform loop transposition (currently unsafe)") },
{"unroll-loops", &flag_unroll_loops, 1,
N_("Perform loop unrolling when iteration count is known") },
{"unroll-all-loops", &flag_unroll_all_loops, 1,
N_("Perform loop unrolling for all loops") },
{"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1,
N_("Generate prefetch instructions, if available, for arrays in loops") },
{"move-all-movables", &flag_move_all_movables, 1,
N_("Force all loop invariant computations out of loops") },
{"reduce-all-givs", &flag_reduce_all_givs, 1,
N_("Strength reduce all loop general induction variables") },
{"writable-strings", &flag_writable_strings, 1,
N_("Store strings in writable data section") },
{"peephole", &flag_no_peephole, 0,
N_("Enable machine specific peephole optimizations") },
{"force-mem", &flag_force_mem, 1,
N_("Copy memory operands into registers before using") },
{"force-addr", &flag_force_addr, 1,
N_("Copy memory address constants into regs before using") },
{"function-cse", &flag_no_function_cse, 0,
N_("Allow function addresses to be held in registers") },
{"inline-functions", &flag_inline_functions, 1,
N_("Integrate simple functions into their callers") },
{"keep-inline-functions", &flag_keep_inline_functions, 1,
N_("Generate code for funcs even if they are fully inlined") },
{"inline", &flag_no_inline, 0,
N_("Pay attention to the 'inline' keyword") },
{"obey-inline", &flag_obey_inline, 1,
N_("Obey 'inline' keyword and always inline, regardless of size") },
{"keep-static-consts", &flag_keep_static_consts, 1,
N_("Emit static const variables even if they are not used") },
{"syntax-only", &flag_syntax_only, 1,
N_("Check for syntax errors, then stop") },
{"shared-data", &flag_shared_data, 1,
N_("Mark data as shared rather than private") },
{"caller-saves", &flag_caller_saves, 1,
N_("Enable saving registers around function calls") },
{"pcc-struct-return", &flag_pcc_struct_return, 1,
N_("Return 'short' aggregates in memory, not registers") },
{"reg-struct-return", &flag_pcc_struct_return, 0,
N_("Return 'short' aggregates in registers") },
{"delayed-branch", &flag_delayed_branch, 1,
N_("Attempt to fill delay slots of branch instructions") },
{"gcse", &flag_gcse, 1,
N_("Perform the global common subexpression elimination") },
{"gcse-lm", &flag_gcse_lm, 1,
N_("Perform enhanced load motion during global subexpression elimination") },
{"gcse-sm", &flag_gcse_sm, 1,
N_("Perform store motion after global subexpression elimination") },
{"loop-optimize", &flag_loop_optimize, 1,
N_("Perform the loop optimizations") },
{"crossjumping", &flag_crossjumping, 1,
N_("Perform cross-jumping optimization") },
{"if-conversion", &flag_if_conversion, 1,
N_("Perform conversion of conditional jumps to branchless equivalents") },
{"if-conversion2", &flag_if_conversion2, 1,
N_("Perform conversion of conditional jumps to conditional execution") },
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
N_("Run CSE pass after loop optimizations") },
{"rerun-loop-opt", &flag_rerun_loop_opt, 1,
N_("Run the loop optimizer twice") },
{"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1,
N_("Delete useless null pointer checks") },
{"schedule-insns", &flag_schedule_insns, 1,
N_("Reschedule instructions before register allocation") },
{"schedule-insns2", &flag_schedule_insns_after_reload, 1,
N_("Reschedule instructions after register allocation") },
{"sched-interblock",&flag_schedule_interblock, 1,
N_("Enable scheduling across basic blocks") },
{"sched-spec",&flag_schedule_speculative, 1,
N_("Allow speculative motion of non-loads") },
{"sched-spec-load",&flag_schedule_speculative_load, 1,
N_("Allow speculative motion of some loads") },
{"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
N_("Allow speculative motion of more loads") },
{"branch-count-reg",&flag_branch_on_count_reg, 1,
N_("Replace add,compare,branch with branch on count reg") },
{"pic", &flag_pic, 1,
N_("Generate position independent code, if possible") },
{"PIC", &flag_pic, 2, ""},
{"exceptions", &flag_exceptions, 1,
N_("Enable exception handling") },
{"unwind-tables", &flag_unwind_tables, 1,
N_("Just generate unwind tables for exception handling") },
{"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1,
N_("Generate unwind tables exact at each instruction boundary") },
{"non-call-exceptions", &flag_non_call_exceptions, 1,
N_("Support synchronous non-call exceptions") },
{"profile-arcs", &profile_arc_flag, 1,
N_("Insert arc based program profiling code") },
{"test-coverage", &flag_test_coverage, 1,
N_("Create data files needed by gcov") },
{"branch-probabilities", &flag_branch_probabilities, 1,
N_("Use profiling information for branch probabilities") },
{"create-profile", &flag_create_feedback, 1,
N_("Insert arc counters for profile optimizations") },
{"use-profile", &flag_use_feedback, 1,
N_("Use profile information for various optimizations") },
{"profile", &profile_flag, 1,
N_("Enable basic program profiling code") },
{"reorder-blocks", &flag_reorder_blocks, 1,
N_("Reorder basic blocks to improve code placement") },
{"reorder-functions", &flag_reorder_functions, 1,
N_("Reorder functions to improve code placement") },
{"rename-registers", &flag_rename_registers, 1,
N_("Do the register renaming optimization pass") },
{"cprop-registers", &flag_cprop_registers, 1,
N_("Do the register copy-propagation optimization pass") },
{"common", &flag_no_common, 0,
N_("Do not put uninitialized globals in the common section") },
{"inhibit-size-directive", &flag_inhibit_size_directive, 1,
N_("Do not generate .size directives") },
{"function-sections", &flag_function_sections, 1,
N_("place each function into its own section") },
{"data-sections", &flag_data_sections, 1,
N_("place data items into their own section") },
{"verbose-asm", &flag_verbose_asm, 1,
N_("Add extra commentry to assembler output") },
{"gnu-linker", &flag_gnu_linker, 1,
N_("Output GNU ld formatted global initializers") },
{"regmove", &flag_regmove, 1,
N_("Enables a register move optimization") },
{"optimize-register-move", &flag_regmove, 1,
N_("Do the full regmove optimization pass") },
{"pack-struct", &flag_pack_struct, 1,
N_("Pack structure members together without holes") },
{"stack-check", &flag_stack_check, 1,
N_("Insert stack checking code into the program") },
{"argument-alias", &flag_argument_noalias, 0,
N_("Specify that arguments may alias each other & globals") },
{"argument-noalias", &flag_argument_noalias, 1,
N_("Assume arguments may alias globals but not each other") },
{"argument-noalias-global", &flag_argument_noalias, 2,
N_("Assume arguments do not alias each other or globals") },
{"strict-aliasing", &flag_strict_aliasing, 1,
N_("Assume strict aliasing rules apply") },
{"align-loops", &align_loops, 0,
N_("Align the start of loops") },
{"align-loops-max-skip", &align_loops_max_skip, 0,
N_("Set Maximum skip for loops alignment") },
{"align-jumps", &align_jumps, 0,
N_("Align labels which are only reached by jumping") },
{"align-jumps-max-skip", &align_jumps_max_skip, 0,
N_("Set Maximum skip for align labels which are only reached by jumping") },
{"align-labels", &align_labels, 0,
N_("Align all labels") },
{"align-functions", &align_functions, 0,
N_("Align the start of functions") },
{"merge-constants", &flag_merge_constants, 1,
N_("Attempt to merge identical constants accross compilation units") },
{"merge-all-constants", &flag_merge_constants, 2,
N_("Attempt to merge identical constants and constant variables") },
{"dump-unnumbered", &flag_dump_unnumbered, 1,
N_("Suppress output of instruction numbers and line number notes in debugging dumps") },
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
N_("Instrument function entry/exit with profiling calls") },
{"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1,
N_("Put zero initialized data in the bss section") },
{"ssa", &flag_ssa, 1,
N_("Enable SSA optimizations") },
{"ssa-ccp", &flag_ssa_ccp, 1,
N_("Enable SSA conditional constant propagation") },
{"ssa-dce", &flag_ssa_dce, 1,
N_("Enable aggressive SSA dead code elimination") },
{"leading-underscore", &flag_leading_underscore, 1,
N_("External symbols have a leading underscore") },
{"ident", &flag_no_ident, 0,
N_("Process #ident directives") },
{ "peephole2", &flag_peephole2, 1,
N_("Enables an rtl peephole pass run before sched2") },
{"finite-math-only", &flag_finite_math_only, 1,
N_("Assume no NaNs or +-Infs are generated") },
{ "guess-branch-probability", &flag_guess_branch_prob, 1,
N_("Enables guessing of branch probabilities") },
{"math-errno", &flag_errno_math, 1,
N_("Set errno after built-in math functions") },
{"trapping-math", &flag_trapping_math, 1,
N_("Floating-point operations can trap") },
{"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
N_("Allow math optimizations that may violate IEEE or ANSI standards") },
{"signaling-nans", &flag_signaling_nans, 1,
N_("Disable optimizations observable by IEEE signaling NaNs") },
{"bounds-check", &flag_bounds_check, 1,
N_("Generate code to check bounds before indexing arrays") },
{"single-precision-constant", &flag_single_precision_constant, 1,
N_("Convert floating point constant to single precision constant") },
{"time-report", &time_report, 1,
N_("Report time taken by each compiler pass at end of run") },
{"mem-report", &mem_report, 1,
N_("Report on permanent memory allocation at end of run") },
{ "branch-predictions", &flag_branch_predictions, 1,
N_("Enable generation of branch prediction bits") },
{ "slow-exit", &flag_slow_exit, 1,
N_("Sleep before exiting") },
{ "trapv", &flag_trapv, 1,
N_("Trap for signed overflow in addition / subtraction / multiplication") },
{ "new-ra", &flag_new_regalloc, 1,
N_("Use graph coloring register allocation.") },
{ "fix-and-continue", &flag_fix_and_continue, 1,
N_("Generate code suitable for fast turn around debugging") },
{ "indirect-data", &flag_indirect_data, 1,
N_("Generate code suitable for fast turn around debugging") },
{ "predictive-compilation", &predictive_compilation, 0,
N_("Read from stdin but for predictive compilation") },
{ "fppc", &flag_fppc, 1,
N_("Perform floating-point precision-control pass") },
{ "coalesce", &flag_coalescing_enabled, 1,
N_("Coalesce duplicate C++ functions and data") },
{ "weak-coalesced", &flag_weak_coalesced_definitions, 1,
N_("Use the OS X 10.2 'weak_definitions' attribute when coalescing") },
{ "coalesce-templates", &flag_coalesce_templates, 1,
N_("Coalesce duplicate C++ templates") },
{ "export-coalesced", &flag_export_coalesced, 1,
N_("EXPERIMENTAL: Export coalesced symbols from dylibs") },
{ "ss-const-prop", &flag_ss_const_prop, 1,
N_("Perform simple single-assignment constant propagation") },
{ "reorder-blocks-and-partition", &flag_reorder_blocks_and_partition, 1,
N_("Put hot and cold blocks in separate sections") },
{ "pascal-strings", &flag_pascal_strings, 1,
N_("Allow Pascal-style string literals") }
};
static const struct lang_opt
{
const char *const option;
const char *const description;
}
documented_lang_options[] =
{
{ "-ansi",
N_("Compile just for ISO C90") },
{ "-std= ",
N_("Determine language standard") },
{ "-fsigned-bitfields", "" },
{ "-funsigned-bitfields",
N_("Make bit-fields by unsigned by default") },
{ "-fno-signed-bitfields", "" },
{ "-fno-unsigned-bitfields","" },
{ "-fsigned-char",
N_("Make 'char' be signed by default") },
{ "-funsigned-char",
N_("Make 'char' be unsigned by default") },
{ "-fno-signed-char", "" },
{ "-fno-unsigned-char", "" },
{ "-fasm", "" },
{ "-fno-asm",
N_("Do not recognize the 'asm' keyword") },
{ "-fasm-blocks",
N_("Accept blocks and functions of assembly") },
{ "-fno-asm-blocks", "" },
{ "-fbuiltin", "" },
{ "-fno-builtin",
N_("Do not recognize any built in functions") },
{ "-fhosted",
N_("Assume normal C execution environment") },
{ "-fno-hosted", "" },
{ "-ffreestanding",
N_("Assume that standard libraries & main might not exist") },
{ "-fno-freestanding", "" },
{ "-fcond-mismatch",
N_("Allow different types as args of ? operator") },
{ "-fno-cond-mismatch", "" },
{ "-fdollars-in-identifiers",
N_("Allow the use of $ inside identifiers") },
{ "-fno-dollars-in-identifiers", "" },
{ "-fpreprocessed", "" },
{ "-fno-preprocessed", "" },
{ "-fshort-double",
N_("Use the same size for double as for float") },
{ "-fno-short-double", "" },
{ "-fshort-enums",
N_("Use the smallest fitting integer to hold enums") },
{ "-fno-short-enums", "" },
{ "-fshort-wchar",
N_("Override the underlying type for wchar_t to `unsigned short'") },
{ "-fno-short-wchar", "" },
{ "-faltivec", "Enable the AltiVec Programming Model"},
{ "-fno-altivec", "" },
{ "-Wall",
N_("Enable most warning messages") },
{ "-Wbad-function-cast",
N_("Warn about casting functions to incompatible types") },
{ "-Wno-bad-function-cast", "" },
{ "-Wmissing-format-attribute",
N_("Warn about functions which might be candidates for format attributes") },
{ "-Wno-missing-format-attribute", "" },
{ "-Wcast-qual",
N_("Warn about casts which discard qualifiers") },
{ "-Wno-cast-qual", "" },
{ "-Wchar-subscripts",
N_("Warn about subscripts whose type is 'char'") },
{ "-Wno-char-subscripts", "" },
{ "-Wcomment",
N_("Warn if nested comments are detected") },
{ "-Wno-comment", "" },
{ "-Wcomments",
N_("Warn if nested comments are detected") },
{ "-Wno-comments", "" },
{ "-Wconversion",
N_("Warn about possibly confusing type conversions") },
{ "-Wno-conversion", "" },
{ "-Wdiv-by-zero", "" },
{ "-Wno-div-by-zero",
N_("Do not warn about compile-time integer division by zero") },
{ "-Wfloat-equal",
N_("Warn about testing equality of floating point numbers") },
{ "-Wno-float-equal", "" },
{ "-Wformat",
N_("Warn about printf/scanf/strftime/strfmon format anomalies") },
{ "-Wno-format", "" },
{ "-Wformat-extra-args", "" },
{ "-Wno-format-extra-args",
N_("Don't warn about too many arguments to format functions") },
{ "-Wformat-nonliteral",
N_("Warn about non-string-literal format strings") },
{ "-Wno-format-nonliteral", "" },
{ "-Wformat-security",
N_("Warn about possible security problems with format functions") },
{ "-Wno-format-security", "" },
{ "-Wformat-y2k", "" },
{ "-Wno-format-y2k",
N_("Don't warn about strftime formats yielding 2 digit years") },
{ "-Wimplicit-function-declaration",
N_("Warn about implicit function declarations") },
{ "-Wno-implicit-function-declaration", "" },
{ "-Werror-implicit-function-declaration", "" },
{ "-Wimplicit-int",
N_("Warn when a declaration does not specify a type") },
{ "-Wno-implicit-int", "" },
{ "-Wimplicit", "" },
{ "-Wno-implicit", "" },
{ "-Wimport",
N_("Warn about the use of the #import directive") },
{ "-Wno-import", "" },
{ "-Winvalid-pch",
N_("Warn about PCH files that are found but not used") },
{ "-Winvalid-sr",
N_("Warn about Symbol Repositories that are found but not used") },
{ "-Wlong-long","" },
{ "-Wno-long-long",
N_("Do not warn about using 'long long' when -pedantic") },
{ "-Wmain",
N_("Warn about suspicious declarations of main") },
{ "-Wno-main", "" },
{ "-Wmissing-braces",
N_("Warn about possibly missing braces around initializers") },
{ "-Wno-missing-braces", "" },
{ "-Wmissing-declarations",
N_("Warn about global funcs without previous declarations") },
{ "-Wno-missing-declarations", "" },
{ "-Wmissing-prototypes",
N_("Warn about global funcs without prototypes") },
{ "-Wno-missing-prototypes", "" },
{ "-Wmultichar",
N_("Warn about use of multicharacter literals") },
{ "-Wno-multichar", "" },
{ "-Wfour-char-constants",
N_("Warn about use of 'abcd' four char literals") },
{ "-Wno-four-char-constants", "" },
{ "-Wnonportable-cfstrings",
N_("Warn about use of non-ASCII chars in CFStrings") },
{ "-Wno-nonportable-cfstrings", "" },
{ "-Wnested-externs",
N_("Warn about externs not at file scope level") },
{ "-Wno-nested-externs", "" },
{ "-Wparentheses",
N_("Warn about possible missing parentheses") },
{ "-Wno-parentheses", "" },
{ "-Wpointer-arith",
N_("Warn about function pointer arithmetic") },
{ "-Wno-pointer-arith", "" },
{ "-Wredundant-decls",
N_("Warn about multiple declarations of the same object") },
{ "-Wno-redundant-decls", "" },
{ "-Wreturn-type",
N_("Warn whenever a function's return-type defaults to int") },
{ "-Wno-return-type", "" },
{ "-Wsequence-point",
N_("Warn about possible violations of sequence point rules") },
{ "-Wno-sequence-point", "" },
{ "-Wsign-compare",
N_("Warn about signed/unsigned comparisons") },
{ "-Wno-sign-compare", "" },
{ "-Wstrict-prototypes",
N_("Warn about non-prototyped function decls") },
{ "-Wno-strict-prototypes", "" },
{ "-Wtraditional",
N_("Warn about constructs whose meanings change in ISO C") },
{ "-Wno-traditional", "" },
{ "-Wtrigraphs",
N_("Warn when trigraphs are encountered") },
{ "-Wno-trigraphs", "" },
{ "-Wundef", "" },
{ "-Wno-undef", "" },
{ "-Wunknown-pragmas",
N_("Warn about unrecognized pragmas") },
{ "-Wno-unknown-pragmas", "" },
{ "-Wwrite-strings",
N_("Mark strings as 'const char *'") },
{ "-Wno-write-strings", "" },
{ "-Wno-altivec-long-deprecated",
N_("Do not warn about using deprecated 'long' AltiVec types") },
#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
#include "options.h"
};
static const struct
{
const char *const name;
const int value;
const char *const description;
}
target_switches[] = TARGET_SWITCHES;
#ifdef TARGET_OPTIONS
static const struct
{
const char *const prefix;
const char **const variable;
const char *const description;
}
target_options[] = TARGET_OPTIONS;
#endif
int inhibit_warnings = 0;
int warn_system_headers = 0;
int extra_warnings = 0;
int warnings_are_errors = 0;
int warn_unused_function;
int warn_unused_label;
int warn_unused_parameter;
int warn_unused_variable;
int warn_unused_value;
int warn_notreached;
int warn_uninitialized;
int warn_shadow;
int warn_switch;
int warn_switch_default;
int warn_switch_enum;
int warn_return_type;
int warn_cast_align;
int warn_larger_than;
HOST_WIDE_INT larger_than_size;
int warn_inline;
int warn_aggregate_return;
int warn_packed;
int warn_padded;
int warn_disabled_optimization;
int warn_missing_noreturn;
int warn_deprecated_decl = 1;
int warn_strict_aliasing;
static const lang_independent_options W_options[] =
{
{"unused-function", &warn_unused_function, 1,
N_("Warn when a function is unused") },
{"unused-label", &warn_unused_label, 1,
N_("Warn when a label is unused") },
{"unused-parameter", &warn_unused_parameter, 1,
N_("Warn when a function parameter is unused") },
{"unused-variable", &warn_unused_variable, 1,
N_("Warn when a variable is unused") },
{"unused-value", &warn_unused_value, 1,
N_("Warn when an expression value is unused") },
{"system-headers", &warn_system_headers, 1,
N_("Do not suppress warnings from system headers") },
{"error", &warnings_are_errors, 1,
N_("Treat all warnings as errors") },
{"shadow", &warn_shadow, 1,
N_("Warn when one local variable shadows another") },
{"switch", &warn_switch, 1,
N_("Warn about enumerated switches, with no default, missing a case") },
{"switch-default", &warn_switch_default, 1,
N_("Warn about enumerated switches missing a default case") },
{"switch-enum", &warn_switch_enum, 1,
N_("Warn about all enumerated switches missing a specific case") },
{"aggregate-return", &warn_aggregate_return, 1,
N_("Warn about returning structures, unions or arrays") },
{"cast-align", &warn_cast_align, 1,
N_("Warn about pointer casts which increase alignment") },
{"unreachable-code", &warn_notreached, 1,
N_("Warn about code that will never be executed") },
{"uninitialized", &warn_uninitialized, 1,
N_("Warn about uninitialized automatic variables") },
{"inline", &warn_inline, 1,
N_("Warn when an inlined function cannot be inlined") },
{"packed", &warn_packed, 1,
N_("Warn when the packed attribute has no effect on struct layout") },
{"padded", &warn_padded, 1,
N_("Warn when padding is required to align struct members") },
{"disabled-optimization", &warn_disabled_optimization, 1,
N_("Warn when an optimization pass is disabled") },
{"deprecated-declarations", &warn_deprecated_decl, 1,
N_("Warn about uses of __attribute__((deprecated)) declarations") },
{"missing-noreturn", &warn_missing_noreturn, 1,
N_("Warn about functions which might be candidates for attribute noreturn") },
{"strict-aliasing", &warn_strict_aliasing, 1,
N_ ("Warn about code which might break the strict aliasing rules") }
};
void
set_Wunused (setting)
int setting;
{
warn_unused_function = setting;
warn_unused_label = setting;
if (!setting)
warn_unused_parameter = 0;
else if (!warn_unused_parameter)
warn_unused_parameter = -1;
warn_unused_variable = setting;
warn_unused_value = setting;
}
void
set_fast_math_flags (set)
int set;
{
flag_trapping_math = !set;
flag_unsafe_math_optimizations = set;
flag_finite_math_only = set;
flag_errno_math = !set;
if (set)
flag_signaling_nans = 0;
}
bool
fast_math_flags_set_p ()
{
return (!flag_trapping_math
&& flag_unsafe_math_optimizations
&& flag_finite_math_only
&& !flag_errno_math);
}
FILE *asm_out_file;
FILE *aux_info_file;
FILE *rtl_dump_file = NULL;
struct env_overrides {
char *option;
unsigned short flags;
};
#define env_ovr_used 1
#define env_ovr_has_arg 2
#define env_ovr_add_arg 4
#define env_over_no_msg 8
static struct env_overrides *env_override_options;
static int n_overrides = 0;
static int env_override_options_max = 0;
static int have_added_opts = 0;
static int add_env_opts = 0;
static int env_ovr_confirm = 1;
static char *extract_override_options PARAMS ((void));
static void override_O_option PARAMS ((void));
static int override_option PARAMS ((int, int, char **));
static int add_env_options PARAMS ((int *, char ***));
int
read_integral_parameter (p, pname, defval)
const char *p;
const char *pname;
const int defval;
{
const char *endp = p;
while (*endp)
{
if (ISDIGIT (*endp))
endp++;
else
break;
}
if (*endp != 0)
{
if (pname != 0)
error ("invalid option `%s'", pname);
return defval;
}
return atoi (p);
}
void
do_abort ()
{
abort ();
}
void
botch (s)
const char *s ATTRIBUTE_UNUSED;
{
abort ();
}
int
exact_log2_wide (x)
unsigned HOST_WIDE_INT x;
{
int log = 0;
if (x == 0 || x != (x & -x))
return -1;
while ((x >>= 1) != 0)
log++;
return log;
}
int
floor_log2_wide (x)
unsigned HOST_WIDE_INT x;
{
int log = -1;
while (x != 0)
log++,
x >>= 1;
return log;
}
static void
crash_signal (signo)
int signo;
{
internal_error ("%s", strsignal (signo));
}
static void
interrupt_signal (signo)
int signo ATTRIBUTE_UNUSED;
{
if (flag_gen_aux_info)
{
fclose (aux_info_file);
unlink (aux_info_file_name);
}
if (asm_out_file)
{
fclose (asm_out_file);
if (asm_file_name && *asm_file_name)
unlink (asm_file_name);
}
exit (FATAL_EXIT_CODE);
}
static void
setup_core_dumping ()
{
#ifdef SIGABRT
signal (SIGABRT, SIG_DFL);
#endif
#if defined(HAVE_SETRLIMIT)
{
struct rlimit rlim;
if (getrlimit (RLIMIT_CORE, &rlim) != 0)
fatal_io_error ("getting core file size maximum limit");
rlim.rlim_cur = rlim.rlim_max;
if (setrlimit (RLIMIT_CORE, &rlim) != 0)
fatal_io_error ("setting core file size limit to maximum");
}
#endif
diagnostic_abort_on_error (global_dc);
}
void
strip_off_ending (name, len)
char *name;
int len;
{
int i;
for (i = 2; i < 6 && len > i; i++)
{
if (name[len - i] == '.')
{
name[len - i] = '\0';
break;
}
}
}
void
output_quoted_string (asm_file, string)
FILE *asm_file;
const char *string;
{
#ifdef OUTPUT_QUOTED_STRING
OUTPUT_QUOTED_STRING (asm_file, string);
#else
char c;
putc ('\"', asm_file);
while ((c = *string++) != 0)
{
if (ISPRINT (c))
{
if (c == '\"' || c == '\\')
putc ('\\', asm_file);
putc (c, asm_file);
}
else
fprintf (asm_file, "\\%03o", (unsigned char) c);
}
putc ('\"', asm_file);
#endif
}
void
output_clean_symbol_name (file, name)
FILE *file;
const char *name;
{
char *id = xstrdup (name);
clean_symbol_name (id);
fputs (id, file);
free (id);
}
void
output_file_directive (asm_file, input_name)
FILE *asm_file;
const char *input_name;
{
int len = strlen (input_name);
const char *na = input_name + len;
while (na > input_name)
{
if (IS_DIR_SEPARATOR (na[-1]))
break;
na--;
}
#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
#else
#ifdef ASM_OUTPUT_SOURCE_FILENAME
ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
#else
fprintf (asm_file, "\t.file\t");
output_quoted_string (asm_file, na);
fputc ('\n', asm_file);
#endif
#endif
}
static int
open_dump_file (index, decl)
enum dump_file_index index;
tree decl;
{
char *dump_name;
const char *open_arg;
char seq[16];
if (! dump_file[index].enabled)
return 0;
timevar_push (TV_DUMP);
if (rtl_dump_file != NULL)
fclose (rtl_dump_file);
sprintf (seq, DUMPFILE_FORMAT, index);
if (! dump_file[index].initialized)
{
if (graph_dump_format != no_graph
&& dump_file[index].graph_dump_p)
{
dump_name = concat (seq, dump_file[index].extension, NULL);
clean_graph_dump_file (dump_base_name, dump_name);
free (dump_name);
}
dump_file[index].initialized = 1;
open_arg = "w";
}
else
open_arg = "a";
dump_name = concat (dump_base_name, seq,
dump_file[index].extension, NULL);
rtl_dump_file = fopen (dump_name, open_arg);
if (rtl_dump_file == NULL)
fatal_io_error ("can't open %s", dump_name);
free (dump_name);
if (decl)
fprintf (rtl_dump_file, "\n;; Function %s%s\n\n",
(*lang_hooks.decl_printable_name) (decl, 2),
cfun->function_frequency == FUNCTION_FREQUENCY_HOT
? " (hot)"
: cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
? " (unlikely executed)"
: "");
timevar_pop (TV_DUMP);
return 1;
}
static void
close_dump_file (index, func, insns)
enum dump_file_index index;
void (*func) PARAMS ((FILE *, rtx));
rtx insns;
{
if (! rtl_dump_file)
return;
timevar_push (TV_DUMP);
if (insns
&& graph_dump_format != no_graph
&& dump_file[index].graph_dump_p)
{
char seq[16];
char *suffix;
sprintf (seq, DUMPFILE_FORMAT, index);
suffix = concat (seq, dump_file[index].extension, NULL);
print_rtl_graph_with_bb (dump_base_name, suffix, insns);
free (suffix);
}
if (func && insns)
func (rtl_dump_file, insns);
fflush (rtl_dump_file);
fclose (rtl_dump_file);
rtl_dump_file = NULL;
timevar_pop (TV_DUMP);
}
int
wrapup_global_declarations (vec, len)
tree *vec;
int len;
{
tree decl;
int i;
int reconsider;
int output_something = 0;
for (i = 0; i < len; i++)
{
decl = vec[i];
if (DECL_DEFER_OUTPUT (decl) != 0)
DECL_DEFER_OUTPUT (decl) = 0;
if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0)
(*lang_hooks.finish_incomplete_decl) (decl);
}
do
{
reconsider = 0;
for (i = 0; i < len; i++)
{
decl = vec[i];
if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
continue;
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
{
bool needed = 1;
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
;
else if (DECL_COMDAT (decl))
needed = 0;
else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl)
&& (optimize || !flag_keep_static_consts
|| DECL_ARTIFICIAL (decl)))
needed = 0;
if (needed)
{
reconsider = 1;
rest_of_decl_compilation (decl, NULL, 1, 1);
}
}
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl) != 0
&& DECL_SAVED_INSNS (decl) != 0
&& (flag_keep_inline_functions
|| (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
reconsider = 1;
output_inline_function (decl);
}
}
if (reconsider)
output_something = 1;
}
while (reconsider);
return output_something;
}
void
check_global_declarations (vec, len)
tree *vec;
int len;
{
tree decl;
int i;
for (i = 0; i < len; i++)
{
decl = vec[i];
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& ! TREE_ASM_WRITTEN (decl))
SET_DECL_RTL (decl, NULL_RTX);
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl) == 0
&& DECL_EXTERNAL (decl)
&& ! DECL_ARTIFICIAL (decl)
&& ! TREE_PUBLIC (decl)
&& (warn_unused_function
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
pedwarn_with_decl (decl,
"`%s' used but never defined");
else
warning_with_decl (decl,
"`%s' declared `static' but never defined");
TREE_PUBLIC (decl) = 1;
assemble_external (decl);
}
if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL)
|| (warn_unused_variable && TREE_CODE (decl) == VAR_DECL))
&& ! TREE_USED (decl)
&& ! TREE_USED (DECL_NAME (decl))
&& ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl)
&& ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
&& (*lang_hooks.decls.warn_unused_global) (decl))
warning_with_decl (decl, "`%s' defined but not used");
if (errorcount == 0 && sorrycount == 0)
{
timevar_push (TV_SYMOUT);
(*debug_hooks->global_decl) (decl);
timevar_pop (TV_SYMOUT);
}
}
}
void
push_srcloc (file, line)
const char *file;
int line;
{
struct file_stack *fs;
if (input_file_stack)
{
input_file_stack->name = input_filename;
input_file_stack->line = lineno;
}
fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
fs->name = input_filename = file;
fs->line = lineno = line;
fs->next = input_file_stack;
input_file_stack = fs;
input_file_stack_tick++;
if (flag_gen_index_original)
push_cur_index_filename (input_filename);
}
void
pop_srcloc ()
{
struct file_stack *fs;
fs = input_file_stack;
input_file_stack = fs->next;
free (fs);
input_file_stack_tick++;
if (!input_file_stack)
abort ();
input_filename = input_file_stack->name;
lineno = input_file_stack->line;
if (flag_gen_index_original)
pop_cur_index_filename ();
}
static void
compile_file ()
{
init_final (main_input_filename);
init_branch_prob (aux_base_name);
timevar_push (TV_PARSE);
(*lang_hooks.parse_file) (set_yydebug);
(*lang_hooks.clear_binding_stack) ();
timevar_pop (TV_PARSE);
if (flag_syntax_only)
return;
(*lang_hooks.decls.final_write_globals)();
output_func_start_profiler ();
weak_finish ();
timevar_push (TV_SYMOUT);
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_frame ())
dwarf2out_frame_finish ();
#endif
(*debug_hooks->finish) (main_input_filename);
timevar_pop (TV_SYMOUT);
dw2_output_indirect_constants ();
end_final (aux_base_name);
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
timevar_push (TV_DUMP);
open_dump_file (DFI_bp, NULL);
end_branch_prob ();
close_dump_file (DFI_bp, NULL, NULL_RTX);
timevar_pop (TV_DUMP);
}
targetm.asm_out.file_end ();
#ifdef IDENT_ASM_OP
if (!flag_no_ident)
fprintf (asm_out_file, "%s\"GCC: (GNU) %s\"\n",
IDENT_ASM_OP, version_string);
#endif
if (optimize > 0 && open_dump_file (DFI_combine, NULL))
{
timevar_push (TV_DUMP);
dump_combine_total_stats (rtl_dump_file);
close_dump_file (DFI_combine, NULL, NULL_RTX);
timevar_pop (TV_DUMP);
}
}
void
rest_of_decl_compilation (decl, asmspec, top_level, at_end)
tree decl;
const char *asmspec;
int top_level;
int at_end;
{
#ifndef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
#endif
{
tree alias;
alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
if (alias)
{
alias = TREE_VALUE (TREE_VALUE (alias));
alias = get_identifier (TREE_STRING_POINTER (alias));
assemble_alias (decl, alias);
}
}
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|| TREE_CODE (decl) == FUNCTION_DECL)
{
timevar_push (TV_VARCONST);
if (asmspec)
make_decl_rtl (decl, asmspec);
if (at_end || !DECL_DEFER_OUTPUT (decl))
assemble_variable (decl, top_level, at_end, 0);
if (decl == last_assemble_variable_decl)
{
ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
top_level, at_end);
}
timevar_pop (TV_VARCONST);
}
else if (DECL_REGISTER (decl) && asmspec != 0)
{
if (decode_reg_name (asmspec) >= 0)
{
SET_DECL_RTL (decl, NULL_RTX);
make_decl_rtl (decl, asmspec);
}
else
{
error ("invalid register name `%s' for register variable", asmspec);
DECL_REGISTER (decl) = 0;
if (!top_level)
expand_decl (decl);
}
}
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
&& TREE_CODE (decl) == TYPE_DECL)
{
timevar_push (TV_SYMOUT);
dbxout_symbol (decl, 0);
timevar_pop (TV_SYMOUT);
}
#endif
#ifdef SDB_DEBUGGING_INFO
else if (write_symbols == SDB_DEBUG && top_level
&& TREE_CODE (decl) == TYPE_DECL)
{
timevar_push (TV_SYMOUT);
sdbout_symbol (decl, 0);
timevar_pop (TV_SYMOUT);
}
#endif
#ifdef DWARF2_DEBUGGING_INFO
else if ((write_symbols == DWARF2_DEBUG
|| write_symbols == VMS_AND_DWARF2_DEBUG)
&& top_level
&& TREE_CODE (decl) == TYPE_DECL)
{
timevar_push (TV_SYMOUT);
dwarf2out_decl (decl);
timevar_pop (TV_SYMOUT);
}
#endif
}
void
rest_of_type_compilation (type, toplev)
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
tree type;
int toplev;
#else
tree type ATTRIBUTE_UNUSED;
int toplev ATTRIBUTE_UNUSED;
#endif
{
if (errorcount != 0 || sorrycount != 0)
return;
timevar_push (TV_SYMOUT);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
dbxout_symbol (TYPE_STUB_DECL (type), !toplev);
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
#endif
#ifdef DWARF2_DEBUGGING_INFO
if ((write_symbols == DWARF2_DEBUG
|| write_symbols == VMS_AND_DWARF2_DEBUG)
&& toplev)
dwarf2out_decl (TYPE_STUB_DECL (type));
#endif
timevar_pop (TV_SYMOUT);
}
void
rest_of_compilation (decl)
tree decl;
{
rtx insns;
int tem;
int failure = 0;
int rebuild_label_notes_after_reload;
int register_life_up_to_date;
timevar_push (TV_REST_OF_COMPILATION);
generating_concat_p = 0;
cse_not_expected = ! optimize;
if (!cfun->x_whole_function_mode_p)
identify_blocks ();
if (cfun->x_whole_function_mode_p)
reorder_blocks ();
init_flow ();
if (DECL_SAVED_INSNS (decl) == 0)
{
int inlinable = 0;
tree parent;
const char *lose;
for (parent = DECL_CONTEXT (current_function_decl);
parent != NULL_TREE;
parent = get_containing_scope (parent))
if (TREE_CODE (parent) == FUNCTION_DECL
&& DECL_INLINE (parent) && DECL_EXTERNAL (parent))
{
DECL_INITIAL (decl) = 0;
goto exit_rest_of_compilation;
}
else if (TYPE_P (parent))
break;
if ((DECL_INLINE (decl) && !flag_no_inline)
|| flag_inline_functions)
{
timevar_push (TV_INTEGRATION);
lose = function_cannot_inline_p (decl);
timevar_pop (TV_INTEGRATION);
if (lose || ! optimize)
{
if (warn_inline && DECL_INLINE (decl))
warning_with_decl (decl, lose);
DECL_ABSTRACT_ORIGIN (decl) = 0;
if (DECL_EXTERNAL (decl))
{
DECL_INITIAL (decl) = 0;
goto exit_rest_of_compilation;
}
}
else {
if (!DECL_INLINE (decl))
DID_INLINE_FUNC (decl) = 1;
inlinable = DECL_INLINE (decl) = 1;
}
}
insns = get_insns ();
if (open_dump_file (DFI_rtl, decl))
{
if (DECL_SAVED_INSNS (decl))
fprintf (rtl_dump_file, ";; (integrable)\n\n");
close_dump_file (DFI_rtl, print_rtl, insns);
}
convert_from_eh_region_ranges ();
if (inlinable
|| (DECL_INLINE (decl)
&& ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
&& ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
&& ! flag_keep_inline_functions)
|| DECL_EXTERNAL (decl))))
DECL_DEFER_OUTPUT (decl) = 1;
if (DECL_INLINE (decl))
(*debug_hooks->deferred_inline_function) (decl);
if (DECL_DEFER_OUTPUT (decl))
{
if (warn_return_type)
{
int saved_optimize = optimize;
optimize = 0;
rebuild_jump_labels (insns);
find_exception_handler_labels ();
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
optimize = saved_optimize;
free_bb_for_insn ();
}
set_nothrow_function_flags ();
if (current_function_nothrow)
TREE_NOTHROW (current_function_decl) = 1;
timevar_push (TV_INTEGRATION);
save_for_inline (decl);
timevar_pop (TV_INTEGRATION);
DECL_SAVED_INSNS (decl)->inlinable = inlinable;
goto exit_rest_of_compilation;
}
if (DECL_EXTERNAL (decl))
goto exit_rest_of_compilation;
}
{
tree parent;
for (parent = DECL_CONTEXT (current_function_decl);
parent != NULL_TREE;
parent = get_containing_scope (parent))
if (TREE_CODE (parent) == FUNCTION_DECL)
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1;
}
if (DECL_INLINE (decl))
(*debug_hooks->outlining_inline_function) (decl);
remove_unnecessary_notes ();
reorder_blocks ();
ggc_collect ();
init_function_for_compilation ();
if (! DECL_DEFER_OUTPUT (decl))
TREE_ASM_WRITTEN (decl) = 1;
rtx_equal_function_value_matters = 0;
purge_hard_subreg_sets (get_insns ());
if (((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
|| errorcount || sorrycount)
goto exit_rest_of_compilation;
timevar_push (TV_JUMP);
open_dump_file (DFI_sibling, decl);
insns = get_insns ();
rebuild_jump_labels (insns);
find_exception_handler_labels ();
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
delete_unreachable_blocks ();
if (flag_guess_branch_prob)
{
timevar_push (TV_BRANCH_PROB);
note_prediction_to_br_prob ();
timevar_pop (TV_BRANCH_PROB);
}
if (flag_optimize_sibling_calls)
{
rtx insn;
optimize_sibling_and_tail_recursive_calls ();
free_bb_for_insn ();
find_exception_handler_labels ();
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
delete_insn (insn);
}
close_dump_file (DFI_sibling, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
scope_to_insns_initialize ();
if (doing_eh (0))
{
timevar_push (TV_JUMP);
open_dump_file (DFI_eh, decl);
finish_eh_generation ();
close_dump_file (DFI_eh, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
}
emit_initial_value_sets ();
#ifdef FINALIZE_PIC
if (flag_pic)
FINALIZE_PIC;
#endif
insns = get_insns ();
unshare_all_rtl (current_function_decl, insns);
#ifdef SETJMP_VIA_SAVE_AREA
if (current_function_calls_alloca)
optimize_save_area_alloca (insns);
#endif
instantiate_virtual_regs (current_function_decl, insns);
open_dump_file (DFI_jump, decl);
timevar_push (TV_JUMP);
if (flag_guess_branch_prob)
expected_value_to_br_prob ();
reg_scan (insns, max_reg_num (), 0);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
delete_trivially_dead_insns (insns, max_reg_num ());
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
if (optimize)
{
free_bb_for_insn ();
copy_loop_headers (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
}
purge_line_number_notes (insns);
timevar_pop (TV_JUMP);
close_dump_file (DFI_jump, print_rtl, insns);
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
{
goto exit_rest_of_compilation;
}
if (optimize > 0 && flag_ssa)
{
timevar_push (TV_TO_SSA);
open_dump_file (DFI_ssa, decl);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
convert_to_ssa ();
close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
timevar_pop (TV_TO_SSA);
if (flag_ssa_ccp)
{
timevar_push (TV_SSA_CCP);
open_dump_file (DFI_ssa_ccp, decl);
ssa_const_prop ();
close_dump_file (DFI_ssa_ccp, print_rtl_with_bb, get_insns ());
timevar_pop (TV_SSA_CCP);
}
if (flag_ssa_dce)
{
timevar_push (TV_SSA_DCE);
open_dump_file (DFI_ssa_dce, decl);
insns = get_insns ();
ssa_eliminate_dead_code ();
close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns);
timevar_pop (TV_SSA_DCE);
}
timevar_push (TV_FROM_SSA);
open_dump_file (DFI_ussa, decl);
convert_from_ssa ();
reg_scan (insns, max_reg_num (), 1);
close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
timevar_pop (TV_FROM_SSA);
ggc_collect ();
}
timevar_push (TV_JUMP);
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
if (flag_delete_null_pointer_checks)
{
open_dump_file (DFI_null, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
if (delete_null_pointer_checks (insns))
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
close_dump_file (DFI_null, print_rtl_with_bb, insns);
}
renumber_insns (rtl_dump_file);
timevar_pop (TV_JUMP);
close_dump_file (DFI_jump, print_rtl_with_bb, insns);
ggc_collect ();
if (optimize > 0)
{
open_dump_file (DFI_cse, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
timevar_push (TV_CSE);
reg_scan (insns, max_reg_num (), 1);
tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
if (tem)
rebuild_jump_labels (insns);
purge_all_dead_edges (0);
delete_trivially_dead_insns (insns, max_reg_num ());
cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
if (tem || optimize > 1)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
if (flag_delete_null_pointer_checks)
{
timevar_push (TV_JUMP);
if (delete_null_pointer_checks (insns))
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
}
renumber_insns (rtl_dump_file);
timevar_pop (TV_CSE);
close_dump_file (DFI_cse, print_rtl_with_bb, insns);
}
open_dump_file (DFI_addressof, decl);
purge_addressof (insns);
if (optimize)
purge_all_dead_edges (0);
reg_scan (insns, max_reg_num (), 1);
close_dump_file (DFI_addressof, print_rtl, insns);
ggc_collect ();
if (optimize > 0 && flag_gcse)
{
int save_csb, save_cfj;
int tem2 = 0;
timevar_push (TV_GCSE);
open_dump_file (DFI_gcse, decl);
tem = gcse_main (insns, rtl_dump_file);
rebuild_jump_labels (insns);
delete_trivially_dead_insns (insns, max_reg_num ());
save_csb = flag_cse_skip_blocks;
save_cfj = flag_cse_follow_jumps;
flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
if (flag_expensive_optimizations)
{
timevar_push (TV_CSE);
reg_scan (insns, max_reg_num (), 1);
tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
purge_all_dead_edges (0);
delete_trivially_dead_insns (insns, max_reg_num ());
timevar_pop (TV_CSE);
cse_not_expected = !flag_rerun_cse_after_loop;
}
while (tem || tem2)
{
tem = tem2 = 0;
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
if (flag_expensive_optimizations)
{
timevar_push (TV_CSE);
reg_scan (insns, max_reg_num (), 1);
tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
purge_all_dead_edges (0);
delete_trivially_dead_insns (insns, max_reg_num ());
timevar_pop (TV_CSE);
}
}
close_dump_file (DFI_gcse, print_rtl_with_bb, insns);
timevar_pop (TV_GCSE);
ggc_collect ();
flag_cse_skip_blocks = save_csb;
flag_cse_follow_jumps = save_cfj;
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
}
if (optimize > 0 && flag_loop_optimize)
{
int do_unroll, do_prefetch;
timevar_push (TV_LOOP);
delete_dead_jumptables ();
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
open_dump_file (DFI_loop, decl);
free_bb_for_insn ();
do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
if (flag_rerun_loop_opt)
{
cleanup_barriers ();
loop_optimize (insns, rtl_dump_file, do_unroll);
do_unroll = 0;
delete_trivially_dead_insns (insns, max_reg_num ());
reg_scan (insns, max_reg_num (), 1);
}
cleanup_barriers ();
loop_optimize (insns, rtl_dump_file, do_unroll | LOOP_BCT | do_prefetch);
delete_trivially_dead_insns (insns, max_reg_num ());
close_dump_file (DFI_loop, print_rtl, insns);
timevar_pop (TV_LOOP);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
ggc_collect ();
}
timevar_push (TV_FLOW);
open_dump_file (DFI_cfg, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
if (optimize)
mark_constant_function ();
close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
if (optimize > 0 || cfun->arc_profile || flag_branch_probabilities)
{
struct loops loops;
timevar_push (TV_BRANCH_PROB);
open_dump_file (DFI_bp, decl);
if (cfun->arc_profile || flag_branch_probabilities)
branch_prob ();
flow_loops_find (&loops, LOOP_TREE);
if (rtl_dump_file)
flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
if (flag_guess_branch_prob)
estimate_probability (&loops);
flow_loops_free (&loops);
close_dump_file (DFI_bp, print_rtl_with_bb, insns);
timevar_pop (TV_BRANCH_PROB);
}
if (optimize > 0)
{
open_dump_file (DFI_ce1, decl);
if (flag_if_conversion)
{
timevar_push (TV_IFCVT);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE);
reg_scan (insns, max_reg_num (), 0);
if_convert (0);
timevar_pop (TV_IFCVT);
}
timevar_push (TV_JUMP);
cleanup_cfg (CLEANUP_EXPENSIVE);
reg_scan (insns, max_reg_num (), 0);
timevar_pop (TV_JUMP);
close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
}
if (flag_tracer)
{
timevar_push (TV_TRACER);
open_dump_file (DFI_tracer, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
tracer ();
cleanup_cfg (CLEANUP_EXPENSIVE);
reg_scan (insns, max_reg_num (), 0);
close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
timevar_pop (TV_TRACER);
}
if (flag_rerun_cse_after_loop)
{
timevar_push (TV_CSE2);
open_dump_file (DFI_cse2, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
purge_all_dead_edges (0);
delete_trivially_dead_insns (insns, max_reg_num ());
if (tem)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
cleanup_cfg (CLEANUP_EXPENSIVE);
timevar_pop (TV_JUMP);
}
reg_scan (insns, max_reg_num (), 0);
close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
ggc_collect ();
timevar_pop (TV_CSE2);
}
cse_not_expected = 1;
open_dump_file (DFI_life, decl);
regclass_init ();
check_function_return_warnings ();
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
life_analysis (insns, rtl_dump_file, PROP_FINAL);
if (optimize)
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
timevar_pop (TV_FLOW);
no_new_pseudos = 1;
if (warn_uninitialized || extra_warnings)
{
uninitialized_vars_warning (DECL_INITIAL (decl));
if (extra_warnings)
setjmp_args_warning ();
}
if (optimize)
{
clear_bb_flags ();
if (!flag_new_regalloc && initialize_uninitialized_subregs ())
{
insns = get_insns ();
update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_LOG_LINKS | PROP_REG_INFO
| PROP_DEATH_NOTES);
}
}
close_dump_file (DFI_life, print_rtl_with_bb, insns);
ggc_collect ();
if (optimize > 0)
{
int rebuild_jump_labels_after_combine = 0;
timevar_push (TV_COMBINE);
open_dump_file (DFI_combine, decl);
if (flag_ss_const_prop)
find_all_single_set_constants ();
rebuild_jump_labels_after_combine
= combine_instructions (insns, max_reg_num ());
if (rebuild_jump_labels_after_combine)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
timevar_pop (TV_JUMP);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
}
close_dump_file (DFI_combine, print_rtl_with_bb, insns);
timevar_pop (TV_COMBINE);
ggc_collect ();
}
if (flag_ss_const_prop)
cleanup_ss_constant_propagation ();
if (flag_if_conversion)
{
timevar_push (TV_IFCVT);
open_dump_file (DFI_ce2, decl);
no_new_pseudos = 0;
if_convert (1);
no_new_pseudos = 1;
close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
timevar_pop (TV_IFCVT);
}
if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
{
timevar_push (TV_REGMOVE);
open_dump_file (DFI_regmove, decl);
regmove_optimize (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
timevar_pop (TV_REGMOVE);
ggc_collect ();
}
split_all_insns (1);
register_life_up_to_date = 0;
#ifdef OPTIMIZE_MODE_SWITCHING
timevar_push (TV_MODE_SWITCH);
no_new_pseudos = 0;
optimize_mode_switching (NULL);
no_new_pseudos = 1;
timevar_pop (TV_MODE_SWITCH);
#endif
timevar_push (TV_SCHED);
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns)
{
open_dump_file (DFI_sched, decl);
schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched, print_rtl_with_bb, insns);
register_life_up_to_date = 1;
}
#endif
timevar_pop (TV_SCHED);
ggc_collect ();
current_function_is_leaf = leaf_function_p ();
timevar_push (TV_LOCAL_ALLOC);
open_dump_file (DFI_lreg, decl);
if (! register_life_up_to_date)
recompute_reg_usage (insns, ! optimize_size);
if (flag_new_regalloc)
{
delete_trivially_dead_insns (insns, max_reg_num ());
reg_alloc ();
timevar_pop (TV_LOCAL_ALLOC);
if (dump_file[DFI_lreg].enabled)
{
timevar_push (TV_DUMP);
close_dump_file (DFI_lreg, NULL, NULL);
timevar_pop (TV_DUMP);
}
timevar_push (TV_GLOBAL_ALLOC);
open_dump_file (DFI_greg, decl);
build_insn_chain (insns);
failure = reload (insns, 0);
timevar_pop (TV_GLOBAL_ALLOC);
if (dump_file[DFI_greg].enabled)
{
timevar_push (TV_DUMP);
dump_global_regs (rtl_dump_file);
close_dump_file (DFI_greg, print_rtl_with_bb, insns);
timevar_pop (TV_DUMP);
}
if (failure)
goto exit_rest_of_compilation;
reload_completed = 1;
rebuild_label_notes_after_reload = 0;
}
else
{
allocate_reg_info (max_regno, FALSE, TRUE);
reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
allocate_initial_values (reg_equiv_memory_loc);
regclass (insns, max_reg_num (), rtl_dump_file);
rebuild_label_notes_after_reload = local_alloc ();
timevar_pop (TV_LOCAL_ALLOC);
if (dump_file[DFI_lreg].enabled)
{
timevar_push (TV_DUMP);
dump_flow_info (rtl_dump_file);
dump_local_alloc (rtl_dump_file);
close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
timevar_pop (TV_DUMP);
}
ggc_collect ();
timevar_push (TV_GLOBAL_ALLOC);
open_dump_file (DFI_greg, decl);
if (optimize)
failure = global_alloc (rtl_dump_file);
else
{
build_insn_chain (insns);
failure = reload (insns, 0);
}
timevar_pop (TV_GLOBAL_ALLOC);
if (dump_file[DFI_greg].enabled)
{
timevar_push (TV_DUMP);
dump_global_regs (rtl_dump_file);
close_dump_file (DFI_greg, print_rtl_with_bb, insns);
timevar_pop (TV_DUMP);
}
if (failure)
goto exit_rest_of_compilation;
}
ggc_collect ();
open_dump_file (DFI_postreload, decl);
if (optimize > 0)
{
timevar_push (TV_RELOAD_CSE_REGS);
reload_cse_regs (insns);
timevar_pop (TV_RELOAD_CSE_REGS);
}
if (rebuild_label_notes_after_reload)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
purge_all_dead_edges (0);
timevar_pop (TV_JUMP);
}
close_dump_file (DFI_postreload, print_rtl_with_bb, insns);
timevar_push (TV_FLOW2);
open_dump_file (DFI_flow2, decl);
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
#ifndef STACK_REGS
if (optimize > 0)
#endif
split_all_insns (0);
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE);
thread_prologue_and_epilogue_insns (insns);
if (optimize)
{
life_analysis (insns, rtl_dump_file, PROP_FINAL);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
#ifndef PUSH_ROUNDING
if (!ACCUMULATE_OUTGOING_ARGS)
#endif
combine_stack_adjustments ();
ggc_collect ();
}
flow2_completed = 1;
close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
timevar_pop (TV_FLOW2);
#ifdef HAVE_peephole2
if (optimize > 0 && flag_peephole2)
{
timevar_push (TV_PEEPHOLE2);
open_dump_file (DFI_peephole2, decl);
peephole2_optimize (rtl_dump_file);
close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
timevar_pop (TV_PEEPHOLE2);
}
#endif
if (optimize > 0 && (flag_rename_registers || flag_cprop_registers))
{
timevar_push (TV_RENAME_REGISTERS);
open_dump_file (DFI_rnreg, decl);
if (flag_rename_registers)
regrename_optimize ();
if (flag_cprop_registers)
copyprop_hardreg_forward ();
close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
timevar_pop (TV_RENAME_REGISTERS);
}
if (flag_if_conversion2)
{
timevar_push (TV_IFCVT2);
open_dump_file (DFI_ce3, decl);
if_convert (1);
close_dump_file (DFI_ce3, print_rtl_with_bb, insns);
timevar_pop (TV_IFCVT2);
}
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)
{
timevar_push (TV_SCHED2);
open_dump_file (DFI_sched2, decl);
split_all_insns (1);
schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
timevar_pop (TV_SCHED2);
ggc_collect ();
}
#endif
#ifdef LEAF_REGISTERS
current_function_uses_only_leaf_regs
= optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
#endif
#ifdef STACK_REGS
timevar_push (TV_REG_STACK);
open_dump_file (DFI_stack, decl);
reg_to_stack (insns, rtl_dump_file);
close_dump_file (DFI_stack, print_rtl_with_bb, insns);
timevar_pop (TV_REG_STACK);
ggc_collect ();
#endif
if (optimize > 0)
{
timevar_push (TV_REORDER_BLOCKS);
open_dump_file (DFI_bbro, decl);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
if ((flag_reorder_blocks) || (flag_reorder_blocks_and_partition))
{
reorder_basic_blocks (flag_reorder_blocks_and_partition);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
}
close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
timevar_pop (TV_REORDER_BLOCKS);
}
compute_alignments ();
free_bb_for_insn ();
#ifdef MACHINE_DEPENDENT_REORG
timevar_push (TV_MACH_DEP);
open_dump_file (DFI_mach, decl);
MACHINE_DEPENDENT_REORG (insns);
close_dump_file (DFI_mach, print_rtl, insns);
timevar_pop (TV_MACH_DEP);
ggc_collect ();
#endif
purge_line_number_notes (insns);
cleanup_barriers ();
#ifdef DELAY_SLOTS
if (optimize > 0 && flag_delayed_branch)
{
timevar_push (TV_DBR_SCHED);
open_dump_file (DFI_dbr, decl);
dbr_schedule (insns, rtl_dump_file);
close_dump_file (DFI_dbr, print_rtl, insns);
timevar_pop (TV_DBR_SCHED);
ggc_collect ();
}
#endif
#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
timevar_push (TV_SHORTEN_BRANCH);
split_all_insns_noflow ();
timevar_pop (TV_SHORTEN_BRANCH);
#endif
convert_to_eh_region_ranges ();
timevar_push (TV_SHORTEN_BRANCH);
shorten_branches (get_insns ());
timevar_pop (TV_SHORTEN_BRANCH);
set_nothrow_function_flags ();
if (current_function_nothrow)
TREE_NOTHROW (current_function_decl) = 1;
timevar_push (TV_FINAL);
{
rtx x;
const char *fnname;
x = DECL_RTL (decl);
if (GET_CODE (x) != MEM)
abort ();
x = XEXP (x, 0);
if (GET_CODE (x) != SYMBOL_REF)
abort ();
fnname = XSTR (x, 0);
assemble_start_function (decl, fnname);
final_start_function (insns, asm_out_file, optimize);
final (insns, asm_out_file, optimize, 0);
final_end_function ();
#ifdef IA64_UNWIND_INFO
output_function_exception_table ();
#endif
assemble_end_function (decl, fnname);
#ifndef IA64_UNWIND_INFO
output_function_exception_table ();
#endif
if (! quiet_flag)
fflush (asm_out_file);
free_basic_block_vars (0);
regset_release_memory ();
}
timevar_pop (TV_FINAL);
ggc_collect ();
timevar_push (TV_SYMOUT);
(*debug_hooks->function_decl) (decl);
timevar_pop (TV_SYMOUT);
exit_rest_of_compilation:
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
sdbout_types (NULL_TREE);
#endif
reload_completed = 0;
flow2_completed = 0;
no_new_pseudos = 0;
timevar_push (TV_FINAL);
init_insn_lengths ();
init_temp_slots ();
free_basic_block_vars (0);
free_bb_for_insn ();
timevar_pop (TV_FINAL);
init_recog_no_volatile ();
free_after_parsing (cfun);
if (! DECL_DEFER_OUTPUT (decl))
{
free_after_compilation (cfun);
DECL_SAVED_INSNS (decl) = 0;
}
cfun = 0;
ggc_collect ();
timevar_pop (TV_REST_OF_COMPILATION);
}
static void
display_help ()
{
int undoc;
unsigned long i;
const char *lang;
printf (_(" -ffixed-<register> Mark <register> as being unavailable to the compiler\n"));
printf (_(" -fcall-used-<register> Mark <register> as being corrupted by function calls\n"));
printf (_(" -fcall-saved-<register> Mark <register> as being preserved across functions\n"));
printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
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"));
printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
for (i = ARRAY_SIZE (f_options); i--;)
{
const char *description = f_options[i].description;
if (description != NULL && *description != 0)
printf (" -f%-21s %s\n",
f_options[i].string, _(description));
}
printf (_(" -O[number] Set optimization level to [number]\n"));
printf (_(" -Os Optimize for space rather than speed\n"));
for (i = LAST_PARAM; i--;)
{
const char *description = compiler_params[i].help;
const int length = 21 - strlen (compiler_params[i].option);
if (description != NULL && *description != 0)
printf (" --param %s=<value>%.*s%s\n",
compiler_params[i].option,
length > 0 ? length : 1, " ",
_(description));
}
printf (_(" -pedantic Issue warnings needed by strict compliance to ISO C\n"));
printf (_(" -pedantic-errors Like -pedantic except that errors are produced\n"));
printf (_(" -w Suppress warnings\n"));
printf (_(" -W Enable extra warnings\n"));
for (i = ARRAY_SIZE (W_options); i--;)
{
const char *description = W_options[i].description;
if (description != NULL && *description != 0)
printf (" -W%-21s %s\n",
W_options[i].string, _(description));
}
printf (_(" -Wunused Enable unused warnings\n"));
printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"));
printf (_(" -p Enable function profiling\n"));
printf (_(" -o <file> Place output into <file> \n"));
printf (_("\
-G <number> Put global and static data smaller than <number>\n\
bytes into a special section (on some targets)\n"));
#ifdef DBX_ONLY_USED_SYMBOLS
for (i = ARRAY_SIZE (debug_args); i--;)
{
if (debug_args[i].description != NULL)
printf (" -g[[-]used%s]%-*s %s\n",
*debug_args[i].arg ? "-" : "",
12 - (*debug_args[i].arg != '\0'),
debug_args[i].arg, _(debug_args[i].description));
}
printf (
_(" (debug info for all symbols)\n"));
#else
for (i = ARRAY_SIZE (debug_args); i--;)
{
if (debug_args[i].description != NULL)
printf (" -g%-21s %s\n",
debug_args[i].arg, _(debug_args[i].description));
}
#endif
printf (_(" -aux-info <file> Emit declaration info into <file>\n"));
printf (_(" -quiet Do not display functions compiled or elapsed time\n"));
printf (_(" -version Display the compiler's version\n"));
printf (_(" -d[letters] Enable dumps from specific passes of the compiler\n"));
printf (_(" -dumpbase <file> Base name to be used for dumps from specific passes\n"));
#if defined INSN_SCHEDULING
printf (_(" -fsched-verbose=<number> Set the verbosity level of the scheduler\n"));
#endif
printf (_(" --help Display this information\n"));
undoc = 0;
lang = "language";
if (ARRAY_SIZE (documented_lang_options) > 1)
{
printf (_("\nLanguage specific options:\n"));
for (i = 0; i < ARRAY_SIZE (documented_lang_options); i++)
{
const char *description = documented_lang_options[i].description;
const char *option = documented_lang_options[i].option;
if (description == NULL)
{
undoc = 1;
if (extra_warnings)
printf (_(" %-23.23s [undocumented]\n"), option);
}
else if (*description == 0)
continue;
else if (option == NULL)
{
if (undoc)
printf
(_("\nThere are undocumented %s specific options as well.\n"),
lang);
undoc = 0;
printf (_("\n Options for %s:\n"), description);
lang = description;
}
else
printf (" %-23.23s %s\n", option, _(description));
}
}
if (undoc)
printf (_("\nThere are undocumented %s specific options as well.\n"),
lang);
display_target_options ();
}
static void
display_target_options ()
{
int undoc, i;
static bool displayed = false;
if (displayed)
return;
displayed = true;
if (ARRAY_SIZE (target_switches) > 1
#ifdef TARGET_OPTIONS
|| ARRAY_SIZE (target_options) > 1
#endif
)
{
int doc = 0;
undoc = 0;
printf (_("\nTarget specific options:\n"));
for (i = ARRAY_SIZE (target_switches); i--;)
{
const char *option = target_switches[i].name;
const char *description = target_switches[i].description;
if (option == NULL || *option == 0)
continue;
else if (description == NULL)
{
undoc = 1;
if (extra_warnings)
printf (_(" -m%-23.23s [undocumented]\n"), option);
}
else if (*description != 0)
doc += printf (" -m%-23.23s %s\n", option, _(description));
}
#ifdef TARGET_OPTIONS
for (i = ARRAY_SIZE (target_options); i--;)
{
const char *option = target_options[i].prefix;
const char *description = target_options[i].description;
if (option == NULL || *option == 0)
continue;
else if (description == NULL)
{
undoc = 1;
if (extra_warnings)
printf (_(" -m%-23.23s [undocumented]\n"), option);
}
else if (*description != 0)
doc += printf (" -m%-23.23s %s\n", option, _(description));
}
#endif
if (undoc)
{
if (doc)
printf (_("\nThere are undocumented target specific options as well.\n"));
else
printf (_(" They exist, but they are not documented.\n"));
}
}
}
static void
decode_d_option (arg)
const char *arg;
{
int i, c, matched;
while (*arg)
switch (c = *arg++)
{
case 'a':
for (i = 0; i < (int) DFI_MAX; ++i)
dump_file[i].enabled = 1;
break;
case 'A':
flag_debug_asm = 1;
break;
case 'p':
flag_print_asm_name = 1;
break;
case 'P':
flag_dump_rtl_in_asm = 1;
flag_print_asm_name = 1;
break;
case 'v':
graph_dump_format = vcg;
break;
case 'x':
rtl_dump_and_exit = 1;
break;
case 'y':
set_yydebug = 1;
break;
case 'D':
case 'I':
break;
case 'H':
setup_core_dumping();
break;
default:
matched = 0;
for (i = 0; i < (int) DFI_MAX; ++i)
if (c == dump_file[i].debug_switch)
{
dump_file[i].enabled = 1;
matched = 1;
}
if (! matched)
warning ("unrecognized gcc debugging option: %c", c);
break;
}
}
static int
decode_f_option (arg)
const char *arg;
{
int j;
const char *option_value = NULL;
for (j = ARRAY_SIZE (f_options); j--;)
{
if (!strcmp (arg, f_options[j].string))
{
*f_options[j].variable = f_options[j].on_value;
return 1;
}
if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
&& ! strcmp (arg + 3, f_options[j].string))
{
*f_options[j].variable = ! f_options[j].on_value;
return 1;
}
}
if (!strcmp (arg, "ast"))
{
flag_fast = 1;
return 1;
}
if (!strcmp (arg, "fast-math"))
set_fast_math_flags (1);
else if (!strcmp (arg, "no-fast-math"))
set_fast_math_flags (0);
else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
|| (option_value = skip_leading_substring (arg, "inline-limit=")))
{
int val =
read_integral_parameter (option_value, arg - 2,
MAX_INLINE_INSNS);
set_param_value ("max-inline-insns", val);
set_param_value ("max-inline-insns-single", val/2);
set_param_value ("max-inline-insns-auto", val/2);
set_param_value ("max-inline-insns-rtl", val);
if (val/4 < MIN_INLINE_INSNS)
{
if (val/4 > 10)
set_param_value ("min-inline-insns", val/4);
else
set_param_value ("min-inline-insns", 10);
}
}
else if ((option_value = skip_leading_substring (arg, "tls-model=")))
{
if (strcmp (option_value, "global-dynamic") == 0)
flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
else if (strcmp (option_value, "local-dynamic") == 0)
flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
else if (strcmp (option_value, "initial-exec") == 0)
flag_tls_default = TLS_MODEL_INITIAL_EXEC;
else if (strcmp (option_value, "local-exec") == 0)
flag_tls_default = TLS_MODEL_LOCAL_EXEC;
else
warning ("`%s': unknown tls-model option", arg - 2);
}
#ifdef INSN_SCHEDULING
else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
fix_sched_param ("verbose", option_value);
#endif
else if ((option_value = skip_leading_substring (arg, "fixed-")))
fix_register (option_value, 1, 1);
else if ((option_value = skip_leading_substring (arg, "call-used-")))
fix_register (option_value, 0, 1);
else if ((option_value = skip_leading_substring (arg, "call-saved-")))
fix_register (option_value, 0, 0);
else if ((option_value = skip_leading_substring (arg, "align-loops=")))
align_loops = read_integral_parameter (option_value, arg - 2, align_loops);
else if ((option_value = skip_leading_substring (arg, "align-loops-max-skip=")))
align_loops_max_skip = read_integral_parameter (option_value, arg - 2, align_loops_max_skip);
else if ((option_value = skip_leading_substring (arg, "align-functions=")))
align_functions
= read_integral_parameter (option_value, arg - 2, align_functions);
else if ((option_value = skip_leading_substring (arg, "align-jumps=")))
align_jumps = read_integral_parameter (option_value, arg - 2, align_jumps);
else if ((option_value = skip_leading_substring (arg, "align-jumps-max-skip=")))
align_jumps_max_skip = read_integral_parameter (option_value, arg - 2, align_jumps_max_skip);
else if ((option_value = skip_leading_substring (arg, "align-labels=")))
align_labels
= read_integral_parameter (option_value, arg - 2, align_labels);
else if ((option_value
= skip_leading_substring (arg, "stack-limit-register=")))
{
int reg = decode_reg_name (option_value);
if (reg < 0)
error ("unrecognized register name `%s'", option_value);
else
stack_limit_rtx = gen_rtx_REG (Pmode, reg);
}
else if ((option_value
= skip_leading_substring (arg, "stack-limit-symbol=")))
{
const char *nm;
nm = ggc_strdup (option_value);
stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
}
else if ((option_value
= skip_leading_substring (arg, "message-length=")))
output_set_maximum_length
(&global_dc->buffer, read_integral_parameter
(option_value, arg - 2, diagnostic_line_cutoff (global_dc)));
else if ((option_value
= skip_leading_substring (arg, "diagnostics-show-location=")))
{
if (!strcmp (option_value, "once"))
diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
else if (!strcmp (option_value, "every-line"))
diagnostic_prefixing_rule (global_dc)
= DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
else
error ("unrecognized option `%s'", arg - 2);
}
else if (!strcmp (arg, "no-stack-limit"))
stack_limit_rtx = NULL_RTX;
else if (!strcmp (arg, "preprocessed"))
;
else if (!strcmp (arg, "debug-gen-index"))
{
flag_debug_gen_index = 1;
}
else if ((option_value = skip_leading_substring (arg, "predictive-compilation=")))
predictive_compilation = read_integral_parameter (option_value, arg - 2, predictive_compilation);
else
return 0;
return 1;
}
static int
decode_W_option (arg)
const char *arg;
{
const char *option_value = NULL;
int j;
for (j = ARRAY_SIZE (W_options); j--;)
{
if (!strcmp (arg, W_options[j].string))
{
*W_options[j].variable = W_options[j].on_value;
if (!strcmp (arg, "error") && getenv ("QA_DISABLE_WERROR"))
*W_options[j].variable = 0;
return 1;
}
if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
&& ! strcmp (arg + 3, W_options[j].string))
{
*W_options[j].variable = ! W_options[j].on_value;
return 1;
}
}
if ((option_value = skip_leading_substring (arg, "id-clash-")))
warning ("-Wid-clash-LEN is no longer supported");
else if ((option_value = skip_leading_substring (arg, "larger-than-")))
{
larger_than_size = read_integral_parameter (option_value, arg - 2, -1);
warn_larger_than = larger_than_size != -1;
}
else if (!strcmp (arg, "unused"))
{
set_Wunused (1);
}
else if (!strcmp (arg, "no-unused"))
{
set_Wunused (0);
}
else
return 0;
return 1;
}
const char *const debug_type_names[] =
{
"none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
};
static int
decode_g_option (arg)
const char *arg;
{
static unsigned level = 0;
static enum debug_info_type selected_debug_type = NO_DEBUG;
static int type_explicitly_set_p = 0;
static const unsigned max_debug_level = 3;
int g_all_len = 0;
#ifdef DBX_ONLY_USED_SYMBOLS
if (strncmp (arg, "full", 4) == 0 || strncmp (arg, "-full", 5) == 0)
{
char *p = (char *)arg + (*(char *)arg == '-') + 4;
flag_debug_only_used_symbols = 0;
if (*p == '-')
++p;
g_all_len = p - arg;
arg += g_all_len;
}
if (strncmp (arg, "used", 4) == 0 || strncmp (arg, "-used", 5) == 0)
{
char *p = (char *)arg + (*(char *)arg == '-') + 4;
flag_debug_only_used_symbols = 1;
if (*p == '-')
++p;
g_all_len = p - arg;
arg += g_all_len;
}
#endif
if (strncmp (arg, "repository", 10) == 0 || strncmp (arg, "-repository", 11) == 0)
{
char *p = (char *)arg + (*(char *)arg == '-') + 10;
flag_grepository = 1;
if (*p == '-')
++p;
g_all_len = p - arg;
arg += g_all_len;
}
for (da = debug_args; da->arg; da++)
{
const int da_len = strlen (da->arg);
if (da_len == 0 || ! strncmp (arg, da->arg, da_len))
{
enum debug_info_type type = da->debug_type;
const char *p = arg + da_len;
if (*p && ! ISDIGIT (*p))
continue;
if (*p)
level = read_integral_parameter (p, 0, max_debug_level + 1);
else
level = (level == 0) ? 2 : level;
if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
{
error ("use -gdwarf -g%d for DWARF v1, level %d",
level, level);
if (level == 2)
error ("use -gdwarf-2 for DWARF v2");
}
if (level > max_debug_level)
{
warning ("\
ignoring option `%s' due to invalid debug level specification",
arg - 2 - g_all_len);
level = debug_info_level;
}
if (type == NO_DEBUG)
{
type = PREFERRED_DEBUGGING_TYPE;
if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0)
{
#ifdef DWARF2_DEBUGGING_INFO
type = DWARF2_DEBUG;
#else
#ifdef DBX_DEBUGGING_INFO
type = DBX_DEBUG;
#endif
#endif
type = DBX_DEBUG;
}
}
if (type == NO_DEBUG)
warning ("`%s': unknown or unsupported -g option", arg - 2 - g_all_len);
if (type_explicitly_set_p
&& da->debug_type != NO_DEBUG
&& type != selected_debug_type)
warning ("`%s' ignored, conflicts with `-g%s'",
arg - 2 - g_all_len, debug_type_names[(int) selected_debug_type]);
else
{
if (type_explicitly_set_p && da->debug_type == NO_DEBUG)
;
else
{
selected_debug_type = type;
type_explicitly_set_p = da->debug_type != NO_DEBUG;
}
write_symbols = (level == 0
? NO_DEBUG
: selected_debug_type);
use_gnu_debug_info_extensions = da->use_extensions_p;
debug_info_level = (enum debug_info_level) level;
}
break;
}
}
orig_write_symbols = write_symbols;
if (! da->arg)
return 0;
return 1;
}
static unsigned int
independent_decode_option (argc, argv)
int argc;
char **argv;
{
char *arg = argv[0];
if (arg[0] != '-' || arg[1] == 0)
{
if (arg[0] == '+')
return 0;
filename = arg;
return 1;
}
arg++;
if (!strcmp (arg, "-help"))
{
display_help ();
exit_after_options = 1;
return 1;
}
if (!strcmp (arg, "-target-help"))
{
display_target_options ();
exit_after_options = 1;
return 1;
}
if (!strcmp (arg, "-version"))
{
print_version (stderr, "");
exit_after_options = 1;
return 1;
}
if (strcmp (arg, "-param") == 0)
{
char *equal;
if (argc == 1)
{
error ("-param option missing argument");
return 1;
}
arg = argv[1];
equal = strchr (arg, '=');
if (!equal)
error ("invalid --param option: %s", arg);
else
{
int val;
*equal = '\0';
val = read_integral_parameter (equal + 1, NULL, INVALID_PARAM_VAL);
if (val != INVALID_PARAM_VAL)
set_param_value (arg, val);
else
error ("invalid parameter value `%s'", equal + 1);
}
return 2;
}
if (*arg == 'Y')
arg++;
switch (*arg)
{
default:
return 0;
case 'E':
flag_preprocessing = 1;
break;
case 'O':
break;
case 'm':
set_target_switch (arg + 1);
break;
case 'f':
return decode_f_option (arg + 1);
case 'g':
return decode_g_option (arg + 1);
case 'd':
if (!strcmp (arg, "dumpbase"))
{
if (argc == 1)
return 0;
if (argv[1][0])
dump_base_name = argv[1];
return 2;
}
else
decode_d_option (arg + 1);
break;
case 'h':
if (!strcmp (arg, "header-mapfile"))
{
if (argc == 1)
return 0;
return 2;
}
break;
case 'i':
if (!strcmp (arg, "inclusion-log-file"))
{
if (argc == 1)
return 0;
return 2;
}
break;
case 'p':
if (!strcmp (arg, "pedantic"))
pedantic = 1;
else if (!strcmp (arg, "pedantic-errors"))
flag_pedantic_errors = pedantic = 1;
else if (arg[1] == 0)
profile_flag = 1;
else
return 0;
break;
case 'q':
if (!strcmp (arg, "quiet"))
quiet_flag = 1;
else
return 0;
break;
case 'v':
if (!strcmp (arg, "version"))
version_flag = 1;
else
return 0;
break;
case 'w':
if (arg[1] == 0)
inhibit_warnings = 1;
else
return 0;
break;
case 'W':
if (arg[1] == 0)
{
extra_warnings = 1;
if (warn_uninitialized != 1)
warn_uninitialized = 2;
}
else
return decode_W_option (arg + 1);
break;
case 'a':
if (!strncmp (arg, "aux-info", 8))
{
if (arg[8] == '\0')
{
if (argc == 1)
return 0;
aux_info_file_name = argv[1];
flag_gen_aux_info = 1;
return 2;
}
else if (arg[8] == '=')
{
aux_info_file_name = arg + 9;
flag_gen_aux_info = 1;
}
else
return 0;
}
else if (!strcmp (arg, "arch"))
{
if (argc == 1)
return 0;
arch_specified = 1;
return 2;
}
else if (!strcmp (arg, "auxbase"))
{
if (argc == 1)
return 0;
if (argv[1][0])
aux_base_name = argv[1];
return 2;
}
else if (!strcmp (arg, "auxbase-strip"))
{
if (argc == 1)
return 0;
if (argv[1][0])
{
strip_off_ending (argv[1], strlen (argv[1]));
if (argv[1][0])
aux_base_name = argv[1];
}
return 2;
}
else
return 0;
break;
case 'o':
if (arg[1] == 0)
{
if (argc == 1)
return 0;
asm_file_name = argv[1];
return 2;
}
return 0;
case 'G':
{
int g_switch_val;
int return_val;
if (arg[1] == 0)
{
if (argc == 1)
return 0;
g_switch_val = read_integral_parameter (argv[1], 0, -1);
return_val = 2;
}
else
{
g_switch_val = read_integral_parameter (arg + 1, 0, -1);
return_val = 1;
}
if (g_switch_val == -1)
return_val = 0;
else
{
g_switch_set = TRUE;
g_switch_value = g_switch_val;
}
return return_val;
}
}
return 1;
}
void
set_target_switch (name)
const char *name;
{
size_t j;
int valid_target_option = 0;
for (j = 0; j < ARRAY_SIZE (target_switches); j++)
if (!strcmp (target_switches[j].name, name))
{
if (target_switches[j].value < 0)
target_flags &= ~-target_switches[j].value;
else
target_flags |= target_switches[j].value;
if (name[0] != 0)
{
if (target_switches[j].value < 0)
target_flags_explicit |= -target_switches[j].value;
else
target_flags_explicit |= target_switches[j].value;
}
valid_target_option = 1;
}
#ifdef TARGET_OPTIONS
if (!valid_target_option)
for (j = 0; j < ARRAY_SIZE (target_options); j++)
{
int len = strlen (target_options[j].prefix);
if (!strncmp (target_options[j].prefix, name, len))
{
*target_options[j].variable = name + len;
valid_target_option = 1;
}
}
#endif
if (!valid_target_option && !arch_specified)
error ("invalid option `%s'", name);
}
static void
print_version (file, indent)
FILE *file;
const char *indent;
{
#ifndef __VERSION__
#define __VERSION__ "[?]"
#endif
fnotice (file,
#ifdef __GNUC__
"%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n"
#else
"%s%s%s version %s (%s) compiled by CC.\n"
#endif
, indent, *indent != 0 ? " " : "",
lang_hooks.name, version_string, TARGET_NAME,
indent, __VERSION__);
fnotice (file, "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n",
indent, *indent != 0 ? " " : "",
PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
}
static int
print_single_switch (file, pos, max, indent, sep, term, type, name)
FILE *file;
int pos, max;
const char *indent, *sep, *term, *type, *name;
{
int len = strlen (sep) + strlen (type) + strlen (name);
if (pos != 0
&& pos + len > max)
{
fprintf (file, "%s", term);
pos = 0;
}
if (pos == 0)
{
fprintf (file, "%s", indent);
pos = strlen (indent);
}
fprintf (file, "%s%s%s", sep, type, name);
pos += len;
return pos;
}
static void
print_switch_values (file, pos, max, indent, sep, term)
FILE *file;
int pos, max;
const char *indent, *sep, *term;
{
size_t j;
char **p;
pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
_("options passed: "), "");
for (p = &save_argv[1]; *p != NULL; p++)
if (**p == '-')
{
if (strcmp (*p, "-o") == 0)
{
if (p[1] != NULL)
p++;
continue;
}
if (strcmp (*p, "-quiet") == 0)
continue;
if (strcmp (*p, "-version") == 0)
continue;
if ((*p)[1] == 'd')
continue;
pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
}
if (pos > 0)
fprintf (file, "%s", term);
pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
_("options enabled: "), "");
for (j = 0; j < ARRAY_SIZE (f_options); j++)
if (*f_options[j].variable == f_options[j].on_value)
pos = print_single_switch (file, pos, max, indent, sep, term,
"-f", f_options[j].string);
for (j = 0; j < ARRAY_SIZE (target_switches); j++)
if (target_switches[j].name[0] != '\0'
&& target_switches[j].value > 0
&& ((target_switches[j].value & target_flags)
== target_switches[j].value))
{
pos = print_single_switch (file, pos, max, indent, sep, term,
"-m", target_switches[j].name);
}
#ifdef TARGET_OPTIONS
for (j = 0; j < ARRAY_SIZE (target_options); j++)
if (*target_options[j].variable != NULL)
{
char prefix[256];
sprintf (prefix, "-m%s", target_options[j].prefix);
pos = print_single_switch (file, pos, max, indent, sep, term,
prefix, *target_options[j].variable);
}
#endif
fprintf (file, "%s", term);
}
static void
init_asm_output (name)
const char *name;
{
if (name == NULL && asm_file_name == 0)
asm_out_file = stdout;
else
{
if (asm_file_name == 0)
{
int len = strlen (dump_base_name);
char *dumpname = (char *) xmalloc (len + 6);
memcpy (dumpname, dump_base_name, len + 1);
strip_off_ending (dumpname, len);
strcat (dumpname, ".s");
asm_file_name = dumpname;
}
if (!strcmp (asm_file_name, "-"))
asm_out_file = stdout;
else
asm_out_file = fopen (asm_file_name, "w+");
if (asm_out_file == 0)
fatal_io_error ("can't open %s for writing", asm_file_name);
}
#ifdef IO_BUFFER_SIZE
setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
_IOFBF, IO_BUFFER_SIZE);
#endif
if (!flag_syntax_only)
{
targetm.asm_out.file_start ();
#ifdef ASM_COMMENT_START
if (flag_verbose_asm)
{
print_version (asm_out_file, ASM_COMMENT_START);
print_switch_values (asm_out_file, 0, MAX_LINE,
ASM_COMMENT_START, " ", "\n");
fprintf (asm_out_file, "\n");
}
#endif
}
}
static void
general_init (argv0)
char *argv0;
{
char *p;
p = argv0 + strlen (argv0);
while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
--p;
progname = p;
xmalloc_set_program_name (progname);
hex_init ();
gcc_init_libintl ();
#ifdef SIGSEGV
signal (SIGSEGV, crash_signal);
#endif
#ifdef SIGILL
signal (SIGILL, crash_signal);
#endif
#ifdef SIGBUS
signal (SIGBUS, crash_signal);
#endif
#ifdef SIGABRT
signal (SIGABRT, crash_signal);
#endif
#if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
signal (SIGIOT, crash_signal);
#endif
if (signal (SIGINT, SIG_IGN) != SIG_IGN)
signal (SIGINT, interrupt_signal);
if (signal (SIGKILL, SIG_IGN) != SIG_IGN)
signal (SIGINT, interrupt_signal);
if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
signal (SIGTERM, interrupt_signal);
#ifdef SIGFPE
signal (SIGFPE, crash_signal);
#endif
(*host_hooks.extra_signals)();
diagnostic_initialize (global_dc);
init_ggc ();
init_stringpool ();
init_ttree ();
#ifdef RLIMIT_STACK
{
struct rlimit rlim;
getrlimit (RLIMIT_STACK, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit (RLIMIT_STACK, &rlim);
}
#endif
}
static void
parse_options_and_default_flags (argc, argv)
int argc;
char **argv;
{
int i;
save_argc = argc;
save_argv = argv;
init_reg_sets ();
add_params (lang_independent_params, LAST_PARAM);
init_ggc_heuristics();
(*lang_hooks.init_options) ();
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "-O"))
{
optimize = 1;
optimize_size = 0;
}
else if (argv[i][0] == '-' && argv[i][1] == 'O')
{
char *p = &argv[i][2];
if ((p[0] == 's') && (p[1] == 0))
{
optimize_size = 1;
optimize = 2;
}
else
{
const int optimize_val = read_integral_parameter (p, p - 2, -1);
if (optimize_val != -1)
{
optimize = optimize_val;
optimize_size = 0;
}
}
}
}
override_O_option ();
if (!optimize)
{
flag_merge_constants = 0;
}
if (optimize >= 1)
{
flag_defer_pop = 1;
flag_thread_jumps = 1;
#ifdef DELAY_SLOTS
flag_delayed_branch = 1;
#endif
#ifdef CAN_DEBUG_WITHOUT_FP
flag_omit_frame_pointer = 1;
#endif
flag_guess_branch_prob = 1;
flag_cprop_registers = 1;
flag_loop_optimize = 1;
flag_crossjumping = 1;
flag_if_conversion = 1;
flag_if_conversion2 = 1;
}
if (optimize >= 2)
{
flag_optimize_sibling_calls = 1;
flag_cse_follow_jumps = 1;
flag_cse_skip_blocks = 1;
flag_gcse = 1;
flag_expensive_optimizations = 1;
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
flag_rerun_loop_opt = 1;
flag_caller_saves = 1;
flag_force_mem = 1;
flag_peephole2 = 1;
#ifdef INSN_SCHEDULING
flag_schedule_insns = 1;
flag_schedule_insns_after_reload = 1;
#endif
flag_regmove = 1;
flag_strict_aliasing = 1;
flag_delete_null_pointer_checks = 1;
flag_reorder_blocks = 1;
flag_reorder_functions = 1;
flag_ss_const_prop = 1;
}
if (optimize >= 3)
{
flag_inline_functions = 1;
flag_rename_registers = 1;
}
if (optimize < 2 || optimize_size)
{
align_loops = 1;
align_jumps = 1;
align_labels = 1;
align_functions = 1;
flag_reorder_blocks = 0;
flag_reorder_blocks_and_partition = 0;
}
flag_signed_char = DEFAULT_SIGNED_CHAR;
#ifdef DEFAULT_SHORT_ENUMS
flag_short_enums = DEFAULT_SHORT_ENUMS;
#endif
target_flags = 0;
set_target_switch ("");
#ifdef IA64_UNWIND_INFO
flag_unwind_tables = IA64_UNWIND_INFO;
#endif
#ifdef OPTIMIZATION_OPTIONS
OPTIMIZATION_OPTIONS (optimize, optimize_size);
#endif
do {
for (i = 1; i < argc;)
{
int lang_processed;
int indep_processed;
if (!override_option (i, argc, argv))
{
++i;
continue;
}
lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i);
if (lang_processed >= 0)
indep_processed = independent_decode_option (argc - i, argv + i);
else
{
lang_processed = -lang_processed;
indep_processed = 0;
}
if (lang_processed || indep_processed)
i += MAX (lang_processed, indep_processed);
else
{
const char *option = NULL;
const char *lang = NULL;
unsigned int j;
for (j = 0; j < ARRAY_SIZE (documented_lang_options); j++)
{
option = documented_lang_options[j].option;
if (option == NULL)
lang = documented_lang_options[j].description;
else if (! strncmp (argv[i], option, strlen (option)))
break;
}
if (j != ARRAY_SIZE (documented_lang_options))
{
if (extra_warnings)
{
warning ("ignoring command line option '%s'", argv[i]);
if (lang)
warning
("(it is valid for %s but not the selected language)",
lang);
}
}
else if (argv[i][0] == '-' && argv[i][1] == 'g')
warning ("`%s': unknown or unsupported -g option", &argv[i][2]);
else
error ("unrecognized option `%s'", argv[i]);
i++;
}
}
} while (add_env_options (&argc, &argv));
if (flag_no_inline == 2)
flag_no_inline = 0;
else
flag_really_no_inline = flag_no_inline;
if (optimize == 0)
{
flag_no_inline = 1;
warn_inline = 0;
if (warn_uninitialized == 1)
warning ("-Wuninitialized is not supported without -O");
}
if (flag_really_no_inline == 2)
flag_really_no_inline = flag_no_inline;
}
static void
process_options ()
{
#ifdef OVERRIDE_OPTIONS
OVERRIDE_OPTIONS;
#endif
if (align_loops <= 0) align_loops = 1;
if (align_loops_max_skip > align_loops || !align_loops)
align_loops_max_skip = align_loops - 1;
align_loops_log = floor_log2 (align_loops * 2 - 1);
if (align_jumps <= 0) align_jumps = 1;
if (align_jumps_max_skip > align_jumps || !align_jumps)
align_jumps_max_skip = align_jumps - 1;
align_jumps_log = floor_log2 (align_jumps * 2 - 1);
if (align_labels <= 0) align_labels = 1;
align_labels_log = floor_log2 (align_labels * 2 - 1);
if (align_labels_max_skip > align_labels || !align_labels)
align_labels_max_skip = align_labels - 1;
if (align_functions <= 0) align_functions = 1;
align_functions_log = floor_log2 (align_functions * 2 - 1);
if (flag_unroll_all_loops)
flag_unroll_loops = 1;
if (flag_unroll_loops)
{
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
}
if (flag_non_call_exceptions)
flag_asynchronous_unwind_tables = 1;
if (flag_asynchronous_unwind_tables)
flag_unwind_tables = 1;
#ifndef INSN_SCHEDULING
if (flag_schedule_insns || flag_schedule_insns_after_reload)
warning ("instruction scheduling not supported on this target machine");
#endif
#ifndef DELAY_SLOTS
if (flag_delayed_branch)
warning ("this target machine does not have delayed branches");
#endif
user_label_prefix = USER_LABEL_PREFIX;
if (flag_leading_underscore != -1)
{
if (user_label_prefix[0] == 0 ||
(user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
{
user_label_prefix = flag_leading_underscore ? "_" : "";
}
else
warning ("-f%sleading-underscore not supported on this target machine",
flag_leading_underscore ? "" : "no-");
}
if (version_flag)
{
print_version (stderr, "");
if (! quiet_flag)
print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
}
if (! quiet_flag || flag_detailed_statistics)
time_report = 1;
if (flag_syntax_only)
{
write_symbols = NO_DEBUG;
profile_flag = 0;
}
#if defined(DBX_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG)
debug_hooks = &dbx_debug_hooks;
#endif
#if defined(XCOFF_DEBUGGING_INFO)
if (write_symbols == XCOFF_DEBUG)
debug_hooks = &xcoff_debug_hooks;
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
debug_hooks = &sdb_debug_hooks;
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
debug_hooks = &dwarf_debug_hooks;
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
debug_hooks = &dwarf2_debug_hooks;
#endif
#ifdef VMS_DEBUGGING_INFO
if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
debug_hooks = &vmsdbg_debug_hooks;
#endif
if (flag_gen_aux_info)
{
aux_info_file = fopen (aux_info_file_name, "w");
if (aux_info_file == 0)
fatal_io_error ("can't open %s", aux_info_file_name);
}
if (! targetm.have_named_sections)
{
if (flag_function_sections)
{
warning ("-ffunction-sections not supported for this target");
flag_function_sections = 0;
}
if (flag_data_sections)
{
warning ("-fdata-sections not supported for this target");
flag_data_sections = 0;
}
}
if (flag_function_sections && profile_flag)
{
warning ("-ffunction-sections disabled; it makes profiling impossible");
flag_function_sections = 0;
}
#ifndef HAVE_prefetch
if (flag_prefetch_loop_arrays)
{
warning ("-fprefetch-loop-arrays not supported for this target");
flag_prefetch_loop_arrays = 0;
}
#else
if (flag_prefetch_loop_arrays && !HAVE_prefetch)
{
warning ("-fprefetch-loop-arrays not supported for this target (try -march switches)");
flag_prefetch_loop_arrays = 0;
}
#endif
if (flag_prefetch_loop_arrays && optimize_size)
{
warning ("-fprefetch-loop-arrays is not supported with -Os");
flag_prefetch_loop_arrays = 0;
}
#ifndef OBJECT_FORMAT_ELF
if (flag_function_sections && write_symbols != NO_DEBUG)
warning ("-ffunction-sections may affect debugging on some targets");
#endif
if (flag_signaling_nans)
flag_trapping_math = 1;
}
static void
backend_init ()
{
init_regs ();
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
#ifdef VMS_DEBUGGING_INFO
|| debug_info_level > DINFO_LEVEL_NONE
#endif
|| flag_test_coverage
|| warn_notreached);
init_fake_stack_mems ();
init_alias_once ();
init_loop ();
init_reload ();
init_function_once ();
init_varasm_once ();
init_dummy_function_start ();
init_expmed ();
if (flag_caller_saves)
init_caller_save ();
expand_dummy_function_end ();
}
static int
lang_dependent_init (name)
const char *name;
{
if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump";
if (flag_preprocessing)
disable_gen_index ();
else
init_gen_indexing ();
name = (*lang_hooks.init) (name);
if (name == NULL)
return 0;
if (flag_gen_index && flag_gen_index_header)
{
if (name[0] != '/')
{
char *apath;
int alen = PATH_MAX + strlen (name) + 2;
apath = (char *) xmalloc (sizeof (char) * alen);
apath = getcwd(apath, alen);
strcat (apath, "/");
strcat (apath, name);
gen_indexing_header ((char *) apath);
gen_indexing_info (INDEX_FILE_BEGIN, apath, -1);
free (apath);
}
else
{
gen_indexing_header ((char *) name);
gen_indexing_info (INDEX_FILE_BEGIN, (char *) name, -1);
}
flag_gen_index_header = 0;
}
name = ggc_strdup (name);
main_input_filename = input_filename = name;
init_asm_output (name);
init_eh ();
init_optabs ();
init_dummy_function_start ();
init_expr_once ();
expand_dummy_function_end ();
push_srcloc (input_filename, 0);
timevar_push (TV_SYMOUT);
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_frame ())
dwarf2out_frame_init ();
#endif
(*debug_hooks->init) (name);
timevar_pop (TV_SYMOUT);
return 1;
}
static void
finalize ()
{
if (flag_gen_aux_info)
{
fclose (aux_info_file);
if (errorcount)
unlink (aux_info_file_name);
}
if (asm_out_file)
{
if (ferror (asm_out_file) != 0)
fatal_io_error ("error writing to %s", asm_file_name);
if (fclose (asm_out_file) != 0)
fatal_io_error ("error closing %s", asm_file_name);
}
if (graph_dump_format != no_graph)
{
int i;
for (i = 0; i < (int) DFI_MAX; ++i)
if (dump_file[i].initialized && dump_file[i].graph_dump_p)
{
char seq[16];
char *suffix;
sprintf (seq, DUMPFILE_FORMAT, i);
suffix = concat (seq, dump_file[i].extension, NULL);
finish_graph_dump_file (dump_base_name, suffix);
free (suffix);
}
}
if (mem_report)
{
ggc_print_statistics ();
stringpool_statistics ();
dump_tree_statistics ();
}
free_reg_info ();
(*lang_hooks.finish) ();
if (flag_gen_index_original)
{
gen_indexing_footer ();
flush_index_buffer ();
finish_gen_indexing ();
}
}
static void
do_compile ()
{
bool no_backend = (*lang_hooks.post_options) ();
process_options ();
if (errorcount)
return;
if (aux_base_name)
;
else if (filename)
{
char *name = xstrdup (lbasename (filename));
aux_base_name = name;
strip_off_ending (name, strlen (name));
}
else
aux_base_name = "gccaux";
init_timevar ();
timevar_start (TV_TOTAL);
if (!no_backend)
backend_init ();
if (lang_dependent_init (filename))
compile_file ();
finalize ();
timevar_stop (TV_TOTAL);
timevar_print (stderr);
}
unsigned int toplev_argv_hash;
static void
init_toplev_hash_code (unsigned int argc, const char **argv)
{
unsigned int val = 137;
bool output_option = false;
for ( ; argc ; --argc, ++argv)
{
const char *s = *argv;
if (!output_option)
while (*s)
val = val * 67 + ((unsigned) *s++ - 113);
output_option = strcmp(*argv, "-o") == 0;
}
toplev_argv_hash = val;
}
int
toplev_main (argc, argv)
int argc;
char **argv;
{
general_init (argv[0]);
init_toplev_hash_code (argc, argv);
parse_options_and_default_flags (argc, argv);
if (!exit_after_options)
do_compile ();
#ifdef CONFIG_DARWIN_H
if (flag_slow_exit)
sleep (1);
#endif
if (errorcount || sorrycount)
return (FATAL_EXIT_CODE);
return (SUCCESS_EXIT_CODE);
}
static char *
extract_override_options ()
{
int has_arg = 0, scnt = 0, added_flag;
char *override_O = NULL, s = 0;
char *opts = getenv ("QA_OVERRIDE_GCC3_OPTIONS");
if (opts && *opts)
{
char c, *p, quote;
static char *override_options_line;
override_options_line = xstrdup (opts);
if (override_options_line[0] == '#')
{
env_ovr_confirm = 0;
p = override_options_line;
}
else
{
env_ovr_confirm = 1;
p = override_options_line - 1;
}
if (env_ovr_confirm)
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: %s\n",
override_options_line);
n_overrides = 0;
while (1)
{
while (*++p == ' ') ;
if ((c = *p) == '\0')
break;
if (p[0] == '-' && p[1] == 'O')
override_O = p;
else
{
if (p[0] == '+')
{
have_added_opts = env_ovr_add_arg;
continue;
}
if (p[0] == 's')
{
s = p[1];
scnt = 0;
added_flag = 0;
}
else
{
s = scnt = 0;
added_flag = have_added_opts;
}
if (n_overrides >= env_override_options_max)
{
env_override_options_max += 6;
env_override_options = (struct env_overrides *)
xrealloc (env_override_options,
sizeof (struct env_overrides)
* env_override_options_max);
if (n_overrides == 0)
++n_overrides;
}
if (!has_arg && p[0] == '-' && p[1] == '-')
{
env_override_options[n_overrides].flags = env_ovr_has_arg | added_flag;
env_override_options[n_overrides].option = p + 1;
has_arg = 1;
}
else
{
env_override_options[n_overrides].flags = added_flag;
env_override_options[n_overrides].option = p--;
has_arg = 0;
}
++n_overrides;
}
quote = 0;
while (*++p && (*p != ' ' || quote || s))
if (*p == '"' || *p == '\'')
quote = (quote && *p == quote) ? 0 : *p;
else if (*p == '\\')
++p;
else if (*p == s && ++scnt == 3)
s = 0;
if (!*p)
break;
*p = '\0';
}
}
if (has_arg)
fatal_error ("QA_OVERRIDE_GCC3_OPTIONS invalid - last option should have an argument");
return override_O;
}
static void
override_O_option ()
{
char *overide_opt = extract_override_options ();
int optimize0 = optimize, optimize_size0 = optimize_size;
if (!overide_opt)
return;
optimize = -1;
if (!strcmp (overide_opt, "-O"))
{
optimize = 1;
optimize_size = 0;
}
else if (overide_opt[0] == '-' && overide_opt[1] == 'O')
{
char *p = overide_opt + 2;
if ((p[0] == 's') && (p[1] == 0))
{
optimize_size = 1;
optimize = 2;
}
else
{
const int optimize_val = read_integral_parameter (p, p - 2, -1);
if (optimize_val != -1)
{
optimize = optimize_val;
optimize_size = 0;
}
}
}
if (optimize < 0)
fatal_error ("QA_OVERRIDE_GCC3_OPTIONS set with an invalid O option (%s).",
overide_opt);
if (env_ovr_confirm
&& (optimize != optimize0 || optimize_size != optimize_size0))
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: Optimization set to %s\n", overide_opt);
}
static int
override_option (i, argc, argv)
int i, argc;
char **argv;
{
int j, len, parg;
char *p, *opt, letter_opt1, letter_opt2, s = 0, *repopt, *reparg, *repend;
static char rep_option[256], rep_arg[256];
if (n_overrides == 0)
return 1;
if (add_env_opts)
{
if ((env_override_options[i].flags & env_ovr_add_arg) == 0
|| (env_override_options[i].flags & env_ovr_used) != 0
|| env_override_options[i].option == NULL)
return 0;
argv[i] = env_override_options[i].option;
if (env_override_options[i].flags & env_ovr_has_arg)
{
argv[i+1] = env_override_options[i+1].option;
if (env_ovr_confirm
&& (env_override_options[i].flags & env_over_no_msg) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Adding command line option '%s %s'\n",
argv[i], argv[i+1]);
}
else if (env_ovr_confirm
&& (env_override_options[i].flags & env_over_no_msg) == 0)
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: Adding command line option '%s'\n",
argv[i]);
return 1;
}
if (!argv[i])
return 0;
opt = argv[i];
letter_opt1 = 0;
if (opt[0] == '-')
{
if (opt[1] == 'f' || opt[1] == 'm' || opt[1] == 'W')
{
letter_opt1 = opt[1];
opt += 2;
}
if (opt[0] == 'n' && opt[1] == 'o' && opt[2] == '-')
opt += 3;
}
for (j = 1; j < n_overrides; ++j)
{
p = env_override_options[j].option;
letter_opt2 = 0;
s = 0;
parg = 0;
if (p[0] == 's')
{
s = p[1];
p += 2;
repopt = strchr (p, s);
if (!repopt)
return 1;
*repopt++ = '\0';
if (p[0] == '-' && p[1] == '-')
{
parg = 1;
++p;
}
}
if (p[0] == '-')
{
if (p[1] == 'f' || p[1] == 'm' || p[1] == 'W')
{
letter_opt2 = p[1];
p += 2;
}
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
p += 3;
}
if (strcmp (p, opt) == 0 && letter_opt1 == letter_opt2)
{
if (i < argc - 1
&& (env_override_options[j].flags & env_ovr_has_arg))
argv[i + 1] = env_override_options[j + 1].option;
if (s)
{
repend = strchr (repopt, s);
reparg = NULL;
if (repend)
{
reparg = strchr(repopt, ' ');
if (reparg)
{
strncpy (rep_option, repopt, len = reparg - repopt);
rep_option[len] = '\0';
++reparg;
strncpy (rep_arg, reparg, len = repend - reparg);
rep_arg[len] = '\0';
}
else
{
strncpy (rep_option, repopt, len = repend - repopt);
rep_option[len] = rep_arg[0] = '\0';
}
if (len)
{
if (parg)
{
if (reparg)
{
if (strcmp (argv[i], rep_option) != 0
|| strcmp (argv[i+1], rep_arg) == 0)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s %s' with '%s %s'\n",
argv[i], argv[i + 1], rep_option, rep_arg);
argv[i] = rep_option;
argv[i + 1] = rep_arg;
}
}
else
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s %s' with '%s'\n",
argv[i], argv[i + 1], rep_option);
argv[i] = rep_option;
argv[i+1] = NULL;
}
}
else if (reparg)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s' with '%s %s'\n",
argv[i], rep_option, rep_arg);
if (n_overrides+1 >= env_override_options_max)
{
env_override_options_max += 6;
env_override_options = (struct env_overrides *)
xrealloc (env_override_options,
sizeof (struct env_overrides)
* env_override_options_max);
if (n_overrides == 0)
++n_overrides;
}
env_override_options[n_overrides ].option = rep_option;
env_override_options[n_overrides++].flags = env_ovr_has_arg | env_ovr_add_arg | env_over_no_msg;
env_override_options[n_overrides ].option = rep_arg;
env_override_options[n_overrides++].flags = env_ovr_add_arg | env_over_no_msg;
argv[i] = NULL;
have_added_opts = 1;
}
else if (strcmp (argv[i], rep_option) != 0)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Replacing command line option '%s' with '%s'\n",
argv[i], rep_option);
argv[i] = rep_option;
}
}
else
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: Deleting command line option '%s", argv[i]);
if (parg)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr, " %s", argv[i + 1]);
argv[i + 1] = NULL;
}
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fputs ("'\n", stderr);
argv[i] = NULL;
}
}
*(repopt-1) = s;
env_override_options[j].flags |= env_ovr_used;
return argv[i] != NULL;
}
else if (strcmp (argv[i], env_override_options[j].option) != 0)
{
if (env_ovr_confirm
&& (env_override_options[j].flags & env_ovr_used) == 0)
fprintf (stderr,
"### QA_OVERRIDE_GCC3_OPTIONS: Overriding command line option '%s' with '%s'\n",
argv[i], env_override_options[j].option);
argv[i] = env_override_options[j].option;
env_override_options[j].flags |= env_ovr_used;
return 1;
}
}
else if (s)
*(repopt-1) = s;
}
return 1;
}
static int
add_env_options (argc, argv)
int *argc;
char ***argv;
{
static int save_argc;
static char **save_argv;
if (have_added_opts)
{
if (!add_env_opts)
{
save_argv = *argv;
save_argc = *argc;
*argc = n_overrides;
*argv = (char **)xmalloc(n_overrides * sizeof (char *));
add_env_opts = 1;
return 1;
}
free (*argv);
*argc = save_argc;
*argv = save_argv;
add_env_opts = 0;
}
return 0;
}
static const char *toplev_pwd;
const char *
gcc_getpwd ()
{
if (toplev_pwd == 0)
toplev_pwd = getpwd ();
return toplev_pwd;
}
void
gcc_setpwd (const char *wd)
{
toplev_pwd = strcpy (xmalloc (strlen (wd) + 1), wd);
}