Commit de12be17 by John Carr Committed by John Carr

alias.c (alias_invariant): New variable.

	* alias.c (alias_invariant): New variable.
	(record_base_value): New argument INVARIANT.
	(memrefs_conflict_p): If a register has an entry in the alias_invariant
	array, try substituting that value for the register.
	* rtl.h: Declare record_base_value.
	* loop.c, unroll.c: Update callers of record_base_value.
	* alias.c (find_base_value, find_base_term): SIGN_EXTEND and
	ZERO_EXTEND do not affect base values.

From-SVN: r19408
parent fb2c5c00
Sat Apr 25 17:55:54 1998 John Carr <jfc@mit.edu>
* alias.c (alias_invariant): New variable.
(record_base_value): New argument INVARIANT.
(memrefs_conflict_p): If a register has an entry in the alias_invariant
array, try substituting that value for the register.
* rtl.h: Declare record_base_value.
* loop.c, unroll.c: Update callers of record_base_value.
* alias.c (find_base_value, find_base_term): SIGN_EXTEND and
ZERO_EXTEND do not affect base values.
Fri Apr 24 15:57:02 1998 Jeffrey A Law (law@cygnus.com) Fri Apr 24 15:57:02 1998 Jeffrey A Law (law@cygnus.com)
* dbxout.c (dbxout_type): Fix typo. * dbxout.c (dbxout_type): Fix typo.
......
...@@ -68,6 +68,16 @@ unsigned int reg_base_value_size; /* size of reg_base_value array */ ...@@ -68,6 +68,16 @@ unsigned int reg_base_value_size; /* size of reg_base_value array */
#define REG_BASE_VALUE(X) \ #define REG_BASE_VALUE(X) \
(REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0) (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
/* Vector of known invariant relationships between registers. Set in
loop unrolling. Indexed by register number, if nonzero the value
is an expression describing this register in terms of another.
The length of this array is REG_BASE_VALUE_SIZE.
Because this array contains only pseudo registers it has no effect
after reload. */
static rtx *alias_invariant;
/* Vector indexed by N giving the initial (unchanging) value known /* Vector indexed by N giving the initial (unchanging) value known
for pseudo-register N. */ for pseudo-register N. */
rtx *reg_known_value; rtx *reg_known_value;
...@@ -205,6 +215,8 @@ find_base_value (src) ...@@ -205,6 +215,8 @@ find_base_value (src)
return find_base_value (XEXP (src, 0)); return find_base_value (XEXP (src, 0));
return 0; return 0;
case ZERO_EXTEND:
case SIGN_EXTEND: /* used for NT/Alpha pointers */
case HIGH: case HIGH:
return find_base_value (XEXP (src, 0)); return find_base_value (XEXP (src, 0));
...@@ -295,16 +307,26 @@ record_set (dest, set) ...@@ -295,16 +307,26 @@ record_set (dest, set)
/* Called from loop optimization when a new pseudo-register is created. */ /* Called from loop optimization when a new pseudo-register is created. */
void void
record_base_value (regno, val) record_base_value (regno, val, invariant)
int regno; int regno;
rtx val; rtx val;
int invariant;
{ {
if (regno >= reg_base_value_size) if (regno >= reg_base_value_size)
return; return;
/* If INVARIANT is true then this value also describes an invariant
relationship which can be used to deduce that two registers with
unknown values are different. */
if (invariant && alias_invariant)
alias_invariant[regno] = val;
if (GET_CODE (val) == REG) if (GET_CODE (val) == REG)
{ {
if (REGNO (val) < reg_base_value_size) if (REGNO (val) < reg_base_value_size)
reg_base_value[regno] = reg_base_value[REGNO (val)]; {
reg_base_value[regno] = reg_base_value[REGNO (val)];
}
return; return;
} }
reg_base_value[regno] = find_base_value (val); reg_base_value[regno] = find_base_value (val);
...@@ -397,6 +419,10 @@ rtx_equal_for_memref_p (x, y) ...@@ -397,6 +419,10 @@ rtx_equal_for_memref_p (x, y)
return XEXP (x, 0) == XEXP (y, 0); return XEXP (x, 0) == XEXP (y, 0);
if (code == SYMBOL_REF) if (code == SYMBOL_REF)
return XSTR (x, 0) == XSTR (y, 0); return XSTR (x, 0) == XSTR (y, 0);
if (code == CONST_INT)
return INTVAL (x) == INTVAL (y);
if (code == ADDRESSOF)
return REGNO (XEXP (x, 0)) == REGNO (XEXP (y, 0)) && XINT (x, 1) == XINT (y, 1);
/* For commutative operations, the RTX match if the operand match in any /* For commutative operations, the RTX match if the operand match in any
order. Also handle the simple binary and unary cases without a loop. */ order. Also handle the simple binary and unary cases without a loop. */
...@@ -412,25 +438,20 @@ rtx_equal_for_memref_p (x, y) ...@@ -412,25 +438,20 @@ rtx_equal_for_memref_p (x, y)
return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)); return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0));
/* Compare the elements. If any pair of corresponding elements /* Compare the elements. If any pair of corresponding elements
fail to match, return 0 for the whole things. */ fail to match, return 0 for the whole things.
Limit cases to types which actually appear in addresses. */
fmt = GET_RTX_FORMAT (code); fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{ {
switch (fmt[i]) switch (fmt[i])
{ {
case 'w':
if (XWINT (x, i) != XWINT (y, i))
return 0;
break;
case 'n':
case 'i': case 'i':
if (XINT (x, i) != XINT (y, i)) if (XINT (x, i) != XINT (y, i))
return 0; return 0;
break; break;
case 'V':
case 'E': case 'E':
/* Two vectors must have the same length. */ /* Two vectors must have the same length. */
if (XVECLEN (x, i) != XVECLEN (y, i)) if (XVECLEN (x, i) != XVECLEN (y, i))
...@@ -447,19 +468,6 @@ rtx_equal_for_memref_p (x, y) ...@@ -447,19 +468,6 @@ rtx_equal_for_memref_p (x, y)
return 0; return 0;
break; break;
case 'S':
case 's':
if (strcmp (XSTR (x, i), XSTR (y, i)))
return 0;
break;
case 'u':
/* These are just backpointers, so they don't matter. */
break;
case '0':
break;
/* It is believed that rtx's at this level will never /* It is believed that rtx's at this level will never
contain anything but integers and other rtx's, contain anything but integers and other rtx's,
except for within LABEL_REFs and SYMBOL_REFs. */ except for within LABEL_REFs and SYMBOL_REFs. */
...@@ -513,9 +521,9 @@ find_base_term (x) ...@@ -513,9 +521,9 @@ find_base_term (x)
case REG: case REG:
return REG_BASE_VALUE (x); return REG_BASE_VALUE (x);
case ZERO_EXTEND:
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
case HIGH: case HIGH:
return find_base_term (XEXP (x, 0));
case PRE_INC: case PRE_INC:
case PRE_DEC: case PRE_DEC:
case POST_INC: case POST_INC:
...@@ -747,6 +755,25 @@ memrefs_conflict_p (xsize, x, ysize, y, c) ...@@ -747,6 +755,25 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
return memrefs_conflict_p (xsize, x0, ysize, y0, c); return memrefs_conflict_p (xsize, x0, ysize, y0, c);
} }
case REG:
/* Are these registers known not to be equal? */
if (alias_invariant)
{
int r_x = REGNO (x), r_y = REGNO (y);
rtx i_x, i_y; /* invariant relationships of X and Y */
i_x = r_x >= reg_base_value_size ? 0 : alias_invariant[r_x];
i_y = r_y >= reg_base_value_size ? 0 : alias_invariant[r_y];
if (i_x == 0 && i_y == 0)
break;
if (! memrefs_conflict_p (xsize, i_x ? i_x : x,
ysize, i_y ? i_y : y, c))
return 0;
}
break;
default: default:
break; break;
} }
...@@ -1034,6 +1061,13 @@ init_alias_analysis () ...@@ -1034,6 +1061,13 @@ init_alias_analysis ()
new_reg_base_value = (rtx *)alloca (reg_base_value_size * sizeof (rtx)); new_reg_base_value = (rtx *)alloca (reg_base_value_size * sizeof (rtx));
reg_seen = (char *)alloca (reg_base_value_size); reg_seen = (char *)alloca (reg_base_value_size);
bzero ((char *) reg_base_value, reg_base_value_size * sizeof (rtx)); bzero ((char *) reg_base_value, reg_base_value_size * sizeof (rtx));
if (! reload_completed && flag_unroll_loops)
{
alias_invariant = (rtx *)xrealloc (alias_invariant,
reg_base_value_size * sizeof (rtx));
bzero ((char *)alias_invariant, reg_base_value_size * sizeof (rtx));
}
/* The basic idea is that each pass through this loop will use the /* The basic idea is that each pass through this loop will use the
"constant" information from the previous pass to propagate alias "constant" information from the previous pass to propagate alias
...@@ -1203,4 +1237,9 @@ end_alias_analysis () ...@@ -1203,4 +1237,9 @@ end_alias_analysis ()
reg_known_value = 0; reg_known_value = 0;
reg_base_value = 0; reg_base_value = 0;
reg_base_value_size = 0; reg_base_value_size = 0;
if (alias_invariant)
{
free ((char *)alias_invariant);
alias_invariant = 0;
}
} }
...@@ -5986,7 +5986,7 @@ emit_iv_add_mult (b, m, a, reg, insert_before) ...@@ -5986,7 +5986,7 @@ emit_iv_add_mult (b, m, a, reg, insert_before)
emit_insn_before (seq, insert_before); emit_insn_before (seq, insert_before);
record_base_value (REGNO (reg), b); record_base_value (REGNO (reg), b, 0);
} }
/* Test whether A * B can be computed without /* Test whether A * B can be computed without
......
...@@ -1402,4 +1402,6 @@ extern void init_alias_once PROTO ((void)); ...@@ -1402,4 +1402,6 @@ extern void init_alias_once PROTO ((void));
extern void init_alias_analysis PROTO ((void)); extern void init_alias_analysis PROTO ((void));
extern void end_alias_analysis PROTO ((void)); extern void end_alias_analysis PROTO ((void));
extern void record_base_value PROTO ((int, rtx, int));
#endif /* _RTL_H */ #endif /* _RTL_H */
...@@ -1054,7 +1054,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -1054,7 +1054,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
{ {
map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
record_base_value (REGNO (map->reg_map[j]), record_base_value (REGNO (map->reg_map[j]),
regno_reg_rtx[j]); regno_reg_rtx[j], 0);
} }
/* The last copy needs the compare/branch insns at the end, /* The last copy needs the compare/branch insns at the end,
so reset copy_end here if the loop ends with a conditional so reset copy_end here if the loop ends with a conditional
...@@ -1216,7 +1216,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, ...@@ -1216,7 +1216,7 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
{ {
map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j])); map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
record_base_value (REGNO (map->reg_map[j]), record_base_value (REGNO (map->reg_map[j]),
regno_reg_rtx[j]); regno_reg_rtx[j], 0);
} }
/* If loop starts with a branch to the test, then fix it so that /* If loop starts with a branch to the test, then fix it so that
...@@ -1861,7 +1861,12 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration, ...@@ -1861,7 +1861,12 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
tem = gen_reg_rtx (GET_MODE (giv_src_reg)); tem = gen_reg_rtx (GET_MODE (giv_src_reg));
giv_dest_reg = tem; giv_dest_reg = tem;
map->reg_map[regno] = tem; map->reg_map[regno] = tem;
record_base_value (REGNO (tem), giv_src_reg); record_base_value (REGNO (tem),
giv_inc == const0_rtx
? giv_src_reg
: gen_rtx_PLUS (GET_MODE (giv_src_reg),
giv_src_reg, giv_inc),
1);
} }
else else
map->reg_map[regno] = giv_src_reg; map->reg_map[regno] = giv_src_reg;
...@@ -2560,7 +2565,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, ...@@ -2560,7 +2565,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
{ {
rtx tem = gen_reg_rtx (bl->biv->mode); rtx tem = gen_reg_rtx (bl->biv->mode);
record_base_value (REGNO (tem), bl->biv->add_val); record_base_value (REGNO (tem), bl->biv->add_val, 0);
emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
loop_start); loop_start);
...@@ -2617,7 +2622,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, ...@@ -2617,7 +2622,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
this insn will always be executed, no matter how the loop this insn will always be executed, no matter how the loop
exits. */ exits. */
rtx tem = gen_reg_rtx (bl->biv->mode); rtx tem = gen_reg_rtx (bl->biv->mode);
record_base_value (REGNO (tem), bl->biv->add_val); record_base_value (REGNO (tem), bl->biv->add_val, 0);
emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
loop_start); loop_start);
...@@ -2799,7 +2804,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2799,7 +2804,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
{ {
rtx tem = gen_reg_rtx (bl->biv->mode); rtx tem = gen_reg_rtx (bl->biv->mode);
record_base_value (REGNO (tem), bl->biv->add_val); record_base_value (REGNO (tem), bl->biv->add_val, 0);
emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
loop_start); loop_start);
biv_initial_value = tem; biv_initial_value = tem;
...@@ -2841,7 +2846,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2841,7 +2846,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
|| GET_CODE (XEXP (value, 1)) != CONST_INT)) || GET_CODE (XEXP (value, 1)) != CONST_INT))
{ {
rtx tem = gen_reg_rtx (v->mode); rtx tem = gen_reg_rtx (v->mode);
record_base_value (REGNO (tem), v->add_val); record_base_value (REGNO (tem), v->add_val, 0);
emit_iv_add_mult (bl->initial_value, v->mult_val, emit_iv_add_mult (bl->initial_value, v->mult_val,
v->add_val, tem, loop_start); v->add_val, tem, loop_start);
value = tem; value = tem;
...@@ -2900,7 +2905,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment, ...@@ -2900,7 +2905,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
Emit insn to initialize its value before loop start. */ Emit insn to initialize its value before loop start. */
rtx tem = gen_reg_rtx (v->mode); rtx tem = gen_reg_rtx (v->mode);
record_base_value (REGNO (tem), v->add_val); record_base_value (REGNO (tem), v->add_val, 0);
v->unrolled = 1; v->unrolled = 1;
/* If the address giv has a constant in its new_reg value, /* If the address giv has a constant in its new_reg value,
...@@ -3216,7 +3221,7 @@ final_biv_value (bl, loop_start, loop_end) ...@@ -3216,7 +3221,7 @@ final_biv_value (bl, loop_start, loop_end)
case it is needed later. */ case it is needed later. */
tem = gen_reg_rtx (bl->biv->mode); tem = gen_reg_rtx (bl->biv->mode);
record_base_value (REGNO (tem), bl->biv->add_val); record_base_value (REGNO (tem), bl->biv->add_val, 0);
/* Make sure loop_end is not the last insn. */ /* Make sure loop_end is not the last insn. */
if (NEXT_INSN (loop_end) == 0) if (NEXT_INSN (loop_end) == 0)
emit_note_after (NOTE_INSN_DELETED, loop_end); emit_note_after (NOTE_INSN_DELETED, loop_end);
...@@ -3315,7 +3320,7 @@ final_giv_value (v, loop_start, loop_end) ...@@ -3315,7 +3320,7 @@ final_giv_value (v, loop_start, loop_end)
/* Put the final biv value in tem. */ /* Put the final biv value in tem. */
tem = gen_reg_rtx (bl->biv->mode); tem = gen_reg_rtx (bl->biv->mode);
record_base_value (REGNO (tem), bl->biv->add_val); record_base_value (REGNO (tem), bl->biv->add_val, 0);
emit_iv_add_mult (increment, GEN_INT (loop_n_iterations), emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
bl->initial_value, tem, insert_before); bl->initial_value, tem, insert_before);
......
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