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
This commit is contained in:
Richard Henderson 2001-12-29 10:46:38 -08:00 committed by Richard Henderson
parent 4e5ea414df
commit b7fe373bfb
3 changed files with 82 additions and 56 deletions

View File

@ -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.

View File

@ -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));
}
if (flag_non_call_exceptions && can_throw_internal (insn))
loop_info->has_multiple_exit_targets = 1;
break;
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);
}
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;

View File

@ -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. */