OSDN Git Service

* loop.c (invariant_p): Don't test flag_rerun_loop_opt.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index cb11ab4..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>
@@ -126,11 +125,6 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 #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))
@@ -251,6 +245,7 @@ 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;
@@ -451,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.  */
 
@@ -500,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.  */
 
@@ -546,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.  */
@@ -572,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
@@ -612,6 +650,29 @@ int flag_pack_struct = 0;
    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
@@ -632,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},
@@ -648,9 +711,19 @@ 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},
@@ -665,9 +738,16 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"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.  */
@@ -727,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",
@@ -865,6 +950,7 @@ 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;
@@ -885,6 +971,7 @@ 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;
@@ -901,7 +988,7 @@ int dump_time;
 int
 get_run_time ()
 {
-#ifndef _WIN32
+#if !defined (_WIN32) || defined (__CYGWIN32__)
 #ifdef USG
   struct tms tms;
 #else
@@ -921,7 +1008,7 @@ get_run_time ()
 
   if (quiet_flag)
     return 0;
-#ifdef _WIN32
+#if defined (_WIN32) && !defined (__CYGWIN32__)
   if (clock() < 0)
     return 0;
   else
@@ -1035,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)
@@ -1848,14 +1937,17 @@ xmalloc (size)
   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;
@@ -2015,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);
@@ -2025,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.  */
@@ -2113,6 +2209,7 @@ compile_file (name)
   branch_prob_time = 0;
   flow_time = 0;
   combine_time = 0;
+  regmove_time = 0;
   sched_time = 0;
   local_alloc_time = 0;
   global_alloc_time = 0;
@@ -2215,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");
@@ -2284,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)
@@ -2386,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));
@@ -2520,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++)
       {
@@ -2636,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,
@@ -2702,6 +2833,9 @@ compile_file (name)
       fclose (combine_dump_file);
     }
 
+  if (regmove_dump)
+    fclose (regmove_dump_file);
+
   if (sched_dump)
     fclose (sched_dump_file);
 
@@ -2754,6 +2888,7 @@ compile_file (name)
          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);
@@ -2936,6 +3071,11 @@ rest_of_compilation (decl)
                   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
@@ -2948,7 +3088,7 @@ rest_of_compilation (decl)
         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);
@@ -3173,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);
               });
     }
 
@@ -3296,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);
             });
 
@@ -3313,10 +3463,30 @@ rest_of_compilation (decl)
               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.  */
 
@@ -3340,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);
             });
 
@@ -3363,7 +3533,7 @@ rest_of_compilation (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);
             });
 
@@ -3392,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);
             });
 
@@ -3431,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);
                 });
     }
@@ -3459,7 +3629,7 @@ rest_of_compilation (decl)
             {
               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);
             });
 
@@ -3481,7 +3651,7 @@ rest_of_compilation (decl)
                 {
                   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);
                 });
        }
@@ -3502,7 +3672,7 @@ rest_of_compilation (decl)
               {
                 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);
               });
     }
@@ -3700,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)
@@ -3709,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)
@@ -3777,6 +3950,7 @@ main (argc, argv, envp)
                    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;
@@ -3831,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;
@@ -3878,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))
@@ -4066,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)
@@ -4090,9 +4289,11 @@ main (argc, argv, envp)
                            {
 #ifdef DWARF2_DEBUGGING_INFO
                              type = DWARF2_DEBUG;
-#elif defined DBX_DEBUGGING_INFO
+#else
+#ifdef DBX_DEBUGGING_INFO
                              type = DBX_DEBUG;
 #endif
+#endif
                            }
                        }
 
@@ -4155,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)
@@ -4186,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.");
@@ -4236,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) */