OSDN Git Service

* df.c (df_insn_refs_record): Use XEXP to get the operand of a USE,
[pf3gnuchains/gcc-fork.git] / gcc / df.c
index dd3ab26..1fe44f2 100644 (file)
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -1,5 +1,5 @@
 /* Dataflow support routines.
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz,
                                     mhayes@redhat.com)
@@ -107,8 +107,8 @@ These are linked into a variety of lists; namely reg-def, reg-use,
 the reg-def lists contain all the refs that define a given register
 while the insn-use lists contain all the refs used by an insn.
 
-Note that the reg-def and reg-use chains are generally short (except for the
-hard registers) and thus it is much faster to search these chains
+Note that the reg-def and reg-use chains are generally short (except for
+the hard registers) and thus it is much faster to search these chains
 rather than searching the def or use bitmaps.
 
 If the insns are in SSA form then the reg-def and use-def lists
@@ -166,10 +166,13 @@ generates a use of reg 41 then a def of reg 41 (both marked read/write),
 even though reg 41 is decremented before it is used for the memory
 address in this second example.
 
-A set to a REG inside a ZERO_EXTRACT, SIGN_EXTRACT, or SUBREG invokes
-a read-modify write operation.  We generate both a use and a def
-and again mark them read/write.
-*/
+A set to a REG inside a ZERO_EXTRACT, or a set to a non-paradoxical SUBREG
+for which the number of word_mode units covered by the outer mode is
+smaller than that covered by the inner mode, invokes a read-modify-write.
+operation.  We generate both a use and a def and again mark them
+read/write.
+Paradoxical subreg writes don't leave a trace of the old content, so they
+are write-only operations.  */
 
 #include "config.h"
 #include "system.h"
@@ -580,12 +583,10 @@ df_free (struct df *df)
   df->regs = 0;
   df->reg_size = 0;
 
-  if (df->bbs_modified)
-    BITMAP_XFREE (df->bbs_modified);
+  BITMAP_XFREE (df->bbs_modified);
   df->bbs_modified = 0;
 
-  if (df->insns_modified)
-    BITMAP_XFREE (df->insns_modified);
+  BITMAP_XFREE (df->insns_modified);
   df->insns_modified = 0;
 
   BITMAP_XFREE (df->all_blocks);
@@ -860,8 +861,10 @@ df_ref_record (struct df *df, rtx reg, rtx *loc, rtx insn,
 }
 
 
-/* Return nonzero if writes to paradoxical SUBREGs, or SUBREGs which
-   are too narrow, are read-modify-write.  */
+/* A set to a non-paradoxical SUBREG for which the number of word_mode units
+   covered by the outer mode is smaller than that covered by the inner mode,
+   is a read-modify-write operation.
+   This function returns true iff the SUBREG X is such a SUBREG.  */
 bool
 read_modify_subreg_p (rtx x)
 {
@@ -870,7 +873,6 @@ read_modify_subreg_p (rtx x)
     return false;
   isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
   osize = GET_MODE_SIZE (GET_MODE (x));
-  /* Paradoxical subreg writes don't leave a trace of the old content.  */
   return (isize > osize && isize > UNITS_PER_WORD);
 }
 
@@ -911,9 +913,7 @@ df_def_record_1 (struct df *df, rtx x, basic_block bb, rtx insn)
      be handy for the reg allocator.  */
   while (GET_CODE (dst) == STRICT_LOW_PART
         || GET_CODE (dst) == ZERO_EXTRACT
-        || GET_CODE (dst) == SIGN_EXTRACT
-        || ((df->flags & DF_FOR_REGALLOC) == 0
-             && read_modify_subreg_p (dst)))
+        || read_modify_subreg_p (dst))
     {
       /* Strict low part always contains SUBREG, but we do not want to make
         it appear outside, as whole register is always considered.  */
@@ -1024,8 +1024,7 @@ df_uses_record (struct df *df, rtx *loc, enum df_ref_type ref_type,
        switch (GET_CODE (dst))
          {
            case SUBREG:
-             if ((df->flags & DF_FOR_REGALLOC) == 0
-                  && read_modify_subreg_p (dst))
+             if (read_modify_subreg_p (dst))
                {
                  df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
                                  insn, DF_REF_READ_WRITE);
@@ -1197,7 +1196,7 @@ df_insn_refs_record (struct df *df, basic_block bb, rtx insn)
                if (global_regs[i])
                  {
                    x = df_reg_use_gen (i);
-                   df_uses_record (df, &SET_DEST (x),
+                   df_uses_record (df, &XEXP (x, 0),
                                    DF_REF_REG_USE, bb, insn, 0);
                  }
            }
@@ -3723,10 +3722,13 @@ debug_df_chain (struct df_link *link)
 }
 \f
 
+/* Perform the set operation OP1 OP OP2, using set representation REPR, and
+   storing the result in OP1.  */
+
 static void
 dataflow_set_a_op_b (enum set_representation repr,
                     enum df_confluence_op op,
-                    void *rslt, void *op1, void *op2)
+                    void *op1, void *op2)
 {
   switch (repr)
     {
@@ -3734,11 +3736,11 @@ dataflow_set_a_op_b (enum set_representation repr,
       switch (op)
        {
        case DF_UNION:
-         sbitmap_a_or_b (rslt, op1, op2);
+         sbitmap_a_or_b (op1, op1, op2);
          break;
 
        case DF_INTERSECTION:
-         sbitmap_a_and_b (rslt, op1, op2);
+         sbitmap_a_and_b (op1, op1, op2);
          break;
 
        default:
@@ -3750,11 +3752,11 @@ dataflow_set_a_op_b (enum set_representation repr,
       switch (op)
        {
        case DF_UNION:
-         bitmap_ior (rslt, op1, op2);
+         bitmap_ior_into (op1, op2);
          break;
 
        case DF_INTERSECTION:
-         bitmap_and (rslt, op1, op2);
+         bitmap_and_into (op1, op2);
          break;
 
        default:
@@ -3815,7 +3817,7 @@ hybrid_search (basic_block bb, struct dataflow *dataflow,
            continue;                                                   \
                                                                        \
          dataflow_set_a_op_b (dataflow->repr, dataflow->conf_op,       \
-                              IN_SET[i], IN_SET[i],                    \
+                              IN_SET[i],                               \
                               OUT_SET[e->E_ANTI_BB->index]);           \
        }                                                               \
                                                                        \