Commit 131db6b8 by Steven Bosscher

tracer.c (mark_bb_seen): Use SBITMAP_SIZE.

	* 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.

From-SVN: r190602
parent c637141a
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> 2012-08-22 H.J. Lu <hongjiu.lu@intel.com>
* doc/invoke.texi: Document -mlong-double-64/-mlong-double-80. * doc/invoke.texi: Document -mlong-double-64/-mlong-double-80.
......
...@@ -168,7 +168,10 @@ static void memory_modified_1 (rtx, const_rtx, void *); ...@@ -168,7 +168,10 @@ static void memory_modified_1 (rtx, const_rtx, void *);
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
/* Cap the number of passes we make over the insns propagating alias /* 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 #define MAX_ALIAS_LOOP_PASSES 10
/* reg_base_value[N] gives an address to which register N is related. /* reg_base_value[N] gives an address to which register N is related.
...@@ -2764,6 +2767,8 @@ init_alias_analysis (void) ...@@ -2764,6 +2767,8 @@ init_alias_analysis (void)
int i; int i;
unsigned int ui; unsigned int ui;
rtx insn, val; rtx insn, val;
int rpo_cnt;
int *rpo;
timevar_push (TV_ALIAS_ANALYSIS); timevar_push (TV_ALIAS_ANALYSIS);
...@@ -2786,6 +2791,9 @@ init_alias_analysis (void) ...@@ -2786,6 +2791,9 @@ init_alias_analysis (void)
"constant" information from the previous pass to propagate alias "constant" information from the previous pass to propagate alias
information through another level of assignments. 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 This could get expensive if the assignment chains are long. Maybe
we should throttle the number of iterations, possibly based on we should throttle the number of iterations, possibly based on
the optimization level or flag_expensive_optimizations. the optimization level or flag_expensive_optimizations.
...@@ -2801,6 +2809,9 @@ init_alias_analysis (void) ...@@ -2801,6 +2809,9 @@ init_alias_analysis (void)
The state of the arrays for the set chain in question does not matter The state of the arrays for the set chain in question does not matter
since the program has undefined behavior. */ 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; pass = 0;
do do
{ {
...@@ -2833,80 +2844,84 @@ init_alias_analysis (void) ...@@ -2833,80 +2844,84 @@ init_alias_analysis (void)
FIRST_PSEUDO_REGISTER * sizeof (rtx)); FIRST_PSEUDO_REGISTER * sizeof (rtx));
/* Walk the insns adding values to the new_reg_base_value array. */ /* 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) #if defined (HAVE_prologue) || defined (HAVE_epilogue)
/* The prologue/epilogue insns are not threaded onto the /* The prologue/epilogue insns are not threaded onto the
insn chain until after reload has completed. Thus, insn chain until after reload has completed. Thus,
there is no sense wasting time checking if INSN is in there is no sense wasting time checking if INSN is in
the prologue/epilogue until after reload has completed. */ the prologue/epilogue until after reload has completed. */
if (reload_completed if (reload_completed
&& prologue_epilogue_contains (insn)) && prologue_epilogue_contains (insn))
continue; continue;
#endif #endif
/* If this insn has a noalias note, process it, Otherwise, /* If this insn has a noalias note, process it, Otherwise,
scan for sets. A simple set will have no side effects scan for sets. A simple set will have no side effects
which could change the base value of any other register. */ which could change the base value of any other register. */
if (GET_CODE (PATTERN (insn)) == SET if (GET_CODE (PATTERN (insn)) == SET
&& REG_NOTES (insn) != 0 && REG_NOTES (insn) != 0
&& find_reg_note (insn, REG_NOALIAS, NULL_RTX)) && find_reg_note (insn, REG_NOALIAS, NULL_RTX))
record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL); record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL);
else else
note_stores (PATTERN (insn), record_set, NULL); note_stores (PATTERN (insn), record_set, NULL);
set = single_set (insn); set = single_set (insn);
if (set != 0 if (set != 0
&& REG_P (SET_DEST (set)) && REG_P (SET_DEST (set))
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) && 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))
{ {
set_reg_known_value (regno, src); unsigned int regno = REGNO (SET_DEST (set));
set_reg_known_equiv_p (regno, false); 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. */ /* Now propagate values from new_reg_base_value to reg_base_value. */
...@@ -2925,6 +2940,7 @@ init_alias_analysis (void) ...@@ -2925,6 +2940,7 @@ init_alias_analysis (void)
} }
} }
while (changed && ++pass < MAX_ALIAS_LOOP_PASSES); while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
XDELETEVEC (rpo);
/* Fill in the remaining entries. */ /* Fill in the remaining entries. */
FOR_EACH_VEC_ELT (rtx, reg_known_value, i, val) FOR_EACH_VEC_ELT (rtx, reg_known_value, i, val)
......
...@@ -69,7 +69,7 @@ sbitmap bb_seen; ...@@ -69,7 +69,7 @@ sbitmap bb_seen;
static inline void static inline void
mark_bb_seen (basic_block bb) 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) if ((unsigned int)bb->index >= size)
bb_seen = sbitmap_resize (bb_seen, size * 2, 0); bb_seen = sbitmap_resize (bb_seen, size * 2, 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment