diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-08 06:41:13 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-08 06:41:13 +0000 |
commit | 920d6e22ef831d1e37da0ce492bdd849b1bd9b12 (patch) | |
tree | 454ddf1767762dfc1ccdad5d13dd948be2f91726 /gcc | |
parent | df62eec83cf244dcfc47d56ef05e658b201b4163 (diff) | |
download | gcc-920d6e22ef831d1e37da0ce492bdd849b1bd9b12.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84273 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/reorg.c | 147 |
2 files changed, 96 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e5f51936e9..9e1b8ee5d2f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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> * tree-flow.h (addressable_vars): Declare. diff --git a/gcc/reorg.c b/gcc/reorg.c index da4a1a03e83..eb3836696c1 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -317,23 +317,25 @@ insn_sets_resource_p (rtx insn, struct resources *res, mark_set_resources (insn, &insn_sets, 0, include_delayed_effects); 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 - none, make one. */ +/* Find a label at the end of the function or before a RETURN. If there + 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 find_end_label (void) @@ -358,13 +360,15 @@ find_end_label (void) /* When a target threads its epilogue we might already have a suitable return insn. If so put a label before it for the 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)); end_of_function_label = gen_label_rtx (); 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) temp = PREV_INSN (temp); @@ -380,7 +384,8 @@ find_end_label (void) /* If the basic block reorder pass moves the return insn to some other place try to locate it again and put our 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); if (insn) { @@ -395,6 +400,22 @@ find_end_label (void) } 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, if needed. */ emit_label (end_of_function_label); @@ -742,7 +763,6 @@ optimize_skip (rtx insn) rtx trial = next_nonnote_insn (insn); rtx next_trial = next_active_insn (trial); rtx delay_list = 0; - rtx target_label; int flags; flags = get_jump_flags (insn, JUMP_LABEL (insn)); @@ -791,17 +811,20 @@ optimize_skip (rtx insn) && (simplejump_p (next_trial) || GET_CODE (PATTERN (next_trial)) == RETURN)) { - target_label = JUMP_LABEL (next_trial); + rtx target_label = JUMP_LABEL (next_trial); if (target_label == 0) target_label = find_end_label (); - /* Recompute the flags based on TARGET_LABEL since threading - the jump to TARGET_LABEL may change the direction of the - jump (which may change the circumstances in which the - delay slot is nullified). */ - flags = get_jump_flags (insn, target_label); - if (eligible_for_annul_true (insn, 0, trial, flags)) - reorg_redirect_jump (insn, target_label); + if (target_label) + { + /* Recompute the flags based on TARGET_LABEL since threading + the jump to TARGET_LABEL may change the direction of the + jump (which may change the circumstances in which the + delay slot is nullified). */ + 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; @@ -2373,15 +2396,18 @@ fill_simple_delay_slots (int non_jumps_p) else new_label = find_end_label (); - delay_list - = add_to_delay_list (copy_rtx (next_trial), delay_list); - slots_filled++; - reorg_redirect_jump (trial, new_label); - - /* If we merged because we both jumped to the same place, - redirect the original insn also. */ - if (target) - reorg_redirect_jump (insn, new_label); + if (new_label) + { + delay_list + = add_to_delay_list (copy_rtx (next_trial), delay_list); + slots_filled++; + reorg_redirect_jump (trial, new_label); + + /* If we merged because we both jumped to the same place, + 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, else label = get_label_before (new_thread); - reorg_redirect_jump (insn, label); + if (label) + reorg_redirect_jump (insn, label); } return delay_list; @@ -3094,14 +3121,14 @@ relax_delay_slots (rtx first) if (target_label == 0) 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)) { delete_jump (insn); continue; } - if (target_label != JUMP_LABEL (insn)) + if (target_label && target_label != JUMP_LABEL (insn)) reorg_redirect_jump (insn, target_label); /* See if this jump branches around an unconditional jump. @@ -3109,6 +3136,7 @@ relax_delay_slots (rtx first) second jump. */ if (next && GET_CODE (next) == JUMP_INSN && (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN) + && target_label && next_active_insn (target_label) == next_active_insn (next) && no_labels_between_p (insn, next)) { @@ -3242,7 +3270,7 @@ relax_delay_slots (rtx first) if (trial == 0) trial = find_end_label (); - if (trial != target_label + if (trial && trial != target_label && redirect_with_delay_slots_safe_p (delay_insn, trial, insn)) { reorg_redirect_jump (delay_insn, trial); @@ -3256,23 +3284,24 @@ relax_delay_slots (rtx first) && redundant_insn (trial, insn, 0) && ! can_throw_internal (trial)) { - rtx tmp; - /* Figure out where to emit the special USE insn so we don't later incorrectly compute register live/death info. */ - tmp = next_active_insn (trial); + rtx tmp = next_active_insn (trial); if (tmp == 0) tmp = find_end_label (); - /* Insert the special USE insn and update dataflow info. */ - update_block (trial, tmp); + if (tmp) + { + /* Insert the special USE insn and update dataflow info. */ + update_block (trial, tmp); - /* Now emit a label before the special USE insn, and - redirect our jump to the new label. */ - target_label = get_label_before (PREV_INSN (tmp)); - reorg_redirect_jump (delay_insn, target_label); - next = insn; - continue; + /* Now emit a label before the special USE insn, and + redirect our jump to the new label. */ + target_label = get_label_before (PREV_INSN (tmp)); + reorg_redirect_jump (delay_insn, target_label); + next = insn; + continue; + } } /* Similarly, if it is an unconditional jump with one insn in its @@ -3286,17 +3315,10 @@ relax_delay_slots (rtx first) { target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0)); if (target_label == 0) - { - 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; - } + target_label = find_end_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)) { reorg_redirect_jump (delay_insn, target_label); @@ -3382,7 +3404,8 @@ relax_delay_slots (rtx first) label = find_end_label (); /* 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)) { /* Be careful how we do this to avoid deleting code or labels |