diff options
author | Paul-Antoine Arras <parras@baylibre.com> | 2025-09-03 16:34:53 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2025-09-03 16:34:53 -0600 |
commit | f6e62242362cc57503751bb725d6a1c1119096ed (patch) | |
tree | f437f4fa270c66515875bba313a759580e92543e | |
parent | 692281a38773a70ae795b3b594f0c0f8fd83e5ef (diff) | |
download | gcc-f6e62242362cc57503751bb725d6a1c1119096ed.zip gcc-f6e62242362cc57503751bb725d6a1c1119096ed.tar.gz gcc-f6e62242362cc57503751bb725d6a1c1119096ed.tar.bz2 |
RISC-V: Add pattern for vector-scalar floating-point max
This pattern enables the combine pass (or late-combine, depending on the case)
to merge a vec_duplicate into an smax RTL instruction.
Before this patch, we have two instructions, e.g.:
vfmv.v.f v2,fa0
vfmax.vv v1,v1,v2
After, we get only one:
vfmax.vf v1,v1,fa0
In some cases, it also shaves off one vsetvli.
gcc/ChangeLog:
* config/riscv/autovec-opt.md (*vfmax_vf_<mode>): Rename into...
(*vf<optab>_vf_<mode>): New pattern to combine vec_duplicate +
vf{min,max}.vv into vf{max,min}.vf.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/vls/floating-point-max-2.c: Adjust scan
dump.
* gcc.target/riscv/rvv/autovec/vls/floating-point-max-4.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c: Add vfmax. Also add
missing scan-dump for vfmul.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c: Add vfmax.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c: Likewise.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h: Add max functions.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h: Add data for
vfmax.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f16.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f32.c: New test.
* gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f64.c: New test.
21 files changed, 1800 insertions, 6 deletions
@@ -0,0 +1,1545 @@ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1) /* Code for RTL register eliminations. +6441eb6dc020f gcc/lra-eliminations.cc (Jakub Jelinek 2025-01-02 11:59:57 +0100 2) Copyright (C) 2010-2025 Free Software Foundation, Inc. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 3) Contributed by Vladimir Makarov <vmakarov@redhat.com>. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 4) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 5) This file is part of GCC. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 6) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 7) GCC is free software; you can redistribute it and/or modify it under +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 8) the terms of the GNU General Public License as published by the Free +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 9) Software Foundation; either version 3, or (at your option) any later +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 10) version. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 11) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 12) GCC is distributed in the hope that it will be useful, but WITHOUT ANY +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 13) WARRANTY; without even the implied warranty of MERCHANTABILITY or +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 14) FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 15) for more details. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 16) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 17) You should have received a copy of the GNU General Public License +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 18) along with GCC; see the file COPYING3. If not see +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 19) <http://www.gnu.org/licenses/>. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 20) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 21) /* Eliminable registers (like a soft argument or frame pointer) are +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 22) widely used in RTL. These eliminable registers should be replaced +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 23) by real hard registers (like the stack pointer or hard frame +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 24) pointer) plus some offset. The offsets usually change whenever the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 25) stack is expanded. We know the final offsets only at the very end +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 26) of LRA. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 27) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 28) Within LRA, we usually keep the RTL in such a state that the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 29) eliminable registers can be replaced by just the corresponding hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 30) register (without any offset). To achieve this we should add the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 31) initial elimination offset at the beginning of LRA and update the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 32) offsets whenever the stack is expanded. We need to do this before +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 33) every constraint pass because the choice of offset often affects +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 34) whether a particular address or memory constraint is satisfied. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 35) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 36) We keep RTL code at most time in such state that the virtual +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 37) registers can be changed by just the corresponding hard registers +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 38) (with zero offsets) and we have the right RTL code. To achieve this +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 39) we should add initial offset at the beginning of LRA work and update +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 40) offsets after each stack expanding. But actually we update virtual +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 41) registers to the same virtual registers + corresponding offsets +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 42) before every constraint pass because it affects constraint +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 43) satisfaction (e.g. an address displacement became too big for some +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 44) target). +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 45) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 46) The final change of eliminable registers to the corresponding hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 47) registers are done at the very end of LRA when there were no change +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 48) in offsets anymore: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 49) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 50) fp + 42 => sp + 42 +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 51) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 52) */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 53) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 54) #include "config.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 55) #include "system.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 56) #include "coretypes.h" +c7131fb2b58ab gcc/lra-eliminations.c (Andrew MacLeod 2015-07-08 00:53:03 +0000 57) #include "backend.h" +957060b5c5d27 gcc/lra-eliminations.c (Andrew MacLeod 2015-10-29 13:57:32 +0000 58) #include "target.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 59) #include "rtl.h" +957060b5c5d27 gcc/lra-eliminations.c (Andrew MacLeod 2015-10-29 13:57:32 +0000 60) #include "tree.h" +c7131fb2b58ab gcc/lra-eliminations.c (Andrew MacLeod 2015-07-08 00:53:03 +0000 61) #include "df.h" +4d0cdd0ce64e8 gcc/lra-eliminations.c (Thomas Preud'homme 2016-10-13 14:17:52 +0000 62) #include "memmodel.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 63) #include "tm_p.h" +957060b5c5d27 gcc/lra-eliminations.c (Andrew MacLeod 2015-10-29 13:57:32 +0000 64) #include "optabs.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 65) #include "regs.h" +957060b5c5d27 gcc/lra-eliminations.c (Andrew MacLeod 2015-10-29 13:57:32 +0000 66) #include "ira.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 67) #include "recog.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 68) #include "output.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 69) #include "rtl-error.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 70) #include "lra-int.h" +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 71) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 72) /* This structure is used to record information about hard register +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 73) eliminations. */ +6c1dae73cd2ce gcc/lra-eliminations.c (Martin Sebor 2019-07-09 16:36:00 +0000 74) class lra_elim_table +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 75) { +6c1dae73cd2ce gcc/lra-eliminations.c (Martin Sebor 2019-07-09 16:36:00 +0000 76) public: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 77) /* Hard register number to be eliminated. */ +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 78) int from; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 79) /* Hard register number used as replacement. */ +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 80) int to; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 81) /* Difference between values of the two hard registers above on +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 82) previous iteration. */ +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 83) poly_int64 previous_offset; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 84) /* Difference between the values on the current iteration. */ +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 85) poly_int64 offset; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 86) /* Nonzero if this elimination can be done. */ +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 87) bool can_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 88) /* CAN_ELIMINATE since the last check. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 89) bool prev_can_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 90) /* REG rtx for the register to be eliminated. We cannot simply +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 91) compare the number since we might then spuriously replace a hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 92) register corresponding to a pseudo assigned to the reg to be +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 93) eliminated. */ +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 94) rtx from_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 95) /* REG rtx for the replacement. */ +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 96) rtx to_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 97) }; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 98) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 99) /* The elimination table. Each array entry describes one possible way +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 100) of eliminating a register in favor of another. If there is more +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 101) than one way of eliminating a particular register, the most +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 102) preferred should be specified first. */ +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 103) static class lra_elim_table *reg_eliminate = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 104) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 105) /* This is an intermediate structure to initialize the table. It has +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 106) exactly the members provided by ELIMINABLE_REGS. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 107) static const struct elim_table_1 +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 108) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 109) const int from; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 110) const int to; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 111) } reg_eliminate_1[] = +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 112) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 113) ELIMINABLE_REGS; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 114) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 115) #define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 116) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 117) /* Print info about elimination table to file F. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 118) static void +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 119) print_elim_table (FILE *f) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 120) { +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 121) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 122) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 123) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 124) { +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 125) fprintf (f, "%s eliminate %d to %d (offset=", +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 126) ep->can_eliminate ? "Can" : "Can't", ep->from, ep->to); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 127) print_dec (ep->offset, f); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 128) fprintf (f, ", prev_offset="); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 129) print_dec (ep->previous_offset, f); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 130) fprintf (f, ")\n"); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 131) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 132) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 133) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 134) /* Print info about elimination table to stderr. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 135) void +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 136) lra_debug_elim_table (void) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 137) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 138) print_elim_table (stderr); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 139) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 140) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 141) /* Setup possibility of elimination in elimination table element EP to +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 142) VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 143) pointer to stack pointer is not possible anymore. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 144) static void +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 145) setup_can_eliminate (class lra_elim_table *ep, bool value) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 146) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 147) ep->can_eliminate = ep->prev_can_eliminate = value; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 148) if (! value +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 149) && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 150) frame_pointer_needed = 1; +d303ff9764d32 gcc/lra-eliminations.c (H.J. Lu 2015-02-04 12:02:21 -0800 151) if (!frame_pointer_needed) +d303ff9764d32 gcc/lra-eliminations.c (H.J. Lu 2015-02-04 12:02:21 -0800 152) REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 153) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 154) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 155) /* Map: eliminable "from" register -> its current elimination, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 156) or NULL if none. The elimination table may contain more than +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 157) one elimination for the same hard register, but this map specifies +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 158) the one that we are currently using. */ +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 159) static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 160) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 161) /* When an eliminable hard register becomes not eliminable, we use the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 162) following special structure to restore original offsets for the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 163) register. */ +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 164) static class lra_elim_table self_elim_table; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 165) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 166) /* Offsets should be used to restore original offsets for eliminable +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 167) hard register which just became not eliminable. Zero, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 168) otherwise. */ +eaa41a6dc127d gcc/lra-eliminations.cc (Richard Sandiford 2023-09-29 17:55:12 +0100 169) static poly_int64 self_elim_offsets[FIRST_PSEUDO_REGISTER]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 170) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 171) /* Map: hard regno -> RTL presentation. RTL presentations of all +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 172) potentially eliminable hard registers are stored in the map. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 173) static rtx eliminable_reg_rtx[FIRST_PSEUDO_REGISTER]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 174) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 175) /* Set up ELIMINATION_MAP of the currently used eliminations. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 176) static void +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 177) setup_elimination_map (void) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 178) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 179) int i; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 180) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 181) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 182) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 183) elimination_map[i] = NULL; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 184) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 185) if (ep->can_eliminate && elimination_map[ep->from] == NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 186) elimination_map[ep->from] = ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 187) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 188) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 189) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 190) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 191) /* Compute the sum of X and Y, making canonicalizations assumed in an +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 192) address, namely: sum constant integers, surround the sum of two +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 193) constants with a CONST, put the constant as the second operand, and +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 194) group the constant on the outermost sum. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 195) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 196) This routine assumes both inputs are already in canonical form. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 197) static rtx +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 198) form_sum (rtx x, rtx y) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 199) { +ef4bddc299eae gcc/lra-eliminations.c (Richard Sandiford 2014-10-29 12:02:45 +0000 200) machine_mode mode = GET_MODE (x); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 201) poly_int64 offset; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 202) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 203) if (mode == VOIDmode) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 204) mode = GET_MODE (y); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 205) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 206) if (mode == VOIDmode) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 207) mode = Pmode; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 208) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 209) if (poly_int_rtx_p (x, &offset)) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 210) return plus_constant (mode, y, offset); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 211) else if (poly_int_rtx_p (y, &offset)) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 212) return plus_constant (mode, x, offset); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 213) else if (CONSTANT_P (x)) +4e1952ab19938 gcc/lra-eliminations.c (Kyrylo Tkachov 2015-07-24 16:46:04 +0000 214) std::swap (x, y); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 215) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 216) if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1))) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 217) return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 218) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 219) /* Note that if the operands of Y are specified in the opposite +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 220) order in the recursive calls below, infinite recursion will +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 221) occur. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 222) if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1))) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 223) return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 224) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 225) /* If both constant, encapsulate sum. Otherwise, just form sum. A +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 226) constant will have been placed second. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 227) if (CONSTANT_P (x) && CONSTANT_P (y)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 228) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 229) if (GET_CODE (x) == CONST) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 230) x = XEXP (x, 0); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 231) if (GET_CODE (y) == CONST) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 232) y = XEXP (y, 0); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 233) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 234) return gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (mode, x, y)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 235) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 236) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 237) return gen_rtx_PLUS (mode, x, y); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 238) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 239) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 240) /* Return the current substitution hard register of the elimination of +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 241) HARD_REGNO. If HARD_REGNO is not eliminable, return itself. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 242) int +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 243) lra_get_elimination_hard_regno (int hard_regno) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 244) { +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 245) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 246) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 247) if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 248) return hard_regno; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 249) if ((ep = elimination_map[hard_regno]) == NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 250) return hard_regno; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 251) return ep->to; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 252) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 253) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 254) /* Return elimination which will be used for hard reg REG, NULL +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 255) otherwise. */ +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 256) static class lra_elim_table * +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 257) get_elimination (rtx reg) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 258) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 259) int hard_regno; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 260) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 261) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 262) lra_assert (REG_P (reg)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 263) if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 264) return NULL; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 265) if ((ep = elimination_map[hard_regno]) != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 266) return ep->from_rtx != reg ? NULL : ep; +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 267) poly_int64 offset = self_elim_offsets[hard_regno]; +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 268) if (known_eq (offset, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 269) return NULL; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 270) /* This is an iteration to restore offsets just after HARD_REGNO +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 271) stopped to be eliminable. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 272) self_elim_table.from = self_elim_table.to = hard_regno; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 273) self_elim_table.from_rtx +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 274) = self_elim_table.to_rtx +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 275) = eliminable_reg_rtx[hard_regno]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 276) lra_assert (self_elim_table.from_rtx != NULL); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 277) self_elim_table.offset = offset; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 278) return &self_elim_table; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 279) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 280) +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 281) /* Transform (subreg (plus reg const)) to (plus (subreg reg) const) +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 282) when it is possible. Return X or the transformation result if the +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 283) transformation is done. */ +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 284) static rtx +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 285) move_plus_up (rtx x) +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 286) { +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 287) rtx subreg_reg; +b8506a8ac0a98 gcc/lra-eliminations.c (Richard Sandiford 2017-07-05 15:29:27 +0000 288) machine_mode x_mode, subreg_reg_mode; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 289) +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 290) if (GET_CODE (x) != SUBREG || !subreg_lowpart_p (x)) +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 291) return x; +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 292) subreg_reg = SUBREG_REG (x); +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 293) x_mode = GET_MODE (x); +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 294) subreg_reg_mode = GET_MODE (subreg_reg); +03a9562184454 gcc/lra-eliminations.c (Richard Sandiford 2017-08-22 16:14:48 +0000 295) if (!paradoxical_subreg_p (x) +03a9562184454 gcc/lra-eliminations.c (Richard Sandiford 2017-08-22 16:14:48 +0000 296) && GET_CODE (subreg_reg) == PLUS +cd65ae9071036 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-14 20:57:34 +0100 297) && CONSTANT_P (XEXP (subreg_reg, 1)) +cd65ae9071036 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-14 20:57:34 +0100 298) && GET_MODE_CLASS (x_mode) == MODE_INT +cd65ae9071036 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-14 20:57:34 +0100 299) && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT) +26ff85b0b9d79 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-11 20:06:34 +0100 300) { +26ff85b0b9d79 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-11 20:06:34 +0100 301) rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode, +26ff85b0b9d79 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-11 20:06:34 +0100 302) subreg_lowpart_offset (x_mode, +26ff85b0b9d79 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-11 20:06:34 +0100 303) subreg_reg_mode)); +26ff85b0b9d79 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-11 20:06:34 +0100 304) if (cst && CONSTANT_P (cst)) +da3f2a561649c gcc/lra-eliminations.cc (Richard Sandiford 2025-06-30 08:52:26 +0100 305) { +da3f2a561649c gcc/lra-eliminations.cc (Richard Sandiford 2025-06-30 08:52:26 +0100 306) rtx lowpart = lowpart_subreg (x_mode, XEXP (subreg_reg, 0), +da3f2a561649c gcc/lra-eliminations.cc (Richard Sandiford 2025-06-30 08:52:26 +0100 307) subreg_reg_mode); +da3f2a561649c gcc/lra-eliminations.cc (Richard Sandiford 2025-06-30 08:52:26 +0100 308) if (lowpart) +da3f2a561649c gcc/lra-eliminations.cc (Richard Sandiford 2025-06-30 08:52:26 +0100 309) return gen_rtx_PLUS (x_mode, lowpart, cst); +da3f2a561649c gcc/lra-eliminations.cc (Richard Sandiford 2025-06-30 08:52:26 +0100 310) } +26ff85b0b9d79 gcc/lra-eliminations.c (Jakub Jelinek 2016-01-11 20:06:34 +0100 311) } +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 312) return x; +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 313) } +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 314) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 315) /* Flag that we already applied nonzero stack pointer elimination +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 316) offset; such sp updates cannot currently be undone. */ +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 317) static bool elimination_2sp_occurred_p = false; +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 318) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 319) /* Take note of any nonzero sp-OFFSET used in eliminations to sp. */ +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 320) static inline poly_int64 +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 321) note_spoff (poly_int64 offset) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 322) { +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 323) if (maybe_ne (offset, 0)) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 324) elimination_2sp_occurred_p = true; +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 325) return offset; +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 326) } +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 327) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 328) /* Scan X and replace any eliminable registers (such as fp) with a +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 329) replacement (such as sp) if SUBST_P, plus an offset. The offset is +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 330) a change in the offset between the eliminable register and its +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 331) substitution if UPDATE_P, or the full offset if FULL_P, or +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 332) otherwise zero. If FULL_P, we also use the SP offsets for +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 333) elimination to SP. If UPDATE_P, use UPDATE_SP_OFFSET for updating +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 334) offsets of register elimnable to SP. If UPDATE_SP_OFFSET is +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 335) non-zero, don't use difference of the offset and the previous +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 336) offset. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 337) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 338) MEM_MODE is the mode of an enclosing MEM. We need this to know how +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 339) much to adjust a register for, e.g., PRE_DEC. Also, if we are +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 340) inside a MEM, we are allowed to replace a sum of a hard register +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 341) and the constant zero with the hard register, which we cannot do +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 342) outside a MEM. In addition, we need to record the fact that a +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 343) hard register is referenced outside a MEM. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 344) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 345) If we make full substitution to SP for non-null INSN, add the insn +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 346) sp offset. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 347) rtx +ef4bddc299eae gcc/lra-eliminations.c (Richard Sandiford 2014-10-29 12:02:45 +0000 348) lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 349) bool subst_p, bool update_p, +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 350) poly_int64 update_sp_offset, bool full_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 351) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 352) enum rtx_code code = GET_CODE (x); +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 353) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 354) rtx new_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 355) int i, j; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 356) const char *fmt; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 357) int copied = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 358) +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 359) lra_assert (!update_p || !full_p); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 360) lra_assert (known_eq (update_sp_offset, 0) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 361) || (!subst_p && update_p && !full_p)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 362) if (! current_function_decl) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 363) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 364) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 365) switch (code) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 366) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 367) CASE_CONST_ANY: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 368) case CONST: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 369) case SYMBOL_REF: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 370) case CODE_LABEL: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 371) case PC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 372) case ASM_INPUT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 373) case ADDR_VEC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 374) case ADDR_DIFF_VEC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 375) case RETURN: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 376) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 377) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 378) case REG: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 379) /* First handle the case where we encounter a bare hard register +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 380) that is eliminable. Replace it with a PLUS. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 381) if ((ep = get_elimination (x)) != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 382) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 383) rtx to = subst_p ? ep->to_rtx : ep->from_rtx; +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 384) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 385) if (maybe_ne (update_sp_offset, 0)) +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 386) { +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 387) if (ep->to_rtx == stack_pointer_rtx) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 388) return plus_constant (Pmode, to, note_spoff (update_sp_offset)); +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 389) return to; +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 390) } +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 391) else if (update_p) +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 392) return plus_constant (Pmode, to, ep->offset - ep->previous_offset); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 393) else if (full_p) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 394) return plus_constant (Pmode, to, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 395) ep->offset +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 396) - (insn != NULL_RTX +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 397) && ep->to_rtx == stack_pointer_rtx +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 398) ? note_spoff (lra_get_insn_recog_data +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 399) (insn)->sp_offset) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 400) : 0)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 401) else +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 402) return to; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 403) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 404) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 405) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 406) case PLUS: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 407) /* If this is the sum of an eliminable register and a constant, rework +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 408) the sum. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 409) if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1))) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 410) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 411) if ((ep = get_elimination (XEXP (x, 0))) != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 412) { +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 413) poly_int64 offset, curr_offset; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 414) rtx to = subst_p ? ep->to_rtx : ep->from_rtx; +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 415) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 416) if (! update_p && ! full_p) +10d59b802a7db gcc/lra-eliminations.cc (Richard Sandiford 2023-09-07 07:28:50 +0100 417) return simplify_gen_binary (PLUS, Pmode, to, XEXP (x, 1)); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 418) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 419) if (maybe_ne (update_sp_offset, 0)) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 420) offset = (ep->to_rtx == stack_pointer_rtx +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 421) ? note_spoff (update_sp_offset) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 422) : 0); +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 423) else +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 424) offset = (update_p +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 425) ? ep->offset - ep->previous_offset : ep->offset); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 426) if (full_p && insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 427) offset -= note_spoff (lra_get_insn_recog_data (insn)->sp_offset); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 428) if (poly_int_rtx_p (XEXP (x, 1), &curr_offset) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 429) && known_eq (curr_offset, -offset)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 430) return to; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 431) else +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 432) return gen_rtx_PLUS (Pmode, to, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 433) plus_constant (Pmode, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 434) XEXP (x, 1), offset)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 435) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 436) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 437) /* If the hard register is not eliminable, we are done since +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 438) the other operand is a constant. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 439) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 440) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 441) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 442) /* If this is part of an address, we want to bring any constant +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 443) to the outermost PLUS. We will do this by doing hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 444) register replacement in our operands and seeing if a constant +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 445) shows up in one of them. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 446) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 447) Note that there is no risk of modifying the structure of the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 448) insn, since we only get called for its operands, thus we are +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 449) either modifying the address inside a MEM, or something like +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 450) an address operand of a load-address insn. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 451) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 452) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 453) rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 454) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 455) update_sp_offset, full_p); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 456) rtx new1 = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 457) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 458) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 459) +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 460) new0 = move_plus_up (new0); +18c8f1a812865 gcc/lra-eliminations.c (Vladimir Makarov 2015-12-04 19:23:21 +0000 461) new1 = move_plus_up (new1); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 462) if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 463) return form_sum (new0, new1); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 464) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 465) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 466) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 467) case MULT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 468) /* If this is the product of an eliminable hard register and a +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 469) constant, apply the distribute law and move the constant out +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 470) so that we have (plus (mult ..) ..). This is needed in order +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 471) to keep load-address insns valid. This case is pathological. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 472) We ignore the possibility of overflow here. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 473) if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 474) && (ep = get_elimination (XEXP (x, 0))) != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 475) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 476) rtx to = subst_p ? ep->to_rtx : ep->from_rtx; +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 477) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 478) if (maybe_ne (update_sp_offset, 0)) +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 479) { +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 480) if (ep->to_rtx == stack_pointer_rtx) +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 481) return plus_constant (Pmode, +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 482) gen_rtx_MULT (Pmode, to, XEXP (x, 1)), +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 483) note_spoff (update_sp_offset) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 484) * INTVAL (XEXP (x, 1))); +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 485) return gen_rtx_MULT (Pmode, to, XEXP (x, 1)); +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 486) } +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 487) else if (update_p) +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 488) return plus_constant (Pmode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 489) gen_rtx_MULT (Pmode, to, XEXP (x, 1)), +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 490) (ep->offset - ep->previous_offset) +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 491) * INTVAL (XEXP (x, 1))); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 492) else if (full_p) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 493) { +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 494) poly_int64 offset = ep->offset; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 495) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 496) if (insn != NULL_RTX && ep->to_rtx == stack_pointer_rtx) +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 497) offset -= note_spoff (lra_get_insn_recog_data (insn)->sp_offset); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 498) return +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 499) plus_constant (Pmode, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 500) gen_rtx_MULT (Pmode, to, XEXP (x, 1)), +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 501) offset * INTVAL (XEXP (x, 1))); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 502) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 503) else +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 504) return gen_rtx_MULT (Pmode, to, XEXP (x, 1)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 505) } +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 506) +191816a36b90e gcc/lra-eliminations.c (Marek Polacek 2016-08-12 10:30:47 +0000 507) /* fall through */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 508) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 509) case CALL: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 510) case COMPARE: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 511) /* See comments before PLUS about handling MINUS. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 512) case MINUS: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 513) case DIV: case UDIV: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 514) case MOD: case UMOD: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 515) case AND: case IOR: case XOR: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 516) case ROTATERT: case ROTATE: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 517) case ASHIFTRT: case LSHIFTRT: case ASHIFT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 518) case NE: case EQ: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 519) case GE: case GT: case GEU: case GTU: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 520) case LE: case LT: case LEU: case LTU: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 521) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 522) rtx new0 = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 523) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 524) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 525) rtx new1 = XEXP (x, 1) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 526) ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 527) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 528) update_sp_offset, full_p) : 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 529) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 530) if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 531) return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 532) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 533) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 534) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 535) case EXPR_LIST: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 536) /* If we have something in XEXP (x, 0), the usual case, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 537) eliminate it. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 538) if (XEXP (x, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 539) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 540) new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 541) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 542) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 543) if (new_rtx != XEXP (x, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 544) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 545) /* If this is a REG_DEAD note, it is not valid anymore. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 546) Using the eliminated version could result in creating a +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 547) REG_DEAD note for the stack or frame pointer. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 548) if (REG_NOTE_KIND (x) == REG_DEAD) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 549) return (XEXP (x, 1) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 550) ? lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 551) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 552) update_sp_offset, full_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 553) : NULL_RTX); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 554) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 555) x = alloc_reg_note (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 556) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 557) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 558) +191816a36b90e gcc/lra-eliminations.c (Marek Polacek 2016-08-12 10:30:47 +0000 559) /* fall through */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 560) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 561) case INSN_LIST: +f91aec98e2fe7 gcc/lra-eliminations.c (Richard Sandiford 2013-09-27 11:17:34 +0000 562) case INT_LIST: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 563) /* Now do eliminations in the rest of the chain. If this was +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 564) an EXPR_LIST, this might result in allocating more memory than is +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 565) strictly needed, but it simplifies the code. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 566) if (XEXP (x, 1)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 567) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 568) new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 1), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 569) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 570) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 571) if (new_rtx != XEXP (x, 1)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 572) return +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 573) gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 574) XEXP (x, 0), new_rtx); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 575) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 576) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 577) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 578) case PRE_INC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 579) case POST_INC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 580) case PRE_DEC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 581) case POST_DEC: +ccef9e5dd9ffd gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:27 -0300 582) /* Recurse to adjust elimination offsets in a spilled pseudo. */ +ccef9e5dd9ffd gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:27 -0300 583) if (GET_CODE (XEXP (x, 0)) == MEM) +ccef9e5dd9ffd gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:27 -0300 584) break; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 585) /* We do not support elimination of a register that is modified. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 586) elimination_effects has already make sure that this does not +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 587) happen. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 588) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 589) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 590) case PRE_MODIFY: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 591) case POST_MODIFY: +ccef9e5dd9ffd gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:27 -0300 592) /* Recurse to adjust elimination offsets in a spilled pseudo. */ +ccef9e5dd9ffd gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:27 -0300 593) if (GET_CODE (XEXP (x, 0)) == MEM) +ccef9e5dd9ffd gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:27 -0300 594) break; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 595) /* We do not support elimination of a hard register that is +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 596) modified. LRA has already make sure that this does not +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 597) happen. The only remaining case we need to consider here is +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 598) that the increment value may be an eliminable register. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 599) if (GET_CODE (XEXP (x, 1)) == PLUS +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 600) && XEXP (XEXP (x, 1), 0) == XEXP (x, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 601) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 602) rtx new_rtx = lra_eliminate_regs_1 (insn, XEXP (XEXP (x, 1), 1), +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 603) mem_mode, subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 604) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 605) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 606) if (new_rtx != XEXP (XEXP (x, 1), 1)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 607) return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0), +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 608) gen_rtx_PLUS (GET_MODE (x), +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 609) XEXP (x, 0), new_rtx)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 610) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 611) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 612) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 613) case STRICT_LOW_PART: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 614) case NEG: case NOT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 615) case SIGN_EXTEND: case ZERO_EXTEND: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 616) case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 617) case FLOAT: case FIX: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 618) case UNSIGNED_FIX: case UNSIGNED_FLOAT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 619) case ABS: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 620) case SQRT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 621) case FFS: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 622) case CLZ: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 623) case CTZ: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 624) case POPCOUNT: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 625) case PARITY: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 626) case BSWAP: +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 627) new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 628) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 629) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 630) if (new_rtx != XEXP (x, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 631) return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 632) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 633) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 634) case SUBREG: +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 635) new_rtx = lra_eliminate_regs_1 (insn, SUBREG_REG (x), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 636) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 637) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 638) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 639) if (new_rtx != SUBREG_REG (x)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 640) { +03a9562184454 gcc/lra-eliminations.c (Richard Sandiford 2017-08-22 16:14:48 +0000 641) if (MEM_P (new_rtx) && !paradoxical_subreg_p (x)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 642) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 643) SUBREG_REG (x) = new_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 644) alter_subreg (&x, false); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 645) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 646) } +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 647) else if (! subst_p) +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 648) { +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 649) /* LRA can transform subregs itself. So don't call +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 650) simplify_gen_subreg until LRA transformations are +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 651) finished. Function simplify_gen_subreg can do +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 652) non-trivial transformations (like truncation) which +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 653) might make LRA work to fail. */ +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 654) SUBREG_REG (x) = new_rtx; +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 655) return x; +b17ec42d4c8cd gcc/lra-eliminations.c (Vladimir Makarov 2014-05-23 01:52:01 +0000 656) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 657) else +baa061be44ee3 gcc/lra-eliminations.c (Richard Sandiford 2012-10-30 14:33:48 +0000 658) return simplify_gen_subreg (GET_MODE (x), new_rtx, +baa061be44ee3 gcc/lra-eliminations.c (Richard Sandiford 2012-10-30 14:33:48 +0000 659) GET_MODE (new_rtx), SUBREG_BYTE (x)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 660) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 661) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 662) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 663) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 664) case MEM: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 665) /* Our only special processing is to pass the mode of the MEM to our +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 666) recursive call and copy the flags. While we are here, handle this +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 667) case more efficiently. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 668) return +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 669) replace_equiv_address_nv +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 670) (x, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 671) lra_eliminate_regs_1 (insn, XEXP (x, 0), GET_MODE (x), +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 672) subst_p, update_p, update_sp_offset, full_p)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 673) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 674) case USE: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 675) /* Handle insn_list USE that a call to a pure function may generate. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 676) new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, 0), VOIDmode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 677) subst_p, update_p, update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 678) if (new_rtx != XEXP (x, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 679) return gen_rtx_USE (GET_MODE (x), new_rtx); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 680) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 681) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 682) case CLOBBER: +48cb51827c9eb gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-12-08 15:37:42 -0500 683) case ASM_OPERANDS: +48cb51827c9eb gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-12-08 15:37:42 -0500 684) gcc_assert (insn && DEBUG_INSN_P (insn)); +48cb51827c9eb gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-12-08 15:37:42 -0500 685) break; +48cb51827c9eb gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-12-08 15:37:42 -0500 686) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 687) case SET: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 688) gcc_unreachable (); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 689) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 690) default: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 691) break; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 692) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 693) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 694) /* Process each of our operands recursively. If any have changed, make a +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 695) copy of the rtx. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 696) fmt = GET_RTX_FORMAT (code); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 697) for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 698) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 699) if (*fmt == 'e') +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 700) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 701) new_rtx = lra_eliminate_regs_1 (insn, XEXP (x, i), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 702) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 703) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 704) if (new_rtx != XEXP (x, i) && ! copied) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 705) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 706) x = shallow_copy_rtx (x); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 707) copied = 1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 708) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 709) XEXP (x, i) = new_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 710) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 711) else if (*fmt == 'E') +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 712) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 713) int copied_vec = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 714) for (j = 0; j < XVECLEN (x, i); j++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 715) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 716) new_rtx = lra_eliminate_regs_1 (insn, XVECEXP (x, i, j), mem_mode, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 717) subst_p, update_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 718) update_sp_offset, full_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 719) if (new_rtx != XVECEXP (x, i, j) && ! copied_vec) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 720) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 721) rtvec new_v = gen_rtvec_v (XVECLEN (x, i), +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 722) XVEC (x, i)->elem); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 723) if (! copied) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 724) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 725) x = shallow_copy_rtx (x); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 726) copied = 1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 727) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 728) XVEC (x, i) = new_v; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 729) copied_vec = 1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 730) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 731) XVECEXP (x, i, j) = new_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 732) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 733) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 734) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 735) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 736) return x; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 737) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 738) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 739) /* This function is used externally in subsequent passes of GCC. It +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 740) always does a full elimination of X. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 741) rtx +ef4bddc299eae gcc/lra-eliminations.c (Richard Sandiford 2014-10-29 12:02:45 +0000 742) lra_eliminate_regs (rtx x, machine_mode mem_mode, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 743) rtx insn ATTRIBUTE_UNUSED) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 744) { +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 745) return lra_eliminate_regs_1 (NULL, x, mem_mode, true, false, 0, true); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 746) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 747) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 748) /* Stack pointer offset before the current insn relative to one at the +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 749) func start. RTL insns can change SP explicitly. We keep the +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 750) changes from one insn to another through this variable. */ +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 751) static poly_int64 curr_sp_change; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 752) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 753) /* Scan rtx X for references to elimination source or target registers +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 754) in contexts that would prevent the elimination from happening. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 755) Update the table of eliminables to reflect the changed state. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 756) MEM_MODE is the mode of an enclosing MEM rtx, or VOIDmode if not +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 757) within a MEM. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 758) static void +ef4bddc299eae gcc/lra-eliminations.c (Richard Sandiford 2014-10-29 12:02:45 +0000 759) mark_not_eliminable (rtx x, machine_mode mem_mode) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 760) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 761) enum rtx_code code = GET_CODE (x); +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 762) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 763) int i, j; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 764) const char *fmt; +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 765) poly_int64 offset = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 766) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 767) switch (code) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 768) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 769) case PRE_INC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 770) case POST_INC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 771) case PRE_DEC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 772) case POST_DEC: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 773) case POST_MODIFY: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 774) case PRE_MODIFY: +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 775) if (XEXP (x, 0) == stack_pointer_rtx +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 776) && ((code != PRE_MODIFY && code != POST_MODIFY) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 777) || (GET_CODE (XEXP (x, 1)) == PLUS +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 778) && XEXP (x, 0) == XEXP (XEXP (x, 1), 0) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 779) && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset)))) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 780) { +7b4df2bf95d22 gcc/lra-eliminations.c (Richard Sandiford 2018-01-03 07:18:13 +0000 781) poly_int64 size = GET_MODE_SIZE (mem_mode); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 782) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 783) #ifdef PUSH_ROUNDING +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 784) /* If more bytes than MEM_MODE are pushed, account for +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 785) them. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 786) size = PUSH_ROUNDING (size); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 787) #endif +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 788) if (code == PRE_DEC || code == POST_DEC) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 789) curr_sp_change -= size; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 790) else if (code == PRE_INC || code == POST_INC) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 791) curr_sp_change += size; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 792) else if (code == PRE_MODIFY || code == POST_MODIFY) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 793) curr_sp_change += offset; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 794) } +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 795) else if (REG_P (XEXP (x, 0)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 796) && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 797) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 798) /* If we modify the source of an elimination rule, disable +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 799) it. Do the same if it is the destination and not the +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 800) hard frame register. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 801) for (ep = reg_eliminate; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 802) ep < ®_eliminate[NUM_ELIMINABLE_REGS]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 803) ep++) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 804) if (ep->from_rtx == XEXP (x, 0) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 805) || (ep->to_rtx == XEXP (x, 0) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 806) && ep->to_rtx != hard_frame_pointer_rtx)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 807) setup_can_eliminate (ep, false); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 808) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 809) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 810) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 811) case USE: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 812) if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 813) /* If using a hard register that is the source of an eliminate +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 814) we still think can be performed, note it cannot be +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 815) performed since we don't know how this hard register is +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 816) used. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 817) for (ep = reg_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 818) ep < ®_eliminate[NUM_ELIMINABLE_REGS]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 819) ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 820) if (ep->from_rtx == XEXP (x, 0) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 821) && ep->to_rtx != hard_frame_pointer_rtx) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 822) setup_can_eliminate (ep, false); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 823) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 824) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 825) case CLOBBER: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 826) if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 827) /* If clobbering a hard register that is the replacement +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 828) register for an elimination we still think can be +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 829) performed, note that it cannot be performed. Otherwise, we +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 830) need not be concerned about it. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 831) for (ep = reg_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 832) ep < ®_eliminate[NUM_ELIMINABLE_REGS]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 833) ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 834) if (ep->to_rtx == XEXP (x, 0) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 835) && ep->to_rtx != hard_frame_pointer_rtx) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 836) setup_can_eliminate (ep, false); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 837) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 838) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 839) case SET: +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 840) if (SET_DEST (x) == stack_pointer_rtx +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 841) && GET_CODE (SET_SRC (x)) == PLUS +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 842) && XEXP (SET_SRC (x), 0) == SET_DEST (x) +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 843) && poly_int_rtx_p (XEXP (SET_SRC (x), 1), &offset)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 844) { +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 845) curr_sp_change += offset; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 846) return; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 847) } +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 848) if (! REG_P (SET_DEST (x)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 849) || REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 850) mark_not_eliminable (SET_DEST (x), mem_mode); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 851) else +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 852) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 853) /* See if this is setting the replacement hard register for +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 854) an elimination. +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 855) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 856) If DEST is the hard frame pointer, we do nothing because +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 857) we assume that all assignments to the frame pointer are +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 858) for non-local gotos and are being done at a time when +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 859) they are valid and do not disturb anything else. Some +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 860) machines want to eliminate a fake argument pointer (or +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 861) even a fake frame pointer) with either the real frame +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 862) pointer or the stack pointer. Assignments to the hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 863) frame pointer must not prevent this elimination. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 864) for (ep = reg_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 865) ep < ®_eliminate[NUM_ELIMINABLE_REGS]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 866) ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 867) if (ep->to_rtx == SET_DEST (x) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 868) && SET_DEST (x) != hard_frame_pointer_rtx) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 869) setup_can_eliminate (ep, false); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 870) } +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 871) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 872) mark_not_eliminable (SET_SRC (x), mem_mode); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 873) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 874) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 875) case MEM: +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 876) /* Our only special processing is to pass the mode of the MEM to +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 877) our recursive call. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 878) mark_not_eliminable (XEXP (x, 0), GET_MODE (x)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 879) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 880) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 881) default: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 882) break; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 883) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 884) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 885) fmt = GET_RTX_FORMAT (code); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 886) for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 887) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 888) if (*fmt == 'e') +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 889) mark_not_eliminable (XEXP (x, i), mem_mode); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 890) else if (*fmt == 'E') +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 891) for (j = 0; j < XVECLEN (x, i); j++) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 892) mark_not_eliminable (XVECEXP (x, i, j), mem_mode); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 893) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 894) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 895) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 896) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 897) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 898) /* Scan INSN and eliminate all eliminable hard registers in it. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 899) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 900) If REPLACE_P is true, do the replacement destructively. Also +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 901) delete the insn as dead it if it is setting an eliminable register. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 902) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 903) If REPLACE_P is false, just update the offsets while keeping the +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 904) base register the same. If FIRST_P, use the sp offset for +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 905) elimination to sp. Otherwise, use UPDATE_SP_OFFSET for this. If +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 906) UPDATE_SP_OFFSET is non-zero, don't use difference of the offset +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 907) and the previous offset. Attach the note about used elimination +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 908) for insns setting frame pointer to update elimination easy (without +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 909) parsing already generated elimination insns to find offset +a6af1bf9fe2f7 gcc/lra-eliminations.c (Vladimir Makarov 2015-04-19 23:48:24 +0000 910) previously used) in future. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 911) +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 912) void +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 913) eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p, +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 914) poly_int64 update_sp_offset) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 915) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 916) int icode = recog_memoized (insn); +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 917) rtx set, old_set = single_set (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 918) bool validate_p; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 919) int i; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 920) rtx substed_operand[MAX_RECOG_OPERANDS]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 921) rtx orig_operand[MAX_RECOG_OPERANDS]; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 922) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 923) rtx plus_src, plus_cst_src; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 924) lra_insn_recog_data_t id; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 925) struct lra_static_insn_data *static_id; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 926) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 927) if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 928) { +397186076bb72 gcc/lra-eliminations.c (Steven Bosscher 2013-03-30 14:26:42 +0000 929) lra_assert (GET_CODE (PATTERN (insn)) == USE +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 930) || GET_CODE (PATTERN (insn)) == CLOBBER +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 931) || GET_CODE (PATTERN (insn)) == ASM_INPUT); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 932) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 933) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 934) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 935) /* We allow one special case which happens to work on all machines we +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 936) currently support: a single set with the source or a REG_EQUAL +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 937) note being a PLUS of an eliminable register and a constant. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 938) plus_src = plus_cst_src = 0; +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 939) poly_int64 offset = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 940) if (old_set && REG_P (SET_DEST (old_set))) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 941) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 942) if (GET_CODE (SET_SRC (old_set)) == PLUS) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 943) plus_src = SET_SRC (old_set); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 944) /* First see if the source is of the form (plus (...) CST). */ +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 945) if (plus_src && poly_int_rtx_p (XEXP (plus_src, 1), &offset)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 946) plus_cst_src = plus_src; +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 947) /* If we are doing initial offset computation, then utilize +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 948) eqivalences to discover a constant for the second term +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 949) of PLUS_SRC. */ +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 950) else if (plus_src && REG_P (XEXP (plus_src, 1))) +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 951) { +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 952) int regno = REGNO (XEXP (plus_src, 1)); +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 953) if (regno < ira_reg_equiv_len +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 954) && ira_reg_equiv[regno].constant != NULL_RTX +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 955) && !replace_p +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 956) && poly_int_rtx_p (ira_reg_equiv[regno].constant, &offset)) +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 957) plus_cst_src = plus_src; +6619b3d4c15cd gcc/lra-eliminations.cc (Jivan Hakobyan 2023-08-23 14:10:30 -0600 958) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 959) /* Check that the first operand of the PLUS is a hard reg or +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 960) the lowpart subreg of one. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 961) if (plus_cst_src) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 962) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 963) rtx reg = XEXP (plus_cst_src, 0); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 964) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 965) if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 966) reg = SUBREG_REG (reg); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 967) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 968) if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 969) plus_cst_src = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 970) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 971) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 972) if (plus_cst_src) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 973) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 974) rtx reg = XEXP (plus_cst_src, 0); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 975) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 976) if (GET_CODE (reg) == SUBREG) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 977) reg = SUBREG_REG (reg); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 978) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 979) if (REG_P (reg) && (ep = get_elimination (reg)) != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 980) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 981) rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx; +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 982) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 983) if (! replace_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 984) { +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 985) if (known_eq (update_sp_offset, 0)) +542773888190e gcc/lra-eliminations.cc (Michael Matz 2024-08-22 17:09:11 +0200 986) offset += (!first_p +542773888190e gcc/lra-eliminations.cc (Michael Matz 2024-08-22 17:09:11 +0200 987) ? ep->offset - ep->previous_offset : ep->offset); +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 988) if (ep->to_rtx == stack_pointer_rtx) +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 989) { +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 990) if (first_p) +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 991) offset -= lra_get_insn_recog_data (insn)->sp_offset; +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 992) else +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 993) offset += update_sp_offset; +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 994) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 995) offset = trunc_int_for_mode (offset, GET_MODE (plus_cst_src)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 996) } +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 997) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 998) if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 999) to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)), to_rtx); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1000) /* If we have a nonzero offset, and the source is already a +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1001) simple REG, the following transformation would increase +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1002) the cost of the insn by replacing a simple REG with (plus +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1003) (reg sp) CST). So try only when we already had a PLUS +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1004) before. */ +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 1005) if (known_eq (offset, 0) || plus_src) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1006) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1007) rtx new_src = plus_constant (GET_MODE (to_rtx), to_rtx, offset); +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 1008) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1009) old_set = single_set (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1010) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1011) /* First see if this insn remains valid when we make the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1012) change. If not, try to replace the whole pattern +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1013) with a simple set (this may help if the original insn +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1014) was a PARALLEL that was only recognized as single_set +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1015) due to REG_UNUSED notes). If this isn't valid +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1016) either, keep the INSN_CODE the same and let the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1017) constraint pass fix it up. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1018) if (! validate_change (insn, &SET_SRC (old_set), new_src, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1019) { +f7df4a840c478 gcc/lra-eliminations.c (Richard Sandiford 2015-05-07 16:58:46 +0000 1020) rtx new_pat = gen_rtx_SET (SET_DEST (old_set), new_src); +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 1021) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1022) if (! validate_change (insn, &PATTERN (insn), new_pat, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1023) SET_SRC (old_set) = new_src; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1024) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1025) lra_update_insn_recog_data (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1026) /* This can't have an effect on elimination offsets, so skip +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1027) right to the end. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1028) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1029) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1030) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1031) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1032) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1033) /* Eliminate all eliminable registers occurring in operands that +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1034) can be handled by the constraint pass. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1035) id = lra_get_insn_recog_data (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1036) static_id = id->insn_static_data; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1037) validate_p = false; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1038) for (i = 0; i < static_id->n_operands; i++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1039) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1040) orig_operand[i] = *id->operand_loc[i]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1041) substed_operand[i] = *id->operand_loc[i]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1042) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1043) /* For an asm statement, every operand is eliminable. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1044) if (icode < 0 || insn_data[icode].operand[i].eliminable) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1045) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1046) /* Check for setting a hard register that we know about. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1047) if (static_id->operand[i].type != OP_IN +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1048) && REG_P (orig_operand[i])) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1049) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1050) /* If we are assigning to a hard register that can be +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1051) eliminated, it must be as part of a PARALLEL, since +67914693144c0 gcc/lra-eliminations.c (Sandra Loosemore 2019-01-09 16:37:45 -0500 1052) the code above handles single SETs. This reg cannot +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1053) be longer eliminated -- it is forced by +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1054) mark_not_eliminable. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1055) for (ep = reg_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1056) ep < ®_eliminate[NUM_ELIMINABLE_REGS]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1057) ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1058) lra_assert (ep->from_rtx != orig_operand[i] +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1059) || ! ep->can_eliminate); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1060) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1061) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1062) /* Companion to the above plus substitution, we can allow +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1063) invariants as the source of a plain move. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1064) substed_operand[i] +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1065) = lra_eliminate_regs_1 (insn, *id->operand_loc[i], VOIDmode, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1066) replace_p, ! replace_p && ! first_p, +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 1067) update_sp_offset, first_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1068) if (substed_operand[i] != orig_operand[i]) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1069) validate_p = true; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1070) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1071) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1072) +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1073) if (! validate_p) +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1074) return; +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1075) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1076) /* Substitute the operands; the new values are in the substed_operand +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1077) array. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1078) for (i = 0; i < static_id->n_operands; i++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1079) *id->operand_loc[i] = substed_operand[i]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1080) for (i = 0; i < static_id->n_dups; i++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1081) *id->dup_loc[i] = substed_operand[(int) static_id->dup_num[i]]; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1082) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1083) /* Transform plus (plus (hard reg, const), pseudo) to plus (plus (pseudo, +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1084) const), hard reg) in order to keep insn containing eliminated register +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1085) after all reloads calculating its offset. This permits to keep register +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1086) pressure under control and helps to avoid LRA cycling in patalogical +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1087) cases. */ +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1088) if (! replace_p && (set = single_set (insn)) != NULL +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1089) && GET_CODE (SET_SRC (set)) == PLUS +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1090) && GET_CODE (XEXP (SET_SRC (set), 0)) == PLUS) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1091) { +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1092) rtx reg1, reg2, op1, op2; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1093) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1094) reg1 = op1 = XEXP (XEXP (SET_SRC (set), 0), 0); +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1095) reg2 = op2 = XEXP (SET_SRC (set), 1); +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1096) if (GET_CODE (reg1) == SUBREG) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1097) reg1 = SUBREG_REG (reg1); +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1098) if (GET_CODE (reg2) == SUBREG) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1099) reg2 = SUBREG_REG (reg2); +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1100) if (REG_P (reg1) && REG_P (reg2) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1101) && REGNO (reg1) < FIRST_PSEUDO_REGISTER +4334b52427420 gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-20 11:40:14 -0500 1102) && REGNO (reg2) >= FIRST_PSEUDO_REGISTER +4334b52427420 gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-20 11:40:14 -0500 1103) && GET_MODE (reg1) == Pmode +68ba1039c7daf gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-21 17:27:01 -0500 1104) && !have_addptr3_insn (lra_pmode_pseudo, reg1, +4334b52427420 gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-20 11:40:14 -0500 1105) XEXP (XEXP (SET_SRC (set), 0), 1))) +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1106) { +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1107) XEXP (XEXP (SET_SRC (set), 0), 0) = op2; +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1108) XEXP (SET_SRC (set), 1) = op1; +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1109) } +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1110) } +cf2ac1c30af0f gcc/lra-eliminations.c (Vladimir N. Makarov 2021-01-12 11:26:15 -0500 1111) +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1112) /* If we had a move insn but now we don't, re-recognize it. +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1113) This will cause spurious re-recognition if the old move had a +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1114) PARALLEL since the new one still will, but we can't call +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1115) single_set without having put new body into the insn and the +2c62cbaaf13c7 gcc/lra-eliminations.c (Vladimir Makarov 2013-04-26 18:11:35 +0000 1116) re-recognition won't hurt in this rare case. */ +8ba6ea878fd09 gcc/lra-eliminations.c (Martin Liska 2019-07-03 10:34:20 +0200 1117) lra_update_insn_recog_data (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1118) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1119) +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1120) /* Spill pseudos which are assigned to hard registers in SET, record them in +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1121) SPILLED_PSEUDOS unless it is null, and return the recorded pseudos number. +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1122) Add affected insns for processing in the subsequent constraint pass. */ +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1123) static int +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1124) spill_pseudos (HARD_REG_SET set, int *spilled_pseudos) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1125) { +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1126) int i, n; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1127) bitmap_head to_process; +cfa434f6d2c4e gcc/lra-eliminations.c (David Malcolm 2014-08-22 18:36:35 +0000 1128) rtx_insn *insn; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1129) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1130) if (hard_reg_set_empty_p (set)) +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1131) return 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1132) if (lra_dump_file != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1133) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1134) fprintf (lra_dump_file, " Spilling non-eliminable hard regs:"); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1135) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1136) if (TEST_HARD_REG_BIT (set, i)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1137) fprintf (lra_dump_file, " %d", i); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1138) fprintf (lra_dump_file, "\n"); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1139) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1140) bitmap_initialize (&to_process, ®_obstack); +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1141) n = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1142) for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1143) if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0 +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1144) && overlaps_hard_reg_set_p (set, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1145) PSEUDO_REGNO_MODE (i), reg_renumber[i])) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1146) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1147) if (lra_dump_file != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1148) fprintf (lra_dump_file, " Spilling r%d(%d)\n", +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1149) i, reg_renumber[i]); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1150) reg_renumber[i] = -1; +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1151) if (spilled_pseudos != NULL) +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1152) spilled_pseudos[n++] = i; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1153) bitmap_ior_into (&to_process, &lra_reg_info[i].insn_bitmap); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1154) } +44942965f4eae gcc/lra-eliminations.c (Richard Sandiford 2019-09-09 17:59:19 +0000 1155) lra_no_alloc_regs |= set; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1156) for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1157) if (bitmap_bit_p (&to_process, INSN_UID (insn))) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1158) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1159) lra_push_insn (insn); +7874b7c5b5992 gcc/lra-eliminations.c (Vladimir Makarov 2018-02-22 21:17:51 +0000 1160) lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1161) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1162) bitmap_clear (&to_process); +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1163) return n; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1164) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1165) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1166) /* Update all offsets and possibility for elimination on eliminable +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1167) registers. Spill pseudos assigned to registers which are +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1168) uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET. Add +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1169) insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1170) registers whose offsets should be changed. Return true if any +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1171) elimination offset changed. */ +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1172) static bool +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1173) update_reg_eliminate (bitmap insns_with_changed_offsets) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1174) { +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1175) bool prev, result; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 1176) class lra_elim_table *ep, *ep1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1177) HARD_REG_SET temp_hard_reg_set; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1178) +29eb9a442b145 gcc/lra-eliminations.c (Bernd Edlinger 2017-05-08 17:44:36 +0000 1179) targetm.compute_frame_layout (); +29eb9a442b145 gcc/lra-eliminations.c (Bernd Edlinger 2017-05-08 17:44:36 +0000 1180) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1181) /* Clear self elimination offsets. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1182) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1183) self_elim_offsets[ep->from] = 0; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1184) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1185) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1186) /* If it is a currently used elimination: update the previous +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1187) offset. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1188) if (elimination_map[ep->from] == ep) +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1189) { +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1190) ep->previous_offset = ep->offset; +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1191) /* Restore the stack_pointer_rtx into to_rtx, that +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1192) lra_update_fp2sp_elimination set to from_rtx, so that the assert +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1193) below still checks what it was supposed to check. */ +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1194) if (ep->from_rtx == ep->to_rtx +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1195) && ep->from != ep->to +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1196) && ep->from == FRAME_POINTER_REGNUM) +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1197) ep->to_rtx = stack_pointer_rtx; +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1198) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1199) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1200) prev = ep->prev_can_eliminate; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1201) setup_can_eliminate (ep, targetm.can_eliminate (ep->from, ep->to)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1202) if (ep->can_eliminate && ! prev) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1203) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1204) /* It is possible that not eliminable register becomes +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1205) eliminable because we took other reasons into account to +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1206) set up eliminable regs in the initial set up. Just +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1207) ignore new eliminable registers. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1208) setup_can_eliminate (ep, false); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1209) continue; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1210) } +2edb50a310896 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-02 20:21:45 -0300 1211) if (!ep->can_eliminate && elimination_map[ep->from] == ep) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1212) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1213) /* We cannot use this elimination anymore -- find another +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1214) one. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1215) if (lra_dump_file != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1216) fprintf (lra_dump_file, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1217) " Elimination %d to %d is not possible anymore\n", +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1218) ep->from, ep->to); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1219) /* If after processing RTL we decides that SP can be used as a result +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1220) of elimination, it cannot be changed. For frame pointer to stack +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1221) pointer elimination the condition is a bit relaxed and we just require +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1222) that actual elimination has not been done yet. */ +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1223) gcc_assert (ep->to_rtx != stack_pointer_rtx +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 1224) || !elimination_2sp_occurred_p +16894253cd152 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-21 20:28:50 -0400 1225) || (ep->from < FIRST_PSEUDO_REGISTER +ddcfa953fc03e gcc/lra-eliminations.c (Jiong Wang 2014-11-18 09:30:08 +0000 1226) && fixed_regs [ep->from])); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1227) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1228) /* Mark that is not eliminable anymore. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1229) elimination_map[ep->from] = NULL; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1230) for (ep1 = ep + 1; ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]; ep1++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1231) if (ep1->can_eliminate && ep1->from == ep->from) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1232) break; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1233) if (ep1 < ®_eliminate[NUM_ELIMINABLE_REGS]) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1234) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1235) if (lra_dump_file != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1236) fprintf (lra_dump_file, " Using elimination %d to %d now\n", +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1237) ep1->from, ep1->to); +542773888190e gcc/lra-eliminations.cc (Michael Matz 2024-08-22 17:09:11 +0200 1238) lra_assert (known_eq (ep1->previous_offset, -1)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1239) ep1->previous_offset = ep->offset; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1240) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1241) else +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1242) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1243) /* There is no elimination anymore just use the hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1244) register `from' itself. Setup self elimination +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1245) offset to restore the original offset values. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1246) if (lra_dump_file != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1247) fprintf (lra_dump_file, " %d is not eliminable at all\n", +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1248) ep->from); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1249) self_elim_offsets[ep->from] = -ep->offset; +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 1250) if (maybe_ne (ep->offset, 0)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1251) bitmap_ior_into (insns_with_changed_offsets, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1252) &lra_reg_info[ep->from].insn_bitmap); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1253) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1254) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1255) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1256) INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->offset); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1257) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1258) setup_elimination_map (); +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1259) result = false; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1260) CLEAR_HARD_REG_SET (temp_hard_reg_set); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1261) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1262) if (elimination_map[ep->from] == NULL) +764df76cb2dc6 gcc/lra-eliminations.c (Dimitar Dimitrov 2018-06-28 03:43:48 +0000 1263) add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->from); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1264) else if (elimination_map[ep->from] == ep) +d70a81dddc916 gcc/lra-eliminations.c (Shiva Chen 2013-04-23 17:38:59 +0000 1265) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1266) /* Prevent the hard register into which we eliminate from +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1267) the usage for pseudos. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1268) if (ep->from != ep->to) +764df76cb2dc6 gcc/lra-eliminations.c (Dimitar Dimitrov 2018-06-28 03:43:48 +0000 1269) add_to_hard_reg_set (&temp_hard_reg_set, Pmode, ep->to); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 1270) if (maybe_ne (ep->previous_offset, ep->offset)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1271) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1272) bitmap_ior_into (insns_with_changed_offsets, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1273) &lra_reg_info[ep->from].insn_bitmap); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1274) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1275) /* Update offset when the eliminate offset have been +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1276) changed. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1277) lra_update_reg_val_offset (lra_reg_info[ep->from].val, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1278) ep->offset - ep->previous_offset); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1279) result = true; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1280) } +d70a81dddc916 gcc/lra-eliminations.c (Shiva Chen 2013-04-23 17:38:59 +0000 1281) } +44942965f4eae gcc/lra-eliminations.c (Richard Sandiford 2019-09-09 17:59:19 +0000 1282) lra_no_alloc_regs |= temp_hard_reg_set; +d15e5131845e2 gcc/lra-eliminations.c (Richard Sandiford 2019-09-09 17:59:25 +0000 1283) eliminable_regset &= ~temp_hard_reg_set; +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1284) spill_pseudos (temp_hard_reg_set, NULL); +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1285) return result; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1286) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1287) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1288) /* Initialize the table of hard registers to eliminate. +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1289) Pre-condition: global flag frame_pointer_needed has been set before +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1290) calling this function. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1291) static void +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1292) init_elim_table (void) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1293) { +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 1294) class lra_elim_table *ep; +522d4efcd3bda gcc/lra-eliminations.c (Jan-Benedict Glaw 2013-09-27 20:20:35 +0000 1295) bool value_p; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1296) const struct elim_table_1 *ep1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1297) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1298) if (!reg_eliminate) +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 1299) reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1300) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1301) memset (self_elim_offsets, 0, sizeof (self_elim_offsets)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1302) /* Initiate member values which will be never changed. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1303) self_elim_table.can_eliminate = self_elim_table.prev_can_eliminate = true; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1304) self_elim_table.previous_offset = 0; +5368023839d4b gcc/lra-eliminations.c (Bernd Edlinger 2016-09-09 23:08:54 +0000 1305) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1306) for (ep = reg_eliminate, ep1 = reg_eliminate_1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1307) ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1308) { +542773888190e gcc/lra-eliminations.cc (Michael Matz 2024-08-22 17:09:11 +0200 1309) ep->offset = ep->previous_offset = -1; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1310) ep->from = ep1->from; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1311) ep->to = ep1->to; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1312) value_p = (targetm.can_eliminate (ep->from, ep->to) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1313) && ! (ep->to == STACK_POINTER_REGNUM +f4eafc3059ff4 gcc/lra-eliminations.c (H.J. Lu 2012-10-29 21:56:35 +0000 1314) && frame_pointer_needed +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1315) && (! SUPPORTS_STACK_ALIGNMENT +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1316) || ! stack_realign_fp))); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1317) setup_can_eliminate (ep, value_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1318) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1319) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1320) /* Build the FROM and TO REG rtx's. Note that code in gen_rtx_REG +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1321) will cause, e.g., gen_rtx_REG (Pmode, STACK_POINTER_REGNUM) to +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1322) equal stack_pointer_rtx. We depend on this. Threfore we switch +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1323) off that we are in LRA temporarily. */ +0c8ecbcd3cf7d gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-09-28 09:41:18 -0400 1324) lra_in_progress = false; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1325) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1326) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1327) ep->from_rtx = gen_rtx_REG (Pmode, ep->from); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1328) ep->to_rtx = gen_rtx_REG (Pmode, ep->to); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1329) eliminable_reg_rtx[ep->from] = ep->from_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1330) } +0c8ecbcd3cf7d gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-09-28 09:41:18 -0400 1331) lra_in_progress = true; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1332) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1333) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1334) /* Function for initialization of elimination once per function. It +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1335) sets up sp offset for each insn. */ +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1336) static void +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1337) init_elimination (void) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1338) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1339) bool stop_to_sp_elimination_p; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1340) basic_block bb; +cfa434f6d2c4e gcc/lra-eliminations.c (David Malcolm 2014-08-22 18:36:35 +0000 1341) rtx_insn *insn; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 1342) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1343) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1344) init_elim_table (); +11cd3bed28f13 gcc/lra-eliminations.c (David Malcolm 2013-12-09 21:06:06 +0000 1345) FOR_EACH_BB_FN (bb, cfun) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1346) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1347) curr_sp_change = 0; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1348) stop_to_sp_elimination_p = false; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1349) FOR_BB_INSNS (bb, insn) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1350) if (INSN_P (insn)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1351) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1352) lra_get_insn_recog_data (insn)->sp_offset = curr_sp_change; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1353) if (NONDEBUG_INSN_P (insn)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1354) { +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1355) mark_not_eliminable (PATTERN (insn), VOIDmode); +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 1356) if (maybe_ne (curr_sp_change, 0) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1357) && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX)) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1358) stop_to_sp_elimination_p = true; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1359) } +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1360) } +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1361) if (! frame_pointer_needed +73ca989cb823c gcc/lra-eliminations.c (Richard Sandiford 2017-12-20 12:53:35 +0000 1362) && (maybe_ne (curr_sp_change, 0) || stop_to_sp_elimination_p) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1363) && bb->succs && bb->succs->length () != 0) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1364) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1365) if (ep->to == STACK_POINTER_REGNUM) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1366) setup_can_eliminate (ep, false); +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1367) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1368) setup_elimination_map (); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1369) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1370) +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1371) /* Update and return stack pointer OFFSET after processing X. */ +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1372) poly_int64 +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1373) lra_update_sp_offset (rtx x, poly_int64 offset) +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1374) { +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1375) curr_sp_change = offset; +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1376) mark_not_eliminable (x, VOIDmode); +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1377) return curr_sp_change; +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1378) } +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1379) +30038a207c10a gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-05-30 15:54:28 -0400 1380) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1381) /* Eliminate hard reg given by its location LOC. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1382) void +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1383) lra_eliminate_reg_if_possible (rtx *loc) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1384) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1385) int regno; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 1386) class lra_elim_table *ep; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1387) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1388) lra_assert (REG_P (*loc)); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1389) if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1390) || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1391) return; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1392) if ((ep = get_elimination (*loc)) != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1393) *loc = ep->to_rtx; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1394) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1395) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1396) /* Do (final if FINAL_P or first if FIRST_P) elimination in INSN. Add +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1397) the insn for subsequent processing in the constraint pass, update +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1398) the insn info. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1399) static void +cfa434f6d2c4e gcc/lra-eliminations.c (David Malcolm 2014-08-22 18:36:35 +0000 1400) process_insn_for_elimination (rtx_insn *insn, bool final_p, bool first_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1401) { +d9cf932c33070 gcc/lra-eliminations.c (Vladimir Makarov 2014-11-13 03:02:49 +0000 1402) eliminate_regs_in_insn (insn, final_p, first_p, 0); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1403) if (! final_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1404) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1405) /* Check that insn changed its code. This is a case when a move +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1406) insn becomes an add insn and we do not want to process the +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1407) insn as a move anymore. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1408) int icode = recog (PATTERN (insn), insn, 0); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1409) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1410) if (icode >= 0 && icode != INSN_CODE (insn)) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1411) { +7436a1c6750d1 gcc/lra-eliminations.c (Vladimir Makarov 2019-12-10 22:07:57 +0000 1412) if (INSN_CODE (insn) >= 0) +7436a1c6750d1 gcc/lra-eliminations.c (Vladimir Makarov 2019-12-10 22:07:57 +0000 1413) /* Insn code is changed. It may change its operand type +7436a1c6750d1 gcc/lra-eliminations.c (Vladimir Makarov 2019-12-10 22:07:57 +0000 1414) from IN to INOUT. Inform the subsequent assignment +7436a1c6750d1 gcc/lra-eliminations.c (Vladimir Makarov 2019-12-10 22:07:57 +0000 1415) subpass about this situation. */ +7436a1c6750d1 gcc/lra-eliminations.c (Vladimir Makarov 2019-12-10 22:07:57 +0000 1416) check_and_force_assignment_correctness_p = true; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1417) INSN_CODE (insn) = icode; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1418) lra_update_insn_recog_data (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1419) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1420) lra_update_insn_regno_info (insn); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1421) lra_push_insn (insn); +7874b7c5b5992 gcc/lra-eliminations.c (Vladimir Makarov 2018-02-22 21:17:51 +0000 1422) lra_set_used_insn_alternative (insn, LRA_UNKNOWN_ALT); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1423) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1424) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1425) +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1426) /* Update frame pointer to stack pointer elimination if we started with +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1427) permitted frame pointer elimination and now target reports that we can not +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1428) do this elimination anymore. Record spilled pseudos in SPILLED_PSEUDOS +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1429) unless it is null, and return the recorded pseudos number. */ +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1430) int +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1431) lra_update_fp2sp_elimination (int *spilled_pseudos) +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1432) { +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1433) int n; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1434) HARD_REG_SET set; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1435) class lra_elim_table *ep; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1436) +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1437) if (frame_pointer_needed || !targetm.frame_pointer_required ()) +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1438) return 0; +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 1439) gcc_assert (!elimination_2sp_occurred_p); +7ce8a87f78122 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:19 -0300 1440) ep = elimination_map[FRAME_POINTER_REGNUM]; +7ce8a87f78122 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:19 -0300 1441) if (ep->to == STACK_POINTER_REGNUM) +7ce8a87f78122 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:19 -0300 1442) { +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1443) /* Prevent any further uses of fp, say in spill addresses, from being +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1444) eliminated to sp and affected by sp offsets. Alas, deactivating the +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1445) elimination altogether causes the next chosen fp elimination to miss +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1446) the offset propagation, so it may keep -1 as its prev_offset, and that +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1447) will make subsequent offsets incorrect. */ +b49473448966b gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:24 -0300 1448) ep->to_rtx = ep->from_rtx; +7ce8a87f78122 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:19 -0300 1449) setup_can_eliminate (ep, false); +7ce8a87f78122 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:19 -0300 1450) } +7ce8a87f78122 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:19 -0300 1451) else +66b6da3b66ed0 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:26 -0300 1452) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +66b6da3b66ed0 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:26 -0300 1453) if (ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) +66b6da3b66ed0 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:26 -0300 1454) setup_can_eliminate (ep, false); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1455) if (lra_dump_file != NULL) +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1456) fprintf (lra_dump_file, +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1457) " Frame pointer can not be eliminated anymore\n"); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1458) frame_pointer_needed = true; +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1459) /* If !lra_reg_spill_p, we likely have incomplete range information +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1460) for pseudos assigned to the frame pointer that will have to be +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1461) spilled, and so we may end up incorrectly sharing them unless we +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1462) get live range information for them. */ +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1463) if (lra_complete_live_ranges ()) +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1464) /* If lives ranges changed, update the aggregate live ranges in +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1465) slots as well before spilling any further pseudos. */ +be547188b632d gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:22 -0300 1466) lra_recompute_slots_live_ranges (); +66b6da3b66ed0 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:26 -0300 1467) CLEAR_HARD_REG_SET (set); +66b6da3b66ed0 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:26 -0300 1468) add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1469) n = spill_pseudos (set, spilled_pseudos); +3452652236aa7 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-08-16 09:13:54 -0400 1470) return n; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1471) } +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1472) +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1473) /* Return true if we have a pseudo assigned to hard frame pointer. */ +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1474) bool +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1475) lra_fp_pseudo_p (void) +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1476) { +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1477) HARD_REG_SET set; +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1478) +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1479) if (frame_pointer_needed) +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1480) /* At this stage it means we have no pseudos assigned to FP: */ +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1481) return false; +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1482) CLEAR_HARD_REG_SET (set); +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1483) add_to_hard_reg_set (&set, Pmode, HARD_FRAME_POINTER_REGNUM); +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1484) for (int i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++) +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1485) if (lra_reg_info[i].nrefs != 0 && reg_renumber[i] >= 0 +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1486) && overlaps_hard_reg_set_p (set, PSEUDO_REGNO_MODE (i), +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1487) reg_renumber[i])) +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1488) return true; +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1489) return false; +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1490) } +fca0ab08cd936 gcc/lra-eliminations.cc (Vladimir N. Makarov 2024-12-11 15:36:21 -0500 1491) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1492) /* Entry function to do final elimination if FINAL_P or to update +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1493) elimination register offsets (FIRST_P if we are doing it the first +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1494) time). */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1495) void +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1496) lra_eliminate (bool final_p, bool first_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1497) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1498) unsigned int uid; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1499) bitmap_head insns_with_changed_offsets; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1500) bitmap_iterator bi; +99b1c316ec974 gcc/lra-eliminations.c (Martin Sebor 2019-07-09 18:32:49 +0000 1501) class lra_elim_table *ep; +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1502) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1503) gcc_assert (! final_p || ! first_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1504) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1505) timevar_push (TV_LRA_ELIMINATE); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1506) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1507) if (first_p) +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1508) { +f9a6efa7a71e8 gcc/lra-eliminations.cc (Alexandre Oliva 2025-06-26 21:01:29 -0300 1509) elimination_2sp_occurred_p = false; +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1510) init_elimination (); +2971ff7b1d564 gcc/lra-eliminations.cc (Vladimir N. Makarov 2023-07-19 09:35:37 -0400 1511) } +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1512) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1513) bitmap_initialize (&insns_with_changed_offsets, ®_obstack); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1514) if (final_p) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1515) { +b2b293775a27c gcc/lra-eliminations.c (Mikhail Maltsev 2015-10-28 01:05:53 +0000 1516) if (flag_checking) +b2b293775a27c gcc/lra-eliminations.c (Mikhail Maltsev 2015-10-28 01:05:53 +0000 1517) { +b2b293775a27c gcc/lra-eliminations.c (Mikhail Maltsev 2015-10-28 01:05:53 +0000 1518) update_reg_eliminate (&insns_with_changed_offsets); +b2b293775a27c gcc/lra-eliminations.c (Mikhail Maltsev 2015-10-28 01:05:53 +0000 1519) gcc_assert (bitmap_empty_p (&insns_with_changed_offsets)); +b2b293775a27c gcc/lra-eliminations.c (Mikhail Maltsev 2015-10-28 01:05:53 +0000 1520) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1521) /* We change eliminable hard registers in insns so we should do +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1522) this for all insns containing any eliminable hard +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1523) register. */ +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1524) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1525) if (elimination_map[ep->from] != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1526) bitmap_ior_into (&insns_with_changed_offsets, +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1527) &lra_reg_info[ep->from].insn_bitmap); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1528) } +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1529) else if (! update_reg_eliminate (&insns_with_changed_offsets)) +5a107a0f0cdf9 gcc/lra-eliminations.c (Vladimir Makarov 2013-05-07 19:29:05 +0000 1530) goto lra_eliminate_done; +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1531) if (lra_dump_file != NULL) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1532) { +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1533) fprintf (lra_dump_file, "New elimination table:\n"); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1534) print_elim_table (lra_dump_file); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1535) } +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1536) EXECUTE_IF_SET_IN_BITMAP (&insns_with_changed_offsets, 0, uid, bi) +80f466c4a620c gcc/lra-eliminations.c (Vladimir Makarov 2013-10-03 00:35:43 +0000 1537) /* A dead insn can be deleted in process_insn_for_elimination. */ +80f466c4a620c gcc/lra-eliminations.c (Vladimir Makarov 2013-10-03 00:35:43 +0000 1538) if (lra_insn_recog_data[uid] != NULL) +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1539) process_insn_for_elimination (lra_insn_recog_data[uid]->insn, +8d49e7ef0a184 gcc/lra-eliminations.c (Vladimir Makarov 2013-11-28 21:45:21 +0000 1540) final_p, first_p); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1541) bitmap_clear (&insns_with_changed_offsets); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1542) +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1543) lra_eliminate_done: +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1544) timevar_pop (TV_LRA_ELIMINATE); +55a2c3226a3e9 gcc/lra-eliminations.c (Vladimir Makarov 2012-10-23 15:51:41 +0000 1545) } diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 9695fdc..80b3b78 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -2088,10 +2088,10 @@ [(set_attr "type" "vfdiv")] ) -;; vfmin.vf -(define_insn_and_split "*vfmin_vf_<mode>" +;; vfmin.vf, vfmax.vf +(define_insn_and_split "*vf<optab>_vf_<mode>" [(set (match_operand:V_VLSF 0 "register_operand") - (smin:V_VLSF + (commutative_float_binop_nofrm:V_VLSF (vec_duplicate:V_VLSF (match_operand:<VEL> 2 "register_operand")) (match_operand:V_VLSF 1 "register_operand")))] @@ -2100,7 +2100,7 @@ "&& 1" [(const_int 0)] { - riscv_vector::emit_vlmax_insn (code_for_pred_scalar (SMIN, <MODE>mode), + riscv_vector::emit_vlmax_insn (code_for_pred_scalar (<CODE>, <MODE>mode), riscv_vector::BINARY_OP, operands); DONE; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-2.c index 8dc5a31..fd11835 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-2.c @@ -39,5 +39,5 @@ DEF_MINMAX_VX (max, 128, double, >) DEF_MINMAX_VX (max, 256, double, >) DEF_MINMAX_VX (max, 512, double, >) -/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 30 } } */ +/* { dg-final { scan-assembler-times {vfmax\.vf\s+v[0-9]+,\s*v[0-9]+,\s*f[ast]?[0-9]+} 30 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-4.c index db3bf86..eb0edac 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls/floating-point-max-4.c @@ -39,5 +39,5 @@ DEF_MINMAX_VX (max, 128, double, >=) DEF_MINMAX_VX (max, 256, double, >=) DEF_MINMAX_VX (max, 512, double, >=) -/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 30 } } */ +/* { dg-final { scan-assembler-times {vfmax\.vf\s+v[0-9]+,\s*v[0-9]+,\s*f[ast]?[0-9]+} 30 } } */ /* { dg-final { scan-assembler-not {csrr} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c index 7e56330..0be64f1 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f16.c @@ -20,6 +20,8 @@ DEF_VF_BINOP_CASE_0 (_Float16, *, mul) DEF_VF_BINOP_REVERSE_CASE_0 (_Float16, /, rdiv) DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_0_WRAP (_Float16), min) DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_1_WRAP (_Float16), min) +DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_0_WRAP (_Float16), max) +DEF_VF_BINOP_CASE_2_WRAP (_Float16, MAX_FUNC_1_WRAP (_Float16), max) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ @@ -33,5 +35,7 @@ DEF_VF_BINOP_CASE_2_WRAP (_Float16, MIN_FUNC_1_WRAP (_Float16), min) /* { dg-final { scan-assembler-times {vfwmsac.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfwnmacc.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfwnmsac.vf} 1 } } */ +/* { dg-final { scan-assembler-times {vfmul.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfrdiv.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmin.vf} 2 } } */ +/* { dg-final { scan-assembler-times {vfmax.vf} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c index e674cf7..a9cd38a 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f32.c @@ -20,6 +20,8 @@ DEF_VF_BINOP_CASE_0 (float, *, mul) DEF_VF_BINOP_REVERSE_CASE_0 (float, /, rdiv) DEF_VF_BINOP_CASE_2_WRAP (float, MIN_FUNC_0_WRAP (float), min) DEF_VF_BINOP_CASE_2_WRAP (float, MIN_FUNC_1_WRAP (float), min) +DEF_VF_BINOP_CASE_2_WRAP (float, MAX_FUNC_0_WRAP (float), max) +DEF_VF_BINOP_CASE_2_WRAP (float, MAX_FUNC_1_WRAP (float), max) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ @@ -36,3 +38,4 @@ DEF_VF_BINOP_CASE_2_WRAP (float, MIN_FUNC_1_WRAP (float), min) /* { dg-final { scan-assembler-times {vfmul.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfrdiv.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmin.vf} 2 } } */ +/* { dg-final { scan-assembler-times {vfmax.vf} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c index b36e966..4eb4a4e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-1-f64.c @@ -16,6 +16,8 @@ DEF_VF_BINOP_CASE_0 (double, *, mul) DEF_VF_BINOP_REVERSE_CASE_0 (double, /, rdiv) DEF_VF_BINOP_CASE_2_WRAP (double, MIN_FUNC_0_WRAP (double), min) DEF_VF_BINOP_CASE_2_WRAP (double, MIN_FUNC_1_WRAP (double), min) +DEF_VF_BINOP_CASE_2_WRAP (double, MAX_FUNC_0_WRAP (double), max) +DEF_VF_BINOP_CASE_2_WRAP (double, MAX_FUNC_1_WRAP (double), max) /* { dg-final { scan-assembler-times {vfmadd.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmsub.vf} 1 } } */ @@ -28,3 +30,4 @@ DEF_VF_BINOP_CASE_2_WRAP (double, MIN_FUNC_1_WRAP (double), min) /* { dg-final { scan-assembler-times {vfmul.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfrdiv.vf} 1 } } */ /* { dg-final { scan-assembler-times {vfmin.vf} 2 } } */ +/* { dg-final { scan-assembler-times {vfmax.vf} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c index 1914b18..0db3048 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f16.c @@ -18,4 +18,5 @@ /* { dg-final { scan-assembler-not {vfmul.vf} } } */ /* { dg-final { scan-assembler-not {vfrdiv.vf} } } */ /* { dg-final { scan-assembler-not {vfmin.vf} } } */ +/* { dg-final { scan-assembler-not {vfmax.vf} } } */ /* { dg-final { scan-assembler-times {fcvt.s.h} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c index f8dab37..494b33e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f32.c @@ -18,4 +18,5 @@ /* { dg-final { scan-assembler-not {vfmul.vf} } } */ /* { dg-final { scan-assembler-not {vfrdiv.vf} } } */ /* { dg-final { scan-assembler-not {vfmin.vf} } } */ +/* { dg-final { scan-assembler-not {vfmax.vf} } } */ /* { dg-final { scan-assembler-times {fcvt.d.s} 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c index 909770f..ffffde7 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-2-f64.c @@ -14,3 +14,4 @@ /* { dg-final { scan-assembler-not {vfmul.vf} } } */ /* { dg-final { scan-assembler-not {vfrdiv.vf} } } */ /* { dg-final { scan-assembler-not {vfmin.vf} } } */ +/* { dg-final { scan-assembler-not {vfmax.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c index c703ed6..c2c4f43 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f16.c @@ -22,6 +22,10 @@ DEF_VF_BINOP_CASE_3_WRAP (_Float16, MIN_FUNC_0_WRAP (_Float16), min, VF_BINOP_FUNC_BODY_X128) DEF_VF_BINOP_CASE_3_WRAP (_Float16, MIN_FUNC_1_WRAP (_Float16), min, VF_BINOP_FUNC_BODY_X128) +DEF_VF_BINOP_CASE_3_WRAP (_Float16, MAX_FUNC_0_WRAP (_Float16), max, + VF_BINOP_FUNC_BODY_X128) +DEF_VF_BINOP_CASE_3_WRAP (_Float16, MAX_FUNC_1_WRAP (_Float16), max, + VF_BINOP_FUNC_BODY_X128) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ @@ -38,3 +42,4 @@ DEF_VF_BINOP_CASE_3_WRAP (_Float16, MIN_FUNC_1_WRAP (_Float16), min, /* { dg-final { scan-assembler {vfmul.vf} } } */ /* { dg-final { scan-assembler {vfrdiv.vf} } } */ /* { dg-final { scan-assembler {vfmin.vf} } } */ +/* { dg-final { scan-assembler {vfmax.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c index 99b84dd..f2582ca 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f32.c @@ -22,6 +22,10 @@ DEF_VF_BINOP_CASE_3_WRAP (float, MIN_FUNC_0_WRAP (float), min, VF_BINOP_FUNC_BODY_X128) DEF_VF_BINOP_CASE_3_WRAP (float, MIN_FUNC_1_WRAP (float), min, VF_BINOP_FUNC_BODY_X128) +DEF_VF_BINOP_CASE_3_WRAP (float, MAX_FUNC_0_WRAP (float), max, + VF_BINOP_FUNC_BODY_X128) +DEF_VF_BINOP_CASE_3_WRAP (float, MAX_FUNC_1_WRAP (float), max, + VF_BINOP_FUNC_BODY_X128) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ @@ -38,3 +42,4 @@ DEF_VF_BINOP_CASE_3_WRAP (float, MIN_FUNC_1_WRAP (float), min, /* { dg-final { scan-assembler {vfmul.vf} } } */ /* { dg-final { scan-assembler {vfrdiv.vf} } } */ /* { dg-final { scan-assembler {vfmin.vf} } } */ +/* { dg-final { scan-assembler {vfmax.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c index 889fed2..831646f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-3-f64.c @@ -18,6 +18,10 @@ DEF_VF_BINOP_CASE_3_WRAP (double, MIN_FUNC_0_WRAP (double), min, VF_BINOP_FUNC_BODY_X128) DEF_VF_BINOP_CASE_3_WRAP (double, MIN_FUNC_1_WRAP (double), min, VF_BINOP_FUNC_BODY_X128) +DEF_VF_BINOP_CASE_3_WRAP (double, MAX_FUNC_0_WRAP (double), max, + VF_BINOP_FUNC_BODY_X128) +DEF_VF_BINOP_CASE_3_WRAP (double, MAX_FUNC_1_WRAP (double), max, + VF_BINOP_FUNC_BODY_X128) /* { dg-final { scan-assembler {vfmadd.vf} } } */ /* { dg-final { scan-assembler {vfmsub.vf} } } */ @@ -30,3 +34,4 @@ DEF_VF_BINOP_CASE_3_WRAP (double, MIN_FUNC_1_WRAP (double), min, /* { dg-final { scan-assembler {vfmul.vf} } } */ /* { dg-final { scan-assembler {vfrdiv.vf} } } */ /* { dg-final { scan-assembler {vfmin.vf} } } */ +/* { dg-final { scan-assembler {vfmax.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c index 9db8736..3fa3150 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f16.c @@ -18,4 +18,5 @@ /* { dg-final { scan-assembler-not {vfmul.vf} } } */ /* { dg-final { scan-assembler-not {vfrdiv.vf} } } */ /* { dg-final { scan-assembler-not {vfmin.vf} } } */ +/* { dg-final { scan-assembler-not {vfmax.vf} } } */ /* { dg-final { scan-assembler {fcvt.s.h} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c index 577ad8d..3d526b5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f32.c @@ -18,4 +18,5 @@ /* { dg-final { scan-assembler-not {vfmul.vf} } } */ /* { dg-final { scan-assembler-not {vfrdiv.vf} } } */ /* { dg-final { scan-assembler-not {vfmin.vf} } } */ +/* { dg-final { scan-assembler-not {vfmax.vf} } } */ /* { dg-final { scan-assembler {fcvt.d.s} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c index 30e5660..d29006e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf-4-f64.c @@ -14,3 +14,4 @@ /* { dg-final { scan-assembler-not {vfmul.vf} } } */ /* { dg-final { scan-assembler-not {vfrdiv.vf} } } */ /* { dg-final { scan-assembler-not {vfmin.vf} } } */ +/* { dg-final { scan-assembler-not {vfmax.vf} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h index 90436a2..da02065 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop.h @@ -130,6 +130,12 @@ #define DEF_MIN_1(T) \ static inline T test_##T##_min_1 (T a, T b) { return a >= b ? b : a; } +#define DEF_MAX_0(T) \ + static inline T test_##T##_max_0 (T a, T b) { return a > b ? a : b; } + +#define DEF_MAX_1(T) \ + static inline T test_##T##_max_1 (T a, T b) { return a >= b ? a : b; } + DEF_MIN_0 (_Float16) DEF_MIN_0 (float) DEF_MIN_0 (double) @@ -138,12 +144,26 @@ DEF_MIN_1 (_Float16) DEF_MIN_1 (float) DEF_MIN_1 (double) +DEF_MAX_0 (_Float16) +DEF_MAX_0 (float) +DEF_MAX_0 (double) + +DEF_MAX_1 (_Float16) +DEF_MAX_1 (float) +DEF_MAX_1 (double) + #define MIN_FUNC_0(T) test_##T##_min_0 #define MIN_FUNC_0_WRAP(T) MIN_FUNC_0 (T) #define MIN_FUNC_1(T) test_##T##_min_1 #define MIN_FUNC_1_WRAP(T) MIN_FUNC_1 (T) +#define MAX_FUNC_0(T) test_##T##_max_0 +#define MAX_FUNC_0_WRAP(T) MAX_FUNC_0 (T) + +#define MAX_FUNC_1(T) test_##T##_max_1 +#define MAX_FUNC_1_WRAP(T) MAX_FUNC_1 (T) + #define DEF_VF_BINOP_CASE_2(T, FUNC, NAME) \ void test_vf_binop_##NAME##_##FUNC##_##T##_case_2 (T *restrict out, \ T *restrict in, T f, \ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h index e6ddd1e..2f79cee 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_binop_data.h @@ -447,5 +447,151 @@ double TEST_BINOP_DATA(double, min)[][4][N] = }, }, }; +_Float16 TEST_BINOP_DATA(_Float16, max)[][4][N] = +{ + { + { 0x1.e000000000000p+4f16 }, + { + 0x1.8fc0000000000p+4f16, 0x1.8fc0000000000p+4f16, 0x1.8fc0000000000p+4f16, 0x1.8fc0000000000p+4f16, + 0x1.b880000000000p+6f16, 0x1.b880000000000p+6f16, 0x1.b880000000000p+6f16, 0x1.b880000000000p+6f16, + 0x1.a4c0000000000p+5f16, 0x1.a4c0000000000p+5f16, 0x1.a4c0000000000p+5f16, 0x1.a4c0000000000p+5f16, + 0x1.6f80000000000p+4f16, 0x1.6f80000000000p+4f16, 0x1.6f80000000000p+4f16, 0x1.6f80000000000p+4f16, + }, + { + 0x1.e000000000000p+4f16, 0x1.e000000000000p+4f16, 0x1.e000000000000p+4f16, 0x1.e000000000000p+4f16, + 0x1.b880000000000p+6f16, 0x1.b880000000000p+6f16, 0x1.b880000000000p+6f16, 0x1.b880000000000p+6f16, + 0x1.a4c0000000000p+5f16, 0x1.a4c0000000000p+5f16, 0x1.a4c0000000000p+5f16, 0x1.a4c0000000000p+5f16, + 0x1.e000000000000p+4f16, 0x1.e000000000000p+4f16, 0x1.e000000000000p+4f16, 0x1.e000000000000p+4f16, + }, + }, + { + { -0x1.e000000000000p+4f16 }, + { + -0x1.53c0000000000p+5f16, -0x1.53c0000000000p+5f16, -0x1.53c0000000000p+5f16, -0x1.53c0000000000p+5f16, + 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, + -0x1.ffc0000000000p+7f16, -0x1.ffc0000000000p+7f16, -0x1.ffc0000000000p+7f16, -0x1.ffc0000000000p+7f16, + -0x1.94c0000000000p+6f16, -0x1.94c0000000000p+6f16, -0x1.94c0000000000p+6f16, -0x1.94c0000000000p+6f16, + }, + { + -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, + 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, + -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, + -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, -0x1.e000000000000p+4f16, + }, + }, + { + { -0x0.0p+0f16 }, + { + -0x1.53c0000000000p+5f16, -0x1.53c0000000000p+5f16, -0x1.53c0000000000p+5f16, -0x1.53c0000000000p+5f16, + 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, + -0x1.ffc0000000000p+7f16, -0x1.ffc0000000000p+7f16, -0x1.ffc0000000000p+7f16, -0x1.ffc0000000000p+7f16, + -0x1.94c0000000000p+6f16, -0x1.94c0000000000p+6f16, -0x1.94c0000000000p+6f16, -0x1.94c0000000000p+6f16, + }, + { + -0x0.0p+0f16, -0x0.0p+0f16, -0x0.0p+0f16, -0x0.0p+0f16, + 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, 0x1.c300000000000p+6f16, + -0x0.0p+0f16, -0x0.0p+0f16, -0x0.0p+0f16, -0x0.0p+0f16, + -0x0.0p+0f16, -0x0.0p+0f16, -0x0.0p+0f16, -0x0.0p+0f16, + }, + }, +}; + +float TEST_BINOP_DATA(float, max)[][4][N] = +{ + { + { 0x1.4d11200000000p+61f }, + { + 0x1.8fe1540000000p+60f, 0x1.8fe1540000000p+60f, 0x1.8fe1540000000p+60f, 0x1.8fe1540000000p+60f, + 0x1.b8b5320000000p+62f, 0x1.b8b5320000000p+62f, 0x1.b8b5320000000p+62f, 0x1.b8b5320000000p+62f, + 0x1.a4eb340000000p+61f, 0x1.a4eb340000000p+61f, 0x1.a4eb340000000p+61f, 0x1.a4eb340000000p+61f, + 0x1.6faeda0000000p+60f, 0x1.6faeda0000000p+60f, 0x1.6faeda0000000p+60f, 0x1.6faeda0000000p+60f, + }, + { + 0x1.4d11200000000p+61f, 0x1.4d11200000000p+61f, 0x1.4d11200000000p+61f, 0x1.4d11200000000p+61f, + 0x1.b8b5320000000p+62f, 0x1.b8b5320000000p+62f, 0x1.b8b5320000000p+62f, 0x1.b8b5320000000p+62f, + 0x1.a4eb340000000p+61f, 0x1.a4eb340000000p+61f, 0x1.a4eb340000000p+61f, 0x1.a4eb340000000p+61f, + 0x1.4d11200000000p+61f, 0x1.4d11200000000p+61f, 0x1.4d11200000000p+61f, 0x1.4d11200000000p+61f, + }, + }, + { + { 0x1.0000000000000p+0f }, + { + -0x1.53e0ba0000000p+61f, -0x1.53e0ba0000000p+61f, -0x1.53e0ba0000000p+61f, -0x1.53e0ba0000000p+61f, + 0x1.c3397c0000000p+62f, 0x1.c3397c0000000p+62f, 0x1.c3397c0000000p+62f, 0x1.c3397c0000000p+62f, + -0x1.ffe2020000000p+63f, -0x1.ffe2020000000p+63f, -0x1.ffe2020000000p+63f, -0x1.ffe2020000000p+63f, + -0x1.94d2a80000000p+62f, -0x1.94d2a80000000p+62f, -0x1.94d2a80000000p+62f, -0x1.94d2a80000000p+62f, + }, + { + 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, + 0x1.c3397c0000000p+62f, 0x1.c3397c0000000p+62f, 0x1.c3397c0000000p+62f, 0x1.c3397c0000000p+62f, + 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, + 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, 0x1.0000000000000p+0f, + }, + }, + { + { -0x0.0p+0f }, + { + -0x1.062a340000000p+61f, -0x1.062a340000000p+61f, -0x1.062a340000000p+61f, -0x1.062a340000000p+61f, + -0x1.e573960000000p+63f, -0x1.e573960000000p+63f, -0x1.e573960000000p+63f, -0x1.e573960000000p+63f, + 0x1.96d5c20000000p+60f, 0x1.96d5c20000000p+60f, 0x1.96d5c20000000p+60f, 0x1.96d5c20000000p+60f, + -0x1.08eb620000000p+61f, -0x1.08eb620000000p+61f, -0x1.08eb620000000p+61f, -0x1.08eb620000000p+61f, + }, + { + -0x0.0p+0f, -0x0.0p+0f, -0x0.0p+0f, -0x0.0p+0f, + -0x0.0p+0f, -0x0.0p+0f, -0x0.0p+0f, -0x0.0p+0f, + 0x1.96d5c20000000p+60f, 0x1.96d5c20000000p+60f, 0x1.96d5c20000000p+60f, 0x1.96d5c20000000p+60f, + -0x0.0p+0f, -0x0.0p+0f, -0x0.0p+0f, -0x0.0p+0f, + }, + }, +}; + +double TEST_BINOP_DATA(double, max)[][4][N] = +{ + { + { 0x1.317e5ef3ab327p+509 }, + { + 0x1.8fe1565f12a78p+508, 0x1.8fe1565f12a78p+508, 0x1.8fe1565f12a78p+508, 0x1.8fe1565f12a78p+508, + 0x1.b8b533d821ccap+510, 0x1.b8b533d821ccap+510, 0x1.b8b533d821ccap+510, 0x1.b8b533d821ccap+510, + 0x1.a4eb35b744a54p+509, 0x1.a4eb35b744a54p+509, 0x1.a4eb35b744a54p+509, 0x1.a4eb35b744a54p+509, + 0x1.6faedb6395f48p+508, 0x1.6faedb6395f48p+508, 0x1.6faedb6395f48p+508, 0x1.6faedb6395f48p+508, + }, + { + 0x1.317e5ef3ab327p+509, 0x1.317e5ef3ab327p+509, 0x1.317e5ef3ab327p+509, 0x1.317e5ef3ab327p+509, + 0x1.b8b533d821ccap+510, 0x1.b8b533d821ccap+510, 0x1.b8b533d821ccap+510, 0x1.b8b533d821ccap+510, + 0x1.a4eb35b744a54p+509, 0x1.a4eb35b744a54p+509, 0x1.a4eb35b744a54p+509, 0x1.a4eb35b744a54p+509, + 0x1.317e5ef3ab327p+509, 0x1.317e5ef3ab327p+509, 0x1.317e5ef3ab327p+509, 0x1.317e5ef3ab327p+509, + }, + }, + { + { 0x1.0000000000000p+0 }, + { + -0x1.53e0bc0170fe8p+509, -0x1.53e0bc0170fe8p+509, -0x1.53e0bc0170fe8p+509, -0x1.53e0bc0170fe8p+509, + 0x1.c3397ceebc142p+510, 0x1.c3397ceebc142p+510, 0x1.c3397ceebc142p+510, 0x1.c3397ceebc142p+510, + -0x1.ffe2046f999e3p+511, -0x1.ffe2046f999e3p+511, -0x1.ffe2046f999e3p+511, -0x1.ffe2046f999e3p+511, + -0x1.94d2a9003ee18p+510, -0x1.94d2a9003ee18p+510, -0x1.94d2a9003ee18p+510, -0x1.94d2a9003ee18p+510, + }, + { + 0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x1.0000000000000p+0, + 0x1.c3397ceebc142p+510, 0x1.c3397ceebc142p+510, 0x1.c3397ceebc142p+510, 0x1.c3397ceebc142p+510, + 0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x1.0000000000000p+0, + 0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x1.0000000000000p+0, 0x1.0000000000000p+0, + }, + }, + { + { -0x1.317e5ef3ab327p+509 }, + { + -0x1.062a35a13cec0p+509, -0x1.062a35a13cec0p+509, -0x1.062a35a13cec0p+509, -0x1.062a35a13cec0p+509, + -0x1.e5739808c344dp+511, -0x1.e5739808c344dp+511, -0x1.e5739808c344dp+511, -0x1.e5739808c344dp+511, + 0x1.96d5c3ca79e38p+508, 0x1.96d5c3ca79e38p+508, 0x1.96d5c3ca79e38p+508, 0x1.96d5c3ca79e38p+508, + -0x1.08eb6307cef78p+509, -0x1.08eb6307cef78p+509, -0x1.08eb6307cef78p+509, -0x1.08eb6307cef78p+509, + }, + { + -0x1.062a35a13cec0p+509, -0x1.062a35a13cec0p+509, -0x1.062a35a13cec0p+509, -0x1.062a35a13cec0p+509, + -0x1.317e5ef3ab327p+509, -0x1.317e5ef3ab327p+509, -0x1.317e5ef3ab327p+509, -0x1.317e5ef3ab327p+509, + 0x1.96d5c3ca79e38p+508, 0x1.96d5c3ca79e38p+508, 0x1.96d5c3ca79e38p+508, 0x1.96d5c3ca79e38p+508, + -0x1.08eb6307cef78p+509, -0x1.08eb6307cef78p+509, -0x1.08eb6307cef78p+509, -0x1.08eb6307cef78p+509, + }, + }, +}; #endif diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f16.c new file mode 100644 index 0000000..9965523 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f16.c @@ -0,0 +1,20 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-require-effective-target riscv_v_ok } */ +/* { dg-require-effective-target riscv_zvfh_ok } */ +/* { dg-add-options "riscv_v" } */ +/* { dg-add-options "riscv_zvfh" } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_binop.h" +#include "vf_binop_data.h" + +#define T _Float16 +#define FUNC MAX_FUNC_0_WRAP(T) +#define NAME max + +DEF_VF_BINOP_CASE_2_WRAP (T, FUNC, NAME) + +#define TEST_DATA TEST_BINOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, f, n) RUN_VF_BINOP_CASE_2_WRAP(T, NAME, FUNC, out, in, f, n) + +#include "vf_binop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f32.c new file mode 100644 index 0000000..5394f18 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f32.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_binop.h" +#include "vf_binop_data.h" + +#define T float +#define FUNC MAX_FUNC_0_WRAP(T) +#define NAME max + +DEF_VF_BINOP_CASE_2_WRAP (T, FUNC, NAME) + +#define TEST_DATA TEST_BINOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, f, n) RUN_VF_BINOP_CASE_2_WRAP(T, NAME, FUNC, out, in, f, n) + +#include "vf_binop_run.h" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f64.c new file mode 100644 index 0000000..b3df50f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vf_vfmax-run-1-f64.c @@ -0,0 +1,16 @@ +/* { dg-do run { target { riscv_v } } } */ +/* { dg-additional-options "--param=fpr2vr-cost=0" } */ + +#include "vf_binop.h" +#include "vf_binop_data.h" + +#define T double +#define FUNC MAX_FUNC_0_WRAP(T) +#define NAME max + +DEF_VF_BINOP_CASE_2_WRAP (T, FUNC, NAME) + +#define TEST_DATA TEST_BINOP_DATA_WRAP(T, NAME) +#define TEST_RUN(T, NAME, out, in, f, n) RUN_VF_BINOP_CASE_2_WRAP(T, NAME, FUNC, out, in, f, n) + +#include "vf_binop_run.h" |