Commit b9185691 by Eric Botcazou Committed by Eric Botcazou

re PR bootstrap/16326 (Bootstrap failure after "RTL prologue/epilogue for SPARC" patch)

	PR bootstrap/16326
	* reorg.c: Revert 2004-06-30 change.
	(find_end_label): If HAVE_epilogue and !HAVE_return,
	return 0 instead of creating a label at the end of the insn chain.
	(optimize_skip): Account for the failure mode of find_end_label.
	(fill_simple_delay_slots): Likewise.
	(fill_slots_from_thread): Likewise.
	(relax_delay_slots): Likewise.

From-SVN: r84273
parent a6d02559
2004-07-08 Eric Botcazou <ebotcazou@libertysurf.fr>
PR bootstrap/16326
* reorg.c: Revert 2004-06-30 change.
(find_end_label): If HAVE_epilogue and !HAVE_return,
return 0 instead of creating a label at the end of the insn chain.
(optimize_skip): Account for the failure mode of find_end_label.
(fill_simple_delay_slots): Likewise.
(fill_slots_from_thread): Likewise.
(relax_delay_slots): Likewise.
2004-07-08 Diego Novillo <dnovillo@redhat.com> 2004-07-08 Diego Novillo <dnovillo@redhat.com>
* tree-flow.h (addressable_vars): Declare. * tree-flow.h (addressable_vars): Declare.
......
...@@ -317,23 +317,25 @@ insn_sets_resource_p (rtx insn, struct resources *res, ...@@ -317,23 +317,25 @@ insn_sets_resource_p (rtx insn, struct resources *res,
mark_set_resources (insn, &insn_sets, 0, include_delayed_effects); mark_set_resources (insn, &insn_sets, 0, include_delayed_effects);
return resource_conflicts_p (&insn_sets, res); return resource_conflicts_p (&insn_sets, res);
} }
/* Return TRUE if INSN is a return, possibly with a filled delay slot. */
static bool
return_insn_p (rtx insn)
{
if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == RETURN)
return true;
if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
return return_insn_p (XVECEXP (PATTERN (insn), 0, 0));
return false;
}
/* Find a label at the end of the function or before a RETURN. If there is /* Find a label at the end of the function or before a RETURN. If there
none, make one. */ is none, try to make one. If that fails, returns 0.
The property of such a label is that it is placed just before the
epilogue or a bare RETURN insn, so that another bare RETURN can be
turned into a jump to the label unconditionally. In particular, the
label cannot be placed before a RETURN insn with a filled delay slot.
??? There may be a problem with the current implementation. Suppose
we start with a bare RETURN insn and call find_end_label. It may set
end_of_function_label just before the RETURN. Suppose the machinery
is able to fill the delay slot of the RETURN insn afterwards. Then
end_of_function_label is no longer valid according to the property
described above and find_end_label will still return it unmodified.
Note that this is probably mitigated by the following observation:
once end_of_function_label is made, it is very likely the target of
a jump, so filling the delay slot of the RETURN will be much more
difficult. */
static rtx static rtx
find_end_label (void) find_end_label (void)
...@@ -358,13 +360,15 @@ find_end_label (void) ...@@ -358,13 +360,15 @@ find_end_label (void)
/* When a target threads its epilogue we might already have a /* When a target threads its epilogue we might already have a
suitable return insn. If so put a label before it for the suitable return insn. If so put a label before it for the
end_of_function_label. */ end_of_function_label. */
if (GET_CODE (insn) == BARRIER && return_insn_p (PREV_INSN (insn))) if (GET_CODE (insn) == BARRIER
&& GET_CODE (PREV_INSN (insn)) == JUMP_INSN
&& GET_CODE (PATTERN (PREV_INSN (insn))) == RETURN)
{ {
rtx temp = PREV_INSN (PREV_INSN (insn)); rtx temp = PREV_INSN (PREV_INSN (insn));
end_of_function_label = gen_label_rtx (); end_of_function_label = gen_label_rtx ();
LABEL_NUSES (end_of_function_label) = 0; LABEL_NUSES (end_of_function_label) = 0;
/* Put the label before an USE insn that may precede the RETURN insn. */ /* Put the label before an USE insns that may precede the RETURN insn. */
while (GET_CODE (temp) == USE) while (GET_CODE (temp) == USE)
temp = PREV_INSN (temp); temp = PREV_INSN (temp);
...@@ -380,7 +384,8 @@ find_end_label (void) ...@@ -380,7 +384,8 @@ find_end_label (void)
/* If the basic block reorder pass moves the return insn to /* If the basic block reorder pass moves the return insn to
some other place try to locate it again and put our some other place try to locate it again and put our
end_of_function_label there. */ end_of_function_label there. */
while (insn && ! return_insn_p (insn)) while (insn && ! (GET_CODE (insn) == JUMP_INSN
&& (GET_CODE (PATTERN (insn)) == RETURN)))
insn = PREV_INSN (insn); insn = PREV_INSN (insn);
if (insn) if (insn)
{ {
...@@ -395,6 +400,22 @@ find_end_label (void) ...@@ -395,6 +400,22 @@ find_end_label (void)
} }
else else
{ {
#ifdef HAVE_epilogue
if (HAVE_epilogue
#ifdef HAVE_return
&& ! HAVE_return
#endif
)
{
/* The RETURN insn has its delay slot filled so we cannot
emit the label just before it. Since we already have
an epilogue and cannot emit a new RETURN, we cannot
emit the label at all. */
end_of_function_label = NULL_RTX;
return end_of_function_label;
}
#endif /* HAVE_epilogue */
/* Otherwise, make a new label and emit a RETURN and BARRIER, /* Otherwise, make a new label and emit a RETURN and BARRIER,
if needed. */ if needed. */
emit_label (end_of_function_label); emit_label (end_of_function_label);
...@@ -742,7 +763,6 @@ optimize_skip (rtx insn) ...@@ -742,7 +763,6 @@ optimize_skip (rtx insn)
rtx trial = next_nonnote_insn (insn); rtx trial = next_nonnote_insn (insn);
rtx next_trial = next_active_insn (trial); rtx next_trial = next_active_insn (trial);
rtx delay_list = 0; rtx delay_list = 0;
rtx target_label;
int flags; int flags;
flags = get_jump_flags (insn, JUMP_LABEL (insn)); flags = get_jump_flags (insn, JUMP_LABEL (insn));
...@@ -791,17 +811,20 @@ optimize_skip (rtx insn) ...@@ -791,17 +811,20 @@ optimize_skip (rtx insn)
&& (simplejump_p (next_trial) && (simplejump_p (next_trial)
|| GET_CODE (PATTERN (next_trial)) == RETURN)) || GET_CODE (PATTERN (next_trial)) == RETURN))
{ {
target_label = JUMP_LABEL (next_trial); rtx target_label = JUMP_LABEL (next_trial);
if (target_label == 0) if (target_label == 0)
target_label = find_end_label (); target_label = find_end_label ();
/* Recompute the flags based on TARGET_LABEL since threading if (target_label)
the jump to TARGET_LABEL may change the direction of the {
jump (which may change the circumstances in which the /* Recompute the flags based on TARGET_LABEL since threading
delay slot is nullified). */ the jump to TARGET_LABEL may change the direction of the
flags = get_jump_flags (insn, target_label); jump (which may change the circumstances in which the
if (eligible_for_annul_true (insn, 0, trial, flags)) delay slot is nullified). */
reorg_redirect_jump (insn, target_label); flags = get_jump_flags (insn, target_label);
if (eligible_for_annul_true (insn, 0, trial, flags))
reorg_redirect_jump (insn, target_label);
}
} }
INSN_ANNULLED_BRANCH_P (insn) = 1; INSN_ANNULLED_BRANCH_P (insn) = 1;
...@@ -2373,15 +2396,18 @@ fill_simple_delay_slots (int non_jumps_p) ...@@ -2373,15 +2396,18 @@ fill_simple_delay_slots (int non_jumps_p)
else else
new_label = find_end_label (); new_label = find_end_label ();
delay_list if (new_label)
= add_to_delay_list (copy_rtx (next_trial), delay_list); {
slots_filled++; delay_list
reorg_redirect_jump (trial, new_label); = add_to_delay_list (copy_rtx (next_trial), delay_list);
slots_filled++;
/* If we merged because we both jumped to the same place, reorg_redirect_jump (trial, new_label);
redirect the original insn also. */
if (target) /* If we merged because we both jumped to the same place,
reorg_redirect_jump (insn, new_label); redirect the original insn also. */
if (target)
reorg_redirect_jump (insn, new_label);
}
} }
} }
...@@ -2926,7 +2952,8 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread, ...@@ -2926,7 +2952,8 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
else else
label = get_label_before (new_thread); label = get_label_before (new_thread);
reorg_redirect_jump (insn, label); if (label)
reorg_redirect_jump (insn, label);
} }
return delay_list; return delay_list;
...@@ -3094,14 +3121,14 @@ relax_delay_slots (rtx first) ...@@ -3094,14 +3121,14 @@ relax_delay_slots (rtx first)
if (target_label == 0) if (target_label == 0)
target_label = find_end_label (); target_label = find_end_label ();
if (next_active_insn (target_label) == next if (target_label && next_active_insn (target_label) == next
&& ! condjump_in_parallel_p (insn)) && ! condjump_in_parallel_p (insn))
{ {
delete_jump (insn); delete_jump (insn);
continue; continue;
} }
if (target_label != JUMP_LABEL (insn)) if (target_label && target_label != JUMP_LABEL (insn))
reorg_redirect_jump (insn, target_label); reorg_redirect_jump (insn, target_label);
/* See if this jump branches around an unconditional jump. /* See if this jump branches around an unconditional jump.
...@@ -3109,6 +3136,7 @@ relax_delay_slots (rtx first) ...@@ -3109,6 +3136,7 @@ relax_delay_slots (rtx first)
second jump. */ second jump. */
if (next && GET_CODE (next) == JUMP_INSN if (next && GET_CODE (next) == JUMP_INSN
&& (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN) && (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)
&& target_label
&& next_active_insn (target_label) == next_active_insn (next) && next_active_insn (target_label) == next_active_insn (next)
&& no_labels_between_p (insn, next)) && no_labels_between_p (insn, next))
{ {
...@@ -3242,7 +3270,7 @@ relax_delay_slots (rtx first) ...@@ -3242,7 +3270,7 @@ relax_delay_slots (rtx first)
if (trial == 0) if (trial == 0)
trial = find_end_label (); trial = find_end_label ();
if (trial != target_label if (trial && trial != target_label
&& redirect_with_delay_slots_safe_p (delay_insn, trial, insn)) && redirect_with_delay_slots_safe_p (delay_insn, trial, insn))
{ {
reorg_redirect_jump (delay_insn, trial); reorg_redirect_jump (delay_insn, trial);
...@@ -3256,23 +3284,24 @@ relax_delay_slots (rtx first) ...@@ -3256,23 +3284,24 @@ relax_delay_slots (rtx first)
&& redundant_insn (trial, insn, 0) && redundant_insn (trial, insn, 0)
&& ! can_throw_internal (trial)) && ! can_throw_internal (trial))
{ {
rtx tmp;
/* Figure out where to emit the special USE insn so we don't /* Figure out where to emit the special USE insn so we don't
later incorrectly compute register live/death info. */ later incorrectly compute register live/death info. */
tmp = next_active_insn (trial); rtx tmp = next_active_insn (trial);
if (tmp == 0) if (tmp == 0)
tmp = find_end_label (); tmp = find_end_label ();
/* Insert the special USE insn and update dataflow info. */ if (tmp)
update_block (trial, tmp); {
/* Insert the special USE insn and update dataflow info. */
update_block (trial, tmp);
/* Now emit a label before the special USE insn, and /* Now emit a label before the special USE insn, and
redirect our jump to the new label. */ redirect our jump to the new label. */
target_label = get_label_before (PREV_INSN (tmp)); target_label = get_label_before (PREV_INSN (tmp));
reorg_redirect_jump (delay_insn, target_label); reorg_redirect_jump (delay_insn, target_label);
next = insn; next = insn;
continue; continue;
}
} }
/* Similarly, if it is an unconditional jump with one insn in its /* Similarly, if it is an unconditional jump with one insn in its
...@@ -3286,17 +3315,10 @@ relax_delay_slots (rtx first) ...@@ -3286,17 +3315,10 @@ relax_delay_slots (rtx first)
{ {
target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0)); target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0));
if (target_label == 0) if (target_label == 0)
{ target_label = find_end_label ();
target_label = find_end_label ();
/* The following condition may be true if TRIAL contains
the unique RETURN. In this case, threading would be
a nop and we would enter an infinite loop if we did it. */
if (next_active_insn (target_label) == trial)
target_label = 0;
}
if (target_label if (target_label
&& redirect_with_delay_slots_safe_p (delay_insn, target_label, && redirect_with_delay_slots_safe_p (delay_insn, target_label,
insn)) insn))
{ {
reorg_redirect_jump (delay_insn, target_label); reorg_redirect_jump (delay_insn, target_label);
...@@ -3382,7 +3404,8 @@ relax_delay_slots (rtx first) ...@@ -3382,7 +3404,8 @@ relax_delay_slots (rtx first)
label = find_end_label (); label = find_end_label ();
/* find_end_label can generate a new label. Check this first. */ /* find_end_label can generate a new label. Check this first. */
if (no_labels_between_p (insn, next) if (label
&& no_labels_between_p (insn, next)
&& redirect_with_delay_slots_safe_p (delay_insn, label, insn)) && redirect_with_delay_slots_safe_p (delay_insn, label, insn))
{ {
/* Be careful how we do this to avoid deleting code or labels /* Be careful how we do this to avoid deleting code or labels
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment