From e4c5f9c3f567489f89b41a0d96e321acb5d18152 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Thu, 16 Jul 2020 11:34:50 +0100 Subject: [PATCH 4/5] 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.opt: Add -mdebug-insn-costs option. 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 | 29 +++++++++++++ gcc/config/msp430/msp430.opt | 4 ++ .../gcc.target/msp430/rtx-cost-O3-default.c | 42 ++++++++++++++++++ .../gcc.target/msp430/rtx-cost-O3-f5series.c | 38 ++++++++++++++++ .../gcc.target/msp430/rtx-cost-Os-default.c | 43 +++++++++++++++++++ .../gcc.target/msp430/rtx-cost-Os-f5series.c | 38 ++++++++++++++++ 6 files changed, 194 insertions(+) create mode 100644 gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c create mode 100644 gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c create mode 100644 gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c create mode 100644 gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index b7daafcc11a..7ef651fb324 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1711,6 +1711,35 @@ 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) +{ + int cost; + + if (recog_memoized (insn) < 0) + return 0; + + cost = get_attr_length (insn); + if (TARGET_DEBUG_INSN_COSTS) + { + fprintf (stderr, "cost %d for insn:\n", cost); + debug_rtx (insn); + } + + /* 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 (cost) / (2 * COSTS_N_INSNS (1)); + + /* 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 */ diff --git a/gcc/config/msp430/msp430.opt b/gcc/config/msp430/msp430.opt index 8134ca7ac95..448c41aa81c 100644 --- a/gcc/config/msp430/msp430.opt +++ b/gcc/config/msp430/msp430.opt @@ -115,3 +115,7 @@ Target RejectNegative Joined UInteger IntegerRange(0,65) Var(msp430_max_inline_s For shift operations by a constant amount, which require an individual instruction to shift by one position, set the maximum number of inline shift instructions (maximum value 64) to emit instead of using the corresponding __mspabi helper function. The default value is 4. + +mdebug-insn-costs +Target Report Mask(DEBUG_INSN_COSTS) +Print insns and their costs as calculated by TARGET_INSN_COSTS. 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 index 00000000000..1bd6a142002 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-default.c @@ -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 index 00000000000..1e48625f2e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-O3-f5series.c @@ -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 index 00000000000..8f3d1b28049 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-default.c @@ -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 index 00000000000..bb37f9083d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/rtx-cost-Os-f5series.c @@ -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; +} -- 2.27.0