recog.c (split_all_insns): Do not update reg info.
authorJan Hubicka <jh@suse.cz>
Fri, 6 Feb 2004 13:57:15 +0000 (14:57 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 6 Feb 2004 13:57:15 +0000 (13:57 +0000)
* recog.c (split_all_insns): Do not update reg info.
* regrename.c (regrename_optimize): Likewise.
* toplev.c (rest_of_handle_reorder_blocks): Likewise.
* flow.c (struct propagate_block_info): Add insn_num field.
(reg_deaths): New array.
(life_analysis): Free reg_deaths info.
(allocate_reg_life_data): Allocate reg_deaths array.
(propagate_one_insn): Use new array.
(init_propagate_block): Initialize it.
(free_propagate_block_info): Finish compuation of
REG_LIVE_LENGTH
(attempt_auto_inc): Sanity check that REG_INFO is not
computed at same time.
(mark_used_regs): Update new array.

* reg-stack.c (subst_stack_regs): Unshare clobbers before
substitution.

From-SVN: r77396

gcc/ChangeLog
gcc/flow.c
gcc/recog.c
gcc/reg-stack.c
gcc/regrename.c
gcc/toplev.c

index dea07e5a38c26e03a2cfa6c2b21816da51dde2ce..3eaa2a20b46b33c630842203697669f09c817f5e 100644 (file)
@@ -1,3 +1,23 @@
+2004-02-06  Jan Hubicka  <jh@suse.cz>
+
+       * recog.c (split_all_insns): Do not update reg info.
+       * regrename.c (regrename_optimize): Likewise.
+       * toplev.c (rest_of_handle_reorder_blocks): Likewise.
+       * flow.c (struct propagate_block_info): Add insn_num field.
+       (reg_deaths): New array.
+       (life_analysis): Free reg_deaths info.
+       (allocate_reg_life_data): Allocate reg_deaths array.
+       (propagate_one_insn): Use new array.
+       (init_propagate_block): Initialize it.
+       (free_propagate_block_info): Finish compuation of
+       REG_LIVE_LENGTH
+       (attempt_auto_inc): Sanity check that REG_INFO is not
+       computed at same time.
+       (mark_used_regs): Update new array.
+
+       * reg-stack.c (subst_stack_regs): Unshare clobbers before
+       substitution.
+
 2004-02-06  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/s390/s390.md (*extendsiqi2_short_displ): Change to
index 1ed469f8f488be367637261a936b6ae7535ac567..049a587903e9c7042f25d2e6208fb87b03f32198 100644 (file)
@@ -264,11 +264,28 @@ struct propagate_block_info
 
   /* Flags controlling the set of information propagate_block collects.  */
   int flags;
+  /* Index of instruction being processed.  */
+  int insn_num;
 };
 
 /* Number of dead insns removed.  */
 static int ndead;
 
+/* When PROP_REG_INFO set, array contains pbi->insn_num of instruction
+   where given register died.  When the register is marked alive, we use the
+   information to compute amount of instructions life range cross.
+   (remember, we are walking backward).  This can be computed as current
+   pbi->insn_num - reg_deaths[regno].
+   At the end of processing each basic block, the remaining live registers
+   are inspected and liferanges are increased same way so liverange of global
+   registers are computed correctly.
+  
+   The array is maintained clear for dead registers, so it can be safely reused
+   for next basic block without expensive memset of the whole array after
+   reseting pbi->insn_num to 0.  */
+
+static int *reg_deaths;
+
 /* Maximum length of pbi->mem_set_list before we start dropping
    new elements on the floor.  */
 #define MAX_MEM_SET_LIST_LEN   100
@@ -458,6 +475,11 @@ life_analysis (rtx f, FILE *file, int flags)
       memset (regs_asm_clobbered, 0, sizeof (regs_asm_clobbered));
     }
   update_life_info (NULL, UPDATE_LIFE_GLOBAL, flags);
+  if (reg_deaths)
+    {
+      free (reg_deaths);
+      reg_deaths = NULL;
+    }
 
   /* Clean up.  */
   if (optimize && (flags & PROP_SCAN_DEAD_STORES))
@@ -734,6 +756,11 @@ update_life_info (sbitmap blocks, enum update_life_extent extent, int prop_flags
                                     }
                                 });
     }
+  if (reg_deaths)
+    {
+      free (reg_deaths);
+      reg_deaths = NULL;
+    }
   timevar_pop ((extent == UPDATE_LIFE_LOCAL || blocks)
               ? TV_LIFE_UPDATE : TV_LIFE);
   if (ndead && rtl_dump_file)
@@ -1457,6 +1484,9 @@ allocate_reg_life_data (void)
   int i;
 
   max_regno = max_reg_num ();
+  if (reg_deaths)
+    abort ();
+  reg_deaths = xcalloc (sizeof (*reg_deaths), max_regno);
 
   /* Recalculate the register space, in case it has grown.  Old style
      vector oriented regsets would set regset_{size,bytes} here also.  */
@@ -1783,6 +1813,9 @@ propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
            mark_used_regs (pbi, XEXP (XEXP (note, 0), 0), cond, insn);
 
          /* The stack ptr is used (honorarily) by a CALL insn.  */
+         if ((flags & PROP_REG_INFO)
+             && !REGNO_REG_SET_P (pbi->reg_live, STACK_POINTER_REGNUM))
+           reg_deaths[STACK_POINTER_REGNUM] = pbi->insn_num;
          SET_REGNO_REG_SET (pbi->reg_live, STACK_POINTER_REGNUM);
 
          /* Calls may also reference any of the global registers,
@@ -1793,11 +1826,7 @@ propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
        }
     }
 
-  /* On final pass, update counts of how many insns in which each reg
-     is live.  */
-  if (flags & PROP_REG_INFO)
-    EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i,
-                              { REG_LIVE_LENGTH (i)++; });
+  pbi->insn_num++;
 
   return prev;
 }
@@ -1820,6 +1849,7 @@ init_propagate_block_info (basic_block bb, regset live, regset local_set,
   pbi->cond_local_set = cond_local_set;
   pbi->cc0_live = 0;
   pbi->flags = flags;
+  pbi->insn_num = 0;
 
   if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
     pbi->reg_next_use = xcalloc (max_reg_num (), sizeof (rtx));
@@ -1976,6 +2006,16 @@ free_propagate_block_info (struct propagate_block_info *pbi)
   BITMAP_XFREE (pbi->reg_cond_reg);
 #endif
 
+  if (pbi->flags & PROP_REG_INFO)
+    {
+      int num = pbi->insn_num;
+      int i;
+
+      EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i,
+        { REG_LIVE_LENGTH (i) += num - reg_deaths[i];
+          reg_deaths[i] = 0;
+         });
+    }
   if (pbi->reg_next_use)
     free (pbi->reg_next_use);
 
@@ -2803,7 +2843,15 @@ mark_set_1 (struct propagate_block_info *pbi, enum rtx_code code, rtx reg, rtx c
        {
          for (i = regno_first; i <= regno_last; ++i)
            if (!(not_dead & (((unsigned long) 1) << (i - regno_first))))
-             CLEAR_REGNO_REG_SET (pbi->reg_live, i);
+             {
+               if ((pbi->flags & PROP_REG_INFO)
+                   && REGNO_REG_SET_P (pbi->reg_live, i))
+                 {
+                   REG_LIVE_LENGTH (i) += pbi->insn_num - reg_deaths[i];
+                   reg_deaths[i] = 0;
+                 }
+               CLEAR_REGNO_REG_SET (pbi->reg_live, i);
+             }
        }
     }
   else if (GET_CODE (reg) == REG)
@@ -3334,6 +3382,10 @@ attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn,
         on this insn, which is incorrect.  */
       SET_REGNO_REG_SET (pbi->reg_live, regno);
 
+      /* We shall not do the autoinc during final pass.  */
+      if (flags & PROP_REG_INFO)
+       abort ();
+
       /* If there are any calls between INSN and INCR, show
         that REGNO now crosses them.  */
       for (temp = insn; temp != incr; temp = NEXT_INSN (temp))
@@ -3365,6 +3417,9 @@ attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn,
       /* If the original source was dead, it's dead now.  */
       rtx note;
 
+      /* We shall not do the autoinc during final pass.  */
+      if (flags & PROP_REG_INFO)
+       abort ();
       while ((note = find_reg_note (incr, REG_DEAD, NULL_RTX)) != NULL_RTX)
        {
          remove_note (incr, note);
@@ -3550,6 +3605,15 @@ mark_used_reg (struct propagate_block_info *pbi, rtx reg,
          REG_FREQ (regno_first) += REG_FREQ_FROM_BB (pbi->bb);
          REG_N_REFS (regno_first)++;
        }
+      for (i = regno_first; i <= regno_last; ++i)
+       if (! REGNO_REG_SET_P (pbi->reg_live, i))
+         {
+#ifdef ENABLE_CHECKING
+           if (reg_deaths[i])
+             abort ();
+#endif
+           reg_deaths[i] = pbi->insn_num;
+         }
     }
 
   /* Record and count the insns in which a reg dies.  If it is used in
index 470e93b06a3798a0f6abc3461d0a2ccc0991c394..9b5f4d4152c0eeb7dcbbc324e436fc0166ab673e 100644 (file)
@@ -2795,7 +2795,7 @@ split_all_insns (int upd_life)
 
   if (changed && upd_life)
     update_life_info (blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
-                     PROP_DEATH_NOTES | PROP_REG_INFO);
+                     PROP_DEATH_NOTES);
 
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
index 433b7393ab6f2974b28277fbb24aaea0cceae3c8..90e137df56a9e73c1d00e75db6337d93e76a6882 100644 (file)
@@ -2236,9 +2236,14 @@ subst_stack_regs (rtx insn, stack regstack)
        for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
          {
            if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
-             control_flow_insn_deleted
-               |= subst_stack_regs_pat (insn, regstack,
-                                        XVECEXP (PATTERN (insn), 0, i));
+             {
+               if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER)
+                  XVECEXP (PATTERN (insn), 0, i)
+                    = shallow_copy_rtx (XVECEXP (PATTERN (insn), 0, i));
+               control_flow_insn_deleted
+                 |= subst_stack_regs_pat (insn, regstack,
+                                          XVECEXP (PATTERN (insn), 0, i));
+             }
          }
       else
        control_flow_insn_deleted
index 914bfbc9cb6eb152d169bb6872a1370d6407481a..8a83b9687e2d69d0f07af2d591c12ee7e503e227 100644 (file)
@@ -360,7 +360,7 @@ regrename_optimize (void)
 
   count_or_remove_death_notes (NULL, 1);
   update_life_info (NULL, UPDATE_LIFE_LOCAL,
-                   PROP_REG_INFO | PROP_DEATH_NOTES);
+                   PROP_DEATH_NOTES);
 }
 
 static void
index 5f2c12b665333f9a3d17e68ef722bbaf43af8dfe..369ba5c04f4953009430606f7f15c7415439a97e 100644 (file)
@@ -2331,7 +2331,7 @@ rest_of_handle_reorder_blocks (tree decl, rtx insns)
      but should not be terribly bad.  */
   if (changed && HAVE_conditional_execution)
     update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
-                     PROP_DEATH_NOTES | PROP_REG_INFO);
+                     PROP_DEATH_NOTES);
   close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
 }