This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: activate thread_jumps for ix86


Bootstraps and compares for ix86.  No testsuite regressions.
SPARC tests in progress.

OK? (assuming SPARC is clean)

2000-09-22  Greg McGary  <greg@mcgary.org>

	* jump.c (explode_condition): New function.
	(thread_jumps): Call explode_condition.

Index: jump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/jump.c,v
retrieving revision 1.136
diff -u -p -r1.136 jump.c
--- jump.c	2000/08/04 20:28:05	1.136
+++ jump.c	2000/09/22 20:45:08
@@ -127,6 +127,7 @@ static int invert_exp			PARAMS ((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 *));
+static rtx explode_condition		PARAMS ((rtx, enum rtx_code *, rtx *, rtx *, rtx *));
 static void redirect_tablejump		PARAMS ((rtx, rtx));
 static void jump_optimize_1		PARAMS ((rtx, int, int, int, int, int));
 static int returnjump_p_1	        PARAMS ((rtx *, void *));
@@ -3789,9 +3790,10 @@ thread_jumps (f, max_reg, flag_before_lo
      senses of the two branches.  So adjust the first branch accordingly
      in this case.  */
 
-  rtx label, b1, b2, t1, t2;
+  rtx label;
   enum rtx_code code1, code2;
-  rtx b1op0, b1op1, b2op0, b2op1;
+  rtx b1, bc1, t1, cond1, b1op0, b1op1;
+  rtx b2, bc2, t2, cond2, b2op0, b2op1;
   int changed = 1;
   int i;
   int *all_reset;
@@ -3809,9 +3811,6 @@ thread_jumps (f, max_reg, flag_before_lo
 
       for (b1 = f; b1; b1 = NEXT_INSN (b1))
 	{
-	  rtx set;
-	  rtx set2;
-
 	  /* Get to a candidate branch insn.  */
 	  if (GET_CODE (b1) != JUMP_INSN
 	      || ! any_condjump_p (b1) || JUMP_LABEL (b1) == 0)
@@ -3876,33 +3875,21 @@ thread_jumps (f, max_reg, flag_before_lo
 	      || !any_condjump_p (b2)
 	      || !onlyjump_p (b2))
 	    continue;
-	  set = pc_set (b1);
-	  set2 = pc_set (b2);
 
 	  /* Get the comparison codes and operands, reversing the
 	     codes if appropriate.  If we don't have comparison codes,
 	     we can't do anything.  */
-	  b1op0 = XEXP (XEXP (SET_SRC (set), 0), 0);
-	  b1op1 = XEXP (XEXP (SET_SRC (set), 0), 1);
-	  code1 = GET_CODE (XEXP (SET_SRC (set), 0));
-	  if (XEXP (SET_SRC (set), 1) == pc_rtx)
-	    code1 = reverse_condition (code1);
-
-	  b2op0 = XEXP (XEXP (SET_SRC (set2), 0), 0);
-	  b2op1 = XEXP (XEXP (SET_SRC (set2), 0), 1);
-	  code2 = GET_CODE (XEXP (SET_SRC (set2), 0));
-	  if (XEXP (SET_SRC (set2), 1) == pc_rtx)
-	    code2 = reverse_condition (code2);
+	  bc1 = explode_condition (b1, &code1, &cond1, &b1op0, &b1op1);
+	  bc2 = explode_condition (b2, &code2, &cond2, &b2op0, &b2op1);
 
 	  /* If they test the same things and knowing that B1 branches
 	     tells us whether or not B2 branches, check if we
 	     can thread the branch.  */
-	  if (rtx_equal_for_thread_p (b1op0, b2op0, b2)
-	      && rtx_equal_for_thread_p (b1op1, b2op1, b2)
+	  if (rtx_equal_for_thread_p (b1op0, b2op0, bc2)
+	      && rtx_equal_for_thread_p (b1op1, b2op1, bc2)
 	      && (comparison_dominates_p (code1, code2)
-		  || (can_reverse_comparison_p (XEXP (SET_SRC (set), 0), b1)
-		      && comparison_dominates_p (code1,
-						 reverse_condition (code2)))))
+		  || (can_reverse_comparison_p (cond1, bc1)
+		      && comparison_dominates_p (code1, reverse_condition (code2)))))
 
 	    {
 	      t1 = prev_nonnote_insn (b1);
@@ -3967,6 +3954,61 @@ thread_jumps (f, max_reg, flag_before_lo
   free (modified_regs);
   free (same_regs);
   free (all_reset);
+}
+
+/* Extract the interesting pieces from a conditional jump or
+   conditional trap insn, and for architectures that use a
+   condition-code register, from the associated insn that sets
+   condition codes based on a comparison.  The pieces we want are the
+   condition expression, the comparison code, and the two operands of
+   the comparison.  If we needed to grope backward to find a
+   set-condition-code insn, return that insn, otherwise return the
+   given conditional jump/trap insn.  */
+
+static rtx
+explode_condition (insn, code_loc, cond_loc, op0_loc, op1_loc)
+     rtx insn;
+     enum rtx_code *code_loc;
+     rtx *cond_loc, *op0_loc, *op1_loc;
+{
+  /* set is non-NULL for cond jump, and NULL for cond trap */
+  rtx set = pc_set (insn);
+  rtx src = set ? SET_SRC (set) : PATTERN (insn);
+  rtx cond = XEXP (src, 0);
+  enum rtx_code code = GET_CODE (cond);
+  rtx op0 = XEXP (cond, 0);
+  rtx op1 = XEXP (cond, 1);
+  rtx prev;
+
+  if (set && XEXP (src, 1) == pc_rtx)
+    code = reverse_condition (code);
+
+  if (op1 == const0_rtx
+      && ((GET_CODE (op0) == REG && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
+#ifdef HAVE_cc0
+	  || op0 == cc0_rtx
+#endif
+	  ))
+    {
+      for (prev = prev_nonnote_insn (insn);
+	   prev && GET_CODE (prev) != CODE_LABEL;
+	   prev = prev_nonnote_insn (prev))
+	if ((set = single_set (prev)) != 0
+	    && rtx_equal_p (SET_DEST (set), op0)
+	    && GET_CODE (SET_SRC (set)) == COMPARE)
+	  {
+	    op0 = XEXP (SET_SRC (set), 0);
+	    op1 = XEXP (SET_SRC (set), 1);
+	    insn = prev;
+	    break;
+	  }
+    }
+
+  *cond_loc = cond;
+  *code_loc = code;
+  *op0_loc = op0;
+  *op1_loc = op1;
+  return insn;
 }
 
 /* This is like RTX_EQUAL_P except that it knows about our handling of

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]