Skip to content

Commit 54896b1

Browse files
committed
MSP430: Implement TARGET_INSN_COST
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.
1 parent 546c8f9 commit 54896b1

File tree

6 files changed

+189
-5
lines changed

6 files changed

+189
-5
lines changed

gcc/config/msp430/msp430.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,11 +1181,6 @@ msp430_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
11811181
return 2 * cost;
11821182
}
11831183

1184-
/* BRANCH_COST
1185-
Changing from the default of 1 doesn't affect code generation, presumably
1186-
because there are no conditional move insns - when a condition is involved,
1187-
the only option is to use a cbranch. */
1188-
11891184
/* For X, which must be a MEM RTX, return TRUE if it is an indirect memory
11901185
reference, @Rn or @Rn+. */
11911186
static bool
@@ -1650,6 +1645,26 @@ msp430_rtx_costs (rtx x,
16501645
return false;
16511646
}
16521647
}
1648+
1649+
#undef TARGET_INSN_COST
1650+
#define TARGET_INSN_COST msp430_insn_cost
1651+
1652+
static int
1653+
msp430_insn_cost (rtx_insn *insn, bool speed ATTRIBUTE_UNUSED)
1654+
{
1655+
if (recog_memoized (insn) < 0)
1656+
return 0;
1657+
1658+
/* The returned cost must be relative to COSTS_N_INSNS (1). An insn with a
1659+
length of 2 bytes is the smallest possible size and so must be equivalent
1660+
to COSTS_N_INSNS (1). */
1661+
return COSTS_N_INSNS (get_attr_length (insn) / 2);
1662+
1663+
/* FIXME Add more detailed costs when optimizing for speed.
1664+
For now the length of the instruction is a good approximiation and roughly
1665+
correlates with cycle cost. */
1666+
}
1667+
16531668

16541669
/* Function Entry and Exit */
16551670

gcc/config/msp430/msp430.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@ extern const char *msp430_get_linker_devices_include_path (int, const char **);
243243
#define HAS_LONG_COND_BRANCH 0
244244
#define HAS_LONG_UNCOND_BRANCH 0
245245

246+
/* The cost of a branch sequence is roughly 3 "cheap" instructions. */
247+
#define BRANCH_COST(speed_p, predictable_p) 3
248+
249+
/* Override the default BRANCH_COST heuristic to indicate that it is preferable
250+
to retain short-circuit operations, this results in significantly better
251+
codesize and performance. */
252+
#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
253+
246254
#define LOAD_EXTEND_OP(M) ZERO_EXTEND
247255
#define WORD_REGISTER_OPERATIONS 1
248256

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O3" } */
3+
/* { dg-final { check-function-bodies "**" "" } } */
4+
5+
/* Verify the MSP430 cost model is working as expected for the default ISA
6+
(msp430x) and hwmult (none), when compiling at -O3. */
7+
8+
char arr[2];
9+
char a;
10+
char *ptr;
11+
12+
/*
13+
** foo:
14+
** ...
15+
** MOV.B \&a, \&arr\+1
16+
** MOV.* #arr\+2, \&ptr
17+
** ...
18+
*/
19+
20+
void
21+
foo (void)
22+
{
23+
arr[1] = a;
24+
ptr = arr + 2;
25+
}
26+
27+
extern void ext (void);
28+
29+
/*
30+
** bar:
31+
** ...
32+
** CALL.* #ext
33+
** CALL.* #ext
34+
** ...
35+
*/
36+
37+
void
38+
bar (void)
39+
{
40+
ext ();
41+
ext ();
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-O3 -mhwmult=f5series" } */
3+
/* { dg-final { check-function-bodies "**" "" } } */
4+
5+
/* Verify the MSP430 cost model is working as expected for the default ISA
6+
(msp430x) and f5series hwmult, when compiling at -O3. */
7+
8+
volatile unsigned long a;
9+
volatile unsigned int b;
10+
volatile unsigned long c;
11+
unsigned long res1;
12+
unsigned long res2;
13+
unsigned long res3;
14+
15+
/*
16+
** foo:
17+
** ...
18+
** MOV.B #16, R14
19+
** CALL.* #__mspabi_slll
20+
** ...
21+
** MOV.* \&res2.*
22+
** ...
23+
** RLA.*RLC.*
24+
** ...
25+
** MOV.* \&res3.*
26+
** ...
27+
** RLA.*RLC.*
28+
** ...
29+
*/
30+
void foo (void)
31+
{
32+
/* Use the shift library function for this. */
33+
res1 = (a << 16) | b;
34+
/* Emit 7 inline shifts for this. */
35+
res2 *= 128;
36+
/* Perform this multiplication inline, using addition and shifts. */
37+
res3 *= 100;
38+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-Os" } */
3+
/* { dg-final { check-function-bodies "**" "" } } */
4+
5+
/* Verify the MSP430 cost model is working as expected for the default ISA
6+
(msp430x) and hwmult (none), when compiling at -Os. */
7+
8+
char arr[2];
9+
char a;
10+
char *ptr;
11+
12+
/*
13+
** foo:
14+
** ...
15+
** MOV.B \&a, \&arr\+1
16+
** MOV.* #arr\+2, \&ptr
17+
** ...
18+
*/
19+
20+
void
21+
foo (void)
22+
{
23+
arr[1] = a;
24+
ptr = arr + 2;
25+
}
26+
27+
extern void ext (void);
28+
29+
/*
30+
** bar:
31+
** ...
32+
** MOV.* #ext, R10
33+
** CALL.* R10
34+
** CALL.* R10
35+
** ...
36+
*/
37+
38+
void
39+
bar (void)
40+
{
41+
ext ();
42+
ext ();
43+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-Os -mhwmult=f5series" } */
3+
/* { dg-final { check-function-bodies "**" "" } } */
4+
5+
/* Verify the MSP430 cost model is working as expected for the default ISA
6+
(msp430x) and f5series hwmult, when compiling at -Os. */
7+
8+
volatile unsigned long a;
9+
volatile unsigned int b;
10+
volatile unsigned long c;
11+
unsigned long res1;
12+
unsigned long res2;
13+
unsigned long res3;
14+
15+
/*
16+
** foo:
17+
** ...
18+
** MOV.B #16, R14
19+
** CALL.* #__mspabi_slll
20+
** ...
21+
** MOV.B #7, R14
22+
** CALL.* #__mspabi_slll
23+
** ...
24+
** MOV.B #100, R14
25+
** MOV.B #0, R15
26+
** ...
27+
** CALL.* #__mulsi2_f5
28+
** ...
29+
*/
30+
void foo (void)
31+
{
32+
/* Use the shift library function for this. */
33+
res1 = (a << 16) | b;
34+
/* Likewise. */
35+
res2 *= 128;
36+
/* Use the hardware multiply library function for this. */
37+
res3 *= 100;
38+
}

0 commit comments

Comments
 (0)