diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d6fad5631dff8017fb2708c95a2763e7c4e78c4b..29ad2683c86a8f9d0b0ef38cd3c399dd6f0b1fda 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+Wed Mar 31 12:32:43 1999  Richard Henderson  <rth@cygnus.com>
+
+	* flow.c (find_basic_blocks): New argument `do_cleanup'.
+	Conditionally call delete_unreachable_blocks.
+	(free_basic_block_vars): Zero ENTRY/EXIT data.
+	(allocate_for_life_analysis): Kill.  Split into...
+	(allocate_bb_life_data, allocate_reg_life_data): ... new functions.
+	(life_analysis_1): Update.
+	* gcse.c (gcse_main): Update find_basic_blocks call.
+	* toplev.c (rest_of_compilation): Likewise.
+	* stupid.c (stupid_life_analysis): Update life data calls.
+	* rtl.h, output.h: Update prototypes.
+
 Wed Mar 31 12:10:00 1999  Bruce Korb <ddsinc09@ix.netcom.com>
 
 	* inclhack.def (several): added spaces in tests to ensure
diff --git a/gcc/flow.c b/gcc/flow.c
index 3c3c0904633509463b0d8db07819e3b89fb5b126..0d2f486ab39082136497dec083a72302b3ddc634 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -340,10 +340,11 @@ static void invalidate_mems_from_autoinc	PROTO ((rtx));
    numbers in use.  */
 
 void
-find_basic_blocks (f, nregs, file)
+find_basic_blocks (f, nregs, file, do_cleanup)
      rtx f;
      int nregs ATTRIBUTE_UNUSED;
      FILE *file ATTRIBUTE_UNUSED;
+     int do_cleanup;
 {
   rtx *bb_eh_end;
   int max_uid;
@@ -402,9 +403,9 @@ find_basic_blocks (f, nregs, file)
   make_edges (label_value_list, bb_eh_end);
 
   /* Delete unreachable blocks.  */
-  /* ??? Do this conditionally, or make this another entry point?  */
 
-  delete_unreachable_blocks ();
+  if (do_cleanup)
+    delete_unreachable_blocks ();
 
   /* Mark critical edges.  */
 
@@ -2097,6 +2098,11 @@ free_basic_block_vars (keep_head_end_p)
       clear_edges ();
       VARRAY_FREE (basic_block_info);
       n_basic_blocks = 0;
+
+      ENTRY_BLOCK_PTR->aux = NULL;
+      ENTRY_BLOCK_PTR->global_live_at_end = NULL;
+      EXIT_BLOCK_PTR->aux = NULL;
+      EXIT_BLOCK_PTR->global_live_at_start = NULL;
     }
 }
 
@@ -2298,7 +2304,8 @@ life_analysis_1 (f, nregs)
   /* Allocate and zero out many data structures
      that will record the data from lifetime analysis.  */
 
-  allocate_for_life_analysis ();
+  allocate_reg_life_data ();
+  allocate_bb_life_data ();
 
   reg_next_use = (rtx *) alloca (nregs * sizeof (rtx));
   memset (reg_next_use, 0, nregs * sizeof (rtx));
@@ -2511,21 +2518,10 @@ life_analysis_1 (f, nregs)
    of life analysis.  Not static since used also for stupid life analysis.  */
 
 void
-allocate_for_life_analysis ()
+allocate_bb_life_data ()
 {
   register int i;
 
-  /* Recalculate the register space, in case it has grown.  Old style
-     vector oriented regsets would set regset_{size,bytes} here also.  */
-  allocate_reg_info (max_regno, FALSE, FALSE);
-
-  /* Because both reg_scan and flow_analysis want to set up the REG_N_SETS
-     information, explicitly reset it here.  The allocation should have
-     already happened on the previous reg_scan pass.  Make sure in case
-     some more registers were allocated.  */
-  for (i = 0; i < max_regno; i++)
-    REG_N_SETS (i) = 0;
-
   for (i = 0; i < n_basic_blocks; i++)
     {
       basic_block bb = BASIC_BLOCK (i);
@@ -2541,7 +2537,23 @@ allocate_for_life_analysis ()
     = OBSTACK_ALLOC_REG_SET (function_obstack);
 
   regs_live_at_setjmp = OBSTACK_ALLOC_REG_SET (function_obstack);
-  CLEAR_REG_SET (regs_live_at_setjmp);
+}
+
+void
+allocate_reg_life_data ()
+{
+  int i;
+
+  /* Recalculate the register space, in case it has grown.  Old style
+     vector oriented regsets would set regset_{size,bytes} here also.  */
+  allocate_reg_info (max_regno, FALSE, FALSE);
+
+  /* Because both reg_scan and flow_analysis want to set up the REG_N_SETS
+     information, explicitly reset it here.  The allocation should have
+     already happened on the previous reg_scan pass.  Make sure in case
+     some more registers were allocated.  */
+  for (i = 0; i < max_regno; i++)
+    REG_N_SETS (i) = 0;
 }
 
 /* Make each element of VECTOR point at a regset.  The vector has
diff --git a/gcc/gcse.c b/gcc/gcse.c
index dc970cd2446066e68232196a9ba14c7da4624eff..dab5ddf34307669ed4437528b7ab86d094f67b26 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -644,7 +644,7 @@ gcse_main (f, file)
   /* Identify the basic block information for this function, including
      successors and predecessors.  */
   max_gcse_regno = max_reg_num ();
-  find_basic_blocks (f, max_gcse_regno, file);
+  find_basic_blocks (f, max_gcse_regno, file, 1);
 
   /* Return if there's nothing to do.  */
   if (n_basic_blocks <= 1)
diff --git a/gcc/output.h b/gcc/output.h
index 3a34371d0e8766e2818772747c40e688d337d421..91708ae7d368363052bfc2cb13650255b0dfccbb 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -128,7 +128,7 @@ extern void allocate_for_life_analysis	PROTO((void));
 extern int regno_uninitialized		PROTO((int));
 extern int regno_clobbered_at_setjmp	PROTO((int));
 extern void dump_flow_info		PROTO((FILE *));
-extern void find_basic_blocks         PROTO((rtx, int, FILE *));
+extern void find_basic_blocks         PROTO((rtx, int, FILE *, int));
 extern void free_basic_block_vars     PROTO((int));
 extern void set_block_num             PROTO((rtx, int));
 extern void life_analysis             PROTO((rtx, int, FILE *));
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 23a1338844baf14c9b886a228cd65edcd27c7f34..60eadc556aa48c85fc176c1a3ba3c41d08f9f6a2 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1438,7 +1438,8 @@ extern void stupid_life_analysis	PROTO ((rtx, int, FILE *));
 #endif
 
 /* In flow.c */
-extern void allocate_for_life_analysis	PROTO ((void));
+extern void allocate_bb_life_data	PROTO ((void));
+extern void allocate_reg_life_data	PROTO ((void));
 extern void recompute_reg_usage		PROTO ((rtx, int));
 #ifdef BUFSIZ
 extern void dump_flow_info		PROTO ((FILE *));
diff --git a/gcc/stupid.c b/gcc/stupid.c
index 73ec3573933841c851c7c4500ca7d9f0c5fe865e..a0368bec3cacb808d8866a17e9dc1289ba44df19 100644
--- a/gcc/stupid.c
+++ b/gcc/stupid.c
@@ -253,7 +253,8 @@ stupid_life_analysis (f, nregs, file)
   /* Allocate and zero out many data structures
      that will record the data from lifetime analysis.  */
 
-  allocate_for_life_analysis ();
+  allocate_reg_life_data ();
+  allocate_bb_life_data ();
 
   for (i = 0; i < max_regno; i++)
     REG_N_DEATHS (i) = 1;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 0b413eb463836a92c002772e8433f6cf1a4bdcbd..cf2e8f0cb4bc1ba2d63ef41188d387c1111fdc98 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3978,7 +3978,7 @@ rest_of_compilation (decl)
       TIMEVAR
 	(flow_time,
 	 {
-	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
 	   life_analysis (insns, max_reg_num (), rtl_dump_file);
 	 });
 
@@ -4152,7 +4152,7 @@ rest_of_compilation (decl)
       TIMEVAR
 	(flow2_time,
 	 {
-	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+	   find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
 	   life_analysis (insns, max_reg_num (), rtl_dump_file);
 	 });
     }