OSDN Git Service

add sparc64-*-solaris2 support just like sparcv9-*-solaris2
[pf3gnuchains/gcc-fork.git] / gcc / df.c
index 36ae66f..177da10 100644 (file)
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -3,22 +3,22 @@
    Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz,
                                     mhayes@redhat.com)
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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 2, or (at your option)
-any later version.
+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 2, or (at your option) any later
+version.
 
-GNU CC 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.
+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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
 
 
 OVERVIEW:
@@ -238,7 +238,8 @@ static void df_insn_refs_record PARAMS((struct df *, basic_block, rtx));
 static void df_bb_refs_record PARAMS((struct df *, basic_block));
 static void df_refs_record PARAMS((struct df *, bitmap));
 
-static int df_visit_next PARAMS ((struct df *, sbitmap));
+static int df_visit_next_rc PARAMS ((struct df *, sbitmap));
+static int df_visit_next_rts PARAMS ((struct df *, sbitmap));
 static void df_bb_reg_def_chain_create PARAMS((struct df *, basic_block));
 static void df_reg_def_chain_create PARAMS((struct df *, bitmap));
 static void df_bb_reg_use_chain_create PARAMS((struct df *, basic_block));
@@ -1163,6 +1164,7 @@ df_uses_record (df, loc, ref_type, bb, insn)
            for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
              df_uses_record (df, &ASM_OPERANDS_INPUT (x, j), 
                              DF_REF_REG_USE, bb, insn);
+           return;
          }
        break;
       }
@@ -1176,7 +1178,7 @@ df_uses_record (df, loc, ref_type, bb, insn)
       /* Catch the def of the register being modified.  */
       df_ref_record (df, XEXP (x, 0), &XEXP (x, 0), bb, insn, DF_REF_REG_DEF);
 
-      /* ... Fall through to handle uses ... */
+      /* ... Fall through to handle uses ...  */
 
     default:
       break;
@@ -1268,14 +1270,9 @@ df_insn_refs_record (df, bb, insn)
 
          if (df->flags & DF_HARD_REGS)
            {
-             /* Each call clobbers all call-clobbered regs that are not
-                global or fixed and have not been explicitly defined
-                in the call pattern.  */
+             /* Kill all registers invalidated by a call.  */
              for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-               if (call_used_regs[i] 
-                   && ! global_regs[i]
-                   && ! fixed_regs[i]
-                   && ! df_insn_regno_def_p (df, bb, insn, i))
+               if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
                  {
                    rtx reg_clob = df_reg_clobber_gen (i);
                    df_defs_record (df, reg_clob, bb, insn);
@@ -1604,11 +1601,11 @@ df_ud_chain_create (df, blocks)
 }
 \f
 
-/* Use depth first order, and the worklist, to figure out what block
-   to look at next. */
+/* Use reverse completion order, and the worklist, to figure out what block
+   to look at next.  */
 
 static int
-df_visit_next (df, blocks)
+df_visit_next_rc (df, blocks)
      struct df *df ATTRIBUTE_UNUSED;
      sbitmap blocks;
 {
@@ -1619,6 +1616,22 @@ df_visit_next (df, blocks)
   return sbitmap_first_set_bit (blocks);
 }
 
+/* Use reverse topsort order, and the worklist, to figure out what block
+   to look at next.  */
+
+static int
+df_visit_next_rts (df, blocks)
+     struct df *df ATTRIBUTE_UNUSED;
+     sbitmap blocks;
+{
+  int i=0;
+  for (i = 0; i < n_basic_blocks; i++)
+    if (TEST_BIT (blocks, df->rts_order[i]))
+      return df->rts_order[i];
+  return sbitmap_first_set_bit (blocks);
+}
+
+
 /* Calculate reaching defs for each basic block in BLOCKS, i.e., the
    defs that are live at the start of a basic block.  */
 static void
@@ -1648,7 +1661,7 @@ df_rd_global_compute (df, blocks)
       bitmap_copy (bb_info->rd_out, bb_info->rd_gen);
     });
   
-  while ((i = df_visit_next (df, worklist)) >= 0)
+  while ((i = df_visit_next_rc (df, worklist)) >= 0)
     {
       struct bb_info *bb_info;
       edge e;
@@ -1689,7 +1702,7 @@ df_rd_global_compute (df, blocks)
              if (e->dest == EXIT_BLOCK_PTR)
                continue;
              
-             SET_BIT (worklist, i);
+             SET_BIT (worklist, e->dest->index);
            }
        }
     }
@@ -1726,7 +1739,7 @@ df_ru_global_compute (df, blocks)
     });
 
 
-  while ((i = df_visit_next (df, worklist)) >= 0)
+  while ((i = df_visit_next_rts (df, worklist)) >= 0)
     {
       struct bb_info *bb_info;
       edge e;
@@ -1766,7 +1779,7 @@ df_ru_global_compute (df, blocks)
              if (e->src == ENTRY_BLOCK_PTR)
                continue;
 
-             SET_BIT (worklist, i);          
+             SET_BIT (worklist, e->src->index);              
            }
        }
     }
@@ -2225,9 +2238,10 @@ df_analyse_1 (df, blocks, flags, update)
 
   df->dfs_order = xmalloc (sizeof(int) * n_basic_blocks);
   df->rc_order = xmalloc (sizeof(int) * n_basic_blocks);
+  df->rts_order = xmalloc (sizeof(int) * n_basic_blocks);
   
   flow_depth_first_order_compute (df->dfs_order, df->rc_order);
-
+  flow_reverse_top_sort_order_compute (df->rts_order);
   if (aflags & DF_RD)
     {
       /* Compute the sets of gens and kills for the defs of each bb.  */
@@ -2284,6 +2298,7 @@ df_analyse_1 (df, blocks, flags, update)
     } 
   free (df->dfs_order);
   free (df->rc_order);
+  free (df->rts_order);
 }
 
 
@@ -2606,6 +2621,9 @@ df_insn_modify (df, bb, insn)
 
   uid = INSN_UID (insn);
 
+  if (uid >= df->insn_size)
+    df_insn_table_realloc (df, 0);
+
   bitmap_set_bit (df->bbs_modified, bb->index);
   bitmap_set_bit (df->insns_modified, uid);
 
@@ -2887,7 +2905,7 @@ df_insns_modify (df, bb, first_insn, last_insn)
         it does, we need to create a new basic block.  Ouch.  The
         same applies for a label.  */
       if ((GET_CODE (insn) == CALL_INSN
-          && ! CONST_CALL_P (insn))
+          && ! CONST_OR_PURE_CALL_P (insn))
          || GET_CODE (insn) == CODE_LABEL)
        abort ();