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

login
register
mail settings
Submitter Uros Bizjak
Date Aug. 23, 2011, 7:59 p.m.
Message ID <CAFULd4ZXuqJhX8jM3wjeuMCK_Nza7wP4yxqRHWvZLX_fKkx-Lw@mail.gmail.com>
Download mbox | patch
Permalink /patch/111174/
State New
Headers show

Comments

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.
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

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)))