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]

[COMMITTED]: update to df to mainline.


All of the additional formatting changes were done as you have asked. 
I rebootstrapped this on

x86_64-unknown-linux-gnu
powerpc64-unknown-linux-gnu
i686-pc-linux-gnu 

The prior patch without the formatting changes was bootstrapped and regression tested on all three of the above platforms.


Kenny

2006-05-19  Daniel Berlin  <dberlin@dberlin.org>
            Kenneth Zadeck <zadeck@naturalbridge.com>

    PR rtl-optimization/26855

    * df-scan.c (mw_reg_pool, mw_link_pool): New allocation pools for
    multiword refs.
    (df_scan_alloc): Added code to properly handle multiword hard
    registers and add all_blocks parameter.
    (df_scan_free_internal, df_insn_refs_delete, df_ref_record): Added
    code to properly handle multiword hard registers.
    (df_rescan_blocks): Added code to remove deleted blocks from
    bitmap.
    (df_ref_create_structure, df_ref_record): Added code to properly
    handle subregs.
    (df_ref_record_1): Changed DF_REF_CLOBBER into DF_REF_MUST_CLOBBER
    and set DF_REF_PARTIAL.
    (df_defs_record): Changed DF_REF_CLOBBER into DF_REF_MUST_CLOBBER.
    (df_uses_record): Added DF_REF_PARTIAL for subreg.
    (df_scan_add_problem): Added flags parameter.
    (df_ref_create_structure): Changed switching structure.
    (df_bb_refs_record): Fixed case where duplicate artificial refs
    were created.  Changed location of flags.
    (df_record_entry_block_defs): Added code to make stack pointer
    live in entry block.  Refined cases where frame pointer is needed.
    Changed location of flags.
    (df_record_exit_block_uses, df_insn_refs_record): Changed location
of flags.
    (df_set_state): Removed function.
    (df_grow_reg_info, df_reg_chain_unlink, df_ref_remove,
    df_insn_create_insn_record, df_insn_refs_delete,
    df_ref_create_structure): Formatting changes. 
    * df-core.c (df_mvs_dump, df_set_flags, df_clear_flags,
    df_delete_basic_block): New function.
    (df_init): Changed location of flags.
    (df_add_problem): Added flags parameter and the way flags are
    processed.
    (df_insn_uid_debug, df_ref_debug, debug_df_defno, debug_df_ref,
    debug_df_chain): Improved debugging output.
    (df_insn_debug, df_insn_uid_debug): Added multiword reg support.
    (df_refs_chain_dump): Removed df parameter.
    (df_iterative_dataflow): Added consistency check.
    (df_prune_to_subcfg): Made public.
    (df_analyze_problem): Added blocks_to_init parameter and made
    public.
    (df_ref_record, df_bb_refs_record, df_mark_reg,
     df_record_exit_block_uses): Whitespace changes.
    (df_dump): Whitespace changes.
    * df.h: Some reordering to remove forward references.
    (df_ref_flags.DF_REF_MW_HARDREG, DF_REF_PARTIAL,
    DF_REF_MUST_CLOBBER, DF_REF_MAY_CLOBBER): New fields.
    (df_ref_flags.DF_REF_CLOBBER): Deleted field.
    (dataflow.flags): New field.
    (df.flag): Deleted field.
    (df_alloc_function): Added additional bitmap parameter.
    (df_dependent_problem_function): New type.
    (df_problem.changeable_flags): New field.
    (df_ref_flags.DF_REF_DIES_AFTER_THIS_USE, DF_SCAN_INITIAL,
    DF_SCAN_GLOBAL, DF_SCAN_POST_ALLOC, df_state): Removed.
    (df_mw_hardreg): New struct.
    (DF_INSN_UID_MWS): New macro.
    (df_refs_chain_dump, df_ref_debug, df_chain_dump): Removed df
    parameter.
    (df_add_problem, df_ru_add_problem, df_rd_add_problem,
    df_lr_add_problem, df_ur_add_problem, df_urec_add_problem,
    df_ri_add_problem, df_scan_add_problem): Added flags parameter.
    (df_set_state): Removed function.
    (df_set_flags, df_clear_flags, df_delete_basic_block) New functions.
    * df-problems.c (df_chain_dump): Removed df parameter.
    (df_ru_alloc, df_rd_alloc, df_lr_alloc, df_ur_alloc,
    df_urec_alloc, df_chain_alloc, df_ri_alloc): Added all blocks
    parameter.
    (df_ru_alloc, df_rd_alloc): Now resets all blocks.
    (df_rd_bb_local_compute_process_def, df_ur_bb_local_compute,
    df_chain_create_bb, df_create_unused_note, df_ri_bb_compute):
    Split DF_REF_CLOBBER into DF_REF_MAY_CLOBBER and
    DF_REF_MUST_CLOBBER cases.
    (df_ru_bb_local_compute_process_def,
    df_rd_bb_local_compute_process_def, df_lr_bb_local_compute,
    df_lr_bb_local_compute, df_ur_bb_local_compute,
    df_chain_create_bb): Made subreg aware.
    (df_ru_bb_local_compute, df_rd_bb_local_compute,
    df_lr_bb_local_compute, df_lr_bb_local_compute,
    df_chain_create_bb): Cleanup to use proper macros.
    (df_ur_local_finalize, df_urec_local_finalize): Removed unnecessary
    code to fixup bitvectors.
    (df_ri_alloc): Cleared lifetime.
    (df_ignore_stack_reg, df_kill_notes, df_set_notes_for_mw,
    df_create_unused_note): New function.
    (df_ri_bb_compute, df_ri_compute): Added code to create/update
    REG_DEAD and REG_UNUSED notes as well as register information.
    (df_ru_dump, df_rd_dump, df_lr_dump, df_ur_dump, df_urec_dump,
    df_chains_dump): Fixed crash if problem was never run.
    (df_ru_add_problem, df_rd_add_problem, df_lr_add_problem,
    df_ur_add_problem, df_urec_add_problem, df_chain_add_problem,
    df_ri_add_problem): Processes flags in uniform manner.
    (df_ru_alloc, df_ru_local_compute, df_ru_confluence_n, df_ru_free,
    df_ru_dump, df_rd_local_compute, df_rd_confluence_n, df_rd_free,
    df_rd_dump, df_urec_free_bb_info): Formatting changes.
    (df_ru_free_bb_info, df_ru_bb_local_compute, df_ru_dump,
    df_rd_free_bb_info, df_rd_bb_local_compute_process_def,
    df_rd_bb_local_compute, df_rd_dump, df_lr_free_bb_info,
    df_lr_bb_local_compute, df_lr_local_compute, df_ur_free_bb_info,
    df_ur_dump, df_urec_free_bb_info, df_urec_dump,
    df_chain_create_bb, df_ri_bb_compute): Whitespace changes.
    * modulo-sched.c (sms_schedule): Added flag parameter to calls.
    * see.c (see_initialize_data): Ditto.
    * final.c (rest_of_clean_state) Added regstack_completed.
    * rtl.h (regstack_completed): Ditto.
    * reg-stack.c (regstack_completed): Ditto.











Bernd Schmidt wrote:
> Thunderbird crashed a few times while I was trying to reply in-line,
> hence please read the attachment.
>
>
> Bernd
> ------------------------------------------------------------------------
>
>   
>> @@ -1845,7 +1952,7 @@ df_record_exit_block_uses (struct datafl
>>       If we end up eliminating it, it will be removed from the live
>>       list of each basic block by reload.  */
>>    
>> -  if (! reload_completed || frame_pointer_needed)
>> +  if ((! reload_completed) || frame_pointer_needed)
>>    {
>>      bitmap_set_bit (df->exit_block_uses, FRAME_POINTER_REGNUM);
>> if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
>>     
>
> Not an improvement.  Several such cases.
>
> The patch is inconsistent in the formatting of the ! operator; and while I
> dislike the coding style recommendation, I'll have to ask you to consistently
> format things without the space.
>
>   
>>    /* Init Data Flow analysis, to be used in interloop dep calculation.  */
>>    df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES |	DF_SUBREGS);
>>     
>
> Stray tab character.  Elsewhere too.
>
>
> The patch is ok with those changes.  I have some additional requests though.
>
> In the future, please submit one patch per functional change.  This set had
> coding style fixups, code movement, bugfixes, and extra features all mixed
> into one.  You're much more likely to get a review for something that doesn't
> need to be disentangled.
>
> Also, I've been looking at the code for the urec problem, and it looks a bit
> dodgy at first glance.  What can you tell me about this code - when does it
> run, who uses it?
>
> Have you done any testing to ensure that your version of the flow code finds
> the same REG_DEAD/REG_UNUSED notes, and computes the same values for things
> like REG_FREQ or REG_LIVE_LENGTH?
>
>
> Bernd
>   

Index: df-scan.c
===================================================================
--- df-scan.c	(revision 113909)
+++ df-scan.c	(working copy)
@@ -65,9 +65,6 @@ Software Foundation, 51 Franklin Street,
 #define EPILOGUE_USES(REGNO)  0
 #endif
 
-/* Indicates where we are in the compilation.  */
-int df_state;
-
 /* The bitmap_obstack is used to hold some static variables that
    should not be reset after each function is compiled.  */
 
@@ -122,6 +119,8 @@ struct df_scan_problem_data
   alloc_pool ref_pool;
   alloc_pool insn_pool;
   alloc_pool reg_pool;
+  alloc_pool mw_reg_pool;
+  alloc_pool mw_link_pool;
 };
 
 typedef struct df_scan_bb_info *df_scan_bb_info_t;
@@ -130,8 +129,8 @@ static void 
 df_scan_free_internal (struct dataflow *dflow)
 {
   struct df *df = dflow->df;
-  struct df_scan_problem_data *problem_data = 
-    (struct df_scan_problem_data *) dflow->problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) dflow->problem_data;
 
   free (df->def_info.regs);
   free (df->def_info.refs);
@@ -157,6 +156,8 @@ df_scan_free_internal (struct dataflow *
   free_alloc_pool (problem_data->ref_pool);
   free_alloc_pool (problem_data->insn_pool);
   free_alloc_pool (problem_data->reg_pool);
+  free_alloc_pool (problem_data->mw_reg_pool);
+  free_alloc_pool (problem_data->mw_link_pool);
 }
 
 
@@ -200,7 +201,8 @@ df_scan_free_bb_info (struct dataflow *d
    be rescanned.  */
 
 static void 
-df_scan_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_scan_alloc (struct dataflow *dflow, bitmap blocks_to_rescan, 
+	       bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   struct df *df = dflow->df;
   struct df_scan_problem_data *problem_data;
@@ -231,6 +233,12 @@ df_scan_alloc (struct dataflow *dflow, b
   problem_data->reg_pool 
     = create_alloc_pool ("df_scan_reg pool", 
 			 sizeof (struct df_reg_info), block_size);
+  problem_data->mw_reg_pool 
+    = create_alloc_pool ("df_scan_mw_reg pool", 
+			 sizeof (struct df_mw_hardreg), block_size);
+  problem_data->mw_link_pool 
+    = create_alloc_pool ("df_scan_mw_link pool", 
+			 sizeof (struct df_link), block_size);
 
   insn_num += insn_num / 4; 
   df_grow_reg_info (dflow, &df->def_info);
@@ -319,7 +327,8 @@ static struct df_problem problem_SCAN =
   NULL,                       /* Finalize function.  */
   df_scan_free,               /* Free all of the problem information.  */
   df_scan_dump,               /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -328,9 +337,9 @@ static struct df_problem problem_SCAN =
    solution.  */
 
 struct dataflow *
-df_scan_add_problem (struct df *df)
+df_scan_add_problem (struct df *df, int flags)
 {
-  return df_add_problem (df, &problem_SCAN);
+  return df_add_problem (df, &problem_SCAN, flags);
 }
 
 /*----------------------------------------------------------------------------
@@ -350,8 +359,8 @@ df_grow_reg_info (struct dataflow *dflow
 {
   unsigned int max_reg = max_reg_num ();
   unsigned int new_size = max_reg;
-  struct df_scan_problem_data *problem_data =
-    (struct df_scan_problem_data *) dflow->problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) dflow->problem_data;
   unsigned int i;
 
   if (ref_info->regs_size < new_size)
@@ -432,6 +441,9 @@ df_rescan_blocks (struct df *df, bitmap 
   if (blocks)
     {
       int i;
+      unsigned int bb_index;
+      bitmap_iterator bi;
+      bool cleared_bits = false;
 
       /* Need to assure that there are space in all of the tables.  */
       unsigned int insn_num = get_max_uid () + 1;
@@ -447,6 +459,20 @@ df_rescan_blocks (struct df *df, bitmap 
       df_grow_bb_info (dflow);
 
       bitmap_copy (local_blocks_to_scan, blocks);
+
+      EXECUTE_IF_SET_IN_BITMAP (blocks, 0, bb_index, bi)
+	{
+	  basic_block bb = BASIC_BLOCK (bb_index);
+	  if (!bb)
+	    {
+	      bitmap_clear_bit (local_blocks_to_scan, bb_index);
+	      cleared_bits = true;
+	    }
+	}
+
+      if (cleared_bits)
+	bitmap_copy (blocks, local_blocks_to_scan);
+
       df->def_info.add_refs_inline = true;
       df->use_info.add_refs_inline = true;
 
@@ -490,7 +516,7 @@ df_rescan_blocks (struct df *df, bitmap 
 	  {
 	    bitmap_set_bit (local_blocks_to_scan, bb->index);
 	  }
-      df_scan_alloc (dflow, local_blocks_to_scan);
+      df_scan_alloc (dflow, local_blocks_to_scan, NULL);
 
       df->def_info.add_refs_inline = false;
       df->use_info.add_refs_inline = false;
@@ -508,6 +534,7 @@ df_rescan_blocks (struct df *df, bitmap 
   BITMAP_FREE (local_blocks_to_scan);
 }
 
+
 /* Create a new ref of type DF_REF_TYPE for register REG at address
    LOC within INSN of BB.  */
 
@@ -634,8 +661,8 @@ df_reg_chain_unlink (struct dataflow *df
   struct df *df = dflow->df;
   struct df_ref *next = DF_REF_NEXT_REG (ref);  
   struct df_ref *prev = DF_REF_PREV_REG (ref);
-  struct df_scan_problem_data *problem_data =
-    (struct df_scan_problem_data *) dflow->problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) dflow->problem_data;
   struct df_reg_info *reg_info;
   struct df_ref *next_ref = ref->next_ref;
   unsigned int id = DF_REF_ID (ref);
@@ -697,8 +724,8 @@ df_ref_remove (struct df *df, struct df_
 	    = df_ref_unlink (bb_info->artificial_defs, ref);
 	}
       else
-	DF_INSN_UID_DEFS (df, DF_REF_INSN_UID (ref)) = 
-	  df_ref_unlink (DF_INSN_UID_DEFS (df, DF_REF_INSN_UID (ref)), ref);
+	DF_INSN_UID_DEFS (df, DF_REF_INSN_UID (ref))
+	  = df_ref_unlink (DF_INSN_UID_DEFS (df, DF_REF_INSN_UID (ref)), ref);
 
       if (df->def_info.add_refs_inline)
 	DF_DEFS_SET (df, DF_REF_ID (ref), NULL);
@@ -713,8 +740,8 @@ df_ref_remove (struct df *df, struct df_
 	    = df_ref_unlink (bb_info->artificial_uses, ref);
 	}
       else
-	DF_INSN_UID_USES (df, DF_REF_INSN_UID (ref)) = 
-	  df_ref_unlink (DF_INSN_UID_USES (df, DF_REF_INSN_UID (ref)), ref);
+	DF_INSN_UID_USES (df, DF_REF_INSN_UID (ref))
+	  = df_ref_unlink (DF_INSN_UID_USES (df, DF_REF_INSN_UID (ref)), ref);
       
       if (df->use_info.add_refs_inline)
 	DF_USES_SET (df, DF_REF_ID (ref), NULL);
@@ -730,8 +757,8 @@ static struct df_insn_info *
 df_insn_create_insn_record (struct dataflow *dflow, rtx insn)
 {
   struct df *df = dflow->df;
-  struct df_scan_problem_data *problem_data =
-    (struct df_scan_problem_data *) dflow->problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) dflow->problem_data;
 
   struct df_insn_info *insn_rec = DF_INSN_GET (df, insn);
   if (!insn_rec)
@@ -754,14 +781,31 @@ df_insn_refs_delete (struct dataflow *df
   unsigned int uid = INSN_UID (insn);
   struct df_insn_info *insn_info = NULL;
   struct df_ref *ref;
-  struct df_scan_problem_data *problem_data =
-    (struct df_scan_problem_data *) dflow->problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) dflow->problem_data;
 
   if (uid < df->insns_size)
     insn_info = DF_INSN_UID_GET (df, uid);
 
   if (insn_info)
     {
+      struct df_mw_hardreg *hardregs = insn_info->mw_hardregs;
+      
+      while (hardregs)
+	{
+	  struct df_mw_hardreg *next_hr = hardregs->next;
+	  struct df_link *link = hardregs->regs;
+	  while (link)
+	    {
+	      struct df_link *next_l = link->next;
+	      pool_free (problem_data->mw_link_pool, link);
+	      link = next_l;
+	    }
+	  
+	  pool_free (problem_data->mw_reg_pool, hardregs);
+	  hardregs = next_hr;
+	}
+
       ref = insn_info->defs;
       while (ref) 
 	ref = df_reg_chain_unlink (dflow, ref);
@@ -876,20 +920,6 @@ df_reorganize_refs (struct df_ref_info *
 }
 
 
-/* Local miscellaneous routines.  */
-
-/* Local routines for recording refs.  */
-
-/* Set where we are in the compilation.  */
-
-void 
-df_set_state (int state)
-{
-  df_state = state;
-}
-
-
-
 /*----------------------------------------------------------------------------
    Hard core instruction scanning code.  No external interfaces here,
    just a lot of routines that look inside insns.
@@ -906,8 +936,8 @@ df_ref_create_structure (struct dataflow
   struct df_ref *this_ref;
   struct df *df = dflow->df;
   int regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
-  struct df_scan_problem_data *problem_data =
-    (struct df_scan_problem_data *) dflow->problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) dflow->problem_data;
 
   this_ref = pool_alloc (problem_data->ref_pool);
   DF_REF_REG (this_ref) = reg;
@@ -922,76 +952,88 @@ df_ref_create_structure (struct dataflow
 
   /* Link the ref into the reg_def and reg_use chains and keep a count
      of the instances.  */
-  if (ref_type == DF_REF_REG_DEF)
+  switch (ref_type)
     {
-      struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno);
-      reg_info->n_refs++;
-
-      /* Add the ref to the reg_def chain.  */
-      df_reg_chain_create (reg_info, this_ref);
-      DF_REF_ID (this_ref) = df->def_info.bitmap_size;
-      if (df->def_info.add_refs_inline)
-	{
-	  if (DF_DEFS_SIZE (df) >= df->def_info.refs_size)
-	    {
-	      int new_size = df->def_info.bitmap_size 
-		+ df->def_info.bitmap_size / 4;
-	      df_grow_ref_info (&df->def_info, new_size);
-	    }
-	  /* Add the ref to the big array of defs.  */
-	  DF_DEFS_SET (df, df->def_info.bitmap_size, this_ref);
-	  df->def_info.refs_organized = false;
-	}
-
-      df->def_info.bitmap_size++;
+    case DF_REF_REG_DEF:
+      {
+	struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno);
+	reg_info->n_refs++;
+	
+	/* Add the ref to the reg_def chain.  */
+	df_reg_chain_create (reg_info, this_ref);
+	DF_REF_ID (this_ref) = df->def_info.bitmap_size;
+	if (df->def_info.add_refs_inline)
+	  {
+	    if (DF_DEFS_SIZE (df) >= df->def_info.refs_size)
+	      {
+		int new_size = df->def_info.bitmap_size 
+		  + df->def_info.bitmap_size / 4;
+		df_grow_ref_info (&df->def_info, new_size);
+	      }
+	    /* Add the ref to the big array of defs.  */
+	    DF_DEFS_SET (df, df->def_info.bitmap_size, this_ref);
+	    df->def_info.refs_organized = false;
+	  }
+	
+	df->def_info.bitmap_size++;
+	
+	if (DF_REF_FLAGS (this_ref) & DF_REF_ARTIFICIAL)
+	  {
+	    struct df_scan_bb_info *bb_info 
+	      = df_scan_get_bb_info (dflow, bb->index);
+	    this_ref->next_ref = bb_info->artificial_defs;
+	    bb_info->artificial_defs = this_ref;
+	  }
+	else
+	  {
+	    this_ref->next_ref = DF_INSN_GET (df, insn)->defs;
+	    DF_INSN_GET (df, insn)->defs = this_ref;
+	  }
+      }
+      break;
 
-      if (DF_REF_FLAGS (this_ref) & DF_REF_ARTIFICIAL)
-	{
-	  struct df_scan_bb_info *bb_info 
-	    = df_scan_get_bb_info (dflow, bb->index);
-	  this_ref->next_ref = bb_info->artificial_defs;
-	  bb_info->artificial_defs = this_ref;
-	}
-      else
-	{
-	  this_ref->next_ref = DF_INSN_GET (df, insn)->defs;
-	  DF_INSN_GET (df, insn)->defs = this_ref;
-	}
-    }
-  else
-    {
-      struct df_reg_info *reg_info = DF_REG_USE_GET (df, regno);
-      reg_info->n_refs++;
+    case DF_REF_REG_MEM_LOAD:
+    case DF_REF_REG_MEM_STORE:
+    case DF_REF_REG_USE:
+      {
+	struct df_reg_info *reg_info = DF_REG_USE_GET (df, regno);
+	reg_info->n_refs++;
+	
+	/* Add the ref to the reg_use chain.  */
+	df_reg_chain_create (reg_info, this_ref);
+	DF_REF_ID (this_ref) = df->use_info.bitmap_size;
+	if (df->use_info.add_refs_inline)
+	  {
+	    if (DF_USES_SIZE (df) >= df->use_info.refs_size)
+	      {
+		int new_size = df->use_info.bitmap_size 
+		  + df->use_info.bitmap_size / 4;
+		df_grow_ref_info (&df->use_info, new_size);
+	      }
+	    /* Add the ref to the big array of defs.  */
+	    DF_USES_SET (df, df->use_info.bitmap_size, this_ref);
+	    df->use_info.refs_organized = false;
+	  }
+	
+	df->use_info.bitmap_size++;
+	if (DF_REF_FLAGS (this_ref) & DF_REF_ARTIFICIAL)
+	  {
+	    struct df_scan_bb_info *bb_info 
+	      = df_scan_get_bb_info (dflow, bb->index);
+	    this_ref->next_ref = bb_info->artificial_uses;
+	    bb_info->artificial_uses = this_ref;
+	  }
+	else
+	  {
+	    this_ref->next_ref = DF_INSN_GET (df, insn)->uses;
+	    DF_INSN_GET (df, insn)->uses = this_ref;
+	  }
+      }
+      break;
 
-      /* Add the ref to the reg_use chain.  */
-      df_reg_chain_create (reg_info, this_ref);
-      DF_REF_ID (this_ref) = df->use_info.bitmap_size;
-      if (df->use_info.add_refs_inline)
-	{
-	  if (DF_USES_SIZE (df) >= df->use_info.refs_size)
-	    {
-	      int new_size = df->use_info.bitmap_size 
-		+ df->use_info.bitmap_size / 4;
-	      df_grow_ref_info (&df->use_info, new_size);
-	    }
-	  /* Add the ref to the big array of defs.  */
-	  DF_USES_SET (df, df->use_info.bitmap_size, this_ref);
-	  df->use_info.refs_organized = false;
-	}
+    default:
+      gcc_unreachable ();
 
-      df->use_info.bitmap_size++;
-      if (DF_REF_FLAGS (this_ref) & DF_REF_ARTIFICIAL)
-	{
-	  struct df_scan_bb_info *bb_info 
-	    = df_scan_get_bb_info (dflow, bb->index);
-	  this_ref->next_ref = bb_info->artificial_uses;
-	  bb_info->artificial_uses = this_ref;
-	}
-      else
-	{
-	  this_ref->next_ref = DF_INSN_GET (df, insn)->uses;
-	  DF_INSN_GET (df, insn)->uses = this_ref;
-	}
     }
   return this_ref;
 }
@@ -1007,8 +1049,9 @@ df_ref_record (struct dataflow *dflow, r
 	       enum df_ref_flags ref_flags, 
 	       bool record_live)
 {
-  unsigned int regno;
   struct df *df = dflow->df;
+  rtx oldreg = reg;
+  unsigned int regno;
 
   gcc_assert (REG_P (reg) || GET_CODE (reg) == SUBREG);
 
@@ -1017,7 +1060,7 @@ df_ref_record (struct dataflow *dflow, r
      reg.  As written in the docu those should have the form
      (subreg:SI (reg:M A) N), with size(SImode) > size(Mmode).
      XXX Is that true?  We could also use the global word_mode variable.  */
-  if ((df->flags & DF_SUBREGS) == 0
+  if ((dflow->flags & DF_SUBREGS) == 0
       && GET_CODE (reg) == SUBREG
       && (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (word_mode)
 	  || GET_MODE_SIZE (GET_MODE (reg))
@@ -1031,10 +1074,13 @@ df_ref_record (struct dataflow *dflow, r
   regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
   if (regno < FIRST_PSEUDO_REGISTER)
     {
-      int i;
-      int endregno;
+      unsigned int i;
+      unsigned int endregno;
+      struct df_mw_hardreg *hardreg = NULL;
+      struct df_scan_problem_data *problem_data
+	= (struct df_scan_problem_data *) dflow->problem_data;
 
-      if (! (df->flags & DF_HARD_REGS))
+      if (!(dflow->flags & DF_HARD_REGS))
 	return;
 
       /* GET_MODE (reg) is correct here.  We do not want to go into a SUBREG
@@ -1048,8 +1094,30 @@ df_ref_record (struct dataflow *dflow, r
 				      SUBREG_BYTE (reg), GET_MODE (reg));
       endregno += regno;
 
+      /*  If this is a multiword hardreg, we create some extra datastructures that 
+	  will enable us to easily build REG_DEAD and REG_UNUSED notes.  */
+      if ((endregno != regno + 1) && insn)
+	{
+	  struct df_insn_info *insn_info = DF_INSN_GET (df, insn);
+	  /* Sets to a subreg of a multiword register are partial. 
+	     Sets to a non-subreg of a multiword register are not.  */
+	  if (GET_CODE (oldreg) == SUBREG)
+	    ref_flags |= DF_REF_PARTIAL;
+	  ref_flags |= DF_REF_MW_HARDREG;
+	  hardreg = pool_alloc (problem_data->mw_reg_pool);
+	  hardreg->next = insn_info->mw_hardregs;
+	  insn_info->mw_hardregs = hardreg;
+	  hardreg->type = ref_type;
+	  hardreg->flags = ref_flags;
+	  hardreg->mw_reg = reg;
+	  hardreg->regs = NULL;
+
+	}
+
       for (i = regno; i < endregno; i++)
 	{
+	  struct df_ref *ref;
+
 	  /* Calls are handled at call site because regs_ever_live
 	     doesn't include clobbered regs, only used ones.  */
 	  if (ref_type == DF_REF_REG_DEF && record_live)
@@ -1061,14 +1129,22 @@ df_ref_record (struct dataflow *dflow, r
 	    {
 	      /* Set regs_ever_live on uses of non-eliminable frame
 		 pointers and arg pointers.  */
-	      if (! (TEST_HARD_REG_BIT (elim_reg_set, regno)
+	      if (!(TEST_HARD_REG_BIT (elim_reg_set, regno)
 		     && (regno == FRAME_POINTER_REGNUM 
 			 || regno == ARG_POINTER_REGNUM)))
 		regs_ever_live[i] = 1;
 	    }
 
-	  df_ref_create_structure (dflow, regno_reg_rtx[i], loc, 
-				   bb, insn, ref_type, ref_flags);
+	  ref = df_ref_create_structure (dflow, regno_reg_rtx[i], loc, 
+					 bb, insn, ref_type, ref_flags);
+	  if (hardreg)
+	    {
+	      struct df_link *link = pool_alloc (problem_data->mw_link_pool);
+
+	      link->next = hardreg->regs;
+	      link->ref = ref;
+	      hardreg->regs = link;
+	    }
 	}
     }
   else
@@ -1107,6 +1183,7 @@ df_def_record_1 (struct dataflow *dflow,
 {
   rtx *loc;
   rtx dst;
+  bool dst_in_strict_lowpart = false;
 
  /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
      construct.  */
@@ -1127,7 +1204,8 @@ df_def_record_1 (struct dataflow *dflow,
 	  if (GET_CODE (temp) == EXPR_LIST || GET_CODE (temp) == CLOBBER
 	      || GET_CODE (temp) == SET)
 	    df_def_record_1 (dflow, temp, bb, insn, 
-			     GET_CODE (temp) == CLOBBER ? flags | DF_REF_CLOBBER : flags, 
+			     GET_CODE (temp) == CLOBBER 
+			     ? flags | DF_REF_MUST_CLOBBER : flags, 
 			     record_live);
 	}
       return;
@@ -1149,10 +1227,20 @@ df_def_record_1 (struct dataflow *dflow,
 	}
 #endif
       loc = &XEXP (dst, 0);
+      if (GET_CODE (dst) == STRICT_LOW_PART)
+	dst_in_strict_lowpart = true;
       dst = *loc;
       flags |= DF_REF_READ_WRITE;
+
     }
 
+  /* Sets to a subreg of a single word register are partial sets if
+     they are wrapped in a strict lowpart, and not partial otherwise.
+  */
+  if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))
+      && dst_in_strict_lowpart)
+    flags |= DF_REF_PARTIAL;
+    
   if (REG_P (dst)
       || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
     df_ref_record (dflow, dst, loc, bb, insn, 
@@ -1171,7 +1259,7 @@ df_defs_record (struct dataflow *dflow, 
     {
       /* Mark the single def within the pattern.  */
       df_def_record_1 (dflow, x, bb, insn, 
-		       code == CLOBBER ? DF_REF_CLOBBER : 0, true);
+		       code == CLOBBER ? DF_REF_MUST_CLOBBER : 0, true);
     }
   else if (code == COND_EXEC)
     {
@@ -1232,7 +1320,7 @@ df_uses_record (struct dataflow *dflow, 
 
     case SUBREG:
       /* While we're here, optimize this case.  */
-
+      flags |= DF_REF_PARTIAL;
       /* In case the SUBREG is not of a REG, do not optimize.  */
       if (!REG_P (SUBREG_REG (x)))
 	{
@@ -1424,8 +1512,8 @@ df_insn_contains_asm (rtx insn)
 static void
 df_insn_refs_record (struct dataflow *dflow, basic_block bb, rtx insn)
 {
-  int i;
   struct df *df = dflow->df;
+  int i;
 
   if (INSN_P (insn))
     {
@@ -1437,7 +1525,7 @@ df_insn_refs_record (struct dataflow *df
       /* Record register defs.  */
       df_defs_record (dflow, PATTERN (insn), bb, insn);
 
-      if (df->flags & DF_EQUIV_NOTES)
+      if (dflow->flags & DF_EQUIV_NOTES)
 	for (note = REG_NOTES (insn); note;
 	     note = XEXP (note, 1))
 	  {
@@ -1490,7 +1578,7 @@ df_insn_refs_record (struct dataflow *df
 			  DF_REF_REG_USE, bb, insn, 
 			  0);
 
-	  if (df->flags & DF_HARD_REGS)
+	  if (dflow->flags & DF_HARD_REGS)
 	    {
 	      bitmap_iterator bi;
 	      unsigned int ui;
@@ -1502,8 +1590,8 @@ df_insn_refs_record (struct dataflow *df
 				  DF_REF_REG_USE, bb, insn, 
 				  0);
 	      EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, ui, bi)
-	        df_ref_record (dflow, regno_reg_rtx[ui], &regno_reg_rtx[ui], bb, insn, 
-	                       DF_REF_REG_DEF, DF_REF_CLOBBER, false);
+	        df_ref_record (dflow, regno_reg_rtx[ui], &regno_reg_rtx[ui], bb, 
+			       insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER, false);
 	    }
 	}
 
@@ -1537,6 +1625,10 @@ df_bb_refs_record (struct dataflow *dflo
   rtx insn;
   int luid = 0;
   struct df_scan_bb_info *bb_info = df_scan_get_bb_info (dflow, bb->index);
+  bitmap artificial_uses_at_bottom = NULL;
+
+  if (dflow->flags & DF_HARD_REGS)
+    artificial_uses_at_bottom = BITMAP_ALLOC (NULL);
 
   /* Need to make sure that there is a record in the basic block info. */  
   if (!bb_info)
@@ -1561,7 +1653,7 @@ df_bb_refs_record (struct dataflow *dflo
     }
 
 #ifdef EH_RETURN_DATA_REGNO
-  if ((df->flags & DF_HARD_REGS)
+  if ((dflow->flags & DF_HARD_REGS)
       && df_has_eh_preds (bb))
     {
       unsigned int i;
@@ -1580,7 +1672,7 @@ df_bb_refs_record (struct dataflow *dflo
 #endif
 
 
-  if ((df->flags & DF_HARD_REGS)
+  if ((dflow->flags & DF_HARD_REGS)
       && df_has_eh_preds (bb))
     {
 #ifdef EH_USES
@@ -1611,56 +1703,60 @@ df_bb_refs_record (struct dataflow *dflo
 	{
 	  if (frame_pointer_needed)
 	    {
-	      df_uses_record (dflow, &regno_reg_rtx[FRAME_POINTER_REGNUM],
-			      DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+	      bitmap_set_bit (artificial_uses_at_bottom, FRAME_POINTER_REGNUM);
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-	      df_uses_record (dflow, &regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
-			      DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+	      bitmap_set_bit (artificial_uses_at_bottom, HARD_FRAME_POINTER_REGNUM);
 #endif
 	    }
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
 	  if (fixed_regs[ARG_POINTER_REGNUM])
-	    df_uses_record (dflow, &regno_reg_rtx[ARG_POINTER_REGNUM],
-			    DF_REF_REG_USE, bb, NULL, 
-			    DF_REF_ARTIFICIAL);
+	    bitmap_set_bit (artificial_uses_at_bottom, ARG_POINTER_REGNUM);
 #endif
 	}
     }
 
-  if ((df->flags & DF_HARD_REGS) 
+  if ((dflow->flags & DF_HARD_REGS) 
       && bb->index >= NUM_FIXED_BLOCKS)
     {
       /* Before reload, there are a few registers that must be forced
 	 live everywhere -- which might not already be the case for
 	 blocks within infinite loops.  */
-      if (! reload_completed)
+      if (!reload_completed)
 	{
 	  
 	  /* Any reference to any pseudo before reload is a potential
 	     reference of the frame pointer.  */
-	  df_uses_record (dflow, &regno_reg_rtx[FRAME_POINTER_REGNUM],
-			  DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+	  bitmap_set_bit (artificial_uses_at_bottom, FRAME_POINTER_REGNUM);
 	  
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
 	  /* Pseudos with argument area equivalences may require
 	     reloading via the argument pointer.  */
 	  if (fixed_regs[ARG_POINTER_REGNUM])
-	    df_uses_record (dflow, &regno_reg_rtx[ARG_POINTER_REGNUM],
-			    DF_REF_REG_USE, bb, NULL, 
-			    DF_REF_ARTIFICIAL);
+	    bitmap_set_bit (artificial_uses_at_bottom, ARG_POINTER_REGNUM);
 #endif
 	  
 	  /* Any constant, or pseudo with constant equivalences, may
 	     require reloading from memory using the pic register.  */
 	  if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
 	      && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
-	    df_uses_record (dflow, &regno_reg_rtx[PIC_OFFSET_TABLE_REGNUM],
-			    DF_REF_REG_USE, bb, NULL, 
-			    DF_REF_ARTIFICIAL);
+	    bitmap_set_bit (artificial_uses_at_bottom, PIC_OFFSET_TABLE_REGNUM);
 	}
       /* The all-important stack pointer must always be live.  */
-      df_uses_record (dflow, &regno_reg_rtx[STACK_POINTER_REGNUM],
-		      DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+      bitmap_set_bit (artificial_uses_at_bottom, STACK_POINTER_REGNUM);
+    }
+
+  if (dflow->flags & DF_HARD_REGS)
+    {
+      bitmap_iterator bi;
+      unsigned int regno;
+
+      EXECUTE_IF_SET_IN_BITMAP (artificial_uses_at_bottom, 0, regno, bi)
+	{
+	  df_uses_record (dflow, &regno_reg_rtx[regno],
+			  DF_REF_REG_USE, bb, NULL, DF_REF_ARTIFICIAL);
+	}
+
+      BITMAP_FREE (artificial_uses_at_bottom);
     }
 }
 
@@ -1716,16 +1812,16 @@ df_mark_reg (rtx reg, void *vset)
    entry to the function.  */
 
 static void
-df_record_entry_block_defs (struct dataflow * dflow)
+df_record_entry_block_defs (struct dataflow *dflow)
 {
   unsigned int i; 
   bitmap_iterator bi;
   rtx r;
-  struct df * df = dflow->df;
+  struct df *df = dflow->df;
 
   bitmap_clear (df->entry_block_defs);
 
-  if (! (df->flags & DF_HARD_REGS))
+  if (!(dflow->flags & DF_HARD_REGS))
     return;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -1750,6 +1846,9 @@ df_record_entry_block_defs (struct dataf
     }
   else
     {
+      /* The always important stack pointer.  */
+      bitmap_set_bit (df->entry_block_defs, STACK_POINTER_REGNUM);
+
 #ifdef INCOMING_RETURN_ADDR_RTX
       if (REG_P (INCOMING_RETURN_ADDR_RTX))
 	bitmap_set_bit (df->entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));
@@ -1771,13 +1870,21 @@ df_record_entry_block_defs (struct dataf
 	bitmap_set_bit (df->entry_block_defs, REGNO (r));
     }
 
-  /* These registers are live everywhere.  */
-  if (!reload_completed)
+  if ((!reload_completed) || frame_pointer_needed)
     {
       /* Any reference to any pseudo before reload is a potential
 	 reference of the frame pointer.  */
       bitmap_set_bit (df->entry_block_defs, FRAME_POINTER_REGNUM);
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+      /* If they are different, also mark the hard frame pointer as live.  */
+      if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
+	bitmap_set_bit (df->entry_block_defs, HARD_FRAME_POINTER_REGNUM);
+#endif
+    }
 
+  /* These registers are live everywhere.  */
+  if (!reload_completed)
+    {
 #ifdef EH_USES
       /* The ia-64, the only machine that uses this, does not define these 
 	 until after reload.  */
@@ -1826,15 +1933,15 @@ df_record_exit_block_uses (struct datafl
 
   bitmap_clear (df->exit_block_uses);
   
-  if (! (df->flags & DF_HARD_REGS))
+  if (!(dflow->flags & DF_HARD_REGS))
     return;
 
   /* If exiting needs the right stack value, consider the stack
      pointer live at the end of the function.  */
   if ((HAVE_epilogue && epilogue_completed)
-      || ! EXIT_IGNORE_STACK
-      || (! FRAME_POINTER_REQUIRED
-	  && ! current_function_calls_alloca
+      || !EXIT_IGNORE_STACK
+      || (!FRAME_POINTER_REQUIRED
+	  && !current_function_calls_alloca
 	  && flag_omit_frame_pointer)
       || current_function_sp_is_unchanging)
     {
@@ -1845,12 +1952,12 @@ df_record_exit_block_uses (struct datafl
      If we end up eliminating it, it will be removed from the live
      list of each basic block by reload.  */
   
-  if (! reload_completed || frame_pointer_needed)
+  if ((!reload_completed) || frame_pointer_needed)
     {
       bitmap_set_bit (df->exit_block_uses, FRAME_POINTER_REGNUM);
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
       /* If they are different, also mark the hard frame pointer as live.  */
-      if (! LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
+      if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
 	bitmap_set_bit (df->exit_block_uses, HARD_FRAME_POINTER_REGNUM);
 #endif
     }
@@ -1875,8 +1982,8 @@ df_record_exit_block_uses (struct datafl
     {
       /* Mark all call-saved registers that we actually used.  */
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-	if (regs_ever_live[i] && ! LOCAL_REGNO (i)
-	    && ! TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
+	if (regs_ever_live[i] && !LOCAL_REGNO (i)
+	    && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
 	  bitmap_set_bit (df->exit_block_uses, i);
     }
   
@@ -1893,7 +2000,7 @@ df_record_exit_block_uses (struct datafl
 #endif
 
 #ifdef EH_RETURN_STACKADJ_RTX
-  if ((! HAVE_epilogue || ! epilogue_completed)
+  if ((!HAVE_epilogue || ! epilogue_completed)
       && current_function_calls_eh_return)
     {
       rtx tmp = EH_RETURN_STACKADJ_RTX;
@@ -1903,7 +2010,7 @@ df_record_exit_block_uses (struct datafl
 #endif
 
 #ifdef EH_RETURN_HANDLER_RTX
-  if ((! HAVE_epilogue || ! epilogue_completed)
+  if ((!HAVE_epilogue || ! epilogue_completed)
       && current_function_calls_eh_return)
     {
       rtx tmp = EH_RETURN_HANDLER_RTX;
@@ -1915,7 +2022,7 @@ df_record_exit_block_uses (struct datafl
   /* Mark function return value.  */
   diddle_return_value (df_mark_reg, (void*) df->exit_block_uses);
 
-  if (df->flags & DF_HARD_REGS)
+  if (dflow->flags & DF_HARD_REGS)
     EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, 0, i, bi)
       df_uses_record (dflow, &regno_reg_rtx[i], 
   		      DF_REF_REG_USE, EXIT_BLOCK_PTR, NULL,
Index: df-core.c
===================================================================
--- df-core.c	(revision 113909)
+++ df-core.c	(working copy)
@@ -45,7 +45,7 @@ Here is an example of using the dataflow
 
       df = df_init (init_flags);
       
-      df_add_problem (df, problem);
+      df_add_problem (df, problem, flags);
 
       df_set_blocks (df, blocks);
 
@@ -63,21 +63,20 @@ DF_INIT simply creates a poor man's obje
 passed to all the dataflow routines.  df_finish destroys this object
 and frees up any allocated memory.
 
-There are two flags that can be passed to df_init:
-
-DF_NO_SCAN means that no scanning of the rtl code is performed.  This
-is used if the problem instance is to do it's own scanning.
+There are three flags that can be passed to df_init, each of these
+flags controls the scanning of the rtl:
 
 DF_HARD_REGS means that the scanning is to build information about
 both pseudo registers and hardware registers.  Without this
 information, the problems will be solved only on pseudo registers.
-
+DF_EQUIV_NOTES marks the uses present in EQUIV/EQUAL notes.
+DF_SUBREGS return subregs rather than the inner reg.
 
 
 DF_ADD_PROBLEM adds a problem, defined by an instance to struct
 df_problem, to the set of problems solved in this instance of df.  All
 calls to add a problem for a given instance of df must occur before
-the first call to DF_RESCAN_BLOCKS or DF_ANALYZE.
+the first call to DF_RESCAN_BLOCKS, DF_SET_BLOCKS or DF_ANALYZE.
 
 For all of the problems defined in df-problems.c, there are
 convenience functions named DF_*_ADD_PROBLEM.
@@ -297,7 +296,7 @@ are write-only operations.  
 static struct df *ddf = NULL;
 struct df *shared_df = NULL;
 
-static void * df_get_bb_info (struct dataflow *, unsigned int);
+static void *df_get_bb_info (struct dataflow *, unsigned int);
 static void df_set_bb_info (struct dataflow *, unsigned int, void *);
 /*----------------------------------------------------------------------------
   Functions to create, destroy and manipulate an instance of df.
@@ -311,14 +310,13 @@ struct df *
 df_init (int flags)
 {
   struct df *df = XCNEW (struct df);
-  df->flags = flags;
 
   /* This is executed once per compilation to initialize platform
      specific data structures. */
   df_hard_reg_init ();
   
   /* All df instance must define the scanning problem.  */
-  df_scan_add_problem (df);
+  df_scan_add_problem (df, flags);
   ddf = df;
   return df;
 }
@@ -326,13 +324,13 @@ df_init (int flags)
 /* Add PROBLEM to the DF instance.  */
 
 struct dataflow *
-df_add_problem (struct df *df, struct df_problem *problem)
+df_add_problem (struct df *df, struct df_problem *problem, int flags)
 {
   struct dataflow *dflow;
 
   /* First try to add the dependent problem. */
-  if (problem->dependent_problem)
-    df_add_problem (df, problem->dependent_problem);
+  if (problem->dependent_problem_fun)
+    (problem->dependent_problem_fun) (df, 0);
 
   /* Check to see if this problem has already been defined.  If it
      has, just return that instance, if not, add it to the end of the
@@ -343,6 +341,7 @@ df_add_problem (struct df *df, struct df
 
   /* Make a new one and add it to the end.  */
   dflow = XCNEW (struct dataflow);
+  dflow->flags = flags;
   dflow->df = df;
   dflow->problem = problem;
   df->problems_in_order[df->num_problems_defined++] = dflow;
@@ -352,6 +351,36 @@ df_add_problem (struct df *df, struct df
 }
 
 
+/* Set the MASK flags in the DFLOW problem.  The old flags are
+   returned.  If a flag is not allowed to be changed this will fail if
+   checking is enabled.  */
+int 
+df_set_flags (struct dataflow *dflow, int mask)
+{
+  int old_flags = dflow->flags;
+
+  gcc_assert (!(mask & (~dflow->problem->changeable_flags)));
+
+  dflow->flags |= mask;
+
+  return old_flags;
+}
+
+/* Clear the MASK flags in the DFLOW problem.  The old flags are
+   returned.  If a flag is not allowed to be changed this will fail if
+   checking is enabled.  */
+int 
+df_clear_flags (struct dataflow *dflow, int mask)
+{
+  int old_flags = dflow->flags;
+
+  gcc_assert (!(mask & (~dflow->problem->changeable_flags)));
+
+  dflow->flags &= !mask;
+
+  return old_flags;
+}
+
 /* Set the blocks that are to be considered for analysis.  If this is
    not called or is called with null, the entire function in
    analyzed.  */
@@ -435,6 +464,26 @@ df_set_blocks (struct df *df, bitmap blo
 }
 
 
+/* Free all of the per basic block dataflow from all of the problems.
+   This is typically called before a basic block is deleted and the
+   problem will be reanalyzed.  */
+
+void
+df_delete_basic_block (struct df *df, int bb_index)
+{
+  basic_block bb = BASIC_BLOCK (bb_index);
+  int i;
+  
+  for (i = 0; i < df->num_problems_defined; i++)
+    {
+      struct dataflow *dflow = df->problems_in_order[i];
+      if (dflow->problem->free_bb_fun)
+	dflow->problem->free_bb_fun 
+	  (dflow, bb, df_get_bb_info (dflow, bb_index)); 
+    }
+}
+
+
 /* Free all the dataflow info and the DF structure.  This should be
    called from the df_finish macro which also NULLs the parm.  */
 
@@ -594,6 +643,8 @@ df_iterative_dataflow (struct dataflow *
   sbitmap_zero (pending);
   sbitmap_zero (considered);
 
+  gcc_assert (dataflow->problem->dir);
+
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_consider, 0, idx, bi)
     {
       SET_BIT (considered, idx);
@@ -696,7 +747,7 @@ df_prune_to_subcfg (int list[], unsigned
    small fixup     fringe                sub               sub
 */
 
-static void
+void
 df_analyze_problem (struct dataflow *dflow, 
 		    bitmap blocks_to_consider, 
 		    bitmap blocks_to_init,
@@ -705,7 +756,7 @@ df_analyze_problem (struct dataflow *dfl
 {
   /* (Re)Allocate the datastructures necessary to solve the problem.  */ 
   if (dflow->problem->alloc_fun)
-    dflow->problem->alloc_fun (dflow, blocks_to_scan);
+    dflow->problem->alloc_fun (dflow, blocks_to_scan, blocks_to_init);
 
   /* Set up the problem and compute the local information.  This
      function is passed both the blocks_to_consider and the
@@ -1066,7 +1117,7 @@ df_dump (struct df *df, FILE *file)
 {
   int i;
 
-  if (! df || ! file)
+  if (!df || !file)
     return;
 
   fprintf (file, "\n\n%s\n", current_function_name ());
@@ -1082,8 +1133,7 @@ df_dump (struct df *df, FILE *file)
 
 
 void
-df_refs_chain_dump (struct df *df, struct df_ref *ref, 
-		   bool follow_chain, FILE *file)
+df_refs_chain_dump (struct df_ref *ref, bool follow_chain, FILE *file)
 {
   fprintf (file, "{ ");
   while (ref)
@@ -1093,7 +1143,7 @@ df_refs_chain_dump (struct df *df, struc
 	       DF_REF_ID (ref),
 	       DF_REF_REGNO (ref));
       if (follow_chain)
-	df_chain_dump (df, DF_REF_CHAIN (ref), file);
+	df_chain_dump (DF_REF_CHAIN (ref), file);
       ref = ref->next_ref;
     }
   fprintf (file, "}");
@@ -1118,13 +1168,32 @@ df_regs_chain_dump (struct df *df ATTRIB
 }
 
 
-void
-df_insn_debug (struct df *df, rtx insn, bool follow_chain, FILE *file)
+static void
+df_mws_dump (struct df_mw_hardreg *mws, FILE *file)
 {
-  unsigned int uid;
-  int bbi;
+  while (mws)
+    {
+      struct df_link *regs = mws->regs;
+      fprintf (file, "%c%d(", 
+	       (mws->type == DF_REF_REG_DEF) ? 'd' : 'u',
+	       DF_REF_REGNO (regs->ref));
+      while (regs)
+	{
+	  fprintf (file, "%d ", DF_REF_REGNO (regs->ref));
+	  regs = regs->next;
+	}
 
-  uid = INSN_UID (insn);
+      fprintf (file, ") "); 
+      mws = mws->next;
+    }
+}
+
+
+static void 
+df_insn_uid_debug (struct df *df, unsigned int uid, 
+		   bool follow_chain, FILE *file)
+{
+  int bbi;
 
   if (DF_INSN_UID_DEFS (df, uid))
     bbi = DF_REF_BBNO (DF_INSN_UID_DEFS (df, uid));
@@ -1133,15 +1202,36 @@ df_insn_debug (struct df *df, rtx insn, 
   else
     bbi = -1;
 
-  fprintf (file, "insn %d bb %d luid %d defs ",
-	   uid, bbi, DF_INSN_LUID (df, insn));
+  fprintf (file, "insn %d bb %d luid %d",
+	   uid, bbi, DF_INSN_UID_LUID (df, uid));
 
-  df_refs_chain_dump (df, DF_INSN_UID_DEFS (df, uid), follow_chain, file);
-  fprintf (file, " defs ");
-  df_refs_chain_dump (df, DF_INSN_UID_USES (df, uid), follow_chain, file);
+  if (DF_INSN_UID_DEFS (df, uid))
+    {
+      fprintf (file, " defs ");
+      df_refs_chain_dump (DF_INSN_UID_DEFS (df, uid), follow_chain, file);
+    }
+
+  if (DF_INSN_UID_USES (df, uid))
+    {
+      fprintf (file, " uses ");
+      df_refs_chain_dump (DF_INSN_UID_USES (df, uid), follow_chain, file);
+    }
+
+  if (DF_INSN_UID_MWS (df, uid))
+    {
+      fprintf (file, " mws ");
+      df_mws_dump (DF_INSN_UID_MWS (df, uid), file);
+    }
   fprintf (file, "\n");
 }
 
+
+void
+df_insn_debug (struct df *df, rtx insn, bool follow_chain, FILE *file)
+{
+  df_insn_uid_debug (df, INSN_UID (insn), follow_chain, file);
+}
+
 void
 df_insn_debug_regno (struct df *df, rtx insn, FILE *file)
 {
@@ -1177,17 +1267,17 @@ df_regno_debug (struct df *df, unsigned 
 
 
 void
-df_ref_debug (struct df *df, struct df_ref *ref, FILE *file)
+df_ref_debug (struct df_ref *ref, FILE *file)
 {
   fprintf (file, "%c%d ",
 	   DF_REF_REG_DEF_P (ref) ? 'd' : 'u',
 	   DF_REF_ID (ref));
-  fprintf (file, "reg %d bb %d luid %d insn %d chain ",
+  fprintf (file, "reg %d bb %d insn %d flag %x chain ",
 	   DF_REF_REGNO (ref),
 	   DF_REF_BBNO (ref),
-	   DF_REF_INSN (ref) ? DF_INSN_LUID (df, DF_REF_INSN (ref)) : -1,
-	   DF_REF_INSN (ref) ? INSN_UID (DF_REF_INSN (ref)) : -1);
-  df_chain_dump (df, DF_REF_CHAIN (ref), file);
+	   DF_REF_INSN (ref) ? INSN_UID (DF_REF_INSN (ref)) : -1,
+	   DF_REF_FLAGS (ref));
+  df_chain_dump (DF_REF_CHAIN (ref), file);
   fprintf (file, "\n");
 }
 
@@ -1218,27 +1308,27 @@ debug_df_regno (unsigned int regno)
 void
 debug_df_ref (struct df_ref *ref)
 {
-  df_ref_debug (ddf, ref, stderr);
+  df_ref_debug (ref, stderr);
 }
 
 
 void
 debug_df_defno (unsigned int defno)
 {
-  df_ref_debug (ddf, DF_DEFS_GET (ddf, defno), stderr);
+  df_ref_debug (DF_DEFS_GET (ddf, defno), stderr);
 }
 
 
 void
 debug_df_useno (unsigned int defno)
 {
-  df_ref_debug (ddf, DF_USES_GET (ddf, defno), stderr);
+  df_ref_debug (DF_USES_GET (ddf, defno), stderr);
 }
 
 
 void
 debug_df_chain (struct df_link *link)
 {
-  df_chain_dump (ddf, link, stderr);
+  df_chain_dump (link, stderr);
   fputc ('\n', stderr);
 }
Index: df.h
===================================================================
--- df.h	(revision 113909)
+++ df.h	(working copy)
@@ -34,6 +34,7 @@ Software Foundation, 51 Franklin Street,
 struct dataflow;
 struct df;
 struct df_problem;
+struct df_link;
 
 /* Data flow problems.  All problems must have a unique here.  */ 
 /* Scanning is not really a dataflow problem, but it is useful to have
@@ -49,10 +50,6 @@ struct df_problem;
 #define DF_RI    7      /* Register Info. */
 #define DF_LAST_PROBLEM_PLUS1 (DF_RI + 1)
 
-/* Flags that control the building of chains.  */
-#define DF_DU_CHAIN   1    /* Build DU chains.  */  
-#define DF_UD_CHAIN   2    /* Build UD chains.  */
-
 
 /* Dataflow direction.  */
 enum df_flow_dir
@@ -62,10 +59,72 @@ enum df_flow_dir
     DF_BACKWARD
   };
 
+
+/* The first of these is a set of a register.  The remaining three are
+   all uses of a register (the mem_load and mem_store relate to how
+   the register as an addressing operand).  */
+enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
+		  DF_REF_REG_MEM_STORE};
+
+#define DF_REF_TYPE_NAMES {"def", "use", "mem load", "mem store"}
+
+enum df_ref_flags
+  {
+    /* Read-modify-write refs generate both a use and a def and
+       these are marked with this flag to show that they are not
+       independent.  */
+    DF_REF_READ_WRITE = 1,
+
+    /* This flag is set, if we stripped the subreg from the reference.
+       In this case we must make conservative guesses, at what the
+       outer mode was.  */
+    DF_REF_STRIPPED = 2,
+    
+    /* If this flag is set, this is not a real definition/use, but an
+       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
+       bottom of the block.  This is never set for regular refs.  */
+    DF_REF_AT_TOP = 8,
+
+    /* This flag is set if the use is inside a REG_EQUAL note.  */
+    DF_REF_IN_NOTE = 16,
+
+    /* This flag is set if this ref, generally a def, may clobber the
+       referenced register.  This is generally only set for hard
+       registers that cross a call site.  With better information
+       about calls, some of these could be changed in the future to
+       DF_REF_MUST_CLOBBER.  */
+    DF_REF_MAY_CLOBBER = 32,
+
+    /* This flag is set if this ref, generally a def, is a real
+       clobber. This is not currently set for registers live across a
+       call because that clobbering may or may not happen.  
+
+       Most of the uses of this are with sets that have a
+       GET_CODE(..)==CLOBBER.  Note that this is set even if the
+       clobber is to a subreg.  So in order to tell if the clobber
+       wipes out the entire register, it is necessary to also check
+       the DF_REF_PARTIAL flag.  */
+    DF_REF_MUST_CLOBBER = 64,
+
+    /* This bit is true if this ref is part of a multiword hardreg.  */
+    DF_REF_MW_HARDREG = 128,
+
+    /* This flag is set if this ref is a partial use or def of the
+       associated register.  */
+    DF_REF_PARTIAL = 256
+  };
+
+
 /* Function prototypes added to df_problem instance.  */
 
 /* Allocate the problem specific data.  */
-typedef void (*df_alloc_function) (struct dataflow *, bitmap);
+typedef void (*df_alloc_function) (struct dataflow *, bitmap, bitmap);
 
 /* This function is called if the problem has global data that needs
    to be cleared when ever the set of blocks changes.  The bitmap
@@ -107,6 +166,10 @@ typedef void (*df_free_function) (struct
 /* Function to dump results to FILE.  */
 typedef void (*df_dump_problem_function) (struct dataflow *, FILE *);
 
+/* Function to add problem a dataflow problem that must be solved
+   before this problem can be solved.  */
+typedef struct dataflow * (*df_dependent_problem_function) (struct df *, int);
+
 /* The static description of a dataflow problem to solve.  See above
    typedefs for doc for the function fields.  */
 
@@ -127,10 +190,10 @@ struct df_problem {
   df_finalizer_function finalize_fun;
   df_free_function free_fun;
   df_dump_problem_function dump_fun;
+  df_dependent_problem_function dependent_problem_fun;
 
-  /* A dataflow problem that must be solved before this problem can be
-     solved.  */
-  struct df_problem *dependent_problem;
+  /* Flags can be changed after analysis starts.  */
+  int changeable_flags;
 };
 
 
@@ -151,6 +214,20 @@ struct dataflow
   /* The pool to allocate the block_info from. */
   alloc_pool block_pool;                
 
+  /* Problem specific control infomation.  */
+
+  /* Scanning flags.  */
+#define DF_HARD_REGS	     1	/* Mark hard registers.  */
+#define DF_EQUIV_NOTES	     2	/* Mark uses present in EQUIV/EQUAL notes.  */
+#define DF_SUBREGS	     4	/* Return subregs rather than the inner reg.  */
+  /* Flags that control the building of chains.  */
+#define DF_DU_CHAIN          1    /* Build DU chains.  */  
+#define DF_UD_CHAIN          2    /* Build UD chains.  */
+  /* Flag to control the building of register info.  */
+#define DF_RI_LIFE           1    /* Build register info.  */
+
+  int flags;
+
   /* Other problem specific data that is not on a per basic block
      basis.  The structure is generally defined privately for the
      problem.  The exception being the scanning problem where it is
@@ -158,17 +235,35 @@ struct dataflow
   void *problem_data;                  
 };
 
+
+/* The set of multiword hardregs used as operands to this
+   instruction. These are factored into individual uses and defs but
+   the aggregate is still needed to service the REG_DEAD and
+   REG_UNUSED notes.  */
+struct df_mw_hardreg
+{
+  rtx mw_reg;                   /* The multiword hardreg.  */ 
+  enum df_ref_type type;        /* Used to see if the ref is read or write.  */
+  enum df_ref_flags flags;	/* Various flags.  */
+  struct df_link *regs;         /* The individual regs that make up
+				   this hardreg.  */
+  struct df_mw_hardreg *next;   /* The next mw_hardreg in this insn.  */
+};
+ 
+
 /* One of these structures is allocated for every insn.  */
 struct df_insn_info
 {
   struct df_ref *defs;	        /* Head of insn-def chain.  */
   struct df_ref *uses;	        /* Head of insn-use chain.  */
+  struct df_mw_hardreg *mw_hardregs;   
   /* ???? The following luid field should be considered private so that
      we can change it on the fly to accommodate new insns?  */
   int luid;			/* Logical UID.  */
   bool contains_asm;            /* Contains an asm instruction.  */
 };
 
+
 /* Two of these structures are allocated for every pseudo reg, one for
    the uses and one for the defs.  */
 struct df_reg_info
@@ -178,48 +273,6 @@ struct df_reg_info
   unsigned int n_refs;          /* Number of refs or defs for this pseudo.  */
 };
 
-
-enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
-		  DF_REF_REG_MEM_STORE};
-
-#define DF_REF_TYPE_NAMES {"def", "use", "mem load", "mem store"}
-
-enum df_ref_flags
-  {
-    /* Read-modify-write refs generate both a use and a def and
-       these are marked with this flag to show that they are not
-       independent.  */
-    DF_REF_READ_WRITE = 1,
-
-    /* This flag is set, if we stripped the subreg from the reference.
-       In this case we must make conservative guesses, at what the
-       outer mode was.  */
-    DF_REF_STRIPPED = 2,
-    
-    /* If this flag is set, this is not a real definition/use, but an
-       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
-       bottom of the block.  This is never set for regular refs.  */
-    DF_REF_AT_TOP = 8,
-
-    /* This flag is set if the use is inside a REG_EQUAL note.  */
-    DF_REF_IN_NOTE = 16,
-
-    /* This flag is set if this ref is really a clobber, and not a def.  */
-    DF_REF_CLOBBER = 32,
-
-    /* True if ref is dead (i.e. the next ref is a def or clobber or
-       the end of the function.)  This is only valid the RI problem
-       has been set in this df instance.  */
-    DF_REF_DIES_AFTER_THIS_USE = 64
-  };
-
-
 /* Define a register reference structure.  One of these is allocated
    for every register reference (use or def).  Note some register
    references (e.g., post_inc, subreg) generate both a def and a use.  */
@@ -250,9 +303,9 @@ struct df_ref
   void *data;			/* The data assigned to it by user.  */
 };
 
-/* There are two kinds of links: */
-
-/* This is used for def-use or use-def chains.  */
+/* These links are used for two purposes:
+   1) def-use or use-def chains. 
+   2) Multiword hard registers that underly a single hardware register.  */
 struct df_link
 {
   struct df_ref *ref;
@@ -288,12 +341,6 @@ struct df_ref_info
 struct df
 {
 
-#define DF_HARD_REGS	     1	/* Mark hard registers.  */
-#define DF_EQUIV_NOTES	     2	/* Mark uses present in EQUIV/EQUAL notes.  */
-#define DF_SUBREGS	     4	/* Return subregs rather than the inner reg.  */
-
-  int flags;			/* Indicates what's recorded.  */
-
   /* The set of problems to be solved is stored in two arrays.  In
      PROBLEMS_IN_ORDER, the problems are stored in the order that they
      are solved.  This is an internally dense array that may have
@@ -379,7 +426,7 @@ struct df
 /* Macros to determine the reference type.  */
 
 #define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF)
-#define DF_REF_REG_USE_P(REF) ((REF) && ! DF_REF_REG_DEF_P (REF))
+#define DF_REF_REG_USE_P(REF) ((REF) && !DF_REF_REG_DEF_P (REF))
 #define DF_REF_REG_MEM_STORE_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_STORE)
 #define DF_REF_REG_MEM_LOAD_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_LOAD)
 #define DF_REF_REG_MEM_P(REF) (DF_REF_REG_MEM_STORE_P (REF) \
@@ -398,8 +445,10 @@ struct df
 #define DF_REG_SIZE(DF) ((DF)->def_info.regs_inited)
 #define DF_REG_DEF_GET(DF, REG) ((DF)->def_info.regs[(REG)])
 #define DF_REG_DEF_SET(DF, REG, VAL) ((DF)->def_info.regs[(REG)]=(VAL))
+#define DF_REG_DEF_COUNT(DF, REG) ((DF)->def_info.regs[(REG)]->n_refs)
 #define DF_REG_USE_GET(DF, REG) ((DF)->use_info.regs[(REG)])
 #define DF_REG_USE_SET(DF, REG, VAL) ((DF)->use_info.regs[(REG)]=(VAL))
+#define DF_REG_USE_COUNT(DF, REG) ((DF)->use_info.regs[(REG)]->n_refs)
 
 /* Macros to access the elements within the reg_info structure table.  */
 
@@ -422,27 +471,13 @@ struct df
 #define DF_INSN_UID_LUID(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->luid)
 #define DF_INSN_UID_DEFS(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->defs)
 #define DF_INSN_UID_USES(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->uses)
+#define DF_INSN_UID_MWS(DF, INSN) (DF_INSN_UID_GET(DF,INSN)->mw_hardregs)
 
 /* This is a bitmap copy of regs_invalidated_by_call so that we can
    easily add it into bitmaps, etc. */ 
 
 extern bitmap df_invalidated_by_call;
 
-/* Initialize ur_in and ur_out as if all hard registers were partially
-available.  */
-
-/* The way that registers are processed, especially hard registers,
-   changes as the compilation proceeds. These states are passed to
-   df_set_state to control this processing.  */
-
-#define DF_SCAN_INITIAL    1    /* Processing from beginning of rtl to
-				   global-alloc.  */
-#define DF_SCAN_GLOBAL     2    /* Processing before global
-				   allocation.  */
-#define DF_SCAN_POST_ALLOC 4    /* Processing after register
-				   allocation.  */
-extern int df_state;            /* Indicates where we are in the compilation.  */
-
 
 /* One of these structures is allocated for every basic block.  */
 struct df_scan_bb_info
@@ -513,9 +548,13 @@ struct df_urec_bb_info 
 /* Functions defined in df-core.c.  */
 
 extern struct df *df_init (int);
-extern struct dataflow *df_add_problem (struct df *, struct df_problem *);
+extern struct dataflow *df_add_problem (struct df *, struct df_problem *, int);
+extern int df_set_flags (struct dataflow *, int);
+extern int df_clear_flags (struct dataflow *, int);
 extern void df_set_blocks (struct df*, bitmap);
+extern void df_delete_basic_block (struct df *, int);
 extern void df_finish1 (struct df *);
+extern void df_analyze_problem (struct dataflow *, bitmap, bitmap, bitmap, int *, int, bool);
 extern void df_analyze (struct df *);
 extern void df_compact_blocks (struct df *);
 extern void df_bb_replace (struct df *, int, basic_block);
@@ -529,13 +568,12 @@ extern struct df_ref *df_find_use (struc
 extern bool df_reg_used (struct df *, rtx, rtx);
 extern void df_iterative_dataflow (struct dataflow *, bitmap, bitmap, int *, int, bool);
 extern void df_dump (struct df *, FILE *);
-extern void df_chain_dump (struct df *, struct df_link *, FILE *);
-extern void df_refs_chain_dump (struct df *, struct df_ref *, bool, FILE *);
+extern void df_refs_chain_dump (struct df_ref *, bool, FILE *);
 extern void df_regs_chain_dump (struct df *, struct df_ref *,  FILE *);
 extern void df_insn_debug (struct df *, rtx, bool, FILE *);
 extern void df_insn_debug_regno (struct df *, rtx, FILE *);
 extern void df_regno_debug (struct df *, unsigned int, FILE *);
-extern void df_ref_debug (struct df *, struct df_ref *, FILE *);
+extern void df_ref_debug (struct df_ref *, FILE *);
 extern void debug_df_insn (rtx);
 extern void debug_df_regno (unsigned int);
 extern void debug_df_reg (rtx);
@@ -549,34 +587,32 @@ extern struct df *shared_df; 
 
 /* Functions defined in df-problems.c. */
 
-extern struct dataflow *df_get_dependent_problem (struct dataflow *);
 extern struct df_link *df_chain_create (struct dataflow *, struct df_ref *, struct df_ref *);
 extern void df_chain_unlink (struct dataflow *, struct df_ref *, struct df_link *);
 extern void df_chain_copy (struct dataflow *, struct df_ref *, struct df_link *);
 extern bitmap df_get_live_in (struct df *, basic_block);
 extern bitmap df_get_live_out (struct df *, basic_block);
 extern void df_grow_bb_info (struct dataflow *);
-extern void df_chain_dump (struct df *, struct df_link *, FILE *);
+extern void df_chain_dump (struct df_link *, FILE *);
 extern void df_print_bb_index (basic_block bb, FILE *file);
-extern struct dataflow *df_ru_add_problem (struct df *);
+extern struct dataflow *df_ru_add_problem (struct df *, int);
 extern struct df_ru_bb_info *df_ru_get_bb_info (struct dataflow *, unsigned int);
-extern struct dataflow *df_rd_add_problem (struct df *);
+extern struct dataflow *df_rd_add_problem (struct df *, int);
 extern struct df_rd_bb_info *df_rd_get_bb_info (struct dataflow *, unsigned int);
-extern struct dataflow *df_lr_add_problem (struct df *);
+extern struct dataflow *df_lr_add_problem (struct df *, int);
 extern struct df_lr_bb_info *df_lr_get_bb_info (struct dataflow *, unsigned int);
-extern struct dataflow *df_ur_add_problem (struct df *);
+extern struct dataflow *df_ur_add_problem (struct df *, int);
 extern struct df_ur_bb_info *df_ur_get_bb_info (struct dataflow *, unsigned int);
-extern struct dataflow *df_urec_add_problem (struct df *);
+extern struct dataflow *df_urec_add_problem (struct df *, int);
 extern struct df_urec_bb_info *df_urec_get_bb_info (struct dataflow *, unsigned int);
-extern struct dataflow *df_chain_add_problem (struct df *, int flags);
-extern struct dataflow *df_ri_add_problem (struct df *);
-extern int df_reg_lifetime (struct df *, rtx reg);
+extern struct dataflow *df_chain_add_problem (struct df *, int);
+extern struct dataflow *df_ri_add_problem (struct df *, int);
 
 
 /* Functions defined in df-scan.c.  */
 
 extern struct df_scan_bb_info *df_scan_get_bb_info (struct dataflow *, unsigned int);
-extern struct dataflow *df_scan_add_problem (struct df *);
+extern struct dataflow *df_scan_add_problem (struct df *, int);
 extern void df_rescan_blocks (struct df *, bitmap);
 extern struct df_ref *df_ref_create (struct df *, rtx, rtx *, rtx,basic_block,enum df_ref_type, enum df_ref_flags);
 extern struct df_ref *df_get_artificial_defs (struct df *, unsigned int);
@@ -588,7 +624,6 @@ extern void df_insn_refs_delete (struct 
 extern void df_bb_refs_delete (struct dataflow *, int);
 extern void df_refs_delete (struct dataflow *, bitmap);
 extern void df_reorganize_refs (struct df_ref_info *);
-extern void df_set_state (int);
 extern void df_hard_reg_init (void);
 extern bool df_read_modify_subreg_p (rtx);
 
Index: df-problems.c
===================================================================
--- df-problems.c	(revision 113909)
+++ df-problems.c	(working copy)
@@ -43,30 +43,23 @@ Software Foundation, 51 Franklin Street,
 #include "timevar.h"
 #include "df.h"
 #include "vecprim.h"
+#include "except.h"
+
+#if 0
+#define REG_DEAD_DEBUGGING
+#endif
 
 #define DF_SPARSE_THRESHOLD 32
 
 static bitmap seen_in_block = NULL;
 static bitmap seen_in_insn = NULL;
+static void df_ri_dump (struct dataflow *, FILE *);
 
 
 /*----------------------------------------------------------------------------
    Public functions access functions for the dataflow problems.
 ----------------------------------------------------------------------------*/
 
-/* Get the instance of the problem that DFLOW is dependent on.  */
-
-struct dataflow *
-df_get_dependent_problem (struct dataflow *dflow)
-{
-  struct df *df = dflow->df;
-  struct df_problem *dependent_problem = dflow->problem->dependent_problem;
-
-  gcc_assert (dependent_problem);
-  return df->problems_by_index[dependent_problem->id];
-}
-
-
 /* Create a du or ud chain from SRC to DST and link it into SRC.   */
 
 struct df_link *
@@ -207,7 +200,7 @@ df_grow_bb_info (struct dataflow *dflow)
 /* Dump a def-use or use-def chain for REF to FILE.  */
 
 void
-df_chain_dump (struct df *df ATTRIBUTE_UNUSED, struct df_link *link, FILE *file)
+df_chain_dump (struct df_link *link, FILE *file)
 {
   fprintf (file, "{ ");
   for (; link; link = link->next)
@@ -346,21 +339,23 @@ df_ru_free_bb_info (struct dataflow *dfl
    not touched unless the block is new.  */
 
 static void 
-df_ru_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_ru_alloc (struct dataflow *dflow, 
+	     bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+	     bitmap all_blocks)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int reg_size = max_reg_num ();
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_ru_block pool", 
 					   sizeof (struct df_ru_bb_info), 50);
 
   if (dflow->problem_data)
     {
       unsigned int i;
-      struct df_ru_problem_data *problem_data =
-	(struct df_ru_problem_data *) dflow->problem_data;
+      struct df_ru_problem_data *problem_data
+	= (struct df_ru_problem_data *) dflow->problem_data;
 
       for (i = 0; i < problem_data->use_sites_size; i++)
 	{
@@ -401,7 +396,7 @@ df_ru_alloc (struct dataflow *dflow, bit
      we have to process all of the blocks before doing the
      analysis.  */
 
-  EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
+  EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
       struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
       if (bb_info)
@@ -435,7 +430,10 @@ df_ru_bb_local_compute_process_def (stru
   struct df *df = dflow->df;
   while (def)
     {
-      if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
+      if ((top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
+	  /* If the def is to only part of the reg, it is as if it did
+	     not happen, since some of the bits may get thru.  */
+	  && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
 	{
 	  unsigned int regno = DF_REF_REGNO (def);
 	  unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
@@ -453,10 +451,10 @@ df_ru_bb_local_compute_process_def (stru
 		    }
 		  else
 		    {
-		      struct df_ru_problem_data * problem_data =
-			(struct df_ru_problem_data *)dflow->problem_data;
-		      bitmap uses = 
-			df_ref_bitmap (problem_data->use_sites, regno, 
+		      struct df_ru_problem_data * problem_data
+			= (struct df_ru_problem_data *)dflow->problem_data;
+		      bitmap uses 
+			= df_ref_bitmap (problem_data->use_sites, regno, 
 				       begin, n_uses);
 		      bitmap_ior_into (bb_info->kill, uses);
 		      bitmap_and_compl_into (bb_info->gen, uses);
@@ -519,18 +517,18 @@ df_ru_bb_local_compute (struct dataflow 
   FOR_BB_INSNS (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
 	continue;
 
       df_ru_bb_local_compute_process_def (dflow, bb_info, 
-					  DF_INSN_UID_GET (df, uid)->defs, 0);
+					  DF_INSN_UID_DEFS (df, uid), 0);
 
       /* The use processing must happen after the defs processing even
 	 though the uses logically happen first since the defs clear
 	 the gen set. Otherwise, a use for regno occuring in the same
 	 instruction as a def for regno would be cleared.  */ 
       df_ru_bb_local_compute_process_use (bb_info, 
-					  DF_INSN_UID_GET (df, uid)->uses, 0);
+					  DF_INSN_UID_USES (df, uid), 0);
 
       bitmap_ior_into (seen_in_block, seen_in_insn);
       bitmap_clear (seen_in_insn);
@@ -556,8 +554,8 @@ df_ru_local_compute (struct dataflow *df
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int regno;
-  struct df_ru_problem_data *problem_data =
-    (struct df_ru_problem_data *) dflow->problem_data;
+  struct df_ru_problem_data *problem_data
+    = (struct df_ru_problem_data *) dflow->problem_data;
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
@@ -616,8 +614,8 @@ df_ru_confluence_n (struct dataflow *dfl
 
   if (e->flags & EDGE_EH)
     {
-      struct df_ru_problem_data *problem_data =
-	(struct df_ru_problem_data *) dflow->problem_data;
+      struct df_ru_problem_data *problem_data
+	= (struct df_ru_problem_data *) dflow->problem_data;
       bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       struct df *df = dflow->df;
@@ -691,8 +689,8 @@ static void
 df_ru_free (struct dataflow *dflow)
 {
   unsigned int i;
-  struct df_ru_problem_data *problem_data =
-    (struct df_ru_problem_data *) dflow->problem_data;
+  struct df_ru_problem_data *problem_data
+    = (struct df_ru_problem_data *) dflow->problem_data;
 
   if (problem_data)
     {
@@ -737,10 +735,13 @@ df_ru_dump (struct dataflow *dflow, FILE
 {
   basic_block bb;
   struct df *df = dflow->df;
-  struct df_ru_problem_data *problem_data =
-    (struct df_ru_problem_data *) dflow->problem_data;
+  struct df_ru_problem_data *problem_data
+    = (struct df_ru_problem_data *) dflow->problem_data;
   unsigned int m = max_reg_num ();
   unsigned int regno;
+  
+  if (!dflow->block_info) 
+    return;
 
   fprintf (file, "Reaching uses:\n");
 
@@ -761,7 +762,7 @@ df_ru_dump (struct dataflow *dflow, FILE
       struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
 	continue;
       
       fprintf (file, "  in  \t");
@@ -793,7 +794,8 @@ static struct df_problem problem_RU =
   NULL,                       /* Finalize function.  */
   df_ru_free,                 /* Free all of the problem information.  */
   df_ru_dump,                 /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -803,9 +805,9 @@ static struct df_problem problem_RU =
    solution.  */
 
 struct dataflow *
-df_ru_add_problem (struct df *df)
+df_ru_add_problem (struct df *df, int flags)
 {
-  return df_add_problem (df, &problem_RU);
+  return df_add_problem (df, &problem_RU, flags);
 }
 
 
@@ -869,21 +871,23 @@ df_rd_free_bb_info (struct dataflow *dfl
    not touched unless the block is new.  */
 
 static void 
-df_rd_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_rd_alloc (struct dataflow *dflow, 
+	     bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+	     bitmap all_blocks)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int reg_size = max_reg_num ();
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_rd_block pool", 
 					   sizeof (struct df_rd_bb_info), 50);
 
   if (dflow->problem_data)
     {
       unsigned int i;
-      struct df_rd_problem_data *problem_data =
-	(struct df_rd_problem_data *) dflow->problem_data;
+      struct df_rd_problem_data *problem_data
+	= (struct df_rd_problem_data *) dflow->problem_data;
 
       for (i = 0; i < problem_data->def_sites_size; i++)
 	{
@@ -920,11 +924,11 @@ df_rd_alloc (struct dataflow *dflow, bit
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
+  /* Because of the clustering of all use sites for the same pseudo,
      we have to process all of the blocks before doing the
      analysis.  */
 
-  EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
+  EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
       if (bb_info)
@@ -970,7 +974,11 @@ df_rd_bb_local_compute_process_def (stru
 	    {
 	      /* The first def for regno in insn gets to knock out the
 		 defs from other instructions.  */
-	      if (!bitmap_bit_p (seen_in_insn, regno))
+	      if ((!bitmap_bit_p (seen_in_insn, regno))
+		  /* If the def is to only part of the reg, it does
+		     not kill the other defs that reach here.  */
+		  && (!((DF_REF_FLAGS (def) & DF_REF_PARTIAL)
+			 || (DF_REF_FLAGS (def) & DF_REF_MAY_CLOBBER))))
 		{
 		  if (n_defs > DF_SPARSE_THRESHOLD)
 		    {
@@ -979,11 +987,10 @@ df_rd_bb_local_compute_process_def (stru
 		    }
 		  else
 		    {
-		      struct df_rd_problem_data * problem_data =
-			(struct df_rd_problem_data *)dflow->problem_data;
-		      bitmap defs = 
-			df_ref_bitmap (problem_data->def_sites, regno, 
-				       begin, n_defs);
+		      struct df_rd_problem_data * problem_data
+			= (struct df_rd_problem_data *)dflow->problem_data;
+		      bitmap defs = df_ref_bitmap (problem_data->def_sites, 
+						   regno, begin, n_defs);
 		      bitmap_ior_into (bb_info->kill, defs);
 		      bitmap_and_compl_into (bb_info->gen, defs);
 		    }
@@ -992,7 +999,8 @@ df_rd_bb_local_compute_process_def (stru
 	      bitmap_set_bit (seen_in_insn, regno);
 	      /* All defs for regno in the instruction may be put into
 		 the gen set.  */
-	      if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+	      if (!(DF_REF_FLAGS (def) 
+		     & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
 		bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
 	    }
 	}
@@ -1020,11 +1028,11 @@ df_rd_bb_local_compute (struct dataflow 
     {
       unsigned int uid = INSN_UID (insn);
 
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
 	continue;
 
       df_rd_bb_local_compute_process_def (dflow, bb_info, 
-					  DF_INSN_UID_GET (df, uid)->defs, 0);
+					  DF_INSN_UID_DEFS (df, uid), 0);
 
       /* This complex dance with the two bitmaps is required because
 	 instructions can assign twice to the same pseudo.  This
@@ -1056,8 +1064,8 @@ df_rd_local_compute (struct dataflow *df
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int regno;
-  struct df_rd_problem_data *problem_data =
-    (struct df_rd_problem_data *) dflow->problem_data;
+  struct df_rd_problem_data *problem_data
+    = (struct df_rd_problem_data *) dflow->problem_data;
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
@@ -1117,8 +1125,8 @@ df_rd_confluence_n (struct dataflow *dfl
 
   if (e->flags & EDGE_EH)
     {
-      struct df_rd_problem_data *problem_data =
-	(struct df_rd_problem_data *) dflow->problem_data;
+      struct df_rd_problem_data *problem_data
+	= (struct df_rd_problem_data *) dflow->problem_data;
       bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       struct df *df = dflow->df;
@@ -1192,8 +1200,8 @@ static void
 df_rd_free (struct dataflow *dflow)
 {
   unsigned int i;
-  struct df_rd_problem_data *problem_data =
-    (struct df_rd_problem_data *) dflow->problem_data;
+  struct df_rd_problem_data *problem_data
+    = (struct df_rd_problem_data *) dflow->problem_data;
 
   if (problem_data)
     {
@@ -1238,11 +1246,14 @@ df_rd_dump (struct dataflow *dflow, FILE
 {
   struct df *df = dflow->df;
   basic_block bb;
-  struct df_rd_problem_data *problem_data =
-    (struct df_rd_problem_data *) dflow->problem_data;
+  struct df_rd_problem_data *problem_data
+    = (struct df_rd_problem_data *) dflow->problem_data;
   unsigned int m = max_reg_num ();
   unsigned int regno;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Reaching defs:\n\n");
 
   fprintf (file, "  sparse invalidated \t");
@@ -1262,7 +1273,7 @@ df_rd_dump (struct dataflow *dflow, FILE
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
 	continue;
       
       fprintf (file, "  in\t(%d)\n", (int) bitmap_count_bits (bb_info->in));
@@ -1294,7 +1305,8 @@ static struct df_problem problem_RD =
   NULL,                       /* Finalize function.  */
   df_rd_free,                 /* Free all of the problem information.  */
   df_rd_dump,                 /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -1304,9 +1316,9 @@ static struct df_problem problem_RD =
    solution.  */
 
 struct dataflow *
-df_rd_add_problem (struct df *df)
+df_rd_add_problem (struct df *df, int flags)
 {
-  return df_add_problem (df, &problem_RD);
+  return df_add_problem (df, &problem_RD, flags);
 }
 
 
@@ -1360,21 +1372,18 @@ df_lr_free_bb_info (struct dataflow *dfl
    not touched unless the block is new.  */
 
 static void 
-df_lr_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_lr_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
+	     bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_lr_block pool", 
 					   sizeof (struct df_lr_bb_info), 50);
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
-     we have to process all of the blocks before doing the
-     analysis.  */
-
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
@@ -1410,7 +1419,8 @@ df_lr_bb_local_compute (struct dataflow 
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+    if (((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+	&& (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
       {
 	unsigned int dregno = DF_REF_REGNO (def);
 	bitmap_set_bit (bb_info->def, dregno);
@@ -1427,12 +1437,12 @@ df_lr_bb_local_compute (struct dataflow 
     {
       unsigned int uid = INSN_UID (insn);
 
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
 	continue;	
 
       if (CALL_P (insn))
 	{
-	  for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+	  for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
 	    {
 	      unsigned int dregno = DF_REF_REGNO (def);
 	      
@@ -1443,15 +1453,19 @@ df_lr_bb_local_compute (struct dataflow 
 					      current_function_return_rtx,
 					      (rtx *)0)))
 		{
-		  /* Add def to set of defs in this BB.  */
-		  bitmap_set_bit (bb_info->def, dregno);
-		  bitmap_clear_bit (bb_info->use, dregno);
+		  /* If the def is to only part of the reg, it does
+		     not kill the other defs that reach here.  */
+		  if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+		    {
+		      bitmap_set_bit (bb_info->def, dregno);
+		      bitmap_clear_bit (bb_info->use, dregno);
+		    }
 		}
 	    }
 	}
       else
 	{
-	  for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+	  for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
 	    {
 	      unsigned int dregno = DF_REF_REGNO (def);
 	      
@@ -1459,25 +1473,30 @@ df_lr_bb_local_compute (struct dataflow 
 		  && dregno < FIRST_PSEUDO_REGISTER)
 		{
 		  unsigned int i;
-		  unsigned int end = 
-		    dregno + hard_regno_nregs[dregno][GET_MODE (DF_REF_REG (def))] - 1;
+		  unsigned int end = dregno 
+		    + hard_regno_nregs[dregno][GET_MODE (DF_REF_REG (def))] - 1;
 		  for (i = dregno; i <= end; ++i)
 		    regs_asm_clobbered[i] = 1;
 		}
-	      /* Add def to set of defs in this BB.  */
-	      bitmap_set_bit (bb_info->def, dregno);
-	      bitmap_clear_bit (bb_info->use, dregno);
+	      /* If the def is to only part of the reg, it does
+		     not kill the other defs that reach here.  */
+	      if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+		{
+		  bitmap_set_bit (bb_info->def, dregno);
+		  bitmap_clear_bit (bb_info->use, dregno);
+		}
 	    }
 	}
 
-      for (use = DF_INSN_UID_GET (df, uid)->uses; use; use = use->next_ref)
+      for (use = DF_INSN_UID_USES (df, uid); use; use = use->next_ref)
 	/* Add use to set of uses in this BB.  */
 	bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
     }
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+	&& (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
       {
 	unsigned int dregno = DF_REF_REGNO (def);
 	bitmap_set_bit (bb_info->def, dregno);
@@ -1493,6 +1512,7 @@ df_lr_bb_local_compute (struct dataflow 
 #endif
 }
 
+
 /* Compute local live register info for each basic block within BLOCKS.  */
 
 static void
@@ -1517,7 +1537,7 @@ df_lr_local_compute (struct dataflow *df
   /* Before reload, there are a few registers that must be forced
      live everywhere -- which might not already be the case for
      blocks within infinite loops.  */
-  if (! reload_completed)
+  if (!reload_completed)
     {
       /* Any reference to any pseudo before reload is a potential
 	 reference of the frame pointer.  */
@@ -1586,6 +1606,7 @@ df_lr_confluence_0 (struct dataflow *dfl
 
 
 /* Confluence function that ignores fake edges.  */
+
 static void
 df_lr_confluence_n (struct dataflow *dflow, edge e)
 {
@@ -1605,6 +1626,7 @@ df_lr_confluence_n (struct dataflow *dfl
 
 
 /* Transfer function.  */
+
 static bool
 df_lr_transfer_function (struct dataflow *dflow, int bb_index)
 {
@@ -1642,6 +1664,8 @@ df_lr_free (struct dataflow *dflow)
       dflow->block_info_size = 0;
       free (dflow->block_info);
     }
+
+  free (dflow->problem_data);
   free (dflow);
 }
 
@@ -1653,6 +1677,9 @@ df_lr_dump (struct dataflow *dflow, FILE
 {
   basic_block bb;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Live Registers:\n");
   FOR_ALL_BB (bb)
     {
@@ -1691,7 +1718,8 @@ static struct df_problem problem_LR =
   NULL,                       /* Finalize function.  */
   df_lr_free,                 /* Free all of the problem information.  */
   df_lr_dump,                 /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0
 };
 
 
@@ -1700,9 +1728,9 @@ static struct df_problem problem_LR =
    solution.  */
 
 struct dataflow *
-df_lr_add_problem (struct df *df)
+df_lr_add_problem (struct df *df, int flags)
 {
-  return df_add_problem (df, &problem_LR);
+  return df_add_problem (df, &problem_LR, flags);
 }
 
 
@@ -1756,21 +1784,18 @@ df_ur_free_bb_info (struct dataflow *dfl
    not touched unless the block is new.  */
 
 static void 
-df_ur_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_ur_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
+	     bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_ur_block pool", 
 					   sizeof (struct df_ur_bb_info), 100);
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
-     we have to process all of the blocks before doing the
-     analysis.  */
-
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
@@ -1823,16 +1848,23 @@ df_ur_bb_local_compute (struct dataflow 
       if (!INSN_P (insn))
 	continue;
 
-      for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+      for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
 	{
 	  unsigned int regno = DF_REF_REGNO (def);
-	      /* Only the last def counts.  */
+	  /* Only the last def counts.  */
 	  if (!bitmap_bit_p (seen_in_block, regno))
 	    {
 	      bitmap_set_bit (seen_in_insn, regno);
 	      
-	      if (DF_REF_FLAGS (def) & DF_REF_CLOBBER)
-		bitmap_set_bit (bb_info->kill, regno);
+	      if (DF_REF_FLAGS (def) 
+		  & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
+		{
+		  /* Only must clobbers for the entire reg destroy the
+		     value.  */
+		  if ((DF_REF_FLAGS (def) & DF_REF_MUST_CLOBBER)
+		      && (!DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+		    bitmap_set_bit (bb_info->kill, regno);
+		}
 	      else
 		bitmap_set_bit (bb_info->gen, regno);
 	    }
@@ -1927,7 +1959,7 @@ df_ur_local_finalize (struct dataflow *d
       bitmap_and_into (bb_info->out, tmp);
 #endif
     }
-  
+
   BITMAP_FREE (tmp);
 }
 
@@ -1998,6 +2030,9 @@ df_ur_dump (struct dataflow *dflow, FILE
 {
   basic_block bb;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Undefined regs:\n");
  
   FOR_ALL_BB (bb)
@@ -2005,7 +2040,7 @@ df_ur_dump (struct dataflow *dflow, FILE
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
 	continue;
       
       fprintf (file, "  in  \t");
@@ -2037,7 +2072,8 @@ static struct df_problem problem_UR =
   df_ur_local_finalize,       /* Finalize function.  */
   df_ur_free,                 /* Free all of the problem information.  */
   df_ur_dump,                 /* Debugging.  */
-  &problem_LR                 /* Dependent problem.  */
+  df_lr_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -2046,9 +2082,9 @@ static struct df_problem problem_UR =
    solution.  */
 
 struct dataflow *
-df_ur_add_problem (struct df *df)
+df_ur_add_problem (struct df *df, int flags)
 {
-  return df_add_problem (df, &problem_UR);
+  return df_add_problem (df, &problem_UR, flags);
 }
 
 
@@ -2116,14 +2152,16 @@ df_urec_free_bb_info (struct dataflow *d
    not touched unless the block is new.  */
 
 static void 
-df_urec_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_urec_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
+	       bitmap all_blocks ATTRIBUTE_UNUSED)
+
 {
   unsigned int bb_index;
   bitmap_iterator bi;
-  struct df_urec_problem_data *problem_data =
-    (struct df_urec_problem_data *) dflow->problem_data;
+  struct df_urec_problem_data *problem_data
+    = (struct df_urec_problem_data *) dflow->problem_data;
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_urec_block pool", 
 					   sizeof (struct df_urec_bb_info), 50);
 
@@ -2136,10 +2174,6 @@ df_urec_alloc (struct dataflow *dflow, b
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
-     we have to process all of the blocks before doing the
-     analysis.  */
-
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
@@ -2376,11 +2410,10 @@ df_urec_bb_local_compute (struct dataflo
       if (INSN_P (insn))
 	{
 	  note_stores (PATTERN (insn), df_urec_mark_reg_change, bb_info);
-	  if (df_state & (DF_SCAN_GLOBAL | DF_SCAN_POST_ALLOC) 
-	      && df_urec_check_earlyclobber (insn))
+	  if (df_urec_check_earlyclobber (insn))
 	    {
-	      struct df_urec_problem_data *problem_data =
-		(struct df_urec_problem_data *) dflow->problem_data;
+	      struct df_urec_problem_data *problem_data
+		= (struct df_urec_problem_data *) dflow->problem_data;
 	      problem_data->earlyclobbers_found = true;
 	      note_uses (&PATTERN (insn), 
 			 df_urec_mark_reg_use_for_earlyclobber_1, bb_info);
@@ -2410,8 +2443,8 @@ df_urec_local_compute (struct dataflow *
 #ifdef STACK_REGS
   int i;
   HARD_REG_SET zero, stack_hard_regs, used;
-  struct df_urec_problem_data *problem_data =
-    (struct df_urec_problem_data *) dflow->problem_data;
+  struct df_urec_problem_data *problem_data
+    = (struct df_urec_problem_data *) dflow->problem_data;
   
   /* Any register that MAY be allocated to a register stack (like the
      387) is treated poorly.  Each such register is marked as being
@@ -2479,8 +2512,8 @@ df_urec_local_finalize (struct dataflow 
   bitmap tmp = BITMAP_ALLOC (NULL);
   bitmap_iterator bi;
   unsigned int bb_index;
-  struct df_urec_problem_data *problem_data =
-    (struct df_urec_problem_data *) dflow->problem_data;
+  struct df_urec_problem_data *problem_data
+    = (struct df_urec_problem_data *) dflow->problem_data;
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
@@ -2597,6 +2630,9 @@ df_urec_dump (struct dataflow *dflow, FI
 {
   basic_block bb;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Undefined regs:\n");
  
   FOR_ALL_BB (bb)
@@ -2604,7 +2640,7 @@ df_urec_dump (struct dataflow *dflow, FI
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
 	continue;
       
       fprintf (file, "  in  \t");
@@ -2638,7 +2674,8 @@ static struct df_problem problem_UREC =
   df_urec_local_finalize,     /* Finalize function.  */
   df_urec_free,               /* Free all of the problem information.  */
   df_urec_dump,               /* Debugging.  */
-  &problem_LR                 /* Dependent problem.  */
+  df_lr_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -2647,9 +2684,9 @@ static struct df_problem problem_UREC =
    solution.  */
 
 struct dataflow *
-df_urec_add_problem (struct df *df)
+df_urec_add_problem (struct df *df, int flags)
 {
-  return df_add_problem (df, &problem_UREC);
+  return df_add_problem (df, &problem_UREC, flags);
 }
 
 
@@ -2665,22 +2702,16 @@ df_urec_add_problem (struct df *df)
    the reaching defs information (the dependent problem).
 ----------------------------------------------------------------------------*/
 
-struct df_chain_problem_data
-{
-  int flags;
-};
-
-
 /* Create def-use or use-def chains.  */
 
 static void  
 df_chain_alloc (struct dataflow *dflow, 
-		bitmap blocks_to_rescan ATTRIBUTE_UNUSED)
+		bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+		bitmap all_blocks ATTRIBUTE_UNUSED)
+
 {
   struct df *df = dflow->df;
   unsigned int i;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
 
   /* Wholesale destruction of the old chains.  */ 
   if (dflow->block_pool)
@@ -2689,7 +2720,7 @@ df_chain_alloc (struct dataflow *dflow, 
   dflow->block_pool = create_alloc_pool ("df_chain_chain_block pool", 
 					 sizeof (struct df_link), 100);
 
-  if (problem_data->flags & DF_DU_CHAIN)
+  if (dflow->flags & DF_DU_CHAIN)
     {
       if (!df->def_info.refs_organized)
 	df_reorganize_refs (&df->def_info);
@@ -2702,7 +2733,7 @@ df_chain_alloc (struct dataflow *dflow, 
 	}
     }
   
-  if (problem_data->flags & DF_UD_CHAIN)
+  if (dflow->flags & DF_UD_CHAIN)
     {
       if (!df->use_info.refs_organized)
 	df_reorganize_refs (&df->use_info);
@@ -2721,8 +2752,6 @@ static void 
 df_chain_insn_reset (struct dataflow *dflow, rtx insn)
 {
   struct df *df = dflow->df;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
   unsigned int uid = INSN_UID (insn);
   struct df_insn_info *insn_info = NULL;
   struct df_ref *ref;
@@ -2732,7 +2761,7 @@ df_chain_insn_reset (struct dataflow *df
 
   if (insn_info)
     {
-      if (problem_data->flags & DF_DU_CHAIN)
+      if (dflow->flags & DF_DU_CHAIN)
 	{
 	  ref = insn_info->defs;
 	  while (ref)
@@ -2742,7 +2771,7 @@ df_chain_insn_reset (struct dataflow *df
 	    }
 	}
 
-      if (problem_data->flags & DF_UD_CHAIN)
+      if (dflow->flags & DF_UD_CHAIN)
 	{
 	  ref = insn_info->uses;
 	  while (ref) 
@@ -2761,8 +2790,6 @@ static void 
 df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
 {
   struct df *df = dflow->df; 
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
   rtx insn;
   basic_block bb = BASIC_BLOCK (bb_index);
 
@@ -2780,7 +2807,7 @@ df_chain_bb_reset (struct dataflow *dflo
     }
   
   /* Get rid of any chains in artificial uses or defs.  */
-  if (problem_data->flags & DF_DU_CHAIN)
+  if (dflow->flags & DF_DU_CHAIN)
     {
       struct df_ref *def;
       def = df_get_artificial_defs (df, bb_index);
@@ -2791,7 +2818,7 @@ df_chain_bb_reset (struct dataflow *dflo
 	}
     }
 
-  if (problem_data->flags & DF_UD_CHAIN)
+  if (dflow->flags & DF_UD_CHAIN)
     {
       struct df_ref *use;
       use = df_get_artificial_uses (df, bb_index);
@@ -2827,7 +2854,6 @@ df_chain_reset (struct dataflow *dflow, 
 
 static void
 df_chain_create_bb_process_use (struct dataflow *dflow, 
-				struct df_chain_problem_data *problem_data,
 				bitmap local_rd,
 				struct df_ref *use,
 				enum df_ref_flags top_flag)
@@ -2855,9 +2881,9 @@ df_chain_create_bb_process_use (struct d
 		    break;
 		  
 		  def = DF_DEFS_GET (df, def_index);
-		  if (problem_data->flags & DF_DU_CHAIN)
+		  if (dflow->flags & DF_DU_CHAIN)
 		    df_chain_create (dflow, def, use);
-		  if (problem_data->flags & DF_UD_CHAIN)
+		  if (dflow->flags & DF_UD_CHAIN)
 		    df_chain_create (dflow, use, def);
 		}
 	    }
@@ -2881,8 +2907,6 @@ df_chain_create_bb (struct dataflow *dfl
   rtx insn;
   bitmap cpy = BITMAP_ALLOC (NULL);
   struct df *df = dflow->df;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
   struct df_ref *def;
 
   bitmap_copy (cpy, bb_info->in);
@@ -2893,7 +2917,7 @@ df_chain_create_bb (struct dataflow *dfl
 #ifdef EH_USES
   /* Create the chains for the artificial uses from the EH_USES at the
      beginning of the block.  */
-  df_chain_create_bb_process_use (dflow, problem_data, cpy,
+  df_chain_create_bb_process_use (dflow, cpy,
 				  df_get_artificial_uses (df, bb->index), 
 				  DF_REF_AT_TOP);
 #endif
@@ -2902,11 +2926,11 @@ df_chain_create_bb (struct dataflow *dfl
     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
       {
 	unsigned int dregno = DF_REF_REGNO (def);
-	bitmap_clear_range (cpy, 
-			    DF_REG_DEF_GET (df, dregno)->begin, 
-			    DF_REG_DEF_GET (df, dregno)->n_refs);
-	if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
-	  bitmap_set_bit (cpy, DF_REF_ID (def));
+	if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+	  bitmap_clear_range (cpy, 
+			      DF_REG_DEF_GET (df, dregno)->begin, 
+			      DF_REG_DEF_GET (df, dregno)->n_refs);
+	bitmap_set_bit (cpy, DF_REF_ID (def));
       }
   
   /* Process the regular instructions next.  */
@@ -2915,31 +2939,33 @@ df_chain_create_bb (struct dataflow *dfl
       struct df_ref *def;
       unsigned int uid = INSN_UID (insn);
 
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
 	continue;
 
       /* Now scan the uses and link them up with the defs that remain
 	 in the cpy vector.  */
       
-      df_chain_create_bb_process_use (dflow, problem_data, cpy,		     
-				     DF_INSN_UID_GET (df, uid)->uses, 0);
+      df_chain_create_bb_process_use (dflow, cpy,
+				     DF_INSN_UID_USES (df, uid), 0);
 
       /* Since we are going forwards, process the defs second.  This
          pass only changes the bits in cpy.  */
-      for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+      for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
 	{
 	  unsigned int dregno = DF_REF_REGNO (def);
-	  bitmap_clear_range (cpy, 
-			      DF_REG_DEF_GET (df, dregno)->begin, 
-			      DF_REG_DEF_GET (df, dregno)->n_refs);
-	  if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+	  if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+	    bitmap_clear_range (cpy, 
+				DF_REG_DEF_GET (df, dregno)->begin, 
+				DF_REG_DEF_GET (df, dregno)->n_refs);
+	  if (!(DF_REF_FLAGS (def) 
+		 & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
 	    bitmap_set_bit (cpy, DF_REF_ID (def));
 	}
     }
 
   /* Create the chains for the artificial uses of the hard registers
      at the end of the block.  */
-  df_chain_create_bb_process_use (dflow, problem_data, cpy,
+  df_chain_create_bb_process_use (dflow, cpy,
 				  df_get_artificial_uses (df, bb->index), 0);
 }
 
@@ -2967,7 +2993,6 @@ static void
 df_chain_free (struct dataflow *dflow)
 {
   free_alloc_pool (dflow->block_pool);
-  free (dflow->problem_data);
   free (dflow);
 }
 
@@ -2979,10 +3004,8 @@ df_chains_dump (struct dataflow *dflow, 
 {
   struct df *df = dflow->df;
   unsigned int j;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
 
-  if (problem_data->flags & DF_DU_CHAIN)
+  if (dflow->flags & DF_DU_CHAIN)
     {
       fprintf (file, "Def-use chains:\n");
       for (j = 0; j < df->def_info.bitmap_size; j++)
@@ -2999,13 +3022,13 @@ df_chains_dump (struct dataflow *dflow, 
 		       DF_REF_REGNO (def));
 	      if (def->flags & DF_REF_READ_WRITE)
 		fprintf (file, "read/write ");
-	      df_chain_dump (df, DF_REF_CHAIN (def), file);
+	      df_chain_dump (DF_REF_CHAIN (def), file);
 	      fprintf (file, "\n");
 	    }
 	}
     }
 
-  if (problem_data->flags & DF_UD_CHAIN)
+  if (dflow->flags & DF_UD_CHAIN)
     {
       fprintf (file, "Use-def chains:\n");
       for (j = 0; j < df->use_info.bitmap_size; j++)
@@ -3028,7 +3051,7 @@ df_chains_dump (struct dataflow *dflow, 
 		fprintf (file, "stripped ");
 	      if (use->flags & DF_REF_IN_NOTE)
 		fprintf (file, "note ");
-	      df_chain_dump (df, DF_REF_CHAIN (use), file);
+	      df_chain_dump (DF_REF_CHAIN (use), file);
 	      fprintf (file, "\n");
 	    }
 	}
@@ -3052,7 +3075,8 @@ static struct df_problem problem_CHAIN =
   df_chain_finalize,          /* Finalize function.  */
   df_chain_free,              /* Free all of the problem information.  */
   df_chains_dump,             /* Debugging.  */
-  &problem_RD                 /* Dependent problem.  */
+  df_rd_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -3063,104 +3087,560 @@ static struct df_problem problem_CHAIN =
 struct dataflow *
 df_chain_add_problem (struct df *df, int flags)
 {
-  struct df_chain_problem_data *problem_data =
-	XNEW (struct df_chain_problem_data);
-  struct dataflow *dflow = df_add_problem (df, &problem_CHAIN);
-
-  dflow->problem_data = problem_data;
-  problem_data->flags = flags;
-  
-  return dflow;
+  return df_add_problem (df, &problem_CHAIN, flags);
 }
 
 
 /*----------------------------------------------------------------------------
    REGISTER INFORMATION
 
-   Currently this consists of only lifetime information.  But the plan is
-   to enhance it so that it produces all of the register information needed
-   by the register allocators.
-----------------------------------------------------------------------------*/
-
+   Currently this consists of only lifetime information and reg_dead
+   and reg_unused.  
+   ----------------------------------------------------------------------------*/
 
-struct df_ri_problem_data
+#ifdef REG_DEAD_DEBUGGING
+static void 
+print_note (char *prefix, rtx insn, rtx note)
 {
-  int *lifetime;
-};
-
+  fprintf (stderr, "%s %d ", prefix, INSN_UID (insn));
+  print_rtl (stderr, note);
+  fprintf (stderr, "\n");
+}
+#endif
 
 /* Allocate the lifetime information.  */
 
 static void 
-df_ri_alloc (struct dataflow *dflow, bitmap blocks_to_rescan ATTRIBUTE_UNUSED)
+df_ri_alloc (struct dataflow *dflow, 
+	     bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+	     bitmap all_blocks ATTRIBUTE_UNUSED)
 {
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
+  int i;
+  struct df *df = dflow->df;
 
-  if (!dflow->problem_data)
+  if (dflow->flags & DF_RI_LIFE)
     {
-      struct df_ri_problem_data *problem_data =	XNEW (struct df_ri_problem_data);
-      dflow->problem_data = problem_data;
+      max_regno = max_reg_num ();
+      allocate_reg_info (max_regno, FALSE, FALSE);
+      
+      /* Reset all the data we'll collect.  */
+      for (i = 0; i < max_regno; i++)
+	{
+	  REG_N_SETS (i) = DF_REG_DEF_COUNT (df, i);
+	  REG_N_REFS (i) = DF_REG_USE_COUNT (df, i) + REG_N_SETS (i);
+	  REG_N_DEATHS (i) = 0;
+	  REG_N_CALLS_CROSSED (i) = 0;
+	  REG_N_THROWING_CALLS_CROSSED (i) = 0;
+	  REG_LIVE_LENGTH (i) = 0;
+	  REG_FREQ (i) = 0;
+	  REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
+	}
     }
+}
+
 
-  problem_data->lifetime = xrealloc (problem_data->lifetime, 
-				     max_reg_num () *sizeof (int));
-  memset (problem_data->lifetime, 0, max_reg_num () *sizeof (int));
+/* After reg-stack, the x86 floating point stack regs are difficult to
+   analyze because of all of the pushes, pops and rotations.  Thus, we
+   just leave the notes alone. */
+
+static inline bool 
+df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
+{
+#ifdef STACK_REGS
+  return (regstack_completed
+	  && IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG));
+#else
+  return false;
+#endif
 }
 
-/* Compute register info: lifetime, bb, and number of defs and uses
-   for basic block BB.  */
+
+/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN.  */
 
 static void
-df_ri_bb_compute (struct dataflow *dflow, unsigned int bb_index, bitmap live)
+df_kill_notes (rtx insn, int flags)
+{
+  rtx *pprev = &REG_NOTES (insn);
+  rtx link = *pprev;
+  
+  while (link)
+    {
+      switch (REG_NOTE_KIND (link))
+	{
+	case REG_DEAD:
+	  if (flags & DF_RI_LIFE)
+	    if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
+	      REG_N_DEATHS (REGNO (XEXP (link, 0)))++;
+
+	  /* Fallthru */
+	case REG_UNUSED:
+	  if (!df_ignore_stack_reg (REGNO (XEXP (link, 0))))
+	    {
+	      rtx next = XEXP (link, 1);
+#ifdef REG_DEAD_DEBUGGING
+	      print_note ("deleting: ", insn, link);
+#endif
+	      free_EXPR_LIST_node (link);
+	      *pprev = link = next;
+	    }
+	  break;
+	  
+	default:
+	  pprev = &XEXP (link, 1);
+	  link = *pprev;
+	  break;
+	}
+    }
+}
+
+
+/* Set the REG_UNUSED notes for the multiword hardreg defs in INSN
+   based on the bits in LIVE.  Do not generate notes for registers in
+   artificial uses.  DO_NOT_GEN is updated so that REG_DEAD notes are
+   not generated if the reg is both read and written by the
+   instruction.
+*/
+
+static void
+df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+			    bitmap live, bitmap do_not_gen, 
+			    bitmap artificial_uses, int flags)
+{
+  bool all_dead = true;
+  struct df_link *regs = mws->regs;
+  unsigned int regno = DF_REF_REGNO (regs->ref);
+  
+#ifdef REG_DEAD_DEBUGGING
+  fprintf (stderr, "mw unused looking at %d\n", DF_REF_REGNO (regs->ref));
+  df_ref_debug (regs->ref, stderr);
+#endif
+  while (regs)
+    {
+      unsigned int regno = DF_REF_REGNO (regs->ref);
+      if ((bitmap_bit_p (live, regno))
+	  || bitmap_bit_p (artificial_uses, regno))
+	{
+	  all_dead = false;
+	  break;
+	}
+      regs = regs->next;
+    }
+  
+  if (all_dead)
+    {
+      struct df_link *regs = mws->regs;
+      rtx note = alloc_EXPR_LIST (REG_UNUSED, *DF_REF_LOC (regs->ref), 
+				  REG_NOTES (insn));
+      REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+      print_note ("adding 1: ", insn, note);
+#endif
+      bitmap_set_bit (do_not_gen, regno);
+      /* Only do this if the value is totally dead.  */
+      if (flags & DF_RI_LIFE)
+	{
+	  REG_N_DEATHS (regno) ++;
+	  REG_LIVE_LENGTH (regno)++;
+	}
+    }
+  else
+    {
+      struct df_link *regs = mws->regs;
+      while (regs)
+	{
+	  struct df_ref *ref = regs->ref;
+	  
+	  regno = DF_REF_REGNO (ref);
+	  if ((!bitmap_bit_p (live, regno))
+	      && (!bitmap_bit_p (artificial_uses, regno)))
+	    {
+	      rtx note = alloc_EXPR_LIST (REG_UNUSED, regno_reg_rtx[regno], 
+					  REG_NOTES (insn));
+	      REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+	      print_note ("adding 2: ", insn, note);
+#endif
+	    }
+	  bitmap_set_bit (do_not_gen, regno);
+	  regs = regs->next;
+	}
+    }
+}
+
+
+/* Set the REG_DEAD notes for the multiword hardreg use in INSN based
+   on the bits in LIVE.  DO_NOT_GEN is used to keep REG_DEAD notes
+   from being set if the instruction both reads and writes the
+   register.  */
+
+static void
+df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+			  bitmap live, bitmap do_not_gen,
+			  bitmap artificial_uses, int flags)
+{
+  bool all_dead = true;
+  struct df_link *regs = mws->regs;
+  unsigned int regno = DF_REF_REGNO (regs->ref);
+  
+#ifdef REG_DEAD_DEBUGGING
+  fprintf (stderr, "mw looking at %d\n", DF_REF_REGNO (regs->ref));
+  df_ref_debug (regs->ref, stderr);
+#endif
+  while (regs)
+    {
+      unsigned int regno = DF_REF_REGNO (regs->ref);
+      if ((bitmap_bit_p (live, regno))
+	  || bitmap_bit_p (artificial_uses, regno))
+	{
+	  all_dead = false;
+	  break;
+	}
+      regs = regs->next;
+    }
+  
+  if (all_dead)
+    {
+      if (!bitmap_bit_p (do_not_gen, regno))
+	{
+	  /* Add a dead note for the entire multi word register.  */
+	  struct df_link *regs = mws->regs;
+	  rtx note = alloc_EXPR_LIST (REG_DEAD, *DF_REF_LOC (regs->ref), 
+				      REG_NOTES (insn));
+	  REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+	  print_note ("adding 1: ", insn, note);
+#endif
+
+	  if (flags & DF_RI_LIFE)
+	    {
+	      struct df_link *regs = mws->regs;
+	      while (regs)
+		{
+		  struct df_ref *ref = regs->ref;
+		  regno = DF_REF_REGNO (ref);
+		  REG_N_DEATHS (regno)++;
+		  regs = regs->next;
+		}
+	    }
+	}
+    }
+  else
+    {
+      struct df_link *regs = mws->regs;
+      while (regs)
+	{
+	  struct df_ref *ref = regs->ref;
+
+	  regno = DF_REF_REGNO (ref);
+	  if ((!bitmap_bit_p (live, regno))
+	      && (!bitmap_bit_p (artificial_uses, regno))
+	      && (!bitmap_bit_p (do_not_gen, regno)))
+	    {
+	      rtx note = alloc_EXPR_LIST (REG_DEAD, regno_reg_rtx[regno], 
+					  REG_NOTES (insn));
+	      REG_NOTES (insn) = note;
+	      if (flags & DF_RI_LIFE)
+		REG_N_DEATHS (regno)++;
+#ifdef REG_DEAD_DEBUGGING
+	      print_note ("adding 2: ", insn, note);
+#endif
+	    }
+
+	  regs = regs->next;
+	}
+    }
+}
+
+
+/* Create a REG_UNUSED note if necessary for DEF in INSN updating LIVE
+   and DO_NOT_GEN.  Do not generate notes for registers in artificial
+   uses.  */
+
+static void
+df_create_unused_note (basic_block bb, rtx insn, struct df_ref *def, 
+		       bitmap live, bitmap do_not_gen, bitmap artificial_uses, 
+		       bitmap local_live, bitmap local_processed, 
+		       int flags, int luid)
+{
+  unsigned int dregno = DF_REF_REGNO (def);
+  
+#ifdef REG_DEAD_DEBUGGING
+  fprintf (stderr, "  regular looking at def ");
+  df_ref_debug (def, stderr);
+#endif
+
+  if (bitmap_bit_p (live, dregno))
+    {
+      if (flags & DF_RI_LIFE)
+	{
+	  /* If we have seen this regno, then it has already been
+	     processed correctly with the per insn increment.  If we
+	     have not seen it we need to add the length from here to
+	     the end of the block to the live length.  */
+	  if (bitmap_bit_p (local_processed, dregno))
+	    {
+	      if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+		bitmap_clear_bit (local_live, dregno);
+	    }
+	  else
+	    {
+	      bitmap_set_bit (local_processed, dregno);
+	      REG_LIVE_LENGTH (dregno) += luid;
+	    }
+	}
+    }
+  else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG))
+	    && (!bitmap_bit_p (artificial_uses, dregno)) 
+	    && (!df_ignore_stack_reg (dregno)))
+    {
+      rtx reg = GET_CODE (*DF_REF_LOC (def)) == SUBREG ?
+	SUBREG_REG (*DF_REF_LOC (def)) : *DF_REF_LOC (def);
+      rtx note = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
+      REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+      print_note ("adding 3: ", insn, note);
+#endif
+      if (flags & DF_RI_LIFE)
+	{
+	  REG_N_DEATHS (dregno) ++;
+	  REG_LIVE_LENGTH (dregno)++;
+	}
+    }
+  
+  if ((flags & DF_RI_LIFE) && (dregno >= FIRST_PSEUDO_REGISTER))
+    {
+      REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb);
+      if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN)
+	REG_BASIC_BLOCK (dregno) = bb->index;
+      else if (REG_BASIC_BLOCK (dregno) != bb->index)
+	REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL;
+    }
+
+  if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER + DF_REF_MAY_CLOBBER)))
+    bitmap_set_bit (do_not_gen, dregno);
+  
+  /* Kill this register if it is not a subreg store.  */
+  if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+    bitmap_clear_bit (live, dregno);
+}
+
+
+/* Recompute the REG_DEAD and REG_UNUSED notes and compute register
+   info: lifetime, bb, and number of defs and uses for basic block
+   BB.  The three bitvectors are scratch regs used here.  */
+
+static void
+df_ri_bb_compute (struct dataflow *dflow, unsigned int bb_index, 
+		  bitmap live, bitmap do_not_gen, bitmap artificial_uses,
+		  bitmap local_live, bitmap local_processed, bitmap setjumps_crossed)
 {
   struct df *df = dflow->df;
-  struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
   basic_block bb = BASIC_BLOCK (bb_index);
   rtx insn;
+  struct df_ref *def;
+  struct df_ref *use;
+  int luid = 0;
+
+  bitmap_copy (live, df_get_live_out (df, bb));
+  bitmap_clear (artificial_uses);
+
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      /* Process the regs live at the end of the block.  Mark them as
+	 not local to any one basic block.  */
+      bitmap_iterator bi;
+      unsigned int regno;
+      EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
+	REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
+    }
 
-  bitmap_copy (live, bb_info->out);
+  /* Process the artificial defs and uses at the bottom of the block
+     to begin processing.  */
+  for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+      bitmap_clear_bit (live, DF_REF_REGNO (def));
 
+  for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
+    if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
+      {
+	unsigned int regno = DF_REF_REGNO (use);
+	bitmap_set_bit (live, regno);
+
+	/* Notes are not generated for any of the artificial registers
+	   at the bottom of the block.  */
+	bitmap_set_bit (artificial_uses, regno);
+      }
+  
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
       unsigned int regno;
       bitmap_iterator bi;
-      struct df_ref *def;
-      struct df_ref *use;
-
-      if (! INSN_P (insn))
+      struct df_mw_hardreg *mws;
+      
+      if (!INSN_P (insn))
 	continue;
 
-      for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+      if (dflow->flags & DF_RI_LIFE)
 	{
-	  unsigned int dregno = DF_REF_REGNO (def);
+	  /* Increment the live_length for all of the registers that
+	     are are referenced in this block and live at this
+	     particular point.  */
+	  bitmap_iterator bi;
+	  unsigned int regno;
+	  EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi)
+	    {
+	      REG_LIVE_LENGTH (regno)++;
+	    }
+	  luid++;
+	}
+
+      bitmap_clear (do_not_gen);
+      df_kill_notes (insn, dflow->flags);
 
-	  /* Kill this register.  */
-	  bitmap_clear_bit (live, dregno);
+      /* Process the defs.  */
+      if (CALL_P (insn))
+	{
+	  if (dflow->flags & DF_RI_LIFE)
+	    {
+	      bool can_throw = can_throw_internal (insn); 
+	      bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL);
+	      EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
+		{
+		  REG_N_CALLS_CROSSED (regno)++;
+		  if (can_throw)
+		    REG_N_THROWING_CALLS_CROSSED (regno)++;
+
+		  /* We have a problem with any pseudoreg that lives
+		     across the setjmp.  ANSI says that if a user
+		     variable does not change in value between the
+		     setjmp and the longjmp, then the longjmp
+		     preserves it.  This includes longjmp from a place
+		     where the pseudo appears dead.  (In principle,
+		     the value still exists if it is in scope.)  If
+		     the pseudo goes in a hard reg, some other value
+		     may occupy that hard reg where this pseudo is
+		     dead, thus clobbering the pseudo.  Conclusion:
+		     such a pseudo must not go in a hard reg.  */
+		  if (set_jump && regno >= FIRST_PSEUDO_REGISTER)
+		    bitmap_set_bit (setjumps_crossed, regno);
+		}
+	    }
+	  
+	  /* We only care about real sets for calls.  Clobbers only
+	     may clobber and cannot be depended on.  */
+	  for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
+	    {
+	      if ((mws->type == DF_REF_REG_DEF) 
+		  && !df_ignore_stack_reg (REGNO (mws->mw_reg)))
+		df_set_unused_notes_for_mw (insn, mws, live, do_not_gen, 
+					    artificial_uses, dflow->flags);
+	    }
+
+	  /* All of the defs except the return value are some sort of
+	     clobber.  This code is for the return.  */
+	  for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
+	    if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
+	      df_create_unused_note (bb, insn, def, live, do_not_gen, 
+				     artificial_uses, local_live, 
+				     local_processed, dflow->flags, luid);
+
+	}
+      else
+	{
+	  /* Regular insn.  */
+	  for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
+	    {
+	      if (mws->type == DF_REF_REG_DEF)
+		df_set_unused_notes_for_mw (insn, mws, live, do_not_gen, 
+					    artificial_uses, dflow->flags);
+	    }
+
+	  for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
+	    df_create_unused_note (bb, insn, def, live, do_not_gen, 
+				   artificial_uses, local_live, 
+				   local_processed, dflow->flags, luid);
+	}
+      
+      /* Process the uses.  */
+      for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
+	{
+	  if ((mws->type != DF_REF_REG_DEF)  
+	      && !df_ignore_stack_reg (REGNO (mws->mw_reg)))
+	    df_set_dead_notes_for_mw (insn, mws, live, do_not_gen,
+				      artificial_uses, dflow->flags);
 	}
 
-      for (use = DF_INSN_UID_GET (df, uid)->uses; use; use = use->next_ref)
+      for (use = DF_INSN_UID_USES (df, uid); use; use = use->next_ref)
 	{
 	  unsigned int uregno = DF_REF_REGNO (use);
 
+	  if ((dflow->flags & DF_RI_LIFE) && (uregno >= FIRST_PSEUDO_REGISTER))
+	    {
+	      REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb);
+	      if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN)
+		REG_BASIC_BLOCK (uregno) = bb->index;
+	      else if (REG_BASIC_BLOCK (uregno) != bb->index)
+		REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL;
+	    }
+	  
+#ifdef REG_DEAD_DEBUGGING
+	  fprintf (stderr, "  regular looking at use ");
+	  df_ref_debug (use, stderr);
+#endif
 	  if (!bitmap_bit_p (live, uregno))
 	    {
-	      use->flags |= DF_REF_DIES_AFTER_THIS_USE;
+	      if ( (!(DF_REF_FLAGS (use) & DF_REF_MW_HARDREG))
+		   && (!bitmap_bit_p (do_not_gen, uregno))
+		   && (!bitmap_bit_p (artificial_uses, uregno))
+		   && (!(DF_REF_FLAGS (use) & DF_REF_READ_WRITE))
+		   && (!df_ignore_stack_reg (uregno)))
+		{
+		  rtx reg = GET_CODE (*DF_REF_LOC (use)) == SUBREG ?
+		    SUBREG_REG (*DF_REF_LOC (use)) : *DF_REF_LOC (use);
+		  rtx note = alloc_EXPR_LIST (REG_DEAD, reg, REG_NOTES (insn));
+		  REG_NOTES (insn) = note;
+		  if (dflow->flags & DF_RI_LIFE)
+		    REG_N_DEATHS (uregno)++;
+
+#ifdef REG_DEAD_DEBUGGING
+		  print_note ("adding 4: ", insn, note);
+#endif
+		}
 	      /* This register is now live.  */
 	      bitmap_set_bit (live, uregno);
+
+	      if (dflow->flags & DF_RI_LIFE)
+		{
+		  /* If we have seen this regno, then it has already
+		     been processed correctly with the per insn
+		     increment.  If we have not seen it we set the bit
+		     so that begins to get processed locally.  Note
+		     that we don't even get here if the variable was
+		     live at the end of the block since just a ref
+		     inside the block does not effect the
+		     calculations.  */
+		  REG_LIVE_LENGTH (uregno) ++;
+		  bitmap_set_bit (local_live, uregno);
+		  bitmap_set_bit (local_processed, uregno);
+		}
 	    }
-	  else
-	    use->flags &= ~DF_REF_DIES_AFTER_THIS_USE;
 	}
-
-      /* Increment lifetimes of all live registers.  */
+    }
+  
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      /* Add the length of the block to all of the registers that were
+	 not referenced, but still live in this block.  */
+      bitmap_iterator bi;
+      unsigned int regno;
+      bitmap_and_compl_into (live, local_processed);
       EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
 	{
-	  problem_data->lifetime[regno]++;
+	  REG_LIVE_LENGTH (regno) += luid;
 	}
+      bitmap_clear (local_processed);
+      bitmap_clear (local_live);
     }
 }
 
@@ -3172,16 +3652,50 @@ df_ri_compute (struct dataflow *dflow, b
 {
   unsigned int bb_index;
   bitmap_iterator bi;
-  bitmap live;
+  bitmap live = BITMAP_ALLOC (NULL);
+  bitmap do_not_gen = BITMAP_ALLOC (NULL);
+  bitmap artificial_uses = BITMAP_ALLOC (NULL);
+  bitmap local_live = NULL;
+  bitmap local_processed = NULL;
+  bitmap setjumps_crossed = NULL;
+
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      local_live = BITMAP_ALLOC (NULL);
+      local_processed = BITMAP_ALLOC (NULL);
+      setjumps_crossed = BITMAP_ALLOC (NULL);
+    }
 
-  live = BITMAP_ALLOC (NULL);
+
+#ifdef REG_DEAD_DEBUGGING
+  df_lr_dump (dflow->df->problems_by_index [DF_LR], stderr);
+  print_rtl_with_bb (stderr, get_insns());
+#endif
 
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_scan, 0, bb_index, bi)
   {
-    df_ri_bb_compute (dflow, bb_index, live);
+    df_ri_bb_compute (dflow, bb_index, live, do_not_gen, artificial_uses,
+		      local_live, local_processed, setjumps_crossed);
   }
 
   BITMAP_FREE (live);
+  BITMAP_FREE (do_not_gen);
+  BITMAP_FREE (artificial_uses);
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      bitmap_iterator bi;
+      unsigned int regno;
+      /* See the setjump comment in df_ri_bb_compute.  */
+      EXECUTE_IF_SET_IN_BITMAP (setjumps_crossed, 0, regno, bi)
+	{
+	  REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
+	  REG_LIVE_LENGTH (regno) = -1;
+	}	  
+
+      BITMAP_FREE (local_live);
+      BITMAP_FREE (local_processed);
+      BITMAP_FREE (setjumps_crossed);
+    }
 }
 
 
@@ -3190,10 +3704,6 @@ df_ri_compute (struct dataflow *dflow, b
 static void
 df_ri_free (struct dataflow *dflow)
 {
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
-
-  free (problem_data->lifetime);
   free (dflow->problem_data);
   free (dflow);
 }
@@ -3204,14 +3714,12 @@ df_ri_free (struct dataflow *dflow)
 static void
 df_ri_dump (struct dataflow *dflow, FILE *file)
 {
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
-  int j;
+  print_rtl_with_bb (file, get_insns ());
 
-  fprintf (file, "Register info:\n");
-  for (j = 0; j < max_reg_num (); j++)
+  if (dflow->flags & DF_RI_LIFE)
     {
-      fprintf (file, "reg %d life %d\n", j, problem_data->lifetime[j]);
+      fprintf (file, "Register info:\n");
+      dump_flow_info (file, -1);
     }
 }
 
@@ -3233,7 +3741,12 @@ static struct df_problem problem_RI =
   NULL,                       /* Finalize function.  */
   df_ri_free,                 /* Free all of the problem information.  */
   df_ri_dump,                 /* Debugging.  */
-  &problem_UR                 /* Dependent problem.  */
+
+  /* Technically this is only dependent on the live registers problem
+     but it will produce infomation if built one of uninitialized
+     register problems (UR, UREC) is also run.  */
+  df_lr_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
@@ -3242,20 +3755,7 @@ static struct df_problem problem_RI =
    solution.  */
 
 struct dataflow * 
-df_ri_add_problem (struct df *df)
-{
-  return df_add_problem (df, &problem_RI);
-}
-
-
-/* Return total lifetime (in insns) of REG.  */
-int
-df_reg_lifetime (struct df *df, rtx reg)
+df_ri_add_problem (struct df *df, int flags)
 {
-  struct dataflow *dflow = df->problems_by_index[DF_RI];
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
-  return problem_data->lifetime[REGNO (reg)];
+  return df_add_problem (df, &problem_RI, flags);
 }
-
-
Index: modulo-sched.c
===================================================================
--- modulo-sched.c	(revision 113909)
+++ modulo-sched.c	(working copy)
@@ -934,9 +934,9 @@ sms_schedule (void)
   sched_init ();
 
   /* Init Data Flow analysis, to be used in interloop dep calculation.  */
-  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES |	DF_SUBREGS);
-  df_rd_add_problem (df);
-  df_ru_add_problem (df);
+  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES | DF_SUBREGS);
+  df_rd_add_problem (df, 0);
+  df_ru_add_problem (df, 0);
   df_chain_add_problem (df, DF_DU_CHAIN | DF_UD_CHAIN);
   df_analyze (df);
 
Index: see.c
===================================================================
--- see.c	(revision 113909)
+++ see.c	(working copy)
@@ -1323,9 +1323,8 @@ static void
 see_initialize_data_structures (void)
 {
   /* Build the df object. */
-  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES |	DF_SUBREGS);
-  df_rd_add_problem (df);
-  /* df_ru_add_problem (df); */
+  df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES | DF_SUBREGS);
+  df_rd_add_problem (df, 0);
   df_chain_add_problem (df, DF_DU_CHAIN | DF_UD_CHAIN);
   df_analyze (df);
 
Index: final.c
===================================================================
--- final.c	(revision 113909)
+++ final.c	(working copy)
@@ -4026,6 +4026,9 @@ rest_of_clean_state (void)
   epilogue_completed = 0;
   flow2_completed = 0;
   no_new_pseudos = 0;
+#ifdef STACK_REGS
+  regstack_completed = 0;
+#endif
 
   /* Clear out the insn_length contents now that they are no
      longer valid.  */
Index: rtl.h
===================================================================
--- rtl.h	(revision 113909)
+++ rtl.h	(working copy)
@@ -1978,6 +1978,12 @@ extern int epilogue_completed;
 
 extern int reload_in_progress;
 
+#ifdef STACK_REGS
+/* Nonzero after end of regstack pass.
+   Set to 1 or 0 by reg-stack.c.  */
+extern int regstack_completed;
+#endif
+
 /* If this is nonzero, we do not bother generating VOLATILE
    around volatile memory references, and we are willing to
    output indirect addresses.  If cse is to follow, we reject
Index: reg-stack.c
===================================================================
--- reg-stack.c	(revision 113909)
+++ reg-stack.c	(working copy)
@@ -187,6 +187,8 @@ static VEC(char,heap) *stack_regs_mentio
 
 #define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
 
+int regstack_completed = 0;
+
 /* This is the basic stack record.  TOP is an index into REG[] such
    that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.
 
@@ -3151,6 +3153,7 @@ rest_of_handle_stack_regs (void)
 #ifdef STACK_REGS
   if (reg_to_stack () && optimize)
     {
+      regstack_completed = 1;
       if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
                        | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
           && (flag_reorder_blocks || flag_reorder_blocks_and_partition))
@@ -3159,6 +3162,8 @@ rest_of_handle_stack_regs (void)
           cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
         }
     }
+  else 
+    regstack_completed = 1;
 #endif
   return 0;
 }

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