#include <sys/types.h>
#include <ctype.h>
#include <sys/stat.h>
-
-#ifndef _WIN32
+#if !defined (_WIN32) || defined (__CYGWIN32__)
#ifdef USG
#undef FLOAT
#include <sys/param.h>
#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
#endif
-#ifdef DWARF2_DEBUGGING_INFO
-#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-#endif
-
extern int rtx_equal_function_value_matters;
#if ! (defined (VMS) || defined (OS2))
int branch_prob_dump = 0;
int flow_dump = 0;
int combine_dump = 0;
+int regmove_dump = 0;
int sched_dump = 0;
int local_reg_dump = 0;
int global_reg_dump = 0;
int flag_unroll_all_loops;
+/* Nonzero forces all invariant computations in loops to be moved
+ outside the loop. */
+
+int flag_move_all_movables = 0;
+
+/* Nonzero forces all general induction variables in loops to be
+ strength reduced. */
+
+int flag_reduce_all_givs = 0;
+
/* Nonzero for -fwritable-strings:
store string constants in data segment and don't uniquize them. */
static int flag_rerun_cse_after_loop;
+/* Nonzero means to run loop optimizations twice. */
+
+int flag_rerun_loop_opt;
+
/* Nonzero for -finline-functions: ok to inline functions that look like
good inline candidates. */
/* Nonzero means generate extra code for exception handling and enable
exception handling. */
-int flag_exceptions = 1;
+int flag_exceptions = 2;
/* Nonzero means don't place uninitialized global data in common storage
by default. */
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
+#ifdef HAIFA
+/* The following flags have effect only for scheduling before register
+ allocation:
+
+ flag_schedule_interblock means schedule insns accross basic blocks.
+ flag_schedule_speculative means allow speculative motion of non-load insns.
+ flag_schedule_speculative_load means allow speculative motion of some
+ load insns.
+ flag_schedule_speculative_load_dangerous allows speculative motion of more
+ load insns.
+ flag_schedule_reverse_before_reload means try to reverse original order
+ of insns (S).
+ flag_schedule_reverse_after_reload means try to reverse original order
+ of insns (R). */
+
+int flag_schedule_interblock = 1;
+int flag_schedule_speculative = 1;
+int flag_schedule_speculative_load = 0;
+int flag_schedule_speculative_load_dangerous = 0;
+int flag_schedule_reverse_before_reload = 0;
+int flag_schedule_reverse_after_reload = 0;
+
+
+/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
+ by a cheaper branch, on a count register. */
+int flag_branch_on_count_reg;
+#endif /* HAIFA */
+
+
/* -finhibit-size-directive inhibits output of .size for ELF.
This is used only for compiling crtstuff.c,
and it may be extended to other effects
to be allocated dynamically. */
int flag_stack_check;
+/* -fcheck-memory-usage causes extra code to be generated in order to check
+ memory accesses. This is used by a detector of bad memory accesses such
+ as Checker. */
+int flag_check_memory_usage = 0;
+
+/* -fprefix-function-name causes function name to be prefixed. This
+ can be used with -fcheck-memory-usage to isolate code compiled with
+ -fcheck-memory-usage. */
+int flag_prefix_function_name = 0;
+
+int flag_regmove = 0;
+
+/* 1 if alias checking is on (by default, when -O). */
+int flag_alias_check = 0;
+
+/* 0 if pointer arguments may alias each other. True in C.
+ 1 if pointer arguments may not alias each other but may alias
+ global variables.
+ 2 if pointer arguments may not alias each other and may not
+ alias global variables. True in Fortran.
+ This defaults to 0 for C. */
+int flag_argument_noalias = 0;
+
/* Table of language-independent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
{"strength-reduce", &flag_strength_reduce, 1},
{"unroll-loops", &flag_unroll_loops, 1},
{"unroll-all-loops", &flag_unroll_all_loops, 1},
+ {"move-all-movables", &flag_move_all_movables, 1},
+ {"reduce-all-givs", &flag_reduce_all_givs, 1},
{"writable-strings", &flag_writable_strings, 1},
{"peephole", &flag_no_peephole, 0},
{"force-mem", &flag_force_mem, 1},
{"reg-struct-return", &flag_pcc_struct_return, 0},
{"delayed-branch", &flag_delayed_branch, 1},
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
+ {"rerun-loop-opt", &flag_rerun_loop_opt, 1},
{"pretend-float", &flag_pretend_float, 1},
{"schedule-insns", &flag_schedule_insns, 1},
{"schedule-insns2", &flag_schedule_insns_after_reload, 1},
+#ifdef HAIFA
+ {"sched-interblock",&flag_schedule_interblock, 1},
+ {"sched-spec",&flag_schedule_speculative, 1},
+ {"sched-spec-load",&flag_schedule_speculative_load, 1},
+ {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1},
+ {"sched-reverse-S",&flag_schedule_reverse_before_reload, 1},
+ {"sched-reverse-R",&flag_schedule_reverse_after_reload, 1},
+ {"branch-count-reg",&flag_branch_on_count_reg, 1},
+#endif /* HAIFA */
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
{"exceptions", &flag_exceptions, 1},
{"function-sections", &flag_function_sections, 1},
{"verbose-asm", &flag_verbose_asm, 1},
{"gnu-linker", &flag_gnu_linker, 1},
+ {"regmove", &flag_regmove, 1},
{"pack-struct", &flag_pack_struct, 1},
{"stack-check", &flag_stack_check, 1},
- {"bytecode", &output_bytecode, 1}
+ {"bytecode", &output_bytecode, 1},
+ {"alias-check", &flag_alias_check, 1},
+ {"argument-alias", &flag_argument_noalias, 0},
+ {"argument-noalias", &flag_argument_noalias, 1},
+ {"argument-noalias-global", &flag_argument_noalias, 2},
+ {"check-memory-usage", &flag_check_memory_usage, 1},
+ {"prefix-function-name", &flag_prefix_function_name, 1}
};
/* Table of language-specific options. */
"-Wno-format",
"-Wimport",
"-Wno-import",
+ "-Wimplicit-function-declaration",
+ "-Wno-implicit-function-declaration",
+ "-Werror-implicit-function-declaration",
+ "-Wimplicit-int",
+ "-Wno-implicit-int",
"-Wimplicit",
"-Wno-implicit",
"-Wmain",
FILE *branch_prob_dump_file;
FILE *flow_dump_file;
FILE *combine_dump_file;
+FILE *regmove_dump_file;
FILE *sched_dump_file;
FILE *local_reg_dump_file;
FILE *global_reg_dump_file;
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
get_run_time ()
{
-#ifndef _WIN32
+#if !defined (_WIN32) || defined (__CYGWIN32__)
#ifdef USG
struct tms tms;
#else
if (quiet_flag)
return 0;
-#ifdef _WIN32
+#if defined (_WIN32) && !defined (__CYGWIN32__)
if (clock() < 0)
return 0;
else
fflush (flow_dump_file);
if (combine_dump_file)
fflush (combine_dump_file);
+ if (regmove_dump_file)
+ fflush (regmove_dump_file);
if (sched_dump_file)
fflush (sched_dump_file);
if (local_reg_dump_file)
return value;
}
-/* Same as `realloc' but report error if no memory available. */
+/* Same as `realloc' but report error if no memory available.
+ Also handle null PTR even if the vendor realloc gets it wrong. */
char *
xrealloc (ptr, size)
char *ptr;
int size;
{
- char *result = (char *) realloc (ptr, size);
+ char *result = (ptr
+ ? (char *) realloc (ptr, size)
+ : (char *) malloc (size));
if (!result)
fatal ("virtual memory exhausted");
return result;
FILE *asm_file;
char *string;
{
+#ifdef OUTPUT_QUOTED_STRING
+ OUTPUT_QUOTED_STRING (asm_file, string);
+#else
char c;
putc ('\"', asm_file);
putc (c, asm_file);
}
putc ('\"', asm_file);
+#endif
}
/* Output a file name in the form wanted by System V. */
branch_prob_time = 0;
flow_time = 0;
combine_time = 0;
+ regmove_time = 0;
sched_time = 0;
local_alloc_time = 0;
global_alloc_time = 0;
if (combine_dump)
combine_dump_file = open_dump_file (dump_base_name, ".combine");
+ /* If regmove dump desired, open the output file. */
+ if (regmove_dump)
+ regmove_dump_file = open_dump_file (dump_base_name, ".regmove");
+
/* If scheduling dump desired, open the output file. */
if (sched_dump)
sched_dump_file = open_dump_file (dump_base_name, ".sched");
input_file_stack->next = 0;
input_file_stack->name = input_filename;
+ /* Gross. Gross. lang_init is (I think) the first callback into
+ the language front end, and is thus the first opportunity to
+ have the selected language override the default value for any
+ -f option.
+
+ So the default value for flag_exceptions is 2 (uninitialized).
+ If we encounter -fno-exceptions or -fexceptions, then flag_exceptions
+ will be set to zero or one respectively.
+
+ flag_exceptions can also be set by lang_init to something other
+ than the default "uninitialized" value of 2.
+
+ After lang_init, if the value is still 2, then we default to
+ -fno-exceptions (value will be reset to zero).
+
+ When our EH mechanism is low enough overhead that we can enable
+ it by default for languages other than C++, then all this braindamage
+ will go away. */
+
/* Perform language-specific initialization.
This may set main_input_filename. */
lang_init ();
+ if (flag_exceptions == 2)
+ flag_exceptions = 0;
+
/* If the input doesn't start with a #line, use the input name
as the official input file name. */
if (main_input_filename == 0)
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));
/* Now that all possible functions have been output, we can dump
the exception table. */
- if (exception_table_p ())
- output_exception_table ();
+ output_exception_table ();
for (i = 0; i < len; i++)
{
});
#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,
fclose (combine_dump_file);
}
+ if (regmove_dump)
+ fclose (regmove_dump_file);
+
if (sched_dump)
fclose (sched_dump_file);
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);
fflush (rtl_dump_file);
});
+ /* If we can, defer compiling inlines until EOF.
+ save_for_inline_copying can be extremely expensive. */
+ if (inlineable && ! decl_function_context (decl))
+ DECL_DEFER_OUTPUT (decl) = 1;
+
/* If function is inline, and we don't yet know whether to
compile it by itself, defer decision till end of compilation.
finish_compilation will call rest_of_compilation again
finish compiling ourselves. Otherwise, wait until EOF.
We have to do this because the purge_addressof transformation
changes the DECL_RTL for many variables, which confuses integrate. */
- if (DECL_INLINE (decl))
+ if (inlineable)
{
if (decl_function_context (decl))
purge_addressof (insns);
{
TIMEVAR (loop_time,
{
- loop_optimize (insns, loop_dump_file);
+ if (flag_rerun_loop_opt)
+ {
+ /* We only want to perform unrolling once. */
+
+ loop_optimize (insns, loop_dump_file, 0);
+
+ /* The regscan pass may not be necessary, but let's
+ be safe until we can prove otherwise. */
+ reg_scan (insns, max_reg_num (), 1);
+ }
+ loop_optimize (insns, loop_dump_file, flag_unroll_loops);
});
}
if (flow_dump)
TIMEVAR (dump_time,
{
- print_rtl (flow_dump_file, insns);
+ print_rtl_with_bb (flow_dump_file, insns);
fflush (flow_dump_file);
});
fprintf (combine_dump_file, "\n;; Function %s\n\n",
(*decl_printable_name) (decl, 2));
dump_combine_stats (combine_dump_file);
- print_rtl (combine_dump_file, insns);
+ print_rtl_with_bb (combine_dump_file, insns);
fflush (combine_dump_file);
});
+ if (regmove_dump)
+ TIMEVAR (dump_time,
+ {
+ fprintf (regmove_dump_file, "\n;; Function %s\n\n",
+ (*decl_printable_name) (decl, 2));
+ });
+
+ /* Register allocation pre-pass, to reduce number of moves
+ necessary for two-address machines. */
+ if (optimize > 0 && flag_regmove)
+ TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
+ regmove_dump_file));
+
+ if (regmove_dump)
+ TIMEVAR (dump_time,
+ {
+ print_rtl_with_bb (regmove_dump_file, insns);
+ fflush (regmove_dump_file);
+ });
+
/* Print function header into sched dump now
because doing the sched analysis makes some of the dump. */
if (sched_dump)
TIMEVAR (dump_time,
{
- print_rtl (sched_dump_file, insns);
+ print_rtl_with_bb (sched_dump_file, insns);
fflush (sched_dump_file);
});
(*decl_printable_name) (decl, 2));
dump_flow_info (local_reg_dump_file);
dump_local_alloc (local_reg_dump_file);
- print_rtl (local_reg_dump_file, insns);
+ print_rtl_with_bb (local_reg_dump_file, insns);
fflush (local_reg_dump_file);
});
TIMEVAR (dump_time,
{
dump_global_regs (global_reg_dump_file);
- print_rtl (global_reg_dump_file, insns);
+ print_rtl_with_bb (global_reg_dump_file, insns);
fflush (global_reg_dump_file);
});
if (sched2_dump)
TIMEVAR (dump_time,
{
- print_rtl (sched2_dump_file, insns);
+ print_rtl_with_bb (sched2_dump_file, insns);
fflush (sched2_dump_file);
});
}
{
fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n",
(*decl_printable_name) (decl, 2));
- print_rtl (jump2_opt_dump_file, insns);
+ print_rtl_with_bb (jump2_opt_dump_file, insns);
fflush (jump2_opt_dump_file);
});
{
fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n",
(*decl_printable_name) (decl, 2));
- print_rtl (dbr_sched_dump_file, insns);
+ print_rtl_with_bb (dbr_sched_dump_file, insns);
fflush (dbr_sched_dump_file);
});
}
{
fprintf (stack_reg_dump_file, "\n;; Function %s\n\n",
(*decl_printable_name) (decl, 2));
- print_rtl (stack_reg_dump_file, insns);
+ print_rtl_with_bb (stack_reg_dump_file, insns);
fflush (stack_reg_dump_file);
});
}
#ifdef CAN_DEBUG_WITHOUT_FP
flag_omit_frame_pointer = 1;
#endif
+ flag_alias_check = 1;
}
if (optimize >= 2)
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)
jump2_opt_dump = 1;
local_reg_dump = 1;
loop_dump = 1;
+ regmove_dump = 1;
rtl_dump = 1;
cse_dump = 1, cse2_dump = 1;
sched_dump = 1;
case 't':
cse2_dump = 1;
break;
+ case 'N':
+ regmove_dump = 1;
+ break;
case 'S':
sched_dump = 1;
break;
if (found)
;
+#ifdef HAIFA
+#ifdef INSN_SCHEDULING
+ else if (!strncmp (p, "sched-verbose-",14))
+ fix_sched_param("verbose",&p[14]);
+ else if (!strncmp (p, "sched-max-",10))
+ fix_sched_param("max",&p[10]);
+ else if (!strncmp (p, "sched-inter-max-b-",18))
+ fix_sched_param("interblock-max-blocks",&p[18]);
+ else if (!strncmp (p, "sched-inter-max-i-",18))
+ fix_sched_param("interblock-max-insns",&p[18]);
+#endif
+#endif /* HAIFA */
else if (!strncmp (p, "fixed-", 6))
fix_register (&p[6], 1, 1);
else if (!strncmp (p, "call-used-", 10))
p = str + strlen (da->arg);
if (*p && (*p < '0' || *p > '9'))
continue;
+ len = p - str;
q = p;
while (*q && (*q >= '0' && *q <= '9'))
q++;
if (*p)
- level = atoi (p);
+ {
+ level = atoi (p);
+ if (len > 1 && !strncmp (str, "gdwarf", len))
+ {
+ error ("use -gdwarf -g%d for DWARF v1, level %d",
+ level, level);
+ if (level == 2)
+ error ("use -gdwarf-2 for DWARF v2");
+ }
+ }
else
level = 2; /* default debugging info level */
if (*q || level > 3)
{
#ifdef DWARF2_DEBUGGING_INFO
type = DWARF2_DEBUG;
-#elif defined DBX_DEBUGGING_INFO
+#else
+#ifdef DBX_DEBUGGING_INFO
type = DBX_DEBUG;
#endif
+#endif
}
}
filename = argv[i];
}
+ /* Checker uses the frame pointer. */
+ if (flag_check_memory_usage)
+ flag_omit_frame_pointer = 0;
+
/* Initialize for bytecode output. A good idea to do this as soon as
possible after the "-f" options have been parsed. */
if (output_bytecode)
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.");
lim - (char *) &environ);
fflush (stderr);
+#ifndef __MSDOS__
#ifdef USG
system ("ps -l 1>&2");
#else /* not USG */
system ("ps v");
#endif /* not USG */
+#endif
}
#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN32) */