Commit 2ea64f10 by Richard Henderson

jump.c (redirect_exp_1): Rework from old redirect_exp.

        * jump.c (redirect_exp_1): Rework from old redirect_exp.  Never
        commit change group changes.
        (invert_exp_1): Similarly.
        (redirect_exp, invert_exp): Use them.
        (redirect_jump_1): New.
        (invert_jump_1): New.
        (jump_optimize_1): Remove code subsumed by condexec.c.
        * rtl.h (invert_jump_1, redirect_jump_1): Declare.

From-SVN: r33474
parent 0a2287bf
2000-04-26 Richard Henderson <rth@cygnus.com>
* jump.c (redirect_exp_1): Rework from old redirect_exp. Never
commit change group changes.
(invert_exp_1): Similarly.
(redirect_exp, invert_exp): Use them.
(redirect_jump_1): New.
(invert_jump_1): New.
(jump_optimize_1): Remove code subsumed by condexec.c.
* rtl.h (invert_jump_1, redirect_jump_1): Declare.
2000-04-26 Richard Henderson <rth@cygnus.com>
* rtlanal.c (dead_or_set_regno_p): Use find_regno_note.
* genconfig.c (main): Set all HAVE_foo to 1.
......
......@@ -121,6 +121,8 @@ static int jump_back_p PARAMS ((rtx, rtx));
static int tension_vector_labels PARAMS ((rtx, int));
static void mark_jump_label PARAMS ((rtx, rtx, int, int));
static void delete_computation PARAMS ((rtx));
static void redirect_exp_1 PARAMS ((rtx *, rtx, rtx, rtx));
static void invert_exp_1 PARAMS ((rtx, rtx));
static void delete_from_jump_chain PARAMS ((rtx));
static int delete_labelref_insn PARAMS ((rtx, rtx, int));
static void mark_modified_reg PARAMS ((rtx, rtx, void *));
......@@ -4414,109 +4416,102 @@ never_reached_warning (avoided_insn)
"will never be executed");
}
/* Invert the condition of the jump JUMP, and make it jump
to label NLABEL instead of where it jumps now. */
/* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
NLABEL as a return. Accrue modifications into the change group. */
int
invert_jump (jump, nlabel)
rtx jump, nlabel;
{
/* We have to either invert the condition and change the label or
do neither. Either operation could fail. We first try to invert
the jump. If that succeeds, we try changing the label. If that fails,
we invert the jump back to what it was. */
if (! invert_exp (PATTERN (jump), jump))
return 0;
if (redirect_jump (jump, nlabel))
{
/* An inverted jump means that a probability taken becomes a
probability not taken. Subtract the branch probability from the
probability base to convert it back to a taken probability. */
rtx note = find_reg_note (jump, REG_BR_PROB, 0);
if (note)
XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
return 1;
}
if (! invert_exp (PATTERN (jump), jump))
/* This should just be putting it back the way it was. */
abort ();
return 0;
}
/* Invert the jump condition of rtx X contained in jump insn, INSN.
Return 1 if we can do so, 0 if we cannot find a way to do so that
matches a pattern. */
int
invert_exp (x, insn)
rtx x;
static void
redirect_exp_1 (loc, olabel, nlabel, insn)
rtx *loc;
rtx olabel, nlabel;
rtx insn;
{
register RTX_CODE code;
register rtx x = *loc;
register RTX_CODE code = GET_CODE (x);
register int i;
register const char *fmt;
code = GET_CODE (x);
if (code == IF_THEN_ELSE)
if (code == LABEL_REF)
{
register rtx comp = XEXP (x, 0);
register rtx tem;
/* We can do this in two ways: The preferable way, which can only
be done if this is not an integer comparison, is to reverse
the comparison code. Otherwise, swap the THEN-part and ELSE-part
of the IF_THEN_ELSE. If we can't do either, fail. */
if (XEXP (x, 0) == olabel)
{
rtx n;
if (nlabel)
n = gen_rtx_LABEL_REF (VOIDmode, nlabel);
else
n = gen_rtx_RETURN (VOIDmode);
if (can_reverse_comparison_p (comp, insn)
&& validate_change (insn, &XEXP (x, 0),
gen_rtx_fmt_ee (reverse_condition (GET_CODE (comp)),
GET_MODE (comp), XEXP (comp, 0),
XEXP (comp, 1)), 0))
return 1;
validate_change (insn, loc, n, 1);
return;
}
}
else if (code == RETURN && olabel == 0)
{
x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
if (loc == &PATTERN (insn))
x = gen_rtx_SET (VOIDmode, pc_rtx, x);
validate_change (insn, loc, x, 1);
return;
}
tem = XEXP (x, 1);
validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
validate_change (insn, &XEXP (x, 2), tem, 1);
return apply_change_group ();
if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
&& GET_CODE (SET_SRC (x)) == LABEL_REF
&& XEXP (SET_SRC (x), 0) == olabel)
{
validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
return;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
if (! invert_exp (XEXP (x, i), insn))
return 0;
}
redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
else if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (x, i); j++)
if (!invert_exp (XVECEXP (x, i, j), insn))
return 0;
redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
}
}
}
return 1;
/* Similar, but apply the change group and report success or failure. */
int
redirect_exp (loc, olabel, nlabel, insn)
rtx *loc;
rtx olabel, nlabel;
rtx insn;
{
redirect_exp_1 (loc, olabel, nlabel, insn);
if (num_validated_changes () == 0)
return 0;
return apply_change_group ();
}
/* Make jump JUMP jump to label NLABEL instead of where it jumps now.
If the old jump target label is unused as a result,
it and the code following it may be deleted.
/* Make JUMP go to NLABEL instead of where it jumps now. Accrue
the modifications into the change group. Return false if we did
not see how to do that. */
int
redirect_jump_1 (jump, nlabel)
rtx jump, nlabel;
{
int ochanges = num_validated_changes ();
redirect_exp_1 (&PATTERN (jump), JUMP_LABEL (jump), nlabel, jump);
return num_validated_changes () > ochanges;
}
/* Make JUMP go to NLABEL instead of where it jumps now. If the old
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.
The return value will be 1 if the change was made, 0 if it wasn't (this
can only occur for NLABEL == 0). */
The return value will be 1 if the change was made, 0 if it wasn't
(this can only occur for NLABEL == 0). */
int
redirect_jump (jump, nlabel)
......@@ -4564,6 +4559,131 @@ redirect_jump (jump, nlabel)
return 1;
}
/* Invert the jump condition of rtx X contained in jump insn, INSN.
Accrue the modifications into the change group. */
static void
invert_exp_1 (x, insn)
rtx x;
rtx insn;
{
register RTX_CODE code;
register int i;
register const char *fmt;
code = GET_CODE (x);
if (code == IF_THEN_ELSE)
{
register rtx comp = XEXP (x, 0);
register rtx tem;
/* We can do this in two ways: The preferable way, which can only
be done if this is not an integer comparison, is to reverse
the comparison code. Otherwise, swap the THEN-part and ELSE-part
of the IF_THEN_ELSE. If we can't do either, fail. */
if (can_reverse_comparison_p (comp, insn))
{
validate_change (insn, &XEXP (x, 0),
gen_rtx_fmt_ee (reverse_condition (GET_CODE (comp)),
GET_MODE (comp), XEXP (comp, 0),
XEXP (comp, 1)),
1);
return;
}
tem = XEXP (x, 1);
validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
validate_change (insn, &XEXP (x, 2), tem, 1);
return;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
invert_exp_1 (XEXP (x, i), insn);
else if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (x, i); j++)
invert_exp_1 (XVECEXP (x, i, j), insn);
}
}
}
/* Invert the jump condition of rtx X contained in jump insn, INSN.
Return 1 if we can do so, 0 if we cannot find a way to do so that
matches a pattern. */
int
invert_exp (x, insn)
rtx x;
rtx insn;
{
invert_exp_1 (x, insn);
if (num_validated_changes () == 0)
return 0;
return apply_change_group ();
}
/* Invert the condition of the jump JUMP, and make it jump to label
NLABEL instead of where it jumps now. Accrue changes into the
change group. Return false if we didn't see how to perform the
inversion and redirection. */
int
invert_jump_1 (jump, nlabel)
rtx jump, nlabel;
{
int ochanges;
ochanges = num_validated_changes ();
invert_exp_1 (PATTERN (jump), jump);
if (num_validated_changes () == ochanges)
return 0;
return redirect_jump_1 (jump, nlabel);
}
/* Invert the condition of the jump JUMP, and make it jump to label
NLABEL instead of where it jumps now. Return true if successful. */
int
invert_jump (jump, nlabel)
rtx jump, nlabel;
{
/* We have to either invert the condition and change the label or
do neither. Either operation could fail. We first try to invert
the jump. If that succeeds, we try changing the label. If that fails,
we invert the jump back to what it was. */
if (! invert_exp (PATTERN (jump), jump))
return 0;
if (redirect_jump (jump, nlabel))
{
/* An inverted jump means that a probability taken becomes a
probability not taken. Subtract the branch probability from the
probability base to convert it back to a taken probability. */
rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
if (note)
XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
return 1;
}
if (! invert_exp (PATTERN (jump), jump))
/* This should just be putting it back the way it was. */
abort ();
return 0;
}
/* Delete the instruction JUMP from any jump chain it might be on. */
static void
......@@ -4600,72 +4720,6 @@ delete_from_jump_chain (jump)
}
}
/* If NLABEL is nonzero, throughout the rtx at LOC,
alter (LABEL_REF OLABEL) to (LABEL_REF NLABEL). If OLABEL is
zero, alter (RETURN) to (LABEL_REF NLABEL).
If NLABEL is zero, alter (LABEL_REF OLABEL) to (RETURN) and check
validity with validate_change. Convert (set (pc) (label_ref olabel))
to (return).
Return 0 if we found a change we would like to make but it is invalid.
Otherwise, return 1. */
int
redirect_exp (loc, olabel, nlabel, insn)
rtx *loc;
rtx olabel, nlabel;
rtx insn;
{
register rtx x = *loc;
register RTX_CODE code = GET_CODE (x);
register int i;
register const char *fmt;
if (code == LABEL_REF)
{
if (XEXP (x, 0) == olabel)
{
if (nlabel)
XEXP (x, 0) = nlabel;
else
return validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 0);
return 1;
}
}
else if (code == RETURN && olabel == 0)
{
x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
if (loc == &PATTERN (insn))
x = gen_rtx_SET (VOIDmode, pc_rtx, x);
return validate_change (insn, loc, x, 0);
}
if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
&& GET_CODE (SET_SRC (x)) == LABEL_REF
&& XEXP (SET_SRC (x), 0) == olabel)
return validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 0);
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
if (! redirect_exp (&XEXP (x, i), olabel, nlabel, insn))
return 0;
}
else if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (x, i); j++)
if (! redirect_exp (&XVECEXP (x, i, j), olabel, nlabel, insn))
return 0;
}
}
return 1;
}
/* Make jump JUMP jump to label NLABEL, assuming it used to be a tablejump.
If the old jump target label (before the dispatch table) becomes unused,
......
......@@ -1502,9 +1502,11 @@ extern int simplejump_p PARAMS ((rtx));
extern int returnjump_p PARAMS ((rtx));
extern int onlyjump_p PARAMS ((rtx));
extern int sets_cc0_p PARAMS ((rtx));
extern int invert_jump_1 PARAMS ((rtx, rtx));
extern int invert_jump PARAMS ((rtx, rtx));
extern int rtx_renumbered_equal_p PARAMS ((rtx, rtx));
extern int true_regnum PARAMS ((rtx));
extern int redirect_jump_1 PARAMS ((rtx, rtx));
extern int redirect_jump PARAMS ((rtx, rtx));
extern void jump_optimize PARAMS ((rtx, int, int, int));
extern void jump_optimize_minimal PARAMS ((rtx));
......@@ -1823,11 +1825,12 @@ extern int stack_regs_mentioned PARAMS ((rtx insn));
#endif
/* In toplev.c */
extern rtx stack_limit_rtx;
/* In regrename.c */
extern void regrename_optimize PARAMS ((void));
/* In condexec.c */
extern void if_convert PARAMS ((int));
#endif /* _RTL_H */
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