* tracer.c (mark_bb_seen): Use SBITMAP_SIZE.
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Aug 2012 21:38:03 +0000 (21:38 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Aug 2012 21:38:03 +0000 (21:38 +0000)
* alias.c (MAX_ALIAS_LOOP_PASSES): Update comment with rationale,
or rather a lack thereof.
(init_alias_analysis): Propagate the latest information across
the CFG in topological order to propagate as far as possible in
each iteration.  Ignore debug insns.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190602 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/alias.c
gcc/tracer.c

index f67c4ac..527f822 100644 (file)
@@ -1,3 +1,13 @@
+2012-08-22  Steven Bosscher  <steven@gcc.gnu.org>
+
+       * tracer.c (mark_bb_seen): Use SBITMAP_SIZE.
+
+       * alias.c (MAX_ALIAS_LOOP_PASSES): Update comment with rationale,
+       or rather a lack thereof.
+       (init_alias_analysis): Propagate the latest information across
+       the CFG in topological order to propagate as far as possible in
+       each iteration.  Ignore debug insns.
+
 2012-08-22  H.J. Lu  <hongjiu.lu@intel.com>
 
        * doc/invoke.texi: Document -mlong-double-64/-mlong-double-80.
index de7640f..a26c299 100644 (file)
@@ -168,7 +168,10 @@ static void memory_modified_1 (rtx, const_rtx, void *);
 #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
 
 /* Cap the number of passes we make over the insns propagating alias
-   information through set chains.   10 is a completely arbitrary choice.  */
+   information through set chains.
+   ??? 10 is a completely arbitrary choice.  This should be based on the
+   maximum loop depth in the CFG, but we do not have this information
+   available (even if current_loops _is_ available).  */
 #define MAX_ALIAS_LOOP_PASSES 10
 
 /* reg_base_value[N] gives an address to which register N is related.
@@ -2764,6 +2767,8 @@ init_alias_analysis (void)
   int i;
   unsigned int ui;
   rtx insn, val;
+  int rpo_cnt;
+  int *rpo;
 
   timevar_push (TV_ALIAS_ANALYSIS);
 
@@ -2786,6 +2791,9 @@ init_alias_analysis (void)
      "constant" information from the previous pass to propagate alias
      information through another level of assignments.
 
+     The propagation is done on the CFG in reverse post-order, to propagate
+     things forward as far as possible in each iteration.
+
      This could get expensive if the assignment chains are long.  Maybe
      we should throttle the number of iterations, possibly based on
      the optimization level or flag_expensive_optimizations.
@@ -2801,6 +2809,9 @@ init_alias_analysis (void)
      The state of the arrays for the set chain in question does not matter
      since the program has undefined behavior.  */
 
+  rpo = XNEWVEC (int, n_basic_blocks);
+  rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false);
+
   pass = 0;
   do
     {
@@ -2833,80 +2844,84 @@ init_alias_analysis (void)
              FIRST_PSEUDO_REGISTER * sizeof (rtx));
 
       /* Walk the insns adding values to the new_reg_base_value array.  */
-      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+      for (i = 0; i < rpo_cnt; i++)
        {
-         if (INSN_P (insn))
+         basic_block bb = BASIC_BLOCK (rpo[i]);
+         FOR_BB_INSNS (bb, insn)
            {
-             rtx note, set;
+             if (NONDEBUG_INSN_P (insn))
+               {
+                 rtx note, set;
 
 #if defined (HAVE_prologue) || defined (HAVE_epilogue)
-             /* The prologue/epilogue insns are not threaded onto the
-                insn chain until after reload has completed.  Thus,
-                there is no sense wasting time checking if INSN is in
-                the prologue/epilogue until after reload has completed.  */
-             if (reload_completed
-                 && prologue_epilogue_contains (insn))
-               continue;
+                 /* The prologue/epilogue insns are not threaded onto the
+                    insn chain until after reload has completed.  Thus,
+                    there is no sense wasting time checking if INSN is in
+                    the prologue/epilogue until after reload has completed.  */
+                 if (reload_completed
+                     && prologue_epilogue_contains (insn))
+                   continue;
 #endif
 
-             /* If this insn has a noalias note, process it,  Otherwise,
-                scan for sets.  A simple set will have no side effects
-                which could change the base value of any other register.  */
+                 /* If this insn has a noalias note, process it,  Otherwise,
+                    scan for sets.  A simple set will have no side effects
+                    which could change the base value of any other register.  */
 
-             if (GET_CODE (PATTERN (insn)) == SET
-                 && REG_NOTES (insn) != 0
-                 && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
-               record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
-             else
-               note_stores (PATTERN (insn), record_set, NULL);
+                 if (GET_CODE (PATTERN (insn)) == SET
+                     && REG_NOTES (insn) != 0
+                     && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
+                   record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
+                 else
+                   note_stores (PATTERN (insn), record_set, NULL);
 
-             set = single_set (insn);
+                 set = single_set (insn);
 
-             if (set != 0
-                 && REG_P (SET_DEST (set))
-                 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
-               {
-                 unsigned int regno = REGNO (SET_DEST (set));
-                 rtx src = SET_SRC (set);
-                 rtx t;
-
-                 note = find_reg_equal_equiv_note (insn);
-                 if (note && REG_NOTE_KIND (note) == REG_EQUAL
-                     && DF_REG_DEF_COUNT (regno) != 1)
-                   note = NULL_RTX;
-
-                 if (note != NULL_RTX
-                     && GET_CODE (XEXP (note, 0)) != EXPR_LIST
-                     && ! rtx_varies_p (XEXP (note, 0), 1)
-                     && ! reg_overlap_mentioned_p (SET_DEST (set),
-                                                   XEXP (note, 0)))
-                   {
-                     set_reg_known_value (regno, XEXP (note, 0));
-                     set_reg_known_equiv_p (regno,
-                       REG_NOTE_KIND (note) == REG_EQUIV);
-                   }
-                 else if (DF_REG_DEF_COUNT (regno) == 1
-                          && GET_CODE (src) == PLUS
-                          && REG_P (XEXP (src, 0))
-                          && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
-                          && CONST_INT_P (XEXP (src, 1)))
-                   {
-                     t = plus_constant (GET_MODE (src), t,
-                                        INTVAL (XEXP (src, 1)));
-                     set_reg_known_value (regno, t);
-                     set_reg_known_equiv_p (regno, false);
-                   }
-                 else if (DF_REG_DEF_COUNT (regno) == 1
-                          && ! rtx_varies_p (src, 1))
+                 if (set != 0
+                     && REG_P (SET_DEST (set))
+                     && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
                    {
-                     set_reg_known_value (regno, src);
-                     set_reg_known_equiv_p (regno, false);
+                     unsigned int regno = REGNO (SET_DEST (set));
+                     rtx src = SET_SRC (set);
+                     rtx t;
+
+                     note = find_reg_equal_equiv_note (insn);
+                     if (note && REG_NOTE_KIND (note) == REG_EQUAL
+                         && DF_REG_DEF_COUNT (regno) != 1)
+                       note = NULL_RTX;
+
+                     if (note != NULL_RTX
+                         && GET_CODE (XEXP (note, 0)) != EXPR_LIST
+                         && ! rtx_varies_p (XEXP (note, 0), 1)
+                         && ! reg_overlap_mentioned_p (SET_DEST (set),
+                                                       XEXP (note, 0)))
+                       {
+                         set_reg_known_value (regno, XEXP (note, 0));
+                         set_reg_known_equiv_p (regno,
+                                                REG_NOTE_KIND (note) == REG_EQUIV);
+                       }
+                     else if (DF_REG_DEF_COUNT (regno) == 1
+                              && GET_CODE (src) == PLUS
+                              && REG_P (XEXP (src, 0))
+                              && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
+                              && CONST_INT_P (XEXP (src, 1)))
+                       {
+                         t = plus_constant (GET_MODE (src), t,
+                                            INTVAL (XEXP (src, 1)));
+                         set_reg_known_value (regno, t);
+                         set_reg_known_equiv_p (regno, false);
+                       }
+                     else if (DF_REG_DEF_COUNT (regno) == 1
+                              && ! rtx_varies_p (src, 1))
+                       {
+                         set_reg_known_value (regno, src);
+                         set_reg_known_equiv_p (regno, false);
+                       }
                    }
                }
+             else if (NOTE_P (insn)
+                      && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
+               copying_arguments = false;
            }
-         else if (NOTE_P (insn)
-                  && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
-           copying_arguments = false;
        }
 
       /* Now propagate values from new_reg_base_value to reg_base_value.  */
@@ -2925,6 +2940,7 @@ init_alias_analysis (void)
        }
     }
   while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
+  XDELETEVEC (rpo);
 
   /* Fill in the remaining entries.  */
   FOR_EACH_VEC_ELT (rtx, reg_known_value, i, val)
index f60f348..9b1d724 100644 (file)
@@ -69,7 +69,7 @@ sbitmap bb_seen;
 static inline void
 mark_bb_seen (basic_block bb)
 {
-  unsigned int size = SBITMAP_SIZE_BYTES (bb_seen) * 8;
+  unsigned int size = SBITMAP_SIZE (bb_seen);
 
   if ((unsigned int)bb->index >= size)
     bb_seen = sbitmap_resize (bb_seen, size * 2, 0);