diff options
author | Richard Henderson <rth@redhat.com> | 2001-12-29 10:46:38 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-12-29 10:46:38 -0800 |
commit | b7fe373bfb4dbbde0178914b2218862f7677b69d (patch) | |
tree | 35b7bc875a47a23ed39a2fd5552bbadc94584ca1 | |
parent | 4e5ea414df790f3de4acff45cd2fc8be4d5e3fff (diff) | |
download | gcc-b7fe373bfb4dbbde0178914b2218862f7677b69d.zip gcc-b7fe373bfb4dbbde0178914b2218862f7677b69d.tar.gz gcc-b7fe373bfb4dbbde0178914b2218862f7677b69d.tar.bz2 |
loop.c (prescan_loop): Set has_multiple_exit_targets for exception edges.
* loop.c (prescan_loop): Set has_multiple_exit_targets for exception
edges. Rearrange jump interpretation code to use pc_set.
(check_dbra_loop): Examine has_multiple_exit_targets not exit_count.
* sched-deps.c (sched_analyze_insn): Set scheduling barrier for
all insns that can throw, not just if flag_non_call_exceptions.
From-SVN: r48377
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/loop.c | 127 | ||||
-rw-r--r-- | gcc/sched-deps.c | 2 |
3 files changed, 82 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a34e7d7..07a78e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2001-12-29 Richard Henderson <rth@redhat.com> + + * loop.c (prescan_loop): Set has_multiple_exit_targets for exception + edges. Rearrange jump interpretation code to use pc_set. + (check_dbra_loop): Examine has_multiple_exit_targets not exit_count. + + * sched-deps.c (sched_analyze_insn): Set scheduling barrier for + all insns that can throw, not just if flag_non_call_exceptions. + 2001-12-29 Stan Shebs <shebs@apple.com> * objc/objc-act.c (STRING_OBJECT_CLASS_NAME): Remove. @@ -2450,8 +2450,9 @@ prescan_loop (loop) for (insn = NEXT_INSN (start); insn != NEXT_INSN (end); insn = NEXT_INSN (insn)) { - if (GET_CODE (insn) == NOTE) + switch (GET_CODE (insn)) { + case NOTE: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG) { ++level; @@ -2459,24 +2460,73 @@ prescan_loop (loop) loop->level++; } else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END) - { - --level; - } - } - else if (GET_CODE (insn) == CALL_INSN) - { + --level; + break; + + case CALL_INSN: if (! CONST_OR_PURE_CALL_P (insn)) { loop_info->unknown_address_altered = 1; loop_info->has_nonconst_call = 1; } loop_info->has_call = 1; - } - else if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) - { - rtx label1 = NULL_RTX; - rtx label2 = NULL_RTX; + if (can_throw_internal (insn)) + loop_info->has_multiple_exit_targets = 1; + break; + + case JUMP_INSN: + if (! loop_info->has_multiple_exit_targets) + { + rtx set = pc_set (insn); + + if (set) + { + rtx label1, label2; + + if (GET_CODE (SET_SRC (set)) == IF_THEN_ELSE) + { + label1 = XEXP (SET_SRC (set), 1); + label2 = XEXP (SET_SRC (set), 2); + } + else + { + label1 = SET_SRC (PATTERN (insn)); + label2 = NULL_RTX; + } + + do + { + if (label1 && label1 != pc_rtx) + { + if (GET_CODE (label1) != LABEL_REF) + { + /* Something tricky. */ + loop_info->has_multiple_exit_targets = 1; + break; + } + else if (XEXP (label1, 0) != exit_target + && LABEL_OUTSIDE_LOOP_P (label1)) + { + /* A jump outside the current loop. */ + loop_info->has_multiple_exit_targets = 1; + break; + } + } + + label1 = label2; + label2 = NULL_RTX; + } + while (label1); + } + else + { + /* A return, or something tricky. */ + loop_info->has_multiple_exit_targets = 1; + } + } + /* FALLTHRU */ + case INSN: if (volatile_refs_p (PATTERN (insn))) loop_info->has_volatile = 1; @@ -2489,48 +2539,13 @@ prescan_loop (loop) if (! loop_info->first_loop_store_insn && loop_info->store_mems) loop_info->first_loop_store_insn = insn; - if (! loop_info->has_multiple_exit_targets - && GET_CODE (insn) == JUMP_INSN - && GET_CODE (PATTERN (insn)) == SET - && SET_DEST (PATTERN (insn)) == pc_rtx) - { - if (GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE) - { - label1 = XEXP (SET_SRC (PATTERN (insn)), 1); - label2 = XEXP (SET_SRC (PATTERN (insn)), 2); - } - else - { - label1 = SET_SRC (PATTERN (insn)); - } - - do - { - if (label1 && label1 != pc_rtx) - { - if (GET_CODE (label1) != LABEL_REF) - { - /* Something tricky. */ - loop_info->has_multiple_exit_targets = 1; - break; - } - else if (XEXP (label1, 0) != exit_target - && LABEL_OUTSIDE_LOOP_P (label1)) - { - /* A jump outside the current loop. */ - loop_info->has_multiple_exit_targets = 1; - break; - } - } + if (flag_non_call_exceptions && can_throw_internal (insn)) + loop_info->has_multiple_exit_targets = 1; + break; - label1 = label2; - label2 = NULL_RTX; - } - while (label1); - } + default: + break; } - else if (GET_CODE (insn) == RETURN) - loop_info->has_multiple_exit_targets = 1; } /* Now, rescan the loop, setting up the LOOP_MEMS array. */ @@ -7962,7 +7977,7 @@ check_dbra_loop (loop, insn_count) which is reversible. */ int reversible_mem_store = 1; - if (bl->giv_count == 0 && ! loop->exit_count) + if (bl->giv_count == 0 && ! loop_info->has_multiple_exit_targets) { rtx bivreg = regno_reg_rtx[bl->regno]; struct iv_class *blt; @@ -8003,9 +8018,11 @@ check_dbra_loop (loop, insn_count) } } - /* A biv has uses besides counting if it is used to set another biv. */ + /* A biv has uses besides counting if it is used to set + another biv. */ for (blt = ivs->list; blt; blt = blt->next) - if (blt->init_set && reg_mentioned_p (bivreg, SET_SRC (blt->init_set))) + if (blt->init_set + && reg_mentioned_p (bivreg, SET_SRC (blt->init_set))) { no_use_except_counting = 0; break; diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 13e929c..e315a4c 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -1141,7 +1141,7 @@ sched_analyze_insn (deps, x, insn, loop_notes) /* If this instruction can throw an exception, then moving it changes where block boundaries fall. This is mighty confusing elsewhere. Therefore, prevent such an instruction from being moved. */ - if (flag_non_call_exceptions && can_throw_internal (insn)) + if (can_throw_internal (insn)) schedule_barrier_found = 1; /* Add dependencies if a scheduling barrier was found. */ |