]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR target/115921] Improve reassociation for rv64
authorJeff Law <jlaw@ventanamicro.com>
Tue, 3 Sep 2024 12:45:30 +0000 (06:45 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Tue, 3 Sep 2024 12:47:49 +0000 (06:47 -0600)
As Jovan pointed out in pr115921, we're not reassociating expressions like this
on rv64:

(x & 0x3e) << 12

It generates something like this:

        li      a5,258048
        slli    a0,a0,12
        and     a0,a0,a5

We have a pattern that's designed to clean this up.  Essentially reassociating
the operations so that we don't need to load the constant resulting in
something like this:

        andi    a0,a0,63
        slli    a0,a0,12

That pattern wasn't working for certain constants due to its condition. The
condition is trying to avoid cases where this kind of reassociation would
hinder shadd generation on rv64.  That condition was just written poorly.

This patch tightens up that condition in a few ways.  First, there's no need to
worry about shadd cases if ZBA is not enabled.  Second we can't use shadd if
the shift value isn't 1, 2 or 3.  Finally rather than open-coding one of the
tests, we can use an existing operand predicate.

The net is we'll start performing this transformation in more cases on rv64
while still avoiding reassociation if it would spoil shadd generation.

PR target/115921
gcc/
* config/riscv/riscv.md (reassociate bitwise ops): Tighten test for
cases we do not want reassociate.

gcc/testsuite/
* gcc.target/riscv/pr115921.c: New test.

gcc/J [new file with mode: 0644]
gcc/config/riscv/riscv.md
gcc/testsuite/gcc.target/riscv/pr115921.c [new file with mode: 0644]

diff --git a/gcc/J b/gcc/J
new file mode 100644 (file)
index 0000000..6b6332d
--- /dev/null
+++ b/gcc/J
@@ -0,0 +1,1064 @@
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    1) /* RTL-based forward propagation pass for GNU compiler.
+a945c346f57b gcc/fwprop.cc (Jakub Jelinek       2024-01-03 12:19:35 +0100    2)    Copyright (C) 2005-2024 Free Software Foundation, Inc.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    3)    Contributed by Paolo Bonzini and Steven Bosscher.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    4) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    5) This file is part of GCC.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    6) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    7) GCC is free software; you can redistribute it and/or modify it under
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000    8) the terms of the GNU General Public License as published by the Free
+9dcd6f09a3dd gcc/fwprop.c  (Nick Clifton        2007-07-26 08:37:01 +0000    9) Software Foundation; either version 3, or (at your option) any later
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   10) version.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   11) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   12) GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   13) WARRANTY; without even the implied warranty of MERCHANTABILITY or
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   14) FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   15) for more details.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   16) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   17) You should have received a copy of the GNU General Public License
+9dcd6f09a3dd gcc/fwprop.c  (Nick Clifton        2007-07-26 08:37:01 +0000   18) along with GCC; see the file COPYING3.  If not see
+9dcd6f09a3dd gcc/fwprop.c  (Nick Clifton        2007-07-26 08:37:01 +0000   19) <http://www.gnu.org/licenses/>.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   20) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   21) #define INCLUDE_ALGORITHM
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   22) #define INCLUDE_FUNCTIONAL
+d6849aa92666 gcc/fwprop.cc (Richard Sandiford   2024-07-25 13:25:32 +0100   23) #define INCLUDE_ARRAY
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   24) #include "config.h"
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   25) #include "system.h"
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   26) #include "coretypes.h"
+c7131fb2b58a gcc/fwprop.c  (Andrew MacLeod      2015-07-08 00:53:03 +0000   27) #include "backend.h"
+c7131fb2b58a gcc/fwprop.c  (Andrew MacLeod      2015-07-08 00:53:03 +0000   28) #include "rtl.h"
+1815e313a8fb gcc/fwprop.cc (Uros Bizjak         2023-07-14 11:46:22 +0200   29) #include "rtlanal.h"
+c7131fb2b58a gcc/fwprop.c  (Andrew MacLeod      2015-07-08 00:53:03 +0000   30) #include "df.h"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   31) #include "rtl-ssa.h"
+957060b5c5d2 gcc/fwprop.c  (Andrew MacLeod      2015-10-29 13:57:32 +0000   32) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   33) #include "predict.h"
+60393bbc613a gcc/fwprop.c  (Andrew MacLeod      2014-10-27 12:41:01 +0000   34) #include "cfgrtl.h"
+60393bbc613a gcc/fwprop.c  (Andrew MacLeod      2014-10-27 12:41:01 +0000   35) #include "cfgcleanup.h"
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   36) #include "cfgloop.h"
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   37) #include "tree-pass.h"
+aa4e2d7ef068 gcc/fwprop.c  (Richard Sandiford   2014-08-28 06:23:26 +0000   38) #include "rtl-iter.h"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   39) #include "target.h"
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   40) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   41) /* This pass does simple forward propagation and simplification when an
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   42)    operand of an insn can only come from a single def.  This pass uses
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   43)    RTL SSA, so it is global.  However, we only do limited analysis of
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   44)    available expressions.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   45) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   46)    1) The pass tries to propagate the source of the def into the use,
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   47)    and checks if the result is independent of the substituted value.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   48)    For example, the high word of a (zero_extend:DI (reg:SI M)) is always
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   49)    zero, independent of the source register.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   50) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   51)    In particular, we propagate constants into the use site.  Sometimes
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   52)    RTL expansion did not put the constant in the same insn on purpose,
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   53)    to satisfy a predicate, and the result will fail to be recognized;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   54)    but this happens rarely and in this case we can still create a
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   55)    REG_EQUAL note.  For multi-word operations, this
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   56) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   57)       (set (subreg:SI (reg:DI 120) 0) (const_int 0))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   58)       (set (subreg:SI (reg:DI 120) 4) (const_int -1))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   59)       (set (subreg:SI (reg:DI 122) 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   60)         (ior:SI (subreg:SI (reg:DI 119) 0) (subreg:SI (reg:DI 120) 0)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   61)       (set (subreg:SI (reg:DI 122) 4)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   62)         (ior:SI (subreg:SI (reg:DI 119) 4) (subreg:SI (reg:DI 120) 4)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   63) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   64)    can be simplified to the much simpler
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   65) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   66)       (set (subreg:SI (reg:DI 122) 0) (subreg:SI (reg:DI 119)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   67)       (set (subreg:SI (reg:DI 122) 4) (const_int -1))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   68) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   69)    This particular propagation is also effective at putting together
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   70)    complex addressing modes.  We are more aggressive inside MEMs, in
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   71)    that all definitions are propagated if the use is in a MEM; if the
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   72)    result is a valid memory address we check address_cost to decide
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   73)    whether the substitution is worthwhile.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   74) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   75)    2) The pass propagates register copies.  This is not as effective as
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   76)    the copy propagation done by CSE's canon_reg, which works by walking
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   77)    the instruction chain, it can help the other transformations.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   78) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   79)    We should consider removing this optimization, and instead reorder the
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   80)    RTL passes, because GCSE does this transformation too.  With some luck,
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   81)    the CSE pass at the end of rest_of_handle_gcse could also go away.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   82) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   83)    3) The pass looks for paradoxical subregs that are actually unnecessary.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   84)    Things like this:
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   85) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   86)      (set (reg:QI 120) (subreg:QI (reg:SI 118) 0))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   87)      (set (reg:QI 121) (subreg:QI (reg:SI 119) 0))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   88)      (set (reg:SI 122) (plus:SI (subreg:SI (reg:QI 120) 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000   89)                                (subreg:SI (reg:QI 121) 0)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   90) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   91)    are very common on machines that can only do word-sized operations.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   92)    For each use of a paradoxical subreg (subreg:WIDER (reg:NARROW N) 0),
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   93)    if it has a single def and it is (subreg:NARROW (reg:WIDE M) 0),
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   94)    we can replace the paradoxical subreg with simply (reg:WIDE M).  The
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   95)    above will simplify this to
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   96) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   97)      (set (reg:QI 120) (subreg:QI (reg:SI 118) 0))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   98)      (set (reg:QI 121) (subreg:QI (reg:SI 119) 0))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000   99)      (set (reg:SI 122) (plus:SI (reg:SI 118) (reg:SI 119)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  100) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  101)    where the first two insns are now dead.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  102) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  103) using namespace rtl_ssa;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  104) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  105) static int num_changes;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  106) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  107) /* Do not try to replace constant addresses or addresses of local and
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  108)    argument slots.  These MEM expressions are made only once and inserted
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  109)    in many instructions, as well as being used to control symbol table
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  110)    output.  It is not safe to clobber them.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  111) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  112)    There are some uncommon cases where the address is already in a register
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  113)    for some reason, but we cannot take advantage of that because we have
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  114)    no easy way to unshare the MEM.  In addition, looking up all stack
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  115)    addresses is costly.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  116) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  117) static bool
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  118) can_simplify_addr (rtx addr)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  119) {
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  120)   rtx reg;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  121) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  122)   if (CONSTANT_ADDRESS_P (addr))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  123)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  124) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  125)   if (GET_CODE (addr) == PLUS)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  126)     reg = XEXP (addr, 0);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  127)   else
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  128)     reg = addr;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  129) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  130)   return (!REG_P (reg)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  131)          || (REGNO (reg) != FRAME_POINTER_REGNUM
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  132)              && REGNO (reg) != HARD_FRAME_POINTER_REGNUM
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  133)              && REGNO (reg) != ARG_POINTER_REGNUM));
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  134) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  135) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  136) /* MEM is the result of an address simplification, and temporarily
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  137)    undoing changes OLD_NUM_CHANGES onwards restores the original address.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  138)    Return whether it is good to use the new address instead of the
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  139)    old one.  INSN is the containing instruction.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  140) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  141) static bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  142) should_replace_address (int old_num_changes, rtx mem, rtx_insn *insn)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  143) {
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  144)   int gain;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  145) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  146)   /* Prefer the new address if it is less expensive.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  147)   bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  148)   temporarily_undo_changes (old_num_changes);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  149)   gain = address_cost (XEXP (mem, 0), GET_MODE (mem),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  150)                       MEM_ADDR_SPACE (mem), speed);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  151)   redo_changes (old_num_changes);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  152)   gain -= address_cost (XEXP (mem, 0), GET_MODE (mem),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  153)                        MEM_ADDR_SPACE (mem), speed);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  154) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  155)   /* If the addresses have equivalent cost, prefer the new address
+5e8f01f434e5 gcc/fwprop.c  (Richard Sandiford   2011-08-18 12:37:27 +0000  156)      if it has the highest `set_src_cost'.  That has the potential of
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  157)      eliminating the most insns without additional costs, and it
+e53b6e564aab gcc/fwprop.cc (Martin Liska        2022-01-14 16:57:02 +0100  158)      is the same that cse.cc used to do.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  159)   if (gain == 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  160)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  161)       gain = set_src_cost (XEXP (mem, 0), VOIDmode, speed);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  162)       temporarily_undo_changes (old_num_changes);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  163)       gain -= set_src_cost (XEXP (mem, 0), VOIDmode, speed);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  164)       redo_changes (old_num_changes);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  165)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  166) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  167)   return (gain > 0);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  168) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  169) 
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  170) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  171) namespace
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  172) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  173)   class fwprop_propagation : public insn_propagation
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  174)   {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  175)   public:
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  176)     static const uint16_t CHANGED_MEM = FIRST_SPARE_RESULT;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  177)     static const uint16_t CONSTANT = FIRST_SPARE_RESULT << 1;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  178)     static const uint16_t PROFITABLE = FIRST_SPARE_RESULT << 2;
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  179) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  180)     fwprop_propagation (insn_info *, set_info *, rtx, rtx);
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  181) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  182)     bool changed_mem_p () const { return result_flags & CHANGED_MEM; }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  183)     bool folded_to_constants_p () const;
+86de9b66480b gcc/fwprop.cc (Roger Sayle         2024-01-21 21:22:28 +0000  184)     bool likely_profitable_p () const;
+f40751dd3417 gcc/fwprop.c  (Jan Hubicka         2008-08-31 11:44:25 +0200  185) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  186)     bool check_mem (int, rtx) final override;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  187)     void note_simplification (int, uint16_t, rtx, rtx) final override;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  188)     uint16_t classify_result (rtx, rtx);
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  189) 
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  190)   private:
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  191)     const bool single_use_p;
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  192)     const bool single_ebb_p;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  193)   };
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  194) }
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  195) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  196) /* Prepare to replace FROM with TO in USE_INSN.  */
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  197) 
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  198) fwprop_propagation::fwprop_propagation (insn_info *use_insn,
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  199)                                        set_info *def, rtx from, rtx to)
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  200)   : insn_propagation (use_insn->rtl (), from, to),
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  201)     single_use_p (def->single_nondebug_use ()),
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  202)     single_ebb_p (use_insn->ebb () == def->ebb ())
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  203) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  204)   should_check_mems = true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  205)   should_note_simplifications = true;
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  206) }
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  207) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  208) /* MEM is the result of an address simplification, and temporarily
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  209)    undoing changes OLD_NUM_CHANGES onwards restores the original address.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  210)    Return true if the propagation should continue, false if it has failed.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  211) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  212) bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  213) fwprop_propagation::check_mem (int old_num_changes, rtx mem)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  214) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  215)   if (!memory_address_addr_space_p (GET_MODE (mem), XEXP (mem, 0),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  216)                                    MEM_ADDR_SPACE (mem)))
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  217)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  218)       failure_reason = "would create an invalid MEM";
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  219)       return false;
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  220)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  221) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  222)   temporarily_undo_changes (old_num_changes);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  223)   bool can_simplify = can_simplify_addr (XEXP (mem, 0));
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  224)   redo_changes (old_num_changes);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  225)   if (!can_simplify)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  226)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  227)       failure_reason = "would replace a frame address";
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  228)       return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  229)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  230) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  231)   /* Copy propagations are always ok.  Otherwise check the costs.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  232)   if (!(REG_P (from) && REG_P (to))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  233)       && !should_replace_address (old_num_changes, mem, insn))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  234)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  235)       failure_reason = "would increase the cost of a MEM";
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  236)       return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  237)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  238) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  239)   result_flags |= CHANGED_MEM;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  240)   return true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  241) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  242) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  243) /* OLDX has been simplified to NEWX.  Describe the change in terms of
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  244)    result_flags.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  245) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  246) uint16_t
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  247) fwprop_propagation::classify_result (rtx old_rtx, rtx new_rtx)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  248) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  249)   if (CONSTANT_P (new_rtx))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  250)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  251)       /* If OLD_RTX is a LO_SUM, then it presumably exists for a reason,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  252)         and NEW_RTX is likely not a legitimate address.  We want it to
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  253)         disappear if it is invalid.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  254) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  255)         ??? Using the mode of the LO_SUM as the mode of the address
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  256)         seems odd, but it was what the pre-SSA code did.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  257)       if (GET_CODE (old_rtx) == LO_SUM
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  258)          && !memory_address_p (GET_MODE (old_rtx), new_rtx))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  259)        return CONSTANT;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  260)       return CONSTANT | PROFITABLE;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  261)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  262) 
+712a93d637f8 gcc/fwprop.c  (Richard Biener      2016-07-12 08:56:14 +0000  263)   /* Allow replacements that simplify operations on a vector or complex
+712a93d637f8 gcc/fwprop.c  (Richard Biener      2016-07-12 08:56:14 +0000  264)      value to a component.  The most prominent case is
+712a93d637f8 gcc/fwprop.c  (Richard Biener      2016-07-12 08:56:14 +0000  265)      (subreg ([vec_]concat ...)).   */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  266)   if (REG_P (new_rtx)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  267)       && !HARD_REGISTER_P (new_rtx)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  268)       && (VECTOR_MODE_P (GET_MODE (from))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  269)          || COMPLEX_MODE_P (GET_MODE (from)))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  270)       && GET_MODE (new_rtx) == GET_MODE_INNER (GET_MODE (from)))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  271)     return PROFITABLE;
+712a93d637f8 gcc/fwprop.c  (Richard Biener      2016-07-12 08:56:14 +0000  272) 
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  273)   /* Allow (subreg (mem)) -> (mem) simplifications with the following
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  274)      exceptions:
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  275)      1) Propagating (mem)s into multiple uses is not profitable.
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  276)      2) Propagating (mem)s across EBBs may not be profitable if the source EBB
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  277)        runs less frequently.
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  278)      3) Propagating (mem)s into paradoxical (subreg)s is not profitable.
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  279)      4) Creating new (mem/v)s is not correct, since DCE will not remove the old
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  280)        ones.  */
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  281)   if (single_use_p
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  282)       && single_ebb_p
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  283)       && SUBREG_P (old_rtx)
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  284)       && !paradoxical_subreg_p (old_rtx)
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  285)       && MEM_P (new_rtx)
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  286)       && !MEM_VOLATILE_P (new_rtx))
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  287)     return PROFITABLE;
+efb6bc55a93a gcc/fwprop.c  (Ilya Leoshkevich    2021-01-15 00:14:56 +0100  288) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  289)   return 0;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  290) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  291) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  292) /* Record that OLD_RTX has been simplified to NEW_RTX.  OLD_NUM_CHANGES
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  293)    is the number of unrelated changes that had been made before processing
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  294)    OLD_RTX and its subrtxes.  OLD_RESULT_FLAGS is the value that result_flags
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  295)    had at that point.  */
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  296) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  297) void
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  298) fwprop_propagation::note_simplification (int old_num_changes,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  299)                                         uint16_t old_result_flags,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  300)                                         rtx old_rtx, rtx new_rtx)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  301) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  302)   result_flags &= ~(CONSTANT | PROFITABLE);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  303)   uint16_t new_flags = classify_result (old_rtx, new_rtx);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  304)   if (old_num_changes)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  305)     new_flags &= old_result_flags;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  306)   result_flags |= new_flags;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  307) }
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  308) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  309) /* Return true if all substitutions eventually folded to constants.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  310) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  311) bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  312) fwprop_propagation::folded_to_constants_p () const
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  313) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  314)   /* If we're propagating a HIGH, require it to be folded with a
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  315)      partnering LO_SUM.  For example, a REG_EQUAL note with a register
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  316)      replaced by an unfolded HIGH is not useful.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  317)   if (CONSTANT_P (to) && GET_CODE (to) != HIGH)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  318)     return true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  319)   return !(result_flags & UNSIMPLIFIED) && (result_flags & CONSTANT);
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  320) }
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  321) 
+460d667de96a gcc/fwprop.c  (Paolo Bonzini       2008-04-02 09:53:34 +0000  322) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  323) /* Return true if it is worth keeping the result of the propagation,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  324)    false if it would increase the complexity of the pattern too much.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  325) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  326) bool
+86de9b66480b gcc/fwprop.cc (Roger Sayle         2024-01-21 21:22:28 +0000  327) fwprop_propagation::likely_profitable_p () const
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  328) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  329)   if (changed_mem_p ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  330)     return true;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  331) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  332)   if (!(result_flags & UNSIMPLIFIED)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  333)       && (result_flags & PROFITABLE))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  334)     return true;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  335) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  336)   if (REG_P (to))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  337)     return true;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  338) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  339)   if (GET_CODE (to) == SUBREG
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  340)       && REG_P (SUBREG_REG (to))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  341)       && !paradoxical_subreg_p (to))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  342)     return true;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  343) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  344)   if (CONSTANT_P (to))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  345)     return true;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  346) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  347)   return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  348) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  349) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  350) /* Check that X has a single def.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  351) 
+6fb5fa3cbc0d gcc/fwprop.c  (Daniel Berlin       2007-06-11 18:02:15 +0000  352) static bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  353) reg_single_def_p (rtx x)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  354) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  355)   return REG_P (x) && crtl->ssa->single_dominating_def (REGNO (x));
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  356) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  357) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  358) /* Try to substitute (set DEST SRC), which defines DEF, into note NOTE of
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  359)    USE_INSN.  Return the number of substitutions on success, otherwise return
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  360)    -1 and leave USE_INSN unchanged.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  361) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  362)    If REQUIRE_CONSTANT is true, require all substituted occurrences of SRC
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  363)    to fold to a constant, so that the note does not use any more registers
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  364)    than it did previously.  If REQUIRE_CONSTANT is false, also allow the
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  365)    substitution if it's something we'd normally allow for the main
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  366)    instruction pattern.  */
+692e7e54e095 gcc/fwprop.c  (Richard Biener      2018-11-05 08:04:49 +0000  367) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  368) static int
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  369) try_fwprop_subst_note (insn_info *use_insn, set_info *def,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  370)                       rtx note, rtx dest, rtx src, bool require_constant)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  371) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  372)   rtx_insn *use_rtl = use_insn->rtl ();
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  373)   insn_info *def_insn = def->insn ();
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  374) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  375)   insn_change_watermark watermark;
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  376)   fwprop_propagation prop (use_insn, def, dest, src);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  377)   if (!prop.apply_to_rvalue (&XEXP (note, 0)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  378)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  379)       if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  380)        fprintf (dump_file, "cannot propagate from insn %d into"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  381)                 " notes of insn %d: %s\n", def_insn->uid (),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  382)                 use_insn->uid (), prop.failure_reason);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  383)       return -1;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  384)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  385) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  386)   if (prop.num_replacements == 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  387)     return 0;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  388) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  389)   if (require_constant)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  390)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  391)       if (!prop.folded_to_constants_p ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  392)        {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  393)          if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  394)            fprintf (dump_file, "cannot propagate from insn %d into"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  395)                     " notes of insn %d: %s\n", def_insn->uid (),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  396)                     use_insn->uid (), "wouldn't fold to constants");
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  397)          return -1;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  398)        }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  399)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  400)   else
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  401)     {
+86de9b66480b gcc/fwprop.cc (Roger Sayle         2024-01-21 21:22:28 +0000  402)       if (!prop.folded_to_constants_p () && !prop.likely_profitable_p ())
+6fb5fa3cbc0d gcc/fwprop.c  (Daniel Berlin       2007-06-11 18:02:15 +0000  403)        {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  404)          if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  405)            fprintf (dump_file, "cannot propagate from insn %d into"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  406)                     " notes of insn %d: %s\n", def_insn->uid (),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  407)                     use_insn->uid (), "would increase complexity of node");
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  408)          return -1;
+6fb5fa3cbc0d gcc/fwprop.c  (Daniel Berlin       2007-06-11 18:02:15 +0000  409)        }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  410)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  411) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  412)   if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  413)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  414)       fprintf (dump_file, "\nin notes of insn %d, replacing:\n  ",
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  415)               INSN_UID (use_rtl));
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  416)       temporarily_undo_changes (0);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  417)       print_inline_rtx (dump_file, note, 2);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  418)       redo_changes (0);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  419)       fprintf (dump_file, "\n with:\n  ");
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  420)       print_inline_rtx (dump_file, note, 2);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  421)       fprintf (dump_file, "\n");
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  422)     }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  423)   watermark.keep ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  424)   return prop.num_replacements;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  425) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  426) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  427) /* Try to substitute (set DEST SRC), which defines DEF, into location LOC of
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  428)    USE_INSN's pattern.  Return true on success, otherwise leave USE_INSN
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  429)    unchanged.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  430) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  431) static bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  432) try_fwprop_subst_pattern (obstack_watermark &attempt, insn_change &use_change,
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  433)                          set_info *def, rtx *loc, rtx dest, rtx src)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  434) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  435)   insn_info *use_insn = use_change.insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  436)   rtx_insn *use_rtl = use_insn->rtl ();
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  437)   insn_info *def_insn = def->insn ();
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  438) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  439)   insn_change_watermark watermark;
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  440)   fwprop_propagation prop (use_insn, def, dest, src);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  441)   if (!prop.apply_to_pattern (loc))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  442)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  443)       if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  444)        fprintf (dump_file, "cannot propagate from insn %d into"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  445)                 " insn %d: %s\n", def_insn->uid (), use_insn->uid (),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  446)                 prop.failure_reason);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  447)       return false;
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  448)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  449) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  450)   if (prop.num_replacements == 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  451)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  452) 
+86de9b66480b gcc/fwprop.cc (Roger Sayle         2024-01-21 21:22:28 +0000  453)   if (!prop.likely_profitable_p ()
+86de9b66480b gcc/fwprop.cc (Roger Sayle         2024-01-21 21:22:28 +0000  454)       && (prop.changed_mem_p ()
+3e3e4156a5f9 gcc/fwprop.cc (Jakub Jelinek       2024-03-09 13:04:26 +0100  455)          || contains_mem_rtx_p (src)
+86de9b66480b gcc/fwprop.cc (Roger Sayle         2024-01-21 21:22:28 +0000  456)          || use_insn->is_asm ()
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  457)          || use_insn->is_debug_insn ()))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  458)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  459)       if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  460)        fprintf (dump_file, "cannot propagate from insn %d into"
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  461)                 " insn %d: %s\n", def_insn->uid (), use_insn->uid (),
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  462)                 "would increase complexity of pattern");
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  463)       return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  464)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  465) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  466)   if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  467)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  468)       fprintf (dump_file, "\npropagating insn %d into insn %d, replacing:\n",
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  469)               def_insn->uid (), use_insn->uid ());
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  470)       temporarily_undo_changes (0);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  471)       print_rtl_single (dump_file, PATTERN (use_rtl));
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  472)       redo_changes (0);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  473)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  474) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  475)   bool ok = recog (attempt, use_change);
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  476)   if (ok
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  477)       && !prop.changed_mem_p ()
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  478)       && !use_insn->is_asm ()
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  479)       && !use_insn->is_debug_insn ())
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  480)     {
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  481)       bool strict_p = !prop.likely_profitable_p ();
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  482)       if (!change_is_worthwhile (use_change, strict_p))
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  483)        {
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  484)          if (dump_file)
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  485)            fprintf (dump_file, "change not profitable");
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  486)          ok = false;
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  487)        }
+ea8061f46a30 gcc/fwprop.cc (Haochen Gui         2024-06-24 13:12:51 +0800  488)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  489) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  490)   if (!ok)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  491)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  492)       /* The pattern didn't match, but if all uses of SRC folded to
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  493)         constants, we can add a REG_EQUAL note for the result, if there
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  494)         isn't one already.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  495)       if (!prop.folded_to_constants_p ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  496)        return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  497) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  498)       /* Test this first to avoid creating an unnecessary copy of SRC.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  499)       if (find_reg_note (use_rtl, REG_EQUAL, NULL_RTX))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  500)        return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  501) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  502)       rtx set = set_for_reg_notes (use_rtl);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  503)       if (!set || !REG_P (SET_DEST (set)))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  504)        return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  505) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  506)       rtx value = copy_rtx (SET_SRC (set));
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  507)       cancel_changes (0);
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  508) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  509)       /* If there are any paradoxical SUBREGs, drop the REG_EQUAL note,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  510)         because the bits in there can be anything and so might not
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  511)         match the REG_EQUAL note content.  See PR70574.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  512)       if (contains_paradoxical_subreg_p (SET_SRC (set)))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  513)        return false;
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  514) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  515)       if (dump_file && (dump_flags & TDF_DETAILS))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  516)        fprintf (dump_file, " Setting REG_EQUAL note\n");
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  517) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  518)       return set_unique_reg_note (use_rtl, REG_EQUAL, value);
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  519)     }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  520) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  521)   rtx *note_ptr = &REG_NOTES (use_rtl);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  522)   while (rtx note = *note_ptr)
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  523)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  524)       if ((REG_NOTE_KIND (note) == REG_EQUAL
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  525)           || REG_NOTE_KIND (note) == REG_EQUIV)
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  526)          && try_fwprop_subst_note (use_insn, def, note, dest, src, false) < 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  527)        {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  528)          *note_ptr = XEXP (note, 1);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  529)          free_EXPR_LIST_node (note);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  530)        }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  531)       else
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  532)        note_ptr = &XEXP (note, 1);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  533)     }
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  534) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  535)   confirm_change_group ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  536)   crtl->ssa->change_insn (use_change);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  537)   num_changes++;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  538)   return true;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  539) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  540) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  541) /* Try to substitute (set DEST SRC), which defines DEF, into USE_INSN's notes,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  542)    given that it was not possible to do this for USE_INSN's main pattern.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  543)    Return true on success, otherwise leave USE_INSN unchanged.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  544) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  545) static bool
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  546) try_fwprop_subst_notes (insn_info *use_insn, set_info *def,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  547)                        rtx dest, rtx src)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  548) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  549)   rtx_insn *use_rtl = use_insn->rtl ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  550)   for (rtx note = REG_NOTES (use_rtl); note; note = XEXP (note, 1))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  551)     if ((REG_NOTE_KIND (note) == REG_EQUAL
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  552)         || REG_NOTE_KIND (note) == REG_EQUIV)
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  553)        && try_fwprop_subst_note (use_insn, def, note, dest, src, true) > 0)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  554)       {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  555)        confirm_change_group ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  556)        return true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  557)       }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  558) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  559)   return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  560) }
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  561) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  562) /* Check whether we could validly substitute (set DEST SRC), which defines DEF,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  563)    into USE.  If so, first try performing the substitution in location LOC
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  564)    of USE->insn ()'s pattern.  If that fails, try instead to substitute
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  565)    into the notes.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  566) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  567)    Return true on success, otherwise leave USE_INSN unchanged.  */
+de266950570f gcc/fwprop.c  (Paolo Bonzini       2007-11-09 13:02:25 +0000  568) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  569) static bool
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  570) try_fwprop_subst (use_info *use, set_info *def,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  571)                  rtx *loc, rtx dest, rtx src)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  572) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  573)   insn_info *use_insn = use->insn ();
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  574)   insn_info *def_insn = def->insn ();
+de266950570f gcc/fwprop.c  (Paolo Bonzini       2007-11-09 13:02:25 +0000  575) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  576)   auto attempt = crtl->ssa->new_change_attempt ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  577)   use_array src_uses = remove_note_accesses (attempt, def_insn->uses ());
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  578) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  579)   /* ??? Not really a meaningful test: it means we can propagate arithmetic
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  580)      involving hard registers but not bare references to them.  A better
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  581)      test would be to iterate over src_uses looking for hard registers
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  582)      that are not fixed.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  583)   if (REG_P (src) && HARD_REGISTER_P (src))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  584)     return false;
+de266950570f gcc/fwprop.c  (Paolo Bonzini       2007-11-09 13:02:25 +0000  585) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  586)   /* ??? It would be better to make this EBB-based instead.  That would
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  587)      involve checking for equal EBBs rather than equal BBs and trying
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  588)      to make the uses available at use_insn->ebb ()->first_bb ().  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  589)   if (def_insn->bb () != use_insn->bb ())
+de266950570f gcc/fwprop.c  (Paolo Bonzini       2007-11-09 13:02:25 +0000  590)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  591)       src_uses = crtl->ssa->make_uses_available (attempt, src_uses,
+c97351c0cf48 gcc/fwprop.c  (Richard Sandiford   2021-04-29 17:24:57 +0100  592)                                                 use_insn->bb (),
+c97351c0cf48 gcc/fwprop.c  (Richard Sandiford   2021-04-29 17:24:57 +0100  593)                                                 use_insn->is_debug_insn ());
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  594)       if (!src_uses.is_valid ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  595)        return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  596)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  597) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  598)   insn_change use_change (use_insn);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  599)   use_change.new_uses = merge_access_arrays (attempt, use_change.new_uses,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  600)                                             src_uses);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  601)   if (!use_change.new_uses.is_valid ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  602)     return false;
+1a13c0a284ea gcc/fwprop.c  (Jakub Jelinek       2016-04-08 19:21:17 +0200  603) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  604)   /* ??? We could allow movement within the EBB by adding:
+de266950570f gcc/fwprop.c  (Paolo Bonzini       2007-11-09 13:02:25 +0000  605) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  606)      use_change.move_range = use_insn->ebb ()->insn_range ();  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  607)   if (!restrict_movement (use_change))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  608)     return false;
+dc007c1fd21c gcc/fwprop.c  (Paolo Bonzini       2010-11-22 16:20:16 +0000  609) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  610)   return (try_fwprop_subst_pattern (attempt, use_change, def, loc, dest, src)
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  611)          || try_fwprop_subst_notes (use_insn, def, dest, src));
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  612) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  613) 
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  614) /* For the given single_set INSN, containing SRC known to be a
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  615)    ZERO_EXTEND or SIGN_EXTEND of a register, return true if INSN
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  616)    is redundant due to the register being set by a LOAD_EXTEND_OP
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  617)    load from memory.  */
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  618) 
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  619) static bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  620) free_load_extend (rtx src, insn_info *insn)
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  621) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  622)   rtx reg = XEXP (src, 0);
+3712c7a30197 gcc/fwprop.c  (Richard Sandiford   2016-11-15 18:13:56 +0000  623)   if (load_extend_op (GET_MODE (reg)) != GET_CODE (src))
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  624)     return false;
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  625) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  626)   def_info *def = nullptr;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  627)   for (use_info *use : insn->uses ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  628)     if (use->regno () == REGNO (reg))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  629)       {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  630)        def = use->def ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  631)        break;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  632)       }
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  633) 
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  634)   if (!def)
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  635)     return false;
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  636) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  637)   insn_info *def_insn = def->insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  638)   if (def_insn->is_artificial ())
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  639)     return false;
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  640) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  641)   rtx_insn *def_rtl = def_insn->rtl ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  642)   if (NONJUMP_INSN_P (def_rtl))
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  643)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  644)       rtx patt = PATTERN (def_rtl);
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  645) 
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  646)       if (GET_CODE (patt) == SET
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  647)          && GET_CODE (SET_SRC (patt)) == MEM
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  648)          && rtx_equal_p (SET_DEST (patt), reg))
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  649)        return true;
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  650)     }
+e85122be92f7 gcc/fwprop.c  (Alan Modra          2009-08-30 06:09:42 +0000  651)   return false;
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  652) }
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  653) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  654) /* Subroutine of forward_propagate_subreg that handles a use of DEST
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  655)    in REF.  The other parameters are the same.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  656) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  657) static bool
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  658) forward_propagate_subreg (use_info *use, set_info *def,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  659)                          rtx dest, rtx src, df_ref ref)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  660) {
+6b9c3decc38f gcc/fwprop.c  (Richard Sandiford   2017-08-30 11:11:42 +0000  661)   scalar_int_mode int_use_mode, src_mode;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  662) 
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  663)   /* Only consider subregs... */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  664)   rtx use_reg = DF_REF_REG (ref);
+ef4bddc299ea gcc/fwprop.c  (Richard Sandiford   2014-10-29 12:02:45 +0000  665)   machine_mode use_mode = GET_MODE (use_reg);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  666)   if (GET_CODE (use_reg) != SUBREG
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  667)       || GET_MODE (SUBREG_REG (use_reg)) != GET_MODE (dest))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  668)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  669) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  670)   /* ??? Replacing throughout the pattern would help for match_dups.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  671)   rtx *loc = DF_REF_LOC (ref);
+03a956218445 gcc/fwprop.c  (Richard Sandiford   2017-08-22 16:14:48 +0000  672)   if (paradoxical_subreg_p (use_reg))
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  673)     {
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  674)       /* If this is a paradoxical SUBREG, we have no idea what value the
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  675)         extra bits would have.  However, if the operand is equivalent to
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  676)         a SUBREG whose operand is the same as our mode, and all the modes
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  677)         are within a word, we can just use the inner operand because
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  678)         these SUBREGs just say how to treat the register.  */
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  679)       if (GET_CODE (src) == SUBREG
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  680)          && REG_P (SUBREG_REG (src))
+509a31f8e558 gcc/fwprop.c  (H.J. Lu             2011-07-05 12:47:35 +0000  681)          && REGNO (SUBREG_REG (src)) >= FIRST_PSEUDO_REGISTER
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  682)          && GET_MODE (SUBREG_REG (src)) == use_mode
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  683)          && subreg_lowpart_p (src))
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  684)        return try_fwprop_subst (use, def, loc, use_reg, SUBREG_REG (src));
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  685)     }
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  686) 
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  687)   /* If this is a SUBREG of a ZERO_EXTEND or SIGN_EXTEND, and the SUBREG
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  688)      is the low part of the reg being extended then just use the inner
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  689)      operand.  Don't do this if the ZERO_EXTEND or SIGN_EXTEND insn will
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  690)      be removed due to it matching a LOAD_EXTEND_OP load from memory,
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  691)      or due to the operation being a no-op when applied to registers.
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  692)      For example, if we have:
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  693) 
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  694)         A: (set (reg:DI X) (sign_extend:DI (reg:SI Y)))
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  695)         B: (... (subreg:SI (reg:DI X)) ...)
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  696) 
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  697)      and mode_rep_extended says that Y is already sign-extended,
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  698)      the backend will typically allow A to be combined with the
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  699)      definition of Y or, failing that, allow A to be deleted after
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  700)      reload through register tying.  Introducing more uses of Y
+7a613929211d gcc/fwprop.c  (Richard Sandiford   2011-12-19 22:05:28 +0000  701)      prevents both optimisations.  */
+6b9c3decc38f gcc/fwprop.c  (Richard Sandiford   2017-08-30 11:11:42 +0000  702)   else if (is_a <scalar_int_mode> (use_mode, &int_use_mode)
+6b9c3decc38f gcc/fwprop.c  (Richard Sandiford   2017-08-30 11:11:42 +0000  703)           && subreg_lowpart_p (use_reg))
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  704)     {
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  705)       if ((GET_CODE (src) == ZERO_EXTEND
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  706)           || GET_CODE (src) == SIGN_EXTEND)
+6b9c3decc38f gcc/fwprop.c  (Richard Sandiford   2017-08-30 11:11:42 +0000  707)          && is_a <scalar_int_mode> (GET_MODE (src), &src_mode)
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  708)          && REG_P (XEXP (src, 0))
+509a31f8e558 gcc/fwprop.c  (H.J. Lu             2011-07-05 12:47:35 +0000  709)          && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  710)          && GET_MODE (XEXP (src, 0)) == use_mode
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  711)          && !free_load_extend (src, def->insn ())
+6b9c3decc38f gcc/fwprop.c  (Richard Sandiford   2017-08-30 11:11:42 +0000  712)          && (targetm.mode_rep_extended (int_use_mode, src_mode)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  713)              != (int) GET_CODE (src)))
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  714)        return try_fwprop_subst (use, def, loc, use_reg, XEXP (src, 0));
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  715)     }
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  716) 
+e25b7843ec71 gcc/fwprop.c  (Alan Modra          2009-08-23 02:57:26 +0000  717)   return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  718) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  719) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  720) /* Try to substitute (set DEST SRC), which defines DEF, into USE and simplify
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  721)    the result, handling cases where DEST is used in a subreg and where
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  722)    applying that subreg to SRC results in a useful simplification.  */
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  723) 
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  724) static bool
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  725) forward_propagate_subreg (use_info *use, set_info *def, rtx dest, rtx src)
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  726) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  727)   if (!use->includes_subregs () || !REG_P (dest))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  728)     return false;
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  729) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  730)   if (GET_CODE (src) != SUBREG
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  731)       && GET_CODE (src) != ZERO_EXTEND
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  732)       && GET_CODE (src) != SIGN_EXTEND)
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  733)     return false;
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  734) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  735)   rtx_insn *use_rtl = use->insn ()->rtl ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  736)   df_ref ref;
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  737) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  738)   FOR_EACH_INSN_USE (ref, use_rtl)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  739)     if (DF_REF_REGNO (ref) == use->regno ()
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  740)        && forward_propagate_subreg (use, def, dest, src, ref))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  741)       return true;
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  742) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  743)   FOR_EACH_INSN_EQ_USE (ref, use_rtl)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  744)     if (DF_REF_REGNO (ref) == use->regno ()
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  745)        && forward_propagate_subreg (use, def, dest, src, ref))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  746)       return true;
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  747) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  748)   return false;
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  749) }
+ce372372f42e gcc/fwprop.c  (Jakub Jelinek       2009-04-26 20:56:14 +0200  750) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  751) /* Try to substitute (set DEST SRC), which defines DEF, into USE and
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  752)    simplify the result.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  753) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  754) static bool
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  755) forward_propagate_and_simplify (use_info *use, set_info *def,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  756)                                rtx dest, rtx src)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  757) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  758)   insn_info *use_insn = use->insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  759)   rtx_insn *use_rtl = use_insn->rtl ();
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  760)   insn_info *def_insn = def->insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  761) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  762)   /* ??? This check seems unnecessary.  We should be able to propagate
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  763)      into any kind of instruction, regardless of whether it's a single set.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  764)      It seems odd to be more permissive with asms than normal instructions.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  765)   bool need_single_set = (!use_insn->is_asm () && !use_insn->is_debug_insn ());
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  766)   rtx use_set = single_set (use_rtl);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  767)   if (need_single_set && !use_set)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  768)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  769) 
+bd1cd0d0e0fe gcc/fwprop.c  (Segher Boessenkool  2021-04-23 19:59:00 +0000  770)   /* Do not propagate into PC etc.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  771) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  772)      ??? This too seems unnecessary.  The current code should work correctly
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  773)      without it, including cases where jumps become unconditional.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  774)   if (use_set && GET_MODE (SET_DEST (use_set)) == VOIDmode)
+8e8af9b74d52 gcc/fwprop.c  (Richard Sandiford   2011-09-27 17:24:03 +0000  775)     return false;
+8e8af9b74d52 gcc/fwprop.c  (Richard Sandiford   2011-09-27 17:24:03 +0000  776) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  777)   /* In __asm don't replace if src might need more registers than
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  778)      reg, as that could increase register pressure on the __asm.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  779)   if (use_insn->is_asm () && def_insn->uses ().size () > 1)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  780)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  781) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  782)   /* Check if the def is loading something from the constant pool; in this
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  783)      case we would undo optimization such as compress_float_constant.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  784)      Still, we can set a REG_EQUAL note.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  785)   if (MEM_P (src) && MEM_READONLY_P (src))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  786)     {
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  787)       rtx x = avoid_constant_pool_reference (src);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  788)       rtx note_set;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  789)       if (x != src
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  790)          && (note_set = set_for_reg_notes (use_rtl))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  791)          && REG_P (SET_DEST (note_set))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  792)          && !contains_paradoxical_subreg_p (SET_SRC (note_set)))
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  793)        {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  794)          rtx note = find_reg_note (use_rtl, REG_EQUAL, NULL_RTX);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  795)          rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (note_set);
+605642891863 gcc/fwprop.c  (Kaveh R. Ghazi      2008-07-15 17:51:00 +0000  796)          rtx new_rtx = simplify_replace_rtx (old_rtx, src, x);
+605642891863 gcc/fwprop.c  (Kaveh R. Ghazi      2008-07-15 17:51:00 +0000  797)          if (old_rtx != new_rtx)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  798)            set_unique_reg_note (use_rtl, REG_EQUAL, copy_rtx (new_rtx));
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  799)        }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  800)       return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  801)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  802) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  803)   /* ??? Unconditionally propagating into PATTERN would work better
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  804)      for instructions that have match_dups.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  805)   rtx *loc = need_single_set ? &use_set : &PATTERN (use_rtl);
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  806)   return try_fwprop_subst (use, def, loc, dest, src);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  807) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  808) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  809) /* Given a use USE of an insn, if it has a single reaching
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  810)    definition, try to forward propagate it into that insn.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  811)    Return true if something changed.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  812) 
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  813)    REG_PROP_ONLY is true if we should only propagate register copies.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  814) 
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  815) static bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  816) forward_propagate_into (use_info *use, bool reg_prop_only = false)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  817) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  818)   if (use->includes_read_writes ())
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  819)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  820) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  821)   /* Disregard uninitialized uses.  */
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  822)   set_info *def = use->def ();
+00952e9784e4 gcc/fwprop.c  (Paolo Bonzini       2009-05-08 12:22:30 +0000  823)   if (!def)
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  824)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  825) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  826)   /* Only consider single-register definitions.  This could be relaxed,
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  827)      but it should rarely be needed before RA.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  828)   def = look_through_degenerate_phi (def);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  829)   if (def->includes_multiregs ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  830)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  831) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  832)   /* Only consider uses whose definition comes from a real instruction.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  833)   insn_info *def_insn = def->insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  834)   if (def_insn->is_artificial ())
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  835)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  836) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  837)   rtx_insn *def_rtl = def_insn->rtl ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  838)   if (!NONJUMP_INSN_P (def_rtl))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  839)     return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  840)   /* ??? This seems an unnecessary restriction.  We can easily tell
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  841)      which set the definition comes from.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  842)   if (multiple_sets (def_rtl))
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  843)     return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  844)   rtx def_set = simple_regno_set (PATTERN (def_rtl), def->regno ());
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  845)   if (!def_set)
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  846)     return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  847) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  848)   rtx dest = SET_DEST (def_set);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  849)   rtx src = SET_SRC (def_set);
+a0e945888d97 gcc/fwprop.cc (Haochen Gui         2024-03-08 09:30:35 +0800  850)   if (volatile_refs_p (src))
+a0e945888d97 gcc/fwprop.cc (Haochen Gui         2024-03-08 09:30:35 +0800  851)     return false;
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  852) 
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  853)   /* Allow propagations into a loop only for reg-to-reg copies, since
+e7a7dbb5ca5d gcc/fwprop.c  (liuhongt            2021-12-20 11:13:38 +0800  854)      replacing one register by another shouldn't increase the cost.
+e7a7dbb5ca5d gcc/fwprop.c  (liuhongt            2021-12-20 11:13:38 +0800  855)      Propagations from inner loop to outer loop should also be ok.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  856)   struct loop *def_loop = def_insn->bb ()->cfg_bb ()->loop_father;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  857)   struct loop *use_loop = use->bb ()->cfg_bb ()->loop_father;
+e7a7dbb5ca5d gcc/fwprop.c  (liuhongt            2021-12-20 11:13:38 +0800  858)   if ((reg_prop_only
+e7a7dbb5ca5d gcc/fwprop.c  (liuhongt            2021-12-20 11:13:38 +0800  859)        || (def_loop != use_loop
+e7a7dbb5ca5d gcc/fwprop.c  (liuhongt            2021-12-20 11:13:38 +0800  860)           && !flow_loop_nested_p (use_loop, def_loop)))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  861)       && (!reg_single_def_p (dest) || !reg_single_def_p (src)))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  862)     return false;
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  863) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  864)   /* Don't substitute into a non-local goto, this confuses CFG.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  865)   insn_info *use_insn = use->insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  866)   rtx_insn *use_rtl = use_insn->rtl ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  867)   if (JUMP_P (use_rtl)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  868)       && find_reg_note (use_rtl, REG_NON_LOCAL_GOTO, NULL_RTX))
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  869)     return false;
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  870) 
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  871)   if (forward_propagate_and_simplify (use, def, dest, src)
+b61461ac7f9b gcc/fwprop.c  (Ilya Leoshkevich    2021-03-02 23:37:26 +0100  872)       || forward_propagate_subreg (use, def, dest, src))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  873)     return true;
+a5a9046deb1a gcc/fwprop.c  (Segher Boessenkool  2017-04-01 00:49:53 +0200  874) 
+7360d2ac8dae gcc/fwprop.c  (Jakub Jelinek       2011-01-21 20:34:03 +0100  875)   return false;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  876) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  877) \f
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  878) static void
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  879) fwprop_init (void)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  880) {
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  881)   num_changes = 0;
+6e0b633f6c2b gcc/fwprop.c  (Paolo Bonzini       2006-11-14 08:46:26 +0000  882)   calculate_dominance_info (CDI_DOMINATORS);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  883) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  884)   /* We do not always want to propagate into loops, so we have to find
+c5f4be845ac0 gcc/fwprop.c  (Steven Bosscher     2013-01-31 20:16:07 +0000  885)      loops and be careful about them.  Avoid CFG modifications so that
+c5f4be845ac0 gcc/fwprop.c  (Steven Bosscher     2013-01-31 20:16:07 +0000  886)      we don't have to update dominance information afterwards for
+c5f4be845ac0 gcc/fwprop.c  (Steven Bosscher     2013-01-31 20:16:07 +0000  887)      build_single_def_use_links.  */
+c5f4be845ac0 gcc/fwprop.c  (Steven Bosscher     2013-01-31 20:16:07 +0000  888)   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  889) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  890)   df_analyze ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  891)   crtl->ssa = new rtl_ssa::function_info (cfun);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  892) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  893) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  894) static void
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  895) fwprop_done (void)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  896) {
+fb4061627b2c gcc/fwprop.c  (Paolo Bonzini       2007-03-20 08:31:13 +0000  897)   loop_optimizer_finalize ();
+6fb5fa3cbc0d gcc/fwprop.c  (Daniel Berlin       2007-06-11 18:02:15 +0000  898) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  899)   crtl->ssa->perform_pending_updates ();
+6e0b633f6c2b gcc/fwprop.c  (Paolo Bonzini       2006-11-14 08:46:26 +0000  900)   free_dominance_info (CDI_DOMINATORS);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  901)   cleanup_cfg (0);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  902) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  903)   delete crtl->ssa;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  904)   crtl->ssa = nullptr;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  905) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  906)   delete_trivially_dead_insns (get_insns (), max_reg_num ());
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  907) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  908)   if (dump_file)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  909)     fprintf (dump_file,
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  910)             "\nNumber of successful forward propagations: %d\n\n",
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  911)             num_changes);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  912) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  913) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  914) /* Try to optimize INSN, returning true if something changes.
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  915)    FWPROP_ADDR_P is true if we are running fwprop_addr rather than
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  916)    the full fwprop.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  917) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  918) static bool
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  919) fwprop_insn (insn_info *insn, bool fwprop_addr_p)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  920) {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  921)   for (use_info *use : insn->uses ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  922)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  923)       if (use->is_mem ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  924)        continue;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  925)       /* ??? The choices here follow those in the pre-SSA code.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  926)       if (!use->includes_address_uses ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  927)        {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  928)          if (forward_propagate_into (use, fwprop_addr_p))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  929)            return true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  930)        }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  931)       else
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  932)        {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  933)          struct loop *loop = insn->bb ()->cfg_bb ()->loop_father;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  934)          /* The outermost loop is not really a loop.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  935)          if (loop == NULL || loop_outer (loop) == NULL)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  936)            {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  937)              if (forward_propagate_into (use, fwprop_addr_p))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  938)                return true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  939)            }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  940)          else if (fwprop_addr_p)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  941)            {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  942)              if (forward_propagate_into (use, false))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  943)                return true;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  944)            }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  945)        }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  946)     }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  947)   return false;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  948) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  949) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  950) /* Main entry point.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  951) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  952) static bool
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  953) gate_fwprop (void)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  954) {
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  955)   return optimize > 0 && flag_forward_propagate;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  956) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  957) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  958) static unsigned int
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  959) fwprop (bool fwprop_addr_p)
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  960) {
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  961)   fwprop_init ();
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  962) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  963)   /* Go through all the instructions (including debug instructions) looking
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  964)      for uses that we could propagate into.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  965) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  966)      Do not forward propagate addresses into loops until after unrolling.
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  967)      CSE did so because it was able to fix its own mess, but we are not.  */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  968) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  969)   insn_info *next;
+75da268e1a56 gcc/fwprop.c  (Prathamesh Kulkarni 2019-07-04 06:48:42 +0000  970) 
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  971)   /* ??? This code uses a worklist in order to preserve the behavior
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  972)      of the pre-SSA implementation.  It would be better to instead
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  973)      iterate on each instruction until no more propagations are
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  974)      possible, then move on to the next.  */
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  975)   auto_vec<insn_info *> worklist;
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  976)   for (insn_info *insn = crtl->ssa->first_insn (); insn; insn = next)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  977)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  978)       next = insn->next_any_insn ();
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  979)       if (insn->can_be_optimized () || insn->is_debug_insn ())
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  980)        if (fwprop_insn (insn, fwprop_addr_p))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  981)          worklist.safe_push (insn);
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  982)     }
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  983)   for (unsigned int i = 0; i < worklist.length (); ++i)
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  984)     {
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  985)       insn_info *insn = worklist[i];
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  986)       if (fwprop_insn (insn, fwprop_addr_p))
+0b76990a9d75 gcc/fwprop.c  (Richard Sandiford   2020-12-17 00:15:12 +0000  987)        worklist.safe_push (insn);
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  988)     }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  989) 
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  990)   fwprop_done ();
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  991)   return 0;
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  992) }
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  993) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000  994) namespace {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000  995) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000  996) const pass_data pass_data_rtl_fwprop =
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000  997) {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000  998)   RTL_PASS, /* type */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000  999)   "fwprop1", /* name */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1000)   OPTGROUP_NONE, /* optinfo_flags */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1001)   TV_FWPROP, /* tv_id */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1002)   0, /* properties_required */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1003)   0, /* properties_provided */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1004)   0, /* properties_destroyed */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1005)   0, /* todo_flags_start */
+3bea341fbd27 gcc/fwprop.c  (Richard Biener      2014-05-06 13:35:40 +0000 1006)   TODO_df_finish, /* todo_flags_finish */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000 1007) };
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000 1008) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1009) class pass_rtl_fwprop : public rtl_opt_pass
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1010) {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1011) public:
+c3284718808c gcc/fwprop.c  (Richard Sandiford   2013-09-28 08:42:34 +0000 1012)   pass_rtl_fwprop (gcc::context *ctxt)
+c3284718808c gcc/fwprop.c  (Richard Sandiford   2013-09-28 08:42:34 +0000 1013)     : rtl_opt_pass (pass_data_rtl_fwprop, ctxt)
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1014)   {}
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1015) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1016)   /* opt_pass methods: */
+725793af7806 gcc/fwprop.cc (David Malcolm       2022-06-27 17:00:33 -0400 1017)   bool gate (function *) final override { return gate_fwprop (); }
+725793af7806 gcc/fwprop.cc (David Malcolm       2022-06-27 17:00:33 -0400 1018)   unsigned int execute (function *) final override { return fwprop (false); }
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1019) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1020) }; // class pass_rtl_fwprop
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1021) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1022) } // anon namespace
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1023) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1024) rtl_opt_pass *
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1025) make_pass_rtl_fwprop (gcc::context *ctxt)
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1026) {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1027)   return new pass_rtl_fwprop (ctxt);
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1028) }
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1029) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1030) namespace {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1031) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1032) const pass_data pass_data_rtl_fwprop_addr =
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000 1033) {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1034)   RTL_PASS, /* type */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1035)   "fwprop2", /* name */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1036)   OPTGROUP_NONE, /* optinfo_flags */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1037)   TV_FWPROP, /* tv_id */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1038)   0, /* properties_required */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1039)   0, /* properties_provided */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1040)   0, /* properties_destroyed */
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1041)   0, /* todo_flags_start */
+3bea341fbd27 gcc/fwprop.c  (Richard Biener      2014-05-06 13:35:40 +0000 1042)   TODO_df_finish, /* todo_flags_finish */
+a52b023a5f03 gcc/fwprop.c  (Paolo Bonzini       2006-11-04 08:36:45 +0000 1043) };
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1044) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1045) class pass_rtl_fwprop_addr : public rtl_opt_pass
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1046) {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1047) public:
+c3284718808c gcc/fwprop.c  (Richard Sandiford   2013-09-28 08:42:34 +0000 1048)   pass_rtl_fwprop_addr (gcc::context *ctxt)
+c3284718808c gcc/fwprop.c  (Richard Sandiford   2013-09-28 08:42:34 +0000 1049)     : rtl_opt_pass (pass_data_rtl_fwprop_addr, ctxt)
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1050)   {}
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1051) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1052)   /* opt_pass methods: */
+725793af7806 gcc/fwprop.cc (David Malcolm       2022-06-27 17:00:33 -0400 1053)   bool gate (function *) final override { return gate_fwprop (); }
+725793af7806 gcc/fwprop.cc (David Malcolm       2022-06-27 17:00:33 -0400 1054)   unsigned int execute (function *) final override { return fwprop (true); }
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1055) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1056) }; // class pass_rtl_fwprop_addr
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1057) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1058) } // anon namespace
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1059) 
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1060) rtl_opt_pass *
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1061) make_pass_rtl_fwprop_addr (gcc::context *ctxt)
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1062) {
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1063)   return new pass_rtl_fwprop_addr (ctxt);
+27a4cd485d37 gcc/fwprop.c  (David Malcolm       2013-08-05 20:16:05 +0000 1064) }
index 789faf66cb8ea8d652362c10234fc93bc8d45e7a..6f7efafb8abecf38f219ea5ef8469ca3bec0c5ff 100644 (file)
 ;; for IOR/XOR.  It probably doesn't matter for AND.
 ;;
 ;; We also don't want to do this if the immediate already fits in a simm12
-;; field.
+;; field, or is a single bit operand, or when we might be able to generate
+;; a shift-add sequence via the splitter in bitmanip.md
+;; in bitmanip.md for masks that are a run of consecutive ones.
 (define_insn_and_split "<optab>_shift_reverse<X:mode>"
   [(set (match_operand:X 0 "register_operand" "=r")
     (any_bitwise:X (ashift:X (match_operand:X 1 "register_operand" "r")
   "(!SMALL_OPERAND (INTVAL (operands[3]))
     && SMALL_OPERAND (INTVAL (operands[3]) >> INTVAL (operands[2]))
     && popcount_hwi (INTVAL (operands[3])) > 1
-    && (!TARGET_64BIT
-       || (exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1)
-            == -1))
+    && (!(TARGET_64BIT && TARGET_ZBA)
+       || !consecutive_bits_operand (operands[3], VOIDmode)
+       || !imm123_operand (operands[2], VOIDmode))
     && (INTVAL (operands[3]) & ((1ULL << INTVAL (operands[2])) - 1)) == 0)"
   "#"
   "&& 1"
diff --git a/gcc/testsuite/gcc.target/riscv/pr115921.c b/gcc/testsuite/gcc.target/riscv/pr115921.c
new file mode 100644 (file)
index 0000000..e508e7c
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64gc_zba" { target { rv64 } } }  */
+/* { dg-options "-O2 -march=rv32gc_zba" { target { rv32 } } }  */
+
+typedef unsigned long target_wide_uint_t;
+
+target_wide_uint_t test_ashift_and(target_wide_uint_t x) {
+    return (x & 0x3f) << 12;
+}
+
+/* { dg-final { scan-assembler-times "\\sandi" 1 } } */
+/* { dg-final { scan-assembler-times "\\sslli" 1 } } */
+