Commit 2a2c8203 by John F. Carr Committed by Jeff Law

alias.c (find_base_value): Improve handling of PLUS, MINUS, and LO_SUM.

        * alias.c (find_base_value): Improve handling of PLUS, MINUS, and
        LO_SUM.
        (record_set): Handle LO_SUM like PLUS.
        (init_alias_analysis): When following chains of base addresses,
        do not stop on reaching a hard register.
Updates from jfc.

From-SVN: r14888
parent d80357b7
Thu Aug 21 23:52:16 1997 John F. Carr <jfc@mit.edu>
* alias.c (find_base_value): Improve handling of PLUS, MINUS, and
LO_SUM.
(record_set): Handle LO_SUM like PLUS.
(init_alias_analysis): When following chains of base addresses,
do not stop on reaching a hard register.
Thu Aug 21 20:17:37 1997 Jeffrey A Law (law@cygnus.com) Thu Aug 21 20:17:37 1997 Jeffrey A Law (law@cygnus.com)
* version.c: Bump for new snapshot. * version.c: Bump for new snapshot.
......
...@@ -40,9 +40,17 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx, ...@@ -40,9 +40,17 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
If all sets after the first add or subtract to the current value If all sets after the first add or subtract to the current value
or otherwise modify it so it does not point to a different top level or otherwise modify it so it does not point to a different top level
object, reg_base_value[N] is equal to the address part of the source object, reg_base_value[N] is equal to the address part of the source
of the first set. The value will be a SYMBOL_REF, a LABEL_REF, or of the first set.
(address (reg)) to indicate that the address is derived from an
argument or fixed register. */ A base address can be an ADDRESS, SYMBOL_REF, or LABEL_REF. ADDRESS
expressions represent certain special values: function arguments and
the stack, frame, and argument pointers. The contents of an address
expression are not used (but they are descriptive for debugging);
only the address and mode matter. Pointer equality, not rtx_equal_p,
determines whether two ADDRESS expressions refer to the same base
address. The mode determines whether it is a function argument or
other special value. */
rtx *reg_base_value; rtx *reg_base_value;
unsigned int reg_base_value_size; /* size of reg_base_value array */ unsigned int reg_base_value_size; /* size of reg_base_value array */
#define REG_BASE_VALUE(X) \ #define REG_BASE_VALUE(X) \
...@@ -68,14 +76,13 @@ static int reg_known_value_size; ...@@ -68,14 +76,13 @@ static int reg_known_value_size;
here. */ here. */
char *reg_known_equiv_p; char *reg_known_equiv_p;
/* Inside SRC, the source of a SET, find a base address. */ /* True when scanning insns from the start of the rtl to the
NOTE_INSN_FUNCTION_BEG note. */
/* When copying arguments into pseudo-registers, record the (ADDRESS)
expression for the argument directly so that even if the argument
register is changed later (e.g. for a function call) the original
value is noted. */
static int copying_arguments; static int copying_arguments;
/* Inside SRC, the source of a SET, find a base address. */
static rtx static rtx
find_base_value (src) find_base_value (src)
register rtx src; register rtx src;
...@@ -87,7 +94,11 @@ find_base_value (src) ...@@ -87,7 +94,11 @@ find_base_value (src)
return src; return src;
case REG: case REG:
if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) /* At the start of a function argument registers have known base
values which may be lost later. Returning an ADDRESS
expression here allows optimization based on argument values
even when the argument registers are used for other purposes. */
if (REGNO (src) < FIRST_PSEUDO_REGISTER && copying_arguments)
return reg_base_value[REGNO (src)]; return reg_base_value[REGNO (src)];
return src; return src;
...@@ -107,43 +118,48 @@ find_base_value (src) ...@@ -107,43 +118,48 @@ find_base_value (src)
if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS) if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS)
break; break;
/* fall through */ /* fall through */
case PLUS: case PLUS:
case MINUS: case MINUS:
/* Guess which operand to set the register equivalent to. */ {
/* If the first operand is a symbol or the second operand is rtx src_0 = XEXP (src, 0), src_1 = XEXP (src, 1);
an integer, the first operand is the base address. */
if (GET_CODE (XEXP (src, 0)) == SYMBOL_REF /* Guess which operand is the base address.
|| GET_CODE (XEXP (src, 0)) == LABEL_REF
|| GET_CODE (XEXP (src, 1)) == CONST_INT) If the first operand is a symbol or the second operand is
return XEXP (src, 0); an integer, the first operand is the base address. Else if
/* If an operand is a register marked as a pointer, it is the base. */ either operand is a register marked as a pointer, it is the
if (GET_CODE (XEXP (src, 0)) == REG base address. */
&& REGNO_POINTER_FLAG (REGNO (XEXP (src, 0))))
src = XEXP (src, 0); if (GET_CODE (src_1) == CONST_INT
else if (GET_CODE (XEXP (src, 1)) == REG || GET_CODE (src_0) == SYMBOL_REF
&& REGNO_POINTER_FLAG (REGNO (XEXP (src, 1)))) || GET_CODE (src_0) == LABEL_REF
src = XEXP (src, 1); || GET_CODE (src_0) == CONST)
else return find_base_value (src_0);
if (GET_CODE (src_0) == REG && REGNO_POINTER_FLAG (REGNO (src_0)))
return find_base_value (src_0);
if (GET_CODE (src_1) == REG && REGNO_POINTER_FLAG (REGNO (src_1)))
return find_base_value (src_1);
return 0; return 0;
if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER) }
return reg_base_value[REGNO (src)];
return src; case LO_SUM:
/* The standard form is (lo_sum reg sym) so look only at the
second operand. */
return find_base_value (XEXP (src, 1));
case AND: case AND:
/* If the second operand is constant set the base /* If the second operand is constant set the base
address to the first operand. */ address to the first operand. */
if (GET_CODE (XEXP (src, 1)) == CONST_INT if (GET_CODE (XEXP (src, 1)) == CONST_INT && INTVAL (XEXP (src, 1)) != 0)
&& GET_CODE (XEXP (src, 0)) == REG) return find_base_value (XEXP (src, 0));
{
src = XEXP (src, 0);
if (copying_arguments && REGNO (src) < FIRST_PSEUDO_REGISTER)
return reg_base_value[REGNO (src)];
return src;
}
return 0; return 0;
case HIGH: case HIGH:
return XEXP (src, 0); return find_base_value (XEXP (src, 0));
} }
return 0; return 0;
...@@ -155,8 +171,8 @@ find_base_value (src) ...@@ -155,8 +171,8 @@ find_base_value (src)
register N has been set in this function. */ register N has been set in this function. */
static char *reg_seen; static char *reg_seen;
static static void
void record_set (dest, set) record_set (dest, set)
rtx dest, set; rtx dest, set;
{ {
register int regno; register int regno;
...@@ -202,6 +218,7 @@ void record_set (dest, set) ...@@ -202,6 +218,7 @@ void record_set (dest, set)
if (reg_base_value[regno]) if (reg_base_value[regno])
switch (GET_CODE (src)) switch (GET_CODE (src))
{ {
case LO_SUM:
case PLUS: case PLUS:
case MINUS: case MINUS:
if (XEXP (src, 0) != dest && XEXP (src, 1) != dest) if (XEXP (src, 0) != dest && XEXP (src, 1) != dest)
...@@ -211,10 +228,6 @@ void record_set (dest, set) ...@@ -211,10 +228,6 @@ void record_set (dest, set)
if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT) if (XEXP (src, 0) != dest || GET_CODE (XEXP (src, 1)) != CONST_INT)
reg_base_value[regno] = 0; reg_base_value[regno] = 0;
break; break;
case LO_SUM:
if (XEXP (src, 0) != dest)
reg_base_value[regno] = 0;
break;
default: default:
reg_base_value[regno] = 0; reg_base_value[regno] = 0;
break; break;
...@@ -931,8 +944,10 @@ init_alias_analysis () ...@@ -931,8 +944,10 @@ init_alias_analysis ()
= gen_rtx (ADDRESS, Pmode, arg_pointer_rtx); = gen_rtx (ADDRESS, Pmode, arg_pointer_rtx);
reg_base_value[FRAME_POINTER_REGNUM] reg_base_value[FRAME_POINTER_REGNUM]
= gen_rtx (ADDRESS, Pmode, frame_pointer_rtx); = gen_rtx (ADDRESS, Pmode, frame_pointer_rtx);
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
reg_base_value[HARD_FRAME_POINTER_REGNUM] reg_base_value[HARD_FRAME_POINTER_REGNUM]
= gen_rtx (ADDRESS, Pmode, hard_frame_pointer_rtx); = gen_rtx (ADDRESS, Pmode, hard_frame_pointer_rtx);
#endif
} }
copying_arguments = 1; copying_arguments = 1;
...@@ -947,7 +962,7 @@ init_alias_analysis () ...@@ -947,7 +962,7 @@ init_alias_analysis ()
rtx noalias_note; rtx noalias_note;
if (GET_CODE (PATTERN (insn)) == SET if (GET_CODE (PATTERN (insn)) == SET
&& (noalias_note = find_reg_note (insn, REG_NOALIAS, NULL_RTX))) && (noalias_note = find_reg_note (insn, REG_NOALIAS, NULL_RTX)))
record_set (SET_DEST (PATTERN (insn)), 0); record_set (SET_DEST (PATTERN (insn)), 0);
else else
note_stores (PATTERN (insn), record_set); note_stores (PATTERN (insn), record_set);
} }
......
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