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