OSDN Git Service

Patches from David Mosberger, and a patch to make bootstrap work.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 2b26ad1..1a35497 100644 (file)
@@ -264,11 +264,13 @@ enum dump_file_index
   DFI_bp,
   DFI_flow,
   DFI_combine,
+  DFI_ce,
   DFI_regmove,
   DFI_sched,
   DFI_lreg,
   DFI_greg,
   DFI_flow2,
+  DFI_ce2,
   DFI_peephole2,
   DFI_sched2,
   DFI_bbro,
@@ -281,7 +283,13 @@ enum dump_file_index
 };
 
 /* Describes all the dump files.  Should be kept in order of the
-   pass and in sync with dump_file_index above.  */
+   pass and in sync with dump_file_index above.
+
+   Remaining -d letters:
+
+       "       h      o q   u     "
+       "       H  K   OPQ  TUVWXYZ"
+*/
 
 struct dump_file_info dump_file[DFI_MAX] = 
 {
@@ -298,11 +306,13 @@ struct dump_file_info dump_file[DFI_MAX] =
   { "bp",      'b', 1, 0, 0 },
   { "flow",    'f', 1, 0, 0 },
   { "combine", 'c', 1, 0, 0 },
+  { "ce",      'C', 1, 0, 0 },
   { "regmove", 'N', 1, 0, 0 },
   { "sched",   'S', 1, 0, 0 },
   { "lreg",    'l', 1, 0, 0 },
   { "greg",    'g', 1, 0, 0 },
   { "flow2",   'w', 1, 0, 0 },
+  { "ce2",     'E', 1, 0, 0 },
   { "peephole2", 'z', 1, 0, 0 },
   { "sched2",  'R', 1, 0, 0 },
   { "bbro",    'B', 1, 0, 0 },
@@ -2588,7 +2598,7 @@ rest_of_compilation (decl)
   /* Then remove any notes we don't need.  That will make iterating
      over the instruction sequence faster, and allow the garbage
      collector to reclaim the memory used by the notes.  */
-  remove_unncessary_notes ();
+  remove_unnecessary_notes ();
 
   /* In function-at-a-time mode, we do not attempt to keep the BLOCK
      tree in sensible shape.  So, we just recalculate it here.  */
@@ -2670,6 +2680,14 @@ rest_of_compilation (decl)
                  || DECL_EXTERNAL (decl))))
        DECL_DEFER_OUTPUT (decl) = 1;
 
+      if (DECL_INLINE (decl))
+       /* DWARF wants seperate debugging info for abstract and
+          concrete instances of all inline functions, including those
+          declared inline but not inlined, and those inlined even
+          though they weren't declared inline.  Conveniently, that's
+          what DECL_INLINE means at this point.  */
+       note_deferral_of_defined_inline_function (decl);
+
       if (DECL_DEFER_OUTPUT (decl))
        {
          /* If -Wreturn-type, we have to do a bit of compilation.
@@ -2696,7 +2714,6 @@ rest_of_compilation (decl)
               of other functions later in this translation unit.  */
            TREE_NOTHROW (current_function_decl) = 1;
 
-         note_deferral_of_defined_inline_function (decl);
          timevar_push (TV_INTEGRATION);
          save_for_inline_nocopy (decl);
          timevar_pop (TV_INTEGRATION);
@@ -2807,12 +2824,23 @@ rest_of_compilation (decl)
     }
 
   timevar_push (TV_JUMP);
-  /* Try to identify useless null pointer tests and delete them.  */
-  if (flag_delete_null_pointer_checks)
+
+  if (optimize > 0)
     {
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
       cleanup_cfg (insns);
-      delete_null_pointer_checks (insns);
+
+      /* ??? Run if-conversion before delete_null_pointer_checks,
+         since the later does not preserve the CFG.  This should
+        be changed -- no since converting if's that are going to
+        be deleted.  */
+      timevar_push (TV_IFCVT);
+      if_convert (0);
+      timevar_pop (TV_IFCVT);
+
+      /* Try to identify useless null pointer tests and delete them.  */
+      if (flag_delete_null_pointer_checks)
+       delete_null_pointer_checks (insns);
     }
 
   /* Jump optimization, and the removal of NULL pointer checks, may
@@ -2991,11 +3019,6 @@ rest_of_compilation (decl)
        ggc_collect ();
     }
 
-  /* ??? Well, nearly.  If HAVE_conditional_arithmetic, jump_optimize
-     has put off all if-conversion until "after CSE".  If we put this
-     off any longer we may miss out doing if-conversion entirely.  */
-  cse_not_expected = 1;
-
   if (optimize > 0)
     {
       timevar_push (TV_CSE2);
@@ -3009,9 +3032,19 @@ rest_of_compilation (decl)
             max_reg_num so we must rerun reg_scan afterwards.
             ??? Rework to not call reg_scan so often.  */
          timevar_push (TV_JUMP);
+
          reg_scan (insns, max_reg_num (), 0);
          jump_optimize (insns, !JUMP_CROSS_JUMP,
                         !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
+
+         timevar_push (TV_IFCVT);
+
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (insns);
+         if_convert (0);
+
+         timevar_pop(TV_IFCVT);
+
          timevar_pop (TV_JUMP);
          
          reg_scan (insns, max_reg_num (), 0);
@@ -3043,6 +3076,8 @@ rest_of_compilation (decl)
        ggc_collect ();
     }
 
+  cse_not_expected = 1;
+
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
       timevar_push (TV_BRANCH_PROB);
@@ -3103,10 +3138,6 @@ rest_of_compilation (decl)
   if (ggc_p)
     ggc_collect ();
 
-  /* The first life analysis pass has finished.  From now on we can not
-     generate any new pseudos.  */
-  no_new_pseudos = 1;
-
   /* If -opt, try combining insns through substitution.  */
 
   if (optimize > 0)
@@ -3127,6 +3158,20 @@ rest_of_compilation (decl)
          timevar_push (TV_JUMP);
          rebuild_jump_labels (insns);
          timevar_pop (TV_JUMP);
+
+         timevar_push (TV_FLOW);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (insns);
+
+         /* Blimey.  We've got to have the CFG up to date for the call to
+            if_convert below.  However, the random deletion of blocks
+            without updating life info can wind up with Wierd Stuff in
+            global_live_at_end.  We then run sched1, which updates things
+            properly, discovers the wierdness and aborts.  */
+         update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+                           PROP_DEATH_NOTES);
+
+         timevar_pop (TV_FLOW);
        }
 
       close_dump_file (DFI_combine, print_rtl_with_bb, insns);
@@ -3136,6 +3181,19 @@ rest_of_compilation (decl)
        ggc_collect ();
     }
 
+  /* Rerun if-conversion, as combine may have simplified things enough to
+     now meet sequence length restrictions.  */
+  if (optimize > 0)
+    {
+      timevar_push (TV_IFCVT);
+      open_dump_file (DFI_ce, decl);
+
+      if_convert (1);
+
+      close_dump_file (DFI_ce, print_rtl_with_bb, insns);
+      timevar_pop (TV_IFCVT);
+    }
+
   /* Register allocation pre-pass, to reduce number of moves
      necessary for two-address machines.  */
   if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
@@ -3178,6 +3236,10 @@ rest_of_compilation (decl)
 
       if (ggc_p)
        ggc_collect ();
+
+      /* Register lifetime information is up to date.  From now on
+        we can not generate any new pseudos.  */
+      no_new_pseudos = 1;
     }
 #endif
 
@@ -3197,7 +3259,13 @@ rest_of_compilation (decl)
   /* We recomputed reg usage as part of updating the rest
      of life info during sched.  */
   if (! flag_schedule_insns)
-    recompute_reg_usage (insns, ! optimize_size);
+    {
+      recompute_reg_usage (insns, ! optimize_size);
+
+      /* Register lifetime information is up to date.  From now on
+        we can not generate any new pseudos.  */
+      no_new_pseudos = 1;
+    }
   regclass (insns, max_reg_num (), rtl_dump_file);
   rebuild_label_notes_after_reload = local_alloc ();
 
@@ -3310,12 +3378,23 @@ rest_of_compilation (decl)
   close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
   timevar_pop (TV_FLOW2);
 
+  if (optimize > 0)
+    {
+      timevar_push (TV_IFCVT2);
+      open_dump_file (DFI_ce2, decl);
+
+      if_convert (1);
+
+      close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
+      timevar_pop (TV_IFCVT2);
+    }
+
 #ifdef HAVE_peephole2
   if (optimize > 0 && flag_peephole2)
     {
       timevar_push (TV_PEEPHOLE2);
-
       open_dump_file (DFI_peephole2, decl);
+
       peephole2_optimize (rtl_dump_file);
 
       close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
@@ -3380,6 +3459,8 @@ rest_of_compilation (decl)
       jump_optimize (insns, JUMP_CROSS_JUMP, JUMP_NOOP_MOVES, 
                     !JUMP_AFTER_REGSCAN);
 
+      /* CFG no longer kept up to date.  */
+
       close_dump_file (DFI_jump2, print_rtl_with_bb, insns);
       timevar_pop (TV_JUMP);
     }
@@ -4843,16 +4924,26 @@ debug_undef (lineno, buffer)
 #endif /* DWARF2_DEBUGGING_INFO */
 }
 
-/* Tell the debugging backend that we've decided not to emit any
-   debugging information for BLOCK, so it can clean up after any local
-   classes or nested functions.  */
+/* Returns nonzero if it is appropriate not to emit any debugging
+   information for BLOCK, because it doesn't contain any instructions.
+   This may not be the case for blocks containing nested functions, since
+   we may actually call such a function even though the BLOCK information
+   is messed up.  */
 
-void
+int
 debug_ignore_block (block)
      tree block ATTRIBUTE_UNUSED;
 {
+  /* Never delete the BLOCK for the outermost scope
+     of the function; we can refer to names from
+     that scope even if the block notes are messed up.  */
+  if (is_body_block (block))
+    return 0;
+
 #ifdef DWARF2_DEBUGGING_INFO
   if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_ignore_block (block);
+    return dwarf2out_ignore_block (block);
 #endif
+
+  return 1;
 }