From 4164e76b80b7edc96585b39d6d4b1b4b85c8116b Mon Sep 17 00:00:00 2001 From: bernds Date: Wed, 27 Dec 2000 12:55:16 +0000 Subject: [PATCH] Avoid unnecessary dependencies on COND_EXEC insns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38496 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 +++++ gcc/sched-deps.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 99 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad406bdb062..9be4297c4bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2000-12-27 Bernd Schmidt + + * 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 * config/rs6000/rs6000.md (define_attr "length"): Correct diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 396b519b164..8d1e2f7ad2c 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -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_insn PARAMS ((struct deps *, rtx, rtx, 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 if LIST does not contain INSN. */ @@ -119,6 +122,53 @@ find_insn_mem_list (insn, x, list, list1) 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 LOG_LINKS of INSN, if not already there. DEP_TYPE indicates the type of dependence that this link represents. */ @@ -132,6 +182,7 @@ add_dependence (insn, elem, dep_type) rtx link, next; int present_p; enum reg_note present_dep_type; + rtx cond1, cond2; /* Don't depend an insn on itself. */ if (insn == elem) @@ -143,6 +194,16 @@ add_dependence (insn, elem, dep_type) if (GET_CODE (elem) == NOTE) 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 make the dependence point to the last insn of the sequence. 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. */ 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)) add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT); SET_REGNO_REG_SET (reg_pending_sets, r); @@ -550,7 +612,8 @@ sched_analyze_1 (deps, x, insn) 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)) add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT); 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)) 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)) add_dependence (insn, XEXP (u, 0), 0); @@ -997,7 +1061,8 @@ sched_analyze_insn (deps, x, insn, loop_notes) rtx u; for (u = deps->reg_last_uses[i]; u; u = XEXP (u, 1)) 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)) 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. */ EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, - { - free_INSN_LIST_list (&deps->reg_last_sets[i]); - free_INSN_LIST_list (&deps->reg_last_clobbers[i]); - deps->reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX); - }); + { + if (GET_CODE (PATTERN (insn)) != COND_EXEC) + { + 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 (reg_pending_clobbers, 0, i, - { - deps->reg_last_clobbers[i] - = alloc_INSN_LIST (insn, deps->reg_last_clobbers[i]); - }); + { + 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_clobbers); @@ -1035,9 +1105,14 @@ sched_analyze_insn (deps, x, insn, loop_notes) { for (i = 0; i < maxreg; i++) { - free_INSN_LIST_list (&deps->reg_last_sets[i]); - free_INSN_LIST_list (&deps->reg_last_clobbers[i]); - deps->reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX); + if (GET_CODE (PATTERN (insn)) != COND_EXEC) + { + 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; -- 2.11.4.GIT