df.c (df_reg_clobber_gen): Removed.
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Tue, 15 Jun 2004 22:15:21 +0000 (00:15 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Tue, 15 Jun 2004 22:15:21 +0000 (22:15 +0000)
* df.c (df_reg_clobber_gen): Removed.
(df_bb_rd_local_compute, df_insn_refs_record, df_rd_local_compute):
Make more effective for hard regs.
* ra-build.c (livethrough_conflicts_bb): Check contains_call.

From-SVN: r83204

gcc/ChangeLog
gcc/df.c
gcc/ra-build.c

index fdd411cd49150ef7593372f9efd1e28137d67321..83d64c54326d7bdff39692d5ba55feea83fcbdb7 100644 (file)
@@ -1,3 +1,10 @@
+2004-06-15  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+
+       * df.c (df_reg_clobber_gen): Removed.
+       (df_bb_rd_local_compute, df_insn_refs_record, df_rd_local_compute):
+       Make more effective for hard regs.
+       * ra-build.c (livethrough_conflicts_bb): Check contains_call.
+
 2004-06-15  Alexandre Oliva  <aoliva@redhat.com>
 
        * c-pragma.h (c_lex_string_translate): Change type to int.
index cd66fe3ba506eb851a385e4764578cea96edbe47..2fa65c351b427ea8138738e184c9a20ddf6183c5 100644 (file)
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -243,7 +243,7 @@ static void df_bb_du_chain_create (struct df *, basic_block, bitmap);
 static void df_du_chain_create (struct df *, bitmap);
 static void df_bb_ud_chain_create (struct df *, basic_block);
 static void df_ud_chain_create (struct df *, bitmap);
-static void df_bb_rd_local_compute (struct df *, basic_block);
+static void df_bb_rd_local_compute (struct df *, basic_block, bitmap);
 static void df_rd_local_compute (struct df *, bitmap);
 static void df_bb_ru_local_compute (struct df *, basic_block);
 static void df_ru_local_compute (struct df *, bitmap);
@@ -604,19 +604,6 @@ static rtx df_reg_use_gen (unsigned int regno)
   use = gen_rtx_USE (GET_MODE (reg), reg);
   return use;
 }
-
-
-/* Return a CLOBBER for register REGNO.  */
-static rtx df_reg_clobber_gen (unsigned int regno)
-{
-  rtx reg;
-  rtx use;
-
-  reg = regno_reg_rtx[regno];
-
-  use = gen_rtx_CLOBBER (GET_MODE (reg), reg);
-  return use;
-}
 \f
 /* Local chain manipulation routines.  */
 
@@ -1221,16 +1208,11 @@ df_insn_refs_record (struct df *df, basic_block bb, rtx insn)
        {
          rtx note;
 
-         if (df->flags & DF_HARD_REGS)
-           {
-             /* Kill all registers invalidated by a call.  */
-             for (i = 0; i < FIRST_PSEUDO_REGISTER; 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);
-                 }
-           }
+         /* We do not record hard registers clobbered by the call,
+            since there are awfully many of them and "defs" created
+            through them are not interesting (since no use can be legally
+            reached by them).  So we must just make sure we include them when
+            computing kill bitmaps.  */
 
          /* There may be extra registers to be clobbered.  */
          for (note = CALL_INSN_FUNCTION_USAGE (insn);
@@ -1629,13 +1611,14 @@ df_lr_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, void *in,
 
 /* Compute local reaching def info for basic block BB.  */
 static void
-df_bb_rd_local_compute (struct df *df, basic_block bb)
+df_bb_rd_local_compute (struct df *df, basic_block bb, bitmap call_killed_defs)
 {
   struct bb_info *bb_info = DF_BB_INFO (df, bb);
   rtx insn;
+  bitmap seen = BITMAP_XMALLOC ();
+  bool call_seen = false;
 
-  for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb));
-       insn = NEXT_INSN (insn))
+  FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
       struct df_link *def_link;
@@ -1649,6 +1632,12 @@ df_bb_rd_local_compute (struct df *df, basic_block bb)
          unsigned int regno = DF_REF_REGNO (def);
          struct df_link *def2_link;
 
+         if (bitmap_bit_p (seen, regno)
+             || (call_seen
+                 && regno < FIRST_PSEUDO_REGISTER
+                 && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)))
+           continue;
+
          for (def2_link = df->regs[regno].defs; def2_link;
               def2_link = def2_link->next)
            {
@@ -1659,16 +1648,21 @@ df_bb_rd_local_compute (struct df *df, basic_block bb)
                 be killed by this BB but it keeps things a lot
                 simpler.  */
              bitmap_set_bit (bb_info->rd_kill, DF_REF_ID (def2));
-
-             /* Zap from the set of gens for this BB.  */
-             bitmap_clear_bit (bb_info->rd_gen, DF_REF_ID (def2));
            }
 
          bitmap_set_bit (bb_info->rd_gen, DF_REF_ID (def));
+         bitmap_set_bit (seen, regno);
+       }
+
+      if (GET_CODE (insn) == CALL_INSN && (df->flags & DF_HARD_REGS))
+       {
+         bitmap_operation (bb_info->rd_kill, bb_info->rd_kill,
+                           call_killed_defs, BITMAP_IOR);
+         call_seen = 1;
        }
     }
 
-  bb_info->rd_valid = 1;
+  BITMAP_XFREE (seen);
 }
 
 
@@ -1677,11 +1671,32 @@ static void
 df_rd_local_compute (struct df *df, bitmap blocks)
 {
   basic_block bb;
+  bitmap killed_by_call = NULL;
+  unsigned regno;
+  struct df_link *def_link;
+
+  if (df->flags & DF_HARD_REGS)
+    {
+      killed_by_call = BITMAP_XMALLOC ();
+      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+       {
+         if (!TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+           continue;
+         
+         for (def_link = df->regs[regno].defs;
+              def_link;
+              def_link = def_link->next)
+           bitmap_set_bit (killed_by_call, DF_REF_ID (def_link->ref));
+       }
+    }
 
   FOR_EACH_BB_IN_BITMAP (blocks, 0, bb,
   {
-    df_bb_rd_local_compute (df, bb);
+    df_bb_rd_local_compute (df, bb, killed_by_call);
   });
+
+  if (df->flags & DF_HARD_REGS)
+    BITMAP_XFREE (killed_by_call);
 }
 
 
index e9863462b107a0a3b3298591f1984451f71df863..698ff4c3fb49ee71cabe9b886013eaa42ee14cc7 100644 (file)
@@ -1054,7 +1054,9 @@ livethrough_conflicts_bb (basic_block bb)
 
   /* And now, if we have found anything, make all live_through
      uses conflict with all defs, and update their other members.  */
-  if (deaths > 0 || bitmap_first_set_bit (all_defs) >= 0)
+  if (deaths > 0
+      || contains_call
+      || bitmap_first_set_bit (all_defs) >= 0)
     EXECUTE_IF_SET_IN_BITMAP (info->live_throughout, first, use_id,
       {
         struct web_part *wp = &web_parts[df->def_id + use_id];