i386 integer move patterns cleanup.

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Thu Nov 25 06:32:00 GMT 1999


Hi
The two copies (clobbering and nonclobbering) of move patterns are pretty
anoying.  I think we can safely remove them now when peephole2 exists.
The changes move patterns to not allow clobbering of flags and adds special
case only for xor reg, reg and or $-1, reg cases.
I've verified that both combine and cse hapilly removes clobbers when
expression gets simplified to move and I am not aware of other place
in compler where this change can cause problems.

I've also rewrote the peep2 converting moves to or and removed all places
in i386.md where clobbers was added to or except the peep2 doing that.
I believe it is cleaner and peepholing them don't cost too much.

Honza

Thu Nov 25 15:21:30 MET 1999  Jan Hubicka  <hubicka@freesoft.cz>
	* i386.c (ix86_expand_move): Never add clobbers to move patterns.
	* i386.md (movsi_xor): New.
	(movsi_or): New.
	(movsi_1): Remove.
	(movsi_2): Rename to movsi_1.
	(movhi_1): Remove.
	(movhi_2): Rename to movhi_1.
	(movqi_1): Remove.
	(movqi_2): Rename to movqi_1.
	(movdi_1): Remove; remove splitter.
	(movdi_2): Rename to movdi_1.
	(zero_extend splitters): Do not emit clobbers for move patterns.
	(mov -1,reg -> or peep2s): Enable again, rewrite to single peephole.

Index: egcs/gcc/config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.107
diff -c -3 -p -r1.107 i386.c
*** i386.c	1999/11/21 01:34:21	1.107
--- i386.c	1999/11/25 14:20:22
*************** ix86_expand_move (mode, operands)
*** 3653,3667 ****
  		   && ! standard_80387_constant_p (operands[1]))
  	    operands[1] = validize_mem (force_const_mem (mode, operands[1]));
  	}
-       else
- 	{
- 	  /* Try to guess when a cc clobber on the move might be fruitful.  */
- 	  if (!strict
- 	      && GET_CODE (operands[0]) == REG
- 	      && operands[1] == const0_rtx
- 	      && !flag_peephole2)
- 	    want_clobber = 1;
- 	}
      }
  
    insn = gen_rtx_SET (VOIDmode, operands[0], operands[1]);
--- 3653,3658 ----
Index: egcs/gcc/config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.110
diff -c -3 -p -r1.110 i386.md
*** i386.md	1999/11/25 12:53:44	1.110
--- i386.md	1999/11/25 14:20:32
***************
*** 1142,1180 ****
    "pop{l}\\t%0"
    [(set_attr "type" "pop")])
  
! (define_insn "*movsi_1"
!   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
! 	(match_operand:SI 1 "general_operand" "rim,ri"))
     (clobber (reg:CC 17))]
!   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
    "*
  {
!   switch (get_attr_type (insn))
!     {
!     case TYPE_ALU1:
!       if (operands[1] != const0_rtx)
! 	abort();
!       return \"xor{l}\\t{%0, %0|%0, %0}\";
!     case TYPE_LEA:
!       return \"lea{l}\\t{%1, %0|%0, %1}\";
!     default:
!       if (flag_pic && SYMBOLIC_CONST (operands[1]))
! 	abort();
!       return \"mov{l}\\t{%1, %0|%0, %1}\";
!     }
  }"
!   [(set (attr "type")
!      (cond [(and (match_operand:SI 1 "const0_operand" "")
! 		 (and (match_operand:SI 0 "register_operand" "")
! 		      (eq (symbol_ref "TARGET_USE_MOV0") (const_int 0))))
! 	      (const_string "alu1")
! 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
! 		 (match_operand:SI 1 "symbolic_operand" ""))
! 	      (const_string "lea")
! 	   ]
! 	   (const_string "imov")))])
  
! (define_insn "*movsi_2"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
  	(match_operand:SI 1 "general_operand" "rinm,rin"))]
    "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
--- 1142,1172 ----
    "pop{l}\\t%0"
    [(set_attr "type" "pop")])
  
! (define_insn "*movsi_xor"
!   [(set (match_operand:SI 0 "register_operand" "=r")
! 	(match_operand:SI 1 "const0_operand" "i"))
     (clobber (reg:CC 17))]
!   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
!   "xor{l}\\t{%0, %0|%0, %0}"
!   [(set_attr "type" "alu1")
!    (set_attr "length" "2")])
! 
! (define_insn "*movsi_or"
!   [(set (match_operand:SI 0 "register_operand" "=r")
! 	(match_operand:SI 1 "immediate_operand" "i"))
!    (clobber (reg:CC 17))]
!   "reload_completed && GET_CODE (operands[1]) == CONST_INT
!    && INTVAL (operands[1]) == -1
!    && (TARGET_PENTIUM || optimize_size)"
    "*
  {
!   operands[1] = constm1_rtx;
!   return \"or{l}\\t{%1, %0|%1, %0}\";
  }"
!   [(set_attr "type" "alu1")
!    (set_attr "length" "3")])
  
! (define_insn "*movsi_1"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
  	(match_operand:SI 1 "general_operand" "rinm,rin"))]
    "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
***************
*** 1234,1291 ****
  
  (define_insn "*movhi_1"
    [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m")
- 	(match_operand:HI 1 "general_operand" "rn,rm,rn"))
-    (clobber (reg:CC 17))]
-   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
-   "*
- {
-   switch (get_attr_type (insn))
-     {
-     case TYPE_ALU1:
-       /* Clear the whole register -- smaller, faster, better.  */
-       if (operands[1] != const0_rtx)
- 	abort();
-       return \"xor{l}\\t%k0, %k0\";
-     case TYPE_IMOVX:
-       return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
-     default:
-       if (get_attr_length_prefix (insn) == 0)
-         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
-       else
-         return \"mov{w}\\t{%1, %0|%0, %1}\";
-     }
- }"
-   [(set (attr "type")
-      (cond [(and (match_operand:HI 1 "const0_operand" "")
- 		 (and (match_operand:HI 0 "register_operand" "")
- 		      (eq (symbol_ref "TARGET_USE_MOV0") (const_int 0))))
- 	      (const_string "alu1")
- 	    (and (ne (symbol_ref "TARGET_MOVX")
- 		     (const_int 0))
- 		 (eq_attr "alternative" "1"))
- 	      (const_string "imovx")
- 	   ]
- 	   (const_string "imov")))
-     (set (attr "length_prefix")
-       (cond [(eq_attr "type" "imovx")
- 	       (const_string "0")
- 	     (and (eq_attr "alternative" "0")
- 		  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
- 		      (const_int 0)))
- 	       (const_string "0")
- 	    ]
- 	    (const_string "1")))
-     ; There's no place to override just the immediate length
-     (set (attr "length")
-       (cond [(and (eq_attr "type" "imov")
- 		  (and (eq_attr "length_prefix" "0")
- 		       (match_operand:HI 1 "immediate_operand" "")))
- 	       (const_string "5")
- 	    ]
- 	    (const_string "*")))])
- 
- (define_insn "*movhi_2"
-   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m")
  	(match_operand:HI 1 "general_operand" "rn,rm,rn"))]
    "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
    "*
--- 1226,1231 ----
***************
*** 1409,1461 ****
  
  (define_insn "*movqi_1"
    [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,*r,*r,m")
- 	(match_operand:QI 1 "general_operand" "qn,qm,*rn,qm,qn"))
-    (clobber (reg:CC 17))]
-   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
-   "*
- {
-   switch (get_attr_type (insn))
-     {
-     case TYPE_ALU1:
-       /* Clear the whole register -- smaller, faster, better.  */
-       if (operands[1] != const0_rtx)
- 	abort();
-       return \"xor{l}\\t%k0, %k0\";
-     case TYPE_IMOVX:
-       if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
- 	abort ();
-       return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
-     default:
-       if (which_alternative == 2)
-         return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
-       else
-         return \"mov{b}\\t{%1, %0|%0, %1}\";
-     }
- }"
-   [(set (attr "type")
-      (cond [(and (match_operand:QI 1 "const0_operand" "")
- 		 (and (match_operand:QI 0 "register_operand" "")
- 		      (eq (symbol_ref "TARGET_USE_MOV0") (const_int 0))))
- 	      (const_string "alu1")
- 	    (eq_attr "alternative" "3")
- 	      (const_string "imovx")
- 	    (and (ne (symbol_ref "TARGET_MOVX")
- 		     (const_int 0))
- 		 (eq_attr "alternative" "1"))
- 	      (const_string "imovx")
- 	   ]
- 	   (const_string "imov")))
-     ; There's no place to override just the immediate length
-     (set (attr "length")
-       (cond [(and (eq_attr "type" "imov")
- 		  (and (eq_attr "alternative" "2")
- 		       (match_operand:HI 1 "immediate_operand" "")))
- 	       (const_string "5")
- 	    ]
- 	    (const_string "*")))])
- 
- (define_insn "*movqi_2"
-   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,*r,*r,m")
  	(match_operand:QI 1 "general_operand" "qn,qm,*rn,qm,qn"))]
    "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
    "*
--- 1349,1354 ----
***************
*** 1649,1661 ****
    ""
    "#")
  
- (define_insn "*movdi_1"
-   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
- 	(match_operand:DI 1 "general_operand" "riFo,riF"))
-    (clobber (reg:CC 17))]
-   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
-   "#")
- 
  (define_insn "*movdi_2"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
  	(match_operand:DI 1 "general_operand" "riFo,riF"))]
--- 1542,1547 ----
***************
*** 1672,1688 ****
  ;; %%% This multiword shite has got to go.
  (define_split
    [(set (match_operand:DI 0 "nonimmediate_operand" "")
-         (match_operand:DI 1 "general_operand" ""))
-    (clobber (reg:CC 17))]
-   "reload_completed"
-   [(parallel [(set (match_dup 2) (match_dup 5))
- 	      (clobber (reg:CC 17))])
-    (parallel [(set (match_dup 3) (match_dup 6))
- 	      (clobber (reg:CC 17))])]
-   "if (ix86_split_long_move (operands)) DONE;")
-   
- (define_split
-   [(set (match_operand:DI 0 "nonimmediate_operand" "")
          (match_operand:DI 1 "general_operand" ""))]
    "reload_completed"
    [(set (match_dup 2) (match_dup 5))
--- 1558,1563 ----
***************
*** 2199,2206 ****
    "reload_completed
     && TARGET_ZERO_EXTEND_WITH_AND
     && !reg_overlap_mentioned_p (operands[0], operands[1])"
!   [(parallel [(set (match_dup 0) (const_int 0))
! 	      (clobber (reg:CC 17))])
     (set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 1))]
    "")
  
--- 2074,2080 ----
    "reload_completed
     && TARGET_ZERO_EXTEND_WITH_AND
     && !reg_overlap_mentioned_p (operands[0], operands[1])"
!   [(set (match_dup 0) (const_int 0))
     (set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 1))]
    "")
  
***************
*** 2252,2259 ****
     && QI_REG_P (operands[0])
     && TARGET_ZERO_EXTEND_WITH_AND
     && !reg_overlap_mentioned_p (operands[0], operands[1])"
!   [(parallel [(set (match_dup 0) (const_int 0))
! 	      (clobber (reg:CC 17))])
     (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))]
    "")
  
--- 2126,2132 ----
     && QI_REG_P (operands[0])
     && TARGET_ZERO_EXTEND_WITH_AND
     && !reg_overlap_mentioned_p (operands[0], operands[1])"
!   [(set (match_dup 0) (const_int 0))
     (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))]
    "")
  
***************
*** 2319,2326 ****
     && QI_REG_P (operands[0])
     && (GET_CODE (operands[1]) == MEM || QI_REG_P (operands[1]))
     && !reg_overlap_mentioned_p (operands[0], operands[1])"
!   [(parallel [(set (match_dup 0) (const_int 0))
! 	      (clobber (reg:CC 17))])
     (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))]
    "")
  
--- 2192,2198 ----
     && QI_REG_P (operands[0])
     && (GET_CODE (operands[1]) == MEM || QI_REG_P (operands[1]))
     && !reg_overlap_mentioned_p (operands[0], operands[1])"
!   [(set (match_dup 0) (const_int 0))
     (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))]
    "")
  
***************
*** 2349,2356 ****
  	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
     (clobber (reg:CC 17))]
    "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
!   [(parallel [(set (match_dup 4) (const_int 0))
! 	      (clobber (reg:CC 17))])]
    "split_di (&operands[0], 1, &operands[3], &operands[4]);")
  
  (define_split 
--- 2221,2227 ----
  	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
     (clobber (reg:CC 17))]
    "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
!   [(set (match_dup 4) (const_int 0))]
    "split_di (&operands[0], 1, &operands[3], &operands[4]);")
  
  (define_split 
***************
*** 2359,2366 ****
     (clobber (reg:CC 17))]
    "reload_completed"
    [(set (match_dup 3) (match_dup 1))
!    (parallel [(set (match_dup 4) (const_int 0))
! 	      (clobber (reg:CC 17))])]
    "split_di (&operands[0], 1, &operands[3], &operands[4]);")
  
  ;; Sign extension instructions
--- 2230,2236 ----
     (clobber (reg:CC 17))]
    "reload_completed"
    [(set (match_dup 3) (match_dup 1))
!    (set (match_dup 4) (const_int 0))]
    "split_di (&operands[0], 1, &operands[3], &operands[4]);")
  
  ;; Sign extension instructions
***************
*** 8585,8616 ****
     && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
    [(parallel [(set (match_dup 0) (const_int 0))
  	      (clobber (reg:CC 17))])]
!   "")
  
- ;; ??? Rewrite these to not introduce the false dependancy.  
- ;; Currently they'll trip update_life_info's sanity checks.
- 
  ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
- (define_peephole2
-   [(set (match_operand:SI 0 "register_operand" "")
- 	(const_int -1))]
-   "0 && (optimize_size || TARGET_PENTIUM)
-    && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
-   [(parallel [(set (match_dup 0)
- 		   (ior:SI (match_dup 0) (const_int -1)))
- 	      (clobber (reg:CC 17))])]
-   "")
- 
  (define_peephole2
!   [(set (match_operand:HI 0 "register_operand" "")
  	(const_int -1))]
!   "0 && (optimize_size || TARGET_PENTIUM)
     && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
!   [(parallel [(set (match_dup 0)
! 		   (ior:HI (match_dup 0) (const_int -1)))
  	      (clobber (reg:CC 17))])]
!   "")
! 
  
  ;; Call-value patterns last so that the wildcard operand does not
  ;; disrupt insn-recog's switch tables.
--- 8455,8473 ----
     && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
    [(parallel [(set (match_dup 0) (const_int 0))
  	      (clobber (reg:CC 17))])]
!   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
  
  ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
  (define_peephole2
!   [(set (match_operand 0 "register_operand" "")
  	(const_int -1))]
!   "(GET_MODE (operands[0]) == HImode
!     || GET_MODE (operands[0]) == SImode)
!    && (optimize_size || TARGET_PENTIUM)
     && reg_dead_p (insn, gen_rtx_REG (CCmode, FLAGS_REG))"
!   [(parallel [(set (match_dup 0) (const_int -1))
  	      (clobber (reg:CC 17))])]
!   "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
  
  ;; Call-value patterns last so that the wildcard operand does not
  ;; disrupt insn-recog's switch tables.


More information about the Gcc-patches mailing list