]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
MSP430: Implement TARGET_INSN_COST
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Fri, 13 Nov 2020 15:35:52 +0000 (15:35 +0000)
committerJozef Lawrynowicz <jozef.l@mittosystems.com>
Fri, 13 Nov 2020 15:36:30 +0000 (15:36 +0000)
The length of an insn can be used to calculate its cost, when optimizing
for size. When optimizing for speed, this is a good estimate, since the
cycle cost of an MSP430 instruction increases with its length.

gcc/ChangeLog:

* config/msp430/msp430.c (TARGET_INSN_COST): Define.
(msp430_insn_cost): New function.
* config/msp430/msp430.h (BRANCH_COST): Define.
(LOGICAL_OP_NON_SHORT_CIRCUIT): Define.

gcc/testsuite/ChangeLog:

* gcc.target/msp430/rtx-cost-O3-default.c: New test.
* gcc.target/msp430/rtx-cost-O3-f5series.c: New test.
* gcc.target/msp430/rtx-cost-Os-default.c: New test.
* gcc.target/msp430/rtx-cost-Os-f5series.c: New test.

gcc/config/msp430/msp430.c
gcc/config/msp430/msp430.h
gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c [new file with mode: 0644]
gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c [new file with mode: 0644]
gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c [new file with mode: 0644]
gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c [new file with mode: 0644]

index cc3472e853dc7509c1beb31bd22ec2413155db3a..e98de8d5dd04a49ceef5886c59bb5d52c28a9c8f 100644 (file)
@@ -1181,11 +1181,6 @@ msp430_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
   return 2 * cost;
 }
 
-/* BRANCH_COST
-   Changing from the default of 1 doesn't affect code generation, presumably
-   because there are no conditional move insns - when a condition is involved,
-   the only option is to use a cbranch.  */
-
 /* For X, which must be a MEM RTX, return TRUE if it is an indirect memory
    reference, @Rn or @Rn+.  */
 static bool
@@ -1650,6 +1645,26 @@ msp430_rtx_costs (rtx x,
       return false;
     }
 }
+
+#undef TARGET_INSN_COST
+#define TARGET_INSN_COST msp430_insn_cost
+
+static int
+msp430_insn_cost (rtx_insn *insn, bool speed ATTRIBUTE_UNUSED)
+{
+  if (recog_memoized (insn) < 0)
+    return 0;
+
+  /* The returned cost must be relative to COSTS_N_INSNS (1). An insn with a
+     length of 2 bytes is the smallest possible size and so must be equivalent
+     to COSTS_N_INSNS (1).  */
+  return COSTS_N_INSNS (get_attr_length (insn) / 2);
+
+  /* FIXME Add more detailed costs when optimizing for speed.
+     For now the length of the instruction is a good approximiation and roughly
+     correlates with cycle cost.  */
+}
+
 \f
 /* Function Entry and Exit */
 
index c2fcaef6c5045810bd0beacc7f1e98217103a817..049151ee975a338a9f8f3df1232638d12a5747d3 100644 (file)
@@ -243,6 +243,14 @@ extern const char *msp430_get_linker_devices_include_path (int, const char **);
 #define HAS_LONG_COND_BRANCH           0
 #define HAS_LONG_UNCOND_BRANCH         0
 
+/* The cost of a branch sequence is roughly 3 "cheap" instructions.  */
+#define BRANCH_COST(speed_p, predictable_p) 3
+
+/* Override the default BRANCH_COST heuristic to indicate that it is preferable
+   to retain short-circuit operations, this results in significantly better
+   codesize and performance.  */
+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
+
 #define LOAD_EXTEND_OP(M)              ZERO_EXTEND
 #define WORD_REGISTER_OPERATIONS       1
 
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c
new file mode 100644 (file)
index 0000000..1bd6a14
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+   (msp430x) and hwmult (none), when compiling at -O3.  */
+
+char arr[2];
+char a;
+char *ptr;
+
+/*
+** foo:
+** ...
+**     MOV.B   \&a, \&arr\+1
+**     MOV.*   #arr\+2, \&ptr
+** ...
+*/
+
+void
+foo (void)
+{
+  arr[1] = a;
+  ptr = arr + 2;
+}
+
+extern void ext (void);
+
+/*
+** bar:
+** ...
+**     CALL.*  #ext
+**     CALL.*  #ext
+** ...
+*/
+
+void
+bar (void)
+{
+  ext ();
+  ext ();
+}
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c
new file mode 100644 (file)
index 0000000..1e48625
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mhwmult=f5series" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+   (msp430x) and f5series hwmult, when compiling at -O3.  */
+
+volatile unsigned long a;
+volatile unsigned int b;
+volatile unsigned long c;
+unsigned long res1;
+unsigned long res2;
+unsigned long res3;
+
+/*
+** foo:
+** ...
+**     MOV.B   #16, R14
+**     CALL.*  #__mspabi_slll
+** ...
+**     MOV.*   \&res2.*
+** ...
+**     RLA.*RLC.*
+** ...
+**     MOV.*   \&res3.*
+** ...
+**     RLA.*RLC.*
+** ...
+*/
+void foo (void)
+{
+  /* Use the shift library function for this.  */
+  res1 = (a << 16) | b;
+  /* Emit 7 inline shifts for this.  */
+  res2 *= 128;
+  /* Perform this multiplication inline, using addition and shifts.  */
+  res3 *= 100;
+}
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c
new file mode 100644 (file)
index 0000000..8f3d1b2
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+   (msp430x) and hwmult (none), when compiling at -Os.  */
+
+char arr[2];
+char a;
+char *ptr;
+
+/*
+** foo:
+** ...
+**     MOV.B   \&a, \&arr\+1
+**     MOV.*   #arr\+2, \&ptr
+** ...
+*/
+
+void
+foo (void)
+{
+  arr[1] = a;
+  ptr = arr + 2;
+}
+
+extern void ext (void);
+
+/*
+** bar:
+** ...
+**     MOV.*   #ext, R10
+**     CALL.*  R10
+**     CALL.*  R10
+** ...
+*/
+
+void
+bar (void)
+{
+  ext ();
+  ext ();
+}
diff --git a/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c
new file mode 100644 (file)
index 0000000..bb37f90
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -mhwmult=f5series" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Verify the MSP430 cost model is working as expected for the default ISA
+   (msp430x) and f5series hwmult, when compiling at -Os.  */
+
+volatile unsigned long a;
+volatile unsigned int b;
+volatile unsigned long c;
+unsigned long res1;
+unsigned long res2;
+unsigned long res3;
+
+/*
+** foo:
+** ...
+**     MOV.B   #16, R14
+**     CALL.*  #__mspabi_slll
+** ...
+**     MOV.B   #7, R14
+**     CALL.*  #__mspabi_slll
+** ...
+**     MOV.B   #100, R14
+**     MOV.B   #0, R15
+** ...
+**     CALL.*  #__mulsi2_f5
+** ...
+*/
+void foo (void)
+{
+  /* Use the shift library function for this.  */
+  res1 = (a << 16) | b;
+  /* Likewise.  */
+  res2 *= 128;
+  /* Use the hardware multiply library function for this.  */
+  res3 *= 100;
+}