public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Cleanup expand_shift
@ 2011-05-03 14:42 Richard Guenther
  2011-05-04 15:34 ` Eric Botcazou
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Guenther @ 2011-05-03 14:42 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou


This is the promised followup to the expand_shift reorg.  The following
patch makes the worker take an RTL expanded shift amount and avoids
re-creating adjusted trees if it recurses for expanding rotates.  Most
of the scary code (involving the conversions) originated from the
fix for PR27861 - but I'm not sure if that bug was actually a side-effect
of using make_tree here.  I'm also not sure how much testing coverage
we have for this particular piece of code.

Anway, I'll bootstrap and test this on x86_64-unknown-linux-gnu
and I have verified PR27861 doesn't re-occur with a cross to
mipsel-linux-gnu.

Ok for trunk if it succeeds?

Thanks,
Richard.

2011-05-03  Richard Guenther  <rguenther@suse.de>

	* expmed.c (expand_variable_shift): Rename to ...
	(expand_shift_1): ... this.  Take an expanded shift amount.
	For rotates recurse directly not building trees for the shift amount.
	(expand_variable_shift): Wrap around expand_shift_1.
	(expand_shift): Adjust.

Index: gcc/expmed.c
===================================================================
*** gcc/expmed.c	(revision 173299)
--- gcc/expmed.c	(working copy)
*************** expand_dec (rtx target, rtx dec)
*** 2034,2047 ****
  \f
  /* Output a shift instruction for expression code CODE,
     with SHIFTED being the rtx for the value to shift,
!    and AMOUNT the tree for the amount to shift by.
     Store the result in the rtx TARGET, if that is convenient.
     If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
     Return the rtx for where the value is.  */
  
! rtx
! expand_variable_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
! 		       tree amount, rtx target, int unsignedp)
  {
    rtx op1, temp = 0;
    int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
--- 2034,2047 ----
  \f
  /* Output a shift instruction for expression code CODE,
     with SHIFTED being the rtx for the value to shift,
!    and AMOUNT the rtx for the amount to shift by.
     Store the result in the rtx TARGET, if that is convenient.
     If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
     Return the rtx for where the value is.  */
  
! static rtx
! expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
! 		rtx amount, rtx target, int unsignedp)
  {
    rtx op1, temp = 0;
    int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
*************** expand_variable_shift (enum tree_code co
*** 2055,2061 ****
    int attempt;
    bool speed = optimize_insn_for_speed_p ();
  
!   op1 = expand_normal (amount);
    op1_mode = GET_MODE (op1);
  
    /* Determine whether the shift/rotate amount is a vector, or scalar.  If the
--- 2055,2061 ----
    int attempt;
    bool speed = optimize_insn_for_speed_p ();
  
!   op1 = amount;
    op1_mode = GET_MODE (op1);
  
    /* Determine whether the shift/rotate amount is a vector, or scalar.  If the
*************** expand_variable_shift (enum tree_code co
*** 2140,2164 ****
  		 code below.  */
  
  	      rtx subtarget = target == shifted ? 0 : target;
! 	      tree new_amount, other_amount;
  	      rtx temp1;
! 	      tree type = TREE_TYPE (amount);
! 	      if (GET_MODE (op1) != TYPE_MODE (type)
! 		  && GET_MODE (op1) != VOIDmode)
! 		op1 = convert_to_mode (TYPE_MODE (type), op1, 1);
! 	      new_amount = make_tree (type, op1);
  	      other_amount
! 		= fold_build2 (MINUS_EXPR, type,
! 			       build_int_cst (type, GET_MODE_BITSIZE (mode)),
! 			       new_amount);
  
  	      shifted = force_reg (mode, shifted);
  
! 	      temp = expand_variable_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
! 					    mode, shifted, new_amount, 0, 1);
! 	      temp1 = expand_variable_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
! 					     mode, shifted, other_amount,
! 					     subtarget, 1);
  	      return expand_binop (mode, ior_optab, temp, temp1, target,
  				   unsignedp, methods);
  	    }
--- 2140,2161 ----
  		 code below.  */
  
  	      rtx subtarget = target == shifted ? 0 : target;
! 	      rtx new_amount, other_amount;
  	      rtx temp1;
! 
! 	      new_amount = amount;
  	      other_amount
! 		= simplify_gen_binary (MINUS, GET_MODE (amount),
! 				       GEN_INT (GET_MODE_BITSIZE (mode)),
! 				       amount);
  
  	      shifted = force_reg (mode, shifted);
  
! 	      temp = expand_shift_1 (left ? LSHIFT_EXPR : RSHIFT_EXPR,
! 				     mode, shifted, new_amount, 0, 1);
! 	      temp1 = expand_shift_1 (left ? RSHIFT_EXPR : LSHIFT_EXPR,
! 				      mode, shifted, other_amount,
! 				      subtarget, 1);
  	      return expand_binop (mode, ior_optab, temp, temp1, target,
  				   unsignedp, methods);
  	    }
*************** rtx
*** 2213,2224 ****
  expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
  	      int amount, rtx target, int unsignedp)
  {
!   /* ???  With re-writing expand_shift we could avoid going through a
!      tree for the shift amount and directly do GEN_INT (amount).  */
!   return expand_variable_shift (code, mode, shifted,
! 				build_int_cst (integer_type_node, amount),
! 				target, unsignedp);
  }
  \f
  /* Indicates the type of fixup needed after a constant multiplication.
     BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that
--- 2210,2234 ----
  expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
  	      int amount, rtx target, int unsignedp)
  {
!   return expand_shift_1 (code, mode,
! 			 shifted, GEN_INT (amount), target, unsignedp);
  }
+ 
+ /* Output a shift instruction for expression code CODE,
+    with SHIFTED being the rtx for the value to shift,
+    and AMOUNT the tree for the amount to shift by.
+    Store the result in the rtx TARGET, if that is convenient.
+    If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
+    Return the rtx for where the value is.  */
+ 
+ rtx
+ expand_variable_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
+ 		       tree amount, rtx target, int unsignedp)
+ {
+   return expand_shift_1 (code, mode,
+ 			 shifted, expand_normal (amount), target, unsignedp);
+ }
+ 
  \f
  /* Indicates the type of fixup needed after a constant multiplication.
     BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-05-06 21:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-03 14:42 [PATCH] Cleanup expand_shift Richard Guenther
2011-05-04 15:34 ` Eric Botcazou
2011-05-04 15:43   ` Richard Guenther
2011-05-04 16:09     ` Eric Botcazou
2011-05-04 16:10       ` Richard Guenther
2011-05-05 12:38         ` Richard Guenther
2011-05-06  4:50           ` Hans-Peter Nilsson
2011-05-06  9:39             ` Richard Guenther
2011-05-06 21:52               ` Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).