OSDN Git Service

* df.h (struct df_ref): Replace 'insn' field with 'insn_info' field.
[pf3gnuchains/gcc-fork.git] / gcc / df.h
index d5c8d7e..30e9850 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -1,6 +1,6 @@
 /* Form lists of pseudo register references for autoinc optimization
    for GNU compiler.  This is part of flow optimization.
-   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Originally contributed by Michael P. Hayes 
              (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
@@ -36,19 +36,19 @@ struct df_problem;
 struct df_link;
 
 /* Data flow problems.  All problems must have a unique id here.  */ 
+
 /* Scanning is not really a dataflow problem, but it is useful to have
    the basic block functions in the vector so that things get done in
-   a uniform manner.  The first four problems are always defined.  The
-   last 5 are optional and can be added or deleted at any time.  */
-#define DF_SCAN  0 
-#define DF_LR    1      /* Live Registers backward. */
-#define DF_LIVE  2      /* Live Registers & Uninitialized Registers */
-
-#define DF_RU    3      /* Reaching Uses. */
-#define DF_RD    4      /* Reaching Defs. */
-#define DF_UREC  5      /* Uninitialized Registers with Early Clobber. */
-#define DF_CHAIN 6      /* Def-Use and/or Use-Def Chains. */
-#define DF_NOTE  7      /* REG_DEF and REG_UNUSED notes. */
+   a uniform manner.  The last four problems can be added or deleted
+   at any time are always defined (though LIVE is always there at -O2
+   or higher); the others are always there.  */
+#define DF_SCAN    0 
+#define DF_LR      1      /* Live Registers backward. */
+#define DF_LIVE    2      /* Live Registers & Uninitialized Registers */
+#define DF_RD      3      /* Reaching Defs. */
+#define DF_CHAIN   4      /* Def-Use and/or Use-Def Chains. */
+#define DF_BYTE_LR 5      /* Subreg tracking lr.  */
+#define DF_NOTE    6      /* REG_DEF and REG_UNUSED notes. */
 
 #define DF_LAST_PROBLEM_PLUS1 (DF_NOTE + 1)
 
@@ -60,6 +60,13 @@ enum df_flow_dir
     DF_BACKWARD
   };
 
+/* Used in the byte scanning to determine if may or must info is to be
+   returned.  */
+enum df_mm
+  {
+    DF_MM_MAY,
+    DF_MM_MUST
+  };
 
 /* 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
@@ -71,10 +78,9 @@ enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
 
 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 << 0,
+    /* This flag is set if this ref occurs inside of a conditional
+       execution instruction.  */
+    DF_REF_CONDITIONAL = 1 << 0,
 
     /* 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
@@ -86,14 +92,26 @@ enum df_ref_flags
        note.  */
     DF_REF_IN_NOTE = 1 << 2,
 
+    /* This bit is true if this ref can make regs_ever_live true for
+       this regno.  */
+    DF_HARD_REG_LIVE = 1 << 3,
+
+
+    /* This flag is set if this ref is a partial use or def of the
+       associated register.  */
+    DF_REF_PARTIAL = 1 << 4,
+    
+    /* 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 << 5,
+
     /* 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 = 1 << 3,
-
-
+    DF_REF_MAY_CLOBBER = 1 << 6,
 
     /* This flag is set if this ref, generally a def, is a real
        clobber. This is not currently set for registers live across a
@@ -104,34 +122,39 @@ enum df_ref_flags
        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 = 1 << 4,
+    DF_REF_MUST_CLOBBER = 1 << 7,
 
-    /* This bit is true if this ref is part of a multiword hardreg.  */
-    DF_REF_MW_HARDREG = 1 << 5,
 
-    /* This flag is set if this ref is a partial use or def of the
-       associated register.  */
-    DF_REF_PARTIAL = 1 << 6,
-    
-    /* This flag is set if this ref occurs inside of a conditional
-       execution instruction.  */
-    DF_REF_CONDITIONAL = 1 << 7,
+    /* If the ref has one of the following two flags set, then the
+       struct df_ref can be cast to struct df_ref_extract to access
+       the width and offset fields.  */
+    /* This flag is set if the ref contains a SIGN_EXTRACT.  */
+    DF_REF_SIGN_EXTRACT = 1 << 8,
 
+    /* This flag is set if the ref contains a ZERO_EXTRACT.  */
+    DF_REF_ZERO_EXTRACT = 1 << 9,
 
+    /* This flag is set if the ref contains a STRICT_LOW_PART.  */
+    DF_REF_STRICT_LOW_PART = 1 << 10,
 
-    /* This flag is set if this ref is inside a pre/post modify.  */
-    DF_REF_PRE_POST_MODIFY = 1 << 8,
+    /* This flag is set if the ref contains a SUBREG.  */
+    DF_REF_SUBREG = 1 << 11,
+
+
+    /* This bit is true if this ref is part of a multiword hardreg.  */
+    DF_REF_MW_HARDREG = 1 << 12,
 
     /* This flag is set if this ref is a usage of the stack pointer by
        a function call.  */
-    DF_REF_CALL_STACK_USAGE = 1 << 9,
+    DF_REF_CALL_STACK_USAGE = 1 << 13,
 
     /* This flag is used for verification of existing refs. */
-    DF_REF_REG_MARKER = 1 << 10,
+    DF_REF_REG_MARKER = 1 << 14,
+
+    /* This flag is set if this ref is inside a pre/post modify.  */
+    DF_REF_PRE_POST_MODIFY = 1 << 15
 
-    /* This bit is true if this ref can make regs_ever_live true for
-       this regno.  */
-    DF_HARD_REG_LIVE = 1 << 11
   };
 
 /* The possible ordering of refs within the df_ref_info.  */
@@ -347,9 +370,10 @@ struct df_ref
   rtx reg;                     /* The register referenced.  */
   basic_block bb;               /* Basic block containing the instruction. */
 
-  /* Insn containing ref. This will be null if this is an artificial
-     reference.  */
-  rtx insn;
+  /* Insn info for the insn containing ref. This will be null if this is
+     an artificial reference.  */
+  struct df_insn_info *insn_info;
+
   rtx *loc;                    /* The location of the reg.  */
   struct df_link *chain;       /* Head of def-use, use-def.  */
   /* Location in the ref table.  This is only valid after a call to 
@@ -374,9 +398,20 @@ struct df_ref
   struct df_ref *prev_reg;     /* Prev ref with same regno and type.  */
 };
 
-/* These links are used for two purposes:
-   1) def-use or use-def chains. 
-   2) Multiword hard registers that underly a single hardware register.  */
+/* A df_ref_extract is just a df_ref with a width and offset field at
+   the end of it.  It is used to hold this information if the ref was
+   wrapped by a SIGN_EXTRACT or a ZERO_EXTRACT and to pass this info
+   to passes that wish to process partial regs precisely.  */
+struct df_ref_extract
+{
+  struct df_ref ref;
+  int width;
+  int offset;
+  enum machine_mode mode;
+};
+
+/* These links are used for ref-ref chains.  Currently only DEF-USE and
+   USE-DEF chains can be built by DF.  */
 struct df_link
 {
   struct df_ref *ref;
@@ -395,20 +430,23 @@ enum df_changeable_flags
 {
   /* Scanning flags.  */
   /* Flag to control the running of dce as a side effect of building LR.  */
-  DF_LR_RUN_DCE           =  1, /* Run DCE.  */
-  DF_NO_HARD_REGS         =  2, /* Skip hard registers in RD and CHAIN Building.  */
-  DF_EQ_NOTES             =  4, /* Build chains with uses present in EQUIV/EQUAL notes. */
-  DF_NO_REGS_EVER_LIVE    =  8, /* Do not compute the regs_ever_live.  */
+  DF_LR_RUN_DCE           = 1 << 0, /* Run DCE.  */
+  DF_NO_HARD_REGS         = 1 << 1, /* Skip hard registers in RD and CHAIN Building.  */
+
+  DF_EQ_NOTES             = 1 << 2, /* Build chains with uses present in EQUIV/EQUAL notes. */
+  DF_NO_REGS_EVER_LIVE    = 1 << 3, /* Do not compute the regs_ever_live.  */
 
   /* Cause df_insn_rescan df_notes_rescan and df_insn_delete, to
   return immediately.  This is used by passes that know how to update
   the scanning them selves.  */
-  DF_NO_INSN_RESCAN       = 16,
+  DF_NO_INSN_RESCAN       = 1 << 4,
 
   /* Cause df_insn_rescan df_notes_rescan and df_insn_delete, to
   return after marking the insn for later processing.  This allows all
   rescans to be batched.  */
-  DF_DEFER_INSN_RESCAN    = 32
+  DF_DEFER_INSN_RESCAN    = 1 << 5,
+
+  DF_VERIFY_SCHEDULED     = 1 << 6
 };
 
 /* Two of these structures are inline in df, one for the uses and one
@@ -541,30 +579,28 @@ struct df
 };
 
 #define DF_SCAN_BB_INFO(BB) (df_scan_get_bb_info((BB)->index))
-#define DF_RU_BB_INFO(BB) (df_ru_get_bb_info((BB)->index))
 #define DF_RD_BB_INFO(BB) (df_rd_get_bb_info((BB)->index))
 #define DF_LR_BB_INFO(BB) (df_lr_get_bb_info((BB)->index))
-#define DF_UREC_BB_INFO(BB) (df_urec_get_bb_info((BB)->index))
 #define DF_LIVE_BB_INFO(BB) (df_live_get_bb_info((BB)->index))
+#define DF_BYTE_LR_BB_INFO(BB) (df_byte_lr_get_bb_info((BB)->index))
 
 /* Most transformations that wish to use live register analysis will
    use these macros.  This info is the and of the lr and live sets.  */
 #define DF_LIVE_IN(BB) (DF_LIVE_BB_INFO(BB)->in) 
 #define DF_LIVE_OUT(BB) (DF_LIVE_BB_INFO(BB)->out) 
 
-
-/* Live in for register allocation also takes into account several other factors.  */
-#define DF_RA_LIVE_IN(BB) (DF_UREC_BB_INFO(BB)->in) 
-#define DF_RA_LIVE_TOP(BB) (DF_UREC_BB_INFO(BB)->top) 
-#define DF_RA_LIVE_OUT(BB) (DF_UREC_BB_INFO(BB)->out) 
-
-/* These macros are currently used by only reg-stack since it is not
-   tolerant of uninitialized variables.  This intolerance should be
-   fixed because it causes other problems.  */ 
+/* These macros are used by passes that are not tolerant of
+   uninitialized variables.  This intolerance should eventually
+   be fixed.  */
 #define DF_LR_IN(BB) (DF_LR_BB_INFO(BB)->in) 
-#define DF_LR_TOP(BB) (DF_LR_BB_INFO(BB)->top) 
 #define DF_LR_OUT(BB) (DF_LR_BB_INFO(BB)->out) 
 
+/* These macros are used by passes that are not tolerant of
+   uninitialized variables.  This intolerance should eventually
+   be fixed.  */
+#define DF_BYTE_LR_IN(BB) (DF_BYTE_LR_BB_INFO(BB)->in) 
+#define DF_BYTE_LR_OUT(BB) (DF_BYTE_LR_BB_INFO(BB)->out) 
+
 /* Macros to access the elements within the ref structure.  */
 
 
@@ -577,8 +613,9 @@ struct df
 #define DF_REF_LOC(REF) ((REF)->loc)
 #define DF_REF_BB(REF) ((REF)->bb)
 #define DF_REF_BBNO(REF) (DF_REF_BB (REF)->index)
-#define DF_REF_INSN(REF) ((REF)->insn)
-#define DF_REF_INSN_UID(REF) (INSN_UID ((REF)->insn))
+#define DF_REF_INSN_INFO(REF) ((REF)->insn_info)
+#define DF_REF_INSN(REF) ((REF)->insn_info->insn)
+#define DF_REF_INSN_UID(REF) (INSN_UID (DF_REF_INSN(REF)))
 #define DF_REF_TYPE(REF) ((REF)->type)
 #define DF_REF_CHAIN(REF) ((REF)->chain)
 #define DF_REF_ID(REF) ((REF)->id)
@@ -591,13 +628,17 @@ struct df
    but an artificial one created to model 
    always live registers, eh uses, etc.  
    ARTIFICIAL refs has NULL insn.  */
-#define DF_REF_IS_ARTIFICIAL(REF) ((REF)->insn == NULL)
+#define DF_REF_IS_ARTIFICIAL(REF) ((REF)->insn_info == NULL)
 #define DF_REF_REG_MARK(REF) (DF_REF_FLAGS_SET ((REF),DF_REF_REG_MARKER))
 #define DF_REF_REG_UNMARK(REF) (DF_REF_FLAGS_CLEAR ((REF),DF_REF_REG_MARKER))
 #define DF_REF_IS_REG_MARKED(REF) (DF_REF_FLAGS_IS_SET ((REF),DF_REF_REG_MARKER))
 #define DF_REF_NEXT_REG(REF) ((REF)->next_reg)
 #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_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)
@@ -652,12 +693,17 @@ struct df
 /* Macros to access the elements within the insn_info structure table.  */
 
 #define DF_INSN_SIZE() ((df)->insns_size)
-#define DF_INSN_GET(INSN) (df->insns[(INSN_UID(INSN))])
-#define DF_INSN_SET(INSN,VAL) (df->insns[(INSN_UID (INSN))]=(VAL))
-#define DF_INSN_LUID(INSN) (DF_INSN_GET(INSN)->luid)
-#define DF_INSN_DEFS(INSN) (DF_INSN_GET(INSN)->defs)
-#define DF_INSN_USES(INSN) (DF_INSN_GET(INSN)->uses)
-#define DF_INSN_EQ_USES(INSN) (DF_INSN_GET(INSN)->eq_uses)
+#define DF_INSN_INFO_GET(INSN) (df->insns[(INSN_UID(INSN))])
+#define DF_INSN_INFO_SET(INSN,VAL) (df->insns[(INSN_UID (INSN))]=(VAL))
+#define DF_INSN_INFO_LUID(II) ((II)->luid)
+#define DF_INSN_INFO_DEFS(II) ((II)->defs)
+#define DF_INSN_INFO_USES(II) ((II)->uses)
+#define DF_INSN_INFO_EQ_USES(II) ((II)->eq_uses)
+
+#define DF_INSN_LUID(INSN) (DF_INSN_INFO_LUID (DF_INSN_INFO_GET(INSN)))
+#define DF_INSN_DEFS(INSN) (DF_INSN_INFO_DEFS (DF_INSN_INFO_GET(INSN)))
+#define DF_INSN_USES(INSN) (DF_INSN_INFO_USES (DF_INSN_INFO_GET(INSN)))
+#define DF_INSN_EQ_USES(INSN) (DF_INSN_INFO_EQ_USES (DF_INSN_INFO_GET(INSN)))
 
 #define DF_INSN_UID_GET(UID) (df->insns[(UID)])
 #define DF_INSN_UID_SET(UID,VAL) (df->insns[(UID)]=(VAL))
@@ -685,45 +731,30 @@ extern bitmap df_invalidated_by_call;
 /* One of these structures is allocated for every basic block.  */
 struct df_scan_bb_info
 {
-  /* Defs at the start of a basic block that is the target of an
-     exception edge.  */
-  struct df_ref **artificial_defs;
+  /* The entry block has many artificial defs and these are at the
+     bottom of the block.
 
-  /* Uses of hard registers that are live at every block.  */
-  struct df_ref **artificial_uses;
-};
+     Blocks that are targets of exception edges may have some
+     artificial defs.  These are logically located at the top of the
+     block.
 
+     Blocks that are the targets of non-local goto's have the hard
+     frame pointer defined at the top of the block.  */
+  struct df_ref **artificial_defs;
 
-/* Reaching uses.  All bitmaps are indexed by the id field of the ref
-   except sparse_kill (see below).  */
-struct df_ru_bb_info 
-{
-  /* Local sets to describe the basic blocks.  */
-  /* The kill set is the set of uses that are killed in this block.
-     However, if the number of uses for this register is greater than
-     DF_SPARSE_THRESHOLD, the sparse_kill is used instead. In
-     sparse_kill, each register gets a slot and a 1 in this bitvector
-     means that all of the uses of that register are killed.  This is
-     a very useful efficiency hack in that it keeps from having push
-     around big groups of 1s.  This is implemented by the
-     bitmap_clear_range call.  */
-
-  bitmap kill;
-  bitmap sparse_kill;
-  bitmap gen;   /* The set of uses generated in this block.  */
+  /* Blocks that are targets of exception edges may have some
+     artificial uses.  These are logically at the top of the block.
 
-  /* The results of the dataflow problem.  */
-  bitmap in;    /* At the top of the block.  */
-  bitmap out;   /* At the bottom of the block.  */
+     Most blocks have artificial uses at the bottom of the block.  */
+  struct df_ref **artificial_uses;
 };
 
 
 /* Reaching definitions.  All bitmaps are indexed by the id field of
-   the ref except sparse_kill (see above).  */
+   the ref except sparse_kill which is indexed by regno.  */
 struct df_rd_bb_info 
 {
-  /* Local sets to describe the basic blocks.  See the note in the RU
-     datastructures for kill and sparse_kill.  */
+  /* Local sets to describe the basic blocks.   */
   bitmap kill;  
   bitmap sparse_kill;
   bitmap gen;   /* The set of defs generated in this block.  */
@@ -734,23 +765,8 @@ struct df_rd_bb_info
 };
 
 
-/* Live registers.  All bitmaps are referenced by the register number.  
-
-   df_lr_bb_info:IN is the "in" set of the traditional dataflow sense
-   which is the confluence of out sets of all predecessor blocks.
-   The difference between IN and TOP is 
-   due to the artificial defs and uses at the top (DF_REF_TOP)
-   (e.g. exception handling dispatch block, which can have
-   a few registers defined by the runtime) - which is NOT included
-   in the "in" set before this function but is included after.  
-   For the initial live set of forward scanning, TOP should be used
-   instead of IN - otherwise, artificial defs won't be in IN set
-   causing the bad transformation. TOP set can not simply be
-   the union of IN set and artificial defs at the top, 
-   because artificial defs might not be used at all,
-   in which case those defs are not live at any point
-   (except as a dangling def) - hence TOP has to be calculated
-   during the LR problem computation and stored in df_lr_bb_info.  */
+/* Live registers, a backwards dataflow problem.  All bitmaps are
+   referenced by the register number.  */
 
 struct df_lr_bb_info 
 {
@@ -758,12 +774,9 @@ struct df_lr_bb_info
   bitmap def;   /* The set of registers set in this block 
                    - except artificial defs at the top.  */
   bitmap use;   /* The set of registers used in this block.  */
-  bitmap adef;  /* The artificial defs at top. */
-  bitmap ause;  /* The artificial uses at top. */
 
   /* The results of the dataflow problem.  */
   bitmap in;    /* Just before the block itself. */
-  bitmap top;   /* Just before the first insn in the block. */
   bitmap out;   /* At the bottom of the block.  */
 };
 
@@ -785,19 +798,18 @@ struct df_live_bb_info
 };
 
 
-/* Uninitialized registers.  All bitmaps are referenced by the register number.  */
-struct df_urec_bb_info 
+/* Live registers, a backwards dataflow problem.  These bitmaps are
+indexed by the df_byte_lr_offset array which is indexed by pseudo.  */
+
+struct df_byte_lr_bb_info 
 {
   /* Local sets to describe the basic blocks.  */
-  bitmap earlyclobber;  /* The set of registers that are referenced
-                          with an early clobber mode.  */
-  /* Kill and gen are defined as in the UR problem.  */
-  bitmap kill;
-  bitmap gen;
+  bitmap def;   /* The set of registers set in this block 
+                   - except artificial defs at the top.  */
+  bitmap use;   /* The set of registers used in this block.  */
 
   /* The results of the dataflow problem.  */
-  bitmap in;    /* Just before the block.  */
-  bitmap top;   /* Just before the first insn in the block. */
+  bitmap in;    /* Just before the block itself. */
   bitmap out;   /* At the bottom of the block.  */
 };
 
@@ -806,14 +818,13 @@ struct df_urec_bb_info
    instance so that the df info can be added to the dumps.  This
    should not be used by regular code.  */ 
 extern struct df *df;
-#define df_scan  (df->problems_by_index[DF_SCAN])
-#define df_ru    (df->problems_by_index[DF_RU])
-#define df_rd    (df->problems_by_index[DF_RD])
-#define df_lr    (df->problems_by_index[DF_LR])
-#define df_live  (df->problems_by_index[DF_LIVE])
-#define df_urec  (df->problems_by_index[DF_UREC])
-#define df_chain (df->problems_by_index[DF_CHAIN])
-#define df_note  (df->problems_by_index[DF_NOTE])
+#define df_scan    (df->problems_by_index[DF_SCAN])
+#define df_rd      (df->problems_by_index[DF_RD])
+#define df_lr      (df->problems_by_index[DF_LR])
+#define df_live    (df->problems_by_index[DF_LIVE])
+#define df_chain   (df->problems_by_index[DF_CHAIN])
+#define df_byte_lr (df->problems_by_index[DF_BYTE_LR])
+#define df_note    (df->problems_by_index[DF_NOTE])
 
 /* This symbol turns on checking that each modification of the cfg has
   been identified to the appropriate df routines.  It is not part of
@@ -834,7 +845,7 @@ extern enum df_changeable_flags df_set_flags (enum df_changeable_flags);
 extern enum df_changeable_flags df_clear_flags (enum df_changeable_flags);
 extern void df_set_blocks (bitmap);
 extern void df_remove_problem (struct dataflow *);
-extern void df_finish_pass (void);
+extern void df_finish_pass (bool);
 extern void df_analyze_problem (struct dataflow *, bitmap, int *, int);
 extern void df_analyze (void);
 extern int df_get_n_blocks (enum df_flow_dir);
@@ -860,7 +871,9 @@ extern struct df_ref *df_find_use (rtx, rtx);
 extern bool df_reg_used (rtx, rtx);
 extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int);
 extern void df_print_regset (FILE *file, bitmap r);
+extern void df_print_byte_regset (FILE *file, bitmap r);
 extern void df_dump (FILE *);
+extern void df_dump_region (FILE *);
 extern void df_dump_start (FILE *);
 extern void df_dump_top (basic_block, FILE *);
 extern void df_dump_bottom (basic_block, FILE *);
@@ -885,27 +898,30 @@ extern void df_chain_unlink (struct df_ref *);
 extern void df_chain_copy (struct df_ref *, struct df_link *);
 extern bitmap df_get_live_in (basic_block);
 extern bitmap df_get_live_out (basic_block);
-extern bitmap df_get_live_top (basic_block);
 extern void df_grow_bb_info (struct dataflow *);
 extern void df_chain_dump (struct df_link *, FILE *);
 extern void df_print_bb_index (basic_block bb, FILE *file);
-extern void df_ru_add_problem (void);
 extern void df_rd_add_problem (void);
 extern void df_lr_add_problem (void);
 extern void df_lr_verify_transfer_functions (void);
 extern void df_live_verify_transfer_functions (void);
 extern void df_live_add_problem (void);
 extern void df_live_set_all_dirty (void);
-extern void df_urec_add_problem (void);
 extern void df_chain_add_problem (enum df_chain_flags);
+extern void df_byte_lr_add_problem (void);
+extern int df_byte_lr_get_regno_start (unsigned int);
+extern int df_byte_lr_get_regno_len (unsigned int);
+extern void df_byte_lr_simulate_defs (rtx, bitmap);
+extern void df_byte_lr_simulate_uses (rtx, bitmap);
+extern void df_byte_lr_simulate_artificial_refs_at_top (basic_block, bitmap);
+extern void df_byte_lr_simulate_artificial_refs_at_end (basic_block, bitmap);
 extern void df_note_add_problem (void);
 extern void df_simulate_find_defs (rtx, bitmap);
 extern void df_simulate_defs (rtx, bitmap);
 extern void df_simulate_uses (rtx, bitmap);
-extern void df_simulate_artificial_refs_at_top (basic_block, bitmap);
-extern void df_simulate_one_insn_forwards (basic_block, rtx, bitmap);
 extern void df_simulate_artificial_refs_at_end (basic_block, bitmap);
-extern void df_simulate_one_insn_backwards (basic_block, rtx, bitmap);
+extern void df_simulate_one_insn (basic_block, rtx, bitmap);
+extern void df_simulate_artificial_refs_at_top (basic_block, bitmap);
 
 /* Functions defined in df-scan.c.  */
 
@@ -915,7 +931,8 @@ extern void df_grow_reg_info (void);
 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);
+                                    enum df_ref_type, enum df_ref_flags,
+                                    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);
@@ -923,9 +940,8 @@ extern void df_bb_refs_record (int, bool);
 extern bool df_insn_rescan (rtx);
 extern void df_insn_rescan_all (void);
 extern void df_process_deferred_rescans (void);
-extern bool df_has_eh_preds (basic_block);
 extern void df_recompute_luids (basic_block);
-extern void df_insn_change_bb (rtx);
+extern void df_insn_change_bb (rtx, basic_block);
 extern void df_maybe_reorganize_use_refs (enum df_ref_order);
 extern void df_maybe_reorganize_def_refs (enum df_ref_order);
 extern void df_ref_change_reg_with_loc (int, int, rtx);
@@ -942,6 +958,10 @@ extern void df_compute_regs_ever_live (bool);
 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 *, enum df_mm, 
+                                      unsigned int *, unsigned int *);
+
 
 /* Get basic block info.  */
 
@@ -954,15 +974,6 @@ df_scan_get_bb_info (unsigned int index)
     return NULL;
 }
 
-static inline struct df_ru_bb_info *
-df_ru_get_bb_info (unsigned int index)
-{
-  if (index < df_ru->block_info_size)
-    return (struct df_ru_bb_info *) df_ru->block_info[index];
-  else
-    return NULL;
-}
-
 static inline struct df_rd_bb_info *
 df_rd_get_bb_info (unsigned int index)
 {
@@ -990,16 +1001,15 @@ df_live_get_bb_info (unsigned int index)
     return NULL;
 }
 
-static inline struct df_urec_bb_info *
-df_urec_get_bb_info (unsigned int index)
+static inline struct df_byte_lr_bb_info *
+df_byte_lr_get_bb_info (unsigned int index)
 {
-  if (index < df_urec->block_info_size)
-    return (struct df_urec_bb_info *) df_urec->block_info[index];
+  if (index < df_byte_lr->block_info_size)
+    return (struct df_byte_lr_bb_info *) df_byte_lr->block_info[index];
   else
     return NULL;
 }
 
-
 /* Get the artificial defs for a basic block.  */
 
 static inline struct df_ref **