[ARC] Use TARGET_INSN_COST.
authorClaudiu Zissulescu <claziss@gmail.com>
Thu, 13 Feb 2020 10:32:05 +0000 (12:32 +0200)
committerClaudiu Zissulescu <claziss@gmail.com>
Thu, 13 Feb 2020 10:32:05 +0000 (12:32 +0200)
TARGET_INSN_COST gives us a better control over the instruction costs
than classical RTX_COSTS.  A simple cost scheme is in place for the
time being, when optimizing for size, the cost is given by the
instruction length. When optimizing for speed, the cost is 1 for any
recognized instruction, and 2 for any load/store instruction.  The
latter one can be overwritten by using cost attribute for an
instruction.  Due to this change, we need to update also a number of
instruction patterns with a new predicate to better reflect the costs.

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

* config/arc/arc.c (arc_insn_cost): New function.
(TARGET_INSN_COST): Define.
* config/arc/arc.md (cost): New attribute.
(add_n): Use arc_nonmemory_operand.
(ashlsi3_insn): Likewise, also update constraints.
(ashrsi3_insn): Likewise.
(rotrsi3): Likewise.
(add_shift): Likewise.
* config/arc/predicates.md (arc_nonmemory_operand): New predicate.

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

* gcc.target/arc/or-cnst-size2.c: Update test.

gcc/ChangeLog
gcc/config/arc/arc.c
gcc/config/arc/arc.md
gcc/config/arc/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/or-cnst-size2.c

index 6209e7615de9eca6a241d02da1730e46be02c19e..96a6b8037d56f613e7b086370c5b045e0d051bb3 100644 (file)
@@ -1,3 +1,15 @@
+2020-02-13  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.c (arc_insn_cost): New function.
+       (TARGET_INSN_COST): Define.
+       * config/arc/arc.md (cost): New attribute.
+       (add_n): Use arc_nonmemory_operand.
+       (ashlsi3_insn): Likewise, also update constraints.
+       (ashrsi3_insn): Likewise.
+       (rotrsi3): Likewise.
+       (add_shift): Likewise.
+       * config/arc/predicates.md (arc_nonmemory_operand): New predicate.
+
 2020-02-13  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc.md (mulsidi_600): Correctly select mlo/mhi
index bc342350440929d3f02a0180008f589f0b2ffb3e..7a9fe08f31dfcfd721fab9f4acba299465063537 100644 (file)
@@ -11757,6 +11757,55 @@ arc_can_use_return_insn (void)
          && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
 }
 
+/* Helper for INSN_COST.
+
+   Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
+   insn, a set, a set source, any random piece of one).  set_src_cost,
+   set_rtx_cost, etc. are helper functions that use that.
+
+   Those functions do not work for parallels.  Also, costs are not
+   additive like this simplified model assumes.  Also, more complex
+   backends tend to miss many cases in their rtx_costs function.
+
+   Many passes that want costs want to know the cost of a full insn.  Like
+   combine.  That's why I created insn_cost: it solves all of the above
+   problems.  */
+
+static int
+arc_insn_cost (rtx_insn *insn, bool speed)
+{
+  int cost;
+  if (recog_memoized (insn) < 0)
+    return 0;
+
+  /* If optimizing for size, we want the insn size.  */
+  if (!speed)
+    return get_attr_length (insn);
+
+  /* Use cost if provided.  */
+  cost = get_attr_cost (insn);
+  if (cost > 0)
+    return cost;
+
+  /* For speed make a simple cost model: memory access is more
+     expensive than any other instruction.  */
+  enum attr_type type = get_attr_type (insn);
+
+  switch (type)
+    {
+    case TYPE_LOAD:
+    case TYPE_STORE:
+      cost = COSTS_N_INSNS (2);
+      break;
+
+    default:
+      cost = COSTS_N_INSNS (1);
+      break;
+    }
+
+  return cost;
+}
+
 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
 
@@ -11778,6 +11827,9 @@ arc_can_use_return_insn (void)
 #undef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
 
+#undef  TARGET_INSN_COST
+#define TARGET_INSN_COST arc_insn_cost
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-arc.h"
index 4c269f565bac98599b1fcef09dc97543a8486a21..3a7bf7d6f5dc1ae3acea78bdca013ff00cc73730 100644 (file)
   ]
 )
 
+;; What is the insn_cost for this insn?  The target hook can still override
+;; this.  For optimizing for size the "length" attribute is used instead.
+(define_attr "cost" "" (const_int 0))
+
 (define_attr "is_sfunc" "no,yes" (const_string "no"))
 
 ;; Insn type.  Used to default other attribute values.
@@ -3127,9 +3131,9 @@ core_3, archs4x, archs4xd, archs4xd_slow"
   [(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")))]
+                (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
   ""
-  "add%z2%?\\t%0,%3,%1%&"
+  "add%z2%?\\t%0,%3,%1"
   [(set_attr "type" "shift")
    (set_attr "length" "*,4,8")
    (set_attr "predicable" "yes,no,no")
@@ -3560,26 +3564,26 @@ core_3, archs4x, archs4xd, archs4xd_slow"
 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
 ; 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,cCsz")
-                  (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
+  [(set (match_operand:SI 0 "dest_reg_operand"                 "=q,q, q, r, r,   r")
+       (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
+                  (match_operand:SI 2 "nonmemory_operand"      "K,K,qM,rL,rL,rCal")))]
   "TARGET_BARREL_SHIFTER
    && (register_operand (operands[1], SImode)
        || register_operand (operands[2], SImode))"
-  "asl%? %0,%1,%2%&"
+  "asl%?\\t%0,%1,%2"
   [(set_attr "type" "shift")
    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
    (set_attr "predicable" "no,no,no,yes,no,no")
    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
 
 (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,cCsz")
-                    (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
+  [(set (match_operand:SI 0 "dest_reg_operand"                   "=q,q, q, r, r,   r")
+       (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
+                    (match_operand:SI 2 "nonmemory_operand"      "K,K,qM,rL,rL,rCal")))]
   "TARGET_BARREL_SHIFTER
    && (register_operand (operands[1], SImode)
        || register_operand (operands[2], SImode))"
-  "asr%? %0,%1,%2%&"
+  "asr%?\\t%0,%1,%2"
   [(set_attr "type" "shift")
    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
    (set_attr "predicable" "no,no,no,yes,no,no")
@@ -3600,11 +3604,11 @@ core_3, archs4x, archs4xd, archs4xd_slow"
    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
 
 (define_insn "rotrsi3"
-  [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
-       (rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCsz")
-                    (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
+  [(set (match_operand:SI 0 "dest_reg_operand"                    "=r, r,   r")
+       (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand"  " 0,rL,rCsz")
+                    (match_operand:SI 2 "nonmemory_operand"      "rL,rL,rCal")))]
   "TARGET_BARREL_SHIFTER"
-  "ror%? %0,%1,%2"
+  "ror%?\\t%0,%1,%2"
   [(set_attr "type" "shift,shift,shift")
    (set_attr "predicable" "yes,no,no")
    (set_attr "length" "4,4,8")])
@@ -4336,16 +4340,15 @@ core_3, archs4x, archs4xd, archs4xd_slow"
        (ashift:SI (match_operand:SI 1 "register_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" "")))]
+       (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "")
+               (match_operand:SI 5 "arc_nonmemory_operand" "")))]
   "(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])))
-   && !(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
+       || (true_regnum (operands[3]) == true_regnum (operands[0])))"
+ ;; 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)
        (plus:SI (mult:SI (match_dup 1)
                          (match_dup 2))
@@ -6422,7 +6425,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,Csz")))]
+                (match_operand:SI 3 "arc_nonmemory_operand"  "0,r,Csz")))]
   ""
   "add%2%?\\t%0,%3,%1"
   [(set_attr "length" "*,4,8")
index 3c03436c901c21d676e27493e866deed78184ddf..2ad476d575570ddaf13ccd3a1d20b02da6b8eba3 100644 (file)
   {
    return arc_check_multi (op, false);
 })
+
+(define_predicate "arc_nonmemory_operand"
+  (ior (match_test "register_operand (op, mode)")
+       (and (match_code "const_int, symbol_ref")
+           (match_test "!optimize_size"))))
index b3e2e3cd1158347e5e30e235828994654c3a028e..572042662d6cac697833481bc03795cea58f8813 100644 (file)
@@ -1,3 +1,7 @@
+2020-02-13  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * gcc.target/arc/or-cnst-size2.c: Update test.
+
 2020-02-13  Claudiu Zissulescu  <claziss@synopsys.com>
        Petro Karashchenko  <petro.karashchenko@ring.com>
 
index 33af97bbdbf50d2db9e0143521ed89e837e9f6bf..8fa1e65c7f653bf7537db34c3b8ac3b303f4624a 100644 (file)
@@ -9,4 +9,4 @@ int foo (void)
 }
 
 /* { dg-final { scan-assembler "tst" } } */
-/* { dg-final { scan-assembler "bset.eq" } } */
+/* { dg-final { scan-assembler "bset" } } */