[i386] : Introduce Yp register constraint and merge *_lea add ans ashift patterns with base

Submitted by Uros Bizjak on Aug. 23, 2011, 7:59 p.m.

Details

Message ID CAFULd4ZXuqJhX8jM3wjeuMCK_Nza7wP4yxqRHWvZLX_fKkx-Lw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Aug. 23, 2011, 7:59 p.m.
Hello!

Attached patch introduces Yp register constraint, conditionalized on
TARGET_PARTIAL_REG_STALL.  Using this constraint, several *_lea
patterns can be merged with their base patterns, resulting in many
removed lines of code.

No functional changes otherwise.

2011-08-23  Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/constraints.md (Yp): New register constraint.
	* config/i386/i386.md (*addhi_1): Merge with *addhi_1_lea using
	Yp register constraint.
	(*addqi_1): Merge with *addqi_1_lea using Yp register constraint.
	(*ashlhi3_1): Merge with *ashlhi3_1_lea using Yp register constraint.
	(*ashlqi3_1): Merge with *ashlqi3_1_lea using Yp register constraint.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu
{,-m32}, committed to mainline SVN.

URos.

Comments

Richard Henderson Aug. 23, 2011, 8:04 p.m.
On 08/23/2011 12:59 PM, Uros Bizjak wrote:
> 	* config/i386/constraints.md (Yp): New register constraint.
> 	* config/i386/i386.md (*addhi_1): Merge with *addhi_1_lea using
> 	Yp register constraint.
> 	(*addqi_1): Merge with *addqi_1_lea using Yp register constraint.
> 	(*ashlhi3_1): Merge with *ashlhi3_1_lea using Yp register constraint.
> 	(*ashlqi3_1): Merge with *ashlqi3_1_lea using Yp register constraint.

You can still make use of attribute enabled...


r~
Uros Bizjak Aug. 23, 2011, 8:23 p.m.
On Tue, Aug 23, 2011 at 10:04 PM, Richard Henderson <rth@redhat.com> wrote:

>>       * config/i386/constraints.md (Yp): New register constraint.
>>       * config/i386/i386.md (*addhi_1): Merge with *addhi_1_lea using
>>       Yp register constraint.
>>       (*addqi_1): Merge with *addqi_1_lea using Yp register constraint.
>>       (*ashlhi3_1): Merge with *ashlhi3_1_lea using Yp register constraint.
>>       (*ashlqi3_1): Merge with *ashlqi3_1_lea using Yp register constraint.
>
> You can still make use of attribute enabled...

Yes, I am aware of this attribute, but OTOH, I propose that we use it
for ISA changes and don't mix everything together. I was thinking of
moving Y2, Y3 and Y4 out of register constraints to "enabled"
attribute, but they clashed with TARGET_AVX somehow.

So, at the end of the day, it was much easier to leave pre-AVX
register constraints as they were, while post-AVX and AVX-independent
ISAs should be handled via "enabled" attribute.

Uros.
Jakub Jelinek Aug. 23, 2011, 8:33 p.m.
On Tue, Aug 23, 2011 at 10:23:54PM +0200, Uros Bizjak wrote:
> On Tue, Aug 23, 2011 at 10:04 PM, Richard Henderson <rth@redhat.com> wrote:
> 
> >>       * config/i386/constraints.md (Yp): New register constraint.
> >>       * config/i386/i386.md (*addhi_1): Merge with *addhi_1_lea using
> >>       Yp register constraint.
> >>       (*addqi_1): Merge with *addqi_1_lea using Yp register constraint.
> >>       (*ashlhi3_1): Merge with *ashlhi3_1_lea using Yp register constraint.
> >>       (*ashlqi3_1): Merge with *ashlqi3_1_lea using Yp register constraint.
> >
> > You can still make use of attribute enabled...
> 
> Yes, I am aware of this attribute, but OTOH, I propose that we use it
> for ISA changes and don't mix everything together. I was thinking of
> moving Y2, Y3 and Y4 out of register constraints to "enabled"
> attribute, but they clashed with TARGET_AVX somehow.

The advantage of enabled attribute over the new special constraints is IMHO that
the constraints are exposed to users, they can use them in inline assembly.
You could mix two or three attributes to compute enabled etc. if needed.

	Jakub
Richard Henderson Aug. 23, 2011, 8:58 p.m.
On 08/23/2011 01:23 PM, Uros Bizjak wrote:
> Yes, I am aware of this attribute, but OTOH, I propose that we use it
> for ISA changes and don't mix everything together.

I think that's more confusing than not.  We can use other
sub-attributes than ISA if that makes it easier for you,
but I do think that these artificial ISA restrictions do
have the quality of a real restricted ISA like coldfire.


r~
Bernd Schmidt Aug. 23, 2011, 9:56 p.m.
On 08/23/11 22:23, Uros Bizjak wrote:
> On Tue, Aug 23, 2011 at 10:04 PM, Richard Henderson <rth@redhat.com> wrote:
> 
>>>       * config/i386/constraints.md (Yp): New register constraint.
>>>       * config/i386/i386.md (*addhi_1): Merge with *addhi_1_lea using
>>>       Yp register constraint.
>>>       (*addqi_1): Merge with *addqi_1_lea using Yp register constraint.
>>>       (*ashlhi3_1): Merge with *ashlhi3_1_lea using Yp register constraint.
>>>       (*ashlqi3_1): Merge with *ashlqi3_1_lea using Yp register constraint.
>>
>> You can still make use of attribute enabled...
> 
> Yes, I am aware of this attribute, but OTOH, I propose that we use it
> for ISA changes and don't mix everything together.

You could have sub-attributes, "isa_enabled" and "tuning_enabled", which
are then anded together.


Bernd

Patch hide | download patch | download mbox

Index: i386.md
===================================================================
--- i386.md	(revision 178001)
+++ i386.md	(working copy)
@@ -5650,52 +5650,14 @@ 
    (set_attr "mode" "SI")])
 
 (define_insn "*addhi_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
-	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
-		 (match_operand:HI 2 "general_operand" "rn,rm")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
+	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
+		 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (PLUS, HImode, operands)"
+  "ix86_binary_operator_ok (PLUS, HImode, operands)"
 {
   switch (get_attr_type (insn))
     {
-    case TYPE_INCDEC:
-      if (operands[2] == const1_rtx)
-	return "inc{w}\t%0";
-      else
-        {
-	  gcc_assert (operands[2] == constm1_rtx);
-	  return "dec{w}\t%0";
-	}
-
-    default:
-      if (x86_maybe_negate_const_int (&operands[2], HImode))
-	return "sub{w}\t{%2, %0|%0, %2}";
-
-      return "add{w}\t{%2, %0|%0, %2}";
-    }
-}
-  [(set (attr "type")
-     (if_then_else (match_operand:HI 2 "incdec_operand" "")
-	(const_string "incdec")
-	(const_string "alu")))
-   (set (attr "length_immediate")
-      (if_then_else
-	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
-	(const_string "1")
-	(const_string "*")))
-   (set_attr "mode" "HI")])
-
-(define_insn "*addhi_1_lea"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
-	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
-		 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (PLUS, HImode, operands)"
-{
-  switch (get_attr_type (insn))
-    {
     case TYPE_LEA:
       return "#";
 
@@ -5739,63 +5701,16 @@ 
 	(const_string "*")))
    (set_attr "mode" "HI,HI,HI,SI")])
 
-;; %%% Potential partial reg stall on alternative 2.  What to do?
+;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
 (define_insn "*addqi_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
-	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
-		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
+	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
+		 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (PLUS, QImode, operands)"
+  "ix86_binary_operator_ok (PLUS, QImode, operands)"
 {
-  int widen = (which_alternative == 2);
-  switch (get_attr_type (insn))
-    {
-    case TYPE_INCDEC:
-      if (operands[2] == const1_rtx)
-	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
-      else
-	{
-	  gcc_assert (operands[2] == constm1_rtx);
-	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
-	}
+  bool widen = (which_alternative == 3 || which_alternative == 4);
 
-    default:
-      if (x86_maybe_negate_const_int (&operands[2], QImode))
-	{
-	  if (widen)
-	    return "sub{l}\t{%2, %k0|%k0, %2}";
-	  else
-	    return "sub{b}\t{%2, %0|%0, %2}";
-	}
-      if (widen)
-        return "add{l}\t{%k2, %k0|%k0, %k2}";
-      else
-        return "add{b}\t{%2, %0|%0, %2}";
-    }
-}
-  [(set (attr "type")
-     (if_then_else (match_operand:QI 2 "incdec_operand" "")
-	(const_string "incdec")
-	(const_string "alu")))
-   (set (attr "length_immediate")
-      (if_then_else
-	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
-	(const_string "1")
-	(const_string "*")))
-   (set_attr "mode" "QI,QI,SI")])
-
-;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
-(define_insn "*addqi_1_lea"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
-	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
-		 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
-   (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (PLUS, QImode, operands)"
-{
-  int widen = (which_alternative == 3 || which_alternative == 4);
-
   switch (get_attr_type (insn))
     {
     case TYPE_LEA:
@@ -9294,53 +9209,11 @@ 
   "operands[2] = gen_lowpart (SImode, operands[2]);")
 
 (define_insn "*ashlhi3_1"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
-	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
-		   (match_operand:QI 2 "nonmemory_operand" "cI")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
-{
-  switch (get_attr_type (insn))
-    {
-    case TYPE_ALU:
-      gcc_assert (operands[2] == const1_rtx);
-      return "add{w}\t%0, %0";
-
-    default:
-      if (operands[2] == const1_rtx
-	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
-	return "sal{w}\t%0";
-      else
-	return "sal{w}\t{%2, %0|%0, %2}";
-    }
-}
-  [(set (attr "type")
-     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
-		          (const_int 0))
-		      (match_operand 0 "register_operand" ""))
-		 (match_operand 2 "const1_operand" ""))
-	      (const_string "alu")
-	   ]
-	   (const_string "ishift")))
-   (set (attr "length_immediate")
-     (if_then_else
-       (ior (eq_attr "type" "alu")
-	    (and (eq_attr "type" "ishift")
-		 (and (match_operand 2 "const1_operand" "")
-		      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
-			  (const_int 0)))))
-       (const_string "0")
-       (const_string "*")))
-   (set_attr "mode" "HI")])
-
-(define_insn "*ashlhi3_1_lea"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
 	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
 		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
+  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
 {
   switch (get_attr_type (insn))
     {
@@ -9380,68 +9253,13 @@ 
        (const_string "*")))
    (set_attr "mode" "HI,SI")])
 
+;; %%% Potential partial reg stall on alternative 1.  What to do?
 (define_insn "*ashlqi3_1"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
-	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
-		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
-   (clobber (reg:CC FLAGS_REG))]
-  "TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
-{
-  switch (get_attr_type (insn))
-    {
-    case TYPE_ALU:
-      gcc_assert (operands[2] == const1_rtx);
-      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
-        return "add{l}\t%k0, %k0";
-      else
-        return "add{b}\t%0, %0";
-
-    default:
-      if (operands[2] == const1_rtx
-	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
-	{
-	  if (get_attr_mode (insn) == MODE_SI)
-	    return "sal{l}\t%k0";
-	  else
-	    return "sal{b}\t%0";
-	}
-      else
-	{
-	  if (get_attr_mode (insn) == MODE_SI)
-	    return "sal{l}\t{%2, %k0|%k0, %2}";
-	  else
-	    return "sal{b}\t{%2, %0|%0, %2}";
-	}
-    }
-}
-  [(set (attr "type")
-     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
-		          (const_int 0))
-		      (match_operand 0 "register_operand" ""))
-		 (match_operand 2 "const1_operand" ""))
-	      (const_string "alu")
-	   ]
-	   (const_string "ishift")))
-   (set (attr "length_immediate")
-     (if_then_else
-       (ior (eq_attr "type" "alu")
-	    (and (eq_attr "type" "ishift")
-		 (and (match_operand 2 "const1_operand" "")
-		      (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
-			  (const_int 0)))))
-       (const_string "0")
-       (const_string "*")))
-   (set_attr "mode" "QI,SI")])
-
-;; %%% Potential partial reg stall on alternative 2.  What to do?
-(define_insn "*ashlqi3_1_lea"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
 	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
 		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
    (clobber (reg:CC FLAGS_REG))]
-  "!TARGET_PARTIAL_REG_STALL
-   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
+  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
 {
   switch (get_attr_type (insn))
     {
Index: constraints.md
===================================================================
--- constraints.md	(revision 178001)
+++ constraints.md	(working copy)
@@ -88,8 +88,11 @@ 
 ;; We use the Y prefix to denote any number of conditional register sets:
 ;;  z	First SSE register.
 ;;  2	SSE2 enabled
+;;  3	SSE3 enabled
+;;  4	SSE4_1 enabled
 ;;  i	SSE2 inter-unit moves enabled
 ;;  m	MMX inter-unit moves enabled
+;;  p	Integer register when TARGET_PARTIAL_REG_STALL is disabled
 ;;  d	Integer register when integer DFmode moves are enabled
 ;;  x	Integer register when integer XFmode moves are enabled
 
@@ -113,6 +116,10 @@ 
  "TARGET_MMX && TARGET_INTER_UNIT_MOVES ? MMX_REGS : NO_REGS"
  "@internal Any MMX register, when inter-unit moves are enabled.")
 
+(define_register_constraint "Yp"
+ "TARGET_PARTIAL_REG_STALL ? NO_REGS : GENERAL_REGS"
+ "@internal Any integer register when TARGET_PARTIAL_REG_STALL is disabled.")
+
 (define_register_constraint "Yd"
  "(TARGET_64BIT
    || (TARGET_INTEGER_DFMODE_MOVES && optimize_function_for_speed_p (cfun)))