From a8346656e23d1a3fc9262a7ac6c80690862a99e9 Mon Sep 17 00:00:00 2001
From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sun, 15 Jul 2001 12:00:34 +0000
Subject: [PATCH] 	* loop.c (scan_loop): Add USEs inside PARALLELs into
 dependencies 	of the movable.

	* toplev.c (rest_of_compilation): Allow new pseudoes for mode switching.

	* i386-protos.h (ix86_split_fp_branch): Update prototype.
	(ix86_fp_jump_nontrivial_p): New.
	* i386.md (fp_jcc_?): Update call of split_fp_branch;
	use ix86_fp_jump_nontrivial_p.
	* i386.c (ix86_fp_jump_nontrivial_p): New.
	(ix86_split_fp_branch): Accept code instead of rtx.
	(ix86_expand_compare): Expand comparison early in case
	doing so is resonably cheap.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44019 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                 | 16 ++++++++
 gcc/config/i386/i386-protos.h |  4 +-
 gcc/config/i386/i386.c        | 77 +++++++++++++++++++++++------------
 gcc/config/i386/i386.md       | 34 ++++++++++------
 gcc/loop.c                    | 12 ++++++
 gcc/toplev.c                  |  2 +
 6 files changed, 107 insertions(+), 38 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2d4928c2448f..9fdfc69d8f6b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+Sun Jul 15 00:53:35 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+	* loop.c (scan_loop): Add USEs inside PARALLELs into dependencies
+	of the movable.
+
+	* toplev.c (rest_of_compilation): Allow new pseudoes for mode switching.
+
+	* i386-protos.h (ix86_split_fp_branch): Update prototype.
+	(ix86_fp_jump_nontrivial_p): New.
+	* i386.md (fp_jcc_?): Update call of split_fp_branch;
+	use ix86_fp_jump_nontrivial_p.
+	* i386.c (ix86_fp_jump_nontrivial_p): New.
+	(ix86_split_fp_branch): Accept code instead of rtx.
+	(ix86_expand_compare): Expand comparison early in case
+	doing so is resonably cheap.
+
 2001-07-15  Nick Clifton  <nickc@cambridge.redhat.com>
 
 	* config/rs6000/sysv4.h (CPP_ENDIAN_BIG_SPEC): Assert 'endian'
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index f98b95ba2fd6..e204834dd21a 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -142,7 +142,8 @@ extern int x86_64_zero_extended_value PARAMS ((rtx));
 
 extern rtx ix86_force_to_memory PARAMS ((enum machine_mode, rtx));
 extern void ix86_free_from_memory PARAMS ((enum machine_mode));
-extern void ix86_split_fp_branch PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
+extern void ix86_split_fp_branch PARAMS ((enum rtx_code code, rtx,
+					  rtx, rtx, rtx, rtx));
 extern int ix86_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
 extern int ix86_register_move_cost PARAMS ((enum machine_mode, enum reg_class,
 					    enum reg_class));
@@ -155,6 +156,7 @@ extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
 					  int));
 extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
 extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
+extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code));
 
 
 #ifdef TREE_CODE
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 81cfcd72a200..dcafe019ba7e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -6060,6 +6060,18 @@ ix86_expand_compare (code, second_test, bypass_test)
   return ret;
 }
 
+/* Return true if the CODE will result in nontrivial jump sequence.  */
+bool
+ix86_fp_jump_nontrivial_p (code)
+    enum rtx_code code;
+{
+  enum rtx_code bypass_code, first_code, second_code;
+  if (!TARGET_CMOVE)
+    return true;
+  ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
+  return bypass_code != NIL || second_code != NIL;
+}
+
 void
 ix86_expand_branch (code, label)
      enum rtx_code code;
@@ -6084,34 +6096,48 @@ ix86_expand_branch (code, label)
     case DFmode:
     case XFmode:
     case TFmode:
-      /* Don't expand the comparison early, so that we get better code
-	 when jump or whoever decides to reverse the comparison.  */
       {
 	rtvec vec;
 	int use_fcomi;
+	enum rtx_code bypass_code, first_code, second_code;
 
 	code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
 					     &ix86_compare_op1);
-
-	tmp = gen_rtx_fmt_ee (code, VOIDmode,
-			      ix86_compare_op0, ix86_compare_op1);
-	tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
-				    gen_rtx_LABEL_REF (VOIDmode, label),
-				    pc_rtx);
-	tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
-
-	use_fcomi = ix86_use_fcomi_compare (code);
-	vec = rtvec_alloc (3 + !use_fcomi);
-	RTVEC_ELT (vec, 0) = tmp;
-	RTVEC_ELT (vec, 1)
-	  = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
-	RTVEC_ELT (vec, 2)
-	  = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
-	if (! use_fcomi)
-	  RTVEC_ELT (vec, 3)
-	    = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
-
-        emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
+	
+	ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
+
+	/* Check whether we will use the natural sequence with one jump.  If
+	   so, we can expand jump early.  Otherwise delay expansion by
+	   creating compound insn to not confuse optimizers.  */
+	if (bypass_code == NIL && second_code == NIL
+	    && TARGET_CMOVE)
+	  {
+	    ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
+				  gen_rtx_LABEL_REF (VOIDmode, label),
+				  pc_rtx, NULL_RTX);
+	  }
+	else
+	  {
+	    tmp = gen_rtx_fmt_ee (code, VOIDmode,
+				  ix86_compare_op0, ix86_compare_op1);
+	    tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
+					gen_rtx_LABEL_REF (VOIDmode, label),
+					pc_rtx);
+	    tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
+
+	    use_fcomi = ix86_use_fcomi_compare (code);
+	    vec = rtvec_alloc (3 + !use_fcomi);
+	    RTVEC_ELT (vec, 0) = tmp;
+	    RTVEC_ELT (vec, 1)
+	      = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
+	    RTVEC_ELT (vec, 2)
+	      = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
+	    if (! use_fcomi)
+	      RTVEC_ELT (vec, 3)
+		= gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
+
+	    emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
+	  }
 	return;
       }
 
@@ -6235,12 +6261,13 @@ ix86_expand_branch (code, label)
 
 /* Split branch based on floating point condition.  */
 void
-ix86_split_fp_branch (condition, op1, op2, target1, target2, tmp)
-     rtx condition, op1, op2, target1, target2, tmp;
+ix86_split_fp_branch (code, op1, op2, target1, target2, tmp)
+     enum rtx_code code;
+     rtx op1, op2, target1, target2, tmp;
 {
   rtx second, bypass;
   rtx label = NULL_RTX;
-  enum rtx_code code = GET_CODE (condition);
+  rtx condition;
 
   if (target2 != pc_rtx)
     {
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index a07c169d1136..baff6bc77453 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12686,7 +12686,8 @@
   "TARGET_CMOVE && TARGET_80387
    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
    && FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_1_sse"
@@ -12700,7 +12701,8 @@
    (clobber (reg:CCFP 17))]
   "TARGET_80387
    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_1_sse_only"
@@ -12713,7 +12715,8 @@
    (clobber (reg:CCFP 18))
    (clobber (reg:CCFP 17))]
   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_2"
@@ -12728,7 +12731,8 @@
   "TARGET_CMOVE && TARGET_80387
    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
    && FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_2_sse"
@@ -12742,7 +12746,8 @@
    (clobber (reg:CCFP 17))]
   "TARGET_80387
    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_2_sse_only"
@@ -12755,7 +12760,8 @@
    (clobber (reg:CCFP 18))
    (clobber (reg:CCFP 17))]
   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_3"
@@ -12773,7 +12779,8 @@
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
-		      operands[1], operands[2]) == CCFPmode"
+		      operands[1], operands[2]) == CCFPmode
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_4"
@@ -12791,7 +12798,8 @@
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
-		      operands[1], operands[2]) == CCFPmode"
+		      operands[1], operands[2]) == CCFPmode
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_5"
@@ -12806,7 +12814,8 @@
    (clobber (match_scratch:HI 4 "=a"))]
   "TARGET_80387
    && FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_insn "*fp_jcc_6"
@@ -12821,7 +12830,8 @@
    (clobber (match_scratch:HI 4 "=a"))]
   "TARGET_80387
    && FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])
+   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
   "#")
 
 (define_split
@@ -12836,7 +12846,7 @@
   "reload_completed"
   [(const_int 0)]
 {
-  ix86_split_fp_branch (operands[0], operands[1], operands[2],
+  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
 			operands[3], operands[4], NULL_RTX);
   DONE;
 })
@@ -12857,7 +12867,7 @@
 	  (match_dup 3)
 	  (match_dup 4)))]
 {
-  ix86_split_fp_branch (operands[0], operands[1], operands[2],
+  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
 			operands[3], operands[4], operands[5]);
   DONE;
 })
diff --git a/gcc/loop.c b/gcc/loop.c
index 82f09f3ecbb3..db1ec9df7a35 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -705,6 +705,18 @@ scan_loop (loop, flags)
 		}
 	    }
 
+	  /* For parallels, add any possible uses to the depencies, as we can't move
+	     the insn without resolving them first.  */
+	  if (GET_CODE (PATTERN (p)) == PARALLEL)
+	    {
+	      for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
+		{
+		  rtx x = XVECEXP (PATTERN (p), 0, i);
+		  if (GET_CODE (x) == USE)
+		    dependencies = gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0), dependencies);
+		}
+	    }
+
 	  /* Don't try to optimize a register that was made
 	     by loop-optimization for an inner loop.
 	     We don't know its life-span, so we can't compute the benefit.  */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e63fc47db67c..416187275b38 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -3422,6 +3422,7 @@ rest_of_compilation (decl)
 #ifdef OPTIMIZE_MODE_SWITCHING
   timevar_push (TV_GCSE);
 
+  no_new_pseudos = 1;
   if (optimize_mode_switching (NULL))
     {
       /* We did work, and so had to regenerate global life information.
@@ -3429,6 +3430,7 @@ rest_of_compilation (decl)
 	 information below.  */
       register_life_up_to_date = 1;
     }
+  no_new_pseudos = 0;
 
   timevar_pop (TV_GCSE);
 #endif
-- 
GitLab