basic-block.h (CLEANUP_PRE_SIBCALL): New constant.
authorJan Hubicka <jh@suse.cz>
Mon, 16 Jul 2001 20:54:44 +0000 (22:54 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 16 Jul 2001 20:54:44 +0000 (20:54 +0000)
* basic-block.h (CLEANUP_PRE_SIBCALL): New constant.
* except.c (finish_eh_generation): Update call of cleanup_cfg;
do rebuild_jump_labels instead of jump_optimize
* sibcall.c (optimize_sibling_and_tail_recursive_call): Likewise.
* toplev.c (rest_of_compulation): Likewise for -Wreturn_type.
* flow.c (try_optimize_cfg): Remove unneeded code_labels.

* flow.c: Include timevar.h
(find_basic_block): Push/pop timevar;
(cleanup_cfg): Likewise.
* timevar.def (TV_CFG, TV_CLEANUP_CFG): New.
* Makefile: Add dependencies on timevar.h

* integrate.c (save_for_inline): Kill all BASIC_BLOCK notes.
(copy_insn_list): Avoid killing of BASIC_BLOCK notes.

* rtl.h (delete_trivially_dead_insns): Add new parameter.
* toplev.c (rest_of_compilation): Update calls.
* cse.c (set_live_p, insn_live_p, dead_libcall_p): Break out from ...
(delete_trivially_dead_insns): ... here; accept new argument
preserve_basic_blocks; preserve basic blocks if set.

* reg-stack.c (stack_regs_mentioned): Return 0 if
stack_regs_mentioned_data is not initialized.
(reg_to_stack): Make stack_regs_mentioned survive after the
reg-stack is completted; do not call cleanup_cfg.
* toplev.c (rest_of_compilation): Do cleanup_cfg before bb-reorder;
make cleanup_cfg after bb-reorder to output to debug file.

From-SVN: r44056

12 files changed:
gcc/ChangeLog
gcc/basic-block.h
gcc/config.in
gcc/cse.c
gcc/except.c
gcc/flow.c
gcc/integrate.c
gcc/reg-stack.c
gcc/rtl.h
gcc/sibcall.c
gcc/timevar.def
gcc/toplev.c

index ef999bf7f7d35fee07339ba6562c72ecc9b7b435..f012bdae56cb202f319985620a8d360b85cf35e4 100644 (file)
@@ -1,3 +1,34 @@
+Mon Jul 16 22:48:00 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * basic-block.h (CLEANUP_PRE_SIBCALL): New constant.
+       * except.c (finish_eh_generation): Update call of cleanup_cfg;
+       do rebuild_jump_labels instead of jump_optimize
+       * sibcall.c (optimize_sibling_and_tail_recursive_call): Likewise.
+       * toplev.c (rest_of_compulation): Likewise for -Wreturn_type.
+       * flow.c (try_optimize_cfg): Remove unneeded code_labels.
+
+       * flow.c: Include timevar.h
+       (find_basic_block): Push/pop timevar;
+       (cleanup_cfg): Likewise.
+       * timevar.def (TV_CFG, TV_CLEANUP_CFG): New.
+       * Makefile: Add dependencies on timevar.h
+
+       * integrate.c (save_for_inline): Kill all BASIC_BLOCK notes.
+       (copy_insn_list): Avoid killing of BASIC_BLOCK notes.
+
+       * rtl.h (delete_trivially_dead_insns): Add new parameter.
+       * toplev.c (rest_of_compilation): Update calls.
+       * cse.c (set_live_p, insn_live_p, dead_libcall_p): Break out from ...
+       (delete_trivially_dead_insns): ... here; accept new argument
+       preserve_basic_blocks; preserve basic blocks if set.
+
+       * reg-stack.c (stack_regs_mentioned): Return 0 if
+       stack_regs_mentioned_data is not initialized.
+       (reg_to_stack): Make stack_regs_mentioned survive after the
+       reg-stack is completted; do not call cleanup_cfg.
+       * toplev.c (rest_of_compilation): Do cleanup_cfg before bb-reorder;
+       make cleanup_cfg after bb-reorder to output to debug file.
+
 2001-07-16  Richard Henderson  <rth@redhat.com>
 
        * regclass.c (init_reg_sets): Use only 32 bits per initializer
index 656c13b980177e2d40fc9350eafb3e07f04536cb..5b210fb981b7bd3f2bd3e3f3c041fb1c84196e5e 100644 (file)
@@ -540,6 +540,8 @@ enum update_life_extent
 #define CLEANUP_CROSSJUMP      2       /* Do crossjumping.  */
 #define CLEANUP_POST_REGSTACK  4       /* We run after reg-stack and need
                                           to care REG_DEAD notes.  */
+#define CLEANUP_PRE_SIBCALL    8       /* Do not get confused by code hidden
+                                          inside call_placeholders..  */
 /* Flags for loop discovery.  */
 
 #define LOOP_TREE              1       /* Build loop hierarchy tree.  */
index e9b10ef750d250bfad0d92d851a8ba47c52d5bca..53995ba2e4bae4980bea4e5ff301c11e65f4a896 100644 (file)
@@ -1,4 +1,4 @@
-/* config.in.  Generated automatically from configure.in by autoheader 2.13.  */
+/* config.in.  Generated automatically from configure.in by autoheader.  */
 
 /* Define to empty if the keyword does not work.  */
 #undef const
index 266f258d7580ffe9eb1674346a5cb0b7b2f760fb..70360d8699314ca7294fe3947067d8bfd20a020a 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -689,6 +689,9 @@ static struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
 static int check_dependence    PARAMS ((rtx *, void *));
 
 static void flush_hash_table   PARAMS ((void));
+static bool insn_live_p                PARAMS ((rtx, int *));
+static bool set_live_p         PARAMS ((rtx, int *));
+static bool dead_libcall_p     PARAMS ((rtx, int *));
 \f
 /* Dump the expressions in the equivalence class indicated by CLASSP.
    This function is used only for debugging.  */
@@ -7481,6 +7484,98 @@ count_reg_usage (x, counts, dest, incr)
     }
 }
 \f
+/* Return true if set is live.  */
+static bool
+set_live_p (set, counts)
+     rtx set;
+     int *counts;
+{
+#ifdef HAVE_cc0
+  rtx tem;
+#endif
+
+  if (set_noop_p (set))
+    ;
+
+#ifdef HAVE_cc0
+  else if (GET_CODE (SET_DEST (set)) == CC0
+          && !side_effects_p (SET_SRC (set))
+          && ((tem = next_nonnote_insn (insn)) == 0
+              || !INSN_P (tem)
+              || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
+    return false;
+#endif
+  else if (GET_CODE (SET_DEST (set)) != REG
+          || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
+          || counts[REGNO (SET_DEST (set))] != 0
+          || side_effects_p (SET_SRC (set))
+          /* An ADDRESSOF expression can turn into a use of the
+             internal arg pointer, so always consider the
+             internal arg pointer live.  If it is truly dead,
+             flow will delete the initializing insn.  */
+          || (SET_DEST (set) == current_function_internal_arg_pointer))
+    return true;
+  return false;
+}
+
+/* Return true if insn is live.  */
+
+static bool
+insn_live_p (insn, counts)
+     rtx insn;
+     int *counts;
+{
+  int i;
+  if (GET_CODE (PATTERN (insn)) == SET)
+    return set_live_p (PATTERN (insn), counts);
+  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+    for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+      {
+       rtx elt = XVECEXP (PATTERN (insn), 0, i);
+
+       if (GET_CODE (elt) == SET)
+         {
+           if (set_live_p (elt, counts))
+             return true;
+         }
+       else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
+         return true;
+      }
+  else
+    return true;
+}
+
+/* Return true if libcall is dead as a whole.  */
+
+static bool
+dead_libcall_p (insn, counts)
+     rtx insn;
+     int *counts;
+{
+  rtx note;
+  /* See if there's a REG_EQUAL note on this insn and try to
+     replace the source with the REG_EQUAL expression.
+
+     We assume that insns with REG_RETVALs can only be reg->reg
+     copies at this point.  */
+  note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+  if (note)
+    {
+      rtx set = single_set (insn);
+      rtx new = simplify_rtx (XEXP (note, 0));
+
+      if (!new)
+       new = XEXP (note, 0);
+
+      if (set && validate_change (insn, &SET_SRC (set), new, 0))
+       {
+         remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
+         return true;
+       }
+    }
+  return false;
+}
+
 /* Scan all the insns and delete any that are dead; i.e., they store a register
    that is never used or they copy a register to itself.
 
@@ -7490,17 +7585,16 @@ count_reg_usage (x, counts, dest, incr)
    remaining passes of the compilation are also sped up.  */
 
 void
-delete_trivially_dead_insns (insns, nreg)
+delete_trivially_dead_insns (insns, nreg, preserve_basic_blocks)
      rtx insns;
      int nreg;
+     int preserve_basic_blocks;
 {
   int *counts;
   rtx insn, prev;
-#ifdef HAVE_cc0
-  rtx tem;
-#endif
   int i;
   int in_libcall = 0, dead_libcall = 0;
+  basic_block bb;
 
   /* First count the number of times each register is used.  */
   counts = (int *) xcalloc (nreg, sizeof (int));
@@ -7518,124 +7612,89 @@ delete_trivially_dead_insns (insns, nreg)
   if (! INSN_P (insn))
     insn = prev_real_insn (insn);
 
-  for (; insn; insn = prev)
-    {
-      int live_insn = 0;
-      rtx note;
-
-      prev = prev_real_insn (insn);
+  if (!preserve_basic_blocks)
+    for (; insn; insn = prev)
+      {
+       int live_insn = 0;
+       rtx note;
 
-      /* Don't delete any insns that are part of a libcall block unless
-        we can delete the whole libcall block.
+       prev = prev_real_insn (insn);
 
-        Flow or loop might get confused if we did that.  Remember
-        that we are scanning backwards.  */
-      if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
-       {
-         in_libcall = 1;
-         live_insn = 1;
-         dead_libcall = 0;
+       /* Don't delete any insns that are part of a libcall block unless
+          we can delete the whole libcall block.
 
-         /* See if there's a REG_EQUAL note on this insn and try to
-            replace the source with the REG_EQUAL expression.
+          Flow or loop might get confused if we did that.  Remember
+          that we are scanning backwards.  */
+       if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+         {
+           in_libcall = 1;
+           live_insn = 1;
+           dead_libcall = dead_libcall_p (insn, counts);
+         }
+       else if (in_libcall)
+         live_insn = ! dead_libcall;
+       else
+         live_insn = insn_live_p (insn, counts);
 
-            We assume that insns with REG_RETVALs can only be reg->reg
-            copies at this point.  */
-         note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
-         if (note)
-           {
-             rtx set = single_set (insn);
-             rtx new = simplify_rtx (XEXP (note, 0));
+       /* If this is a dead insn, delete it and show registers in it aren't
+          being used.  */
 
-             if (!new)
-               new = XEXP (note, 0);
+       if (! live_insn)
+         {
+           count_reg_usage (insn, counts, NULL_RTX, -1);
+           delete_insn (insn);
+         }
 
-             if (set && validate_change (insn, &SET_SRC (set), new, 0))
-               {
-                 remove_note (insn,
-                              find_reg_note (insn, REG_RETVAL, NULL_RTX));
-                 dead_libcall = 1;
-               }
-           }
-       }
-      else if (in_libcall)
-       live_insn = ! dead_libcall;
-      else if (GET_CODE (PATTERN (insn)) == SET)
+       if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+         {
+           in_libcall = 0;
+           dead_libcall = 0;
+         }
+      }
+  else
+    for (i = 0; i < n_basic_blocks; i++)
+      for (bb = BASIC_BLOCK (i), insn = bb->end; insn != bb->head; insn = prev)
        {
-         if (set_noop_p (PATTERN (insn)))
-           ;
+         int live_insn = 0;
+         rtx note;
 
-#ifdef HAVE_cc0
-         else if (GET_CODE (SET_DEST (PATTERN (insn))) == CC0
-                  && ! side_effects_p (SET_SRC (PATTERN (insn)))
-                  && ((tem = next_nonnote_insn (insn)) == 0
-                      || ! INSN_P (tem)
-                      || ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
-           ;
-#endif
-         else if (GET_CODE (SET_DEST (PATTERN (insn))) != REG
-                  || REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
-                  || counts[REGNO (SET_DEST (PATTERN (insn)))] != 0
-                  || side_effects_p (SET_SRC (PATTERN (insn)))
-                  /* An ADDRESSOF expression can turn into a use of the
-                     internal arg pointer, so always consider the
-                     internal arg pointer live.  If it is truly dead,
-                     flow will delete the initializing insn.  */
-                  || (SET_DEST (PATTERN (insn))
-                      == current_function_internal_arg_pointer))
-           live_insn = 1;
-       }
-      else if (GET_CODE (PATTERN (insn)) == PARALLEL)
-       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
-         {
-           rtx elt = XVECEXP (PATTERN (insn), 0, i);
+         prev = PREV_INSN (insn);
+         if (!INSN_P (insn))
+           continue;
 
-           if (GET_CODE (elt) == SET)
-             {
-               if (set_noop_p (elt))
-                 ;
+         /* Don't delete any insns that are part of a libcall block unless
+            we can delete the whole libcall block.
 
-#ifdef HAVE_cc0
-               else if (GET_CODE (SET_DEST (elt)) == CC0
-                        && ! side_effects_p (SET_SRC (elt))
-                        && ((tem = next_nonnote_insn (insn)) == 0
-                            || ! INSN_P (tem)
-                            || ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
-                 ;
-#endif
-               else if (GET_CODE (SET_DEST (elt)) != REG
-                        || REGNO (SET_DEST (elt)) < FIRST_PSEUDO_REGISTER
-                        || counts[REGNO (SET_DEST (elt))] != 0
-                        || side_effects_p (SET_SRC (elt))
-                        /* An ADDRESSOF expression can turn into a use of the
-                           internal arg pointer, so always consider the
-                           internal arg pointer live.  If it is truly dead,
-                           flow will delete the initializing insn.  */
-                        || (SET_DEST (elt)
-                            == current_function_internal_arg_pointer))
-                 live_insn = 1;
-             }
-           else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
+            Flow or loop might get confused if we did that.  Remember
+            that we are scanning backwards.  */
+         if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+           {
+             in_libcall = 1;
              live_insn = 1;
-         }
-      else
-       live_insn = 1;
+             dead_libcall = dead_libcall_p (insn, counts);
+           }
+         else if (in_libcall)
+           live_insn = ! dead_libcall;
+         else
+           live_insn = insn_live_p (insn, counts);
 
-      /* If this is a dead insn, delete it and show registers in it aren't
-        being used.  */
+         /* If this is a dead insn, delete it and show registers in it aren't
+            being used.  */
 
-      if (! live_insn)
-       {
-         count_reg_usage (insn, counts, NULL_RTX, -1);
-         delete_insn (insn);
-       }
+         if (! live_insn)
+           {
+             count_reg_usage (insn, counts, NULL_RTX, -1);
+             if (insn == bb->end)
+               bb->end = PREV_INSN (insn);
+             flow_delete_insn (insn);
+           }
 
-      if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
-       {
-         in_libcall = 0;
-         dead_libcall = 0;
+         if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+           {
+             in_libcall = 0;
+             dead_libcall = 0;
+           }
        }
-    }
 
   /* Clean up.  */
   free (counts);
index 82ef3fe0944cc8cf8cf99192b0a58828d3e4ad9a..da50101264877560297f06b5e5cfcb5802fd8c7e 100644 (file)
@@ -2347,7 +2347,7 @@ finish_eh_generation ()
      connect many of the handlers, and then type information will not
      be effective.  Still, this is a win over previous implementations.  */
 
-  jump_optimize_minimal (get_insns ());
+  rebuild_jump_labels (get_insns ());
   find_basic_blocks (get_insns (), max_reg_num (), 0);
   cleanup_cfg (0);
 
@@ -2370,7 +2370,7 @@ finish_eh_generation ()
 
   /* We've totally changed the CFG.  Start over.  */
   find_exception_handler_labels ();
-  jump_optimize_minimal (get_insns ());
+  rebuild_jump_labels (get_insns ());
   find_basic_blocks (get_insns (), max_reg_num (), 0);
   cleanup_cfg (0);
 }
index 6d25582cebc646f0cac5660fa9de85516337e83b..a771ab4c3d162de318824263b896b44c8fc7e1a4 100644 (file)
@@ -135,6 +135,7 @@ Boston, MA 02111-1307, USA.  */
 #include "recog.h"
 #include "expr.h"
 #include "ssa.h"
+#include "timevar.h"
 
 #include "obstack.h"
 #include "splay-tree.h"
@@ -499,6 +500,7 @@ find_basic_blocks (f, nregs, file)
      FILE *file ATTRIBUTE_UNUSED;
 {
   int max_uid;
+  timevar_push (TV_CFG);
 
   /* Flush out existing data.  */
   if (basic_block_info != NULL)
@@ -556,6 +558,7 @@ find_basic_blocks (f, nregs, file)
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif
+  timevar_pop (TV_CFG);
 }
 
 void
@@ -1002,6 +1005,7 @@ void
 cleanup_cfg (mode)
      int mode;
 {
+  timevar_push (TV_CLEANUP_CFG);
   delete_unreachable_blocks ();
   if (try_optimize_cfg (mode))
     delete_unreachable_blocks ();
@@ -1010,6 +1014,7 @@ cleanup_cfg (mode)
   /* Kill the data we won't maintain.  */
   free_EXPR_LIST_list (&label_value_list);
   free_EXPR_LIST_list (&tail_recursion_label_list);
+  timevar_pop (TV_CLEANUP_CFG);
 }
 
 /* Create a new basic block consisting of the instructions between
@@ -2960,6 +2965,14 @@ merge_blocks (e, b, c, mode)
       int c_has_outgoing_fallthru;
       int b_has_incoming_fallthru;
 
+      /* Avoid overactive code motion, as the forwarder blocks should eb
+         eliminated by the edge redirection instead. Only exception is the
+        case b is an forwarder block and c has no fallthru edge, but no
+        optimizers should be confused by this extra jump and we are about
+        to kill the jump in bb_reorder pass instead.  */
+      if (forwarder_block_p (b) || forwarder_block_p (c))
+       return 0;
+
       /* We must make sure to not munge nesting of exception regions,
         lexical blocks, and loop notes.
 
@@ -3688,6 +3701,26 @@ try_optimize_cfg (mode)
              b = c;
            }
 
+         /* Remove code labels no longer used.  
+            Don't do the optimization before sibling calls are discovered,
+            as some branches may be hidden inside CALL_PLACEHOLDERs.  */
+         if (!(mode & CLEANUP_PRE_SIBCALL)
+             && b->pred->pred_next == NULL
+             && (b->pred->flags & EDGE_FALLTHRU)
+             && GET_CODE (b->head) == CODE_LABEL
+             /* If previous block does end with condjump jumping to next BB,
+                we can't delete the label.  */
+             && (b->pred->src == ENTRY_BLOCK_PTR
+                 || !reg_mentioned_p (b->head, b->pred->src->end)))
+           {
+             rtx label = b->head;
+             b->head = NEXT_INSN (b->head);
+             flow_delete_insn_chain (label, label);
+             if (rtl_dump_file)
+               fprintf (rtl_dump_file, "Deleted label in block %i.\n",
+                        b->index);
+           }
+
          /* A loop because chains of blocks might be combineable.  */
          while ((s = b->succ) != NULL
                 && s->succ_next == NULL
index bcb65e826a3e1e5d18311cc68258c96786e83c10..a642dcc1e08c98823ae97e11fe09016595a7f6e6 100644 (file)
@@ -427,6 +427,13 @@ save_for_inline (fndecl)
 
   argvec = initialize_for_inline (fndecl);
 
+  /* Delete basic block notes created by early run of find_basic_block.
+     The notes would be later used by find_basic_blocks to reuse the memory
+     for basic_block structures on already freed obstack.  */
+  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+    if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
+      delete_insn (insn);
+
   /* If there are insns that copy parms from the stack into pseudo registers,
      those insns are not copied.  `expand_inline_function' must
      emit the correct code to handle such things.  */
@@ -1552,17 +1559,11 @@ copy_insn_list (insns, map, static_chain_value)
             discarded because it is important to have only one of
             each in the current function.
 
-            NOTE_INSN_DELETED notes aren't useful.
-
-            NOTE_INSN_BASIC_BLOCK is discarded because the saved bb
-            pointer (which will soon be dangling) confuses flow's
-            attempts to preserve bb structures during the compilation
-            of a function.  */
+            NOTE_INSN_DELETED notes aren't useful.  */
 
          if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
-             && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
-             && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
+             && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
            {
              copy = emit_note (NOTE_SOURCE_FILE (insn),
                                NOTE_LINE_NUMBER (insn));
index bdd1c98dbbf3245efeb165a46054e7dc57c87c94..19f666087bdcf5653db5e7f4ed764dd1ad4c59da 100644 (file)
@@ -303,7 +303,7 @@ stack_regs_mentioned (insn)
   unsigned int uid, max;
   int test;
 
-  if (! INSN_P (insn))
+  if (! INSN_P (insn) || !stack_regs_mentioned_data)
     return 0;
 
   uid = INSN_UID (insn);
@@ -419,6 +419,13 @@ reg_to_stack (first, file)
   int max_uid;
   block_info bi;
 
+  /* Clean up previous run.  */
+  if (stack_regs_mentioned_data)
+    {
+      VARRAY_FREE (stack_regs_mentioned_data);
+      stack_regs_mentioned_data = 0;
+    }
+
   if (!optimize)
     split_all_insns (0);
 
@@ -479,11 +486,8 @@ reg_to_stack (first, file)
   VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
                    "stack_regs_mentioned cache");
 
-  if (convert_regs (file) && optimize)
-    cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP | CLEANUP_POST_REGSTACK);
+  convert_regs (file);
 
-  /* Clean up.  */
-  VARRAY_FREE (stack_regs_mentioned_data);
   free (bi);
 }
 \f
index 5dd39862097146644e6660f2a08ef073e407990d..0401f8deea87706e1aa98242a9ffc30657fa8322 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1689,7 +1689,7 @@ struct cse_basic_block_data;
 
 extern int rtx_cost                    PARAMS ((rtx, enum rtx_code));
 extern int address_cost                        PARAMS ((rtx, enum machine_mode));
-extern void delete_trivially_dead_insns        PARAMS ((rtx, int));
+extern void delete_trivially_dead_insns        PARAMS ((rtx, int, int));
 #ifdef BUFSIZ
 extern int cse_main                    PARAMS ((rtx, int, int, FILE *));
 #endif
index 62184e84a5b0da881d561b60ce3a69ff11fac6da..1203e68423499a7f60e2eacd58b596a25bbfea62 100644 (file)
@@ -565,11 +565,11 @@ optimize_sibling_and_tail_recursive_calls ()
      ahead and find all the EH labels.  */
   find_exception_handler_labels ();
 
-  jump_optimize_minimal (insns);
+  rebuild_jump_labels (insns);
   /* We need cfg information to determine which blocks are succeeded
      only by the epilogue.  */
   find_basic_blocks (insns, max_reg_num (), 0);
-  cleanup_cfg (0);
+  cleanup_cfg (CLEANUP_PRE_SIBCALL);
 
   /* If there are no basic blocks, then there is nothing to do.  */
   if (n_basic_blocks == 0)
index f07a7d26434fc0259d6367b50e5553c7e7d36bed..1ad57a1c504d7aa57069e4deed7c39bf6233be2d 100644 (file)
@@ -39,6 +39,10 @@ DEFTIMEVAR (TV_GC                    , "garbage collection")
 /* Time spent generating dump files.  */
 DEFTIMEVAR (TV_DUMP                  , "dump files")
 
+/* Time spent by constructing CFG.  */
+DEFTIMEVAR (TV_CFG                   , "cfg construction")
+/* Time spent by cleaning up CFG.  */
+DEFTIMEVAR (TV_CLEANUP_CFG           , "cfg cleanup")
 /* Timing in various stages of the compiler.  */
 DEFTIMEVAR (TV_CPP                  , "preprocessing")
 DEFTIMEVAR (TV_LEX                  , "lexical analysis")
index 746ea908afa368888fd3d371716afaa15c789c30..e357d62b6d386be3eaa0301478872cedfcf118f1 100644 (file)
@@ -2827,17 +2827,18 @@ rest_of_compilation (decl)
       if (DECL_DEFER_OUTPUT (decl))
        {
          /* If -Wreturn-type, we have to do a bit of compilation.  We just
-            want to call jump_optimize to figure out whether or not we can
+            want to call cleanup the cfg to figure out whether or not we can
             fall off the end of the function; we do the minimum amount of
-            work necessary to make that safe.  And, we set optimize to zero
-            to keep jump_optimize from working too hard.  */
+            work necessary to make that safe.  */
          if (warn_return_type)
            {
              int saved_optimize = optimize;
 
              optimize = 0;
+             rebuild_jump_labels (insns);
              find_exception_handler_labels ();
-             jump_optimize (insns, !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
+             find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+             cleanup_cfg (CLEANUP_PRE_SIBCALL);
              optimize = saved_optimize;
            }
 
@@ -3092,7 +3093,7 @@ rest_of_compilation (decl)
 
       /* Run this after jump optmizations remove all the unreachable code
         so that unreachable code will not keep values live.  */
-      delete_trivially_dead_insns (insns, max_reg_num ());
+      delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
       /* Try to identify useless null pointer tests and delete them.  */
       if (flag_delete_null_pointer_checks)
@@ -3195,7 +3196,7 @@ rest_of_compilation (decl)
             trivially dead.  We delete those instructions now in the
             hope that doing so will make the heuristics in loop work
             better and possibly speed up compilation.  */
-         delete_trivially_dead_insns (insns, max_reg_num ());
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
          /* The regscan pass is currently necessary as the alias
                  analysis code depends on this information.  */
@@ -3228,7 +3229,7 @@ rest_of_compilation (decl)
             trivially dead.  We delete those instructions now in the
             hope that doing so will make the heuristics in jump work
             better and possibly speed up compilation.  */
-         delete_trivially_dead_insns (insns, max_reg_num ());
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
          reg_scan (insns, max_reg_num (), 0);
          jump_optimize (insns, !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
@@ -3672,15 +3673,22 @@ rest_of_compilation (decl)
 
   ggc_collect ();
 #endif
-  if (optimize > 0 && flag_reorder_blocks)
+  if (optimize > 0)
     {
       timevar_push (TV_REORDER_BLOCKS);
       open_dump_file (DFI_bbro, decl);
 
-      reorder_basic_blocks ();
+      /* Last attempt to optimize CFG, as life analyzis possibly removed
+        some instructions.  */
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+                  | CLEANUP_CROSSJUMP);
+      if (flag_reorder_blocks)
+       {
+         reorder_basic_blocks ();
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
+       }
 
       close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
-      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
       timevar_pop (TV_REORDER_BLOCKS);
     }