OSDN Git Service

2003-01-26 Steven Bosscher <s.bosscher@student.tudelft.nl>
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 2f3d127..3ab85ad 100644 (file)
@@ -1,6 +1,6 @@
 /* Top level of GNU C compiler
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -28,6 +28,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #undef FLOAT /* This is for hpux. They should change hpux.  */
 #undef FFS  /* Some systems define this in param.h.  */
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include <signal.h>
 
 #ifdef HAVE_SYS_RESOURCE_H
@@ -71,6 +73,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "langhooks.h"
 #include "cfglayout.h"
+#include "cfgloop.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -230,6 +233,7 @@ enum dump_file_index
   DFI_addressof,
   DFI_gcse,
   DFI_loop,
+  DFI_bypass,
   DFI_cfg,
   DFI_bp,
   DFI_ce1,
@@ -279,9 +283,10 @@ static struct dump_file_info dump_file[DFI_MAX] =
   { "addressof", 'F', 0, 0, 0 },
   { "gcse",    'G', 1, 0, 0 },
   { "loop",    'L', 1, 0, 0 },
-  { "ce1",     'C', 1, 0, 0 },
+  { "bypass",   'G', 1, 0, 0 }, /* Yes, duplicate enable switch.  */
   { "cfg",     'f', 1, 0, 0 },
   { "bp",      'b', 1, 0, 0 },
+  { "ce1",     'C', 1, 0, 0 },
   { "tracer",  'T', 1, 0, 0 },
   { "cse2",    't', 1, 0, 0 },
   { "life",    'f', 1, 0, 0 }, /* Yes, duplicate enable switch.  */
@@ -421,7 +426,7 @@ int time_report = 0;
 
 int mem_report = 0;
 
-/* Non-zero means to collect statistics which might be expensive
+/* Nonzero means to collect statistics which might be expensive
    and to print them when we are done.  */
 int flag_detailed_statistics = 0;
 
@@ -617,10 +622,6 @@ int flag_volatile_static;
 
 int flag_syntax_only = 0;
 
-/* Nonzero means perform global cse.  */
-
-static int flag_gcse;
-
 /* Nonzero means perform loop optimizer.  */
 
 static int flag_loop_optimize;
@@ -642,6 +643,10 @@ static int flag_if_conversion2;
 
 static int flag_delete_null_pointer_checks;
 
+/* Nonzero means perform global CSE.  */
+
+int flag_gcse = 0;
+
 /* Nonzero means to do the enhanced load motion during gcse, which trys
    to hoist loads by not killing them when a store to the same location
    is seen.  */
@@ -748,7 +753,7 @@ int flag_schedule_insns_after_reload = 0;
 /* The following flags have effect only for scheduling before register
    allocation:
 
-   flag_schedule_interblock means schedule insns accross basic blocks.
+   flag_schedule_interblock means schedule insns across 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.
@@ -1306,6 +1311,8 @@ documented_lang_options[] =
   { "-Wimport",
     N_("Warn about the use of the #import directive") },
   { "-Wno-import", "" },
+  { "-Winvalid-pch",
+    N_("Warn about PCH files that are found but not used") },
   { "-Wlong-long","" },
   { "-Wno-long-long",
     N_("Do not warn about using 'long long' when -pedantic") },
@@ -1405,7 +1412,7 @@ int inhibit_warnings = 0;
 
 int warn_system_headers = 0;
 
-/* Print various extra warnings.  -W.  */
+/* Print various extra warnings.  -W/-Wextra.  */
 
 int extra_warnings = 0;
 
@@ -1500,7 +1507,7 @@ int warn_deprecated_decl = 1;
 
 int warn_strict_aliasing;
 
-/* Likewise for -W.  */
+/* Like f_options, but for -W.  */
 
 static const lang_independent_options W_options[] =
 {
@@ -1544,6 +1551,8 @@ static const lang_independent_options W_options[] =
    N_("Warn when an optimization pass is disabled") },
   {"deprecated-declarations", &warn_deprecated_decl, 1,
    N_("Warn about uses of __attribute__((deprecated)) declarations") },
+  {"extra", &extra_warnings, 1,
+   N_("Print extra (possibly unwanted) warnings") },
   {"missing-noreturn", &warn_missing_noreturn, 1,
    N_("Warn about functions which might be candidates for attribute noreturn") },
   {"strict-aliasing", &warn_strict_aliasing, 1,
@@ -2156,14 +2165,11 @@ compile_file ()
 
     wrapup_global_declarations (vec, len);
 
-    /* This must occur after the loop to output deferred functions.  Else
-       the profiler initializer would not be emitted if all the functions
-       in this compilation unit were deferred.
-
-       output_func_start_profiler can not cause any additional functions or
-       data to need to be output, so it need not be in the deferred function
-       loop above.  */
-    output_func_start_profiler ();
+    if (profile_arc_flag)
+      /* This must occur after the loop to output deferred functions.
+         Else the profiler initializer would not be emitted if all the
+         functions in this compilation unit were deferred.  */
+      create_profiler ();
 
     check_global_declarations (vec, len);
 
@@ -2190,8 +2196,6 @@ compile_file ()
 
   dw2_output_indirect_constants ();
 
-  end_final (aux_base_name);
-
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
       timevar_push (TV_DUMP);
@@ -2245,14 +2249,6 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
      int top_level;
      int at_end;
 {
-  /* Declarations of variables, and of functions defined elsewhere.  */
-
-/* The most obvious approach, to put an #ifndef around where
-   this macro is used, doesn't work since it's inside a macro call.  */
-#ifndef ASM_FINISH_DECLARE_OBJECT
-#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
-#endif
-
   /* We deferred calling assemble_alias so that we could collect
      other attributes such as visibility.  Emit the alias now.  */
   {
@@ -2280,11 +2276,14 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
         is seen.  But at end of compilation, do output code for them.  */
       if (at_end || !DECL_DEFER_OUTPUT (decl))
        assemble_variable (decl, top_level, at_end, 0);
+
+#ifdef ASM_FINISH_DECLARE_OBJECT
       if (decl == last_assemble_variable_decl)
        {
          ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
                                     top_level, at_end);
        }
+#endif
 
       timevar_pop (TV_VARCONST);
     }
@@ -2338,7 +2337,8 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
 
 void
 rest_of_type_compilation (type, toplev)
-#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)     \
+    || defined (SDB_DEBUGGING_INFO) || defined (DWARF2_DEBUGGING_INFO)
      tree type;
      int toplev;
 #else
@@ -2429,6 +2429,9 @@ rest_of_compilation (decl)
            DECL_INITIAL (decl) = 0;
            goto exit_rest_of_compilation;
          }
+       else if (TYPE_P (parent))
+         /* A function in a local class should be treated normally.  */
+         break;
 
       /* If requested, consider whether to make this function inline.  */
       if ((DECL_INLINE (decl) && !flag_no_inline)
@@ -2476,10 +2479,11 @@ rest_of_compilation (decl)
       convert_from_eh_region_ranges ();
 
       /* 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
-        for those functions that need to be output.  Also defer those
-        functions that we are supposed to defer.  */
+         compile it by itself, defer decision till end of compilation.
+         wrapup_global_declarations will (indirectly) call
+         rest_of_compilation again for those functions that need to
+         be output.  Also defer those functions that we are supposed
+         to defer.  */
 
       if (inlinable
          || (DECL_INLINE (decl)
@@ -2916,6 +2920,10 @@ rest_of_compilation (decl)
 #endif
     }
 
+  /* Instantiate any remaining CONSTANT_P_RTX nodes.  */
+  if (optimize > 0 && flag_gcse && current_function_calls_constant_p)
+    purge_builtin_constant_p ();
+
   /* Move constant computations out of loops.  */
 
   if (optimize > 0 && flag_loop_optimize)
@@ -2961,6 +2969,32 @@ rest_of_compilation (decl)
       ggc_collect ();
     }
 
+  /* Perform jump bypassing and control flow optimizations.  */
+  if (optimize > 0 && flag_gcse)
+    {
+      timevar_push (TV_BYPASS);
+      open_dump_file (DFI_bypass, decl);
+
+      cleanup_cfg (CLEANUP_EXPENSIVE);
+      tem = bypass_jumps (rtl_dump_file);
+
+      if (tem)
+        {
+          rebuild_jump_labels (insns);
+          cleanup_cfg (CLEANUP_EXPENSIVE);
+          delete_trivially_dead_insns (insns, max_reg_num ());
+        }
+
+      close_dump_file (DFI_bypass, print_rtl_with_bb, insns);
+      timevar_pop (TV_BYPASS);
+
+      ggc_collect ();
+
+#ifdef ENABLE_CHECKING
+      verify_flow_info ();
+#endif
+    }
+
   /* Do control and data flow analysis; wrote some of the results to
      the dump file.  */
 
@@ -2972,11 +3006,11 @@ rest_of_compilation (decl)
               | (flag_thread_jumps ? CLEANUP_THREADING : 0));
 
   /* It may make more sense to mark constant functions after dead code is
-     eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs
+     eliminated by life_analysis, but we need to do it early, as -fprofile-arcs
      may insert code making function non-constant, but we still must consider
      it as constant, otherwise -fbranch-probabilities will not read data back.
 
-     life_analyzis rarely eliminates modification of external memory.
+     life_analysis rarely eliminates modification of external memory.
    */
   if (optimize)
     mark_constant_function ();
@@ -3119,7 +3153,7 @@ rest_of_compilation (decl)
        = combine_instructions (insns, max_reg_num ());
 
       /* Combining insns may have turned an indirect jump into a
-        direct jump.  Rebuid the JUMP_LABEL fields of jumping
+        direct jump.  Rebuild the JUMP_LABEL fields of jumping
         instructions.  */
       if (rebuild_jump_labels_after_combine)
        {
@@ -3477,7 +3511,7 @@ rest_of_compilation (decl)
       open_dump_file (DFI_bbro, decl);
 
       /* Last attempt to optimize CFG, as scheduling, peepholing and insn
-        splitting possibly introduced more crossjumping oppurtuntities.
+        splitting possibly introduced more crossjumping opportunities.
         Except that we can't actually run crossjumping without running
         another DCE pass, which we can't do after reg-stack.  */
       cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
@@ -3604,9 +3638,10 @@ rest_of_compilation (decl)
      know for certain that we will be generating an out-of-line copy,
      the first invocation of this routine (rest_of_compilation) will
      skip over this code by doing a `goto exit_rest_of_compilation;'.
-     Later on, finish_compilation will call rest_of_compilation again
-     for those inline functions that need to have out-of-line copies
-     generated.  During that call, we *will* be routed past here.  */
+     Later on, wrapup_global_declarations will (indirectly) call
+     rest_of_compilation again for those inline functions that need
+     to have out-of-line copies generated.  During that call, we
+     *will* be routed past here.  */
 
   timevar_push (TV_SYMOUT);
   (*debug_hooks->function_decl) (decl);
@@ -3708,7 +3743,6 @@ display_help ()
   printf (_("  -pedantic               Issue warnings needed by strict compliance to ISO C\n"));
   printf (_("  -pedantic-errors        Like -pedantic except that errors are produced\n"));
   printf (_("  -w                      Suppress warnings\n"));
-  printf (_("  -W                      Enable extra warnings\n"));
 
   for (i = ARRAY_SIZE (W_options); i--;)
     {
@@ -4082,6 +4116,14 @@ decode_W_option (arg)
     {
       set_Wunused (0);
     }
+  else if (!strcmp (arg, "extra"))
+    {
+      /* We save the value of warn_uninitialized, since if they put
+        -Wuninitialized on the command line, we need to generate a
+        warning about not using it without also specifying -O.  */
+      if (warn_uninitialized != 1)
+       warn_uninitialized = 2;
+    }
   else
     return 0;
 
@@ -4103,7 +4145,7 @@ decode_g_option (arg)
      selected type.  It is an error to specify more than one
      debugging type.  */
   static enum debug_info_type selected_debug_type = NO_DEBUG;
-  /* Non-zero if debugging format has been explicitly set.
+  /* Nonzero if debugging format has been explicitly set.
      -g and -ggdb don't explicitly set the debugging format so
      -gdwarf -g3 is equivalent to -gdwarf3.  */
   static int type_explicitly_set_p = 0;
@@ -4664,7 +4706,7 @@ init_asm_output (name)
       if (!strcmp (asm_file_name, "-"))
        asm_out_file = stdout;
       else
-       asm_out_file = fopen (asm_file_name, "w");
+       asm_out_file = fopen (asm_file_name, "w+");
       if (asm_out_file == 0)
        fatal_io_error ("can't open %s for writing", asm_file_name);
     }