rtlanal.c (tablejump_p): False for returns.
* rtlanal.c (tablejump_p): False for returns. * reorg.c (first_active_target_insn): New static function. (find_end_label): Set JUMP_LABEL for a new returnjump. (optimize_skip, get_jump_flags, rare_destination, mostly_true_jump, get_branch_condition, steal_delay_list_from_target, own_thread_p, fill_simple_delay_slots, follow_jumps, fill_slots_from_thread, fill_eager_delay_slots, relax_delay_slots, make_return_insns, dbr_schedule): Adjust to handle ret_rtx in JUMP_LABELs. * jump.c (delete_related_insns): Likewise. (jump_to_label_p): New function. (redirect_target): New static function. (redirect_exp_1): Use it. Adjust to handle ret_rtx in JUMP_LABELS. (redirect_jump_1): Assert that the new label is nonnull. (redirect_jump): Likewise. (redirect_jump_2): Check for ANY_RETURN_P rather than NULL labels. * ifcvt.c (find_if_case_1): Take care when redirecting jumps to the exit block. (dead_or_predicable): Change NEW_DEST arg to DEST_EDGE. All callers changed. Ensure that the right label is passed to redirect_jump. * function.c (emit_return_into_block, thread_prologue_and_epilogue_insns): Ensure new returnjumps have ret_rtx in their JUMP_LABEL. * print-rtl.c (print_rtx): Handle ret_rtx in a JUMP_LABEL. * emit-rtl.c (skip_consecutive_labels): Allow the caller to pass ret_rtx as label. * cfglayout.c (fixup_reorder_chain): Use force_nonfallthru_and_redirect rather than force_nonfallthru. (duplicate_insn_chain): Copy JUMP_LABELs for returns. * rtl.h (ANY_RETURN_P): New macro. (jump_to_label_p): Declare. * resource.c (find_dead_or_set_registers): Handle ret_rtx in JUMP_LABELs. (mark_target_live_regs): Likewise. * basic-block.h (force_nonfallthru_and_redirect): Declare. * cfgrtl.c (force_nonfallthru_and_redirect): No longer static. * config/alpha/alpha.c (alpha_tablejump_addr_vec, alpha_tablejump_best_label): Remove functions. * config/alpha/alpha-protos.c (alpha_tablejump_addr_vec, alpha_tablejump_best_label): Remove declarations. * config/sh/sh.c (barrier_align, split_branches): Adjust for ret_rtx in JUMP_LABELs. * config/arm/arm.c (is_jump_table): Likewise. From-SVN: r176881
This commit is contained in:
parent
a2e49bb27e
commit
dc0ff1c802
|
@ -1,3 +1,49 @@
|
|||
2011-07-28 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
* rtlanal.c (tablejump_p): False for returns.
|
||||
* reorg.c (first_active_target_insn): New static function.
|
||||
(find_end_label): Set JUMP_LABEL for a new returnjump.
|
||||
(optimize_skip, get_jump_flags, rare_destination,
|
||||
mostly_true_jump, get_branch_condition,
|
||||
steal_delay_list_from_target, own_thread_p,
|
||||
fill_simple_delay_slots, follow_jumps, fill_slots_from_thread,
|
||||
fill_eager_delay_slots, relax_delay_slots, make_return_insns,
|
||||
dbr_schedule): Adjust to handle ret_rtx in JUMP_LABELs.
|
||||
* jump.c (delete_related_insns): Likewise.
|
||||
(jump_to_label_p): New function.
|
||||
(redirect_target): New static function.
|
||||
(redirect_exp_1): Use it. Adjust to handle ret_rtx in JUMP_LABELS.
|
||||
(redirect_jump_1): Assert that the new label is nonnull.
|
||||
(redirect_jump): Likewise.
|
||||
(redirect_jump_2): Check for ANY_RETURN_P rather than NULL labels.
|
||||
* ifcvt.c (find_if_case_1): Take care when redirecting jumps to the
|
||||
exit block.
|
||||
(dead_or_predicable): Change NEW_DEST arg to DEST_EDGE. All callers
|
||||
changed. Ensure that the right label is passed to redirect_jump.
|
||||
* function.c (emit_return_into_block,
|
||||
thread_prologue_and_epilogue_insns): Ensure new returnjumps have
|
||||
ret_rtx in their JUMP_LABEL.
|
||||
* print-rtl.c (print_rtx): Handle ret_rtx in a JUMP_LABEL.
|
||||
* emit-rtl.c (skip_consecutive_labels): Allow the caller to
|
||||
pass ret_rtx as label.
|
||||
* cfglayout.c (fixup_reorder_chain): Use
|
||||
force_nonfallthru_and_redirect rather than force_nonfallthru.
|
||||
(duplicate_insn_chain): Copy JUMP_LABELs for returns.
|
||||
* rtl.h (ANY_RETURN_P): New macro.
|
||||
(jump_to_label_p): Declare.
|
||||
* resource.c (find_dead_or_set_registers): Handle ret_rtx in
|
||||
JUMP_LABELs.
|
||||
(mark_target_live_regs): Likewise.
|
||||
* basic-block.h (force_nonfallthru_and_redirect): Declare.
|
||||
* cfgrtl.c (force_nonfallthru_and_redirect): No longer static.
|
||||
* config/alpha/alpha.c (alpha_tablejump_addr_vec,
|
||||
alpha_tablejump_best_label): Remove functions.
|
||||
* config/alpha/alpha-protos.c (alpha_tablejump_addr_vec,
|
||||
alpha_tablejump_best_label): Remove declarations.
|
||||
* config/sh/sh.c (barrier_align, split_branches): Adjust for
|
||||
ret_rtx in JUMP_LABELs.
|
||||
* config/arm/arm.c (is_jump_table): Likewise.
|
||||
|
||||
2011-07-28 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* config/i386/predicates.md (pic_32bit_opreand): Do not define as
|
||||
|
|
|
@ -804,6 +804,7 @@ extern rtx block_label (basic_block);
|
|||
extern bool purge_all_dead_edges (void);
|
||||
extern bool purge_dead_edges (basic_block);
|
||||
extern bool fixup_abnormal_edges (void);
|
||||
extern basic_block force_nonfallthru_and_redirect (edge, basic_block);
|
||||
|
||||
/* In cfgbuild.c. */
|
||||
extern void find_many_sub_basic_blocks (sbitmap);
|
||||
|
|
|
@ -899,7 +899,7 @@ fixup_reorder_chain (void)
|
|||
Note force_nonfallthru can delete E_FALL and thus we have to
|
||||
save E_FALL->src prior to the call to force_nonfallthru. */
|
||||
src_bb = e_fall->src;
|
||||
nb = force_nonfallthru (e_fall);
|
||||
nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest);
|
||||
if (nb)
|
||||
{
|
||||
nb->il.rtl->visited = 1;
|
||||
|
@ -1195,6 +1195,9 @@ duplicate_insn_chain (rtx from, rtx to)
|
|||
break;
|
||||
}
|
||||
copy = emit_copy_of_insn_after (insn, get_last_insn ());
|
||||
if (JUMP_P (insn) && JUMP_LABEL (insn) != NULL_RTX
|
||||
&& ANY_RETURN_P (JUMP_LABEL (insn)))
|
||||
JUMP_LABEL (copy) = JUMP_LABEL (insn);
|
||||
maybe_copy_prologue_epilogue_insn (insn, copy);
|
||||
break;
|
||||
|
||||
|
|
|
@ -1119,7 +1119,7 @@ rtl_redirect_edge_and_branch (edge e, basic_block target)
|
|||
/* Like force_nonfallthru below, but additionally performs redirection
|
||||
Used by redirect_edge_and_branch_force. */
|
||||
|
||||
static basic_block
|
||||
basic_block
|
||||
force_nonfallthru_and_redirect (edge e, basic_block target)
|
||||
{
|
||||
basic_block jump_block, new_bb = NULL, src = e->src;
|
||||
|
|
|
@ -31,9 +31,6 @@ extern void alpha_expand_prologue (void);
|
|||
extern void alpha_expand_epilogue (void);
|
||||
extern void alpha_output_filename (FILE *, const char *);
|
||||
|
||||
extern rtx alpha_tablejump_addr_vec (rtx);
|
||||
extern rtx alpha_tablejump_best_label (rtx);
|
||||
|
||||
extern bool alpha_legitimate_constant_p (enum machine_mode, rtx);
|
||||
extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
|
||||
int, int, int);
|
||||
|
|
|
@ -571,59 +571,6 @@ direct_return (void)
|
|||
&& crtl->args.pretend_args_size == 0);
|
||||
}
|
||||
|
||||
/* Return the ADDR_VEC associated with a tablejump insn. */
|
||||
|
||||
rtx
|
||||
alpha_tablejump_addr_vec (rtx insn)
|
||||
{
|
||||
rtx tmp;
|
||||
|
||||
tmp = JUMP_LABEL (insn);
|
||||
if (!tmp)
|
||||
return NULL_RTX;
|
||||
tmp = NEXT_INSN (tmp);
|
||||
if (!tmp)
|
||||
return NULL_RTX;
|
||||
if (JUMP_P (tmp)
|
||||
&& GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
|
||||
return PATTERN (tmp);
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
|
||||
|
||||
rtx
|
||||
alpha_tablejump_best_label (rtx insn)
|
||||
{
|
||||
rtx jump_table = alpha_tablejump_addr_vec (insn);
|
||||
rtx best_label = NULL_RTX;
|
||||
|
||||
/* ??? Once the CFG doesn't keep getting completely rebuilt, look
|
||||
there for edge frequency counts from profile data. */
|
||||
|
||||
if (jump_table)
|
||||
{
|
||||
int n_labels = XVECLEN (jump_table, 1);
|
||||
int best_count = -1;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n_labels; i++)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
for (j = i + 1; j < n_labels; j++)
|
||||
if (XEXP (XVECEXP (jump_table, 1, i), 0)
|
||||
== XEXP (XVECEXP (jump_table, 1, j), 0))
|
||||
count++;
|
||||
|
||||
if (count > best_count)
|
||||
best_count = count, best_label = XVECEXP (jump_table, 1, i);
|
||||
}
|
||||
}
|
||||
|
||||
return best_label ? best_label : const0_rtx;
|
||||
}
|
||||
|
||||
/* Return the TLS model to use for SYMBOL. */
|
||||
|
||||
static enum tls_model
|
||||
|
|
|
@ -11477,8 +11477,7 @@ is_jump_table (rtx insn)
|
|||
{
|
||||
rtx table;
|
||||
|
||||
if (GET_CODE (insn) == JUMP_INSN
|
||||
&& JUMP_LABEL (insn) != NULL
|
||||
if (jump_to_label_p (insn)
|
||||
&& ((table = next_real_insn (JUMP_LABEL (insn)))
|
||||
== next_real_insn (insn))
|
||||
&& table != NULL
|
||||
|
|
|
@ -5274,9 +5274,7 @@ barrier_align (rtx barrier_or_label)
|
|||
slot = 0;
|
||||
credit -= get_attr_length (prev);
|
||||
}
|
||||
if (prev
|
||||
&& JUMP_P (prev)
|
||||
&& JUMP_LABEL (prev))
|
||||
if (prev && jump_to_label_p (prev))
|
||||
{
|
||||
rtx x;
|
||||
if (jump_to_next
|
||||
|
@ -5975,7 +5973,7 @@ split_branches (rtx first)
|
|||
JUMP_LABEL (insn) = far_label;
|
||||
LABEL_NUSES (far_label)++;
|
||||
}
|
||||
redirect_jump (insn, NULL_RTX, 1);
|
||||
redirect_jump (insn, ret_rtx, 1);
|
||||
far_label = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3322,14 +3322,17 @@ prev_label (rtx insn)
|
|||
return insn;
|
||||
}
|
||||
|
||||
/* Return the last label to mark the same position as LABEL. Return null
|
||||
if LABEL itself is null. */
|
||||
/* Return the last label to mark the same position as LABEL. Return LABEL
|
||||
itself if it is null or any return rtx. */
|
||||
|
||||
rtx
|
||||
skip_consecutive_labels (rtx label)
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
if (label && ANY_RETURN_P (label))
|
||||
return label;
|
||||
|
||||
for (insn = label; insn != 0 && !INSN_P (insn); insn = NEXT_INSN (insn))
|
||||
if (LABEL_P (insn))
|
||||
label = insn;
|
||||
|
|
|
@ -5305,7 +5305,8 @@ emit_use_return_register_into_block (basic_block bb)
|
|||
static void
|
||||
emit_return_into_block (basic_block bb)
|
||||
{
|
||||
emit_jump_insn_after (gen_return (), BB_END (bb));
|
||||
rtx jump = emit_jump_insn_after (gen_return (), BB_END (bb));
|
||||
JUMP_LABEL (jump) = ret_rtx;
|
||||
}
|
||||
#endif /* HAVE_return */
|
||||
|
||||
|
@ -5464,7 +5465,7 @@ thread_prologue_and_epilogue_insns (void)
|
|||
that with a conditional return instruction. */
|
||||
else if (condjump_p (jump))
|
||||
{
|
||||
if (! redirect_jump (jump, 0, 0))
|
||||
if (! redirect_jump (jump, ret_rtx, 0))
|
||||
{
|
||||
ei_next (&ei2);
|
||||
continue;
|
||||
|
@ -5547,6 +5548,8 @@ thread_prologue_and_epilogue_insns (void)
|
|||
#ifdef HAVE_epilogue
|
||||
if (HAVE_epilogue)
|
||||
{
|
||||
rtx returnjump;
|
||||
|
||||
start_sequence ();
|
||||
epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
|
||||
seq = gen_epilogue ();
|
||||
|
@ -5557,11 +5560,25 @@ thread_prologue_and_epilogue_insns (void)
|
|||
record_insns (seq, NULL, &epilogue_insn_hash);
|
||||
set_insn_locators (seq, epilogue_locator);
|
||||
|
||||
returnjump = get_last_insn ();
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
insert_insn_on_edge (seq, e);
|
||||
inserted = true;
|
||||
|
||||
if (JUMP_P (returnjump))
|
||||
{
|
||||
rtx pat = PATTERN (returnjump);
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
pat = XVECEXP (pat, 0, 0);
|
||||
if (ANY_RETURN_P (pat))
|
||||
JUMP_LABEL (returnjump) = pat;
|
||||
else
|
||||
JUMP_LABEL (returnjump) = ret_rtx;
|
||||
}
|
||||
else
|
||||
returnjump = NULL_RTX;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
31
gcc/ifcvt.c
31
gcc/ifcvt.c
|
@ -104,7 +104,7 @@ static int cond_exec_find_if_block (ce_if_block_t *);
|
|||
static int find_if_case_1 (basic_block, edge, edge);
|
||||
static int find_if_case_2 (basic_block, edge, edge);
|
||||
static int dead_or_predicable (basic_block, basic_block, basic_block,
|
||||
basic_block, int);
|
||||
edge, int);
|
||||
static void noce_emit_move_insn (rtx, rtx);
|
||||
static rtx block_has_only_trap (basic_block);
|
||||
|
||||
|
@ -3847,7 +3847,7 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
|
|||
|
||||
/* Registers set are dead, or are predicable. */
|
||||
if (! dead_or_predicable (test_bb, then_bb, else_bb,
|
||||
single_succ (then_bb), 1))
|
||||
single_succ_edge (then_bb), 1))
|
||||
return FALSE;
|
||||
|
||||
/* Conversion went ok, including moving the insns and fixing up the
|
||||
|
@ -3962,7 +3962,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
|
|||
return FALSE;
|
||||
|
||||
/* Registers set are dead, or are predicable. */
|
||||
if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ->dest, 0))
|
||||
if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0))
|
||||
return FALSE;
|
||||
|
||||
/* Conversion went ok, including moving the insns and fixing up the
|
||||
|
@ -3985,18 +3985,21 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
|
|||
Return TRUE if successful.
|
||||
|
||||
TEST_BB is the block containing the conditional branch. MERGE_BB
|
||||
is the block containing the code to manipulate. NEW_DEST is the
|
||||
label TEST_BB should be branching to after the conversion.
|
||||
is the block containing the code to manipulate. DEST_EDGE is an
|
||||
edge representing a jump to the join block; after the conversion,
|
||||
TEST_BB should be branching to its destination.
|
||||
REVERSEP is true if the sense of the branch should be reversed. */
|
||||
|
||||
static int
|
||||
dead_or_predicable (basic_block test_bb, basic_block merge_bb,
|
||||
basic_block other_bb, basic_block new_dest, int reversep)
|
||||
basic_block other_bb, edge dest_edge, int reversep)
|
||||
{
|
||||
rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
|
||||
basic_block new_dest = dest_edge->dest;
|
||||
rtx head, end, jump, earliest = NULL_RTX, old_dest;
|
||||
bitmap merge_set = NULL;
|
||||
/* Number of pending changes. */
|
||||
int n_validated_changes = 0;
|
||||
rtx new_dest_label = NULL_RTX;
|
||||
|
||||
jump = BB_END (test_bb);
|
||||
|
||||
|
@ -4134,10 +4137,16 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
|
|||
old_dest = JUMP_LABEL (jump);
|
||||
if (other_bb != new_dest)
|
||||
{
|
||||
new_label = block_label (new_dest);
|
||||
if (JUMP_P (BB_END (dest_edge->src)))
|
||||
new_dest_label = JUMP_LABEL (BB_END (dest_edge->src));
|
||||
else if (new_dest == EXIT_BLOCK_PTR)
|
||||
new_dest_label = ret_rtx;
|
||||
else
|
||||
new_dest_label = block_label (new_dest);
|
||||
|
||||
if (reversep
|
||||
? ! invert_jump_1 (jump, new_label)
|
||||
: ! redirect_jump_1 (jump, new_label))
|
||||
? ! invert_jump_1 (jump, new_dest_label)
|
||||
: ! redirect_jump_1 (jump, new_dest_label))
|
||||
goto cancel;
|
||||
}
|
||||
|
||||
|
@ -4148,7 +4157,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
|
|||
|
||||
if (other_bb != new_dest)
|
||||
{
|
||||
redirect_jump_2 (jump, old_dest, new_label, 0, reversep);
|
||||
redirect_jump_2 (jump, old_dest, new_dest_label, 0, reversep);
|
||||
|
||||
redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
|
||||
if (reversep)
|
||||
|
|
72
gcc/jump.c
72
gcc/jump.c
|
@ -970,6 +970,15 @@ onlyjump_p (const_rtx insn)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Return true iff INSN is a jump and its JUMP_LABEL is a label, not
|
||||
NULL or a return. */
|
||||
bool
|
||||
jump_to_label_p (rtx insn)
|
||||
{
|
||||
return (JUMP_P (insn)
|
||||
&& JUMP_LABEL (insn) != NULL && !ANY_RETURN_P (JUMP_LABEL (insn)));
|
||||
}
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
|
||||
/* Return nonzero if X is an RTX that only sets the condition codes
|
||||
|
@ -1233,7 +1242,7 @@ delete_related_insns (rtx insn)
|
|||
/* If deleting a jump, decrement the count of the label,
|
||||
and delete the label if it is now unused. */
|
||||
|
||||
if (JUMP_P (insn) && JUMP_LABEL (insn))
|
||||
if (jump_to_label_p (insn))
|
||||
{
|
||||
rtx lab = JUMP_LABEL (insn), lab_next;
|
||||
|
||||
|
@ -1364,6 +1373,18 @@ delete_for_peephole (rtx from, rtx to)
|
|||
is also an unconditional jump in that case. */
|
||||
}
|
||||
|
||||
/* A helper function for redirect_exp_1; examines its input X and returns
|
||||
either a LABEL_REF around a label, or a RETURN if X was NULL. */
|
||||
static rtx
|
||||
redirect_target (rtx x)
|
||||
{
|
||||
if (x == NULL_RTX)
|
||||
return ret_rtx;
|
||||
if (!ANY_RETURN_P (x))
|
||||
return gen_rtx_LABEL_REF (Pmode, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
|
||||
NLABEL as a return. Accrue modifications into the change group. */
|
||||
|
||||
|
@ -1375,37 +1396,22 @@ redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
|
|||
int i;
|
||||
const char *fmt;
|
||||
|
||||
if (code == LABEL_REF)
|
||||
if ((code == LABEL_REF && XEXP (x, 0) == olabel)
|
||||
|| x == olabel)
|
||||
{
|
||||
if (XEXP (x, 0) == olabel)
|
||||
{
|
||||
rtx n;
|
||||
if (nlabel)
|
||||
n = gen_rtx_LABEL_REF (Pmode, nlabel);
|
||||
else
|
||||
n = ret_rtx;
|
||||
|
||||
validate_change (insn, loc, n, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (code == RETURN && olabel == 0)
|
||||
{
|
||||
if (nlabel)
|
||||
x = gen_rtx_LABEL_REF (Pmode, nlabel);
|
||||
else
|
||||
x = ret_rtx;
|
||||
if (loc == &PATTERN (insn))
|
||||
x = gen_rtx_SET (VOIDmode, pc_rtx, x);
|
||||
x = redirect_target (nlabel);
|
||||
if (GET_CODE (x) == LABEL_REF && loc == &PATTERN (insn))
|
||||
x = gen_rtx_SET (VOIDmode, pc_rtx, x);
|
||||
validate_change (insn, loc, x, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
|
||||
if (code == SET && SET_DEST (x) == pc_rtx
|
||||
&& ANY_RETURN_P (nlabel)
|
||||
&& GET_CODE (SET_SRC (x)) == LABEL_REF
|
||||
&& XEXP (SET_SRC (x), 0) == olabel)
|
||||
{
|
||||
validate_change (insn, loc, ret_rtx, 1);
|
||||
validate_change (insn, loc, nlabel, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1442,6 +1448,7 @@ redirect_jump_1 (rtx jump, rtx nlabel)
|
|||
int ochanges = num_validated_changes ();
|
||||
rtx *loc, asmop;
|
||||
|
||||
gcc_assert (nlabel != NULL_RTX);
|
||||
asmop = extract_asm_operands (PATTERN (jump));
|
||||
if (asmop)
|
||||
{
|
||||
|
@ -1463,17 +1470,20 @@ redirect_jump_1 (rtx jump, rtx nlabel)
|
|||
jump target label is unused as a result, it and the code following
|
||||
it may be deleted.
|
||||
|
||||
If NLABEL is zero, we are to turn the jump into a (possibly conditional)
|
||||
RETURN insn.
|
||||
Normally, NLABEL will be a label, but it may also be a RETURN rtx;
|
||||
in that case we are to turn the jump into a (possibly conditional)
|
||||
return insn.
|
||||
|
||||
The return value will be 1 if the change was made, 0 if it wasn't
|
||||
(this can only occur for NLABEL == 0). */
|
||||
(this can only occur when trying to produce return insns). */
|
||||
|
||||
int
|
||||
redirect_jump (rtx jump, rtx nlabel, int delete_unused)
|
||||
{
|
||||
rtx olabel = JUMP_LABEL (jump);
|
||||
|
||||
gcc_assert (nlabel != NULL_RTX);
|
||||
|
||||
if (nlabel == olabel)
|
||||
return 1;
|
||||
|
||||
|
@ -1501,13 +1511,14 @@ redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
|
|||
about this. */
|
||||
gcc_assert (delete_unused >= 0);
|
||||
JUMP_LABEL (jump) = nlabel;
|
||||
if (nlabel)
|
||||
if (!ANY_RETURN_P (nlabel))
|
||||
++LABEL_NUSES (nlabel);
|
||||
|
||||
/* Update labels in any REG_EQUAL note. */
|
||||
if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
|
||||
{
|
||||
if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
|
||||
if (ANY_RETURN_P (nlabel)
|
||||
|| (invert && !invert_exp_1 (XEXP (note, 0), jump)))
|
||||
remove_note (jump, note);
|
||||
else
|
||||
{
|
||||
|
@ -1516,7 +1527,8 @@ redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
|
|||
}
|
||||
}
|
||||
|
||||
if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
|
||||
if (!ANY_RETURN_P (olabel)
|
||||
&& --LABEL_NUSES (olabel) == 0 && delete_unused > 0
|
||||
/* Undefined labels will remain outside the insn stream. */
|
||||
&& INSN_UID (olabel))
|
||||
delete_related_insns (olabel);
|
||||
|
|
|
@ -323,9 +323,14 @@ print_rtx (const_rtx in_rtx)
|
|||
}
|
||||
}
|
||||
else if (i == 8 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL)
|
||||
/* Output the JUMP_LABEL reference. */
|
||||
fprintf (outfile, "\n%s%*s -> %d", print_rtx_head, indent * 2, "",
|
||||
INSN_UID (JUMP_LABEL (in_rtx)));
|
||||
{
|
||||
/* Output the JUMP_LABEL reference. */
|
||||
fprintf (outfile, "\n%s%*s -> ", print_rtx_head, indent * 2, "");
|
||||
if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
|
||||
fprintf (outfile, "return");
|
||||
else
|
||||
fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
|
||||
}
|
||||
else if (i == 0 && GET_CODE (in_rtx) == VALUE)
|
||||
{
|
||||
#ifndef GENERATOR_FILE
|
||||
|
|
104
gcc/reorg.c
104
gcc/reorg.c
|
@ -220,6 +220,17 @@ static void relax_delay_slots (rtx);
|
|||
static void make_return_insns (rtx);
|
||||
#endif
|
||||
|
||||
/* A wrapper around next_active_insn which takes care to return ret_rtx
|
||||
unchanged. */
|
||||
|
||||
static rtx
|
||||
first_active_target_insn (rtx insn)
|
||||
{
|
||||
if (ANY_RETURN_P (insn))
|
||||
return insn;
|
||||
return next_active_insn (insn);
|
||||
}
|
||||
|
||||
/* Return TRUE if this insn should stop the search for insn to fill delay
|
||||
slots. LABELS_P indicates that labels should terminate the search.
|
||||
In all cases, jumps terminate the search. */
|
||||
|
@ -437,6 +448,7 @@ find_end_label (void)
|
|||
/* The return we make may have delay slots too. */
|
||||
rtx insn = gen_return ();
|
||||
insn = emit_jump_insn (insn);
|
||||
JUMP_LABEL (insn) = ret_rtx;
|
||||
emit_barrier ();
|
||||
if (num_delay_slots (insn) > 0)
|
||||
obstack_ptr_grow (&unfilled_slots_obstack, insn);
|
||||
|
@ -824,7 +836,7 @@ optimize_skip (rtx insn)
|
|||
|| GET_CODE (PATTERN (next_trial)) == RETURN))
|
||||
{
|
||||
rtx target_label = JUMP_LABEL (next_trial);
|
||||
if (target_label == 0)
|
||||
if (ANY_RETURN_P (target_label))
|
||||
target_label = find_end_label ();
|
||||
|
||||
if (target_label)
|
||||
|
@ -861,12 +873,12 @@ get_jump_flags (rtx insn, rtx label)
|
|||
be INSNs, CALL_INSNs, or JUMP_INSNs. Only JUMP_INSNs have branch
|
||||
direction information, and only if they are conditional jumps.
|
||||
|
||||
If LABEL is zero, then there is no way to determine the branch
|
||||
If LABEL is a return, then there is no way to determine the branch
|
||||
direction. */
|
||||
if (JUMP_P (insn)
|
||||
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
|
||||
&& !ANY_RETURN_P (label)
|
||||
&& INSN_UID (insn) <= max_uid
|
||||
&& label != 0
|
||||
&& INSN_UID (label) <= max_uid)
|
||||
flags
|
||||
= (uid_to_ruid[INSN_UID (label)] > uid_to_ruid[INSN_UID (insn)])
|
||||
|
@ -921,7 +933,7 @@ rare_destination (rtx insn)
|
|||
int jump_count = 0;
|
||||
rtx next;
|
||||
|
||||
for (; insn; insn = next)
|
||||
for (; insn && !ANY_RETURN_P (insn); insn = next)
|
||||
{
|
||||
if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
|
||||
insn = XVECEXP (PATTERN (insn), 0, 0);
|
||||
|
@ -1017,7 +1029,7 @@ mostly_true_jump (rtx jump_insn, rtx condition)
|
|||
/* Predict backward branches usually take, forward branches usually not. If
|
||||
we don't know whether this is forward or backward, assume the branch
|
||||
will be taken, since most are. */
|
||||
return (target_label == 0 || INSN_UID (jump_insn) > max_uid
|
||||
return (ANY_RETURN_P (target_label) || INSN_UID (jump_insn) > max_uid
|
||||
|| INSN_UID (target_label) > max_uid
|
||||
|| (uid_to_ruid[INSN_UID (jump_insn)]
|
||||
> uid_to_ruid[INSN_UID (target_label)]));
|
||||
|
@ -1037,10 +1049,10 @@ get_branch_condition (rtx insn, rtx target)
|
|||
if (condjump_in_parallel_p (insn))
|
||||
pat = XVECEXP (pat, 0, 0);
|
||||
|
||||
if (GET_CODE (pat) == RETURN)
|
||||
return target == 0 ? const_true_rtx : 0;
|
||||
if (ANY_RETURN_P (pat))
|
||||
return pat == target ? const_true_rtx : 0;
|
||||
|
||||
else if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
|
||||
if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
|
||||
return 0;
|
||||
|
||||
src = SET_SRC (pat);
|
||||
|
@ -1048,16 +1060,12 @@ get_branch_condition (rtx insn, rtx target)
|
|||
return const_true_rtx;
|
||||
|
||||
else if (GET_CODE (src) == IF_THEN_ELSE
|
||||
&& ((target == 0 && GET_CODE (XEXP (src, 1)) == RETURN)
|
||||
|| (GET_CODE (XEXP (src, 1)) == LABEL_REF
|
||||
&& XEXP (XEXP (src, 1), 0) == target))
|
||||
&& XEXP (XEXP (src, 1), 0) == target
|
||||
&& XEXP (src, 2) == pc_rtx)
|
||||
return XEXP (src, 0);
|
||||
|
||||
else if (GET_CODE (src) == IF_THEN_ELSE
|
||||
&& ((target == 0 && GET_CODE (XEXP (src, 2)) == RETURN)
|
||||
|| (GET_CODE (XEXP (src, 2)) == LABEL_REF
|
||||
&& XEXP (XEXP (src, 2), 0) == target))
|
||||
&& XEXP (XEXP (src, 2), 0) == target
|
||||
&& XEXP (src, 1) == pc_rtx)
|
||||
{
|
||||
enum rtx_code rev;
|
||||
|
@ -1318,7 +1326,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
|
|||
}
|
||||
|
||||
/* Show the place to which we will be branching. */
|
||||
*pnew_thread = next_active_insn (JUMP_LABEL (XVECEXP (seq, 0, 0)));
|
||||
*pnew_thread = first_active_target_insn (JUMP_LABEL (XVECEXP (seq, 0, 0)));
|
||||
|
||||
/* Add any new insns to the delay list and update the count of the
|
||||
number of slots filled. */
|
||||
|
@ -1827,7 +1835,7 @@ own_thread_p (rtx thread, rtx label, int allow_fallthrough)
|
|||
rtx insn;
|
||||
|
||||
/* We don't own the function end. */
|
||||
if (thread == 0)
|
||||
if (thread == 0 || ANY_RETURN_P (thread))
|
||||
return 0;
|
||||
|
||||
/* Get the first active insn, or THREAD, if it is an active insn. */
|
||||
|
@ -2245,7 +2253,7 @@ fill_simple_delay_slots (int non_jumps_p)
|
|||
&& (!JUMP_P (insn)
|
||||
|| ((condjump_p (insn) || condjump_in_parallel_p (insn))
|
||||
&& ! simplejump_p (insn)
|
||||
&& JUMP_LABEL (insn) != 0)))
|
||||
&& !ANY_RETURN_P (JUMP_LABEL (insn)))))
|
||||
{
|
||||
/* Invariant: If insn is a JUMP_INSN, the insn's jump
|
||||
label. Otherwise, zero. */
|
||||
|
@ -2270,7 +2278,7 @@ fill_simple_delay_slots (int non_jumps_p)
|
|||
target = JUMP_LABEL (insn);
|
||||
}
|
||||
|
||||
if (target == 0)
|
||||
if (target == 0 || ANY_RETURN_P (target))
|
||||
for (trial = next_nonnote_insn (insn); !stop_search_p (trial, 1);
|
||||
trial = next_trial)
|
||||
{
|
||||
|
@ -2343,7 +2351,7 @@ fill_simple_delay_slots (int non_jumps_p)
|
|||
Don't do this if the insn at the branch target is a branch. */
|
||||
if (slots_to_fill != slots_filled
|
||||
&& trial
|
||||
&& JUMP_P (trial)
|
||||
&& jump_to_label_p (trial)
|
||||
&& simplejump_p (trial)
|
||||
&& (target == 0 || JUMP_LABEL (trial) == target)
|
||||
&& (next_trial = next_active_insn (JUMP_LABEL (trial))) != 0
|
||||
|
@ -2500,7 +2508,7 @@ fill_simple_delay_slots (int non_jumps_p)
|
|||
|
||||
/* Follow any unconditional jump at LABEL;
|
||||
return the ultimate label reached by any such chain of jumps.
|
||||
Return null if the chain ultimately leads to a return instruction.
|
||||
Return ret_rtx if the chain ultimately leads to a return instruction.
|
||||
If LABEL is not followed by a jump, return LABEL.
|
||||
If the chain loops or we can't find end, return LABEL,
|
||||
since that tells caller to avoid changing the insn. */
|
||||
|
@ -2513,29 +2521,34 @@ follow_jumps (rtx label)
|
|||
rtx value = label;
|
||||
int depth;
|
||||
|
||||
if (ANY_RETURN_P (label))
|
||||
return label;
|
||||
for (depth = 0;
|
||||
(depth < 10
|
||||
&& (insn = next_active_insn (value)) != 0
|
||||
&& JUMP_P (insn)
|
||||
&& ((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
|
||||
&& onlyjump_p (insn))
|
||||
&& JUMP_LABEL (insn) != NULL_RTX
|
||||
&& ((any_uncondjump_p (insn) && onlyjump_p (insn))
|
||||
|| GET_CODE (PATTERN (insn)) == RETURN)
|
||||
&& (next = NEXT_INSN (insn))
|
||||
&& BARRIER_P (next));
|
||||
depth++)
|
||||
{
|
||||
rtx this_label = JUMP_LABEL (insn);
|
||||
rtx tem;
|
||||
|
||||
/* If we have found a cycle, make the insn jump to itself. */
|
||||
if (JUMP_LABEL (insn) == label)
|
||||
if (this_label == label)
|
||||
return label;
|
||||
|
||||
tem = next_active_insn (JUMP_LABEL (insn));
|
||||
if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
|
||||
if (ANY_RETURN_P (this_label))
|
||||
return this_label;
|
||||
tem = next_active_insn (this_label);
|
||||
if (tem
|
||||
&& (GET_CODE (PATTERN (tem)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
|
||||
break;
|
||||
|
||||
value = JUMP_LABEL (insn);
|
||||
value = this_label;
|
||||
}
|
||||
if (depth == 10)
|
||||
return label;
|
||||
|
@ -2587,7 +2600,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
|
|||
|
||||
/* If our thread is the end of subroutine, we can't get any delay
|
||||
insns from that. */
|
||||
if (thread == 0)
|
||||
if (thread == NULL_RTX || ANY_RETURN_P (thread))
|
||||
return delay_list;
|
||||
|
||||
/* If this is an unconditional branch, nothing is needed at the
|
||||
|
@ -2757,7 +2770,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
|
|||
gcc_assert (REG_NOTE_KIND (note)
|
||||
== REG_LABEL_OPERAND);
|
||||
}
|
||||
if (JUMP_P (trial) && JUMP_LABEL (trial))
|
||||
if (jump_to_label_p (trial))
|
||||
LABEL_NUSES (JUMP_LABEL (trial))++;
|
||||
|
||||
delete_related_insns (trial);
|
||||
|
@ -2776,7 +2789,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
|
|||
gcc_assert (REG_NOTE_KIND (note)
|
||||
== REG_LABEL_OPERAND);
|
||||
}
|
||||
if (JUMP_P (trial) && JUMP_LABEL (trial))
|
||||
if (jump_to_label_p (trial))
|
||||
LABEL_NUSES (JUMP_LABEL (trial))--;
|
||||
}
|
||||
else
|
||||
|
@ -2897,7 +2910,8 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
|
|||
depend on the destination register. If so, try to place the opposite
|
||||
arithmetic insn after the jump insn and put the arithmetic insn in the
|
||||
delay slot. If we can't do this, return. */
|
||||
if (delay_list == 0 && likely && new_thread
|
||||
if (delay_list == 0 && likely
|
||||
&& new_thread && !ANY_RETURN_P (new_thread)
|
||||
&& NONJUMP_INSN_P (new_thread)
|
||||
&& GET_CODE (PATTERN (new_thread)) != ASM_INPUT
|
||||
&& asm_noperands (PATTERN (new_thread)) < 0)
|
||||
|
@ -2990,7 +3004,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
|
|||
delay_list))
|
||||
new_thread = follow_jumps (JUMP_LABEL (new_thread));
|
||||
|
||||
if (new_thread == 0)
|
||||
if (ANY_RETURN_P (new_thread))
|
||||
label = find_end_label ();
|
||||
else if (LABEL_P (new_thread))
|
||||
label = new_thread;
|
||||
|
@ -3063,7 +3077,7 @@ fill_eager_delay_slots (void)
|
|||
them. Then see whether the branch is likely true. We don't need
|
||||
to do a lot of this for unconditional branches. */
|
||||
|
||||
insn_at_target = next_active_insn (target_label);
|
||||
insn_at_target = first_active_target_insn (target_label);
|
||||
own_target = own_thread_p (target_label, target_label, 0);
|
||||
|
||||
if (condition == const_true_rtx)
|
||||
|
@ -3098,7 +3112,7 @@ fill_eager_delay_slots (void)
|
|||
from the thread that was filled. So we have to recompute
|
||||
the next insn at the target. */
|
||||
target_label = JUMP_LABEL (insn);
|
||||
insn_at_target = next_active_insn (target_label);
|
||||
insn_at_target = first_active_target_insn (target_label);
|
||||
|
||||
delay_list
|
||||
= fill_slots_from_thread (insn, condition, fallthrough_insn,
|
||||
|
@ -3337,10 +3351,10 @@ relax_delay_slots (rtx first)
|
|||
group of consecutive labels. */
|
||||
if (JUMP_P (insn)
|
||||
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
|
||||
&& (target_label = JUMP_LABEL (insn)) != 0)
|
||||
&& !ANY_RETURN_P (target_label = JUMP_LABEL (insn)))
|
||||
{
|
||||
target_label = skip_consecutive_labels (follow_jumps (target_label));
|
||||
if (target_label == 0)
|
||||
if (ANY_RETURN_P (target_label))
|
||||
target_label = find_end_label ();
|
||||
|
||||
if (target_label && next_active_insn (target_label) == next
|
||||
|
@ -3373,7 +3387,7 @@ relax_delay_slots (rtx first)
|
|||
invert_jump fails. */
|
||||
|
||||
++LABEL_NUSES (target_label);
|
||||
if (label)
|
||||
if (!ANY_RETURN_P (label))
|
||||
++LABEL_NUSES (label);
|
||||
|
||||
if (invert_jump (insn, label, 1))
|
||||
|
@ -3382,7 +3396,7 @@ relax_delay_slots (rtx first)
|
|||
next = insn;
|
||||
}
|
||||
|
||||
if (label)
|
||||
if (!ANY_RETURN_P (label))
|
||||
--LABEL_NUSES (label);
|
||||
|
||||
if (--LABEL_NUSES (target_label) == 0)
|
||||
|
@ -3485,12 +3499,12 @@ relax_delay_slots (rtx first)
|
|||
|
||||
target_label = JUMP_LABEL (delay_insn);
|
||||
|
||||
if (target_label)
|
||||
if (!ANY_RETURN_P (target_label))
|
||||
{
|
||||
/* If this jump goes to another unconditional jump, thread it, but
|
||||
don't convert a jump into a RETURN here. */
|
||||
trial = skip_consecutive_labels (follow_jumps (target_label));
|
||||
if (trial == 0)
|
||||
if (ANY_RETURN_P (trial))
|
||||
trial = find_end_label ();
|
||||
|
||||
if (trial && trial != target_label
|
||||
|
@ -3540,7 +3554,7 @@ relax_delay_slots (rtx first)
|
|||
&& redundant_insn (XVECEXP (PATTERN (trial), 0, 1), insn, 0))
|
||||
{
|
||||
target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0));
|
||||
if (target_label == 0)
|
||||
if (ANY_RETURN_P (target_label))
|
||||
target_label = find_end_label ();
|
||||
|
||||
if (target_label
|
||||
|
@ -3627,7 +3641,7 @@ relax_delay_slots (rtx first)
|
|||
rtx label = JUMP_LABEL (next);
|
||||
rtx old_label = JUMP_LABEL (delay_insn);
|
||||
|
||||
if (label == 0)
|
||||
if (ANY_RETURN_P (label))
|
||||
label = find_end_label ();
|
||||
|
||||
/* find_end_label can generate a new label. Check this first. */
|
||||
|
@ -3737,7 +3751,7 @@ make_return_insns (rtx first)
|
|||
|
||||
/* If we can't make the jump into a RETURN, try to redirect it to the best
|
||||
RETURN and go on to the next insn. */
|
||||
if (! reorg_redirect_jump (jump_insn, NULL_RTX))
|
||||
if (! reorg_redirect_jump (jump_insn, ret_rtx))
|
||||
{
|
||||
/* Make sure redirecting the jump will not invalidate the delay
|
||||
slot insns. */
|
||||
|
@ -3866,7 +3880,7 @@ dbr_schedule (rtx first)
|
|||
/* Ensure all jumps go to the last of a set of consecutive labels. */
|
||||
if (JUMP_P (insn)
|
||||
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
|
||||
&& JUMP_LABEL (insn) != 0
|
||||
&& !ANY_RETURN_P (JUMP_LABEL (insn))
|
||||
&& ((target = skip_consecutive_labels (JUMP_LABEL (insn)))
|
||||
!= JUMP_LABEL (insn)))
|
||||
redirect_jump (insn, target, 1);
|
||||
|
|
|
@ -495,6 +495,8 @@ find_dead_or_set_registers (rtx target, struct resources *res,
|
|||
|| GET_CODE (PATTERN (this_jump_insn)) == RETURN)
|
||||
{
|
||||
next = JUMP_LABEL (this_jump_insn);
|
||||
if (ANY_RETURN_P (next))
|
||||
next = NULL_RTX;
|
||||
if (jump_insn == 0)
|
||||
{
|
||||
jump_insn = insn;
|
||||
|
@ -562,9 +564,10 @@ find_dead_or_set_registers (rtx target, struct resources *res,
|
|||
AND_COMPL_HARD_REG_SET (scratch, needed.regs);
|
||||
AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch);
|
||||
|
||||
find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),
|
||||
&target_res, 0, jump_count,
|
||||
target_set, needed);
|
||||
if (!ANY_RETURN_P (JUMP_LABEL (this_jump_insn)))
|
||||
find_dead_or_set_registers (JUMP_LABEL (this_jump_insn),
|
||||
&target_res, 0, jump_count,
|
||||
target_set, needed);
|
||||
find_dead_or_set_registers (next,
|
||||
&fallthrough_res, 0, jump_count,
|
||||
set, needed);
|
||||
|
@ -878,7 +881,7 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
|
|||
struct resources set, needed;
|
||||
|
||||
/* Handle end of function. */
|
||||
if (target == 0)
|
||||
if (target == 0 || ANY_RETURN_P (target))
|
||||
{
|
||||
*res = end_of_function_needs;
|
||||
return;
|
||||
|
@ -1097,8 +1100,9 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
|
|||
struct resources new_resources;
|
||||
rtx stop_insn = next_active_insn (jump_insn);
|
||||
|
||||
mark_target_live_regs (insns, next_active_insn (jump_target),
|
||||
&new_resources);
|
||||
if (!ANY_RETURN_P (jump_target))
|
||||
jump_target = next_active_insn (jump_target);
|
||||
mark_target_live_regs (insns, jump_target, &new_resources);
|
||||
CLEAR_RESOURCE (&set);
|
||||
CLEAR_RESOURCE (&needed);
|
||||
|
||||
|
|
|
@ -432,6 +432,9 @@ struct GTY((variable_size)) rtvec_def {
|
|||
(JUMP_P (INSN) && (GET_CODE (PATTERN (INSN)) == ADDR_VEC || \
|
||||
GET_CODE (PATTERN (INSN)) == ADDR_DIFF_VEC))
|
||||
|
||||
/* Predicate yielding nonzero iff X is a return. */
|
||||
#define ANY_RETURN_P(X) ((X) == ret_rtx)
|
||||
|
||||
/* 1 if X is a unary operator. */
|
||||
|
||||
#define UNARY_P(X) \
|
||||
|
@ -2341,6 +2344,7 @@ extern void check_for_inc_dec (rtx insn);
|
|||
|
||||
/* In jump.c */
|
||||
extern int comparison_dominates_p (enum rtx_code, enum rtx_code);
|
||||
extern bool jump_to_label_p (rtx);
|
||||
extern int condjump_p (const_rtx);
|
||||
extern int any_condjump_p (const_rtx);
|
||||
extern int any_uncondjump_p (const_rtx);
|
||||
|
|
|
@ -2660,8 +2660,11 @@ tablejump_p (const_rtx insn, rtx *labelp, rtx *tablep)
|
|||
{
|
||||
rtx label, table;
|
||||
|
||||
if (JUMP_P (insn)
|
||||
&& (label = JUMP_LABEL (insn)) != NULL_RTX
|
||||
if (!JUMP_P (insn))
|
||||
return false;
|
||||
|
||||
label = JUMP_LABEL (insn);
|
||||
if (label != NULL_RTX && !ANY_RETURN_P (label)
|
||||
&& (table = next_active_insn (label)) != NULL_RTX
|
||||
&& JUMP_TABLE_DATA_P (table))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue