Commit 713f41f9 by Bernd Schmidt Committed by Bernd Schmidt

Improve alias analysis for ia64

From-SVN: r38660
parent 03378143
...@@ -16,6 +16,12 @@ Wed Jan 3 08:53:50 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> ...@@ -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 * cse.c (cse_rtx_varies_p): Accept additional FROM_ALIAS arg. All
callers changed. 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> 2001-01-03 Alexandre Oliva <aoliva@redhat.com>
* combine.c (simplify_shift_const): Even if we're sign-extracting, * combine.c (simplify_shift_const): Even if we're sign-extracting,
......
...@@ -148,7 +148,8 @@ static rtx *new_reg_base_value; ...@@ -148,7 +148,8 @@ static rtx *new_reg_base_value;
static unsigned int reg_base_value_size; /* size of reg_base_value array */ static 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) (ORIGINAL_REGNO (X) < reg_base_value_size \
? reg_base_value[ORIGINAL_REGNO (X)] : 0)
/* Vector of known invariant relationships between registers. Set in /* Vector of known invariant relationships between registers. Set in
loop unrolling. Indexed by register number, if nonzero the value loop unrolling. Indexed by register number, if nonzero the value
...@@ -659,6 +660,7 @@ static rtx ...@@ -659,6 +660,7 @@ static rtx
find_base_value (src) find_base_value (src)
register rtx src; register rtx src;
{ {
unsigned int regno;
switch (GET_CODE (src)) switch (GET_CODE (src))
{ {
case SYMBOL_REF: case SYMBOL_REF:
...@@ -666,12 +668,13 @@ find_base_value (src) ...@@ -666,12 +668,13 @@ find_base_value (src)
return src; return src;
case REG: case REG:
regno = ORIGINAL_REGNO (src);
/* At the start of a function, argument registers have known base /* At the start of a function, argument registers have known base
values which may be lost later. Returning an ADDRESS values which may be lost later. Returning an ADDRESS
expression here allows optimization based on argument values expression here allows optimization based on argument values
even when the argument registers are used for other purposes. */ even when the argument registers are used for other purposes. */
if (REGNO (src) < FIRST_PSEUDO_REGISTER && copying_arguments) if (regno < FIRST_PSEUDO_REGISTER && copying_arguments)
return new_reg_base_value[REGNO (src)]; return new_reg_base_value[regno];
/* If a pseudo has a known base value, return it. Do not do this /* 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 for hard regs since it can result in a circular dependency
...@@ -679,10 +682,10 @@ find_base_value (src) ...@@ -679,10 +682,10 @@ find_base_value (src)
The test above is not sufficient because the scheduler may move The test above is not sufficient because the scheduler may move
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */ a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
if (REGNO (src) >= FIRST_PSEUDO_REGISTER if (regno >= FIRST_PSEUDO_REGISTER
&& (unsigned) REGNO (src) < reg_base_value_size && regno < reg_base_value_size
&& reg_base_value[REGNO (src)]) && reg_base_value[regno])
return reg_base_value[REGNO (src)]; return reg_base_value[regno];
return src; return src;
...@@ -789,7 +792,7 @@ record_set (dest, set, data) ...@@ -789,7 +792,7 @@ record_set (dest, set, data)
if (GET_CODE (dest) != REG) if (GET_CODE (dest) != REG)
return; return;
regno = REGNO (dest); regno = ORIGINAL_REGNO (dest);
if (regno >= reg_base_value_size) if (regno >= reg_base_value_size)
abort (); abort ();
...@@ -870,8 +873,8 @@ record_base_value (regno, val, invariant) ...@@ -870,8 +873,8 @@ record_base_value (regno, val, invariant)
if (GET_CODE (val) == REG) if (GET_CODE (val) == REG)
{ {
if (REGNO (val) < reg_base_value_size) if (ORIGINAL_REGNO (val) < reg_base_value_size)
reg_base_value[regno] = reg_base_value[REGNO (val)]; reg_base_value[regno] = reg_base_value[ORIGINAL_REGNO (val)];
return; return;
} }
...@@ -889,10 +892,10 @@ canon_rtx (x) ...@@ -889,10 +892,10 @@ canon_rtx (x)
rtx x; rtx x;
{ {
/* Recursively look for equivalences. */ /* Recursively look for equivalences. */
if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER if (GET_CODE (x) == REG && ORIGINAL_REGNO (x) >= FIRST_PSEUDO_REGISTER
&& REGNO (x) < reg_known_value_size) && ORIGINAL_REGNO (x) < reg_known_value_size)
return reg_known_value[REGNO (x)] == x return reg_known_value[ORIGINAL_REGNO (x)] == x
? x : canon_rtx (reg_known_value[REGNO (x)]); ? x : canon_rtx (reg_known_value[ORIGINAL_REGNO (x)]);
else if (GET_CODE (x) == PLUS) else if (GET_CODE (x) == PLUS)
{ {
rtx x0 = canon_rtx (XEXP (x, 0)); rtx x0 = canon_rtx (XEXP (x, 0));
...@@ -2208,17 +2211,42 @@ init_alias_analysis () ...@@ -2208,17 +2211,42 @@ init_alias_analysis ()
if (set != 0 if (set != 0
&& GET_CODE (SET_DEST (set)) == REG && GET_CODE (SET_DEST (set)) == REG
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER && ORIGINAL_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)))
{ {
int regno = REGNO (SET_DEST (set)); unsigned int regno = ORIGINAL_REGNO (SET_DEST (set));
reg_known_value[regno] = XEXP (note, 0); rtx src = SET_SRC (set);
reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
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 else if (GET_CODE (insn) == NOTE
...@@ -2265,7 +2293,7 @@ init_alias_analysis () ...@@ -2265,7 +2293,7 @@ init_alias_analysis ()
rtx base = reg_base_value[ui]; rtx base = reg_base_value[ui];
if (base && GET_CODE (base) == REG) 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 */ if (base_regno == ui) /* register set from itself */
reg_base_value[ui] = 0; reg_base_value[ui] = 0;
else else
......
...@@ -74,6 +74,7 @@ static sbitmap *output_dependency_cache; ...@@ -74,6 +74,7 @@ static sbitmap *output_dependency_cache;
static sbitmap *forward_dependency_cache; static sbitmap *forward_dependency_cache;
#endif #endif
static int deps_may_trap_p PARAMS ((rtx));
static void remove_dependence PARAMS ((rtx, rtx)); static void remove_dependence PARAMS ((rtx, rtx));
static void set_sched_group_p PARAMS ((rtx)); static void set_sched_group_p PARAMS ((rtx));
...@@ -86,6 +87,21 @@ static rtx group_leader PARAMS ((rtx)); ...@@ -86,6 +87,21 @@ static rtx group_leader PARAMS ((rtx));
static rtx get_condition PARAMS ((rtx)); static rtx get_condition PARAMS ((rtx));
static int conditions_mutex_p PARAMS ((rtx, 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 /* Return the INSN_LIST containing INSN in LIST, or NULL
if LIST does not contain INSN. */ if LIST does not contain INSN. */
...@@ -817,7 +833,9 @@ sched_analyze_2 (deps, x, insn) ...@@ -817,7 +833,9 @@ sched_analyze_2 (deps, x, insn)
} }
for (u = deps->last_pending_memory_flush; u; u = XEXP (u, 1)) 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 /* Always add these dependencies to pending_reads, since
this insn may be followed by a write. */ this insn may be followed by a write. */
......
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