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.
This commit is contained in:
parent
546c8f9558
commit
54896b10db
6 changed files with 189 additions and 5 deletions
|
@ -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. */
|
||||
}
|
||||
|
||||
|
||||
/* Function Entry and Exit */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
42
gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c
Normal file
42
gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c
Normal file
|
@ -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 ();
|
||||
}
|
38
gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c
Normal file
38
gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c
Normal file
|
@ -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;
|
||||
}
|
43
gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c
Normal file
43
gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c
Normal file
|
@ -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 ();
|
||||
}
|
38
gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c
Normal file
38
gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue