Avoid unnecessary dependencies on COND_EXEC insns.

From-SVN: r38496
This commit is contained in:
Bernd Schmidt 2000-12-27 12:55:16 +00:00 committed by Bernd Schmidt
parent 6cbadf36b2
commit 0a1bb917fc
2 changed files with 99 additions and 16 deletions

View File

@ -1,3 +1,11 @@
2000-12-27 Bernd Schmidt <bernds@redhat.com>
* sched-deps.c (get_condition, conditions_mutex_p): New functions.
(add_dependence): Use them to avoid adding unnecessary dependencies
between conditionally executed insns.
(sched_analyze_1, sched_analyze_2, sched_analyze_insn): Don't free
dependency lists if current insn is a COND_EXEC.
2000-12-27 Geoffrey Keating <geoffk@redhat.com> 2000-12-27 Geoffrey Keating <geoffk@redhat.com>
* config/rs6000/rs6000.md (define_attr "length"): Correct * config/rs6000/rs6000.md (define_attr "length"): Correct

View File

@ -82,6 +82,9 @@ static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx));
static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx)); static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx));
static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx)); static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx));
static rtx group_leader PARAMS ((rtx)); static rtx group_leader PARAMS ((rtx));
static rtx get_condition PARAMS ((rtx));
static int conditions_mutex_p PARAMS ((rtx, rtx));
/* 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. */
@ -119,6 +122,53 @@ find_insn_mem_list (insn, x, list, list1)
return 0; return 0;
} }
/* Find the condition under which INSN is executed. */
static rtx
get_condition (insn)
rtx insn;
{
rtx pat = PATTERN (insn);
rtx cond;
if (pat == 0)
return 0;
if (GET_CODE (pat) == COND_EXEC)
return COND_EXEC_TEST (pat);
if (GET_CODE (insn) != JUMP_INSN)
return 0;
if (GET_CODE (pat) != SET || SET_SRC (pat) != pc_rtx)
return 0;
if (GET_CODE (SET_DEST (pat)) != IF_THEN_ELSE)
return 0;
pat = SET_DEST (pat);
cond = XEXP (pat, 0);
if (GET_CODE (XEXP (cond, 1)) == LABEL_REF
&& XEXP (cond, 2) == pc_rtx)
return cond;
else if (GET_CODE (XEXP (cond, 2)) == LABEL_REF
&& XEXP (cond, 1) == pc_rtx)
return gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)), GET_MODE (cond),
XEXP (cond, 0), XEXP (cond, 1));
else
return 0;
}
/* Return nonzero if conditions COND1 and COND2 can never be both true. */
static int
conditions_mutex_p (cond1, cond2)
rtx cond1, cond2;
{
if (GET_RTX_CLASS (GET_CODE (cond1)) == '<'
&& GET_RTX_CLASS (GET_CODE (cond2)) == '<'
&& GET_CODE (cond1) == reverse_condition (GET_CODE (cond2))
&& XEXP (cond1, 0) == XEXP (cond2, 0)
&& XEXP (cond1, 1) == XEXP (cond2, 1))
return 1;
return 0;
}
/* Add ELEM wrapped in an INSN_LIST with reg note kind DEP_TYPE to the /* Add ELEM wrapped in an INSN_LIST with reg note kind DEP_TYPE to the
LOG_LINKS of INSN, if not already there. DEP_TYPE indicates the type LOG_LINKS of INSN, if not already there. DEP_TYPE indicates the type
of dependence that this link represents. */ of dependence that this link represents. */
@ -132,6 +182,7 @@ add_dependence (insn, elem, dep_type)
rtx link, next; rtx link, next;
int present_p; int present_p;
enum reg_note present_dep_type; enum reg_note present_dep_type;
rtx cond1, cond2;
/* Don't depend an insn on itself. */ /* Don't depend an insn on itself. */
if (insn == elem) if (insn == elem)
@ -143,6 +194,16 @@ add_dependence (insn, elem, dep_type)
if (GET_CODE (elem) == NOTE) if (GET_CODE (elem) == NOTE)
return; return;
/* flow.c doesn't handle conditional lifetimes entirely correctly;
calls mess up the conditional lifetimes. */
if (GET_CODE (insn) != CALL_INSN && GET_CODE (elem) != CALL_INSN)
{
cond1 = get_condition (insn);
cond2 = get_condition (elem);
if (cond1 && cond2 && conditions_mutex_p (cond1, cond2))
return;
}
/* If elem is part of a sequence that must be scheduled together, then /* If elem is part of a sequence that must be scheduled together, then
make the dependence point to the last insn of the sequence. make the dependence point to the last insn of the sequence.
When HAVE_cc0, it is possible for NOTEs to exist between users and When HAVE_cc0, it is possible for NOTEs to exist between users and
@ -524,7 +585,8 @@ sched_analyze_1 (deps, x, insn)
pending clobber. */ pending clobber. */
if (code == SET) if (code == SET)
{ {
free_INSN_LIST_list (&deps->reg_last_uses[r]); if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&deps->reg_last_uses[r]);
for (u = deps->reg_last_clobbers[r]; u; u = XEXP (u, 1)) for (u = deps->reg_last_clobbers[r]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT); add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
SET_REGNO_REG_SET (reg_pending_sets, r); SET_REGNO_REG_SET (reg_pending_sets, r);
@ -550,7 +612,8 @@ sched_analyze_1 (deps, x, insn)
if (code == SET) if (code == SET)
{ {
free_INSN_LIST_list (&deps->reg_last_uses[regno]); if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&deps->reg_last_uses[regno]);
for (u = deps->reg_last_clobbers[regno]; u; u = XEXP (u, 1)) for (u = deps->reg_last_clobbers[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT); add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
SET_REGNO_REG_SET (reg_pending_sets, regno); SET_REGNO_REG_SET (reg_pending_sets, regno);
@ -791,7 +854,8 @@ sched_analyze_2 (deps, x, insn)
{ {
for (u = deps->reg_last_uses[i]; u; u = XEXP (u, 1)) for (u = deps->reg_last_uses[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI); add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
free_INSN_LIST_list (&deps->reg_last_uses[i]); if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&deps->reg_last_uses[i]);
for (u = deps->reg_last_sets[i]; u; u = XEXP (u, 1)) for (u = deps->reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0); add_dependence (insn, XEXP (u, 0), 0);
@ -997,7 +1061,8 @@ sched_analyze_insn (deps, x, insn, loop_notes)
rtx u; rtx u;
for (u = deps->reg_last_uses[i]; u; u = XEXP (u, 1)) for (u = deps->reg_last_uses[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI); add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
free_INSN_LIST_list (&deps->reg_last_uses[i]); if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&deps->reg_last_uses[i]);
for (u = deps->reg_last_sets[i]; u; u = XEXP (u, 1)) for (u = deps->reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0); add_dependence (insn, XEXP (u, 0), 0);
@ -1017,17 +1082,22 @@ sched_analyze_insn (deps, x, insn, loop_notes)
subsequent sets will be output dependent on it. */ subsequent sets will be output dependent on it. */
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(reg_pending_sets, 0, i, (reg_pending_sets, 0, i,
{ {
free_INSN_LIST_list (&deps->reg_last_sets[i]); if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&deps->reg_last_clobbers[i]); {
deps->reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX); free_INSN_LIST_list (&deps->reg_last_sets[i]);
}); free_INSN_LIST_list (&deps->reg_last_clobbers[i]);
deps->reg_last_sets[i] = 0;
}
deps->reg_last_sets[i]
= alloc_INSN_LIST (insn, deps->reg_last_sets[i]);
});
EXECUTE_IF_SET_IN_REG_SET EXECUTE_IF_SET_IN_REG_SET
(reg_pending_clobbers, 0, i, (reg_pending_clobbers, 0, i,
{ {
deps->reg_last_clobbers[i] deps->reg_last_clobbers[i]
= alloc_INSN_LIST (insn, deps->reg_last_clobbers[i]); = alloc_INSN_LIST (insn, deps->reg_last_clobbers[i]);
}); });
CLEAR_REG_SET (reg_pending_sets); CLEAR_REG_SET (reg_pending_sets);
CLEAR_REG_SET (reg_pending_clobbers); CLEAR_REG_SET (reg_pending_clobbers);
@ -1035,9 +1105,14 @@ sched_analyze_insn (deps, x, insn, loop_notes)
{ {
for (i = 0; i < maxreg; i++) for (i = 0; i < maxreg; i++)
{ {
free_INSN_LIST_list (&deps->reg_last_sets[i]); if (GET_CODE (PATTERN (insn)) != COND_EXEC)
free_INSN_LIST_list (&deps->reg_last_clobbers[i]); {
deps->reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX); free_INSN_LIST_list (&deps->reg_last_sets[i]);
free_INSN_LIST_list (&deps->reg_last_clobbers[i]);
deps->reg_last_sets[i] = 0;
}
deps->reg_last_sets[i]
= alloc_INSN_LIST (insn, deps->reg_last_sets[i]);
} }
reg_pending_sets_all = 0; reg_pending_sets_all = 0;