mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-19 15:10:04 +08:00
Improve alias analysis for ia64
From-SVN: r38660
This commit is contained in:
parent
03378143ac
commit
713f41f9b3
@ -16,6 +16,12 @@ Wed Jan 3 08:53:50 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
* cse.c (cse_rtx_varies_p): Accept additional FROM_ALIAS arg. All
|
||||
callers changed.
|
||||
|
||||
* alias.c (throughout): Use ORIGINAL_REGNO when accessing
|
||||
reg_base_value and reg_known_value arrays.
|
||||
(init_alias_analysis): Add more cases to detect known values.
|
||||
* sched-deps.c (deps_may_trap_p): New function.
|
||||
(sched_analyze_2): Use it.
|
||||
|
||||
2001-01-03 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* combine.c (simplify_shift_const): Even if we're sign-extracting,
|
||||
|
78
gcc/alias.c
78
gcc/alias.c
@ -148,7 +148,8 @@ static rtx *new_reg_base_value;
|
||||
static unsigned int reg_base_value_size; /* size of reg_base_value array */
|
||||
|
||||
#define REG_BASE_VALUE(X) \
|
||||
(REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
|
||||
(ORIGINAL_REGNO (X) < reg_base_value_size \
|
||||
? reg_base_value[ORIGINAL_REGNO (X)] : 0)
|
||||
|
||||
/* Vector of known invariant relationships between registers. Set in
|
||||
loop unrolling. Indexed by register number, if nonzero the value
|
||||
@ -659,6 +660,7 @@ static rtx
|
||||
find_base_value (src)
|
||||
register rtx src;
|
||||
{
|
||||
unsigned int regno;
|
||||
switch (GET_CODE (src))
|
||||
{
|
||||
case SYMBOL_REF:
|
||||
@ -666,12 +668,13 @@ find_base_value (src)
|
||||
return src;
|
||||
|
||||
case REG:
|
||||
regno = ORIGINAL_REGNO (src);
|
||||
/* 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 new_reg_base_value[REGNO (src)];
|
||||
if (regno < FIRST_PSEUDO_REGISTER && copying_arguments)
|
||||
return new_reg_base_value[regno];
|
||||
|
||||
/* If a pseudo has a known base value, return it. Do not do this
|
||||
for hard regs since it can result in a circular dependency
|
||||
@ -679,10 +682,10 @@ find_base_value (src)
|
||||
|
||||
The test above is not sufficient because the scheduler may move
|
||||
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
|
||||
if (REGNO (src) >= FIRST_PSEUDO_REGISTER
|
||||
&& (unsigned) REGNO (src) < reg_base_value_size
|
||||
&& reg_base_value[REGNO (src)])
|
||||
return reg_base_value[REGNO (src)];
|
||||
if (regno >= FIRST_PSEUDO_REGISTER
|
||||
&& regno < reg_base_value_size
|
||||
&& reg_base_value[regno])
|
||||
return reg_base_value[regno];
|
||||
|
||||
return src;
|
||||
|
||||
@ -789,7 +792,7 @@ record_set (dest, set, data)
|
||||
if (GET_CODE (dest) != REG)
|
||||
return;
|
||||
|
||||
regno = REGNO (dest);
|
||||
regno = ORIGINAL_REGNO (dest);
|
||||
|
||||
if (regno >= reg_base_value_size)
|
||||
abort ();
|
||||
@ -870,8 +873,8 @@ record_base_value (regno, val, invariant)
|
||||
|
||||
if (GET_CODE (val) == REG)
|
||||
{
|
||||
if (REGNO (val) < reg_base_value_size)
|
||||
reg_base_value[regno] = reg_base_value[REGNO (val)];
|
||||
if (ORIGINAL_REGNO (val) < reg_base_value_size)
|
||||
reg_base_value[regno] = reg_base_value[ORIGINAL_REGNO (val)];
|
||||
|
||||
return;
|
||||
}
|
||||
@ -889,10 +892,10 @@ canon_rtx (x)
|
||||
rtx x;
|
||||
{
|
||||
/* Recursively look for equivalences. */
|
||||
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
|
||||
&& REGNO (x) < reg_known_value_size)
|
||||
return reg_known_value[REGNO (x)] == x
|
||||
? x : canon_rtx (reg_known_value[REGNO (x)]);
|
||||
if (GET_CODE (x) == REG && ORIGINAL_REGNO (x) >= FIRST_PSEUDO_REGISTER
|
||||
&& ORIGINAL_REGNO (x) < reg_known_value_size)
|
||||
return reg_known_value[ORIGINAL_REGNO (x)] == x
|
||||
? x : canon_rtx (reg_known_value[ORIGINAL_REGNO (x)]);
|
||||
else if (GET_CODE (x) == PLUS)
|
||||
{
|
||||
rtx x0 = canon_rtx (XEXP (x, 0));
|
||||
@ -2208,17 +2211,42 @@ init_alias_analysis ()
|
||||
|
||||
if (set != 0
|
||||
&& GET_CODE (SET_DEST (set)) == REG
|
||||
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
|
||||
&& REG_NOTES (insn) != 0
|
||||
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
|
||||
&& REG_N_SETS (REGNO (SET_DEST (set))) == 1)
|
||||
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
|
||||
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST
|
||||
&& ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
|
||||
&& ORIGINAL_REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
int regno = REGNO (SET_DEST (set));
|
||||
reg_known_value[regno] = XEXP (note, 0);
|
||||
reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
|
||||
unsigned int regno = ORIGINAL_REGNO (SET_DEST (set));
|
||||
rtx src = SET_SRC (set);
|
||||
|
||||
if (REG_NOTES (insn) != 0
|
||||
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
|
||||
&& REG_N_SETS (regno) == 1)
|
||||
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
|
||||
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST
|
||||
&& ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
|
||||
{
|
||||
reg_known_value[regno] = XEXP (note, 0);
|
||||
reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
|
||||
}
|
||||
else if (REG_N_SETS (regno) == 1
|
||||
&& GET_CODE (src) == PLUS
|
||||
&& GET_CODE (XEXP (src, 0)) == REG
|
||||
&& ORIGINAL_REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
|
||||
&& (reg_known_value[ORIGINAL_REGNO (XEXP (src, 0))])
|
||||
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
|
||||
{
|
||||
rtx op0 = XEXP (src, 0);
|
||||
if (reg_known_value[ORIGINAL_REGNO (op0)])
|
||||
op0 = reg_known_value[ORIGINAL_REGNO (op0)];
|
||||
reg_known_value[regno]
|
||||
= plus_constant_for_output (op0,
|
||||
INTVAL (XEXP (src, 1)));
|
||||
reg_known_equiv_p[regno] = 0;
|
||||
}
|
||||
else if (REG_N_SETS (regno) == 1
|
||||
&& ! rtx_varies_p (src, 1))
|
||||
{
|
||||
reg_known_value[regno] = src;
|
||||
reg_known_equiv_p[regno] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (insn) == NOTE
|
||||
@ -2265,7 +2293,7 @@ init_alias_analysis ()
|
||||
rtx base = reg_base_value[ui];
|
||||
if (base && GET_CODE (base) == REG)
|
||||
{
|
||||
unsigned int base_regno = REGNO (base);
|
||||
unsigned int base_regno = ORIGINAL_REGNO (base);
|
||||
if (base_regno == ui) /* register set from itself */
|
||||
reg_base_value[ui] = 0;
|
||||
else
|
||||
|
@ -74,6 +74,7 @@ static sbitmap *output_dependency_cache;
|
||||
static sbitmap *forward_dependency_cache;
|
||||
#endif
|
||||
|
||||
static int deps_may_trap_p PARAMS ((rtx));
|
||||
static void remove_dependence PARAMS ((rtx, rtx));
|
||||
static void set_sched_group_p PARAMS ((rtx));
|
||||
|
||||
@ -86,6 +87,21 @@ static rtx group_leader PARAMS ((rtx));
|
||||
static rtx get_condition PARAMS ((rtx));
|
||||
static int conditions_mutex_p PARAMS ((rtx, rtx));
|
||||
|
||||
/* Return nonzero if a load of the memory reference MEM can cause a trap. */
|
||||
|
||||
static int
|
||||
deps_may_trap_p (mem)
|
||||
rtx mem;
|
||||
{
|
||||
rtx addr = XEXP (mem, 0);
|
||||
|
||||
if (REG_P (addr)
|
||||
&& ORIGINAL_REGNO (addr) >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_known_value[ORIGINAL_REGNO (addr)])
|
||||
addr = reg_known_value[ORIGINAL_REGNO (addr)];
|
||||
return rtx_addr_can_trap_p (addr);
|
||||
}
|
||||
|
||||
/* Return the INSN_LIST containing INSN in LIST, or NULL
|
||||
if LIST does not contain INSN. */
|
||||
|
||||
@ -817,7 +833,9 @@ sched_analyze_2 (deps, x, insn)
|
||||
}
|
||||
|
||||
for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1))
|
||||
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
|
||||
if (GET_CODE (XEXP (u, 0)) != JUMP_INSN
|
||||
|| deps_may_trap_p (x))
|
||||
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
|
||||
|
||||
/* Always add these dependencies to pending_reads, since
|
||||
this insn may be followed by a write. */
|
||||
|
Loading…
Reference in New Issue
Block a user