aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-12-29 10:46:38 -0800
committerRichard Henderson <rth@gcc.gnu.org>2001-12-29 10:46:38 -0800
commitb7fe373bfb4dbbde0178914b2218862f7677b69d (patch)
tree35b7bc875a47a23ed39a2fd5552bbadc94584ca1
parent4e5ea414df790f3de4acff45cd2fc8be4d5e3fff (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/loop.c127
-rw-r--r--gcc/sched-deps.c2
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.
diff --git a/gcc/loop.c b/gcc/loop.c
index 5678354..2069588 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -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. */