diff options
author | Vineet Gupta <vineetg@rivosinc.com> | 2023-08-07 13:45:29 -0700 |
---|---|---|
committer | Vineet Gupta <vineetg@rivosinc.com> | 2023-08-25 12:20:18 -0700 |
commit | b41d7eb0e14785ff0ad6e6922cbd4c880e680bf9 (patch) | |
tree | c051cbe9583c301683b7f9f05c0af9c5384b18a3 /gcc | |
parent | d9a0d692ffc6951c5670f54c3f4f17ec64a58600 (diff) | |
download | gcc-b41d7eb0e14785ff0ad6e6922cbd4c880e680bf9.zip gcc-b41d7eb0e14785ff0ad6e6922cbd4c880e680bf9.tar.gz gcc-b41d7eb0e14785ff0ad6e6922cbd4c880e680bf9.tar.bz2 |
RISC-V: Enable Hoist to GCSE simple constants
Hoist want_to_gcse_p () calls rtx_cost () to compute max distance for
hoist candidates. For a simple const (say 6 which needs seperate insn "LI 6")
backend currently returns 0, causing Hoist to bail and elide GCSE.
Note that constants requiring more than 1 insns to setup were working
fine since riscv_rtx_costs () was returning non-zero (although that
itself might need refining: see bugzilla 111139).
To keep testsuite parity, some V tests need updating which started failing
in the new costing regime.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_rtx_costs): Adjust const_int
cost. Add some comments about different constants handling.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/gcse-const.c: New Test
* gcc.target/riscv/rvv/vsetvl/vlmax_conflict-7.c: Remove test
for Jump.
* gcc.target/riscv/rvv/vsetvl/vlmax_conflict-8.c: Ditto.
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/riscv/riscv.cc | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/gcse-const.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-7.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-8.c | 1 |
4 files changed, 22 insertions, 11 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 13166d1..98a46b0 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2490,6 +2490,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN switch (GET_CODE (x)) { case CONST_INT: + /* trivial constants checked using OUTER_CODE in case they are + encodable in insn itself w/o need for additional insn(s). */ if (riscv_immediate_operand_p (outer_code, INTVAL (x))) { *total = 0; @@ -2507,17 +2509,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN /* Fall through. */ case CONST: + /* Non trivial CONST_INT Fall through: check if need multiple insns. */ if ((cost = riscv_const_insns (x)) > 0) { - /* If the constant is likely to be stored in a GPR, SETs of - single-insn constants are as cheap as register sets; we - never want to CSE them. */ - if (cost == 1 && outer_code == SET) - *total = 0; - /* When we load a constant more than once, it usually is better - to duplicate the last operation in the sequence than to CSE - the constant itself. */ - else if (outer_code == SET || GET_MODE (x) == VOIDmode) + /* 1. Hoist will GCSE constants only if TOTAL returned is non-zero. + 2. For constants loaded more than once, the approach so far has + been to duplicate the operation than to CSE the constant. + 3. TODO: make cost more accurate specially if riscv_const_insns + returns > 1. */ + if (outer_code == SET || GET_MODE (x) == VOIDmode) *total = COSTS_N_INSNS (1); } else /* The instruction will be fetched from the constant pool. */ diff --git a/gcc/testsuite/gcc.target/riscv/gcse-const.c b/gcc/testsuite/gcc.target/riscv/gcse-const.c new file mode 100644 index 0000000..b04707c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/gcse-const.c @@ -0,0 +1,13 @@ +/* Slightly modified copy of gcc.target/arm/pr40956.c. */ +/* { dg-options "-Os" } */ +/* Make sure the constant "6" is loaded into register only once. */ +/* { dg-final { scan-assembler-times "\tli.*6" 1 } } */ + +int foo(int p, int* q) +{ + if (p!=9) + *q = 6; + else + *(q+1) = 6; + return 3; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-7.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-7.c index 60ad108..085ca9d 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-7.c @@ -21,5 +21,4 @@ void f (int32_t * restrict in, int32_t * restrict out, size_t n, size_t cond, si } /* { dg-final { scan-assembler-times {vsetvli} 4 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ -/* { dg-final { scan-assembler-times {j\s+\.L[0-9]+\s+\.L[0-9]+:\s+vlm\.v} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ /* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e8,\s*m8,\s*t[au],\s*m[au]} 3 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-8.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-8.c index 7b9574c..fbca9b0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vlmax_conflict-8.c @@ -21,7 +21,6 @@ void f (int32_t * restrict in, int32_t * restrict out, size_t n, size_t cond, si } /* { dg-final { scan-assembler-times {vsetvli} 5 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ -/* { dg-final { scan-assembler-times {j\s+\.L[0-9]+\s+\.L[0-9]+:\s+vlm\.v} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ /* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e8,\s*m8,\s*t[au],\s*m[au]} 3 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ /* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e8,\s*mf8,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ /* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*zero,\s*e16,\s*mf2,\s*t[au],\s*m[au]} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */ |