i386 fp jumps support bits
Jan Hubicka
jh@suse.cz
Sun May 14 13:15:00 GMT 2000
Hi
We are consistently ignoring the existence of jumps in parallels. Now when
i386 uses them for fp conditionals, we ought to take care for these. Here are
some infrastructure bits that allows to handle condjumps together with
condjumps in parallels.
Basically it adds function to detect condjump, single set equivalent to find
the jump and two functions to verify whether jump is removable and whether we
may change the condition (the condition may be possibly used to set some other
register)
Some use of these bits is comming shortly.
Mon May 8 10:14:56 CEST 2000 Jan Hubicka <jh@suse.cz>
* jump.c (condjump_p): Mark as depreached.
(nontrivial_condump_p): New.
(safe_to_change_condjump_condition_p): New.
(safe_to_remove_condjump_p): New.
* rtl.h (nontrivial_condump_p, safe_to_change_condjump_condition_p,
safe_to_remove_condjump_p): Declare.
*** jump.c.old Sun May 7 09:49:43 2000
--- jump.c Mon May 8 09:55:17 2000
*************** simplejump_p (insn)
*** 2086,2092 ****
}
/* Return nonzero if INSN is a (possibly) conditional jump
! and nothing more. */
int
condjump_p (insn)
--- 2086,2097 ----
}
/* Return nonzero if INSN is a (possibly) conditional jump
! and nothing more.
!
! Use this function is depreached, since we need to support
! branch and compare insns. Use nontrivial_condjump_p instead
! whenever possible.
! */
int
condjump_p (insn)
*************** condjump_p (insn)
*** 2113,2119 ****
}
/* Return nonzero if INSN is a (possibly) conditional jump inside a
! PARALLEL. */
int
condjump_in_parallel_p (insn)
--- 2118,2129 ----
}
/* Return nonzero if INSN is a (possibly) conditional jump inside a
! PARALLEL.
!
! Use this function is depreached, since we need to support
! branch and compare insns. Use nontrivial_condjump_p instead
! whenever possible.
! */
int
condjump_in_parallel_p (insn)
*************** condjump_in_parallel_p (insn)
*** 2143,2148 ****
--- 2153,2241 ----
|| GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
return 1;
return 0;
+ }
+
+ /* Return set of PC if available. */
+ rtx
+ pc_set (insn)
+ rtx insn;
+ {
+ rtx pat;
+ if (GET_CODE (insn) != JUMP_INSN)
+ return NULL;
+ pat = PATTERN (insn);
+ /* The set is allowed to appear eighter as insn pattern or the first in PARALLEL
+ expression. */
+ if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
+ return pat;
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ /* PC set must be always the first expression. */
+ rtx set = XVECEXP (pat, 0, 0);
+ if (GET_CODE (set) == SET && GET_CODE (SET_DEST (set)) == PC)
+ return set;
+ }
+ return NULL;
+ }
+
+ /* Return true when insn is (possibly) conditional jump.
+ This function work for instructions containing PC sets in PARALLELs. */
+ int
+ nontrivial_condjump_p (insn)
+ rtx insn;
+ {
+ rtx x = pc_set (insn);
+ if (!x)
+ return 0;
+ /* ??? Allow computed GOTOs as well? */
+ if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
+ return 0;
+ if (XEXP (SET_SRC (x), 2) == pc_rtx
+ && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
+ || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
+ return 1;
+ if (XEXP (SET_SRC (x), 1) == pc_rtx
+ && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
+ || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
+ return 1;
+ return 0;
+ }
+
+ /* Return true when the condition in insn is used only for jumps and not to store
+ to some other pseudos. */
+ int
+ safe_to_change_condjump_condition_p (insn)
+ rtx insn;
+ {
+ rtx set = pc_set (insn);
+ int i;
+ if (!nontrivial_condjump_p (insn))
+ return 0;
+ if (GET_CODE (PATTERN (insn)) != PARALLEL)
+ return 1;
+ for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ {
+ rtx x = XVECEXP (PATTERN (insn), 0, i);
+ /* We are looking only for the sets that may store
+ condition for later reuse. */
+ if (x != set && GET_CODE (set) == SET)
+ /* TODO: check that changing the condition will clobber the result here. */
+ return 0;
+ }
+ return 1;
+ }
+
+ /* Return true when the condjump is safe to remove. */
+ int
+ safe_to_remove_condjump_p (insn)
+ rtx insn;
+ {
+ if (!nontrivial_condjump_p (insn))
+ return 0;
+ /* For non-single set insns we may remove set of the other registers. */
+ if (!single_set (insn))
+ return 0;
+ return 1;
}
/* Return the label of a conditional jump. */
*** rtl.h.old1 Sun May 7 10:13:55 2000
--- rtl.h Sun May 7 12:33:38 2000
*************** extern void cse_end_of_basic_block PARAM
*** 1498,1503 ****
--- 1500,1509 ----
/* In jump.c */
extern int comparison_dominates_p PARAMS ((enum rtx_code, enum rtx_code));
extern int condjump_p PARAMS ((rtx));
+ extern int nontrivial_condjump_p PARAMS ((rtx));
+ extern int safe_to_remove_condjump_p PARAMS ((rtx));
+ extern int safe_to_condjump_condjump_condition_p PARAMS ((rtx));
+ extern rtx pc_set PARAMS ((rtx));
extern rtx condjump_label PARAMS ((rtx));
extern int simplejump_p PARAMS ((rtx));
extern int returnjump_p PARAMS ((rtx));
More information about the Gcc-patches
mailing list