]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/toplev.c
re PR rtl-optimization/8423 (CSE1 not propagating __builtin_constant_p enough)
[gcc.git] / gcc / toplev.c
index a811c4be8ca2b7e38258678f7af8a13b5b28cb69..b24da96cba3914838e9ef90e8247d02070bc3ed5 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
@@ -230,6 +232,7 @@ enum dump_file_index
   DFI_addressof,
   DFI_gcse,
   DFI_loop,
+  DFI_bypass,
   DFI_cfg,
   DFI_bp,
   DFI_ce1,
@@ -279,9 +282,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 +425,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 +621,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 +642,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 +752,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 +1310,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") },
@@ -2050,9 +2056,14 @@ check_global_declarations (vec, len)
          && (*lang_hooks.decls.warn_unused_global) (decl))
        warning_with_decl (decl, "`%s' defined but not used");
 
-      timevar_push (TV_SYMOUT);
-      (*debug_hooks->global_decl) (decl);
-      timevar_pop (TV_SYMOUT);
+      /* Avoid confusing the debug information machinery when there are
+        errors.  */
+      if (errorcount == 0 && sorrycount == 0)
+       {
+         timevar_push (TV_SYMOUT);
+         (*debug_hooks->global_decl) (decl);
+         timevar_pop (TV_SYMOUT);
+       }
     }
 }
 
@@ -2151,14 +2162,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);
 
@@ -2185,8 +2193,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);
@@ -2341,6 +2347,11 @@ rest_of_type_compilation (type, toplev)
      int toplev ATTRIBUTE_UNUSED;
 #endif
 {
+  /* Avoid confusing the debug information machinery when there are
+     errors.  */
+  if (errorcount != 0 || sorrycount != 0)
+    return;
+
   timevar_push (TV_SYMOUT);
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
@@ -2419,6 +2430,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)
@@ -2466,10 +2480,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)
@@ -2906,6 +2921,9 @@ rest_of_compilation (decl)
 #endif
     }
 
+  /* Instantiate any remaining CONSTANT_P_RTX nodes.  */
+  purge_builtin_constant_p ();
+
   /* Move constant computations out of loops.  */
 
   if (optimize > 0 && flag_loop_optimize)
@@ -2951,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.  */
 
@@ -2962,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 ();
@@ -2998,17 +3042,24 @@ rest_of_compilation (decl)
       close_dump_file (DFI_bp, print_rtl_with_bb, insns);
       timevar_pop (TV_BRANCH_PROB);
     }
-  if (flag_if_conversion)
+  if (optimize >= 0)
     {
-      timevar_push (TV_IFCVT);
-      if (rtl_dump_file)
-       dump_flow_info (rtl_dump_file);
       open_dump_file (DFI_ce1, decl);
+      if (flag_if_conversion)
+       {
+         timevar_push (TV_IFCVT);
+         if (rtl_dump_file)
+           dump_flow_info (rtl_dump_file);
+         cleanup_cfg (CLEANUP_EXPENSIVE);
+         reg_scan (insns, max_reg_num (), 0);
+         if_convert (0);
+         timevar_pop (TV_IFCVT);
+       }
+      timevar_push (TV_JUMP);
       cleanup_cfg (CLEANUP_EXPENSIVE);
       reg_scan (insns, max_reg_num (), 0);
-      if_convert (0);
+      timevar_pop (TV_JUMP);
       close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
-      timevar_pop (TV_IFCVT);
     }
   if (flag_tracer)
     {
@@ -3016,47 +3067,35 @@ rest_of_compilation (decl)
       open_dump_file (DFI_tracer, decl);
       if (rtl_dump_file)
        dump_flow_info (rtl_dump_file);
-      cleanup_cfg (CLEANUP_EXPENSIVE);
       tracer ();
       cleanup_cfg (CLEANUP_EXPENSIVE);
+      reg_scan (insns, max_reg_num (), 0);
       close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
       timevar_pop (TV_TRACER);
-      reg_scan (get_insns (), max_reg_num (), 0);
     }
 
-  if (optimize > 0)
+  if (flag_rerun_cse_after_loop)
     {
       timevar_push (TV_CSE2);
       open_dump_file (DFI_cse2, decl);
       if (rtl_dump_file)
        dump_flow_info (rtl_dump_file);
+      /* CFG is no longer maintained up-to-date.  */
+      tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
+      purge_all_dead_edges (0);
+      delete_trivially_dead_insns (insns, max_reg_num ());
 
-      if (flag_rerun_cse_after_loop)
+      if (tem)
        {
          timevar_push (TV_JUMP);
-         reg_scan (insns, max_reg_num (), 0);
-         timevar_pop (TV_JUMP);
-
+         rebuild_jump_labels (insns);
          cleanup_cfg (CLEANUP_EXPENSIVE);
-         /* CFG is no longer maintained up-to-date.  */
-         reg_scan (insns, max_reg_num (), 0);
-         tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
-         purge_all_dead_edges (0);
-         delete_trivially_dead_insns (insns, max_reg_num ());
-
-         if (tem)
-           {
-             timevar_push (TV_JUMP);
-             rebuild_jump_labels (insns);
-             cleanup_cfg (CLEANUP_EXPENSIVE);
-             timevar_pop (TV_JUMP);
-           }
+         timevar_pop (TV_JUMP);
        }
-
+      reg_scan (insns, max_reg_num (), 0);
       close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
-      timevar_pop (TV_CSE2);
-
       ggc_collect ();
+      timevar_pop (TV_CSE2);
     }
 
   cse_not_expected = 1;
@@ -3114,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)
        {
@@ -3472,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
@@ -3599,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);
@@ -4098,7 +4138,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;
@@ -4659,7 +4699,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);
     }
This page took 0.040098 seconds and 5 git commands to generate.