public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [trunk] Patch to properly model extracts and strict_low_part.
@ 2008-03-20  1:18 Kenneth Zadeck
  0 siblings, 0 replies; only message in thread
From: Kenneth Zadeck @ 2008-03-20  1:18 UTC (permalink / raw)
  To: gcc-patches, Richard Sandiford, Ian Lance Taylor, Park, Seongbae,
	Steven Bosscher, Bonzini, Paolo

[-- Attachment #1: Type: text/plain, Size: 3165 bytes --]

This patch provides a new file with a set of functions that allow loads 
and stores of *_EXTRACT, STRICT_LOW_PART and SUBREGS to be modeled.    
The new calls are in a form that this can be used later if we wish to 
perform this analysis globally rather than just locally as is done with 
this patch in global.c and ra-conflict.c.

This patch has been tested on todays revision on ia-64, x86-32 and 
x86-64 with no regressions.
It was tested on an earlier revision on the ppc-32, 64 (which bootstrap 
is currently broken) with the only issues being the ones raised in pr35642.

Given the conversation that is occurring between Richard Sandiford and 
Joern Renneche, it would not surprise me if some additions were required 
for oddball machines.    Also, all of the machines tested so far are 
pure big or little endian, i.e no machine with weird byte orders has 
been tested.

Ok to commit?

Kenny

2008-03-19  Richard Sandiford  <rsandifo@nildram.co.uk>
        Kenneth Zadeck <zadeck@naturalbridge.com>

    PR rtl-optimization/35404
    * fwprop.c (update_df): Added mode to call df_ref_create.
    Renamed DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
    DF_REF_EXTRACT_OFFSET.
    * dbgcnt.def (ra_byte_scan): Added.
    * ra-conflict.c (ra_init_live_subregs): Change live_subregs_used
    to bitmap.  Handle case where this is call and reg is not a
    subreg.
    (clear_reg_in_live, set_reg_in_live, global_conflicts): Calls
    df_compute_accessed_bytes to get info on subregs, extracts, and
    strict_low_part.  Change live_subregs_used to bitmap.
    (set_reg_in_live): Change last parm from bool to df_ref that may
    be NULL.
    (clear_reg_in_live): Removed reg parameter.
    (set_renumbers_live, dump_ref): Change live_subregs_used to bitmap.
    * Makefile.in (ra-conflict): Added dependency.
    * bitmap.h: Now includes obstack.h.  
    * df-scan.c (df_ref_record, df_uses_record,
    df_ref_create_structure): Added mode parameter.
    (df_ref_create, df_notes_rescan, df_ref_record, df_def_record_1,
    df_defs_record, df_uses_record, df_get_conditional_uses,
    df_get_call_refs, df_insn_refs_collect, df_bb_refs_collect,
    df_entry_block_defs_collect, df_exit_block_uses_collect):
    Added mode parameter to calls to df_ref_record, df_uses_record,
    df_ref_create_structure.
           (df_ref_equal_p, df_ref_compare): Added test for modes.
    (df_ref_create_structure): Added code to set mode.  Renamed
    DF_REF_WIDTH and DF_REF_OFFSET to DF_REF_EXTRACT_WIDTH and
    DF_REF_EXTRACT_OFFSET.
    * global.c (build_insn_chain): Changed live_subregs_used to bitmap.
    * dbgcnt.c (dbg_cnt): Added code to print message to dump_file
    when the last hit happens for a counter.  
    * df.h (df_ref_extract): Added mode field.
    (DF_REF_WIDTH, DF_REF_OFFSET) Renamed to DF_REF_EXTRACT_WIDTH and
    DF_REF_EXTRACT_OFFSET.
    (DF_REF_EXTRACT_MODE): New macro.
    (df_compute_accessed_bytes): New function.
    * ra.h (ra_init_live_subregs): Changed live_subregs_used to
    bitmap.
    * df-byte-scan.c: New file.
    * Makefile.in (df-byte-scan.o): New file.
    (global.o, dbgcnt.o): Added dependencies.
   
 


[-- Attachment #2: extract4.diff --]
[-- Type: text/x-patch, Size: 56188 bytes --]

Index: fwprop.c
===================================================================
--- fwprop.c	(revision 133349)
+++ fwprop.c	(working copy)
@@ -644,6 +644,7 @@ update_df (rtx insn, rtx *loc, struct df
       struct df_ref *orig_use = use, *new_use;
       int width = -1;
       int offset = -1;
+      enum machine_mode mode = 0;
       rtx *new_loc = find_occurrence (loc, DF_REF_REG (orig_use));
       use_rec++;
 
@@ -652,15 +653,17 @@ update_df (rtx insn, rtx *loc, struct df
 
       if (DF_REF_FLAGS_IS_SET (orig_use, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
 	{
-	  width = DF_REF_WIDTH (orig_use);
-	  offset = DF_REF_OFFSET (orig_use);
+	  width = DF_REF_EXTRACT_WIDTH (orig_use);
+	  offset = DF_REF_EXTRACT_OFFSET (orig_use);
+	  mode = DF_REF_EXTRACT_MODE (orig_use);
 	}
 
       /* Add a new insn use.  Use the original type, because it says if the
          use was within a MEM.  */
       new_use = df_ref_create (DF_REF_REG (orig_use), new_loc,
 			       insn, BLOCK_FOR_INSN (insn),
-			       type, DF_REF_FLAGS (orig_use) | new_flags, width, offset);
+			       type, DF_REF_FLAGS (orig_use) | new_flags, 
+			       width, offset, mode);
 
       /* Set up the use-def chain.  */
       df_chain_copy (new_use, DF_REF_CHAIN (orig_use));
Index: dbgcnt.def
===================================================================
--- dbgcnt.def	(revision 133349)
+++ dbgcnt.def	(working copy)
@@ -61,6 +61,73 @@ along with GCC; see the file COPYING3.  
    Use -fdbg-cnt=counter1:N,counter2:M,...
    which sets the limit for counter1 to N, and the limit for counter2 to M, etc.
    e.g. setting a limit to zero will make dbg_cnt () return false *always*.
+
+   The following shell file can then be used to binary search for
+   exact transformation that causes the bug.  A second shell script
+   should be written, say "tryTest", which exits with 1 if the
+   compiled program fails and exits with 0 if the program succeeds.
+   This shell script should take 1 parameter, the value to be passed
+   to set the counter of the compilation command in tryTest.  Then,
+   assuming that the following script is called binarySearch,
+   the command:
+
+	binarySearch tryTest 
+
+   will automatically find the highest value of the counter for which
+   the program fails.
+
+
+=====================================
+#!/bin/bash
+
+while getopts "l:u:i:" opt
+do
+    case $opt in
+        l) lb="$OPTARG";;
+        u) ub="$OPTARG";;
+        i) init="$OPTARG";;
+        ?) usage; exit 3;;
+    esac
+done
+
+shift $(($OPTIND - 1))
+echo $@
+cmd=${1+"${@}"}
+
+lb=${lb:=0}
+init=${init:=100}
+
+$cmd $lb
+lb_val=$?
+if [ -z "$ub" ]; then
+    # find the upper bound
+    ub=$(($init + $lb))
+    true
+    while [ $? -eq $lb_val ]; do
+        ub=$(($ub * 10))
+        #ub=`expr $ub \* 10`
+        $cmd $ub
+    done
+fi
+
+echo command: $cmd
+
+true
+while [ `expr $ub - $lb` -gt 1 ]; do
+    try=$(($lb + ( $ub - $lb ) / 2))
+    $cmd $try
+    if [ $? -eq $lb_val ]; then
+        lb=$try
+    else
+        ub=$try
+    fi
+done
+
+echo lbound: $lb
+echo ubound: $ub
+
+=====================================
+
 */
 
 /* Debug counter definitions.  */
@@ -73,6 +140,7 @@ DEBUG_COUNTER (dce)
 DEBUG_COUNTER (dce_fast)
 DEBUG_COUNTER (dce_ud)
 DEBUG_COUNTER (delete_trivial_dead)
+DEBUG_COUNTER (df_byte_scan)
 DEBUG_COUNTER (dse)
 DEBUG_COUNTER (dse1)
 DEBUG_COUNTER (dse2)
Index: ra-conflict.c
===================================================================
--- ra-conflict.c	(revision 133349)
+++ ra-conflict.c	(working copy)
@@ -411,82 +411,68 @@ set_conflicts_for_earlyclobber (rtx insn
 void
 ra_init_live_subregs (bool init_value, 
 		      sbitmap *live_subregs, 
-		      int *live_subregs_used,
+		      bitmap live_subregs_used,
 		      int allocnum, 
 		      rtx reg)
 {
-  unsigned int regno = REGNO (SUBREG_REG (reg));
+  unsigned int regno = REGNO ((GET_CODE (reg) == SUBREG) ? SUBREG_REG (reg) : reg);
   int size = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
 
   gcc_assert (size > 0);
 
   /* Been there, done that.  */
-  if (live_subregs_used[allocnum])
+  if (bitmap_bit_p (live_subregs_used, allocnum))
     return;
-
+  
   /* Create a new one with zeros.  */
   if (live_subregs[allocnum] == NULL)
     live_subregs[allocnum] = sbitmap_alloc (size);
-
+  
   /* If the entire reg was live before blasting into subregs, we need
      to init all of the subregs to ones else init to 0.  */
   if (init_value)
     sbitmap_ones (live_subregs[allocnum]);
   else 
     sbitmap_zero (live_subregs[allocnum]);
-
+  
   /* Set the number of bits that we really want.  */
-  live_subregs_used[allocnum] = size;
+  bitmap_set_bit (live_subregs_used, allocnum);
 }
 
-
 /* Set REG to be not live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
    HARD_REGS_LIVE.  DEF is the definition of the register.  */
 
 inline static void
 clear_reg_in_live (sparseset allocnos_live,
 		   sbitmap *live_subregs, 
-		   int *live_subregs_used,
+		   bitmap live_subregs_used,
 		   HARD_REG_SET *hard_regs_live, 
-		   rtx reg, struct df_ref *def)
+		   struct df_ref *def)
 {
+  rtx reg = DF_REF_REG (def);
   unsigned int regno = (GET_CODE (reg) == SUBREG) 
     ? REGNO (SUBREG_REG (reg)): REGNO (reg);
   int allocnum = reg_allocno[regno];
 
   if (allocnum >= 0)
     {
-      if (GET_CODE (reg) == SUBREG
-	  && !DF_REF_FLAGS_IS_SET (def, DF_REF_ZERO_EXTRACT))
+      unsigned int start;
+      unsigned int last;
+	  
+      if (!df_compute_accessed_bytes (def, &start, &last))
 	{
-	  unsigned int start = SUBREG_BYTE (reg);
-	  unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
-
 	  ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum), 
 				live_subregs, live_subregs_used, allocnum, reg);
 
-	  if (!DF_REF_FLAGS_IS_SET (def, DF_REF_STRICT_LOW_PART))
-	    {
-	      /* Expand the range to cover entire words.
-		 Bytes added here are "don't care".  */
-	      start = start / UNITS_PER_WORD * UNITS_PER_WORD;
-	      last = ((last + UNITS_PER_WORD - 1)
-		      / UNITS_PER_WORD * UNITS_PER_WORD);
-	    }
-
-	  /* Ignore the paradoxical bits.  */
-	  if ((int)last > live_subregs_used[allocnum])
-	    last = live_subregs_used[allocnum];
-
 	  while (start < last)
 	    {
 	      RESET_BIT (live_subregs[allocnum], start);
 	      start++;
 	    }
-
+	  
 	  if (sbitmap_empty_p (live_subregs[allocnum]))
 	    {
-	      live_subregs_used[allocnum] = 0;
+	      bitmap_clear_bit (live_subregs_used, allocnum);
 	      sparseset_clear_bit (allocnos_live, allocnum);
 	    }
 	  else
@@ -498,7 +484,7 @@ clear_reg_in_live (sparseset allocnos_li
 	{
 	  /* Resetting the live_subregs_used is effectively saying do not use the 
 	     subregs because we are writing the whole pseudo.  */
-	  live_subregs_used[allocnum] = 0;
+	  bitmap_clear_bit (live_subregs_used, allocnum);
 	  sparseset_clear_bit (allocnos_live, allocnum);
 	}
     }
@@ -530,7 +516,6 @@ clear_reg_in_live (sparseset allocnos_li
 }
 
 
-
 /* Set REG to be live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
    HARD_REGS_LIVE.  If EXTRACT is false, assume that the entire reg is
    set live even if REG is a subreg.  */
@@ -538,10 +523,9 @@ clear_reg_in_live (sparseset allocnos_li
 inline static void
 set_reg_in_live (sparseset allocnos_live, 
 		 sbitmap *live_subregs, 
-		 int *live_subregs_used,
+		 bitmap live_subregs_used,
 		 HARD_REG_SET *hard_regs_live, 
-		 rtx reg,
-		 bool extract)
+		 rtx reg, struct df_ref *def)
 {
   unsigned int regno = (GET_CODE (reg) == SUBREG) 
     ? REGNO (SUBREG_REG (reg)): REGNO (reg);
@@ -549,18 +533,17 @@ set_reg_in_live (sparseset allocnos_live
 
   if (allocnum >= 0)
     {
-      if ((GET_CODE (reg) == SUBREG) && !extract)
-	{
-	  unsigned int start = SUBREG_BYTE (reg);
-	  unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
+      unsigned int start;
+      unsigned int last;
 
+      /* Have to check that a def was passed, otherwise, this is
+	 called from the bottom of the block to get things started for
+	 that block and there are no df_refs there.  */
+      if (def && !df_compute_accessed_bytes (def, &start, &last))
+	{
 	  ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum), 
 				live_subregs, live_subregs_used, allocnum, reg);
 	  
-	  /* Ignore the paradoxical bits.  */
-	  if ((int)last > live_subregs_used[allocnum])
-	    last = live_subregs_used[allocnum];
-
 	  while (start < last)
 	    {
 	      SET_BIT (live_subregs[allocnum], start);
@@ -570,18 +553,18 @@ set_reg_in_live (sparseset allocnos_live
       else
 	/* Resetting the live_subregs_used is effectively saying do not use the 
 	   subregs because we are writing the whole pseudo.  */
-	  live_subregs_used[allocnum] = 0;
-     
+	bitmap_clear_bit (live_subregs_used, allocnum);
+      
       sparseset_set_bit (allocnos_live, allocnum);
     }
-      
+
   if (regno >= FIRST_PSEUDO_REGISTER)
     return;
 
   /* Handle hardware regs (and pseudos allocated to hard regs).  */
   if (! fixed_regs[regno])
     {
-      if ((GET_CODE (reg) == SUBREG) && !extract)
+      if (def && (GET_CODE (reg) == SUBREG))
 	{
 	  unsigned int start = regno;
 	  unsigned int last;
@@ -615,11 +598,9 @@ set_reg_in_live (sparseset allocnos_live
 inline static void
 set_renumbers_live (HARD_REG_SET *renumbers_live,   
 		    sbitmap *live_subregs, 
-		    int *live_subregs_used,
+		    bitmap live_subregs_used,
 		    int allocnum, int renumber)
 {
-  /* The width of the pseudo.  */
-  int nbytes = live_subregs_used[allocnum];
   int regno = allocno[allocnum].reg;
   enum machine_mode mode = GET_MODE (regno_reg_rtx[regno]);
 
@@ -627,10 +608,12 @@ set_renumbers_live (HARD_REG_SET *renumb
     fprintf (dump_file, "  set_renumbers_live %d->%d ", 
 	     regno, renumber);
 
-  if (nbytes > 0)
+  if (bitmap_bit_p (live_subregs_used, allocnum))
     {
       int i;
       sbitmap live_subs = live_subregs[allocnum];
+      /* The width of the pseudo.  */
+      int nbytes = live_subregs[allocnum]->n_bits;
 
       /* First figure out how many hard regs we are considering using.  */
       int target_nregs = hard_regno_nregs[renumber][mode];
@@ -679,19 +662,19 @@ dump_ref (FILE *file, 
 	  rtx reg,
 	  unsigned int regno,
 	  sbitmap *live_subregs, 
-	  int *live_subregs_used
+	  bitmap live_subregs_used
 )
 {
   int allocnum = reg_allocno[regno];
 
   fprintf (file, "%s %d", prefix, regno);
-  if (allocnum >= 0 
-      && live_subregs_used[allocnum] > 0)
+  if (allocnum >= 0 && bitmap_bit_p (live_subregs_used, allocnum))
     {
       int j;
       char s = '[';
-      
-      for (j = 0; j < live_subregs_used[allocnum]; j++)
+      int n_bytes = live_subregs[allocnum]->n_bits;
+
+      for (j = 0; j < n_bytes; j++)
 	if (TEST_BIT (live_subregs[allocnum], j))
 	  {
 	    fprintf (dump_file, "%c%d", s, j);
@@ -748,15 +731,14 @@ global_conflicts (void)
   VEC (df_ref_t, heap) *clobbers = NULL;
   VEC (df_ref_t, heap) *dying_regs = NULL;
 
-  /* live_subregs is a vector used to keep accurate information about
-     which hardregs are live in multiword pseudos.  live_subregs and
+  /* Live_subregs is a vector used to keep accurate information about
+     which hardregs are live in multiword pseudos.  Live_subregs and
      live_subregs_used are indexed by reg_allocno.  The live_subreg
-     entry for a particular pseudo is a bitmap with one bit per byte
+     entry for a particular pseudo is an sbitmap with one bit per byte
      of the register.  It is only used if the corresponding element is
-     non zero in live_subregs_used.  The value in live_subregs_used is
-     number of bytes that the pseudo can occupy.  */
+     set in live_subregs_used.  */
   sbitmap *live_subregs = XCNEWVEC (sbitmap, max_allocno);
-  int *live_subregs_used = XNEWVEC (int, max_allocno);
+  bitmap live_subregs_used = BITMAP_ALLOC (NULL);
 
   if (dump_file)
     {
@@ -777,7 +759,6 @@ global_conflicts (void)
       df_simulate_artificial_refs_at_end (bb, live);
 
       sparseset_clear (allocnos_live);
-      memset (live_subregs_used, 0, max_allocno * sizeof (int));
       CLEAR_HARD_REG_SET (hard_regs_live);
       CLEAR_HARD_REG_SET (renumbers_live);
 
@@ -800,7 +781,7 @@ global_conflicts (void)
 	      rtx reg = regno_reg_rtx[i];
 
 	      set_reg_in_live (allocnos_live, live_subregs, live_subregs_used, 
-			       &hard_regs_live, reg, false);
+			       &hard_regs_live, reg, NULL);
 	      if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
 		set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used, 
 				    allocnum, renumber);
@@ -863,8 +844,7 @@ global_conflicts (void)
 		{
 		  rtx reg = DF_REF_REG (def);
 		  set_reg_in_live (allocnos_live, live_subregs, live_subregs_used, 
-				   &hard_regs_live, reg, 
-				   DF_REF_FLAGS_IS_SET (def, DF_REF_ZERO_EXTRACT));
+				   &hard_regs_live, reg, def);
 		  if (dump_file)
 		    dump_ref (dump_file, "  adding def", "\n",
 			      reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);
@@ -898,7 +878,7 @@ global_conflicts (void)
 		  rtx reg = DF_REF_REG (def);
 
 		  clear_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
-				     &hard_regs_live, reg, def);
+				     &hard_regs_live, def);
 		  if (dump_file)
 		    dump_ref (dump_file, "  clearing def", "\n", 
 			      reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);
@@ -939,15 +919,13 @@ global_conflicts (void)
 	      bool renumbering = false;
 	      rtx reg = DF_REF_REG (use);
 
-	      /* DF_REF_READ_WRITE on a use means that this use is
-		 fabricated from a def that is a partial set to a
-		 multiword reg.  Here, we only model the subreg case
-		 precisely so we do not need to look at the fabricated
-		 use unless that set also happens to wrapped in a
-		 ZERO_EXTRACT. */
-	      if (DF_REF_FLAGS_IS_SET (use, DF_REF_READ_WRITE) 
-		  && (!DF_REF_FLAGS_IS_SET (use, DF_REF_ZERO_EXTRACT)) 
-		  && DF_REF_FLAGS_IS_SET (use, DF_REF_SUBREG))
+	      /* DF_REF_READ_WRITE on a use generally means that this
+		 use is fabricated from a def that is a partial set to
+		 a multiword reg.  Here, we only model those cases
+		 precisely so the only one to consider is the use put
+		 on a auto inc and dec insns.  */
+	      if (DF_REF_FLAGS_IS_SET (use, DF_REF_READ_WRITE)
+		  && (!DF_REF_FLAGS_IS_SET (use, DF_REF_PRE_POST_MODIFY)))
 		continue;
 	      
 	      if (dump_file)
@@ -956,19 +934,14 @@ global_conflicts (void)
 
 	      if (allocnum >= 0)
 		{
-		  if (GET_CODE (reg) == SUBREG
-		      && !DF_REF_FLAGS_IS_SET (use, DF_REF_ZERO_EXTRACT)) 
+		  unsigned int start;
+		  unsigned int last;
+		  
+		  if (!df_compute_accessed_bytes (use, &start, &last))
 		    {
-		      unsigned int start = SUBREG_BYTE (reg);
-		      unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
-
 		      ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum), 
 					    live_subregs, live_subregs_used, allocnum, reg);
 		      
-		      /* Ignore the paradoxical bits.  */
-		      if ((int)last > live_subregs_used[allocnum])
-			last = live_subregs_used[allocnum];
-		      
 		      while (start < last)
 			{
 			  if (!TEST_BIT (live_subregs[allocnum], start)) 
@@ -987,16 +960,16 @@ global_conflicts (void)
 			set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used, 
 					    allocnum, renumber);
 		    }
-		  else if (live_subregs_used[allocnum] > 0
+		  else if (bitmap_bit_p (live_subregs_used, allocnum)
 			   || !sparseset_bit_p (allocnos_live, allocnum))
 		    {
 		      if (dump_file)
 			fprintf (dump_file, "    %sdying pseudo\n", 
-				 (live_subregs_used[allocnum] > 0) ? "partially ": "");
+				 (bitmap_bit_p (live_subregs_used, allocnum)) ? "partially ": "");
 		      /* Resetting the live_subregs_used is
 			 effectively saying do not use the subregs
 			 because we are reading the whole pseudo.  */
-		      live_subregs_used[allocnum] = 0;
+		      bitmap_clear_bit (live_subregs_used, allocnum);
 		      sparseset_set_bit (allocnos_live, allocnum);
 		      if (renumber >= 0 && renumber < FIRST_PSEUDO_REGISTER)
 			set_renumbers_live (&renumbers_live, live_subregs, live_subregs_used, 
@@ -1234,8 +1207,8 @@ global_conflicts (void)
   /* Clean up.  */
   free (allocnos_live);
   free (live_subregs);
-  free (live_subregs_used);
   VEC_free (df_ref_t, heap, dying_regs);
   VEC_free (df_ref_t, heap, clobbers);
+  BITMAP_FREE (live_subregs_used);
   BITMAP_FREE (live);
 }
Index: bitmap.h
===================================================================
--- bitmap.h	(revision 133349)
+++ bitmap.h	(working copy)
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  
 #define GCC_BITMAP_H
 #include "hashtab.h"
 #include "statistics.h"
+#include "obstack.h"
 
 /* Fundamental storage type for bitmap.  */
 
Index: df-scan.c
===================================================================
--- df-scan.c	(revision 133349)
+++ df-scan.c	(working copy)
@@ -95,7 +95,7 @@ static struct df_mw_hardreg * df_null_mw
 static void df_ref_record (struct df_collection_rec *,
 			   rtx, rtx *, 
 			   basic_block, rtx, enum df_ref_type, 
-			   enum df_ref_flags, int, int);
+			   enum df_ref_flags, int, int, enum machine_mode);
 static void df_def_record_1 (struct df_collection_rec *,
 			     rtx, basic_block, rtx,
 			     enum df_ref_flags);
@@ -104,11 +104,13 @@ static void df_defs_record (struct df_co
 			    enum df_ref_flags);
 static void df_uses_record (struct df_collection_rec *,
 			    rtx *, enum df_ref_type,
-			    basic_block, rtx, enum df_ref_flags, int, int);
+			    basic_block, rtx, enum df_ref_flags, 
+			    int, int, enum machine_mode);
 
 static struct df_ref *df_ref_create_structure (struct df_collection_rec *, rtx, rtx *, 
 					       basic_block, rtx, enum df_ref_type, 
-					       enum df_ref_flags, int, int);
+					       enum df_ref_flags, 
+					       int, int, enum machine_mode);
 
 static void df_insn_refs_collect (struct df_collection_rec*, 
 				  basic_block, rtx); 
@@ -616,16 +618,16 @@ df_scan_blocks (void)
    LOC within INSN of BB.  This function is only used externally. 
 
    If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
-   DF_REF_ZERO_EXTRACT.  WIDTH and OFFSET are used to access the fields
-   if they were constants.  Otherwise they should be -1 if those flags
-   were set.  */
+   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the
+   fields if they were constants.  Otherwise they should be -1 if
+   those flags were set.  */
 
 struct df_ref *
 df_ref_create (rtx reg, rtx *loc, rtx insn, 
 	       basic_block bb,
 	       enum df_ref_type ref_type, 
 	       enum df_ref_flags ref_flags,
-	       int width, int offset)
+	       int width, int offset, enum machine_mode mode)
 {
   struct df_ref *ref;
   struct df_reg_info **reg_info;
@@ -640,7 +642,8 @@ df_ref_create (rtx reg, rtx *loc, rtx in
   /* You cannot hack artificial refs.  */
   gcc_assert (insn);
   ref = df_ref_create_structure (NULL, reg, loc, bb, insn,
-                                 ref_type, ref_flags, width, offset);
+                                 ref_type, ref_flags, 
+				 width, offset, mode);
 
   if (DF_REF_TYPE (ref) == DF_REF_REG_DEF)
     {
@@ -2066,7 +2069,7 @@ df_notes_rescan (rtx insn)
 	    case REG_EQUAL:
 	      df_uses_record (&collection_rec,
 			      &XEXP (note, 0), DF_REF_REG_USE,
-			      bb, insn, DF_REF_IN_NOTE, -1, -1);
+			      bb, insn, DF_REF_IN_NOTE, -1, -1, 0);
 	    default:
 	      break;
 	    }
@@ -2142,8 +2145,9 @@ df_ref_equal_p (struct df_ref *ref1, str
      compared in the next set of tests.  */
   if ((DF_REF_FLAGS_IS_SET (ref1, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
       && (DF_REF_FLAGS_IS_SET (ref2, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
-      && ((DF_REF_OFFSET (ref1) != DF_REF_OFFSET (ref2))
-	  || (DF_REF_WIDTH (ref1) != DF_REF_WIDTH (ref2))))
+      && ((DF_REF_EXTRACT_OFFSET (ref1) != DF_REF_EXTRACT_OFFSET (ref2))
+	  || (DF_REF_EXTRACT_WIDTH (ref1) != DF_REF_EXTRACT_WIDTH (ref2))
+	  || (DF_REF_EXTRACT_MODE (ref1) != DF_REF_EXTRACT_MODE (ref2))))
     return false;
 
   return (ref1 == ref2) ||
@@ -2199,10 +2203,12 @@ df_ref_compare (const void *r1, const vo
      at ref1.  */
   if (DF_REF_FLAGS_IS_SET (ref1, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
     {
-      if (DF_REF_OFFSET (ref1) != DF_REF_OFFSET (ref2))
-	return DF_REF_OFFSET (ref1) - DF_REF_OFFSET (ref2);
-      if (DF_REF_WIDTH (ref1) != DF_REF_WIDTH (ref2))
-	return DF_REF_WIDTH (ref1) - DF_REF_WIDTH (ref2);
+      if (DF_REF_EXTRACT_OFFSET (ref1) != DF_REF_EXTRACT_OFFSET (ref2))
+	return DF_REF_EXTRACT_OFFSET (ref1) - DF_REF_EXTRACT_OFFSET (ref2);
+      if (DF_REF_EXTRACT_WIDTH (ref1) != DF_REF_EXTRACT_WIDTH (ref2))
+	return DF_REF_EXTRACT_WIDTH (ref1) - DF_REF_EXTRACT_WIDTH (ref2);
+      if (DF_REF_EXTRACT_MODE (ref1) != DF_REF_EXTRACT_MODE (ref2))
+	return DF_REF_EXTRACT_MODE (ref1) - DF_REF_EXTRACT_MODE (ref2);
     }
   return 0;
 }
@@ -2583,7 +2589,7 @@ df_refs_add_to_chains (struct df_collect
 /* Allocate a ref and initialize its fields. 
 
    If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
-   DF_REF_ZERO_EXTRACT.  WIDTH and OFFSET are used to access the fields
+   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the fields
    if they were constants.  Otherwise they should be -1 if those flags
    were set.  */
 
@@ -2593,7 +2599,7 @@ df_ref_create_structure (struct df_colle
 			 basic_block bb, rtx insn, 
 			 enum df_ref_type ref_type, 
 			 enum df_ref_flags ref_flags,
-			 int width, int offset)
+			 int width, int offset, enum machine_mode mode)
 {
   struct df_ref *this_ref;
   int regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
@@ -2603,8 +2609,9 @@ df_ref_create_structure (struct df_colle
   if (ref_flags & (DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
     {
       this_ref = pool_alloc (problem_data->ref_extract_pool);
-      DF_REF_WIDTH (this_ref) = width;
-      DF_REF_OFFSET (this_ref) = offset;
+      DF_REF_EXTRACT_WIDTH (this_ref) = width;
+      DF_REF_EXTRACT_OFFSET (this_ref) = offset;
+      DF_REF_EXTRACT_MODE (this_ref) = mode;
     }
   else
     this_ref = pool_alloc (problem_data->ref_pool);
@@ -2659,9 +2666,9 @@ df_ref_create_structure (struct df_colle
    at address LOC within INSN of BB. 
 
    If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
-   DF_REF_ZERO_EXTRACT.  WIDTH and OFFSET are used to access the fields
-   if they were constants.  Otherwise they should be -1 if those flags
-   were set.  */
+   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the
+   fields if they were constants.  Otherwise they should be -1 if
+   those flags were set.  */
 
 
 static void
@@ -2670,7 +2677,7 @@ df_ref_record (struct df_collection_rec 
 	       basic_block bb, rtx insn, 
 	       enum df_ref_type ref_type, 
 	       enum df_ref_flags ref_flags,
-	       int width, int offset) 
+	       int width, int offset, enum machine_mode mode) 
 {
   unsigned int regno;
 
@@ -2719,7 +2726,8 @@ df_ref_record (struct df_collection_rec 
       for (i = regno; i < endregno; i++)
 	{
 	  ref = df_ref_create_structure (collection_rec, regno_reg_rtx[i], loc, 
-					 bb, insn, ref_type, ref_flags, width, offset);
+					 bb, insn, ref_type, ref_flags, 
+					 width, offset, mode);
 
           gcc_assert (ORIGINAL_REGNO (DF_REF_REG (ref)) == i);
 	}
@@ -2728,7 +2736,7 @@ df_ref_record (struct df_collection_rec 
     {
       struct df_ref *ref;
       ref = df_ref_create_structure (collection_rec, reg, loc, bb, insn, 
-                                     ref_type, ref_flags, width, offset);
+                                     ref_type, ref_flags, width, offset, mode);
     }
 }
 
@@ -2764,6 +2772,7 @@ df_def_record_1 (struct df_collection_re
   rtx dst;
   int offset = -1;
   int width = -1;
+  enum machine_mode mode = 0;
 
  /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
      construct.  */
@@ -2808,6 +2817,7 @@ df_def_record_1 (struct df_collection_re
 	{
 	  width = INTVAL (XEXP (dst, 1));
 	  offset = INTVAL (XEXP (dst, 2));
+	  mode = GET_MODE (dst);
 	}
 
       loc = &XEXP (dst, 0);
@@ -2818,13 +2828,15 @@ df_def_record_1 (struct df_collection_re
   if (REG_P (dst))
     {
       df_ref_record (collection_rec, 
-		     dst, loc, bb, insn, DF_REF_REG_DEF, flags, width, offset);
+		     dst, loc, bb, insn, DF_REF_REG_DEF, flags, 
+		     width, offset, mode);
 
       /* We want to keep sp alive everywhere - by making all
 	 writes to sp also use of sp. */
       if (REGNO (dst) == STACK_POINTER_REGNUM)
 	df_ref_record (collection_rec,
-		       dst, NULL, bb, insn, DF_REF_REG_USE, flags, width, offset);
+		       dst, NULL, bb, insn, DF_REF_REG_USE, flags, 
+		       width, offset, mode);
     }
   else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
     {
@@ -2834,7 +2846,8 @@ df_def_record_1 (struct df_collection_re
       flags |= DF_REF_SUBREG;
 
       df_ref_record (collection_rec, 
-		     dst, loc, bb, insn, DF_REF_REG_DEF, flags, width, offset);
+		     dst, loc, bb, insn, DF_REF_REG_DEF, flags, 
+		     width, offset, mode);
     }
 }
 
@@ -2873,15 +2886,15 @@ df_defs_record (struct df_collection_rec
 /* Process all the registers used in the rtx at address LOC.  
 
    If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
-   DF_REF_ZERO_EXTRACT.  WIDTH and LOWER are used to access the fields
-   if they were constants.  Otherwise they should be -1 if those flags
-   were set.  */
+   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the
+   fields if they were constants.  Otherwise they should be -1 if
+   those flags were set.  */
 
 static void
 df_uses_record (struct df_collection_rec *collection_rec,
                 rtx *loc, enum df_ref_type ref_type,
 		basic_block bb, rtx insn, enum df_ref_flags flags,
-		int width, int offset)
+		int width, int offset, enum machine_mode mode)
 {
   RTX_CODE code;
   rtx x;
@@ -2912,7 +2925,8 @@ df_uses_record (struct df_collection_rec
       if (MEM_P (XEXP (x, 0)))
 	df_uses_record (collection_rec,
 			&XEXP (XEXP (x, 0), 0),
-			DF_REF_REG_MEM_STORE, bb, insn, flags, width, offset);
+			DF_REF_REG_MEM_STORE, bb, insn, flags, 
+			width, offset, mode);
 
       /* If we're clobbering a REG then we have a def so ignore.  */
       return;
@@ -2920,7 +2934,8 @@ df_uses_record (struct df_collection_rec
     case MEM:
       df_uses_record (collection_rec,
 		      &XEXP (x, 0), DF_REF_REG_MEM_LOAD, 
-		      bb, insn, flags & DF_REF_IN_NOTE, width, offset);
+		      bb, insn, flags & DF_REF_IN_NOTE, 
+		      width, offset, mode);
       return;
 
     case SUBREG:
@@ -2930,14 +2945,16 @@ df_uses_record (struct df_collection_rec
       if (!REG_P (SUBREG_REG (x)))
 	{
 	  loc = &SUBREG_REG (x);
-	  df_uses_record (collection_rec, loc, ref_type, bb, insn, flags, width, offset);
+	  df_uses_record (collection_rec, loc, ref_type, bb, insn, flags, 
+			  width, offset, mode);
 	  return;
 	}
       /* ... Fall through ...  */
 
     case REG:
       df_ref_record (collection_rec, 
-		     x, loc, bb, insn, ref_type, flags, width, offset);
+		     x, loc, bb, insn, ref_type, flags, 
+		     width, offset, mode);
       return;
 
     case SIGN_EXTRACT:
@@ -2951,6 +2968,7 @@ df_uses_record (struct df_collection_rec
 	  {
 	    width = INTVAL (XEXP (x, 1));
 	    offset = INTVAL (XEXP (x, 2));
+	    mode = GET_MODE (x);
 
 	    if (code == ZERO_EXTRACT)
 	      flags |= DF_REF_ZERO_EXTRACT;
@@ -2958,7 +2976,8 @@ df_uses_record (struct df_collection_rec
 	      flags |= DF_REF_SIGN_EXTRACT;
 
 	    df_uses_record (collection_rec,
-			    &XEXP (x, 0), ref_type, bb, insn, flags, width, offset);
+			    &XEXP (x, 0), ref_type, bb, insn, flags, 
+			    width, offset, mode);
 	    return;
 	  }
       }
@@ -2969,7 +2988,8 @@ df_uses_record (struct df_collection_rec
 	rtx dst = SET_DEST (x);
 	gcc_assert (!(flags & DF_REF_IN_NOTE));
 	df_uses_record (collection_rec,
-			&SET_SRC (x), DF_REF_REG_USE, bb, insn, flags, width, offset);
+			&SET_SRC (x), DF_REF_REG_USE, bb, insn, flags, 
+			width, offset, mode);
 
 	switch (GET_CODE (dst))
 	  {
@@ -2978,7 +2998,8 @@ df_uses_record (struct df_collection_rec
 		{
 		  df_uses_record (collection_rec, &SUBREG_REG (dst), 
 				  DF_REF_REG_USE, bb, insn, 
-				  flags | DF_REF_READ_WRITE | DF_REF_SUBREG, width, offset);
+				  flags | DF_REF_READ_WRITE | DF_REF_SUBREG, 
+				  width, offset, mode);
 		  break;
 		}
 	      /* Fall through.  */
@@ -2990,7 +3011,8 @@ df_uses_record (struct df_collection_rec
 		break;
 	    case MEM:
 	      df_uses_record (collection_rec, &XEXP (dst, 0),
-			      DF_REF_REG_MEM_STORE, bb, insn, flags, width, offset);
+			      DF_REF_REG_MEM_STORE, bb, insn, flags, 
+			      width, offset, mode);
 	      break;
 	    case STRICT_LOW_PART:
 	      {
@@ -3001,7 +3023,8 @@ df_uses_record (struct df_collection_rec
 		df_uses_record (collection_rec, 
 				(GET_CODE (dst) == SUBREG) ? &SUBREG_REG (dst) : temp, 
 				DF_REF_REG_USE, bb, insn, 
-				DF_REF_READ_WRITE | DF_REF_STRICT_LOW_PART, width, offset);
+				DF_REF_READ_WRITE | DF_REF_STRICT_LOW_PART, 
+				width, offset, mode);
 	      }
 	      break;
 	    case ZERO_EXTRACT:
@@ -3011,18 +3034,22 @@ df_uses_record (struct df_collection_rec
 		  {
 		    width = INTVAL (XEXP (dst, 1));
 		    offset = INTVAL (XEXP (dst, 2));
+		    mode = GET_MODE (dst);
 		  }
 		else 
 		  {
 		    df_uses_record (collection_rec, &XEXP (dst, 1), 
-				    DF_REF_REG_USE, bb, insn, flags, width, offset);
+				    DF_REF_REG_USE, bb, insn, flags, 
+				    width, offset, mode);
 		    df_uses_record (collection_rec, &XEXP (dst, 2), 
-				    DF_REF_REG_USE, bb, insn, flags, width, offset);
+				    DF_REF_REG_USE, bb, insn, flags, 
+				    width, offset, mode);
 		  }
 
 		df_uses_record (collection_rec, &XEXP (dst, 0), 
 				DF_REF_REG_USE, bb, insn, 
-				DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT, width, offset);
+				DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT, 
+				width, offset, mode);
 	      }
 	      break;
 
@@ -3072,7 +3099,8 @@ df_uses_record (struct df_collection_rec
 
 	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
 	      df_uses_record (collection_rec, &ASM_OPERANDS_INPUT (x, j),
-			      DF_REF_REG_USE, bb, insn, flags, width, offset);
+			      DF_REF_REG_USE, bb, insn, flags, 
+			      width, offset, mode);
 	    return;
 	  }
 	break;
@@ -3087,7 +3115,8 @@ df_uses_record (struct df_collection_rec
       /* Catch the def of the register being modified.  */
       df_ref_record (collection_rec, XEXP (x, 0), &XEXP (x, 0), bb, insn, 
 		     DF_REF_REG_DEF,
-                     flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY, width, offset);
+                     flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY, 
+		     width, offset, mode);
 
       /* ... Fall through to handle uses ...  */
 
@@ -3111,7 +3140,8 @@ df_uses_record (struct df_collection_rec
 		goto retry;
 	      }
 	    df_uses_record (collection_rec, &XEXP (x, i), ref_type, 
-			    bb, insn, flags, width, offset);
+			    bb, insn, flags, 
+			    width, offset, mode);
 	  }
 	else if (fmt[i] == 'E')
 	  {
@@ -3119,7 +3149,8 @@ df_uses_record (struct df_collection_rec
 	    for (j = 0; j < XVECLEN (x, i); j++)
 	      df_uses_record (collection_rec,
 			      &XVECEXP (x, i, j), ref_type, 
-			      bb, insn, flags, width, offset);
+			      bb, insn, flags, 
+			      width, offset, mode);
 	  }
       }
   }
@@ -3141,19 +3172,21 @@ df_get_conditional_uses (struct df_colle
         {
 	  int width = -1;
 	  int offset = -1;
+	  enum machine_mode mode = 0;
           struct df_ref *use;
 
 	  if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
 	    {
-	      width = DF_REF_WIDTH (ref);
-	      offset = DF_REF_OFFSET (ref);
+	      width = DF_REF_EXTRACT_WIDTH (ref);
+	      offset = DF_REF_EXTRACT_OFFSET (ref);
+	      mode = DF_REF_EXTRACT_MODE (ref);
 	    }
 
           use = df_ref_create_structure (collection_rec, DF_REF_REG (ref),
 					 DF_REF_LOC (ref), DF_REF_BB (ref),
 					 DF_REF_INSN (ref), DF_REF_REG_USE,
 					 DF_REF_FLAGS (ref) & ~DF_REF_CONDITIONAL,
-					 width, offset);
+					 width, offset, mode);
           DF_REF_REGNO (use) = DF_REF_REGNO (ref);
         }
     }
@@ -3191,7 +3224,7 @@ df_get_call_refs (struct df_collection_r
     {
       if (GET_CODE (XEXP (note, 0)) == USE)
         df_uses_record (collection_rec, &XEXP (XEXP (note, 0), 0),
-			DF_REF_REG_USE, bb, insn, flags, -1, -1);
+			DF_REF_REG_USE, bb, insn, flags, -1, -1, 0);
       else if (GET_CODE (XEXP (note, 0)) == CLOBBER)
 	{
 	  if (REG_P (XEXP (XEXP (note, 0), 0)))
@@ -3203,13 +3236,14 @@ df_get_call_refs (struct df_collection_r
 	    }
 	  else
 	    df_uses_record (collection_rec, &XEXP (note, 0),
-		            DF_REF_REG_USE, bb, insn, flags, -1, -1);
+		            DF_REF_REG_USE, bb, insn, flags, -1, -1, 0);
 	}
     }
 
   /* The stack ptr is used (honorarily) by a CALL insn.  */
   df_ref_record (collection_rec, regno_reg_rtx[STACK_POINTER_REGNUM],
-		 NULL, bb, insn, DF_REF_REG_USE, DF_REF_CALL_STACK_USAGE | flags, -1, -1);
+		 NULL, bb, insn, DF_REF_REG_USE, DF_REF_CALL_STACK_USAGE | flags, 
+		 -1, -1, 0);
 
   /* Calls may also reference any of the global registers,
      so they are recorded as used.  */
@@ -3217,9 +3251,9 @@ df_get_call_refs (struct df_collection_r
     if (global_regs[i])
       {
 	df_ref_record (collection_rec, regno_reg_rtx[i],
-		       NULL, bb, insn, DF_REF_REG_USE, flags, -1, -1);
+		       NULL, bb, insn, DF_REF_REG_USE, flags, -1, -1, 0);
 	df_ref_record (collection_rec, regno_reg_rtx[i],
-		       NULL, bb, insn, DF_REF_REG_DEF, flags, -1, -1);
+		       NULL, bb, insn, DF_REF_REG_DEF, flags, -1, -1, 0);
       }
 
   is_sibling_call = SIBLING_CALL_P (insn);
@@ -3232,7 +3266,8 @@ df_get_call_refs (struct df_collection_r
 	      || refers_to_regno_p (ui, ui+1, 
 				    current_function_return_rtx, NULL)))
         df_ref_record (collection_rec, regno_reg_rtx[ui], 
-		       NULL, bb, insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER | flags, -1, -1);
+		       NULL, bb, insn, DF_REF_REG_DEF, DF_REF_MAY_CLOBBER | flags, 
+		       -1, -1, 0);
     }
 
   BITMAP_FREE (defs_generated);
@@ -3270,7 +3305,7 @@ df_insn_refs_collect (struct df_collecti
         case REG_EQUAL:
           df_uses_record (collection_rec,
                           &XEXP (note, 0), DF_REF_REG_USE,
-                          bb, insn, DF_REF_IN_NOTE, -1, -1);
+                          bb, insn, DF_REF_IN_NOTE, -1, -1, 0);
           break;
         case REG_NON_LOCAL_GOTO:
           /* The frame ptr is used by a non-local goto.  */
@@ -3278,13 +3313,13 @@ df_insn_refs_collect (struct df_collecti
                          regno_reg_rtx[FRAME_POINTER_REGNUM],
                          NULL,
                          bb, insn, 
-                         DF_REF_REG_USE, 0, -1, -1);
+                         DF_REF_REG_USE, 0, -1, -1, 0);
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
           df_ref_record (collection_rec,
                          regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
                          NULL,
                          bb, insn, 
-                         DF_REF_REG_USE, 0, -1, -1);
+                         DF_REF_REG_USE, 0, -1, -1, 0);
 #endif
           break;
         default:
@@ -3298,7 +3333,8 @@ df_insn_refs_collect (struct df_collecti
 
   /* Record the register uses.  */
   df_uses_record (collection_rec,
-		  &PATTERN (insn), DF_REF_REG_USE, bb, insn, 0, -1, -1);
+		  &PATTERN (insn), DF_REF_REG_USE, bb, insn, 0, 
+		  -1, -1, 0);
 
   /* DF_REF_CONDITIONAL needs corresponding USES. */
   if (is_cond_exec)
@@ -3381,7 +3417,7 @@ df_bb_refs_collect (struct df_collection
 	  if (regno == INVALID_REGNUM)
 	    break;
 	  df_ref_record (collection_rec, regno_reg_rtx[regno], NULL,
-			 bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1);
+			 bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, 0);
 	}
     }
 #endif
@@ -3405,7 +3441,7 @@ df_bb_refs_collect (struct df_collection
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
 	if (EH_USES (i))
 	  df_ref_record (collection_rec, regno_reg_rtx[i], NULL,
-			 bb, NULL, DF_REF_REG_USE, DF_REF_AT_TOP, -1, -1);
+			 bb, NULL, DF_REF_REG_USE, DF_REF_AT_TOP, -1, -1, 0);
     }
 #endif
 
@@ -3413,7 +3449,7 @@ df_bb_refs_collect (struct df_collection
      non-local goto.  */
   if (bb->flags & BB_NON_LOCAL_GOTO_TARGET)
     df_ref_record (collection_rec, hard_frame_pointer_rtx, NULL,
-		   bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1);
+		   bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP, -1, -1, 0);
  
   /* Add the artificial uses.  */
   if (bb->index >= NUM_FIXED_BLOCKS)
@@ -3427,7 +3463,7 @@ df_bb_refs_collect (struct df_collection
       EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi)
 	{
 	  df_ref_record (collection_rec, regno_reg_rtx[regno], NULL,
-			 bb, NULL, DF_REF_REG_USE, 0, -1, -1);
+			 bb, NULL, DF_REF_REG_USE, 0, -1, -1, 0);
 	}
     }
 
@@ -3720,7 +3756,7 @@ df_entry_block_defs_collect (struct df_c
   EXECUTE_IF_SET_IN_BITMAP (entry_block_defs, 0, i, bi)
     {
       df_ref_record (collection_rec, regno_reg_rtx[i], NULL, 
-		     ENTRY_BLOCK_PTR, NULL, DF_REF_REG_DEF, 0, -1, -1);
+		     ENTRY_BLOCK_PTR, NULL, DF_REF_REG_DEF, 0, -1, -1, 0);
     }
 
   df_canonize_collection_rec (collection_rec);
@@ -3881,7 +3917,7 @@ df_exit_block_uses_collect (struct df_co
 
   EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi)
     df_ref_record (collection_rec, regno_reg_rtx[i], NULL,
-		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1);
+		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1, 0);
 
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
   /* It is deliberate that this is not put in the exit block uses but
@@ -3891,7 +3927,7 @@ df_exit_block_uses_collect (struct df_co
       && bb_has_eh_pred (EXIT_BLOCK_PTR)
       && fixed_regs[ARG_POINTER_REGNUM])
     df_ref_record (collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
-		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1);
+		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0, -1, -1, 0);
 #endif
 
   df_canonize_collection_rec (collection_rec);
Index: global.c
===================================================================
--- global.c	(revision 133349)
+++ global.c	(working copy)
@@ -1418,7 +1418,7 @@ build_insn_chain (void)
      live_subregs_used is number of bytes that the pseudo can
      occupy.  */
   sbitmap *live_subregs = XCNEWVEC (sbitmap, max_regno);
-  int *live_subregs_used = XNEWVEC (int, max_regno);
+  bitmap live_subregs_used = BITMAP_ALLOC (NULL);
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (TEST_HARD_REG_BIT (eliminable_regset, i))
@@ -1430,7 +1430,6 @@ build_insn_chain (void)
       rtx insn;
       
       CLEAR_REG_SET (live_relevant_regs);
-      memset (live_subregs_used, 0, max_regno * sizeof (int));
       
       EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), 0, i, bi)
 	{
@@ -1492,6 +1491,7 @@ build_insn_chain (void)
 			if (GET_CODE (reg) == SUBREG
 			    && !DF_REF_FLAGS_IS_SET (def, DF_REF_ZERO_EXTRACT))
 			  {
+			    unsigned int regsize = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
 			    unsigned int start = SUBREG_BYTE (reg);
 			    unsigned int last = start 
 			      + GET_MODE_SIZE (GET_MODE (reg));
@@ -1513,8 +1513,8 @@ build_insn_chain (void)
 			      }
 
 			    /* Ignore the paradoxical bits.  */
-			    if ((int)last > live_subregs_used[regno])
-			      last = live_subregs_used[regno];
+			    if (last > regsize)
+			      last = regsize;
 
 			    while (start < last)
 			      {
@@ -1524,7 +1524,7 @@ build_insn_chain (void)
 			    
 			    if (sbitmap_empty_p (live_subregs[regno]))
 			      {
-				live_subregs_used[regno] = 0;
+				bitmap_clear_bit (live_subregs_used, regno);
 				bitmap_clear_bit (live_relevant_regs, regno);
 			      }
 			    else
@@ -1543,7 +1543,7 @@ build_insn_chain (void)
 			    if (!DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL))
 			      {
 				bitmap_clear_bit (live_relevant_regs, regno);
-				live_subregs_used[regno] = 0;
+				bitmap_clear_bit (live_subregs_used, regno);
 			      }
 			  }
 		      }
@@ -1588,6 +1588,7 @@ build_insn_chain (void)
 			    && !DF_REF_FLAGS_IS_SET (use,
 						     DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT)) 
 			  {
+			    unsigned int regsize = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
 			    unsigned int start = SUBREG_BYTE (reg);
 			    unsigned int last = start 
 			      + GET_MODE_SIZE (GET_MODE (reg));
@@ -1599,8 +1600,8 @@ build_insn_chain (void)
 						  regno, reg);
 			    
 			    /* Ignore the paradoxical bits.  */
-			    if ((int)last > live_subregs_used[regno])
-			      last = live_subregs_used[regno];
+			    if (last > regsize)
+			      last = regsize;
 
 			    while (start < last)
 			      {
@@ -1613,7 +1614,7 @@ build_insn_chain (void)
 			     effectively saying do not use the subregs
 			     because we are reading the whole
 			     pseudo.  */
-			  live_subregs_used[regno] = 0;
+			  bitmap_clear_bit (live_subregs_used, regno);
 			bitmap_set_bit (live_relevant_regs, regno);
 		      }
 		  }
@@ -1664,7 +1665,7 @@ build_insn_chain (void)
   *p = NULL;
 
   free (live_subregs);
-  free (live_subregs_used);
+  BITMAP_FREE (live_subregs_used);
   BITMAP_FREE (live_relevant_regs);
   BITMAP_FREE (elim_regset);
 
Index: dbgcnt.c
===================================================================
--- dbgcnt.c	(revision 133349)
+++ dbgcnt.c	(working copy)
@@ -23,6 +23,9 @@ See dbgcnt.def for usage information.  *
 #include "system.h"
 #include "coretypes.h"
 #include "errors.h"
+#include "tm.h"
+#include "rtl.h"
+#include "output.h"
 
 #include "dbgcnt.h"
 
@@ -58,6 +61,9 @@ bool
 dbg_cnt (enum debug_counter index)
 {
   count[index]++;
+  if (dump_file && count[index] == limit[index])
+    fprintf (dump_file, "***dbgcnt: limit reached for %s.***\n", map[index].name);
+
   return dbg_cnt_is_enabled (index);
 }
 
@@ -132,7 +138,8 @@ dbg_cnt_process_opt (const char *arg)
 
 /* Print name, limit and count of all counters.   */
 
-void dbg_cnt_list_all_counters (void)
+void 
+dbg_cnt_list_all_counters (void)
 {
   int i;
   printf ("  %-30s %-5s %-5s\n", "counter name",  "limit", "value");
Index: df.h
===================================================================
--- df.h	(revision 133349)
+++ df.h	(working copy)
@@ -398,6 +398,7 @@ struct df_ref_extract
   struct df_ref ref;
   int width;
   int offset;
+  enum machine_mode mode;
 };
 
 /* These links are used for two purposes:
@@ -619,8 +620,9 @@ struct df
 #define DF_REF_PREV_REG(REF) ((REF)->prev_reg)
 /* The following two macros may only be applied if one of 
    DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT is true. */ 
-#define DF_REF_WIDTH(REF) (((struct df_ref_extract *)(REF))->width)
-#define DF_REF_OFFSET(REF) (((struct df_ref_extract *)(REF))->offset)
+#define DF_REF_EXTRACT_WIDTH(REF) (((struct df_ref_extract *)(REF))->width)
+#define DF_REF_EXTRACT_OFFSET(REF) (((struct df_ref_extract *)(REF))->offset)
+#define DF_REF_EXTRACT_MODE(REF) (((struct df_ref_extract *)(REF))->mode)
 /* Macros to determine the reference type.  */
 
 #define DF_REF_REG_DEF_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_DEF)
@@ -885,7 +887,7 @@ extern void df_grow_insn_info (void);
 extern void df_scan_blocks (void);
 extern struct df_ref *df_ref_create (rtx, rtx *, rtx,basic_block, 
 				     enum df_ref_type, enum df_ref_flags,
-				     int, int);
+				     int, int, enum machine_mode);
 extern void df_ref_remove (struct df_ref *);
 extern struct df_insn_info * df_insn_create_insn_record (rtx);
 extern void df_insn_delete (basic_block, unsigned int);
@@ -911,6 +913,9 @@ extern void df_compute_regs_ever_live (b
 extern bool df_read_modify_subreg_p (rtx);
 extern void df_scan_verify (void);
 
+/* Functions defined in df-byte-scan.c.  */
+extern bool df_compute_accessed_bytes (struct df_ref *, unsigned int *, unsigned int *);
+
 
 /* Get basic block info.  */
 
Index: ra.h
===================================================================
--- ra.h	(revision 133349)
+++ ra.h	(working copy)
@@ -225,7 +225,7 @@ extern void global_conflicts (void);
 	 !adjacency_iter_done (&(ITER));				\
 	 (OUT_ALLOCNO) = adjacency_iter_next (&(ITER)))
 
-extern void ra_init_live_subregs (bool, sbitmap *, int *, int, rtx);
+extern void ra_init_live_subregs (bool, sbitmap *, bitmap, int, rtx);
 extern bool conflict_p (int, int);
 
 #endif /* GCC_RA_H */
Index: df-byte-scan.c
===================================================================
--- df-byte-scan.c	(revision 0)
+++ df-byte-scan.c	(revision 0)
@@ -0,0 +1,265 @@
+/* Scanning of rtl byte level scanning for dataflow analysis.
+   Copyright (C) 2008  Free Software Foundation, Inc.
+   Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "df.h"
+#include "output.h"
+#include "dbgcnt.h"
+
+/* The following suite of functions provides bytewise modeling of REFs
+   which are struct df_ref.  START_BYTE and LAST_BYTE are returned.
+   These can be used as indexes into bitmaps.  The indexes are
+   normalized so that 0 is the lowest numbered byte, of the inner
+   register according to the natural ordering of the machine.
+
+   It is important that if this code is called in a backwards scan
+   (which is, of course, the way all dataflow scanning should really
+   be done) that it not be called with the uses that set the
+   DF_REF_READ_WRITE flag except for DF_REF_PRE_POST_MODIFY uses
+   (because the fabricated uses really is necessary).  These uses are
+   there only to force the whole register alive if part of it is
+   written.  That will defeat the entire purpose of byte-wise modeling
+   of the insns.  */
+
+
+/* Helper for COMPUTE_ACCESSED_BYTES.  Ref is some sort of extract.
+   Return true if this effects the entire reg in REF. Return false if
+   otherwise and set START_BYTE and LAST_BYTE.  */ 
+
+static bool 
+df_compute_accessed_bytes_extract (struct df_ref *ref, unsigned int *start_byte, 
+				   unsigned int *last_byte)
+{
+  int start;
+  int last;
+  rtx reg = DF_REF_REG (ref);
+  enum machine_mode m1;
+  int m1_size;
+  enum machine_mode m2;
+  int m2_size;
+
+  /*  (*_extract:M1 (reg:M2 X) WIDTH POS)
+      (*_extract:M1 (subreg:M1 (reg:M2 X N) WIDTH POS)
+      
+      This is a bitfield extraction.  The assignment clobbers/extracts
+      exactly the bits named by WIDTH and POS and does not affect the
+      other bits in register X.  It is also technically possible that
+      the bits asked for are longer than units per word.  */
+  
+  int offset = DF_REF_EXTRACT_OFFSET (ref);
+  int width = DF_REF_EXTRACT_WIDTH (ref);
+
+  if (width == -1 || offset == -1)
+    return true;
+
+  m1 = DF_REF_EXTRACT_MODE (ref);
+  m1_size = GET_MODE_SIZE (m1);
+
+  gcc_assert (m1_size <= UNITS_PER_WORD);
+
+  /* There is nothing to do if this is a pure big or small endian
+     machine, but if the machine is a pastiche, we have to convert the
+     bit offsets into byte offsets.  This is only possible because we
+     do not care about individual bits because this conversion may
+     make the bits non-contiguous.  */
+  if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
+    offset = GET_MODE_BITSIZE (m1_size) - (offset + width);
+
+  /* The offset is now in the same order as the subreg_byte.  */
+  if (GET_CODE (reg) == SUBREG)
+    {
+      m2 = GET_MODE (SUBREG_REG (reg));
+      m2_size = GET_MODE_SIZE (m2);
+      if (m1_size > m2_size)
+	/* If it is paradoxical, subreg_byte will be zero.  */
+	offset -= subreg_lowpart_offset (m2, m1);
+      else
+	offset += SUBREG_BYTE (reg) * BITS_PER_UNIT;
+    }
+  else
+    {
+      m2 = GET_MODE (reg);
+      m2_size = GET_MODE_SIZE (m2);
+    }
+
+  start = offset / BITS_PER_UNIT;
+  last = (width + offset + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+  
+  /* Paradoxical truncation.  */
+  if  (start < 0)
+    start = 0;
+  if (last >= m2_size)
+    last = m2_size - 1;
+
+  if (dump_file)
+    fprintf (dump_file, "    cpb extract start=%d last=%d\n", start, last);
+  
+  *start_byte = start;
+  *last_byte = last;
+  return false;
+}
+
+
+/* Helper for COMPUTE_ACCESSED_BYTES.  Ref is a strict_low_part.  Return
+   true if this effects the entire reg in REF. Return false if
+   otherwise and set START_BYTE and LAST_BYTE.  */ 
+
+static bool 
+df_compute_accessed_bytes_strict_low_part (struct df_ref *ref, unsigned int *start_byte, 
+					   unsigned int *last_byte)
+{
+  int start;
+  int last;
+  rtx reg = DF_REF_REG (ref);
+  enum machine_mode m1 = GET_MODE (reg);
+  int m1_size = GET_MODE_SIZE (m1);
+  enum machine_mode m2 = GET_MODE (SUBREG_REG (reg));
+  int m2_size = GET_MODE_SIZE (m2);
+  int offset = SUBREG_BYTE (reg);
+
+  /* It does not seem to be meaningful to apply a strict_low_part of a
+     paradoxical register.  */
+  gcc_assert (m1_size <= m2_size);
+
+  /*  (set (strict_low_part (subreg:M1 (reg:M2 X) N)) ...)
+      
+  This is a bitfield insertion.  The assignment clobbers exactly the
+  bits named by the subreg--the M1 bits at position N.  It is also
+  technically possible that the bits asked for are longer than units
+  per word.  */
+  
+  start = offset;
+  last = offset + m1_size;
+
+  if (dump_file)
+    fprintf (dump_file, "    cpb strict low part start=%d last=%d\n", start, last);
+
+  *start_byte = start;
+  *last_byte = last;
+  return false;
+}
+
+/* Helper for COMPUTE_ACCESSED_BYTES.  Ref is a naked subreg.  Return
+   true if this effects the entire reg in REF. Return false if
+   otherwise and set START_BYTE and LAST_BYTE.  */ 
+
+static bool 
+df_compute_accessed_bytes_subreg (struct df_ref *ref, unsigned int *start_byte, 
+				  unsigned int *last_byte)
+
+{
+  /* (subreg:M1 (reg:M2 X) N) */
+  int start;
+  int last;
+  rtx reg = DF_REF_REG (ref);
+  enum machine_mode m1 = GET_MODE (reg);
+  int m1_size = GET_MODE_SIZE (m1);
+  enum machine_mode m2 = GET_MODE (SUBREG_REG (reg));
+  int m2_size = GET_MODE_SIZE (m2);
+
+  /* A simple paradoxical subreg just accesses the entire inner reg.  */
+  if (m1_size >= m2_size)
+    return true;
+
+  /* Defs and uses are different in the amount of the reg that touch.  */
+  if (DF_REF_TYPE (ref) == DF_REF_REG_DEF)
+    {
+      /* This is an lvalue.  */ 
+
+      if (m2_size > UNITS_PER_WORD)
+	{
+	  /* The assignment clobbers UNITS_PER_WORD segments of X.
+	     Look at the bytes named by the subreg, and expand it to
+	     cover a UNITS_PER_WORD part of register X.  That part of
+	     register X is clobbered, the rest is not.
+	     
+	     E.g., (subreg:SI (reg:DI X) 0), where UNITS_PER_WORD is the
+	     size of SImode, clobbers the first SImode part of X, and does
+	     not affect the second SImode part.
+	     
+	     E.g., (subreg:QI (reg:DI X) 0), where UNITS_PER_WORD is the
+	     size of SImode, clobbers the first SImode part of X, and does
+	     not affect the second SImode part.  Here the QImode byte is
+	     expanded to a UNITS_PER_WORD portion of the register for
+	     purposes of determining what is clobbered.
+	     
+	     If this is an rvalue, then it touches just the bytes that it
+	     talks about.  */
+	  int offset = SUBREG_BYTE (reg);
+	  
+	  start = offset & ~(UNITS_PER_WORD - 1);
+	  last = (offset + m1_size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
+	}
+      else
+	/* Whole register size M2 equal to or smaller than
+	   UNITS_PER_WORD The assignment clobbers the entire register
+	   X.  */
+	return true;
+    }
+  else 
+    {
+      /* This is an rvalue. It touches just the bytes they explicitly
+	 mentioned.  */
+      int offset = SUBREG_BYTE (reg);
+      start = offset;
+      last = start + m1_size;
+    }
+  
+  if (dump_file)
+    fprintf (dump_file, "    cpb subreg start=%d last=%d\n", start, last);
+
+  *start_byte = start;
+  *last_byte = last;
+  return false;
+}
+
+
+/* Compute the set of affected bytes by a store to a psuedo to REF.
+   If the store is to the whole register, just return TRUE, if it is
+   to part of the register, return FALSE and set START_BYTE and
+   LAST_BYTE properly.  */
+
+bool 
+df_compute_accessed_bytes (struct df_ref *ref, unsigned int *start_byte, 
+		      unsigned int *last_byte)
+{
+  if (!dbg_cnt (df_byte_scan))
+    return true;
+
+  /* See the comment at the top.  */
+  if (DF_REF_TYPE (ref) != DF_REF_REG_DEF
+      && DF_REF_FLAGS_IS_SET (ref, DF_REF_READ_WRITE))
+    return true;
+
+  if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
+    return df_compute_accessed_bytes_extract (ref, start_byte, last_byte);
+  else if (DF_REF_FLAGS_IS_SET (ref, DF_REF_STRICT_LOW_PART))
+    return df_compute_accessed_bytes_strict_low_part (ref, 
+						      start_byte, last_byte);
+  else if (GET_CODE (DF_REF_REG (ref)) == SUBREG)
+    return df_compute_accessed_bytes_subreg (ref, start_byte, last_byte);
+  return true;
+}
+
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 133349)
+++ Makefile.in	(working copy)
@@ -807,7 +807,7 @@ IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CG
 IPA_REFERENCE_H = ipa-reference.h bitmap.h $(TREE_H)
 IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H)
 CGRAPH_H = cgraph.h $(TREE_H)
-DF_H = df.h bitmap.h $(BASIC_BLOCK_H) alloc-pool.h
+DF_H = df.h bitmap.h $(BASIC_BLOCK_H) alloc-pool.h 
 RESOURCE_H = resource.h hard-reg-set.h $(DF_H)
 DDG_H = ddg.h sbitmap.h $(DF_H)
 GCC_H = gcc.h version.h
@@ -1035,6 +1035,7 @@ OBJS-common = \
 	dce.o \
 	ddg.o \
 	debug.o \
+	df-byte-scan.o \
 	df-core.o \
 	df-problems.o \
 	df-scan.o \
@@ -2617,6 +2618,8 @@ df-scan.o : df-scan.c $(CONFIG_H) $(SYST
    insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
    hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \
    $(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h tree-pass.h
+df-byte-scan.o : df-byte-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+   $(DF_H) output.h $(DBGCNT_H)
 regstat.o : regstat.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TM_P_H) $(FLAGS_H) $(REGS_H) output.h except.h hard-reg-set.h \
    $(BASIC_BLOCK_H) $(TIMEVAR_H) $(DF_H)
@@ -2729,7 +2732,7 @@ global.o : global.c $(CONFIG_H) $(SYSTEM
 ra-conflict.o : ra-conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
    insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
-   $(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h 
+   $(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h
 varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
    $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h
 vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \
@@ -2882,7 +2885,8 @@ hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H)
 pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H) \
    $(TREE_H)
 errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h $(BCONFIG_H)
-dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DBGCNT_H)
+dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DBGCNT_H) $(TM_H) \
+   $(RTL_H) output.h
 lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(MACHMODE_H) $(TM_H) $(RTL_H) $(TM_P_H) $(TIMEVAR_H) $(FLAGS_H) \
    insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) bitmap.h \

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-03-20  1:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-20  1:18 [trunk] Patch to properly model extracts and strict_low_part Kenneth Zadeck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).