This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[dataflow] PATCH removal of more of flow.c.


This is the next to the last patch that will be removing references to
flow.c on the dataflow branch.

Most of this patch is removes the abortive attempt to mimic flow.c's
incremental dataflow in df.  The rest of this patch is code from zdenek
(an updated patch from the dark ages) that builds log links inside of
the combine.c using the instance of df that is completely local to
combine. 

This patch has been bootstrapped and regression tested on
x86-64-unknown-linux-gnu and powerpc- unknown-linux-gnu.


2006-07-16  Zdenek Dvorak <dvorakz@suse.cz>
        Kenneth Zadeck <zadeck@naturalbridge.com>

    * regrename.c: Fixed comments.
    * see.c (rest_of_handle_see): Removed call to
    update_life_info_in_dirty_blocks.
    * tree-pass.h: (pass_clear_df, pass_reset_df): Removed.
    * passes.c (init_optimization_passes): Ditto.
    * cfghooks.c (split_block): Remove call to split_block_end.
    (merge_blocks): Removed call to merge_blocks_end.
    (duplicate_block): Removed call to duplicate_block_end.
    * cfghooks.h (split_block_end, merge_blocks_end,
    duplicate_block_end): Removed.
    * cfgrtl.c (rtl_split_block_end, rtl_merge_blocks_end): Removed.
    (rtl_create_basic_block, force_nonfallthru_and_redirect,
    rtl_split_edge, cfg_layout_merge_blocks, cfg_layout_split_edge):
    Removed old calls to incremental dataflow.
    (dump_regset_in, dump_regset_out): Removed call to dump_regset.
    (rtl_dump_bb, print_rtl_with_bb): Rearranged dataflow printing.
    * cfg.c (compact_blocks): Removed code to keep dataflow up to
    date.
    * flow.c (clear_log_links): Deleted
    (life_analysis, init_propagate_block_info): Removed PROP_LOG_LINKS.
    (update_life_info): Removed call to clear_log_links.
    (mark_set_1): Removed code to build log links.
    (clear_log_links): Deleted.
    * df-scan.c (df_uses_record): Added code to set
    DF_REF_PRE_POST_MODIFY.
    (df_insn_refs_record): Added code to set DF_REF_CALL_STACK_FRAME.
    * df-core.c (df_analyze_simple_change_some_blocks,
    df_analyze_simple_change_one_block, df_compact_blocks,
    df_bb_replace, reset_df, pass_reset_df, clear_df, pass_clear_df):
    Deleted.
    * recog.c (peephole2_optimize): Deleted some rotted code.
    * df.h (DF_REF_PRE_POST_MODIFY, DF_REF_CALL_STACK_USAGE): New
    Flags.
    (df_analyze_simple_change_some_blocks,
    df_analyze_simple_change_one_block, df_compact_blocks,
    df_bb_replace): Deleted.
    * bt-load (branch_target_load_optimize): Removed call to
    update_life_info.
    * cfgcleanup.c (thread_jump, try_forward_edges): Deleted mode
    parameter to thread_jump.
    (try_optimize_cfg, cleanup_cfg): Removed CLEANUP_UPDATE_LIFE.
    * cfglayout.c (cfg_layout_duplicate_bb_end): Deleted.
    * combine.c (combine_instructions): Removed call to
    update_life_info.
    (set_nonzero_bits_and_sign_copies, reg_nonzero_bits_for_combine,
    reg_num_sign_bit_copies_for_combine, get_last_value_validate,
    get_last_value, reg_dead_at_p): Changed to use local df instance.
    (create_log_links, clear_log_links): New function.
    (rest_of_handle_combine): Added new version of df, create and
    destroy log links locally.
    * bb-reorder.c (rest_of_handle_partition_blocks): Removed call to
    update_life_info.
    * basic-block.h (PROP_LOG_LINKS): Removed and renumbered other
    PROP_*.
    (CLEANUP_UPDATE_LIFE, CLEANUP_LOG_LINKS): Removed and renumbered
    other CLEANUP_*.
    * tree-cfg.c (tree_cfg_hooks): Removed fields.
    * struct-equiv.c (struct_equiv_init): Removed call to
    update_life_in_dirty_blocks.
    * dce.c (init_dce, end_dce, end_fast_dce): Removed code to service
    rtl_df.
    

Index: regrename.c
===================================================================
--- regrename.c	(revision 115422)
+++ regrename.c	(working copy)
@@ -1,5 +1,5 @@
 /* Register renaming for the GNU compiler.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -94,7 +94,7 @@ static void clear_dead_regs (HARD_REG_SE
 static void merge_overlapping_regs (struct df *, basic_block, HARD_REG_SET *,
 				    struct du_chain *);
 
-/* Called through note_stores from update_life.  Find sets of registers, and
+/* Called through note_stores.  Find sets of registers, and
    record them in *DATA (which is actually a HARD_REG_SET *).  */
 
 static void
Index: see.c
===================================================================
--- see.c	(revision 115422)
+++ see.c	(working copy)
@@ -3755,8 +3755,6 @@ rest_of_handle_see (void)
   no_new_pseudos = no_new_pseudos_bcp;
   
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
-  update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES, 
-  				    (PROP_DEATH_NOTES));
   cleanup_cfg (CLEANUP_EXPENSIVE);
   reg_scan (get_insns (), max_reg_num ());
 
Index: tree-pass.h
===================================================================
--- tree-pass.h	(revision 115422)
+++ tree-pass.h	(working copy)
@@ -370,8 +370,6 @@ extern struct tree_opt_pass pass_sched;
 extern struct tree_opt_pass pass_local_alloc;
 extern struct tree_opt_pass pass_global_alloc;
 extern struct tree_opt_pass pass_postreload;
-extern struct tree_opt_pass pass_clear_df;
-extern struct tree_opt_pass pass_reset_df;
 extern struct tree_opt_pass pass_clean_state;
 extern struct tree_opt_pass pass_branch_prob;
 extern struct tree_opt_pass pass_value_profile_transformations;
Index: passes.c
===================================================================
--- passes.c	(revision 115422)
+++ passes.c	(working copy)
@@ -654,9 +654,7 @@ init_optimization_passes (void)
   NEXT_PASS (pass_life);
   NEXT_PASS (pass_stack_ptr_mod);
   NEXT_PASS (pass_initialize_subregs);
-  NEXT_PASS (pass_reset_df);
   NEXT_PASS (pass_combine);
-  NEXT_PASS (pass_clear_df);
   NEXT_PASS (pass_rtl_dse);
   NEXT_PASS (pass_if_after_combine);
   NEXT_PASS (pass_fast_rtl_dce);
Index: cfghooks.c
===================================================================
--- cfghooks.c	(revision 115422)
+++ cfghooks.c	(working copy)
@@ -319,7 +319,6 @@ edge
 split_block (basic_block bb, void *i)
 {
   basic_block new_bb;
-  edge ret;
 
   if (!cfg_hooks->split_block)
     internal_error ("%s does not support split_block", cfg_hooks->name);
@@ -338,10 +337,7 @@ split_block (basic_block bb, void *i)
       set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
     }
 
-  ret = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
-  if (cfg_hooks->split_block_end)
-    cfg_hooks->split_block_end (new_bb, bb);
-  return ret;
+  return make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
 }
 
 /* Splits block BB just after labels.  The newly created edge is returned.  */
@@ -559,8 +555,6 @@ merge_blocks (basic_block a, basic_block
     delete_from_dominance_info (CDI_POST_DOMINATORS, b);
 
   expunge_block (b);
-  if (cfg_hooks->merge_blocks_end)
-    cfg_hooks->merge_blocks_end (a);
 }
 
 /* Split BB into entry part and the rest (the rest is the newly created block).
@@ -764,12 +758,6 @@ duplicate_block (basic_block bb, edge e,
       new_bb->frequency = bb->frequency;
     }
 
-  /* This hook may or may not be there.  Currently it is used at the
-     rtl level to update the dataflow since this can not be done until
-     the edges are stable.  */
-  if (cfg_hooks->duplicate_block_end)
-    cfg_hooks->duplicate_block_end (new_bb);
-
   set_bb_original (new_bb, bb);
   set_bb_copy (bb, new_bb);
 
Index: cfghooks.h
===================================================================
--- cfghooks.h	(revision 115422)
+++ cfghooks.h	(working copy)
@@ -54,10 +54,6 @@ struct cfg_hooks
      everything after specified instruction I.  */
   basic_block (*split_block) (basic_block b, void * i);
   
-  /* Called with the newly split block and the old block *after* the
-     edges between the two have been created.  */
-  void (*split_block_end) (basic_block a, basic_block b);
-
   /* Move block B immediately after block A.  */
   bool (*move_block_after) (basic_block b, basic_block a);
 
@@ -67,10 +63,6 @@ struct cfg_hooks
   /* Merge blocks A and B.  */
   void (*merge_blocks) (basic_block a, basic_block b);
 
-  /* Called on the newly merged block after the blocks and edges have
-     been merged.  */
-  void (*merge_blocks_end) (basic_block a);
-
   /* Predict edge E using PREDICTOR to given PROBABILITY.  */
   void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
 
@@ -84,9 +76,6 @@ struct cfg_hooks
   /* Duplicate block A.  */
   basic_block (*duplicate_block) (basic_block a);
 
-  /* This is called after block duplication on the newly duplicated block.  */
-  basic_block (*duplicate_block_end) (basic_block a);
-
   /* Higher level functions representable by primitive operations above if
      we didn't have some oddities in RTL and Tree representations.  */
   basic_block (*split_edge) (edge);
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 115422)
+++ cfgrtl.c	(working copy)
@@ -343,8 +343,6 @@ rtl_create_basic_block (void *headp, voi
   bb = create_basic_block_structure (head, end, NULL, after);
   bb->aux = NULL;
 
-  if (rtl_df)
-    df_analyze_simple_change_one_block (rtl_df, bb);
   return bb;
 }
 
@@ -509,30 +507,6 @@ rtl_split_block (basic_block bb, void *i
   return new_bb;
 }
 
-/* Update life information for blocks NEW and OLD.  */
-
-static void
-rtl_split_block_end (basic_block newbb, basic_block oldbb)
-{
-  if (rtl_df)
-    {
-      int * block_list = alloca (2 * sizeof (int));
-      block_list[0] = newbb->index;
-      block_list[1] = oldbb->index;
-      df_analyze_simple_change_some_blocks (rtl_df, block_list, 2);
-
-#ifdef HAVE_conditional_execution
-      /* In the presence of conditional execution we are not able to update
-	 liveness precisely.  */
-      if (reload_completed)
-	{
-	  newbb->flags |= BB_DIRTY;
-	  oldbb->flags |= BB_DIRTY;
-	}
-#endif
-    }
-}
-
 /* Blocks A and B are to be merged into a single block A.  The insns
    are already contiguous.  */
 
@@ -626,13 +600,6 @@ rtl_merge_blocks (basic_block a, basic_b
 
 }
 
-static void
-rtl_merge_blocks_end (basic_block a)
-{
-  if (rtl_df)
-    df_analyze_simple_change_one_block (rtl_df, a);
-}
-
 /* Return true when block A and B can be merged.  */
 static bool
 rtl_can_merge_blocks (basic_block a,basic_block b)
@@ -1074,9 +1041,6 @@ force_nonfallthru_and_redirect (edge e, 
 
 	  VEC_safe_push (edge, gc, bb->succs, e);
 	  make_single_succ_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
-
-	  if (rtl_df)
-	    df_analyze_simple_change_one_block (rtl_df, bb);
 	}
     }
 
@@ -1120,9 +1084,6 @@ force_nonfallthru_and_redirect (edge e, 
       e->probability = REG_BR_PROB_BASE;
 
       new_bb = jump_block;
-      
-      if (rtl_df)
-	df_analyze_simple_change_one_block (rtl_df, jump_block);
     }
   else
     jump_block = e->src;
@@ -1297,9 +1258,6 @@ rtl_split_edge (edge edge_in)
 
   make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
 
-  if (rtl_df)
-    df_analyze_simple_change_one_block (rtl_df, bb);
-
   /* For non-fallthru edges, we must adjust the predecessor's
      jump instruction to target our new block.  */
   if ((edge_in->flags & EDGE_FALLTHRU) == 0)
@@ -1572,13 +1530,10 @@ commit_edge_insertions_watch_calls (void
 
 /* Print a regset at the beginning of BB to FILE.  */
 
+#if 0
 static void 
 dump_regset_in (basic_block bb, FILE * file)
 {
-  if (!rtl_df)
-    return;
-  
-  dump_regset (df_get_live_in (rtl_df, bb), file);
 }
 
 
@@ -1587,12 +1542,8 @@ dump_regset_in (basic_block bb, FILE * f
 static void 
 dump_regset_out (basic_block bb, FILE * file)
 {
-  if (!rtl_df)
-    return;
-
-  dump_regset (df_get_live_out (rtl_df, bb), file);
 }
-
+#endif
 
 /* Print out RTL-specific basic block information (live information
    at start and end).  */
@@ -1608,6 +1559,7 @@ rtl_dump_bb (basic_block bb, FILE *outf,
   memset (s_indent, ' ', (size_t) indent);
   s_indent[indent] = '\0';
   
+#if 0
   if (rtl_df)
     {
       fprintf (outf, ";;%s Registers live at start: ", s_indent);
@@ -1615,17 +1567,20 @@ rtl_dump_bb (basic_block bb, FILE *outf,
     
       putc ('\n', outf);
     }
+#endif
 
   for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last;
        insn = NEXT_INSN (insn))
     print_rtl_single (outf, insn);
 
+#if 0
   if (rtl_df)
     {
       fprintf (outf, ";;%s Registers live at end: ", s_indent);
       dump_regset_out (bb, outf);
       putc ('\n', outf);
     }
+#endif
 }
 
 /* Like print_rtl, but also print out live information for the start of each
@@ -1671,6 +1626,7 @@ print_rtl_with_bb (FILE *outf, rtx rtx_f
 	{
 	  int did_output;
 
+#if 0
 	  if ((bb = start[INSN_UID (tmp_rtx)]) != NULL)
 	    {
 	      fprintf (outf, ";; Start of basic block %d, registers live:",
@@ -1678,7 +1634,7 @@ print_rtl_with_bb (FILE *outf, rtx rtx_f
 		dump_regset_in (bb, outf);
 	      putc ('\n', outf);
 	    }
-
+#endif
 	  if (in_bb_p[INSN_UID (tmp_rtx)] == NOT_IN_BB
 	      && !NOTE_P (tmp_rtx)
 	      && !BARRIER_P (tmp_rtx))
@@ -1688,6 +1644,7 @@ print_rtl_with_bb (FILE *outf, rtx rtx_f
 
 	  did_output = print_rtl_single (outf, tmp_rtx);
 
+#if 0
 	  if ((bb = end[INSN_UID (tmp_rtx)]) != NULL)
 	    {
 	      fprintf (outf, ";; End of basic block %d, registers live:\n",
@@ -1695,7 +1652,7 @@ print_rtl_with_bb (FILE *outf, rtx rtx_f
 	      dump_regset_out (bb, outf);
 	      putc ('\n', outf);
 	    }
-
+#endif
 	  if (did_output)
 	    putc ('\n', outf);
 	}
@@ -2648,9 +2605,6 @@ cfg_layout_merge_blocks (basic_block a, 
       b->il.rtl->footer = NULL;
     }
 
-  if (rtl_df)
-    df_analyze_simple_change_one_block (rtl_df, a);
-
   if (dump_file)
     fprintf (dump_file, "Merged blocks %d and %d.\n",
 	     a->index, b->index);
@@ -2669,9 +2623,6 @@ cfg_layout_split_edge (edge e)
   make_edge (new_bb, e->dest, EDGE_FALLTHRU);
   redirect_edge_and_branch_force (e, new_bb);
 
-  if (rtl_df)
-    df_analyze_simple_change_one_block (rtl_df, new_bb);
-
   return new_bb;
 }
 
@@ -3018,16 +2969,13 @@ struct cfg_hooks rtl_cfg_hooks = {
   rtl_redirect_edge_and_branch_force,
   rtl_delete_block,
   rtl_split_block,
-  rtl_split_block_end,
   rtl_move_block_after,
   rtl_can_merge_blocks,  /* can_merge_blocks_p */
   rtl_merge_blocks,
-  rtl_merge_blocks_end,
   rtl_predict_edge,
   rtl_predicted_by_p,
   NULL, /* can_duplicate_block_p */
   NULL, /* duplicate_block */
-  NULL, /* duplicate_block_end */
   rtl_split_edge,
   rtl_make_forwarder_block,
   rtl_tidy_fallthru_edge,
@@ -3054,7 +3002,6 @@ struct cfg_hooks rtl_cfg_hooks = {
    code.  */
 extern bool cfg_layout_can_duplicate_bb_p (basic_block);
 extern basic_block cfg_layout_duplicate_bb (basic_block);
-extern basic_block cfg_layout_duplicate_bb_end (basic_block);
 
 struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
   "cfglayout mode",
@@ -3065,16 +3012,13 @@ struct cfg_hooks cfg_layout_rtl_cfg_hook
   cfg_layout_redirect_edge_and_branch_force,
   cfg_layout_delete_block,
   cfg_layout_split_block,
-  rtl_split_block_end,
   rtl_move_block_after,
   cfg_layout_can_merge_blocks_p,
   cfg_layout_merge_blocks,
-  rtl_merge_blocks_end,
   rtl_predict_edge,
   rtl_predicted_by_p,
   cfg_layout_can_duplicate_bb_p,
   cfg_layout_duplicate_bb,
-  cfg_layout_duplicate_bb_end,
   cfg_layout_split_edge,
   rtl_make_forwarder_block,
   NULL,
Index: cfg.c
===================================================================
--- cfg.c	(revision 115422)
+++ cfg.c	(working copy)
@@ -163,28 +163,23 @@ void
 compact_blocks (void)
 {
   int i;
+  basic_block bb;
 
   SET_BASIC_BLOCK (ENTRY_BLOCK, ENTRY_BLOCK_PTR);
   SET_BASIC_BLOCK (EXIT_BLOCK, EXIT_BLOCK_PTR);
   
-  if (rtl_df)
-    df_compact_blocks (rtl_df);
-  else 
+  i = NUM_FIXED_BLOCKS;
+  FOR_EACH_BB (bb)
     {
-      basic_block bb;
-      
-      i = NUM_FIXED_BLOCKS;
-      FOR_EACH_BB (bb)
-	{
-	  SET_BASIC_BLOCK (i, bb);
-	  bb->index = i;
-	  i++;
-	}
-      gcc_assert (i == n_basic_blocks);
-
-      for (; i < last_basic_block; i++)
-	SET_BASIC_BLOCK (i, NULL);
+      SET_BASIC_BLOCK (i, bb);
+      bb->index = i;
+      i++;
     }
+  gcc_assert (i == n_basic_blocks);
+  
+  for (; i < last_basic_block; i++)
+    SET_BASIC_BLOCK (i, NULL);
+
   last_basic_block = n_basic_blocks;
 }
 
Index: flow.c
===================================================================
--- flow.c	(revision 115422)
+++ flow.c	(working copy)
@@ -88,9 +88,6 @@ Software Foundation, 51 Franklin Street,
 
    ** Other actions of life_analysis **
 
-   life_analysis sets up the LOG_LINKS fields of insns because the
-   information needed to do so is readily available.
-
    life_analysis deletes insns whose only effect is to store a value
    that is never used.
 
@@ -115,7 +112,6 @@ Software Foundation, 51 Franklin Street,
    Split out from life_analysis:
 	- local property discovery
 	- global property computation
-	- log links creation
 	- pre/post modify transformation
 */
 
@@ -315,7 +311,6 @@ void debug_flow_info (void);
 static void add_to_mem_set_list (struct propagate_block_info *, rtx);
 static int invalidate_mems_from_autoinc (rtx *, void *);
 static void invalidate_mems_from_set (struct propagate_block_info *, rtx);
-static void clear_log_links (sbitmap);
 static int count_or_remove_death_notes_bb (basic_block, int);
 
 /* Return the INSN immediately following the NOTE_INSN_BASIC_BLOCK
@@ -362,7 +357,7 @@ life_analysis (int flags)
 #endif
 
   if (! optimize)
-    flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
+    flags &= ~(PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
 
   /* The post-reload life analysis have (on a global basis) the same
      registers live as was computed by reload itself.  elimination
@@ -663,10 +658,6 @@ update_life_info (sbitmap blocks, enum u
 				     prop_flags & PROP_POST_REGSTACK ? -1 : 1);
     }
 
-  /* Clear log links in case we are asked to (re)compute them.  */
-  if (prop_flags & PROP_LOG_LINKS)
-    clear_log_links (blocks);
-
   if (blocks)
     {
       sbitmap_iterator sbi;
@@ -1256,7 +1247,7 @@ init_propagate_block_info (basic_block b
   pbi->flags = flags;
   pbi->insn_num = 0;
 
-  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+  if (flags & PROP_AUTOINC)
     pbi->reg_next_use = XCNEWVEC (rtx, max_reg_num ());
   else
     pbi->reg_next_use = NULL;
@@ -2131,14 +2122,13 @@ mark_set_1 (struct propagate_block_info 
 #endif
 
       /* Additional data to record if this is the final pass.  */
-      if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
-		   | PROP_DEATH_NOTES | PROP_AUTOINC))
+      if (flags & (PROP_REG_INFO | PROP_DEATH_NOTES | PROP_AUTOINC))
 	{
 	  rtx y;
 	  int blocknum = pbi->bb->index;
 
 	  y = NULL_RTX;
-	  if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+	  if (flags & PROP_AUTOINC)
 	    {
 	      y = pbi->reg_next_use[regno_first];
 
@@ -2184,34 +2174,7 @@ mark_set_1 (struct propagate_block_info 
 #endif
 	    }
 
-	  if (! some_was_dead)
-	    {
-	      if (flags & PROP_LOG_LINKS)
-		{
-		  /* Make a logical link from the next following insn
-		     that uses this register, back to this insn.
-		     The following insns have already been processed.
-
-		     We don't build a LOG_LINK for hard registers containing
-		     in ASM_OPERANDs.  If these registers get replaced,
-		     we might wind up changing the semantics of the insn,
-		     even if reload can make what appear to be valid
-		     assignments later.
-
-		     We don't build a LOG_LINK for global registers to
-		     or from a function call.  We don't want to let
-		     combine think that it knows what is going on with
-		     global registers.  */
-		  if (y && (BLOCK_NUM (y) == blocknum)
-		      && (regno_first >= FIRST_PSEUDO_REGISTER
-			  || (asm_noperands (PATTERN (y)) < 0
-			      && ! ((CALL_P (insn)
-				     || CALL_P (y))
-				    && global_regs[regno_first]))))
-		    LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
-		}
-	    }
-	  else if (not_dead)
+	  if (! some_was_dead || not_dead)
 	    ;
 	  else if (! some_was_live)
 	    {
@@ -2286,7 +2249,7 @@ mark_set_1 (struct propagate_block_info 
     }
   else if (REG_P (reg))
     {
-      if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+      if (flags & PROP_AUTOINC)
 	pbi->reg_next_use[regno_first] = 0;
 #if 0
       if ((flags & PROP_REG_INFO) != 0
@@ -3005,7 +2968,7 @@ mark_used_reg (struct propagate_block_in
   for (i = regno_first; i <= regno_last; ++i)
     some_not_set |= ! REGNO_REG_SET_P (pbi->new_set, i);
 
-  if (pbi->flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+  if (pbi->flags & PROP_AUTOINC)
     {
       /* Record where each reg is used, so when the reg is set we know
 	 the next insn that uses it.  */
@@ -3799,37 +3762,6 @@ count_or_remove_death_notes_bb (basic_bl
   return count;
 }
 
-/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
-   if blocks is NULL.  */
-
-static void
-clear_log_links (sbitmap blocks)
-{
-  rtx insn;
-
-  if (!blocks)
-    {
-      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-	if (INSN_P (insn))
-	  free_INSN_LIST_list (&LOG_LINKS (insn));
-    }
-  else
-    {
-      unsigned int i = 0;
-      sbitmap_iterator sbi;
-
-      EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i, sbi)
-	{
-	  basic_block bb = BASIC_BLOCK (i);
-
-	  for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
-	       insn = NEXT_INSN (insn))
-	    if (INSN_P (insn))
-	      free_INSN_LIST_list (&LOG_LINKS (insn));
-	}
-    }
-}
-
 /* Given a register bitmap, turn on the bits in a HARD_REG_SET that
    correspond to the hard registers, if any, set in that map.  This
    could be done far more efficiently by having all sorts of special-cases
Index: df-scan.c
===================================================================
--- df-scan.c	(revision 115422)
+++ df-scan.c	(working copy)
@@ -1456,7 +1456,7 @@ df_uses_record (struct dataflow *dflow, 
     case PRE_MODIFY:
     case POST_MODIFY:
       /* Catch the def of the register being modified.  */
-      flags |= DF_REF_READ_WRITE;
+      flags |= DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY;
       df_ref_record (dflow, XEXP (x, 0), &XEXP (x, 0), bb, insn, 
 		     DF_REF_REG_DEF, flags, true);
 
@@ -1586,7 +1586,7 @@ df_insn_refs_record (struct dataflow *df
 	  /* The stack ptr is used (honorarily) by a CALL insn.  */
 	  df_uses_record (dflow, &regno_reg_rtx[STACK_POINTER_REGNUM],
 			  DF_REF_REG_USE, bb, insn, 
-			  0);
+			  DF_REF_CALL_STACK_USAGE);
 
 	  if (dflow->flags & DF_HARD_REGS)
 	    {
Index: df-core.c
===================================================================
--- df-core.c	(revision 115422)
+++ df-core.c	(working copy)
@@ -901,173 +901,6 @@ df_set_bb_info (struct dataflow *dflow, 
   dflow->block_info[index] = bb_info;
 }
 
-
-/* This is a very simple and fast incremental interface to some
-   problems in df.  It's intended usage is for the routine cfg
-   modifications like splitting or combining blocks or edges.  For
-   these modifications, general iteration is not required, a single
-   pass thru the blocks specified reading only the out-sets of the
-   preds and the in-sets of the successors is all the work that is
-   accomplished.  
-
-   The only input is an post ordered (last block in the sequence is
-   first) vector of blocks and the count of these blocks.
-
-   This will not work properly for RD and RU since these problems
-   depend on the bit vectors being ordered in a particular manner and
-   that will be too expensive to keep up to data during simple
-   modifications.
-*/
-
-void
-df_analyze_simple_change_some_blocks (struct df *df, 
-				      int * blocks_in_postorder, 
-				      int n_blocks)
-{
-  bitmap blocks = BITMAP_ALLOC (NULL);
-  bitmap blocks_in_fringe = BITMAP_ALLOC (NULL);
-  int i;
-
-  /* Blocks_in_fringe is the set of blocks in the postorder + all of
-     their preds and succs.  These are the blocks that get their
-     bitmaps set up the dflow vectors and that will be either examined
-     or modified by the propagation.  */
-  for (i=0; i<n_blocks; i++) 
-    {
-      basic_block bb = BASIC_BLOCK (blocks_in_postorder[i]);
-      edge e;
-      edge_iterator ei;
-      FOR_EACH_EDGE (e, ei, bb->preds)
-	bitmap_set_bit (blocks_in_fringe, e->src->index);
-      FOR_EACH_EDGE (e, ei, bb->succs)
-	bitmap_set_bit (blocks_in_fringe, e->dest->index);
-      bitmap_set_bit (blocks, bb->index);
-      bitmap_set_bit (blocks_in_fringe, bb->index);
-    }
-
-  df_rescan_blocks (df, blocks);
-
-  /* Do not do DF_SCAN */
-  for (i=1; i<df->num_problems_defined; i++)
-    df_analyze_problem (df->problems_in_order[i], 
-			blocks_in_fringe, blocks, blocks,
-			blocks_in_postorder, n_blocks, true);
-
-  bitmap_and_compl_into (df->blocks_to_scan, blocks);
-  if (bitmap_empty_p (df->blocks_to_scan))
-    BITMAP_FREE (df->blocks_to_scan);
-
-  BITMAP_FREE (blocks);
-  BITMAP_FREE (blocks_in_fringe);
-}
-
-
-/* Convienence call to df_analyze_simple_changes_some_blocks.  */
-
-void
-df_analyze_simple_change_one_block (struct df * df, basic_block bb)
-{
-  int * block_list = alloca (sizeof (int));
-  if (df)
-    {
-      block_list[0] = bb->index;
-      df_analyze_simple_change_some_blocks (df, block_list, 1);
-    }
-}
-
-
-/* Called from the rtl_compact_blocks to reorganize the problems basic
-   block info.  */
-
-void 
-df_compact_blocks (struct df *df)
-{
-  int i, p;
-  basic_block bb;
-  void **problem_temps;
-  int size = last_basic_block *sizeof (void *);
-  problem_temps = xmalloc (size);
-
-  for (p = 0; p < df->num_problems_defined; p++)
-    {
-      struct dataflow *dflow = df->problems_in_order[p];
-      if (dflow->problem->free_bb_fun)
-	{
-	  df_grow_bb_info (dflow);
-	  memcpy (problem_temps, dflow->block_info, size);
-
-	  /* Copy the bb info from the problem tmps to the proper
-	     place in the block_info vector.  Null out the copied
-	     item.  */
-	  i = NUM_FIXED_BLOCKS;
-	  FOR_EACH_BB (bb) 
-	    {
-	      df_set_bb_info (dflow, i, problem_temps[bb->index]);
-	      problem_temps[bb->index] = NULL;
-	      i++;
-	    }
-	  memset (dflow->block_info + i, 0, 
-		  (last_basic_block - i) *sizeof (void *));
-
-	  /* Free any block infos that were not copied (and NULLed).
-	     These are from orphaned blocks.  */
-	  for (i = NUM_FIXED_BLOCKS; i < last_basic_block; i++)
-	    {
-	      basic_block bb = BASIC_BLOCK (i); 
-	      if (problem_temps[i] && bb)
-		dflow->problem->free_bb_fun
-		  (dflow, bb, problem_temps[i]);
-	    }
-	}
-    }
-
-  free (problem_temps);
-
-  i = NUM_FIXED_BLOCKS;
-  FOR_EACH_BB (bb) 
-    {
-      SET_BASIC_BLOCK (i, bb);
-      bb->index = i;
-      i++;
-    }
-
-  gcc_assert (i == n_basic_blocks);
-
-  for (; i < last_basic_block; i++)
-    SET_BASIC_BLOCK (i, NULL);
-}
-
-
-/* Shove NEW_BLOCK in at OLD_INDEX.  Called from if-cvt to hack a
-   block.  There is no excuse for people to do this kind of thing.  */
-
-void 
-df_bb_replace (struct df *df, int old_index, basic_block new_block)
-{
-  int p;
-
-  for (p = 0; p < df->num_problems_defined; p++)
-    {
-      struct dataflow *dflow = df->problems_in_order[p];
-      if (dflow->block_info)
-	{
-	  void *temp;
-
-	  df_grow_bb_info (dflow);
-
-	  /* The old switcheroo.  */
-
-	  temp = df_get_bb_info (dflow, old_index);
-	  df_set_bb_info (dflow, old_index, 
-			  df_get_bb_info (dflow, new_block->index));
-	  df_set_bb_info (dflow, new_block->index, temp);
-	}
-    }
-
-  SET_BASIC_BLOCK (old_index, new_block);
-  new_block->index = old_index;
-}
-
 /*----------------------------------------------------------------------------
    PUBLIC INTERFACES TO QUERY INFORMATION.
 ----------------------------------------------------------------------------*/
@@ -1447,59 +1280,3 @@ debug_df_chain (struct df_link *link)
   fputc ('\n', stderr);
 }
 
-static unsigned int 
-reset_df (void)
-{
-  rtl_df = df_init (DF_HARD_REGS);
-  df_clrur_add_problem (rtl_df, 0);
-  df_ri_add_problem (rtl_df, DF_RI_LIFE);
-  update_life_info (NULL, UPDATE_LIFE_GLOBAL, PROP_LOG_LINKS);
-  return 0;
-}
-
-struct tree_opt_pass pass_reset_df =
-{
-  "reset_df",                           /* name */
-  NULL,                                 /* gate */
-  reset_df,                             /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  0,                                    /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  0                                     /* letter */
-};
-
-static unsigned int 
-clear_df (void)
-{
-  if (rtl_df)
-    {
-      df_finish (rtl_df);
-      rtl_df = NULL;
-    }
-
-  clear_reg_deaths ();
-  return 0;
-}
-
-struct tree_opt_pass pass_clear_df =
-{
-  "clear_df",                           /* name */
-  NULL,                                 /* gate */
-  clear_df,                /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  0,                                    /* tv_id */
-  0,                                    /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  0                                     /* letter */
-};
Index: recog.c
===================================================================
--- recog.c	(revision 115422)
+++ recog.c	(working copy)
@@ -3076,15 +3076,6 @@ peephole2_optimize (void)
 
       /* Start up propagation.  */
       df_lr_simulate_artificial_refs_at_end (df, bb, live);
-#if 0
-      COPY_REG_SET (livep, DF_LIVE_OUT (rtl_df, bb));
-      gcc_assert (bitmap_equal_p (livep, live));
-#ifdef HAVE_conditional_execution
-      pbi = init_propagate_block_info (bb, livep, NULL, NULL, 0);
-#else
-      pbi = init_propagate_block_info (bb, livep, NULL, NULL, PROP_DEATH_NOTES);
-#endif
-#endif
       bitmap_copy (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
 
       for (insn = BB_END (bb); ; insn = prev)
Index: df.h
===================================================================
--- df.h	(revision 115422)
+++ df.h	(working copy)
@@ -85,7 +85,6 @@ enum df_ref_flags
        artificial one created to model always live registers, eh uses, etc.  */
     DF_REF_ARTIFICIAL = 4,
 
-
     /* If this flag is set for an artificial use or def, that ref
        logically happens at the top of the block.  If it is not set
        for an artificial use or def, that ref logically happens at the
@@ -122,7 +121,14 @@ enum df_ref_flags
     
     /* This flag is set if this ref occurs inside of a conditional
        execution instruction.  */
-    DF_REF_CONDITIONAL = 512
+    DF_REF_CONDITIONAL = 512,
+
+    /* This flag is set if this ref is inside a pre/post modify.  */
+    DF_REF_PRE_POST_MODIFY = 1024,
+
+    /* This flag is set if this ref is a usage of the stack pointer by
+       a function call.  */
+    DF_REF_CALL_STACK_USAGE = 2048
   };
 
 
@@ -616,10 +622,6 @@ extern void df_analyze (struct df *);
 extern void df_simple_iterative_dataflow (enum df_flow_dir, df_init_function,
 					  df_confluence_function_0, df_confluence_function_n,
 					  df_transfer_function, bitmap, int *, int);
-extern void df_analyze_simple_change_some_blocks (struct df *, int *, int);
-extern void df_analyze_simple_change_one_block (struct df *, basic_block);
-extern void df_compact_blocks (struct df *);
-extern void df_bb_replace (struct df *, int, basic_block);
 extern struct df_ref *df_bb_regno_last_use_find (struct df *, basic_block, unsigned int);
 extern struct df_ref *df_bb_regno_first_def_find (struct df *, basic_block, unsigned int);
 extern struct df_ref *df_bb_regno_last_def_find (struct df *, basic_block, unsigned int);
Index: bt-load.c
===================================================================
--- bt-load.c	(revision 115422)
+++ bt-load.c	(working copy)
@@ -1496,13 +1496,6 @@ branch_target_load_optimize (bool after_
 
       free_dominance_info (CDI_DOMINATORS);
       df_finish (df);
-
-      if (!after_prologue_epilogue_gen)
-	{
-	  update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
-			    PROP_DEATH_NOTES | PROP_REG_INFO);
-	}
-
     }
 }
 
Index: cfgcleanup.c
===================================================================
--- cfgcleanup.c	(revision 115422)
+++ cfgcleanup.c	(working copy)
@@ -71,7 +71,7 @@ static void merge_blocks_move_successor_
 static bool try_optimize_cfg (int);
 static bool try_simplify_condjump (basic_block);
 static bool try_forward_edges (int, basic_block);
-static edge thread_jump (int, edge, basic_block);
+static edge thread_jump (edge, basic_block);
 static bool mark_effect (rtx, bitmap);
 static void notice_new_block (basic_block);
 static void update_forwarder_flag (basic_block);
@@ -261,7 +261,7 @@ mentions_nonequal_regs (rtx *x, void *da
    if exist, NULL otherwise.  */
 
 static edge
-thread_jump (int mode, edge e, basic_block b)
+thread_jump (edge e, basic_block b)
 {
   rtx set1, set2, cond1, cond2, insn;
   enum rtx_code code1, code2, reversed_code2;
@@ -381,11 +381,6 @@ thread_jump (int mode, edge e, basic_blo
   if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal))
     goto failed_exit;
 
-  /* In case liveness information is available, we need to prove equivalence
-     only of the live values.  */
-  if (mode & CLEANUP_UPDATE_LIFE)
-    AND_REG_SET (nonequal, DF_LIVE_OUT (rtl_df, b));
-
   EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
     goto failed_exit;
 
@@ -482,7 +477,7 @@ try_forward_edges (int mode, basic_block
 	     of probabilities.  */
 	  else if ((mode & CLEANUP_THREADING) && may_thread)
 	    {
-	      edge t = thread_jump (mode, e, target);
+	      edge t = thread_jump (e, target);
 	      if (t)
 		{
 		  if (!threaded_edges)
@@ -1966,7 +1961,7 @@ try_optimize_cfg (int mode)
   if (mode & CLEANUP_CROSSJUMP)
     add_noreturn_fake_exit_edges ();
 
-  if (mode & (CLEANUP_UPDATE_LIFE | CLEANUP_CROSSJUMP | CLEANUP_THREADING))
+  if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
     clear_bb_flags ();
 
   FOR_EACH_BB (bb)
@@ -2230,7 +2225,7 @@ cleanup_cfg (int mode)
       changed = true;
       /* We've possibly created trivially dead code.  Cleanup it right
 	 now to introduce more opportunities for try_optimize_cfg.  */
-      if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_UPDATE_LIFE))
+      if (!(mode & (CLEANUP_NO_INSN_DEL))
 	  && !reload_completed)
 	delete_trivially_dead_insns (get_insns(), max_reg_num ());
     }
@@ -2240,21 +2235,9 @@ cleanup_cfg (int mode)
   while (try_optimize_cfg (mode))
     {
       delete_unreachable_blocks (), changed = true;
-      if (mode & CLEANUP_UPDATE_LIFE)
-	{
-	  /* Cleaning up CFG introduces more opportunities for dead code
-	     removal that in turn may introduce more opportunities for
-	     cleaning up the CFG.  */
-	  if (!run_fast_dce ()
-	      && !(update_life_info_in_dirty_blocks
-		   (UPDATE_LIFE_GLOBAL_RM_NOTES,
-		    PROP_DEATH_NOTES
-		    | (mode & CLEANUP_LOG_LINKS) ? PROP_LOG_LINKS : 0)))
-	    break;
-	}
-      else if (!(mode & CLEANUP_NO_INSN_DEL)
-	       && (mode & CLEANUP_EXPENSIVE)
-	       && !reload_completed)
+      if (!(mode & CLEANUP_NO_INSN_DEL)
+	  && (mode & CLEANUP_EXPENSIVE)
+	  && !reload_completed)
 	{
 	  if (!delete_trivially_dead_insns (get_insns(), max_reg_num ()))
 	    break;
Index: cfglayout.c
===================================================================
--- cfglayout.c	(revision 115422)
+++ cfglayout.c	(working copy)
@@ -1027,7 +1027,6 @@ duplicate_insn_chain (rtx from, rtx to)
    it to cfgrtl.c since it would require also moving quite a lot of related
    code.  */
 extern basic_block cfg_layout_duplicate_bb (basic_block);
-extern void cfg_layout_duplicate_bb_end (basic_block);
 
 basic_block
 cfg_layout_duplicate_bb (basic_block bb)
@@ -1064,21 +1063,11 @@ cfg_layout_duplicate_bb (basic_block bb)
   return new_bb;
 }
 
-/* Fix up the dataflow for the new basic block.  This can only be done
-   after all of the edges have been connected.  */
-void
-cfg_layout_duplicate_bb_end (basic_block bb)
-{
-  df_analyze_simple_change_one_block (rtl_df, bb);
-}
-
 
 /* Main entry point to this module - initialize the datastructures for
    CFG layout changes.  It keeps LOOPS up-to-date if not null.
 
-   FLAGS is a set of additional flags to pass to cleanup_cfg().  It should
-   include CLEANUP_UPDATE_LIFE if liveness information must be kept up
-   to date.  */
+   FLAGS is a set of additional flags to pass to cleanup_cfg().  */
 
 void
 cfg_layout_initialize (unsigned int flags)
Index: combine.c
===================================================================
--- combine.c	(revision 115422)
+++ combine.c	(working copy)
@@ -104,6 +104,8 @@ Software Foundation, 51 Franklin Street,
 #include "tree-pass.h"
 #include "df.h"
 
+static struct df *df;
+
 /* Number of attempts to combine instructions in this function.  */
 
 static int combine_attempts;
@@ -948,9 +950,7 @@ combine_instructions (rtx f, unsigned in
   clear_bb_flags ();
   new_direct_jump_p |= purge_all_dead_edges ();
   delete_noop_moves ();
-  update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
-				    PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
-				    | PROP_KILL_DEAD_CODE);
+
   /* Clean up.  */
   free (uid_insn_cost);
   free (reg_stat);
@@ -1041,7 +1041,7 @@ set_nonzero_bits_and_sign_copies (rtx x,
       /* If this register is undefined at the start of the file, we can't
 	 say what its contents were.  */
       && REGNO_REG_SET_P
-         (DF_UR_IN (rtl_df, ENTRY_BLOCK_PTR->next_bb), REGNO (x))
+         (DF_UR_IN (df, ENTRY_BLOCK_PTR->next_bb), REGNO (x))
       && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
     {
       if (set == 0 || GET_CODE (set) == CLOBBER)
@@ -1066,8 +1066,7 @@ set_nonzero_bits_and_sign_copies (rtx x,
 
       if (insn
 	  && reg_referenced_p (x, PATTERN (insn))
-	  && !REGNO_REG_SET_P (DF_LR_IN (rtl_df,
-					 BLOCK_FOR_INSN (insn)),
+	  && !REGNO_REG_SET_P (DF_LR_IN (df, BLOCK_FOR_INSN (insn)),
 			       REGNO (x)))
 	{
 	  rtx link;
@@ -8287,7 +8286,7 @@ reg_nonzero_bits_for_combine (rtx x, enu
 	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
 	      && REG_N_SETS (REGNO (x)) == 1
 	      && REGNO_REG_SET_P
-	      (DF_UR_IN (rtl_df, ENTRY_BLOCK_PTR->next_bb), REGNO (x))))
+	      (DF_UR_IN (df, ENTRY_BLOCK_PTR->next_bb), REGNO (x))))
       && INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
     {
       *nonzero &= reg_stat[REGNO (x)].last_set_nonzero_bits;
@@ -8354,7 +8353,7 @@ reg_num_sign_bit_copies_for_combine (rtx
 	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
 	      && REG_N_SETS (REGNO (x)) == 1
 	      && REGNO_REG_SET_P
-	      (DF_UR_IN (rtl_df, ENTRY_BLOCK_PTR->next_bb), REGNO (x))))
+	      (DF_UR_IN (df, ENTRY_BLOCK_PTR->next_bb), REGNO (x))))
       && INSN_CUID (reg_stat[REGNO (x)].last_set) < subst_low_cuid)
     {
       *result = reg_stat[REGNO (x)].last_set_sign_bit_copies;
@@ -11244,7 +11243,7 @@ get_last_value_validate (rtx *loc, rtx i
 	    || (! (regno >= FIRST_PSEUDO_REGISTER
 		   && REG_N_SETS (regno) == 1
 		   && (REGNO_REG_SET_P
-		       (DF_UR_IN (rtl_df, ENTRY_BLOCK_PTR->next_bb), regno)))
+		       (DF_UR_IN (df, ENTRY_BLOCK_PTR->next_bb), regno)))
 		&& reg_stat[j].last_set_label > tick))
 	  {
 	    if (replace)
@@ -11354,7 +11353,7 @@ get_last_value (rtx x)
 	  && (regno < FIRST_PSEUDO_REGISTER
 	      || REG_N_SETS (regno) != 1
 	      || ! (REGNO_REG_SET_P
-		    (DF_UR_IN (rtl_df, ENTRY_BLOCK_PTR->next_bb), regno)))))
+		    (DF_UR_IN (df, ENTRY_BLOCK_PTR->next_bb), regno)))))
     return 0;
 
   /* If the value was set in a later insn than the ones we are processing,
@@ -11515,7 +11514,7 @@ reg_dead_at_p (rtx reg, rtx insn)
     }
 
   for (i = reg_dead_regno; i < reg_dead_endregno; i++)
-    if (REGNO_REG_SET_P (DF_LIVE_IN (rtl_df, block), i))
+    if (REGNO_REG_SET_P (DF_LIVE_IN (df, block), i))
       return 0;
 
   return 1;
@@ -12589,6 +12588,109 @@ dump_combine_total_stats (FILE *file)
 }
 
 
+/* Fill in log links field for all insns.  */
+
+static void
+create_log_links (void)
+{
+  basic_block bb;
+  rtx *next_use, insn;
+  struct df_ref *def, *use;
+
+  next_use = XCNEWVEC (rtx, max_reg_num ());
+
+  /* Pass through each block from the end, recording the uses of each
+     register and establishing log links when def is encountered.
+     Note that we do not clear next_use array in order to save time,
+     so we have to test whether the use is in the same basic block as def.
+              
+     There are a few cases below when we do not consider the definition or
+     usage -- these are taken from original flow.c did. Don't ask me why it is
+     done this way; I don't know and if it works, I don't want to know.  */
+
+  FOR_EACH_BB (bb)
+    {
+      FOR_BB_INSNS_REVERSE (bb, insn)
+        {
+          if (!INSN_P (insn))
+            continue;
+
+	  /* Log links are created only once.  */
+	  gcc_assert (!LOG_LINKS (insn));
+
+          for (def = DF_INSN_GET (df, insn)->defs; def; def = def->next_ref)
+            {
+              int regno = DF_REF_REGNO (def);
+              rtx use_insn;
+
+              if (!next_use[regno])
+                continue;
+
+              /* Do not consider if it is pre/post modification in MEM.  */
+              if (DF_REF_FLAGS (def) & DF_REF_PRE_POST_MODIFY)
+                continue;
+
+              /* Do not make the log link for frame pointer.  */
+              if ((regno == FRAME_POINTER_REGNUM
+                   && (! reload_completed || frame_pointer_needed))
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+                  || (regno == HARD_FRAME_POINTER_REGNUM
+                      && (! reload_completed || frame_pointer_needed))
+#endif
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+                  || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
+#endif
+                  )
+                continue;
+
+              use_insn = next_use[regno];
+              if (BLOCK_FOR_INSN (use_insn) == bb)
+                {
+                  /* flow.c claimed:
+
+                     We don't build a LOG_LINK for hard registers contained
+                     in ASM_OPERANDs.  If these registers get replaced,
+                     we might wind up changing the semantics of the insn,
+                     even if reload can make what appear to be valid
+                     assignments later.  */
+                  if (regno >= FIRST_PSEUDO_REGISTER
+                      || asm_noperands (PATTERN (use_insn)) < 0)
+                    LOG_LINKS (use_insn) =
+                      alloc_INSN_LIST (insn, LOG_LINKS (use_insn));
+                }
+              next_use[regno] = NULL_RTX;
+            }
+
+          for (use = DF_INSN_GET (df, insn)->uses; use; use = use->next_ref)
+            {
+              int regno = DF_REF_REGNO (use);
+
+              /* Do not consider the usage of the stack pointer
+		 by function call.  */
+              if (DF_REF_FLAGS (use) & DF_REF_CALL_STACK_USAGE)
+                continue;
+
+              next_use[regno] = insn;
+            }
+        }
+    }
+
+  free (next_use);
+}
+
+/* Clear LOG_LINKS fields of insns.  */
+
+static void
+clear_log_links (void)
+{
+  rtx insn;
+
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    if (INSN_P (insn))
+      free_INSN_LIST_list (&LOG_LINKS (insn));
+}
+
+
 static bool
 gate_handle_combine (void)
 {
@@ -12599,7 +12701,15 @@ gate_handle_combine (void)
 static unsigned int
 rest_of_handle_combine (void)
 {
-  int rebuild_jump_labels_after_combine
+  int rebuild_jump_labels_after_combine;
+
+  df = df_init (DF_HARD_REGS);
+  df_clrur_add_problem (df, 0);
+  df_ri_add_problem (df, DF_RI_LIFE);
+  df_analyze (df);
+
+  create_log_links ();
+  rebuild_jump_labels_after_combine
     = combine_instructions (get_insns (), max_reg_num ());
 
   /* Combining insns may have turned an indirect jump into a
@@ -12612,8 +12722,10 @@ rest_of_handle_combine (void)
       timevar_pop (TV_JUMP);
 
       delete_dead_jumptables ();
-      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+      cleanup_cfg (CLEANUP_EXPENSIVE);
     }
+  df_finish (df);
+  clear_log_links ();
   return 0;
 }
 
Index: bb-reorder.c
===================================================================
--- bb-reorder.c	(revision 115422)
+++ bb-reorder.c	(working copy)
@@ -2256,8 +2256,6 @@ rest_of_handle_partition_blocks (void)
   no_new_pseudos = 0;
   partition_hot_cold_basic_blocks ();
   allocate_reg_life_data ();
-  update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
-		    PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
   no_new_pseudos = 1;
   return 0;
 }
Index: basic-block.h
===================================================================
--- basic-block.h	(revision 115422)
+++ basic-block.h	(working copy)
@@ -811,14 +811,13 @@ enum update_life_extent
 /* Flags for life_analysis and update_life_info.  */
 
 #define PROP_DEATH_NOTES	1	/* Create DEAD and UNUSED notes.  */
-#define PROP_LOG_LINKS		2	/* Create LOG_LINKS.  */
-#define PROP_REG_INFO		4	/* Update regs_ever_live et al.  */
-#define PROP_KILL_DEAD_CODE	8	/* Remove dead code.  */
-#define PROP_SCAN_DEAD_CODE	16	/* Scan for dead code.  */
-#define PROP_ALLOW_CFG_CHANGES	32	/* Allow the CFG to be changed
+#define PROP_REG_INFO		2	/* Update regs_ever_live et al.  */
+#define PROP_KILL_DEAD_CODE	4	/* Remove dead code.  */
+#define PROP_SCAN_DEAD_CODE	8	/* Scan for dead code.  */
+#define PROP_ALLOW_CFG_CHANGES	16	/* Allow the CFG to be changed
 					   by dead code removal.  */
-#define PROP_AUTOINC		64	/* Create autoinc mem references.  */
-#define PROP_SCAN_DEAD_STORES	128	/* Scan for dead code.  */
+#define PROP_AUTOINC		32	/* Create autoinc mem references.  */
+#define PROP_SCAN_DEAD_STORES	64	/* Scan for dead code.  */
 #define PROP_DEAD_INSN		1024	/* Internal flag used within flow.c
 					   to flag analysis of dead insn.  */
 #define PROP_NO_UNINITIALIZED_LL 2048   /* Build log links without anding in
@@ -828,13 +827,13 @@ enum update_life_extent
 					   to preserve REG_DEAD notes for
 					   stack regs.  */
 #if 1
-#define PROP_FINAL		(PROP_DEATH_NOTES | PROP_LOG_LINKS  \
+#define PROP_FINAL		(PROP_DEATH_NOTES \
 				 | PROP_REG_INFO | PROP_KILL_DEAD_CODE  \
 				 | PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
 				 | PROP_ALLOW_CFG_CHANGES \
 				 | PROP_SCAN_DEAD_STORES)
 #else
-#define PROP_FINAL		(PROP_DEATH_NOTES | PROP_LOG_LINKS  \
+#define PROP_FINAL		(PROP_DEATH_NOTES \
 				 | PROP_REG_INFO | PROP_KILL_DEAD_CODE  \
 				 | PROP_SCAN_DEAD_CODE \
 				 | PROP_ALLOW_CFG_CHANGES \
@@ -849,23 +848,21 @@ 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_UPDATE_LIFE	8	/* Keep life information up to date.  */
 #define CLEANUP_THREADING	16	/* Do jump threading.  */
 #define CLEANUP_NO_INSN_DEL	32	/* Do not try to delete trivially dead
 					   insns.  */
 #define CLEANUP_CFGLAYOUT	64	/* Do cleanup in cfglayout mode.  */
-#define CLEANUP_LOG_LINKS	128	/* Update log links.  */
 
 /* The following are ORed in on top of the CLEANUP* flags in calls to
    struct_equiv_block_eq.  */
-#define STRUCT_EQUIV_START	256	 /* Initializes the search range.  */
-#define STRUCT_EQUIV_RERUN	512	/* Rerun to find register use in
+#define STRUCT_EQUIV_START	128	 /* Initializes the search range.  */
+#define STRUCT_EQUIV_RERUN	256	/* Rerun to find register use in
 					   found equivalence.  */
-#define STRUCT_EQUIV_FINAL	1024	/* Make any changes necessary to get
+#define STRUCT_EQUIV_FINAL	512	/* Make any changes necessary to get
 					   actual equivalence.  */
-#define STRUCT_EQUIV_NEED_FULL_BLOCK 2048 /* struct_equiv_block_eq is required
+#define STRUCT_EQUIV_NEED_FULL_BLOCK 1024 /* struct_equiv_block_eq is required
 					     to match only full blocks  */
-#define STRUCT_EQUIV_MATCH_JUMPS 4096	/* Also include the jumps at the end of the block in the comparison.  */
+#define STRUCT_EQUIV_MATCH_JUMPS 2048	/* Also include the jumps at the end of the block in the comparison.  */
 
 extern void life_analysis (int);
 extern int update_life_info (sbitmap, enum update_life_extent, int);
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 115422)
+++ tree-cfg.c	(working copy)
@@ -5497,16 +5497,13 @@ struct cfg_hooks tree_cfg_hooks = {
   tree_redirect_edge_and_branch_force,/* redirect_edge_and_branch_force  */
   remove_bb,			/* delete_basic_block  */
   tree_split_block,		/* split_block  */
-  NULL,                         /* split_block_end */
   tree_move_block_after,	/* move_block_after  */
   tree_can_merge_blocks_p,	/* can_merge_blocks_p  */
   tree_merge_blocks,		/* merge_blocks  */
-  NULL,                         /* merge_blocks_end  */
   tree_predict_edge,		/* predict_edge  */
   tree_predicted_by_p,		/* predicted_by_p  */
   tree_can_duplicate_bb_p,	/* can_duplicate_block_p  */
   tree_duplicate_bb,		/* duplicate_block  */
-  NULL,		                /* duplicate_block_end  */
   tree_split_edge,		/* split_edge  */
   tree_make_forwarder_block,	/* make_forward_block  */
   NULL,				/* tidy_fallthru_edge  */
Index: struct-equiv.c
===================================================================
--- struct-equiv.c	(revision 115422)
+++ struct-equiv.c	(working copy)
@@ -989,10 +989,6 @@ bool
 struct_equiv_init (int mode, struct equiv_info *info)
 {
   if ((info->x_block->flags | info->y_block->flags) & BB_DIRTY)
-    update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
-				      (PROP_DEATH_NOTES
-				       | ((mode & CLEANUP_POST_REGSTACK)
-					  ? PROP_POST_REGSTACK : 0)));
   if (!REG_SET_EQUAL_P (DF_LR_OUT (rtl_df, info->x_block),
 			DF_LR_OUT (rtl_df, info->y_block)))
     {
Index: dce.c
===================================================================
--- dce.c	(revision 115422)
+++ dce.c	(working copy)
@@ -191,17 +191,9 @@ init_dce (bool fast)
     {
       if (fast)
 	{
-	  if (rtl_df)
-	    {
-	      dce_df = rtl_df;
-	      df_analyze (dce_df);
-	    }
-	  else
-	    {
-	      dce_df = df_init (DF_HARD_REGS);
-	      df_lr_add_problem (dce_df, 0);
-	      df_analyze (dce_df);
-	    }
+	  dce_df = df_init (DF_HARD_REGS);
+	  df_lr_add_problem (dce_df, 0);
+	  df_analyze (dce_df);
 	}
       else
 	{
@@ -301,13 +293,6 @@ end_dce (void)
   BITMAP_FREE (marked_libcalls);
 
   df_finish (dce_df);
-
-  /* People who call dce expect the core data flow to be updated.  */
-  if (rtl_df)
-    {
-      df_rescan_blocks (rtl_df, NULL);
-      df_analyze (rtl_df);
-    }
 }
 
 
@@ -426,11 +411,7 @@ end_fast_dce (void)
   BITMAP_FREE (marked);
   BITMAP_FREE (marked_libcalls);
 
-  if (rtl_df)
-    dce_df = NULL;
-  else
-    df_finish (dce_df);
-  dce_df = NULL;
+  df_finish (dce_df);
 }
 
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]