OSDN Git Service

* flow.c (propagate_one_insn): Break out from propagate_block.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Apr 2000 05:03:35 +0000 (05:03 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Apr 2000 05:03:35 +0000 (05:03 +0000)
        (init_propagate_block_info): Likewise.
        (free_propagate_block_info): Likewise.
        (propagate_block): Use them.  Export.
        * basic-block.h: Declare them all.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33460 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/basic-block.h
gcc/flow.c

index d7d2fd5..5598f71 100644 (file)
@@ -1,5 +1,13 @@
 2000-04-26  Richard Henderson  <rth@cygnus.com>
 
+       * flow.c (propagate_one_insn): Break out from propagate_block.
+       (init_propagate_block_info): Likewise.
+       (free_propagate_block_info): Likewise.
+       (propagate_block): Use them.  Export.
+       * basic-block.h: Declare them all.
+
+2000-04-26  Richard Henderson  <rth@cygnus.com>
+
        * basic-block.h (life_analysis): Declare here ...
        * output.h: ... not here.
        * flow.c (life_analysis): Remove nregs parameter; replace
index f8da181..f9eb268 100644 (file)
@@ -431,6 +431,13 @@ extern void life_analysis  PARAMS ((rtx, FILE *, int));
 extern void update_life_info   PARAMS ((sbitmap, enum update_life_extent,
                                         int));
 extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
+extern void propagate_block    PARAMS ((basic_block, regset, regset, int));
+
+struct propagate_block_info;
+extern rtx propagate_one_insn  PARAMS ((struct propagate_block_info *, rtx));
+extern struct propagate_block_info *init_propagate_block_info
+  PARAMS ((basic_block, regset, regset, int));
+extern void free_propagate_block_info PARAMS ((struct propagate_block_info *));
 
 /* In lcm.c */
 extern struct edge_list *pre_edge_lcm  PARAMS ((FILE *, int, sbitmap *,
index 16537e2..dbff5de 100644 (file)
@@ -329,8 +329,6 @@ static int set_phi_alternative_reg      PARAMS ((rtx, int, int, void *));
 static void calculate_global_regs_live PARAMS ((sbitmap, sbitmap, int));
 static void propagate_block_delete_insn PARAMS ((basic_block, rtx));
 static rtx propagate_block_delete_libcall PARAMS ((basic_block, rtx, rtx));
-static void propagate_block            PARAMS ((basic_block, regset,
-                                                regset, int));
 static int insn_dead_p                 PARAMS ((struct propagate_block_info *,
                                                 rtx, int, rtx));
 static int libcall_dead_p              PARAMS ((struct propagate_block_info *,
@@ -3267,285 +3265,319 @@ propagate_block_delete_libcall (bb, insn, note)
   return before;
 }
 
-/* Compute the registers live at the beginning of a basic block BB from
-   those live at the end.
-
-   When called, REG_LIVE contains those live at the end.  On return, it
-   contains those live at the beginning.
+/* Update the life-status of regs for one insn.  Return the previous insn.  */
 
-   LOCAL_SET, if non-null, will be set with all registers killed by 
-   this basic block.  */
-
-static void
-propagate_block (bb, live, local_set, flags)
-     basic_block bb;
-     regset live;
-     regset local_set;
-     int flags;
+rtx
+propagate_one_insn (pbi, insn)
+     struct propagate_block_info *pbi;
+     rtx insn;
 {
-  struct propagate_block_info pbi;
-  rtx insn, prev;
-  regset_head new_live_head, new_dead_head;
-  
-  pbi.bb = bb;
-  pbi.reg_live = live;
-  pbi.mem_set_list = NULL_RTX;
-  pbi.local_set = local_set;
-  pbi.cc0_live = 0;
-  pbi.flags = flags;
+  rtx prev = PREV_INSN (insn);
+  int flags = pbi->flags;
+  int insn_is_dead = 0;
+  int libcall_is_dead = 0;
+  rtx note;
+  int i;
 
-  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
-    pbi.reg_next_use = (rtx *) xcalloc (max_reg_num (), sizeof (rtx));
-  else
-    pbi.reg_next_use = NULL;
+  if (! INSN_P (insn))
+    return prev;
 
-  pbi.new_live = INITIALIZE_REG_SET (new_live_head);
-  pbi.new_dead = INITIALIZE_REG_SET (new_dead_head);
+  note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
+  if (flags & PROP_SCAN_DEAD_CODE)
+    {
+      insn_is_dead = insn_dead_p (pbi, PATTERN (insn), 0,
+                                 REG_NOTES (insn));
+      libcall_is_dead = (insn_is_dead && note != 0
+                        && libcall_dead_p (pbi, PATTERN (insn),
+                                           note, insn));
+    }
+
+  /* We almost certainly don't want to delete prologue or epilogue
+     instructions.  Warn about probable compiler losage.  */
+  if (insn_is_dead
+      && reload_completed
+      && (((HAVE_epilogue || HAVE_prologue)
+          && prologue_epilogue_contains (insn))
+         || (HAVE_sibcall_epilogue
+             && sibcall_epilogue_contains (insn))))
+    {
+      if (flags & PROP_KILL_DEAD_CODE)
+       { 
+         warning ("ICE: would have deleted prologue/epilogue insn");
+         if (!inhibit_warnings)
+           debug_rtx (insn);
+       }
+      libcall_is_dead = insn_is_dead = 0;
+    }
 
-  if (flags & PROP_REG_INFO)
+  /* If an instruction consists of just dead store(s) on final pass,
+     delete it.  */
+  if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
     {
-      register int i;
+      if (libcall_is_dead)
+       {
+         prev = propagate_block_delete_libcall (pbi->bb, insn, note);
+         insn = NEXT_INSN (prev);
+       }
+      else
+       propagate_block_delete_insn (pbi->bb, insn);
 
-      /* Process the regs live at the end of the block.
-        Mark them as not local to any one basic block. */
-      EXECUTE_IF_SET_IN_REG_SET (live, 0, i,
-                                {
-                                  REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
-                                });
+      /* CC0 is now known to be dead.  Either this insn used it,
+        in which case it doesn't anymore, or clobbered it,
+        so the next insn can't use it.  */
+      pbi->cc0_live = 0;
+
+      return prev;
     }
 
-  /* Scan the block an insn at a time from end to beginning.  */
+  /* See if this is an increment or decrement that can be merged into
+     a following memory address.  */
+#ifdef AUTO_INC_DEC
+  {
+    register rtx x = single_set (insn);
+
+    /* Does this instruction increment or decrement a register?  */
+    if (!reload_completed
+       && (flags & PROP_AUTOINC)
+       && x != 0
+       && GET_CODE (SET_DEST (x)) == REG
+       && (GET_CODE (SET_SRC (x)) == PLUS
+           || GET_CODE (SET_SRC (x)) == MINUS)
+       && XEXP (SET_SRC (x), 0) == SET_DEST (x)
+       && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
+       /* Ok, look for a following memory ref we can combine with.
+          If one is found, change the memory ref to a PRE_INC
+          or PRE_DEC, cancel this insn, and return 1.
+          Return 0 if nothing has been done.  */
+       && try_pre_increment_1 (pbi, insn))
+      return prev;
+  }
+#endif /* AUTO_INC_DEC */
 
-  for (insn = bb->end; ; insn = prev)
+  CLEAR_REG_SET (pbi->new_live);
+  CLEAR_REG_SET (pbi->new_dead);
+
+  /* If this is not the final pass, and this insn is copying the value of
+     a library call and it's dead, don't scan the insns that perform the
+     library call, so that the call's arguments are not marked live.  */
+  if (libcall_is_dead)
+    {
+      /* Record the death of the dest reg.  */
+      mark_set_regs (pbi, PATTERN (insn), insn);
+
+      insn = XEXP (note, 0);
+      return PREV_INSN (insn);
+    }
+  else if (GET_CODE (PATTERN (insn)) == SET
+          && SET_DEST (PATTERN (insn)) == stack_pointer_rtx
+          && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
+          && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx
+          && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+    /* We have an insn to pop a constant amount off the stack.
+       (Such insns use PLUS regardless of the direction of the stack,
+       and any insn to adjust the stack by a constant is always a pop.)
+       These insns, if not dead stores, have no effect on life.  */
+    ;
+  else
     {
-      prev = PREV_INSN (insn);
+      /* Any regs live at the time of a call instruction must not go
+        in a register clobbered by calls.  Find all regs now live and
+        record this for them.  */
 
-      if (GET_CODE (insn) == NOTE)
-       {
-         /* If this is a call to `setjmp' et al,
-            warn if any non-volatile datum is live.  */
+      if (GET_CODE (insn) == CALL_INSN && (flags & PROP_REG_INFO))
+       EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i,
+                                  { REG_N_CALLS_CROSSED (i)++; });
 
-         if ((flags & PROP_REG_INFO)
-             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
-           IOR_REG_SET (regs_live_at_setjmp, pbi.reg_live);
+      /* Record sets.  Do this even for dead instructions, since they
+        would have killed the values if they hadn't been deleted.  */
+      mark_set_regs (pbi, PATTERN (insn), insn);
+
+      if (GET_CODE (insn) == CALL_INSN)
+       {
+         register int i;
+         rtx note, cond;
+
+         cond = NULL_RTX;
+         if (GET_CODE (PATTERN (insn)) == COND_EXEC)
+           cond = COND_EXEC_TEST (PATTERN (insn));
+
+         /* Non-constant calls clobber memory.  */
+         if (! CONST_CALL_P (insn))
+           free_EXPR_LIST_list (&pbi->mem_set_list);
+
+         /* There may be extra registers to be clobbered.  */
+         for (note = CALL_INSN_FUNCTION_USAGE (insn);
+              note;
+              note = XEXP (note, 1))
+           if (GET_CODE (XEXP (note, 0)) == CLOBBER)
+             mark_set_1 (pbi, XEXP (XEXP (note, 0), 0), cond, insn);
+
+         /* Calls change all call-used and global registers.  */
+         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+           if (call_used_regs[i] && ! global_regs[i]
+               && ! fixed_regs[i])
+             {
+               int dummy;
+               mark_set_reg (pbi, gen_rtx_REG (reg_raw_mode[i], i),
+                             cond, &dummy, &dummy);
+             }
        }
 
-      /* Update the life-status of regs for this insn.
-        First DEAD gets which regs are set in this insn
-        then LIVE gets which regs are used in this insn.
-        Then the regs live before the insn
-        are those live after, with DEAD regs turned off,
-        and then LIVE regs turned on.  */
+      /* If an insn doesn't use CC0, it becomes dead since we assume
+        that every insn clobbers it.  So show it dead here;
+        mark_used_regs will set it live if it is referenced.  */
+      pbi->cc0_live = 0;
+
+      /* Record uses.  */
+      if (! insn_is_dead)
+       mark_used_regs (pbi, PATTERN (insn), NULL_RTX, insn);
 
-      else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+      /* Sometimes we may have inserted something before INSN (such as a move)
+        when we make an auto-inc.  So ensure we will scan those insns.  */
+#ifdef AUTO_INC_DEC
+      prev = PREV_INSN (insn);
+#endif
+
+      if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
        {
          register int i;
-         rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
-         int insn_is_dead = 0;
-         int libcall_is_dead = 0;
+         rtx note, cond;
+
+         cond = NULL_RTX;
+         if (GET_CODE (PATTERN (insn)) == COND_EXEC)
+           cond = COND_EXEC_TEST (PATTERN (insn));
+
+         /* Calls use their arguments.  */
+         for (note = CALL_INSN_FUNCTION_USAGE (insn);
+              note;
+              note = XEXP (note, 1))
+           if (GET_CODE (XEXP (note, 0)) == USE)
+             mark_used_regs (pbi, XEXP (XEXP (note, 0), 0),
+                             cond, insn);
+
+         /* The stack ptr is used (honorarily) by a CALL insn.  */
+         SET_REGNO_REG_SET (pbi->reg_live, STACK_POINTER_REGNUM);
+
+         /* Calls may also reference any of the global registers,
+            so they are made live.  */
+         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+           if (global_regs[i])
+             mark_used_reg (pbi, gen_rtx_REG (reg_raw_mode[i], i),
+                            cond, insn);
+       }
+    }
 
-         if (flags & PROP_SCAN_DEAD_CODE)
-           {
-             insn_is_dead = insn_dead_p (&pbi, PATTERN (insn), 0,
-                                         REG_NOTES (insn));
-             libcall_is_dead = (insn_is_dead && note != 0
-                                && libcall_dead_p (&pbi, PATTERN (insn),
-                                                   note, insn));
-           }
+  /* Update reg_live for the registers killed and used.  */
+  AND_COMPL_REG_SET (pbi->reg_live, pbi->new_dead);
+  IOR_REG_SET (pbi->reg_live, pbi->new_live);
 
-         /* We almost certainly don't want to delete prologue or epilogue
-            instructions.  Warn about probable compiler losage.  */
-         if (insn_is_dead
-             && reload_completed
-             && (((HAVE_epilogue || HAVE_prologue)
-                  && prologue_epilogue_contains (insn))
-                 || (HAVE_sibcall_epilogue
-                     && sibcall_epilogue_contains (insn))))
-           {
-             if (flags & PROP_KILL_DEAD_CODE)
-               { 
-                 warning ("ICE: would have deleted prologue/epilogue insn");
-                 if (!inhibit_warnings)
-                   debug_rtx (insn);
-               }
-             libcall_is_dead = insn_is_dead = 0;
-           }
+  /* On final pass, update counts of how many insns in which each reg
+     is live.  */
+  if (flags & PROP_REG_INFO)
+    EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i,
+                              { REG_LIVE_LENGTH (i)++; });
 
-         /* If an instruction consists of just dead store(s) on final pass,
-            delete it.  */
-         if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
-           {
-             if (libcall_is_dead)
-               {
-                 prev = propagate_block_delete_libcall (bb, insn, note);
-                 insn = NEXT_INSN (prev);
-               }
-             else
-               propagate_block_delete_insn (bb, insn);
+  return prev;
+}
 
-             /* CC0 is now known to be dead.  Either this insn used it,
-                in which case it doesn't anymore, or clobbered it,
-                so the next insn can't use it.  */
-             pbi.cc0_live = 0;
+/* Initialize a propagate_block_info struct for public consumption.
+   Note that the structure itself is opaque to this file, but that
+   the user can use the regsets provided here.  */
 
-             goto flushed;
-           }
+struct propagate_block_info *
+init_propagate_block_info (bb, live, local_set, flags)
+     basic_block bb;
+     regset live;
+     regset local_set;
+     int flags;
+{
+  struct propagate_block_info *pbi = xmalloc (sizeof(*pbi));
 
-         /* See if this is an increment or decrement that can be
-            merged into a following memory address.  */
-#ifdef AUTO_INC_DEC
-         {
-           register rtx x = single_set (insn);
-
-           /* Does this instruction increment or decrement a register?  */
-           if (!reload_completed
-               && (flags & PROP_AUTOINC)
-               && x != 0
-               && GET_CODE (SET_DEST (x)) == REG
-               && (GET_CODE (SET_SRC (x)) == PLUS
-                   || GET_CODE (SET_SRC (x)) == MINUS)
-               && XEXP (SET_SRC (x), 0) == SET_DEST (x)
-               && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
-               /* Ok, look for a following memory ref we can combine with.
-                  If one is found, change the memory ref to a PRE_INC
-                  or PRE_DEC, cancel this insn, and return 1.
-                  Return 0 if nothing has been done.  */
-               && try_pre_increment_1 (&pbi, insn))
-             goto flushed;
-         }
-#endif /* AUTO_INC_DEC */
+  pbi->bb = bb;
+  pbi->reg_live = live;
+  pbi->mem_set_list = NULL_RTX;
+  pbi->local_set = local_set;
+  pbi->cc0_live = 0;
+  pbi->flags = flags;
 
-         CLEAR_REG_SET (pbi.new_live);
-         CLEAR_REG_SET (pbi.new_dead);
+  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+    pbi->reg_next_use = (rtx *) xcalloc (max_reg_num (), sizeof (rtx));
+  else
+    pbi->reg_next_use = NULL;
 
-         /* If this is not the final pass, and this insn is copying the
-            value of a library call and it's dead, don't scan the
-            insns that perform the library call, so that the call's
-            arguments are not marked live.  */
-         if (libcall_is_dead)
-           {
-             /* Record the death of the dest reg.  */
-             mark_set_regs (&pbi, PATTERN (insn), insn);
+  pbi->new_live = BITMAP_XMALLOC ();
+  pbi->new_dead = BITMAP_XMALLOC ();
 
-             insn = XEXP (note, 0);
-             prev = PREV_INSN (insn);
-           }
-         else if (GET_CODE (PATTERN (insn)) == SET
-                  && SET_DEST (PATTERN (insn)) == stack_pointer_rtx
-                  && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
-                  && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx
-                  && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
-           /* We have an insn to pop a constant amount off the stack.
-              (Such insns use PLUS regardless of the direction of the stack,
-              and any insn to adjust the stack by a constant is always a pop.)
-              These insns, if not dead stores, have no effect on life.  */
-           ;
-         else
-           {
-             /* Any regs live at the time of a call instruction
-                must not go in a register clobbered by calls.
-                Find all regs now live and record this for them.  */
-
-             if (GET_CODE (insn) == CALL_INSN
-                 && (flags & PROP_REG_INFO))
-               EXECUTE_IF_SET_IN_REG_SET (pbi.reg_live, 0, i,
-                                          { REG_N_CALLS_CROSSED (i)++; });
-
-             /* Record sets.  Do this even for dead instructions,
-                since they would have killed the values if they hadn't
-                been deleted.  */
-             mark_set_regs (&pbi, PATTERN (insn), insn);
-
-             /* If an insn doesn't use CC0, it becomes dead since we 
-                assume that every insn clobbers it.  So show it dead here;
-                mark_used_regs will set it live if it is referenced.  */
-             pbi.cc0_live = 0;
-
-             /* Record uses.  */
-             if (! insn_is_dead)
-               mark_used_regs (&pbi, PATTERN (insn), NULL_RTX, insn);
-
-             /* Sometimes we may have inserted something before INSN
-                (such as a move) when we make an auto-inc.  So ensure
-                we will scan those insns.  */
-#ifdef AUTO_INC_DEC
-             prev = PREV_INSN (insn);
-#endif
+  return pbi;
+}
 
-             if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
-               {
-                 register int i;
-                 rtx note, cond;
+/* Release a propagate_block_info struct.  */
 
-                 cond = NULL_RTX;
-                 if (GET_CODE (PATTERN (insn)) == COND_EXEC)
-                   cond = COND_EXEC_TEST (PATTERN (insn));
+void
+free_propagate_block_info (pbi)
+     struct propagate_block_info *pbi;
+{
+  free_EXPR_LIST_list (&pbi->mem_set_list);
 
-                 /* Non-constant calls clobber memory.  */
-                 if (! CONST_CALL_P (insn))
-                   free_EXPR_LIST_list (&pbi.mem_set_list);
+  BITMAP_XFREE (pbi->new_live);
+  BITMAP_XFREE (pbi->new_dead);
 
-                 /* There may be extra registers to be clobbered.  */
-                 for (note = CALL_INSN_FUNCTION_USAGE (insn);
-                      note;
-                      note = XEXP (note, 1))
-                   if (GET_CODE (XEXP (note, 0)) == CLOBBER)
-                     mark_set_1 (&pbi, XEXP (XEXP (note, 0), 0),
-                                 cond, insn);
-
-                 /* Calls change all call-used and global registers.  */
-                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-                   if (call_used_regs[i] && ! global_regs[i]
-                       && ! fixed_regs[i])
-                     {
-                       int dummy;
-                       mark_set_reg (&pbi, gen_rtx_REG (reg_raw_mode[i], i),
-                                     cond, &dummy, &dummy);
-                     }
-
-                 /* Calls use their arguments.  */
-                 for (note = CALL_INSN_FUNCTION_USAGE (insn);
-                      note;
-                      note = XEXP (note, 1))
-                   if (GET_CODE (XEXP (note, 0)) == USE)
-                     mark_used_regs (&pbi, XEXP (XEXP (note, 0), 0),
-                                     cond, insn);
-
-                 /* The stack ptr is used (honorarily) by a CALL insn.  */
-                 SET_REGNO_REG_SET (pbi.new_live, STACK_POINTER_REGNUM);
-
-                 /* Calls may also reference any of the global registers,
-                    so they are made live.  */
-                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-                   if (global_regs[i])
-                     mark_used_reg (&pbi, gen_rtx_REG (reg_raw_mode[i], i),
-                                    cond, insn);
-               }
-           }
+  if (pbi->reg_next_use)
+    free (pbi->reg_next_use);
 
-         /* Update reg_live for the registers killed and used.  */
-         AND_COMPL_REG_SET (pbi.reg_live, pbi.new_dead);
-         IOR_REG_SET (pbi.reg_live, pbi.new_live);
+  free (pbi);
+}
+
+/* Compute the registers live at the beginning of a basic block BB from
+   those live at the end.
+
+   When called, REG_LIVE contains those live at the end.  On return, it
+   contains those live at the beginning.
+
+   LOCAL_SET, if non-null, will be set with all registers killed by 
+   this basic block.  */
+
+void
+propagate_block (bb, live, local_set, flags)
+     basic_block bb;
+     regset live;
+     regset local_set;
+     int flags;
+{
+  struct propagate_block_info *pbi;
+  rtx insn, prev;
+  
+  pbi = init_propagate_block_info (bb, live, local_set, flags);
+
+  if (flags & PROP_REG_INFO)
+    {
+      register int i;
+
+      /* Process the regs live at the end of the block.
+        Mark them as not local to any one basic block. */
+      EXECUTE_IF_SET_IN_REG_SET (live, 0, i,
+                                { REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL; });
+    }
+
+  /* Scan the block an insn at a time from end to beginning.  */
+
+  for (insn = bb->end; ; insn = prev)
+    {
+      /* If this is a call to `setjmp' et al, warn if any
+        non-volatile datum is live.  */
+      if ((flags & PROP_REG_INFO)
+         && GET_CODE (insn) == NOTE
+         && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
+       IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
+
+      prev = propagate_one_insn (pbi, insn);
 
-         /* On final pass, update counts of how many insns in which
-            each reg is live.  */
-         if (flags & PROP_REG_INFO)
-           EXECUTE_IF_SET_IN_REG_SET (pbi.reg_live, 0, i,
-                                      { REG_LIVE_LENGTH (i)++; });
-       }
-    flushed:
       if (insn == bb->head)
        break;
     }
 
-  FREE_REG_SET (pbi.new_live);
-  FREE_REG_SET (pbi.new_dead);
-  free_EXPR_LIST_list (&pbi.mem_set_list);
-
-  if (pbi.reg_next_use)
-    free (pbi.reg_next_use);
+  free_propagate_block_info (pbi);
 }
-
 \f
 /* Return 1 if X (the body of an insn, or part of it) is just dead stores
    (SET expressions whose destinations are registers dead after the insn).