OSDN Git Service

* loop.c (invariant_p): Don't test flag_rerun_loop_opt.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 364c17d..4e50173 100644 (file)
@@ -35,8 +35,7 @@ Boston, MA 02111-1307, USA.  */
 #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>
@@ -151,6 +150,7 @@ 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 ();
 
 void rest_of_decl_compilation ();
 void error_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
@@ -203,9 +203,10 @@ char *input_filename;
 
 char *main_input_filename;
 
+#if !USE_CPPLIB
 /* Stream for reading from the input file.  */
-
 FILE *finput;
+#endif
 
 /* Current line number in real source file.  */
 
@@ -237,11 +238,14 @@ 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 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;
 int local_reg_dump = 0;
 int global_reg_dump = 0;
@@ -292,9 +296,15 @@ int sorrycount = 0;
 /* Flag to output bytecode instead of native assembler */
 int output_bytecode = 0;
 
-/* Pointer to function to compute the name to use to print a declaration.  */
+/* Pointer to function to compute the name to use to print a declaration.
+   DECL is the declaration in question.
+   VERBOSITY determines what information will be printed:
+     0: DECL_NAME, demangled as necessary.
+     1: and scope information.
+     2: and any other information that might be interesting, such as function
+        parameter types in C++.  */
 
-char *(*decl_printable_name) ();
+char *(*decl_printable_name) (/* tree decl, int verbosity */);
 
 /* Pointer to function to compute rtl for a language-specific tree code.  */
 
@@ -317,6 +327,18 @@ int profile_flag = 0;
 
 int profile_block_flag;
 
+/* Nonzero if generating code to profile program flow graph arcs.  */
+
+int profile_arc_flag = 0;
+
+/* Nonzero if generating info for gcov to calculate line test coverage.  */
+
+int flag_test_coverage = 0;
+
+/* Nonzero indicates that branch taken probabilities should be calculated.  */
+
+int flag_branch_probabilities = 0;
+
 /* Nonzero for -pedantic switch: warn about anything
    that standard spec forbids.  */
 
@@ -424,6 +446,16 @@ int flag_unroll_loops;
 
 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.  */
 
@@ -473,6 +505,10 @@ int flag_syntax_only = 0;
 
 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.  */
 
@@ -509,10 +545,6 @@ int flag_shared_data;
 
 int flag_delayed_branch;
 
-/* Nonzero means to run cleanups after CALL_EXPRs.  */
-
-int flag_short_temps;
-
 /* Nonzero if we are compiling pure (sharable) code.
    Value is 1 if we are doing reasonable (i.e. simple
    offset into offset table) pic.  Value is 2 if we can
@@ -523,7 +555,7 @@ int flag_pic;
 /* 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.  */
@@ -549,6 +581,35 @@ int flag_pedantic_errors = 0;
 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
@@ -585,6 +646,33 @@ int flag_gnu_linker = 1;
 /* Tag all structures with __attribute__(packed) */
 int flag_pack_struct = 0;
 
+/* Emit code to check for stack overflow; also may cause large objects
+   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
@@ -605,6 +693,8 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"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},
@@ -621,20 +711,43 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"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},
+  {"sjlj-exceptions", &exceptions_via_longjmp, 1},
+  {"asynchronous-exceptions", &asynchronous_exceptions, 1},
+  {"profile-arcs", &profile_arc_flag, 1},
+  {"test-coverage", &flag_test_coverage, 1},
+  {"branch-probabilities", &flag_branch_probabilities, 1},
   {"fast-math", &flag_fast_math, 1},
   {"common", &flag_no_common, 0},
   {"inhibit-size-directive", &flag_inhibit_size_directive, 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},
-  {"bytecode", &output_bytecode, 1}
+  {"stack-check", &flag_stack_check, 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.  */
@@ -694,6 +807,11 @@ char *lang_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",
@@ -720,6 +838,8 @@ char *lang_options[] =
   "-Wno-traditional",
   "-Wtrigraphs",
   "-Wno-trigraphs",
+  "-Wundef",
+  "-Wno-undef",
   "-Wwrite-strings",
   "-Wno-write-strings",
 
@@ -823,11 +943,14 @@ FILE *asm_out_file;
 FILE *aux_info_file;
 FILE *rtl_dump_file;
 FILE *jump_opt_dump_file;
+FILE *addressof_dump_file;
 FILE *cse_dump_file;
 FILE *loop_dump_file;
 FILE *cse2_dump_file;
+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;
@@ -845,8 +968,10 @@ int jump_time;
 int cse_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;
@@ -863,7 +988,7 @@ int dump_time;
 int
 get_run_time ()
 {
-#ifndef _WIN32
+#if !defined (_WIN32) || defined (__CYGWIN32__)
 #ifdef USG
   struct tms tms;
 #else
@@ -883,7 +1008,7 @@ get_run_time ()
 
   if (quiet_flag)
     return 0;
-#ifdef _WIN32
+#if defined (_WIN32) && !defined (__CYGWIN32__)
   if (clock() < 0)
     return 0;
   else
@@ -985,6 +1110,8 @@ fatal_insn (message, insn)
     fflush (rtl_dump_file);
   if (jump_opt_dump_file)
     fflush (jump_opt_dump_file);
+  if (addressof_dump_file)
+    fflush (addressof_dump_file);
   if (cse_dump_file)
     fflush (cse_dump_file);
   if (loop_dump_file)
@@ -995,6 +1122,8 @@ fatal_insn (message, insn)
     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)
@@ -1031,9 +1160,9 @@ fatal_insn_not_found (insn)
 /* This is the default decl_printable_name function.  */
 
 static char *
-decl_name (decl, kind)
+decl_name (decl, verbosity)
      tree decl;
-     char **kind;
+     int verbosity;
 {
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
@@ -1057,11 +1186,10 @@ announce_function (decl)
 {
   if (! quiet_flag)
     {
-      char *junk;
       if (rtl_dump_and_exit)
        fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
       else
-       fprintf (stderr, " %s", (*decl_printable_name) (decl, &junk));
+       fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
       fflush (stderr);
       need_error_newline = 1;
       last_error_function = current_function_decl;
@@ -1089,7 +1217,7 @@ default_print_error_function (file)
        fprintf (stderr, "At top level:\n");
       else
        {
-         char *name = (*decl_printable_name) (current_function_decl, &kind);
+         char *name = (*decl_printable_name) (current_function_decl, 2);
          fprintf (stderr, "In %s `%s':\n", kind, name);
        }
 
@@ -1187,7 +1315,7 @@ v_message_with_decl (decl, prefix, s, ap)
      char *s;
      va_list ap;
 {
-  char *n, *p, *junk;
+  char *n, *p;
 
   fprintf (stderr, "%s:%d: ",
           DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
@@ -1223,7 +1351,7 @@ v_message_with_decl (decl, prefix, s, ap)
   if (*p == '%')               /* Print the name.  */
     {
       char *n = (DECL_NAME (decl)
-                ? (*decl_printable_name) (decl, &junk)
+                ? (*decl_printable_name) (decl, 2)
                 : "((anonymous))");
       fputs (n, stderr);
       while (*p)
@@ -1804,19 +1932,22 @@ xmalloc (size)
      unsigned size;
 {
   register char *value = (char *) malloc (size);
-  if (value == 0)
+  if (value == 0 && size != 0)
     fatal ("virtual memory exhausted");
   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;
@@ -1870,9 +2001,27 @@ floor_log2_wide (x)
   return log;
 }
 
+static int float_handler_set;
 int float_handled;
 jmp_buf float_handler;
 
+/* Signals actually come here.  */
+
+static void
+float_signal (signo)
+     /* If this is missing, some compilers complain.  */
+     int signo;
+{
+  if (float_handled == 0)
+    abort ();
+#if defined (USG) || defined (hpux)
+  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
+#endif
+  float_handled = 0;
+  signal (SIGFPE, float_signal);
+  longjmp (float_handler, 1);
+}
+
 /* Specify where to longjmp to when a floating arithmetic error happens.
    If HANDLER is 0, it means don't handle the errors any more.  */
 
@@ -1883,6 +2032,12 @@ set_float_handler (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;
+    }
 }
 
 /* Specify, in HANDLER, where to longjmp to when a floating arithmetic
@@ -1917,23 +2072,6 @@ pop_float_handler (handled, handler)
     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
 }
 
-/* Signals actually come here.  */
-
-static void
-float_signal (signo)
-     /* If this is missing, some compilers complain.  */
-     int signo;
-{
-  if (float_handled == 0)
-    abort ();
-#if defined (USG) || defined (hpux)
-  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
-#endif
-  float_handled = 0;
-  signal (SIGFPE, float_signal);
-  longjmp (float_handler, 1);
-}
-
 /* Handler for SIGPIPE.  */
 
 static void
@@ -1969,6 +2107,9 @@ output_quoted_string (asm_file, string)
      FILE *asm_file;
      char *string;
 {
+#ifdef OUTPUT_QUOTED_STRING
+  OUTPUT_QUOTED_STRING (asm_file, string);
+#else
   char c;
 
   putc ('\"', asm_file);
@@ -1979,6 +2120,7 @@ output_quoted_string (asm_file, string)
       putc (c, asm_file);
     }
   putc ('\"', asm_file);
+#endif
 }
 
 /* Output a file name in the form wanted by System V.  */
@@ -2064,8 +2206,10 @@ compile_file (name)
   cse_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;
@@ -2077,6 +2221,7 @@ compile_file (name)
   symout_time = 0;
   dump_time = 0;
 
+#if !USE_CPPLIB
   /* Open input file.  */
 
   if (name == 0 || !strcmp (name, "-"))
@@ -2092,17 +2237,23 @@ compile_file (name)
 #ifdef IO_BUFFER_SIZE
   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
 #endif
+#endif /* !USE_CPPLIB */
 
   /* Initialize data in various passes.  */
 
   init_obstacks ();
   init_tree_codes ();
+#if USE_CPPLIB
+  init_parse (name);
+#else
   init_lex ();
+#endif
   /* Some of these really don't need to be called when generating bytecode,
      but the options would have to be parsed first to know that. -bson */
   init_rtl ();
   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
-                 || debug_info_level == DINFO_LEVEL_VERBOSE);
+                 || debug_info_level == DINFO_LEVEL_VERBOSE
+                 || flag_test_coverage);
   init_regs ();
   init_decl_processing ();
   init_optabs ();
@@ -2133,6 +2284,10 @@ compile_file (name)
   if (jump_opt_dump)
     jump_opt_dump_file = open_dump_file (dump_base_name, ".jump");
 
+  /* If addressof dump desired, open the output file.  */
+  if (addressof_dump)
+    addressof_dump_file = open_dump_file (dump_base_name, ".addressof");
+
   /* If cse dump desired, open the output file.  */
   if (cse_dump)
     cse_dump_file = open_dump_file (dump_base_name, ".cse");
@@ -2145,6 +2300,10 @@ compile_file (name)
   if (cse2_dump)
     cse2_dump_file = open_dump_file (dump_base_name, ".cse2");
 
+  /* If branch_prob dump desired, open the output file.  */
+  if (branch_prob_dump)
+    branch_prob_dump_file = open_dump_file (dump_base_name, ".bp");
+
   /* If flow dump desired, open the output file.  */
   if (flow_dump)
     flow_dump_file = open_dump_file (dump_base_name, ".flow");
@@ -2153,6 +2312,10 @@ compile_file (name)
   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");
@@ -2222,10 +2385,32 @@ compile_file (name)
   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)
@@ -2324,6 +2509,10 @@ compile_file (name)
   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));
@@ -2333,6 +2522,7 @@ compile_file (name)
 
   if (!output_bytecode)
     init_final (main_input_filename);
+  init_branch_prob (dump_base_name);
 
   start_time = get_run_time ();
 
@@ -2350,6 +2540,8 @@ compile_file (name)
        poplevel (0, 0, 0);
     }
 
+  output_func_start_profiler ();
+
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */
 
@@ -2441,6 +2633,7 @@ compile_file (name)
                && DECL_INITIAL (decl) != 0
                && DECL_SAVED_INSNS (decl) != 0
                && (flag_keep_inline_functions
+                   || TREE_PUBLIC (decl)
                    || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
              {
                reconsider = 1;
@@ -2454,8 +2647,7 @@ compile_file (name)
     /* 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++)
       {
@@ -2570,6 +2762,11 @@ compile_file (name)
             });
 #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,
@@ -2582,7 +2779,8 @@ compile_file (name)
 
   if (!output_bytecode)
     {
-      end_final (main_input_filename);
+      end_final (dump_base_name);
+      end_branch_prob (branch_prob_dump_file);
 
 #ifdef ASM_FILE_END
       ASM_FILE_END (asm_out_file);
@@ -2611,6 +2809,9 @@ compile_file (name)
   if (jump_opt_dump)
     fclose (jump_opt_dump_file);
 
+  if (addressof_dump)
+    fclose (addressof_dump_file);
+
   if (cse_dump)
     fclose (cse_dump_file);
 
@@ -2620,6 +2821,9 @@ compile_file (name)
   if (cse2_dump)
     fclose (cse2_dump_file);
 
+  if (branch_prob_dump)
+    fclose (branch_prob_dump_file);
+
   if (flow_dump)
     fclose (flow_dump_file);
 
@@ -2629,6 +2833,9 @@ compile_file (name)
       fclose (combine_dump_file);
     }
 
+  if (regmove_dump)
+    fclose (regmove_dump_file);
+
   if (sched_dump)
     fclose (sched_dump_file);
 
@@ -2656,7 +2863,11 @@ compile_file (name)
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
 
+#if USE_CPPLIB
+  finish_parse ();
+#else
   fclose (finput);
+#endif
   if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
     fatal_io_error (asm_file_name);
 
@@ -2674,8 +2885,10 @@ compile_file (name)
          print_time ("cse", cse_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);
@@ -2851,13 +3064,18 @@ rest_of_compilation (decl)
        TIMEVAR (dump_time,
                 {
                   fprintf (rtl_dump_file, "\n;; Function %s\n\n",
-                           IDENTIFIER_POINTER (DECL_NAME (decl)));
+                           (*decl_printable_name) (decl, 2));
                   if (DECL_SAVED_INSNS (decl))
                     fprintf (rtl_dump_file, ";; (integrable)\n\n");
                   print_rtl (rtl_dump_file, insns);
                   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
@@ -2866,6 +3084,18 @@ rest_of_compilation (decl)
         functions containing nested functions since the nested function
         data is in our non-saved obstack.  */
 
+      /* If this is a nested inline, remove ADDRESSOF now so we can
+        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 (inlineable)
+       {
+         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)
@@ -3016,7 +3246,7 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*decl_printable_name) (decl, 2));
               print_rtl (jump_opt_dump_file, insns);
               fflush (jump_opt_dump_file);
             });
@@ -3030,7 +3260,7 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (cse_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*decl_printable_name) (decl, 2));
             });
 
   if (optimize > 0)
@@ -3058,11 +3288,23 @@ rest_of_compilation (decl)
               fflush (cse_dump_file);
             });
 
+  purge_addressof (insns);
+  reg_scan (insns, max_reg_num (), 1);
+
+  if (addressof_dump)
+    TIMEVAR (dump_time,
+            {
+              fprintf (addressof_dump_file, "\n;; Function %s\n\n",
+                       (*decl_printable_name) (decl, 2));
+              print_rtl (addressof_dump_file, insns);
+              fflush (addressof_dump_file);
+            });
+
   if (loop_dump)
     TIMEVAR (dump_time,
             {
               fprintf (loop_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*decl_printable_name) (decl, 2));
             });
 
   /* Move constant computations out of loops.  */
@@ -3071,7 +3313,17 @@ rest_of_compilation (decl)
     {
       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);
               });
     }
 
@@ -3088,7 +3340,7 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (cse2_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*decl_printable_name) (decl, 2));
             });
 
   if (optimize > 0 && flag_rerun_cse_after_loop)
@@ -3124,6 +3376,25 @@ rest_of_compilation (decl)
               fflush (cse2_dump_file);
             });
 
+  if (branch_prob_dump)
+    TIMEVAR (dump_time,
+            {
+              fprintf (branch_prob_dump_file, "\n;; Function %s\n\n",
+                       (*decl_printable_name) (decl, 2));
+            });
+
+  if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+    TIMEVAR (branch_prob_time,
+            {
+              branch_prob (insns, branch_prob_dump_file);
+            });
+
+  if (branch_prob_dump)
+    TIMEVAR (dump_time,
+            {
+              print_rtl (branch_prob_dump_file, insns);
+              fflush (branch_prob_dump_file);
+            });
   /* We are no longer anticipating cse in this function, at least.  */
 
   cse_not_expected = 1;
@@ -3144,7 +3415,7 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (flow_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*decl_printable_name) (decl, 2));
             });
 
   if (obey_regdecls)
@@ -3175,7 +3446,7 @@ rest_of_compilation (decl)
   if (flow_dump)
     TIMEVAR (dump_time,
             {
-              print_rtl (flow_dump_file, insns);
+              print_rtl_with_bb (flow_dump_file, insns);
               fflush (flow_dump_file);
             });
 
@@ -3190,12 +3461,32 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (combine_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*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.  */
 
@@ -3203,7 +3494,7 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (sched_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*decl_printable_name) (decl, 2));
             });
 
   if (optimize > 0 && flag_schedule_insns)
@@ -3219,7 +3510,7 @@ rest_of_compilation (decl)
   if (sched_dump)
     TIMEVAR (dump_time,
             {
-              print_rtl (sched_dump_file, insns);
+              print_rtl_with_bb (sched_dump_file, insns);
               fflush (sched_dump_file);
             });
 
@@ -3239,17 +3530,17 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
+                       (*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);
             });
 
   if (global_reg_dump)
     TIMEVAR (dump_time,
             fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
-                     IDENTIFIER_POINTER (DECL_NAME (decl))));
+                     (*decl_printable_name) (decl, 2)));
 
   /* Save the last label number used so far, so reorg can tell
      when it's safe to kill spill regs.  */
@@ -3271,7 +3562,7 @@ rest_of_compilation (decl)
     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);
             });
 
@@ -3280,6 +3571,10 @@ rest_of_compilation (decl)
 
   reload_completed = 1;
 
+  /* Do a very simple CSE pass over just the hard registers.  */
+  if (optimize > 0)
+    reload_cse_regs (insns);
+
   /* On some machines, the prologue and epilogue code, or parts thereof,
      can be represented as RTL.  Doing so lets us schedule insns between
      it and the rest of the code and also allows delayed branch
@@ -3293,7 +3588,7 @@ rest_of_compilation (decl)
        TIMEVAR (dump_time,
                 {
                   fprintf (sched2_dump_file, "\n;; Function %s\n\n",
-                           IDENTIFIER_POINTER (DECL_NAME (decl)));
+                           (*decl_printable_name) (decl, 2));
                 });
 
       /* Do control and data sched analysis again,
@@ -3306,7 +3601,7 @@ rest_of_compilation (decl)
       if (sched2_dump)
        TIMEVAR (dump_time,
                 {
-                  print_rtl (sched2_dump_file, insns);
+                  print_rtl_with_bb (sched2_dump_file, insns);
                   fflush (sched2_dump_file);
                 });
     }
@@ -3333,8 +3628,8 @@ rest_of_compilation (decl)
     TIMEVAR (dump_time,
             {
               fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-              print_rtl (jump2_opt_dump_file, insns);
+                       (*decl_printable_name) (decl, 2));
+              print_rtl_with_bb (jump2_opt_dump_file, insns);
               fflush (jump2_opt_dump_file);
             });
 
@@ -3355,8 +3650,8 @@ rest_of_compilation (decl)
          TIMEVAR (dump_time,
                 {
                   fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n",
-                           IDENTIFIER_POINTER (DECL_NAME (decl)));
-                  print_rtl (dbr_sched_dump_file, insns);
+                           (*decl_printable_name) (decl, 2));
+                  print_rtl_with_bb (dbr_sched_dump_file, insns);
                   fflush (dbr_sched_dump_file);
                 });
        }
@@ -3376,8 +3671,8 @@ rest_of_compilation (decl)
       TIMEVAR (dump_time,
               {
                 fprintf (stack_reg_dump_file, "\n;; Function %s\n\n",
-                         IDENTIFIER_POINTER (DECL_NAME (decl)));
-                print_rtl (stack_reg_dump_file, insns);
+                         (*decl_printable_name) (decl, 2));
+                print_rtl_with_bb (stack_reg_dump_file, insns);
                 fflush (stack_reg_dump_file);
               });
     }
@@ -3408,6 +3703,9 @@ rest_of_compilation (decl)
             final_end_function (insns, asm_out_file, optimize);
             assemble_end_function (decl, fnname);
             fflush (asm_out_file);
+
+            /* Release all memory held by regsets now */
+            regset_release_memory ();
           });
 
   /* Write DBX symbols if requested */
@@ -3561,11 +3859,6 @@ main (argc, argv, envp)
     }
 
   obey_regdecls = (optimize == 0);
-  if (optimize == 0)
-    {
-      flag_no_inline = 1;
-      warn_inline = 0;
-    }
 
   if (optimize >= 1)
     {
@@ -3577,6 +3870,7 @@ main (argc, argv, envp)
 #ifdef CAN_DEBUG_WITHOUT_FP
       flag_omit_frame_pointer = 1;
 #endif
+      flag_alias_check = 1;
     }
 
   if (optimize >= 2)
@@ -3586,12 +3880,14 @@ main (argc, argv, envp)
       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)
@@ -3644,20 +3940,26 @@ main (argc, argv, envp)
                switch (*p++)
                  {
                  case 'a':
+                   branch_prob_dump = 1;
                    combine_dump = 1;
                    dbr_sched_dump = 1;
                    flow_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;
                    sched_dump = 1;
                    sched2_dump = 1;
                    stack_reg_dump = 1;
                    break;
+                 case 'b':
+                   branch_prob_dump = 1;
+                   break;
                  case 'k':
                    stack_reg_dump = 1;
                    break;
@@ -3676,6 +3978,9 @@ main (argc, argv, envp)
                  case 'j':
                    jump_opt_dump = 1;
                    break;
+                 case 'D':
+                   addressof_dump = 1;
+                   break;
                  case 'J':
                    jump2_opt_dump = 1;
                    break;
@@ -3700,6 +4005,9 @@ main (argc, argv, envp)
                  case 't':
                    cse2_dump = 1;
                    break;
+                 case 'N':
+                   regmove_dump = 1;
+                   break;
                  case 'S':
                    sched_dump = 1;
                    break;
@@ -3747,6 +4055,18 @@ main (argc, argv, envp)
 
              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))
@@ -3935,11 +4255,21 @@ main (argc, argv, envp)
                      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)
@@ -3952,10 +4282,24 @@ main (argc, argv, envp)
                          level = 0;
                        }
 
-                     /* ??? A few targets use STR in the
-                        definition of PREFERRED_DEBUGGING_TYPE!  */
                      if (type == NO_DEBUG)
-                       type = PREFERRED_DEBUGGING_TYPE;
+                       {
+                         type = PREFERRED_DEBUGGING_TYPE;
+                         if (len > 1 && strncmp (str, "ggdb", len) == 0)
+                           {
+#ifdef DWARF2_DEBUGGING_INFO
+                             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);
 
                      /* Does it conflict with an already selected type?  */
                      if (type_explicitly_set_p
@@ -4012,6 +4356,10 @@ main (argc, argv, envp)
        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)
@@ -4043,6 +4391,15 @@ main (argc, argv, envp)
   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.");
@@ -4093,11 +4450,13 @@ main (argc, argv, envp)
               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) */