This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] [ARC] Avoid specific constants to end in limm field.


The 3-operand instructions accepts to place an immediate into the
second operand. However, this immediate will end up in the long
immediate field. This patch avoids constants to end up in the limm
field for particular instructions when compiling for size.

gcc/
xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.md (*add_n): Clean up pattern, update instruction
	constraints.
	(ashlsi3_insn): Update instruction constraints.
	(ashrsi3_insn): Likewise.
	(rotrsi3): Likewise.
	(add_shift): Likewise.
	* config/arc/constraints.md (Csz): New 32 bit constraint. It
	avoids placing in the limm field small constants which, otherwise,
	could end into a small instruction.
---
 gcc/config/arc/arc.md                   | 51 +++++++++---------------
 gcc/config/arc/constraints.md           |  6 +++
 gcc/testsuite/gcc.target/arc/tph_addx.c | 53 +++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/tph_addx.c

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 2d108ef166d..c28a87cd3b0 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -3056,30 +3056,17 @@ core_3, archs4x, archs4xd, archs4xd_slow"
    (set (match_dup 3) (match_dup 4))])
 
 (define_insn "*add_n"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
-	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
-	                    (match_operand:SI 2 "_1_2_3_operand" ""))
-		 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
+	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
+			  (match_operand:SI 2 "_2_4_8_operand" ""))
+		 (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))]
   ""
-  "add%c2%? %0,%3,%1%&"
+  "add%z2%?\\t%0,%3,%1%&"
   [(set_attr "type" "shift")
-   (set_attr "length" "*,4,4,8,4,8")
-   (set_attr "predicable" "yes,yes,no,no,no,no")
-   (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
-   (set_attr "iscompact" "maybe,false,false,false,false,false")])
-
-(define_insn "*add_n"
-  [(set (match_operand:SI 0 "dest_reg_operand"                  "=Rcqq,Rcw,W,  W,w,w")
-	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,  c,c,  c,c,c")
-			  (match_operand:SI 2 "_2_4_8_operand"   ""))
-		 (match_operand:SI 3 "nonmemory_operand"            "0,  0,c,Cal,c,Cal")))]
-  ""
-  "add%z2%? %0,%3,%1%&"
-  [(set_attr "type" "shift")
-   (set_attr "length" "*,4,4,8,4,8")
-   (set_attr "predicable" "yes,yes,no,no,no,no")
-   (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
-   (set_attr "iscompact" "maybe,false,false,false,false,false")])
+   (set_attr "length" "*,4,8")
+   (set_attr "predicable" "yes,no,no")
+   (set_attr "cond" "canuse,nocond,nocond")
+   (set_attr "iscompact" "maybe,false,false")])
 
 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
 ;; what synth_mult likes.
@@ -3496,7 +3483,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 ; provide one alternatice for this, without condexec support.
 (define_insn "*ashlsi3_insn"
   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
-	(ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
+	(ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCsz")
 		   (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
   "TARGET_BARREL_SHIFTER
    && (register_operand (operands[1], SImode)
@@ -3509,7 +3496,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 
 (define_insn "*ashrsi3_insn"
   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
-	(ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
+	(ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCsz")
 		     (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
   "TARGET_BARREL_SHIFTER
    && (register_operand (operands[1], SImode)
@@ -3536,7 +3523,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 
 (define_insn "rotrsi3"
   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
-	(rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCal")
+	(rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCsz")
 		     (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
   "TARGET_BARREL_SHIFTER"
   "ror%? %0,%1,%2"
@@ -4284,16 +4271,16 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 (define_peephole2
   [(set (match_operand:SI 0 "dest_reg_operand" "")
 	(ashift:SI (match_operand:SI 1 "register_operand" "")
-		   (match_operand:SI 2 "const_int_operand" "")))
+		   (match_operand:SI 2 "_1_2_3_operand" "")))
   (set (match_operand:SI 3 "dest_reg_operand" "")
        (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
 		(match_operand:SI 5 "nonmemory_operand" "")))]
-  "(INTVAL (operands[2]) == 1
-    || INTVAL (operands[2]) == 2
-    || INTVAL (operands[2]) == 3)
-   && (true_regnum (operands[4]) == true_regnum (operands[0])
+  "(true_regnum (operands[4]) == true_regnum (operands[0])
        || true_regnum (operands[5]) == true_regnum (operands[0]))
-   && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
+   && (peep2_reg_dead_p (2, operands[0])
+       || (true_regnum (operands[3]) == true_regnum (operands[0])))
+   && !(optimize_size && satisfies_constraint_I (operands[4]))
+   && !(optimize_size && satisfies_constraint_I (operands[5]))"
  ;; the preparation statements take care to put proper operand in operands[4]
  ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
   [(set (match_dup 3)
@@ -6329,7 +6316,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
   [(set (match_operand:SI 0 "register_operand" "=q,r,r")
 	(plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
 			    (match_operand:SI 2 "_1_2_3_operand" ""))
-		 (match_operand:SI 3 "nonmemory_operand"  "0,r,Cal")))]
+		 (match_operand:SI 3 "nonmemory_operand"  "0,r,Csz")))]
   ""
   "add%2%?\\t%0,%3,%1"
   [(set_attr "length" "*,4,8")
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index f9ef3f94dfe..abfeedffe9a 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -428,6 +428,12 @@
 	       && !arc_legitimate_pic_addr_p (op)
 	       && !satisfies_constraint_I (op)"))
 
+(define_constraint "Csz"
+  "a 32 bit constant avoided when compiling for size."
+  (match_test "immediate_operand (op, VOIDmode)
+	       && !arc_legitimate_pic_addr_p (op)
+	       && !(satisfies_constraint_I (op) && optimize_size)"))
+
 ; Note that the 'cryptic' register constraints will not make reload use the
 ; associated class to reload into, but this will not penalize reloading of any
 ; other operands, or using an alternate part of the same alternative.
diff --git a/gcc/testsuite/gcc.target/arc/tph_addx.c b/gcc/testsuite/gcc.target/arc/tph_addx.c
new file mode 100644
index 00000000000..f942ab19eb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/tph_addx.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+/* when compiling for size avoid the following peephole
+-------------------------------------------------------------
+Pattern 1 : r0 = r1 << {i}
+            r3 = r4/INT + r0     ;;and commutative
+                ||
+                \/
+            add{i} r3,r4/INT,r1
+-------------------------------------------------------------
+*/
+
+typedef int a;
+typedef int b                                                    ;
+struct c
+{
+  b d;
+};
+
+struct e
+{
+  a f;
+};
+
+int g(int family)
+{
+  switch (family)
+  case 2:
+    return sizeof(struct e);
+  return 0;
+}
+
+int h(int family)
+{
+  return 1 + g(family) - 1 ;
+}
+
+extern void m (void);
+
+int i(int j)
+{
+  struct c *hdr;
+  int k;
+  int l;
+  k = h(j);
+  l = sizeof(struct c) +   k * 2;
+  hdr->d = l ;
+  if (j)
+    m();
+}
+
+/* { dg-final { scan-assembler-not "add\d" } } */
-- 
2.17.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]