#include "config.h"
#undef FLOAT
#undef FFS
#include "system.h"
#include <signal.h>
#include <setjmp.h>
#include <sys/types.h>
#include <ctype.h>
#ifdef REPORT_EVENT
#include <errno.h>
#include "apple/make-support.h"
#endif
#ifdef NEXT_FAT_OUTPUT
#include <mach-o/arch.h>
#endif
#include <sys/stat.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 "flags.h"
#include "insn-attr.h"
#include "insn-codes.h"
#include "insn-config.h"
#include "recog.h"
#include "defaults.h"
#include "output.h"
#include "except.h"
#include "toplev.h"
#include "expr.h"
#include "basic-block.h"
#include "intl.h"
#ifdef DWARF_DEBUGGING_INFO
#include "dwarfout.h"
#endif
#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
#ifdef _WIN32
char *exportNamesForDLL = NULL;
#endif
#ifdef VMS
static FILE *
vms_fopen (fname, type)
char * fname;
char * type;
{
FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen;
if (*type == 'w')
return (*vmslib_fopen) (fname, type, "mbc=32",
"deq=64", "fop=tef", "shr=nil");
else
return (*vmslib_fopen) (fname, type, "mbc=32");
}
#define fopen vms_fopen
#endif
#ifndef DEFAULT_GDB_EXTENSIONS
#define DEFAULT_GDB_EXTENSIONS 1
#endif
#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
#ifndef PREFERRED_DEBUGGING_TYPE
You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#endif
#else
#ifdef DBX_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#endif
#ifdef SDB_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
#endif
#ifdef DWARF_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
#endif
#ifdef DWARF2_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
#endif
#ifdef XCOFF_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
#endif
#endif
#ifndef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
#endif
#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif
#ifdef EXIT_FROM_TOPLEV
#define exit(status) EXIT_FROM_TOPLEV (status)
#endif
extern int rtx_equal_function_value_matters;
#if ! (defined (VMS) || defined (OS2))
extern char **environ;
#endif
extern char *version_string, *language_string;
extern int size_directive_output;
extern tree last_assemble_variable_decl;
extern char *init_parse PVPROTO((char *));
extern void finish_parse ();
extern void init_decl_processing ();
extern void init_obstacks ();
extern void init_tree_codes ();
extern void init_rtl ();
extern void init_regs ();
extern void init_optabs ();
extern void init_stmt ();
extern void init_reg_sets ();
extern void dump_flow_info ();
extern void dump_sched_info ();
extern void dump_local_alloc ();
extern void regset_release_memory ();
extern void print_rtl ();
extern void print_rtl_with_bb ();
void rest_of_decl_compilation ();
#ifdef NEXT_FAT_OUTPUT
void set_target_architecture PROTO((const char *));
#endif
void error_with_file_and_line PVPROTO((const char *file,
int line, const char *s, ...));
void error_with_decl PVPROTO((tree decl, const char *s, ...));
void error_for_asm PVPROTO((rtx insn, const char *s, ...));
void notice PVPROTO((const char *s, ...));
void error PVPROTO((const char *s, ...));
void fatal PVPROTO((const char *s, ...));
void warning_with_file_and_line PVPROTO((const char *file,
int line, const char *s, ...));
void warning_with_decl PVPROTO((tree decl, const char *s, ...));
void warning PVPROTO((const char *s, ...));
void pedwarn PVPROTO((const char *s, ...));
void pedwarn_with_decl PVPROTO((tree decl, const char *s, ...));
void pedwarn_with_file_and_line PVPROTO((const char *file,
int line, const char *s, ...));
void sorry PVPROTO((const char *s, ...));
static void set_target_switch PROTO((const char *));
static char *decl_name PROTO((tree, int));
static void vmessage PROTO((const char *, const char *, va_list));
static void v_message_with_file_and_line PROTO((const char *, int, int,
const char *, va_list));
static void v_message_with_decl PROTO((tree, int, const char *, va_list));
static void file_and_line_for_asm PROTO((rtx, char **, int *));
static void v_error_with_file_and_line PROTO((const char *, int,
const char *, va_list));
static void v_error_with_decl PROTO((tree, const char *, va_list));
static void v_error_for_asm PROTO((rtx, const char *, va_list));
static void verror PROTO((const char *, va_list));
static void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
static void v_warning_with_file_and_line PROTO ((const char *, int,
const char *, va_list));
static void v_warning_with_decl PROTO((tree, const char *, va_list));
static void v_warning_for_asm PROTO((rtx, const char *, va_list));
static void vwarning PROTO((const char *, va_list));
static void vpedwarn PROTO((const char *, va_list));
static void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
static void v_pedwarn_with_file_and_line PROTO((const char *, int,
const char *, va_list));
static void vsorry PROTO((const char *, va_list));
static void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
#ifdef ASM_IDENTIFY_LANGUAGE
static void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
#endif
static void open_dump_file PROTO((const char *, const char *));
static void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
static void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
static void clean_dump_file PROTO((const char *));
static void compile_file PROTO((char *));
static void display_help PROTO ((void));
static void print_version PROTO((FILE *, const char *));
static int print_single_switch PROTO((FILE *, int, int, const char *,
const char *, const char *,
const char *, const char *));
static void print_switch_values PROTO((FILE *, int, int, const char *,
const char *, const char *));
void print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
void clean_graph_dump_file PROTO ((const char *, const char *));
void finish_graph_dump_file PROTO ((const char *, const char *));
#define MAX_LINE 75
char *progname;
int save_argc;
char **save_argv;
char *input_filename;
char *main_input_filename;
int lineno;
int no_new_pseudos;
struct file_stack *input_file_stack;
int input_file_stack_tick;
extern tree current_function_decl;
const char *dump_base_name;
extern int target_flags;
int rtl_dump = 0;
int rtl_dump_and_exit = 0;
int jump_opt_dump = 0;
int addressof_dump = 0;
int cse_dump = 0;
int gcse_dump = 0;
int loop_dump = 0;
int cse2_dump = 0;
int branch_prob_dump = 0;
int flow_dump = 0;
int combine_dump = 0;
int regmove_dump = 0;
int sched_dump = 0;
#ifdef NEXT_SEMANTICS
int fppc_dump = 0;
#endif
int local_reg_dump = 0;
int global_reg_dump = 0;
int flow2_dump = 0;
int sched2_dump = 0;
int jump2_opt_dump = 0;
#ifdef DELAY_SLOTS
int dbr_sched_dump = 0;
#endif
int flag_print_asm_name = 0;
#ifdef STACK_REGS
int stack_reg_dump = 0;
#endif
#ifdef MACHINE_DEPENDENT_REORG
int mach_dep_reorg_dump = 0;
#endif
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_level debug_info_level = DINFO_LEVEL_NONE;
int use_gnu_debug_info_extensions = 0;
int optimize = 0;
int optimize_size = 0;
int errorcount = 0;
int warningcount = 0;
int sorrycount = 0;
char *(*decl_printable_name) PROTO ((tree, int));
typedef rtx (*lang_expand_expr_t)
PROTO ((union tree_node *, rtx, enum machine_mode,
enum expand_modifier modifier));
lang_expand_expr_t lang_expand_expr = 0;
tree (*lang_expand_constant) PROTO((tree)) = 0;
void (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
int profile_flag = 0;
int profile_block_flag;
int profile_arc_flag = 0;
int flag_test_coverage = 0;
int flag_branch_probabilities = 0;
int pedantic = 0;
int in_system_header = 0;
int obey_regdecls = 0;
#ifdef NEXT_FAT_OUTPUT
static char *architecture = 0;
#endif
int quiet_flag = 0;
int flag_signed_char;
int flag_short_enums;
#ifdef DEFAULT_CALLER_SAVES
int flag_caller_saves = 1;
#else
int flag_caller_saves = 0;
#endif
#ifdef NEXT_SEMANTICS
#if defined (DEFAULT_FPPC)
int flag_fppc = 1;
#else
int flag_fppc = 0;
#endif
int flag_check_mem = 0;
int flag_dave_indirect = 0;
#endif
#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_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_fast_math = 0;
int flag_errno_math = 1;
int flag_complex_divide_method = 0;
int flag_volatile;
int flag_volatile_global;
int flag_volatile_static;
int flag_syntax_only = 0;
int flag_dump_symbols = 0;
static int flag_gcse;
static int flag_rerun_cse_after_loop;
int flag_rerun_loop_opt;
int flag_inline_functions;
int flag_keep_inline_functions;
int flag_no_inline;
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;
#ifdef HAVE_COALESCED_SYMBOLS
static int old_write_symbols = NO_DEBUG;
int flag_coalesced = 1;
int flag_coalesce_rtti = 0;
int flag_privatize_coalesced = 1;
int flag_force_coalesced = 0;
#endif
int flag_exceptions;
int flag_new_exceptions = 0;
int flag_no_common;
int flag_pretend_float;
int flag_pedantic_errors = 0;
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
#ifdef HAIFA
int flag_schedule_interblock = 1;
int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;
#endif
int flag_branch_on_count_reg;
int flag_inhibit_size_directive = 0;
int flag_verbose_asm = 0;
int flag_debug_asm = 0;
#ifdef USE_COLLECT2
int flag_gnu_linker = 0;
#else
int flag_gnu_linker = 1;
#endif
int flag_pack_struct = 0;
int flag_stack_check;
int flag_check_memory_usage = 0;
int flag_prefix_function_name = 0;
int flag_argument_noalias = 0;
int flag_strict_aliasing = 0;
int flag_instrument_function_entry_exit = 0;
int flag_no_ident = 0;
static struct
{
const char * arg;
enum debug_info_type debug_type;
int use_extensions_p;
const char * description;
} *da,
debug_args[] =
{
{ "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
"Generate default debug format output" },
{ "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
#ifdef DBX_DEBUGGING_INFO
{ "gstabs", DBX_DEBUG, 0, "Generate STABS format debug output" },
{ "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
#endif
#ifdef DWARF_DEBUGGING_INFO
{ "gdwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
{ "gdwarf+", DWARF_DEBUG, 1,
"Generated extended DWARF-1 format debug output" },
#endif
#ifdef DWARF2_DEBUGGING_INFO
{ "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
#endif
#ifdef XCOFF_DEBUGGING_INFO
{ "gxcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
{ "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
#endif
#ifdef SDB_DEBUGGING_INFO
{ "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
#endif
{ 0, 0, 0, 0 }
};
typedef struct
{
const char * string;
int * variable;
int on_value;
const char * description;
}
lang_independent_options;
int flag_leading_underscore = -1;
const char *user_label_prefix;
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
#endif
lang_independent_options f_options[] =
{
{"float-store", &flag_float_store, 1,
"Do not store floats in registers" },
{"volatile", &flag_volatile, 1,
"Consider all mem refs through pointers as volatile"},
{"volatile-global", &flag_volatile_global, 1,
"Consider all mem refs to global data to be volatile" },
{"volatile-static", &flag_volatile_static, 1,
"Consider all mem refs to static data to be volatile" },
{"defer-pop", &flag_defer_pop, 1,
"Defer popping functions args from stack until later" },
{"omit-frame-pointer", &flag_omit_frame_pointer, 1,
"When possible do not generate stack frames"},
{"cse-follow-jumps", &flag_cse_follow_jumps, 1,
"When running CSE, follow jumps to their targets" },
{"cse-skip-blocks", &flag_cse_skip_blocks, 1,
"When running CSE, follow conditional jumps" },
{"expensive-optimizations", &flag_expensive_optimizations, 1,
"Perform a number of minor, expensive optimisations" },
{"thread-jumps", &flag_thread_jumps, 1,
"Perform jump threading optimisations"},
{"strength-reduce", &flag_strength_reduce, 1,
"Perform strength reduction optimisations" },
{"unroll-loops", &flag_unroll_loops, 1,
"Perform loop unrolling when iteration count is known" },
{"unroll-all-loops", &flag_unroll_all_loops, 1,
"Perform loop unrolling for all loops" },
{"move-all-movables", &flag_move_all_movables, 1,
"Force all loop invariant computations out of loops" },
{"reduce-all-givs", &flag_reduce_all_givs, 1,
"Strength reduce all loop general induction variables" },
{"writable-strings", &flag_writable_strings, 1,
"Store strings in writable data section" },
{"peephole", &flag_no_peephole, 0,
"Enable machine specific peephole optimisations" },
{"force-mem", &flag_force_mem, 1,
"Copy memory operands into registers before using" },
{"force-addr", &flag_force_addr, 1,
"Copy memory address constants into regs before using" },
{"function-cse", &flag_no_function_cse, 0,
"Allow function addresses to be held in registers" },
{"inline-functions", &flag_inline_functions, 1,
"Integrate simple functions into their callers" },
{"keep-inline-functions", &flag_keep_inline_functions, 1,
"Generate code for funcs even if they are fully inlined" },
{"inline", &flag_no_inline, 0,
"Pay attention to the 'inline' keyword"},
{"keep-static-consts", &flag_keep_static_consts, 1,
"Emit static const variables even if they are not used" },
{"syntax-only", &flag_syntax_only, 1,
"Check for syntax errors, then stop" },
{"dump-syms", &flag_dump_symbols, 1,
"Dump ascii description of the parse to stdout" },
{"shared-data", &flag_shared_data, 1,
"Mark data as shared rather than private" },
{"caller-saves", &flag_caller_saves, 1,
"Enable saving registers around function calls" },
{"pcc-struct-return", &flag_pcc_struct_return, 1,
"Return 'short' aggregates in memory, not registers" },
{"reg-struct-return", &flag_pcc_struct_return, 0,
"Return 'short' aggregates in registers" },
{"delayed-branch", &flag_delayed_branch, 1,
"Attempt to fill delay slots of branch instructions" },
{"gcse", &flag_gcse, 1,
"Perform the global common subexpression elimination" },
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
"Run CSE pass after loop optimisations"},
{"rerun-loop-opt", &flag_rerun_loop_opt, 1,
"Run the loop optimiser twice"},
{"pretend-float", &flag_pretend_float, 1,
"Pretend that host and target use the same FP format"},
{"schedule-insns", &flag_schedule_insns, 1,
"Reschedule instructions to avoid pipeline stalls"},
{"schedule-insns2", &flag_schedule_insns_after_reload, 1,
"Run two passes of the instruction scheduler"},
#ifdef HAIFA
{"sched-interblock",&flag_schedule_interblock, 1,
"Enable scheduling across basic blocks" },
{"sched-spec",&flag_schedule_speculative, 1,
"Allow speculative motion of non-loads" },
{"sched-spec-load",&flag_schedule_speculative_load, 1,
"Allow speculative motion of some loads" },
{"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
"Allow speculative motion of more loads" },
#endif
{"branch-count-reg",&flag_branch_on_count_reg, 1,
"Replace add,compare,branch with branch on count reg"},
{"pic", &flag_pic, 1,
"Generate position independent code, if possible"},
{"PIC", &flag_pic, 2, ""},
#ifdef HAVE_COALESCED_SYMBOLS
{"coalesce", &flag_coalesced, 1,
"Coalesce C++ template functions"},
{"coalesce-rtti", &flag_coalesce_rtti, 1,
"Coalesce C++ RTTI stuff"},
{"privatize-coalesced", &flag_privatize_coalesced, 1,
"Mark coalesced symbols as private_extern (except RTTI vars)"},
{"privatize-coalesced-all", &flag_privatize_coalesced, 2,
"Mark ALL coalesced symbols (inc. RTTI) as private_extern"},
{"privatize-all-coalesced", &flag_privatize_coalesced, 2,
"Mark ALL coalesced symbols (inc. RTTI) as private_extern"},
#endif
{"exceptions", &flag_exceptions, 1,
"Enable exception handling" },
{"new-exceptions", &flag_new_exceptions, 1,
"Use the new model for exception handling" },
{"sjlj-exceptions", &exceptions_via_longjmp, 1,
"Use setjmp/longjmp to handle exceptions" },
{"asynchronous-exceptions", &asynchronous_exceptions, 1,
"Support asynchronous exceptions" },
{"profile-arcs", &profile_arc_flag, 1,
"Insert arc based program profiling code" },
{"test-coverage", &flag_test_coverage, 1,
"Create data files needed by gcov" },
{"branch-probabilities", &flag_branch_probabilities, 1,
"Use profiling information for branch probabilities" },
{"fast-math", &flag_fast_math, 1,
"Improve FP speed by violating ANSI & IEEE rules" },
{"common", &flag_no_common, 0,
"Do not put unitialised globals in the common section" },
{"inhibit-size-directive", &flag_inhibit_size_directive, 1,
"Do not generate .size directives" },
{"function-sections", &flag_function_sections, 1,
"place each function into its own section" },
{"data-sections", &flag_data_sections, 1,
"place data items into their own section" },
{"verbose-asm", &flag_verbose_asm, 1,
"Add extra commentry to assembler output"},
{"gnu-linker", &flag_gnu_linker, 1,
"Output GNU ld formatted global initialisers"},
{"regmove", &flag_regmove, 1,
"Enables a register move optimisation"},
{"optimize-register-move", &flag_regmove, 1,
"Do the full regmove optimization pass"},
{"pack-struct", &flag_pack_struct, 1,
"Pack structure members together without holes" },
{"stack-check", &flag_stack_check, 1,
"Insert stack checking code into the program" },
{"argument-alias", &flag_argument_noalias, 0,
"Specify that arguments may alias each other & globals"},
{"argument-noalias", &flag_argument_noalias, 1,
"Assume arguments may alias globals but not each other"},
{"argument-noalias-global", &flag_argument_noalias, 2,
"Assume arguments do not alias each other or globals" },
{"strict-aliasing", &flag_strict_aliasing, 1,
"Assume strict aliasing rules apply" },
{"check-memory-usage", &flag_check_memory_usage, 1,
"Generate code to check every memory access" },
{"prefix-function-name", &flag_prefix_function_name, 1,
"Add a prefix to all function names" },
{"dump-unnumbered", &flag_dump_unnumbered, 1,
"Suppress output of instruction numbers and line number notes in debugging dumps"},
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
"Instrument function entry/exit with profiling calls"},
{"leading-underscore", &flag_leading_underscore, 1,
"External symbols have a leading underscore" },
{"ident", &flag_no_ident, 0,
"Process #ident directives"}
#ifdef NEXT_SEMANTICS
, {"fppc", &flag_fppc, 1,
"Perform floating-point precision-control pass"}
#endif
};
#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0]))
static struct lang_opt
{
const char * option;
const char * description;
}
documented_lang_options[] =
{
{ "-ansi", "Compile just for ANSI C" },
{ "-fallow-single-precision",
"Do not promote floats to double if using -traditional" },
{ "-std= ", "Determine language standard"},
{ "-fsigned-bitfields", "" },
{ "-funsigned-bitfields","Make bitfields by unsigned by default" },
{ "-fno-signed-bitfields", "" },
{ "-fno-unsigned-bitfields","" },
{ "-fsigned-char", "Make 'char' be signed by default"},
{ "-funsigned-char", "Make 'char' be unsigned by default"},
{ "-fno-signed-char", "" },
{ "-fno-unsigned-char", "" },
{ "-ftraditional", "" },
{ "-traditional", "Attempt to support traditional K&R style C"},
{ "-fnotraditional", "" },
{ "-fno-traditional", "" },
{ "-fasm", "" },
{ "-fno-asm", "Do not recognise the 'asm' keyword" },
{ "-fbuiltin", "" },
{ "-fno-builtin", "Do not recognise any built in functions" },
{ "-fhosted", "Assume normal C execution environment" },
{ "-fno-hosted", "" },
{ "-ffreestanding",
"Assume that standard libraries & main might not exist" },
{ "-fno-freestanding", "" },
{ "-fcond-mismatch", "Allow different types as args of ? operator"},
{ "-fno-cond-mismatch", "" },
{ "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
{ "-fno-dollars-in-identifiers", "" },
{ "-fshort-double", "Use the same size for double as for float" },
{ "-fno-short-double", "" },
{ "-fshort-enums", "Use the smallest fitting integer to hold enums"},
{ "-fno-short-enums", "" },
#ifdef ENABLE_NEWLINE_MAPPING
{"-fmap-newline-to-cr", "Interpret \\n as carriage return (0x0D)"},
{"-fno-map-newline-to-cr", ""},
#endif
#ifdef PASCAL_STRINGS
{"-fpascal-strings", "Allow pascal-style strings - \"\\pexample\" "},
{"-fno-pascal-strings", ""},
#endif
#ifdef NEXT_SEMANTICS
{ "-faltivec", "Enable SIMD programming model (vector extensions)" },
{ "-fno-altivec", ""},
#else
{ "-fvec", "Enable SIMD programming model (vector extensions)" },
{ "-fno-vec", ""},
#endif
{ "-Wall", "Enable most warning messages" },
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
{"-Wmost", "Enable most warning messages (without unused params warning)"},
#endif
{ "-Wbad-function-cast",
"Warn about casting functions to incompatible types" },
{ "-Wno-bad-function-cast", "" },
{ "-Wmissing-noreturn",
"Warn about functions which might be candidates for attribute noreturn" },
{ "-Wno-missing-noreturn", "" },
{ "-Wcast-qual", "Warn about casts which discard qualifiers"},
{ "-Wno-cast-qual", "" },
{ "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
{ "-Wno-char-subscripts", "" },
{ "-Wcomment", "Warn if nested comments are detected" },
{ "-Wno-comment", "" },
{ "-Wcomments", "Warn if nested comments are detected" },
{ "-Wno-comments", "" },
{ "-Wconversion", "Warn about possibly confusing type conversions" },
{ "-Wno-conversion", "" },
{ "-Wformat", "Warn about printf format anomalies" },
{ "-Wno-format", "" },
#ifdef NEXT_SEMANTICS
{"-Wnoformat", ""},
#endif
{ "-Wimplicit-function-declaration",
"Warn about implicit function declarations" },
{ "-Wno-implicit-function-declaration", "" },
{ "-Werror-implicit-function-declaration", "" },
{ "-Wimplicit-int", "Warn when a declaration does not specify a type" },
{ "-Wno-implicit-int", "" },
{ "-Wimplicit", "" },
{ "-Wno-implicit", "" },
{ "-Wimport", "Warn about the use of the #import directive" },
{ "-Wno-import", "" },
{ "-Wlong-double","" },
{ "-Wno-long-double", "Do not warn about using 'long double'" },
{ "-Wlong-long","" },
{ "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
{ "-Wmain", "Warn about suspicious declarations of main" },
{ "-Wno-main", "" },
{ "-Wmissing-braces",
"Warn about possibly missing braces around initialisers" },
{ "-Wno-missing-braces", "" },
{ "-Wmissing-declarations",
"Warn about global funcs without previous declarations"},
{ "-Wno-missing-declarations", "" },
{ "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
{ "-Wno-missing-prototypes", "" },
{ "-Wmultichar", "Warn about use of multicharacter literals"},
{ "-Wno-multichar", "" },
{ "-Wnested-externs", "Warn about externs not at file scope level" },
{ "-Wno-nested-externs", "" },
{ "-Wparentheses", "Warn about possible missing parentheses" },
{ "-Wno-parentheses", "" },
{ "-Wpointer-arith", "Warn about function pointer arithmetic" },
{ "-Wno-pointer-arith", "" },
{ "-Wredundant-decls",
"Warn about multiple declarations of the same object" },
{ "-Wno-redundant-decls", "" },
{ "-Wsign-compare", "Warn about signed/unsigned comparisons" },
{ "-Wno-sign-compare", "" },
{ "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
{ "-Wno-unknown-pragmas", "" },
{ "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
{ "-Wno-strict-prototypes", "" },
{ "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
{ "-Wno-traditional", "" },
{ "-Wtrigraphs", "Warn when trigraphs are encountered" },
{ "-Wno-trigraphs", "" },
{ "-Wundef", "" },
{ "-Wno-undef", "" },
{ "-Wwrite-strings", "Mark strings as 'const char *'"},
{ "-Wno-write-strings", "" },
#ifdef FOUR_CHAR_CONSTANTS
{"-Wfour-char-constants", "Allow MacOS-style four-char constants like 'APPL'"},
{"-Wno-four-char-constants", ""},
#endif
{ "--help", "" },
{ "-A", "" },
{ "-D", "" },
{ "-I", "" },
#if USE_CPPLIB
{ "-MD", "Print dependencies to FILE.d" },
{ "-MMD", "Print dependencies to FILE.d" },
{ "-M", "Print dependencies to stdout" },
{ "-MM", "Print dependencies to stdout" },
#endif
{ "-U", "" },
{ "-H", "" },
{ "-idirafter", "" },
{ "-imacros", "" },
{ "-include", "" },
{ "-iprefix", "" },
{ "-isystem", "" },
{ "-iwithprefix", "" },
{ "-iwithprefixbefore", "" },
{ "-lang-c", "" },
{ "-lang-c89", "" },
{ "-lang-c++", "" },
{ "-remap", "" },
{ "-nostdinc", "" },
{ "-nostdinc++", "" },
{ "-trigraphs", "" },
{ "-undef", "" },
#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
DEFINE_LANG_NAME ("Objective C")
#if defined (NEXT_SEMANTICS) || defined(NEXT_PDO)
{"-fobjc", "" },
{"-fno-objc", "" },
#else
{ "-lang-objc", "" },
#endif
{ "-gen-decls", "Dump decls to a .decl file" },
{ "-fgnu-runtime", "Generate code for GNU runtime environment" },
{ "-fno-gnu-runtime", "" },
{ "-fnext-runtime", "Generate code for NeXT runtime environment" },
{ "-fno-next-runtime", "" },
#ifdef MODERN_OBJC_SYNTAX
{"-fmodern-objc-syntax", "Enable 'modern' Objective-C syntax" },
{"-fno-modern-objc-syntax", ""},
#endif
{ "-Wselector", "Warn if a selector has multiple methods" },
{ "-Wno-selector", "" },
{ "-Wprotocol", "" },
{ "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
{ "-print-objc-runtime-info",
"Generate C header of platform specific features" },
#ifdef NEXT_SEMANTICS
{"-ObjC++", "" },
{"-ObjC", "" },
{"-dynamic", "" },
{"-bundle", "" },
{"-static", "" },
{"-threeThreeMethodEncoding", "" },
#endif
#include "options.h"
};
struct
{
const char * name;
int value;
const char * description;
}
target_switches [] = TARGET_SWITCHES;
#ifdef TARGET_OPTIONS
struct
{
const char * prefix;
const char ** variable;
const char * description;
}
target_options [] = TARGET_OPTIONS;
#endif
int inhibit_warnings = 0;
int extra_warnings = 0;
int warnings_are_errors = 0;
int warn_unused;
int warn_uninitialized;
int warn_shadow;
int warn_switch;
int warn_return_type;
int warn_cast_align;
int warn_id_clash;
unsigned id_clash_len;
int warn_larger_than;
unsigned larger_than_size;
int warn_inline;
int warn_aggregate_return;
lang_independent_options W_options[] =
{
#ifdef NEXT_CPP_PRECOMP
{"precomp", NULL, 1, "$$$ what's -precomp do?"},
#endif
{"unused", &warn_unused, 1, "Warn when a variable is unused" },
{"error", &warnings_are_errors, 1, ""},
{"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
{"switch", &warn_switch, 1,
"Warn about enumerated switches missing a specific case" },
{"aggregate-return", &warn_aggregate_return, 1,
"Warn about returning structures, unions or arrays" },
{"cast-align", &warn_cast_align, 1,
"Warn about pointer casts which increase alignment" },
{"uninitialized", &warn_uninitialized, 1,
"Warn about unitialized automatic variables"},
{"inline", &warn_inline, 1,
"Warn when an inlined function cannot be inlined"}
};
FILE *asm_out_file;
FILE *aux_info_file;
FILE *rtl_dump_file = NULL;
int
read_integral_parameter (p, pname, defval)
const char *p;
const char *pname;
const int defval;
{
const char *endp = p;
while (*endp)
{
if (*endp >= '0' && *endp <= '9')
endp++;
else
break;
}
if (*endp != 0)
{
if (pname != 0)
error ("Invalid option `%s'", pname);
return defval;
}
return atoi (p);
}
int parse_time;
int varconst_time;
int integration_time;
int jump_time;
int cse_time;
int gcse_time;
int loop_time;
int cse2_time;
int branch_prob_time;
int flow_time;
int combine_time;
int regmove_time;
int sched_time;
int local_alloc_time;
int global_alloc_time;
int flow2_time;
int sched2_time;
#ifdef DELAY_SLOTS
int dbr_sched_time;
#endif
int shorten_branch_time;
int stack_reg_time;
int final_time;
int symout_time;
int dump_time;
long
get_run_time ()
{
if (quiet_flag)
return 0;
#ifdef __BEOS__
return 0;
#else
#if defined (_WIN32) && !defined (__CYGWIN__)
if (clock() < 0)
return 0;
else
return (clock() * 1000);
#else
#ifdef _SC_CLK_TCK
{
static int tick;
struct tms tms;
if (tick == 0)
tick = 1000000 / sysconf(_SC_CLK_TCK);
times (&tms);
return (tms.tms_utime + tms.tms_stime) * tick;
}
#else
#ifdef USG
{
struct tms tms;
# if HAVE_SYSCONF && defined _SC_CLK_TCK
# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK)
# else
# ifdef CLK_TCK
# define TICKS_PER_SECOND CLK_TCK
# else
# define TICKS_PER_SECOND HZ
# endif
# endif
times (&tms);
return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
}
#else
#ifndef VMS
{
struct rusage rusage;
getrusage (0, &rusage);
return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
+ rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
}
#else
{
struct
{
int proc_user_time;
int proc_system_time;
int child_user_time;
int child_system_time;
} vms_times;
times ((void *) &vms_times);
return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
}
#endif
#endif
#endif
#endif
#endif
}
#define TIMEVAR(VAR, BODY) \
do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
void
print_time (str, total)
const char *str;
int total;
{
fprintf (stderr,
"time in %s: %d.%06d\n",
str, total / 1000000, total % 1000000);
}
#ifdef REPORT_EVENT
#include "c-tree.h"
void
v_report_event (type, decl, file, line, msg, ap)
int type;
tree decl;
char *file;
int line;
const char *msg;
va_list ap;
{
char *name;
tree method_name = maybe_objc_method_name (decl);
if (decl == NULL)
name = "top level";
else if (method_name)
name = IDENTIFIER_POINTER (method_name);
else
name = (*decl_printable_name) (decl, 2);
V_REPORT_EVENT (type, name, file, line, msg, ap);
}
void
v_report_event_with_prefix (type, decl, file, line, prefix, msg, ap)
int type;
tree decl;
char *file;
int line;
char *prefix;
char *msg;
va_list ap;
{
char *temp;
if (!prefix)
temp = msg;
else if (!msg)
temp = prefix;
else
{
temp = (char *) malloc (strlen (prefix) + (msg ? strlen (msg) : 0) + 1);
if (temp)
strcat (strcpy (temp, prefix), msg);
}
v_report_event (type, decl, file, line, temp ? temp : prefix, ap);
if (prefix && msg)
free (temp);
}
void
report_event (int type, tree decl, char *file, int line, char *msg, ...)
{
va_list ap;
va_start (ap, msg);
v_report_event (type, decl, file, line, msg, ap);
va_end (ap);
}
#endif
int
count_error (warningp)
int warningp;
{
if (warningp && inhibit_warnings)
return 0;
#ifdef NEXT_FAT_OUTPUT
if (!warningcount && !errorcount && architecture)
{
const char *a;
if (! strcmp (architecture, "i386"))
a = "Intel";
else if (! strcmp (architecture, "hppa"))
a = "HPPA";
else if (! strcmp (architecture, "m68k"))
a = "NeXT";
else if (! strcmp (architecture, "sparc"))
a = "Sparc";
else if (! strcmp (architecture, "ppc"))
a = "PowerPC";
else
a = architecture;
#ifdef REPORT_EVENT
report_event (1, current_function_decl, input_filename, lineno,
"For architecture %s:", a);
#endif
fprintf (stderr, "For architecture %s:\n", architecture);
}
#endif
if (warningp && !warnings_are_errors)
warningcount++;
else
{
static int warning_message = 0;
if (warningp && !warning_message)
{
notice ("%s: warnings being treated as errors\n", progname);
warning_message = 1;
}
errorcount++;
}
return 1;
}
void
pfatal_with_name (name)
const char *name;
{
#ifdef REPORT_EVENT
report_event (0, current_function_decl, input_filename, lineno,
"%s: %s", name, strerror (errno));
#endif
fprintf (stderr, "%s: ", progname);
perror (name);
exit (FATAL_EXIT_CODE);
}
void
fatal_io_error (name)
const char *name;
{
#ifdef REPORT_EVENT
report_event (0, current_function_decl, input_filename, lineno,
"%s: I/O error", name);
#endif
notice ("%s: %s: I/O error\n", progname, name);
exit (FATAL_EXIT_CODE);
}
void
fatal_insn VPROTO((const char *msgid, rtx insn, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
rtx insn;
#endif
va_list ap;
VA_START (ap, insn);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
insn = va_arg (ap, rtx);
#endif
verror (msgid, ap);
debug_rtx (insn);
exit (FATAL_EXIT_CODE);
}
void
fatal_insn_not_found (insn)
rtx insn;
{
if (INSN_CODE (insn) < 0)
fatal_insn ("internal error--unrecognizable insn:", insn);
else
fatal_insn ("internal error--insn does not satisfy its constraints:", insn);
}
static char *
decl_name (decl, verbosity)
tree decl;
int verbosity ATTRIBUTE_UNUSED;
{
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
static int need_error_newline;
static tree last_error_function = NULL;
static int last_error_tick;
void
announce_function (decl)
tree decl;
{
if (! quiet_flag)
{
if (rtl_dump_and_exit)
fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
else
fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
fflush (stderr);
need_error_newline = 1;
last_error_function = current_function_decl;
}
}
void
default_print_error_function (file)
const char *file;
{
if (last_error_function != current_function_decl)
{
if (file)
fprintf (stderr, "%s: ", file);
if (current_function_decl == NULL)
notice ("At top level:\n");
else
notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
? "In method `%s':\n"
: "In function `%s':\n"),
(*decl_printable_name) (current_function_decl, 2));
last_error_function = current_function_decl;
}
}
void (*print_error_function) PROTO((const char *)) =
default_print_error_function;
void
report_error_function (file)
const char *file ATTRIBUTE_UNUSED;
{
struct file_stack *p;
if (need_error_newline)
{
fprintf (stderr, "\n");
need_error_newline = 0;
}
if (input_file_stack && input_file_stack->next != 0
&& input_file_stack_tick != last_error_tick)
{
for (p = input_file_stack->next; p; p = p->next)
notice ((p == input_file_stack->next
? "In file included from %s:%d"
: ",\n from %s:%d"),
p->name, p->line);
fprintf (stderr, ":\n");
last_error_tick = input_file_stack_tick;
}
(*print_error_function) (input_filename);
}
static void
vnotice (file, msgid, ap)
FILE *file;
char *msgid;
va_list ap;
{
vfprintf (file, _(msgid), ap);
}
void
notice VPROTO((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, char *);
#endif
vnotice (stderr, msgid, ap);
va_end (ap);
}
void
fnotice VPROTO((FILE *file, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
FILE *file;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
file = va_arg (ap, FILE *);
msgid = va_arg (ap, const char *);
#endif
vnotice (file, msgid, ap);
va_end (ap);
}
static void
report_file_and_line (file, line, warn)
char *file;
int line;
int warn;
{
if (file)
fprintf (stderr, "%s:%d: ", file, line);
else
fprintf (stderr, "%s: ", progname);
if (warn)
notice ("warning: ");
}
static void
vmessage (prefix, msgid, ap)
const char *prefix;
const char *msgid;
va_list ap;
{
if (prefix)
fprintf (stderr, "%s: ", prefix);
vfprintf (stderr, msgid, ap);
}
static void
v_message_with_file_and_line (file, line, warn, msgid, ap)
const char *file;
int line;
int warn;
const char *msgid;
va_list ap;
{
#ifdef REPORT_EVENT
v_report_event (warn, current_function_decl, file, line, msgid, ap);
#endif
report_file_and_line (file, line, warn);
vnotice (stderr, msgid, ap);
fputc ('\n', stderr);
}
static void
v_message_with_decl (decl, warn, msgid, ap)
tree decl;
int warn;
const char *msgid;
va_list ap;
{
const char *p;
#ifdef REPORT_EVENT
char *msg = (char *) malloc ((size_t) 512);
if (msg)
*msg = '\0';
#endif
report_file_and_line (DECL_SOURCE_FILE (decl),
DECL_SOURCE_LINE (decl), warn);
for (p = _(msgid); *p; ++p)
{
if (*p == '%')
{
if (*(p + 1) == '%')
++p;
else if (*(p + 1) != 's')
abort ();
else
break;
}
}
if (p > _(msgid))
{
char fmt[sizeof "%.255s"];
long width = p - _(msgid);
if (width > 255L) width = 255L;
sprintf (fmt, "%%.%lds", width);
#ifdef REPORT_EVENT
if (msg)
sprintf (msg, fmt, _(msgid));
#endif
fprintf (stderr, fmt, _(msgid));
}
if (*p == '%')
{
const char *n = (DECL_NAME (decl)
? (*decl_printable_name) (decl, 2)
: "((anonymous))");
#ifdef REPORT_EVENT
char *temp = msg;
msg = (char *) malloc ((msg ? strlen (msg) : 0) + strlen (n) + 1);
if (msg)
{
*msg = '\0';
if (temp)
strcpy (msg, temp);
strcat (msg, n);
}
free (temp);
#endif
fputs (n, stderr);
while (*p)
{
++p;
if (ISALPHA (*(p - 1) & 0xFF))
break;
}
}
#ifdef REPORT_EVENT
v_report_event_with_prefix (warn,
current_function_decl,
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
msg, p, ap);
free (msg);
#endif
if (*p)
vmessage ((char *)NULL, p, ap);
fputc ('\n', stderr);
}
static void
file_and_line_for_asm (insn, pfile, pline)
rtx insn;
char **pfile;
int *pline;
{
rtx body = PATTERN (insn);
rtx asmop;
if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
asmop = SET_SRC (body);
else if (GET_CODE (body) == ASM_OPERANDS)
asmop = body;
else if (GET_CODE (body) == PARALLEL
&& GET_CODE (XVECEXP (body, 0, 0)) == SET)
asmop = SET_SRC (XVECEXP (body, 0, 0));
else if (GET_CODE (body) == PARALLEL
&& GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
asmop = XVECEXP (body, 0, 0);
else
asmop = NULL;
if (asmop)
{
*pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
*pline = ASM_OPERANDS_SOURCE_LINE (asmop);
}
else
{
*pfile = input_filename;
*pline = lineno;
}
}
static void
v_error_with_file_and_line (file, line, msgid, ap)
const char *file;
int line;
const char *msgid;
va_list ap;
{
count_error (0);
report_error_function (file);
v_message_with_file_and_line (file, line, 0, msgid, ap);
}
void
error_with_file_and_line VPROTO((const char *file, int line,
const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *file;
int line;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
file = va_arg (ap, const char *);
line = va_arg (ap, int);
msgid = va_arg (ap, const char *);
#endif
v_error_with_file_and_line (file, line, msgid, ap);
va_end (ap);
}
static void
v_error_with_decl (decl, msgid, ap)
tree decl;
const char *msgid;
va_list ap;
{
count_error (0);
report_error_function (DECL_SOURCE_FILE (decl));
v_message_with_decl (decl, 0, msgid, ap);
}
void
error_with_decl VPROTO((tree decl, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
tree decl;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
decl = va_arg (ap, tree);
msgid = va_arg (ap, const char *);
#endif
v_error_with_decl (decl, msgid, ap);
va_end (ap);
}
static void
v_error_for_asm (insn, msgid, ap)
rtx insn;
const char *msgid;
va_list ap;
{
char *file;
int line;
count_error (0);
file_and_line_for_asm (insn, &file, &line);
report_error_function (file);
v_message_with_file_and_line (file, line, 0, msgid, ap);
}
void
error_for_asm VPROTO((rtx insn, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
rtx insn;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
insn = va_arg (ap, rtx);
msgid = va_arg (ap, const char *);
#endif
v_error_for_asm (insn, msgid, ap);
va_end (ap);
}
static void
verror (msgid, ap)
const char *msgid;
va_list ap;
{
v_error_with_file_and_line (input_filename, lineno, msgid, ap);
}
void
error VPROTO((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
#endif
verror (msgid, ap);
va_end (ap);
}
static void
vfatal (msgid, ap)
const char *msgid;
va_list ap;
{
verror (msgid, ap);
exit (FATAL_EXIT_CODE);
}
void
fatal VPROTO((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
#endif
vfatal (msgid, ap);
va_end (ap);
}
static void
v_warning_with_file_and_line (file, line, msgid, ap)
const char *file;
int line;
const char *msgid;
va_list ap;
{
if (count_error (1))
{
report_error_function (file);
v_message_with_file_and_line (file, line, 1, msgid, ap);
}
}
void
warning_with_file_and_line VPROTO((const char *file, int line,
const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *file;
int line;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
file = va_arg (ap, const char *);
line = va_arg (ap, int);
msgid = va_arg (ap, const char *);
#endif
v_warning_with_file_and_line (file, line, msgid, ap);
va_end (ap);
}
static void
v_warning_with_decl (decl, msgid, ap)
tree decl;
const char *msgid;
va_list ap;
{
if (count_error (1))
{
report_error_function (DECL_SOURCE_FILE (decl));
v_message_with_decl (decl, 1, msgid, ap);
}
}
void
warning_with_decl VPROTO((tree decl, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
tree decl;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
decl = va_arg (ap, tree);
msgid = va_arg (ap, const char *);
#endif
v_warning_with_decl (decl, msgid, ap);
va_end (ap);
}
static void
v_warning_for_asm (insn, msgid, ap)
rtx insn;
const char *msgid;
va_list ap;
{
if (count_error (1))
{
char *file;
int line;
file_and_line_for_asm (insn, &file, &line);
report_error_function (file);
v_message_with_file_and_line (file, line, 1, msgid, ap);
}
}
void
warning_for_asm VPROTO((rtx insn, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
rtx insn;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
insn = va_arg (ap, rtx);
msgid = va_arg (ap, const char *);
#endif
v_warning_for_asm (insn, msgid, ap);
va_end (ap);
}
static void
vwarning (msgid, ap)
const char *msgid;
va_list ap;
{
v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
}
void
warning VPROTO((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
#endif
vwarning (msgid, ap);
va_end (ap);
}
static void
vpedwarn (msgid, ap)
const char *msgid;
va_list ap;
{
if (flag_pedantic_errors)
verror (msgid, ap);
else
vwarning (msgid, ap);
}
void
pedwarn VPROTO((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
#endif
vpedwarn (msgid, ap);
va_end (ap);
}
static void
v_pedwarn_with_decl (decl, msgid, ap)
tree decl;
const char *msgid;
va_list ap;
{
if (! DECL_IN_SYSTEM_HEADER (decl))
{
if (flag_pedantic_errors)
v_error_with_decl (decl, msgid, ap);
else
v_warning_with_decl (decl, msgid, ap);
}
}
void
pedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
tree decl;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
decl = va_arg (ap, tree);
msgid = va_arg (ap, const char *);
#endif
v_pedwarn_with_decl (decl, msgid, ap);
va_end (ap);
}
static void
v_pedwarn_with_file_and_line (file, line, msgid, ap)
const char *file;
int line;
const char *msgid;
va_list ap;
{
if (flag_pedantic_errors)
v_error_with_file_and_line (file, line, msgid, ap);
else
v_warning_with_file_and_line (file, line, msgid, ap);
}
void
pedwarn_with_file_and_line VPROTO((const char *file, int line,
const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *file;
int line;
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
file = va_arg (ap, const char *);
line = va_arg (ap, int);
msgid = va_arg (ap, const char *);
#endif
v_pedwarn_with_file_and_line (file, line, msgid, ap);
va_end (ap);
}
static void
vsorry (msgid, ap)
const char *msgid;
va_list ap;
{
sorrycount++;
#ifdef REPORT_EVENT
v_report_event_with_prefix (0, current_function_decl, input_filename, lineno,
"sorry, not implemented:", msgid, ap);
#endif
if (input_filename)
fprintf (stderr, "%s:%d: ", input_filename, lineno);
else
fprintf (stderr, "%s: ", progname);
notice ("sorry, not implemented: ");
vnotice (stderr, msgid, ap);
fputc ('\n', stderr);
}
void
sorry VPROTO((const char *msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msgid;
#endif
va_list ap;
VA_START (ap, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (ap, const char *);
#endif
vsorry (msgid, ap);
va_end (ap);
}
const char *
trim_filename (name)
const char *name;
{
static const char *this_file = __FILE__;
const char *p = name, *q = this_file;
while (*p == *q && *p != 0 && *q != 0) p++, q++;
while (p > name && p[-1] != DIR_SEPARATOR
#ifdef DIR_SEPARATOR_2
&& p[-1] != DIR_SEPARATOR_2
#endif
)
p--;
return p;
}
void
fancy_abort ()
{
fatal ("internal gcc abort");
}
void
do_abort ()
{
abort ();
}
void
botch (s)
const char * s ATTRIBUTE_UNUSED;
{
abort ();
}
PTR
xmalloc (size)
size_t size;
{
register PTR value;
if (size == 0)
size = 1;
value = (PTR) malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
PTR
xcalloc (size1, size2)
size_t size1, size2;
{
register PTR value;
if (size1 == 0 || size2 == 0)
size1 = size2 = 1;
value = (PTR) calloc (size1, size2);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
PTR
xrealloc (ptr, size)
PTR ptr;
size_t size;
{
register PTR result;
if (size == 0)
size = 1;
result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size));
if (!result)
fatal ("virtual memory exhausted");
return result;
}
char *
xstrdup (s)
register const char *s;
{
register char *result = (char *) malloc (strlen (s) + 1);
if (! result)
fatal ("virtual memory exhausted");
strcpy (result, s);
return result;
}
int
exact_log2_wide (x)
register unsigned HOST_WIDE_INT x;
{
register int log = 0;
if (x == 0 || x != (x & -x))
return -1;
while ((x >>= 1) != 0)
log++;
return log;
}
int
floor_log2_wide (x)
register unsigned HOST_WIDE_INT x;
{
register int log = -1;
while (x != 0)
log++,
x >>= 1;
return log;
}
static int float_handler_set;
int float_handled;
jmp_buf float_handler;
static void
float_signal (signo)
int signo ATTRIBUTE_UNUSED;
{
if (float_handled == 0)
abort ();
#if defined (USG) || defined (hpux)
signal (SIGFPE, float_signal);
#endif
float_handled = 0;
signal (SIGFPE, float_signal);
longjmp (float_handler, 1);
}
void
set_float_handler (handler)
jmp_buf handler;
{
float_handled = (handler != 0);
if (handler)
bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
if (float_handled && ! float_handler_set)
{
signal (SIGFPE, float_signal);
float_handler_set = 1;
}
}
int
do_float_handler (fn, data)
void (*fn) PROTO ((PTR));
PTR data;
{
jmp_buf buf;
if (setjmp (buf))
{
set_float_handler (NULL);
return 0;
}
set_float_handler (buf);
(*fn)(data);
set_float_handler (NULL);
return 1;
}
int
push_float_handler (handler, old_handler)
jmp_buf handler, old_handler;
{
int was_handled = float_handled;
float_handled = 1;
if (was_handled)
memcpy ((char *) old_handler, (char *) float_handler,
sizeof (float_handler));
memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
return was_handled;
}
void
pop_float_handler (handled, handler)
int handled;
jmp_buf handler;
{
float_handled = handled;
if (handled)
bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
}
static void
pipe_closed (signo)
int signo ATTRIBUTE_UNUSED;
{
fatal ("output pipe has been closed");
}
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 (c == '\"' || c == '\\')
putc ('\\', asm_file);
putc (c, asm_file);
}
putc ('\"', asm_file);
#endif
}
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 (na[-1] == '/')
break;
#ifdef DIR_SEPARATOR
if (na[-1] == DIR_SEPARATOR)
break;
#endif
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
}
#ifdef ASM_IDENTIFY_LANGUAGE
static void
output_lang_identify (asm_out_file)
FILE *asm_out_file;
{
int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
char *s = (char *) alloca (len);
sprintf (s, "__gnu_compiled_%s", lang_identify ());
ASM_OUTPUT_LABEL (asm_out_file, s);
}
#endif
static void
open_dump_file (suffix, function_name)
const char *suffix;
const char *function_name;
{
char *dumpname;
TIMEVAR
(dump_time,
{
dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
if (rtl_dump_file != NULL)
fclose (rtl_dump_file);
strcpy (dumpname, dump_base_name);
strcat (dumpname, suffix);
rtl_dump_file = fopen (dumpname, "a");
if (rtl_dump_file == NULL)
pfatal_with_name (dumpname);
free (dumpname);
if (function_name)
fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
});
return;
}
static void
close_dump_file (func, insns)
void (*func) PROTO ((FILE *, rtx));
rtx insns;
{
TIMEVAR
(dump_time,
{
if (func)
func (rtl_dump_file, insns);
fflush (rtl_dump_file);
fclose (rtl_dump_file);
rtl_dump_file = NULL;
});
return;
}
static void
dump_rtl (suffix, decl, func, insns)
const char *suffix;
tree decl;
void (*func) PROTO ((FILE *, rtx));
rtx insns;
{
open_dump_file (suffix, decl_printable_name (decl, 2));
close_dump_file (func, insns);
}
static void
clean_dump_file (suffix)
const char *suffix;
{
char *dumpname;
dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
strcpy (dumpname, dump_base_name);
strcat (dumpname, suffix);
rtl_dump_file = fopen (dumpname, "w");
if (rtl_dump_file == NULL)
pfatal_with_name (dumpname);
free (dumpname);
fclose (rtl_dump_file);
rtl_dump_file = NULL;
return;
}
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];
DECL_DEFER_OUTPUT (decl) = 0;
if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
&& incomplete_decl_finalize_hook != 0)
(*incomplete_decl_finalize_hook) (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)
&& (! TREE_READONLY (decl)
|| TREE_PUBLIC (decl)
|| (!optimize && flag_keep_static_consts)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
reconsider = 1;
rest_of_decl_compilation (decl, NULL_PTR, 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;
temporary_allocation ();
output_inline_function (decl);
permanent_allocation (1);
}
}
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))
DECL_RTL (decl) = NULL;
if (TREE_CODE (decl) == FUNCTION_DECL
&& (warn_unused
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
&& DECL_INITIAL (decl) == 0
&& DECL_EXTERNAL (decl)
&& ! DECL_ARTIFICIAL (decl)
&& ! TREE_PUBLIC (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
&& ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
|| (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl)
&& ! TREE_USED (decl)
&& (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl))
&& ! TREE_USED (DECL_NAME (decl)))
warning_with_decl (decl, "`%s' defined but not used");
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
&& TREE_PUBLIC (decl) && DECL_INITIAL (decl)
&& ! DECL_EXTERNAL (decl)
&& DECL_RTL (decl) != 0)
TIMEVAR (symout_time, sdbout_symbol (decl, 0));
if (write_symbols == SDB_DEBUG
&& TREE_CODE (decl) == VAR_DECL
&& DECL_INITIAL (decl)
&& ! DECL_EXTERNAL (decl)
&& DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == MEM)
TIMEVAR (symout_time, sdbout_toplevel_data (decl));
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG
&& (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG
&& (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
TIMEVAR (symout_time, dwarf2out_decl (decl));
#endif
}
}
static void
compile_file (name)
char *name;
{
tree globals;
int start_time;
int name_specified = name != 0;
if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump";
parse_time = 0;
varconst_time = 0;
integration_time = 0;
jump_time = 0;
cse_time = 0;
gcse_time = 0;
loop_time = 0;
cse2_time = 0;
branch_prob_time = 0;
flow_time = 0;
combine_time = 0;
regmove_time = 0;
sched_time = 0;
local_alloc_time = 0;
global_alloc_time = 0;
flow2_time = 0;
sched2_time = 0;
#ifdef DELAY_SLOTS
dbr_sched_time = 0;
#endif
shorten_branch_time = 0;
stack_reg_time = 0;
final_time = 0;
symout_time = 0;
dump_time = 0;
init_obstacks ();
init_tree_codes ();
name = init_parse (name);
init_rtl ();
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
|| flag_test_coverage);
init_regs ();
init_decl_processing ();
init_optabs ();
init_stmt ();
init_expmed ();
init_expr_once ();
init_loop ();
init_reload ();
init_alias_once ();
if (flag_caller_saves)
init_caller_save ();
if (flag_gen_aux_info)
{
aux_info_file = fopen (aux_info_file_name, "w");
if (aux_info_file == 0)
pfatal_with_name (aux_info_file_name);
}
if (rtl_dump)
clean_dump_file (".rtl");
if (jump_opt_dump)
{
clean_dump_file (".jump");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".jump");
}
if (addressof_dump)
{
clean_dump_file (".addressof");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".addressof");
}
if (cse_dump)
{
clean_dump_file (".cse");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".cse");
}
if (loop_dump)
{
clean_dump_file (".loop");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".loop");
}
if (cse2_dump)
{
clean_dump_file (".cse2");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".cse2");
}
if (branch_prob_dump)
{
clean_dump_file (".bp");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".bp");
}
if (flow_dump)
{
clean_dump_file (".flow");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".flow");
}
if (combine_dump)
{
clean_dump_file (".combine");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".combine");
}
if (regmove_dump)
{
clean_dump_file (".regmove");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".regmove");
}
if (sched_dump)
{
clean_dump_file (".sched");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".sched");
}
if (local_reg_dump)
{
clean_dump_file (".lreg");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".lreg");
}
if (global_reg_dump)
{
clean_dump_file (".greg");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".greg");
}
if (flow2_dump)
{
clean_dump_file (".flow2");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".flow2");
}
if (sched2_dump)
{
clean_dump_file (".sched2");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".sched2");
}
if (jump2_opt_dump)
{
clean_dump_file (".jump2");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".jump2");
}
#ifdef DELAY_SLOTS
if (dbr_sched_dump)
{
clean_dump_file (".dbr");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".dbr");
}
#endif
if (gcse_dump)
{
clean_dump_file (".gcse");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".gcse");
}
#ifdef STACK_REGS
if (stack_reg_dump)
{
clean_dump_file (".stack");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".stack");
}
#endif
#ifdef MACHINE_DEPENDENT_REORG
if (mach_dep_reorg_dump)
{
clean_dump_file (".mach");
if (graph_dump_format != no_graph)
clean_graph_dump_file (dump_base_name, ".mach");
}
#endif
if (flag_syntax_only)
asm_out_file = NULL;
else
{
if (! name_specified && asm_file_name == 0)
asm_out_file = stdout;
else
{
int len = strlen (dump_base_name);
register char *dumpname = (char *) xmalloc (len + 6);
strcpy (dumpname, dump_base_name);
strip_off_ending (dumpname, len);
strcat (dumpname, ".s");
if (asm_file_name == 0)
{
asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
strcpy (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)
pfatal_with_name (asm_file_name);
}
#ifdef IO_BUFFER_SIZE
setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
_IOFBF, IO_BUFFER_SIZE);
#endif
}
input_filename = name;
input_file_stack
= (struct file_stack *) xmalloc (sizeof (struct file_stack));
input_file_stack->next = 0;
input_file_stack->name = input_filename;
lang_init ();
if (main_input_filename == 0)
main_input_filename = name;
if (flag_dump_symbols)
printf ("<Fm %s\n", main_input_filename);
if (flag_syntax_only)
{
write_symbols = NO_DEBUG;
profile_flag = 0;
profile_block_flag = 0;
}
else
{
ASM_FILE_START (asm_out_file);
#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
#ifndef ASM_IDENTIFY_GCC
fprintf (asm_out_file, "gcc2_compiled.:\n");
#else
ASM_IDENTIFY_GCC (asm_out_file);
#endif
#ifdef ASM_IDENTIFY_LANGUAGE
ASM_IDENTIFY_LANGUAGE (asm_out_file);
#endif
}
#ifndef ASM_OUTPUT_SECTION_NAME
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;
}
#endif
if (flag_function_sections
&& (profile_flag || profile_block_flag))
{
warning ("-ffunction-sections disabled; it makes profiling impossible.");
flag_function_sections = 0;
}
#ifndef OBJECT_FORMAT_ELF
if (flag_function_sections && write_symbols != NO_DEBUG)
warning ("-ffunction-sections may affect debugging on some targets.");
#endif
if (profile_flag || profile_block_flag)
{
if (insn_template[CODE_FOR_nop] != 0)
output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
else
assemble_zeros (UNITS_PER_WORD);
}
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
getdecls ()));
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
getdecls ()));
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
#endif
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_frame ())
dwarf2out_frame_init ();
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
#endif
init_final (main_input_filename);
init_branch_prob (dump_base_name);
start_time = get_run_time ();
if (yyparse () != 0)
{
if (errorcount == 0)
notice ("Errors detected in input file (your bison.simple is out of date)\n");
while (! global_bindings_p ())
poplevel (0, 0, 0);
}
#if defined (NEXT_PDO) && defined (_WIN32)
if (exportNamesForDLL && *exportNamesForDLL)
{
fprintf (asm_out_file, ".section\t.drectve , \"s\"\n");
fprintf (asm_out_file, "\t.ascii \"%s\\0\"\n", exportNamesForDLL);
}
#endif
if (flag_dump_symbols)
printf ("-Fm %s\n", main_input_filename);
parse_time += get_run_time () - start_time;
parse_time -= integration_time;
parse_time -= varconst_time;
if (flag_syntax_only)
goto finish_syntax;
globals = getdecls ();
{
int len = list_length (globals);
tree *vec = (tree *) alloca (sizeof (tree) * len);
int i;
tree decl;
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[len - i - 1] = decl;
wrapup_global_declarations (vec, len);
output_func_start_profiler ();
output_exception_table ();
check_global_declarations (vec, len);
}
weak_finish ();
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
TIMEVAR (symout_time,
{
dbxout_finish (asm_out_file, main_input_filename);
});
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
TIMEVAR (symout_time,
{
dwarfout_finish ();
});
#endif
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_frame ())
dwarf2out_frame_finish ();
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
TIMEVAR (symout_time,
{
dwarf2out_finish ();
});
#endif
#ifdef MACHO_PIC
TIMEVAR (symout_time,
{
machopic_finish (asm_out_file);
});
#endif
end_final (dump_base_name);
if (branch_prob_dump)
open_dump_file (".bp", NULL);
TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
if (branch_prob_dump)
close_dump_file (NULL, NULL_RTX);
#ifdef ASM_FILE_END
ASM_FILE_END (asm_out_file);
#endif
finish_syntax:
lang_finish ();
if (flag_gen_aux_info)
{
fclose (aux_info_file);
if (errorcount)
unlink (aux_info_file_name);
}
if (combine_dump)
{
open_dump_file (".combine", NULL);
TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
close_dump_file (NULL, NULL_RTX);
}
finish_parse ();
if (! flag_syntax_only
&& (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
fatal_io_error (asm_file_name);
if (graph_dump_format != no_graph)
{
if (jump_opt_dump)
finish_graph_dump_file (dump_base_name, ".jump");
if (addressof_dump)
finish_graph_dump_file (dump_base_name, ".addressof");
if (cse_dump)
finish_graph_dump_file (dump_base_name, ".cse");
if (loop_dump)
finish_graph_dump_file (dump_base_name, ".loop");
if (cse2_dump)
finish_graph_dump_file (dump_base_name, ".cse2");
if (branch_prob_dump)
finish_graph_dump_file (dump_base_name, ".bp");
if (flow_dump)
finish_graph_dump_file (dump_base_name, ".flow");
if (combine_dump)
finish_graph_dump_file (dump_base_name, ".combine");
if (regmove_dump)
finish_graph_dump_file (dump_base_name, ".regmove");
if (sched_dump)
finish_graph_dump_file (dump_base_name, ".sched");
if (local_reg_dump)
finish_graph_dump_file (dump_base_name, ".lreg");
if (global_reg_dump)
finish_graph_dump_file (dump_base_name, ".greg");
if (flow2_dump)
finish_graph_dump_file (dump_base_name, ".flow2");
if (sched2_dump)
finish_graph_dump_file (dump_base_name, ".sched2");
if (jump2_opt_dump)
finish_graph_dump_file (dump_base_name, ".jump2");
#ifdef DELAY_SLOTS
if (dbr_sched_dump)
finish_graph_dump_file (dump_base_name, ".dbr");
#endif
if (gcse_dump)
finish_graph_dump_file (dump_base_name, ".gcse");
#ifdef STACK_REGS
if (stack_reg_dump)
finish_graph_dump_file (dump_base_name, ".stack");
#endif
#ifdef MACHINE_DEPENDENT_REORG
if (mach_dep_reorg_dump)
finish_graph_dump_file (dump_base_name, ".mach");
#endif
}
free_reg_info ();
if (! quiet_flag)
{
fprintf (stderr,"\n");
print_time ("parse", parse_time);
print_time ("integration", integration_time);
print_time ("jump", jump_time);
print_time ("cse", cse_time);
print_time ("gcse", gcse_time);
print_time ("loop", loop_time);
print_time ("cse2", cse2_time);
print_time ("branch-prob", branch_prob_time);
print_time ("flow", flow_time);
print_time ("combine", combine_time);
print_time ("regmove", regmove_time);
print_time ("sched", sched_time);
print_time ("local-alloc", local_alloc_time);
print_time ("global-alloc", global_alloc_time);
print_time ("flow2", flow2_time);
print_time ("sched2", sched2_time);
#ifdef DELAY_SLOTS
print_time ("dbranch", dbr_sched_time);
#endif
print_time ("shorten-branch", shorten_branch_time);
print_time ("stack-reg", stack_reg_time);
print_time ("final", final_time);
print_time ("varconst", varconst_time);
print_time ("symout", symout_time);
print_time ("dump", dump_time);
}
}
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
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|| TREE_CODE (decl) == FUNCTION_DECL)
TIMEVAR (varconst_time,
{
make_decl_rtl (decl, asmspec, top_level);
if (! (TREE_CODE (decl) == VAR_DECL
&& DECL_EXTERNAL (decl) && TREE_READONLY (decl)
&& DECL_INITIAL (decl) != 0
&& DECL_INITIAL (decl) != error_mark_node))
if (! (! at_end && top_level
&& (DECL_INITIAL (decl) == 0
|| DECL_INITIAL (decl) == error_mark_node)))
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);
}
});
else if (DECL_REGISTER (decl) && asmspec != 0)
{
if (decode_reg_name (asmspec) >= 0)
{
DECL_RTL (decl) = 0;
make_decl_rtl (decl, asmspec, top_level);
}
else
error ("invalid register name `%s' for register variable", asmspec);
}
#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 (symout_time, dbxout_symbol (decl, 0));
#endif
#ifdef SDB_DEBUGGING_INFO
else if (write_symbols == SDB_DEBUG && top_level
&& TREE_CODE (decl) == TYPE_DECL)
TIMEVAR (symout_time, sdbout_symbol (decl, 0));
#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 defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
#endif
}
void
rest_of_compilation (decl)
tree decl;
{
register rtx insns;
int start_time = get_run_time ();
int tem;
tree saved_block_tree = 0;
tree saved_arguments = 0;
int failure = 0;
int rebuild_label_notes_after_reload;
if (DECL_SAVED_INSNS (decl) == 0)
{
int inlinable = 0;
const char *lose;
#ifdef NEXT_SEMANTICS
#define OPTIMIZE_FLAG flag_keep_inline_functions
#else
#define OPTIMIZE_FLAG ! optimize
#endif
if (DECL_INLINE (decl) || flag_inline_functions)
TIMEVAR (integration_time,
{
lose = function_cannot_inline_p (decl);
if (lose || OPTIMIZE_FLAG)
{
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
inlinable = DECL_INLINE (decl) = 1;
});
insns = get_insns ();
if (rtl_dump)
{
open_dump_file (".rtl", decl_printable_name (decl, 2));
if (DECL_SAVED_INSNS (decl))
fprintf (rtl_dump_file, ";; (integrable)\n\n");
close_dump_file (print_rtl, insns);
}
if (inlinable && ! decl_function_context (decl))
DECL_DEFER_OUTPUT (decl) = 1;
if (inlinable)
{
if (decl_function_context (decl))
purge_addressof (insns);
else
DECL_DEFER_OUTPUT (decl) = 1;
}
if (! current_function_contains_functions
&& (DECL_DEFER_OUTPUT (decl)
|| (DECL_INLINE (decl)
&& ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
&& ! flag_keep_inline_functions)
|| DECL_EXTERNAL (decl)))))
{
DECL_DEFER_OUTPUT (decl) = 1;
if (warn_return_type)
{
int saved_optimize = optimize;
optimize = 0;
find_exception_handler_labels ();
jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN);
optimize = saved_optimize;
}
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
set_decl_abstract_flags (decl, 1);
TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
set_decl_abstract_flags (decl, 0);
}
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
{
set_decl_abstract_flags (decl, 1);
TIMEVAR (symout_time, dwarf2out_decl (decl));
set_decl_abstract_flags (decl, 0);
}
#endif
TIMEVAR (integration_time, save_for_inline_nocopy (decl));
RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
goto exit_rest_of_compilation;
}
if (inlinable || DECL_DEFER_OUTPUT (decl))
{
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
set_decl_abstract_flags (decl, 1);
TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
set_decl_abstract_flags (decl, 0);
}
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
{
set_decl_abstract_flags (decl, 1);
TIMEVAR (symout_time, dwarf2out_decl (decl));
set_decl_abstract_flags (decl, 0);
}
#endif
saved_block_tree = DECL_INITIAL (decl);
saved_arguments = DECL_ARGUMENTS (decl);
TIMEVAR (integration_time, save_for_inline_copying (decl));
RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
}
if (DECL_EXTERNAL (decl))
goto exit_rest_of_compilation;
}
if (! DECL_DEFER_OUTPUT (decl))
TREE_ASM_WRITTEN (decl) = 1;
rtx_equal_function_value_matters = 0;
if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
{
goto exit_rest_of_compilation;
}
emit_eh_context ();
#ifdef FINALIZE_PIC
if (flag_pic)
FINALIZE_PIC;
#endif
rtl_in_current_obstack ();
insns = get_insns ();
unshare_all_rtl (insns);
#ifdef SETJMP_VIA_SAVE_AREA
if (current_function_calls_alloca)
optimize_save_area_alloca (insns);
#endif
instantiate_virtual_regs (current_function_decl, get_insns ());
find_exception_handler_labels ();
TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
JUMP_AFTER_REGSCAN));
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
goto exit_rest_of_compilation;
if (jump_opt_dump)
dump_rtl (".jump", decl, print_rtl, insns);
if (optimize > 0)
{
if (cse_dump)
open_dump_file (".cse", decl_printable_name (decl, 2));
TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
if (flag_thread_jumps)
TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
0, rtl_dump_file));
TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
if (tem || optimize > 1)
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
!JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN));
if (cse_dump)
{
close_dump_file (print_rtl, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
}
}
purge_addressof (insns);
reg_scan (insns, max_reg_num (), 1);
if (addressof_dump)
{
dump_rtl (".addressof", decl, print_rtl, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
}
if (optimize > 0 && flag_gcse)
{
if (gcse_dump)
open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
if (tem)
{
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
!JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN));
}
if (gcse_dump)
{
close_dump_file (print_rtl, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
}
}
if (optimize > 0)
{
if (loop_dump)
open_dump_file (".loop", decl_printable_name (decl, 2));
TIMEVAR
(loop_time,
{
if (flag_rerun_loop_opt)
{
loop_optimize (insns, rtl_dump_file, 0, 0);
delete_trivially_dead_insns (insns, max_reg_num ());
reg_scan (insns, max_reg_num (), 1);
}
loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
});
if (loop_dump)
{
close_dump_file (print_rtl, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
}
}
if (optimize > 0)
{
if (cse2_dump)
open_dump_file (".cse2", decl_printable_name (decl, 2));
if (flag_rerun_cse_after_loop)
{
TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
!JUMP_NOOP_MOVES,
JUMP_AFTER_REGSCAN));
TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
1, rtl_dump_file));
if (tem)
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
!JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN));
}
if (flag_thread_jumps)
{
TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
}
if (cse2_dump)
{
close_dump_file (print_rtl, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
}
}
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
if (branch_prob_dump)
open_dump_file (".bp", decl_printable_name (decl, 2));
TIMEVAR
(branch_prob_time,
{
branch_prob (insns, rtl_dump_file);
});
if (branch_prob_dump)
{
close_dump_file (print_rtl, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
}
}
cse_not_expected = 1;
if (optimize > 0)
obey_regdecls = 0;
regclass_init ();
if (flow_dump)
open_dump_file (".flow", decl_printable_name (decl, 2));
if (obey_regdecls)
{
TIMEVAR (flow_time,
{
regclass (insns, max_reg_num ());
stupid_life_analysis (insns, max_reg_num (),
rtl_dump_file);
});
}
else
{
TIMEVAR
(flow_time,
{
find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
});
if (warn_uninitialized)
{
uninitialized_vars_warning (DECL_INITIAL (decl));
setjmp_args_warning ();
}
}
if (flow_dump)
{
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
}
no_new_pseudos = 1;
if (optimize > 0)
{
TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
if (combine_dump)
{
dump_rtl (".combine", decl, print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
}
}
if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
{
if (regmove_dump)
open_dump_file (".regmove", decl_printable_name (decl, 2));
TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
rtl_dump_file));
if (regmove_dump)
{
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
}
}
if (optimize > 0 && flag_schedule_insns)
{
if (sched_dump)
open_dump_file (".sched", decl_printable_name (decl, 2));
TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
if (sched_dump)
{
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
}
}
current_function_is_leaf = leaf_function_p ();
if (!obey_regdecls)
TIMEVAR (local_alloc_time,
{
recompute_reg_usage (insns, ! optimize_size);
regclass (insns, max_reg_num ());
rebuild_label_notes_after_reload = local_alloc ();
});
else
rebuild_label_notes_after_reload = 0;
if (local_reg_dump)
{
open_dump_file (".lreg", decl_printable_name (decl, 2));
TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
}
if (global_reg_dump)
open_dump_file (".greg", decl_printable_name (decl, 2));
TIMEVAR (global_alloc_time,
{
if (!obey_regdecls)
failure = global_alloc (rtl_dump_file);
else
failure = reload (insns, 0, rtl_dump_file);
});
if (failure)
goto exit_rest_of_compilation;
if (optimize > 0)
reload_cse_regs (insns);
if (rebuild_label_notes_after_reload)
TIMEVAR (jump_time, rebuild_jump_labels (insns));
if (optimize > 0 && flag_schedule_insns_after_reload)
{
rtx insn;
for (insn = insns; insn; insn = NEXT_INSN (insn))
{
rtx last;
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
continue;
last = try_split (PATTERN (insn), insn, 1);
if (last != insn)
{
PUT_CODE (insn, NOTE);
NOTE_SOURCE_FILE (insn) = 0;
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
}
}
}
if (global_reg_dump)
{
TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
}
if (flow2_dump)
open_dump_file (".flow2", decl_printable_name (decl, 2));
if (optimize)
{
TIMEVAR
(flow2_time,
{
find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
});
}
flow2_completed = 1;
thread_prologue_and_epilogue_insns (insns);
if (flow2_dump)
{
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
}
if (optimize > 0 && flag_schedule_insns_after_reload)
{
if (sched2_dump)
open_dump_file (".sched2", decl_printable_name (decl, 2));
TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
if (sched2_dump)
{
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
}
}
#ifdef LEAF_REGISTERS
current_function_uses_only_leaf_regs
= optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
#endif
if (optimize > 0)
{
TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN));
if (jump2_opt_dump)
{
dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
}
}
#ifdef MACHINE_DEPENDENT_REORG
MACHINE_DEPENDENT_REORG (insns);
if (mach_dep_reorg_dump)
{
dump_rtl (".mach", decl, print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
}
#endif
#ifdef DELAY_SLOTS
if (optimize > 0 && flag_delayed_branch)
{
if (dbr_sched_dump)
open_dump_file (".dbr", decl_printable_name (decl, 2));
TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
if (dbr_sched_dump)
{
close_dump_file (print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
}
}
#endif
TIMEVAR (shorten_branch_time,
{
shorten_branches (get_insns ());
});
#ifdef STACK_REGS
if (stack_reg_dump)
open_dump_file (".stack", decl_printable_name (decl, 2));
TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
if (stack_reg_dump)
{
dump_rtl (".stack", decl, print_rtl_with_bb, insns);
if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
}
#endif
#ifdef HAVE_COALESCED_SYMBOLS
old_write_symbols = write_symbols;
if (DECL_COALESCED (decl))
write_symbols = NO_DEBUG;
#endif
TIMEVAR (final_time,
{
rtx x;
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 (insns, asm_out_file, optimize);
assemble_end_function (decl, fnname);
if (! quiet_flag)
fflush (asm_out_file);
free_basic_block_vars (0);
regset_release_memory ();
});
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
TIMEVAR (symout_time, dbxout_function (decl));
#endif
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (write_symbols == DWARF2_DEBUG)
TIMEVAR (symout_time, dwarf2out_decl (decl));
#endif
#ifdef HAVE_COALESCED_SYMBOLS
write_symbols = old_write_symbols;
#endif
exit_rest_of_compilation:
free_bb_mem ();
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
sdbout_types (NULL_TREE);
#endif
if (saved_block_tree != 0)
{
DECL_INITIAL (decl) = saved_block_tree;
DECL_ARGUMENTS (decl) = saved_arguments;
DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
}
reload_completed = 0;
flow2_completed = 0;
no_new_pseudos = 0;
TIMEVAR (final_time,
{
init_insn_lengths ();
clear_const_double_mem ();
resume_temporary_allocation ();
init_temp_slots ();
});
init_recog_no_volatile ();
parse_time -= get_run_time () - start_time;
free_basic_block_vars (0);
}
static void
display_help ()
{
int undoc;
unsigned long i;
const char * lang;
#ifndef USE_CPPLIB
printf ("Usage: %s input [switches]\n", progname);
printf ("Switches:\n");
#endif
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");
for (i = NUM_ELEM (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 optimisation level to [number]\n");
printf (" -Os Optimise for space rather than speed\n");
printf (" -pedantic Issue warnings needed by strict compliance to ANSI 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 = NUM_ELEM (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 (" -Wid-clash-<num> Warn if 2 identifiers have the same first <num> chars\n");
printf (" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n");
printf (" -p Enable function profiling\n");
#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
printf (" -a Enable block profiling \n");
#endif
#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
printf (" -ax Enable jump profiling \n");
#endif
printf (" -o <file> Place output into <file> \n");
printf (" -G <number> Put global and static data smaller than <number>\n");
printf (" bytes into a special section (on some targets)\n");
for (i = NUM_ELEM (debug_args); i--;)
{
if (debug_args[i].description != NULL)
printf (" -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
}
printf (" -aux-info <file> Emit declaration info into <file>.X\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 HAIFA || defined INSN_SCHEDULING
printf (" -sched-verbose-<number> Set the verbosity level of the scheduler\n");
#endif
printf (" --help Display this information\n");
undoc = 0;
lang = "language";
if (NUM_ELEM (documented_lang_options) > 1)
{
printf ("\nLanguage specific options:\n");
for (i = 0; i < NUM_ELEM (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);
if (NUM_ELEM (target_switches) > 1
#ifdef TARGET_OPTIONS
|| NUM_ELEM (target_options) > 1
#endif
)
{
int doc = 0;
undoc = 0;
printf ("\nTarget specific options:\n");
for (i = NUM_ELEM (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%-21.21s [undocumented]\n", option);
}
else if (* description != 0)
doc += printf (" -m%-21.21s %s\n", option, description);
}
#ifdef TARGET_OPTIONS
for (i = NUM_ELEM (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%-21.21s [undocumented]\n", option);
}
else if (* description != 0)
doc += printf (" -m%-21.21s %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 int
check_lang_option (option, lang_option)
char * option;
char * lang_option;
{
lang_independent_options * indep_options;
int len;
long k;
char * space;
if (option == NULL || lang_option == NULL)
return 0;
if ((space = strchr (lang_option, ' ')) != NULL)
len = space - lang_option;
else
len = strlen (lang_option);
if (strncmp (option, lang_option, len) != 0)
return 0;
if ((int) strlen (option) == len)
return 1;
if (option[0] != '-')
return 1;
switch (option[1])
{
case 'f': indep_options = f_options; break;
case 'W': indep_options = W_options; break;
default: return 1;
}
option += 2;
if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
option += 3;
for (k = NUM_ELEM (indep_options); k--;)
{
if (!strcmp (option, indep_options[k].string))
{
return 0;
}
}
return 1;
}
int
main (argc, argv)
int argc;
char **argv;
{
register int i;
char *filename = 0;
int flag_print_mem = 0;
int version_flag = 0;
char *p;
save_argc = argc;
save_argv = argv;
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && p[-1] != '/'
#ifdef DIR_SEPARATOR
&& p[-1] != DIR_SEPARATOR
#endif
)
--p;
progname = p;
#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
{
struct rlimit rlim;
getrlimit (RLIMIT_STACK, &rlim);
rlim.rlim_cur = rlim.rlim_max;
setrlimit (RLIMIT_STACK, &rlim);
}
#endif
#ifdef HAVE_LC_MESSAGES
setlocale (LC_MESSAGES, "");
#endif
(void) bindtextdomain (PACKAGE, localedir);
(void) textdomain (PACKAGE);
signal (SIGFPE, float_signal);
#ifdef SIGPIPE
signal (SIGPIPE, pipe_closed);
#endif
decl_printable_name = decl_name;
lang_expand_expr = (lang_expand_expr_t) do_abort;
flag_signed_char = DEFAULT_SIGNED_CHAR;
#ifdef DEFAULT_SHORT_ENUMS
flag_short_enums = DEFAULT_SHORT_ENUMS;
#endif
lang_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;
}
}
}
}
#if defined (MACHO_PIC) && defined (I386)
if (optimize >= 2)
optimize = 2;
else
optimize = 0;
#endif
obey_regdecls = (optimize == 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
}
if (optimize >= 2)
{
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;
#ifdef INSN_SCHEDULING
flag_schedule_insns = 1;
flag_schedule_insns_after_reload = 1;
#endif
flag_regmove = 1;
}
if (optimize >= 3)
{
flag_inline_functions = 1;
}
target_flags = 0;
set_target_switch ("");
#ifdef OPTIMIZATION_OPTIONS
OPTIMIZATION_OPTIONS (optimize, optimize_size);
#endif
init_reg_sets ();
for (i = 1; i < argc; i++)
{
size_t j;
for (j = NUM_ELEM (documented_lang_options); j--;)
if (check_lang_option (argv[i], documented_lang_options[j].option))
break;
if (j != (size_t)-1)
{
int strings_processed = lang_decode_option (argc - i, argv + i);
if (!strcmp (argv[i], "--help"))
{
display_help ();
exit (0);
}
if (strings_processed != 0)
i += strings_processed - 1;
}
else if (argv[i][0] == '-' && argv[i][1] != 0)
{
register char *str = argv[i] + 1;
if (str[0] == 'Y')
str++;
if (str[0] == 'm')
set_target_switch (&str[1]);
else if (!strcmp (str, "dumpbase"))
{
dump_base_name = argv[++i];
}
else if (str[0] == 'd')
{
register char *p = &str[1];
#ifdef _WIN32
if (strcmp (str, "dll") && strcmp (str, "dynamic"))
#endif
while (*p)
switch (*p++)
{
case 'a':
branch_prob_dump = 1;
combine_dump = 1;
#ifdef DELAY_SLOTS
dbr_sched_dump = 1;
#endif
#ifdef NEXT_SEMANTICS
fppc_dump = 1;
#endif
flow_dump = 1;
flow2_dump = 1;
global_reg_dump = 1;
jump_opt_dump = 1;
addressof_dump = 1;
jump2_opt_dump = 1;
local_reg_dump = 1;
loop_dump = 1;
regmove_dump = 1;
rtl_dump = 1;
cse_dump = 1, cse2_dump = 1;
gcse_dump = 1;
sched_dump = 1;
sched2_dump = 1;
#ifdef STACK_REGS
stack_reg_dump = 1;
#endif
#ifdef MACHINE_DEPENDENT_REORG
mach_dep_reorg_dump = 1;
#endif
break;
case 'A':
flag_debug_asm = 1;
break;
case 'b':
branch_prob_dump = 1;
break;
case 'c':
combine_dump = 1;
break;
#ifdef DELAY_SLOTS
case 'd':
dbr_sched_dump = 1;
break;
#endif
case 'f':
flow_dump = 1;
break;
case 'F':
addressof_dump = 1;
break;
case 'g':
global_reg_dump = 1;
break;
case 'G':
gcse_dump = 1;
break;
case 'j':
jump_opt_dump = 1;
break;
case 'J':
jump2_opt_dump = 1;
break;
#ifdef STACK_REGS
case 'k':
stack_reg_dump = 1;
break;
#endif
case 'l':
local_reg_dump = 1;
break;
case 'L':
loop_dump = 1;
break;
case 'm':
flag_print_mem = 1;
break;
#ifdef MACHINE_DEPENDENT_REORG
case 'M':
mach_dep_reorg_dump = 1;
break;
#endif
case 'p':
flag_print_asm_name = 1;
break;
case 'r':
rtl_dump = 1;
break;
case 'R':
sched2_dump = 1;
break;
case 's':
cse_dump = 1;
break;
case 'S':
sched_dump = 1;
break;
case 't':
cse2_dump = 1;
break;
case 'N':
regmove_dump = 1;
break;
case 'v':
graph_dump_format = vcg;
break;
case 'w':
flow2_dump = 1;
break;
case 'y':
set_yydebug (1);
break;
#ifdef NEXT_SEMANTICS
case 'P':
fppc_dump = 1;
break;
#endif
case 'x':
rtl_dump_and_exit = 1;
break;
case 'D':
case 'I':
break;
default:
warning ("unrecognised gcc debugging option: %c", p[-1]);
break;
}
}
else if (str[0] == 'f')
{
register char *p = &str[1];
int found = 0;
for (j = 0;
!found && j < sizeof (f_options) / sizeof (f_options[0]);
j++)
{
if (!strcmp (p, f_options[j].string))
{
*f_options[j].variable = f_options[j].on_value;
found = 1;
}
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
&& ! strcmp (p+3, f_options[j].string))
{
*f_options[j].variable = ! f_options[j].on_value;
found = 1;
}
}
if (found)
;
else if (!strncmp (p, "inline-limit-", 13))
inline_max_insns =
read_integral_parameter (p + 13, p - 2, inline_max_insns);
#ifdef HAIFA
#ifdef INSN_SCHEDULING
else if (!strncmp (p, "sched-verbose-",14))
fix_sched_param("verbose",&p[14]);
#endif
#endif
else if (!strncmp (p, "fixed-", 6))
fix_register (&p[6], 1, 1);
else if (!strncmp (p, "call-used-", 10))
fix_register (&p[10], 0, 1);
else if (!strncmp (p, "call-saved-", 11))
fix_register (&p[11], 0, 0);
#ifdef NEXT_FAT_OUTPUT
else if (!strncmp (p, "orce_cpusubtype_ALL", 19))
;
#endif
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
else if (!strncmp (p, "ramework", 8))
{
if (i + 1 < argc)
i++;
else
error ("Missing argument to -framework");
}
else if (!strncmp (p, "ilelist", 7))
{
if (i + 1 < argc)
i++;
else
error ("Missing argument to -filelist");
}
#endif
else
error ("Invalid option `%s'", argv[i]);
}
else if (str[0] == 'O')
{
}
else if (!strcmp (str, "pedantic"))
pedantic = 1;
else if (!strcmp (str, "pedantic-errors"))
flag_pedantic_errors = pedantic = 1;
#ifdef NEXT_FAT_OUTPUT
else if (!strcmp (str, "arch"))
{
if (i + 1 < argc)
architecture = argv[++i];
else
error ("Missing argument to -arch");
}
#endif
else if (!strcmp (str, "quiet"))
quiet_flag = 1;
else if (!strcmp (str, "version"))
version_flag = 1;
else if (!strcmp (str, "w"))
inhibit_warnings = 1;
else if (!strcmp (str, "W"))
{
extra_warnings = 1;
if (warn_uninitialized != 1)
warn_uninitialized = 2;
}
else if (str[0] == 'W')
{
register char *p = &str[1];
int found = 0;
for (j = 0;
!found && j < sizeof (W_options) / sizeof (W_options[0]);
j++)
{
if (!strcmp (p, W_options[j].string))
{
#ifdef NEXT_SEMANTICS
if (W_options[j].variable)
#endif
*W_options[j].variable = W_options[j].on_value;
found = 1;
}
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
&& ! strcmp (p+3, W_options[j].string))
{
#ifdef NEXT_SEMANTICS
if (W_options[j].variable)
#endif
*W_options[j].variable = ! W_options[j].on_value;
found = 1;
}
}
if (found)
;
else if (!strncmp (p, "id-clash-", 9))
{
const int id_clash_val
= read_integral_parameter (p + 9, p - 2, -1);
if (id_clash_val != -1)
{
id_clash_len = id_clash_val;
warn_id_clash = 1;
}
}
else if (!strncmp (p, "larger-than-", 12))
{
const int larger_than_val
= read_integral_parameter (p + 12, p - 2, -1);
if (larger_than_val != -1)
{
larger_than_size = larger_than_val;
warn_larger_than = 1;
}
}
else
error ("Invalid option `%s'", argv[i]);
}
else if (!strcmp (str, "p"))
{
profile_flag = 1;
}
else if (!strcmp (str, "a"))
{
#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
warning ("`-a' option (basic block profile) not supported");
#else
profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
#endif
}
else if (!strcmp (str, "ax"))
{
#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
warning ("`-ax' option (jump profiling) not supported");
#else
profile_block_flag = (!profile_block_flag
|| profile_block_flag == 2) ? 2 : 3;
#endif
}
else if (str[0] == 'g')
{
unsigned level;
static enum debug_info_type selected_debug_type = NO_DEBUG;
static int type_explicitly_set_p = 0;
static const char *debug_type_names[] =
{
"none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
};
static const unsigned max_debug_level = 3;
for (da = debug_args; da->arg; da++)
{
const int da_len = strlen (da->arg);
if (! strncmp (str, da->arg, da_len))
{
enum debug_info_type type = da->debug_type;
const char *p = str + da_len;
if (*p && (*p < '0' || *p > '9'))
continue;
if (*p)
level = read_integral_parameter (p, 0,
max_debug_level + 1);
else
level = 2;
if (da_len > 1 && *p && !strncmp (str, "gdwarf", 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",
str - 1);
level = debug_info_level;
}
if (type == NO_DEBUG)
{
type = PREFERRED_DEBUGGING_TYPE;
if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
{
#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
type = DWARF2_DEBUG;
#else
#ifdef DBX_DEBUGGING_INFO
type = DBX_DEBUG;
#endif
#endif
}
}
if (type == NO_DEBUG)
warning ("`-%s' not supported by this configuration of GCC",
str);
if (type_explicitly_set_p
&& da->debug_type != NO_DEBUG
&& type != selected_debug_type)
warning ("`-%s' ignored, conflicts with `-g%s'",
str, 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;
}
}
if (! da->arg)
warning ("`-%s' not supported by this configuration of GCC",
str);
}
else if (!strcmp (str, "o"))
{
asm_file_name = argv[++i];
}
else if (str[0] == 'G')
{
const int g_switch_val = (str[1] != '\0') ?
read_integral_parameter(str + 1, 0, -1) :
read_integral_parameter(argv[++i], 0, -1);
if (g_switch_val != -1)
{
g_switch_set = TRUE;
g_switch_value = g_switch_val;
}
else
{
error("Invalid option `-%s'",str);
}
}
else if (!strncmp (str, "aux-info", 8))
{
flag_gen_aux_info = 1;
aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
}
else if (!strcmp (str, "-help"))
{
display_help ();
exit (0);
}
else
error ("Invalid option `%s'", argv[i]);
}
else if (argv[i][0] == '+')
error ("Invalid option `%s'", argv[i]);
else
filename = argv[i];
}
if (flag_check_memory_usage)
flag_omit_frame_pointer = 0;
if (optimize == 0)
{
flag_no_inline = 1;
warn_inline = 0;
if (warn_uninitialized == 1)
warning ("-Wuninitialized is not supported without -O");
}
#ifdef OVERRIDE_OPTIONS
OVERRIDE_OPTIONS;
#endif
if (exceptions_via_longjmp == 2)
{
#ifdef DWARF2_UNWIND_INFO
exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
#else
exceptions_via_longjmp = 1;
#endif
}
if (profile_block_flag == 3)
{
warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
profile_block_flag = 2;
}
if (flag_unroll_all_loops)
flag_unroll_loops = 1;
if (flag_unroll_loops)
{
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 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");
}
compile_file (filename);
#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
if (flag_print_mem)
{
char *lim = (char *) sbrk (0);
notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
fflush (stderr);
#ifndef __MSDOS__
#ifdef USG
system ("ps -l 1>&2");
#else
system ("ps v");
#endif
#endif
}
#endif
if (errorcount)
exit (FATAL_EXIT_CODE);
if (sorrycount)
exit (FATAL_EXIT_CODE);
exit (SUCCESS_EXIT_CODE);
return 0;
}
static void
set_target_switch (name)
const char *name;
{
register size_t j;
int valid_target_option = 0;
for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; 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;
valid_target_option = 1;
}
#ifdef TARGET_OPTIONS
if (!valid_target_option)
for (j = 0; j < sizeof target_options / sizeof target_options[0]; 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
#ifdef NEXT_FAT_OUTPUT
if (!valid_target_option && architecture)
{
int len = strlen (architecture);
if (! strncmp (name, architecture, len) && name[len] == ':')
{
if (getenv ("DEBUGING_GCC"))
printf ("applying -m%s for arch %s\n", name + len, architecture);
set_target_switch (name + len + 1);
return;
}
}
#ifdef DEFAULT_TARGET_ARCH
if (!valid_target_option && !architecture)
{
int len = strlen (DEFAULT_TARGET_ARCH);
if (! strncmp (name, DEFAULT_TARGET_ARCH, len) && name[len] == ':')
{
if (getenv ("DEBUGGING_GCC"))
printf ("applying -m%s for arch %s\n", name + len,
DEFAULT_TARGET_ARCH);
set_target_switch (name + len + 1);
return;
}
}
#endif
if (! valid_target_option)
{
NXArchInfo *info = (NXArchInfo*) NXGetAllArchInfos ();
register int j;
for (j = 0; info[j].name; j++)
{
int len = strlen (info[j].name);
if (! strncmp (name, info[j].name, len)
&& name[len] == ':')
{
if (getenv ("DEBUGGING_GCC"))
printf ("ignoring -m%s for arch %s\n",
name + len + 1,
info[j].name);
return;
}
}
}
if (!valid_target_option && !architecture)
#else
if (!valid_target_option)
#endif
error ("Invalid option `%s'", name);
}
#ifdef NEXT_FAT_OUTPUT
void
set_target_architecture (name)
const char *name;
{
static struct {
char *name;
int value;
} target_arch [] = TARGET_ARCHITECTURE;
register int j;
int found = 0;
if (name == 0) return;
for (j = 0; j < sizeof target_arch / sizeof target_arch[0]; j++)
{
if (!strcmp (target_arch[j].name, name))
{
if (target_arch[j].value < 0)
target_flags &= ~-target_arch[j].value;
else
target_flags |= target_arch[j].value;
found = 1;
}
}
if (!found)
warning ("-arch `%s' not understood", name);
}
#endif
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) compiled by GNU C version %s.\n"
#else
"%s%s%s version %s (%s) compiled by CC.\n"
#endif
, indent, *indent != 0 ? " " : "",
language_string, version_string, TARGET_NAME, __VERSION__);
}
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 < sizeof f_options / sizeof f_options[0]; 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 < sizeof target_switches / sizeof target_switches[0]; 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 < sizeof target_options / sizeof target_options[0]; 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);
}
void
debug_start_source_file (filename)
register char *filename ATTRIBUTE_UNUSED;
{
if (flag_dump_symbols)
printf ("<Fm %s\n", filename);
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
dbxout_start_new_source_file (filename);
#endif
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF_DEBUG)
dwarfout_start_new_source_file (filename);
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF2_DEBUG)
dwarf2out_start_source_file (filename);
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
sdbout_start_new_source_file (filename);
#endif
}
void
debug_end_source_file (lineno)
register unsigned lineno ATTRIBUTE_UNUSED;
{
if (flag_dump_symbols)
printf ("-Fm %u\n", lineno);
#ifdef DBX_DEBUGGING_INFO
if (write_symbols == DBX_DEBUG)
dbxout_resume_previous_source_file ();
#endif
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF_DEBUG)
dwarfout_resume_previous_source_file (lineno);
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF2_DEBUG)
dwarf2out_end_source_file ();
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
sdbout_resume_previous_source_file ();
#endif
}
void
debug_define (lineno, buffer)
register unsigned lineno ATTRIBUTE_UNUSED;
register char *buffer ATTRIBUTE_UNUSED;
{
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF_DEBUG)
dwarfout_define (lineno, buffer);
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF2_DEBUG)
dwarf2out_define (lineno, buffer);
#endif
}
void
debug_undef (lineno, buffer)
register unsigned lineno ATTRIBUTE_UNUSED;
register char *buffer ATTRIBUTE_UNUSED;
{
#ifdef DWARF_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF_DEBUG)
dwarfout_undef (lineno, buffer);
#endif
#ifdef DWARF2_DEBUGGING_INFO
if (debug_info_level == DINFO_LEVEL_VERBOSE
&& write_symbols == DWARF2_DEBUG)
dwarf2out_undef (lineno, buffer);
#endif
}