condexec merge part 11
Richard Henderson
rth@cygnus.com
Thu Apr 27 00:23:00 GMT 2000
This looks longer than it is. Basically reworks invert_jump
and redirect_jump to only add to the change group. Which
allows the caller to modify a bunch o stuff, modify the branch,
then commit everything at once to see if it worked.
The names aren't the best, but I couldn't think what else to
call them. Suggestions?
r~
* 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.
Index: jump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/jump.c,v
retrieving revision 1.118
diff -c -p -d -r1.118 jump.c
*** jump.c 2000/04/27 05:58:05 1.118
--- jump.c 2000/04/27 07:19:20
*************** static int jump_back_p PARAMS ((rtx, r
*** 121,126 ****
--- 121,128 ----
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 *));
*************** never_reached_warning (avoided_insn)
*** 4414,4522 ****
"will never be executed");
}
! /* Invert the condition of the jump JUMP, and make it jump
! to label NLABEL instead of where it jumps now. */
!
! 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;
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)), 0))
! return 1;
!
! 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 ();
}
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;
! }
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;
}
}
! return 1;
}
-
- /* 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.
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). */
int
redirect_jump (jump, nlabel)
--- 4416,4517 ----
"will never be executed");
}
! /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
! NLABEL as a return. Accrue modifications into the change group. */
! static void
! redirect_exp_1 (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)
! {
! rtx n;
! if (nlabel)
! n = gen_rtx_LABEL_REF (VOIDmode, nlabel);
! else
! n = gen_rtx_RETURN (VOIDmode);
! 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;
! }
! 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')
! 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++)
! redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
}
}
+ }
! /* 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 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). */
int
redirect_jump (jump, nlabel)
*************** redirect_jump (jump, nlabel)
*** 4564,4569 ****
--- 4559,4689 ----
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
*************** delete_from_jump_chain (jump)
*** 4598,4669 ****
break;
}
}
- }
-
- /* 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.
--- 4718,4723 ----
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.192
diff -c -p -d -r1.192 rtl.h
*** rtl.h 2000/04/21 19:32:09 1.192
--- rtl.h 2000/04/27 07:19:20
*************** extern int simplejump_p PARAMS ((rtx))
*** 1502,1510 ****
--- 1502,1512 ----
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));
*************** extern int stack_regs_mentioned PARAMS
*** 1823,1833 ****
#endif
/* In toplev.c */
-
extern rtx stack_limit_rtx;
/* In regrename.c */
-
extern void regrename_optimize PARAMS ((void));
#endif /* _RTL_H */
--- 1825,1836 ----
#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 */
More information about the Gcc-patches
mailing list