aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra.cc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-01-14 16:56:44 +0100
committerMartin Liska <mliska@suse.cz>2022-01-17 22:12:04 +0100
commit5c69acb32329d49e58c26fa41ae74229a52b9106 (patch)
treeddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/lra.cc
parent490e23032baaece71f2ec09fa1805064b150fbc2 (diff)
downloadgcc-5c69acb32329d49e58c26fa41ae74229a52b9106.zip
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.gz
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.bz2
Rename .c files to .cc files.
gcc/ada/ChangeLog: * adadecode.c: Moved to... * adadecode.cc: ...here. * affinity.c: Moved to... * affinity.cc: ...here. * argv-lynxos178-raven-cert.c: Moved to... * argv-lynxos178-raven-cert.cc: ...here. * argv.c: Moved to... * argv.cc: ...here. * aux-io.c: Moved to... * aux-io.cc: ...here. * cio.c: Moved to... * cio.cc: ...here. * cstreams.c: Moved to... * cstreams.cc: ...here. * env.c: Moved to... * env.cc: ...here. * exit.c: Moved to... * exit.cc: ...here. * expect.c: Moved to... * expect.cc: ...here. * final.c: Moved to... * final.cc: ...here. * gcc-interface/cuintp.c: Moved to... * gcc-interface/cuintp.cc: ...here. * gcc-interface/decl.c: Moved to... * gcc-interface/decl.cc: ...here. * gcc-interface/misc.c: Moved to... * gcc-interface/misc.cc: ...here. * gcc-interface/targtyps.c: Moved to... * gcc-interface/targtyps.cc: ...here. * gcc-interface/trans.c: Moved to... * gcc-interface/trans.cc: ...here. * gcc-interface/utils.c: Moved to... * gcc-interface/utils.cc: ...here. * gcc-interface/utils2.c: Moved to... * gcc-interface/utils2.cc: ...here. * init.c: Moved to... * init.cc: ...here. * initialize.c: Moved to... * initialize.cc: ...here. * libgnarl/thread.c: Moved to... * libgnarl/thread.cc: ...here. * link.c: Moved to... * link.cc: ...here. * locales.c: Moved to... * locales.cc: ...here. * mkdir.c: Moved to... * mkdir.cc: ...here. * raise.c: Moved to... * raise.cc: ...here. * rtfinal.c: Moved to... * rtfinal.cc: ...here. * rtinit.c: Moved to... * rtinit.cc: ...here. * seh_init.c: Moved to... * seh_init.cc: ...here. * sigtramp-armdroid.c: Moved to... * sigtramp-armdroid.cc: ...here. * sigtramp-ios.c: Moved to... * sigtramp-ios.cc: ...here. * sigtramp-qnx.c: Moved to... * sigtramp-qnx.cc: ...here. * sigtramp-vxworks.c: Moved to... * sigtramp-vxworks.cc: ...here. * socket.c: Moved to... * socket.cc: ...here. * tracebak.c: Moved to... * tracebak.cc: ...here. * version.c: Moved to... * version.cc: ...here. * vx_stack_info.c: Moved to... * vx_stack_info.cc: ...here. gcc/ChangeLog: * adjust-alignment.c: Moved to... * adjust-alignment.cc: ...here. * alias.c: Moved to... * alias.cc: ...here. * alloc-pool.c: Moved to... * alloc-pool.cc: ...here. * asan.c: Moved to... * asan.cc: ...here. * attribs.c: Moved to... * attribs.cc: ...here. * auto-inc-dec.c: Moved to... * auto-inc-dec.cc: ...here. * auto-profile.c: Moved to... * auto-profile.cc: ...here. * bb-reorder.c: Moved to... * bb-reorder.cc: ...here. * bitmap.c: Moved to... * bitmap.cc: ...here. * btfout.c: Moved to... * btfout.cc: ...here. * builtins.c: Moved to... * builtins.cc: ...here. * caller-save.c: Moved to... * caller-save.cc: ...here. * calls.c: Moved to... * calls.cc: ...here. * ccmp.c: Moved to... * ccmp.cc: ...here. * cfg.c: Moved to... * cfg.cc: ...here. * cfganal.c: Moved to... * cfganal.cc: ...here. * cfgbuild.c: Moved to... * cfgbuild.cc: ...here. * cfgcleanup.c: Moved to... * cfgcleanup.cc: ...here. * cfgexpand.c: Moved to... * cfgexpand.cc: ...here. * cfghooks.c: Moved to... * cfghooks.cc: ...here. * cfgloop.c: Moved to... * cfgloop.cc: ...here. * cfgloopanal.c: Moved to... * cfgloopanal.cc: ...here. * cfgloopmanip.c: Moved to... * cfgloopmanip.cc: ...here. * cfgrtl.c: Moved to... * cfgrtl.cc: ...here. * cgraph.c: Moved to... * cgraph.cc: ...here. * cgraphbuild.c: Moved to... * cgraphbuild.cc: ...here. * cgraphclones.c: Moved to... * cgraphclones.cc: ...here. * cgraphunit.c: Moved to... * cgraphunit.cc: ...here. * collect-utils.c: Moved to... * collect-utils.cc: ...here. * collect2-aix.c: Moved to... * collect2-aix.cc: ...here. * collect2.c: Moved to... * collect2.cc: ...here. * combine-stack-adj.c: Moved to... * combine-stack-adj.cc: ...here. * combine.c: Moved to... * combine.cc: ...here. * common/common-targhooks.c: Moved to... * common/common-targhooks.cc: ...here. * common/config/aarch64/aarch64-common.c: Moved to... * common/config/aarch64/aarch64-common.cc: ...here. * common/config/alpha/alpha-common.c: Moved to... * common/config/alpha/alpha-common.cc: ...here. * common/config/arc/arc-common.c: Moved to... * common/config/arc/arc-common.cc: ...here. * common/config/arm/arm-common.c: Moved to... * common/config/arm/arm-common.cc: ...here. * common/config/avr/avr-common.c: Moved to... * common/config/avr/avr-common.cc: ...here. * common/config/bfin/bfin-common.c: Moved to... * common/config/bfin/bfin-common.cc: ...here. * common/config/bpf/bpf-common.c: Moved to... * common/config/bpf/bpf-common.cc: ...here. * common/config/c6x/c6x-common.c: Moved to... * common/config/c6x/c6x-common.cc: ...here. * common/config/cr16/cr16-common.c: Moved to... * common/config/cr16/cr16-common.cc: ...here. * common/config/cris/cris-common.c: Moved to... * common/config/cris/cris-common.cc: ...here. * common/config/csky/csky-common.c: Moved to... * common/config/csky/csky-common.cc: ...here. * common/config/default-common.c: Moved to... * common/config/default-common.cc: ...here. * common/config/epiphany/epiphany-common.c: Moved to... * common/config/epiphany/epiphany-common.cc: ...here. * common/config/fr30/fr30-common.c: Moved to... * common/config/fr30/fr30-common.cc: ...here. * common/config/frv/frv-common.c: Moved to... * common/config/frv/frv-common.cc: ...here. * common/config/gcn/gcn-common.c: Moved to... * common/config/gcn/gcn-common.cc: ...here. * common/config/h8300/h8300-common.c: Moved to... * common/config/h8300/h8300-common.cc: ...here. * common/config/i386/i386-common.c: Moved to... * common/config/i386/i386-common.cc: ...here. * common/config/ia64/ia64-common.c: Moved to... * common/config/ia64/ia64-common.cc: ...here. * common/config/iq2000/iq2000-common.c: Moved to... * common/config/iq2000/iq2000-common.cc: ...here. * common/config/lm32/lm32-common.c: Moved to... * common/config/lm32/lm32-common.cc: ...here. * common/config/m32r/m32r-common.c: Moved to... * common/config/m32r/m32r-common.cc: ...here. * common/config/m68k/m68k-common.c: Moved to... * common/config/m68k/m68k-common.cc: ...here. * common/config/mcore/mcore-common.c: Moved to... * common/config/mcore/mcore-common.cc: ...here. * common/config/microblaze/microblaze-common.c: Moved to... * common/config/microblaze/microblaze-common.cc: ...here. * common/config/mips/mips-common.c: Moved to... * common/config/mips/mips-common.cc: ...here. * common/config/mmix/mmix-common.c: Moved to... * common/config/mmix/mmix-common.cc: ...here. * common/config/mn10300/mn10300-common.c: Moved to... * common/config/mn10300/mn10300-common.cc: ...here. * common/config/msp430/msp430-common.c: Moved to... * common/config/msp430/msp430-common.cc: ...here. * common/config/nds32/nds32-common.c: Moved to... * common/config/nds32/nds32-common.cc: ...here. * common/config/nios2/nios2-common.c: Moved to... * common/config/nios2/nios2-common.cc: ...here. * common/config/nvptx/nvptx-common.c: Moved to... * common/config/nvptx/nvptx-common.cc: ...here. * common/config/or1k/or1k-common.c: Moved to... * common/config/or1k/or1k-common.cc: ...here. * common/config/pa/pa-common.c: Moved to... * common/config/pa/pa-common.cc: ...here. * common/config/pdp11/pdp11-common.c: Moved to... * common/config/pdp11/pdp11-common.cc: ...here. * common/config/pru/pru-common.c: Moved to... * common/config/pru/pru-common.cc: ...here. * common/config/riscv/riscv-common.c: Moved to... * common/config/riscv/riscv-common.cc: ...here. * common/config/rs6000/rs6000-common.c: Moved to... * common/config/rs6000/rs6000-common.cc: ...here. * common/config/rx/rx-common.c: Moved to... * common/config/rx/rx-common.cc: ...here. * common/config/s390/s390-common.c: Moved to... * common/config/s390/s390-common.cc: ...here. * common/config/sh/sh-common.c: Moved to... * common/config/sh/sh-common.cc: ...here. * common/config/sparc/sparc-common.c: Moved to... * common/config/sparc/sparc-common.cc: ...here. * common/config/tilegx/tilegx-common.c: Moved to... * common/config/tilegx/tilegx-common.cc: ...here. * common/config/tilepro/tilepro-common.c: Moved to... * common/config/tilepro/tilepro-common.cc: ...here. * common/config/v850/v850-common.c: Moved to... * common/config/v850/v850-common.cc: ...here. * common/config/vax/vax-common.c: Moved to... * common/config/vax/vax-common.cc: ...here. * common/config/visium/visium-common.c: Moved to... * common/config/visium/visium-common.cc: ...here. * common/config/xstormy16/xstormy16-common.c: Moved to... * common/config/xstormy16/xstormy16-common.cc: ...here. * common/config/xtensa/xtensa-common.c: Moved to... * common/config/xtensa/xtensa-common.cc: ...here. * compare-elim.c: Moved to... * compare-elim.cc: ...here. * config/aarch64/aarch64-bti-insert.c: Moved to... * config/aarch64/aarch64-bti-insert.cc: ...here. * config/aarch64/aarch64-builtins.c: Moved to... * config/aarch64/aarch64-builtins.cc: ...here. * config/aarch64/aarch64-c.c: Moved to... * config/aarch64/aarch64-c.cc: ...here. * config/aarch64/aarch64-d.c: Moved to... * config/aarch64/aarch64-d.cc: ...here. * config/aarch64/aarch64.c: Moved to... * config/aarch64/aarch64.cc: ...here. * config/aarch64/cortex-a57-fma-steering.c: Moved to... * config/aarch64/cortex-a57-fma-steering.cc: ...here. * config/aarch64/driver-aarch64.c: Moved to... * config/aarch64/driver-aarch64.cc: ...here. * config/aarch64/falkor-tag-collision-avoidance.c: Moved to... * config/aarch64/falkor-tag-collision-avoidance.cc: ...here. * config/aarch64/host-aarch64-darwin.c: Moved to... * config/aarch64/host-aarch64-darwin.cc: ...here. * config/alpha/alpha.c: Moved to... * config/alpha/alpha.cc: ...here. * config/alpha/driver-alpha.c: Moved to... * config/alpha/driver-alpha.cc: ...here. * config/arc/arc-c.c: Moved to... * config/arc/arc-c.cc: ...here. * config/arc/arc.c: Moved to... * config/arc/arc.cc: ...here. * config/arc/driver-arc.c: Moved to... * config/arc/driver-arc.cc: ...here. * config/arm/aarch-common.c: Moved to... * config/arm/aarch-common.cc: ...here. * config/arm/arm-builtins.c: Moved to... * config/arm/arm-builtins.cc: ...here. * config/arm/arm-c.c: Moved to... * config/arm/arm-c.cc: ...here. * config/arm/arm-d.c: Moved to... * config/arm/arm-d.cc: ...here. * config/arm/arm.c: Moved to... * config/arm/arm.cc: ...here. * config/arm/driver-arm.c: Moved to... * config/arm/driver-arm.cc: ...here. * config/avr/avr-c.c: Moved to... * config/avr/avr-c.cc: ...here. * config/avr/avr-devices.c: Moved to... * config/avr/avr-devices.cc: ...here. * config/avr/avr-log.c: Moved to... * config/avr/avr-log.cc: ...here. * config/avr/avr.c: Moved to... * config/avr/avr.cc: ...here. * config/avr/driver-avr.c: Moved to... * config/avr/driver-avr.cc: ...here. * config/avr/gen-avr-mmcu-specs.c: Moved to... * config/avr/gen-avr-mmcu-specs.cc: ...here. * config/avr/gen-avr-mmcu-texi.c: Moved to... * config/avr/gen-avr-mmcu-texi.cc: ...here. * config/bfin/bfin.c: Moved to... * config/bfin/bfin.cc: ...here. * config/bpf/bpf.c: Moved to... * config/bpf/bpf.cc: ...here. * config/bpf/coreout.c: Moved to... * config/bpf/coreout.cc: ...here. * config/c6x/c6x.c: Moved to... * config/c6x/c6x.cc: ...here. * config/cr16/cr16.c: Moved to... * config/cr16/cr16.cc: ...here. * config/cris/cris.c: Moved to... * config/cris/cris.cc: ...here. * config/csky/csky.c: Moved to... * config/csky/csky.cc: ...here. * config/darwin-c.c: Moved to... * config/darwin-c.cc: ...here. * config/darwin-d.c: Moved to... * config/darwin-d.cc: ...here. * config/darwin-driver.c: Moved to... * config/darwin-driver.cc: ...here. * config/darwin-f.c: Moved to... * config/darwin-f.cc: ...here. * config/darwin.c: Moved to... * config/darwin.cc: ...here. * config/default-c.c: Moved to... * config/default-c.cc: ...here. * config/default-d.c: Moved to... * config/default-d.cc: ...here. * config/dragonfly-d.c: Moved to... * config/dragonfly-d.cc: ...here. * config/epiphany/epiphany.c: Moved to... * config/epiphany/epiphany.cc: ...here. * config/epiphany/mode-switch-use.c: Moved to... * config/epiphany/mode-switch-use.cc: ...here. * config/epiphany/resolve-sw-modes.c: Moved to... * config/epiphany/resolve-sw-modes.cc: ...here. * config/fr30/fr30.c: Moved to... * config/fr30/fr30.cc: ...here. * config/freebsd-d.c: Moved to... * config/freebsd-d.cc: ...here. * config/frv/frv.c: Moved to... * config/frv/frv.cc: ...here. * config/ft32/ft32.c: Moved to... * config/ft32/ft32.cc: ...here. * config/gcn/driver-gcn.c: Moved to... * config/gcn/driver-gcn.cc: ...here. * config/gcn/gcn-run.c: Moved to... * config/gcn/gcn-run.cc: ...here. * config/gcn/gcn-tree.c: Moved to... * config/gcn/gcn-tree.cc: ...here. * config/gcn/gcn.c: Moved to... * config/gcn/gcn.cc: ...here. * config/gcn/mkoffload.c: Moved to... * config/gcn/mkoffload.cc: ...here. * config/glibc-c.c: Moved to... * config/glibc-c.cc: ...here. * config/glibc-d.c: Moved to... * config/glibc-d.cc: ...here. * config/h8300/h8300.c: Moved to... * config/h8300/h8300.cc: ...here. * config/host-darwin.c: Moved to... * config/host-darwin.cc: ...here. * config/host-hpux.c: Moved to... * config/host-hpux.cc: ...here. * config/host-linux.c: Moved to... * config/host-linux.cc: ...here. * config/host-netbsd.c: Moved to... * config/host-netbsd.cc: ...here. * config/host-openbsd.c: Moved to... * config/host-openbsd.cc: ...here. * config/host-solaris.c: Moved to... * config/host-solaris.cc: ...here. * config/i386/djgpp.c: Moved to... * config/i386/djgpp.cc: ...here. * config/i386/driver-i386.c: Moved to... * config/i386/driver-i386.cc: ...here. * config/i386/driver-mingw32.c: Moved to... * config/i386/driver-mingw32.cc: ...here. * config/i386/gnu-property.c: Moved to... * config/i386/gnu-property.cc: ...here. * config/i386/host-cygwin.c: Moved to... * config/i386/host-cygwin.cc: ...here. * config/i386/host-i386-darwin.c: Moved to... * config/i386/host-i386-darwin.cc: ...here. * config/i386/host-mingw32.c: Moved to... * config/i386/host-mingw32.cc: ...here. * config/i386/i386-builtins.c: Moved to... * config/i386/i386-builtins.cc: ...here. * config/i386/i386-c.c: Moved to... * config/i386/i386-c.cc: ...here. * config/i386/i386-d.c: Moved to... * config/i386/i386-d.cc: ...here. * config/i386/i386-expand.c: Moved to... * config/i386/i386-expand.cc: ...here. * config/i386/i386-features.c: Moved to... * config/i386/i386-features.cc: ...here. * config/i386/i386-options.c: Moved to... * config/i386/i386-options.cc: ...here. * config/i386/i386.c: Moved to... * config/i386/i386.cc: ...here. * config/i386/intelmic-mkoffload.c: Moved to... * config/i386/intelmic-mkoffload.cc: ...here. * config/i386/msformat-c.c: Moved to... * config/i386/msformat-c.cc: ...here. * config/i386/winnt-cxx.c: Moved to... * config/i386/winnt-cxx.cc: ...here. * config/i386/winnt-d.c: Moved to... * config/i386/winnt-d.cc: ...here. * config/i386/winnt-stubs.c: Moved to... * config/i386/winnt-stubs.cc: ...here. * config/i386/winnt.c: Moved to... * config/i386/winnt.cc: ...here. * config/i386/x86-tune-sched-atom.c: Moved to... * config/i386/x86-tune-sched-atom.cc: ...here. * config/i386/x86-tune-sched-bd.c: Moved to... * config/i386/x86-tune-sched-bd.cc: ...here. * config/i386/x86-tune-sched-core.c: Moved to... * config/i386/x86-tune-sched-core.cc: ...here. * config/i386/x86-tune-sched.c: Moved to... * config/i386/x86-tune-sched.cc: ...here. * config/ia64/ia64-c.c: Moved to... * config/ia64/ia64-c.cc: ...here. * config/ia64/ia64.c: Moved to... * config/ia64/ia64.cc: ...here. * config/iq2000/iq2000.c: Moved to... * config/iq2000/iq2000.cc: ...here. * config/linux.c: Moved to... * config/linux.cc: ...here. * config/lm32/lm32.c: Moved to... * config/lm32/lm32.cc: ...here. * config/m32c/m32c-pragma.c: Moved to... * config/m32c/m32c-pragma.cc: ...here. * config/m32c/m32c.c: Moved to... * config/m32c/m32c.cc: ...here. * config/m32r/m32r.c: Moved to... * config/m32r/m32r.cc: ...here. * config/m68k/m68k.c: Moved to... * config/m68k/m68k.cc: ...here. * config/mcore/mcore.c: Moved to... * config/mcore/mcore.cc: ...here. * config/microblaze/microblaze-c.c: Moved to... * config/microblaze/microblaze-c.cc: ...here. * config/microblaze/microblaze.c: Moved to... * config/microblaze/microblaze.cc: ...here. * config/mips/driver-native.c: Moved to... * config/mips/driver-native.cc: ...here. * config/mips/frame-header-opt.c: Moved to... * config/mips/frame-header-opt.cc: ...here. * config/mips/mips-d.c: Moved to... * config/mips/mips-d.cc: ...here. * config/mips/mips.c: Moved to... * config/mips/mips.cc: ...here. * config/mmix/mmix.c: Moved to... * config/mmix/mmix.cc: ...here. * config/mn10300/mn10300.c: Moved to... * config/mn10300/mn10300.cc: ...here. * config/moxie/moxie.c: Moved to... * config/moxie/moxie.cc: ...here. * config/msp430/driver-msp430.c: Moved to... * config/msp430/driver-msp430.cc: ...here. * config/msp430/msp430-c.c: Moved to... * config/msp430/msp430-c.cc: ...here. * config/msp430/msp430-devices.c: Moved to... * config/msp430/msp430-devices.cc: ...here. * config/msp430/msp430.c: Moved to... * config/msp430/msp430.cc: ...here. * config/nds32/nds32-cost.c: Moved to... * config/nds32/nds32-cost.cc: ...here. * config/nds32/nds32-fp-as-gp.c: Moved to... * config/nds32/nds32-fp-as-gp.cc: ...here. * config/nds32/nds32-intrinsic.c: Moved to... * config/nds32/nds32-intrinsic.cc: ...here. * config/nds32/nds32-isr.c: Moved to... * config/nds32/nds32-isr.cc: ...here. * config/nds32/nds32-md-auxiliary.c: Moved to... * config/nds32/nds32-md-auxiliary.cc: ...here. * config/nds32/nds32-memory-manipulation.c: Moved to... * config/nds32/nds32-memory-manipulation.cc: ...here. * config/nds32/nds32-pipelines-auxiliary.c: Moved to... * config/nds32/nds32-pipelines-auxiliary.cc: ...here. * config/nds32/nds32-predicates.c: Moved to... * config/nds32/nds32-predicates.cc: ...here. * config/nds32/nds32-relax-opt.c: Moved to... * config/nds32/nds32-relax-opt.cc: ...here. * config/nds32/nds32-utils.c: Moved to... * config/nds32/nds32-utils.cc: ...here. * config/nds32/nds32.c: Moved to... * config/nds32/nds32.cc: ...here. * config/netbsd-d.c: Moved to... * config/netbsd-d.cc: ...here. * config/netbsd.c: Moved to... * config/netbsd.cc: ...here. * config/nios2/nios2.c: Moved to... * config/nios2/nios2.cc: ...here. * config/nvptx/mkoffload.c: Moved to... * config/nvptx/mkoffload.cc: ...here. * config/nvptx/nvptx-c.c: Moved to... * config/nvptx/nvptx-c.cc: ...here. * config/nvptx/nvptx.c: Moved to... * config/nvptx/nvptx.cc: ...here. * config/openbsd-d.c: Moved to... * config/openbsd-d.cc: ...here. * config/or1k/or1k.c: Moved to... * config/or1k/or1k.cc: ...here. * config/pa/pa-d.c: Moved to... * config/pa/pa-d.cc: ...here. * config/pa/pa.c: Moved to... * config/pa/pa.cc: ...here. * config/pdp11/pdp11.c: Moved to... * config/pdp11/pdp11.cc: ...here. * config/pru/pru-passes.c: Moved to... * config/pru/pru-passes.cc: ...here. * config/pru/pru-pragma.c: Moved to... * config/pru/pru-pragma.cc: ...here. * config/pru/pru.c: Moved to... * config/pru/pru.cc: ...here. * config/riscv/riscv-builtins.c: Moved to... * config/riscv/riscv-builtins.cc: ...here. * config/riscv/riscv-c.c: Moved to... * config/riscv/riscv-c.cc: ...here. * config/riscv/riscv-d.c: Moved to... * config/riscv/riscv-d.cc: ...here. * config/riscv/riscv-shorten-memrefs.c: Moved to... * config/riscv/riscv-shorten-memrefs.cc: ...here. * config/riscv/riscv-sr.c: Moved to... * config/riscv/riscv-sr.cc: ...here. * config/riscv/riscv.c: Moved to... * config/riscv/riscv.cc: ...here. * config/rl78/rl78-c.c: Moved to... * config/rl78/rl78-c.cc: ...here. * config/rl78/rl78.c: Moved to... * config/rl78/rl78.cc: ...here. * config/rs6000/driver-rs6000.c: Moved to... * config/rs6000/driver-rs6000.cc: ...here. * config/rs6000/host-darwin.c: Moved to... * config/rs6000/host-darwin.cc: ...here. * config/rs6000/host-ppc64-darwin.c: Moved to... * config/rs6000/host-ppc64-darwin.cc: ...here. * config/rs6000/rbtree.c: Moved to... * config/rs6000/rbtree.cc: ...here. * config/rs6000/rs6000-c.c: Moved to... * config/rs6000/rs6000-c.cc: ...here. * config/rs6000/rs6000-call.c: Moved to... * config/rs6000/rs6000-call.cc: ...here. * config/rs6000/rs6000-d.c: Moved to... * config/rs6000/rs6000-d.cc: ...here. * config/rs6000/rs6000-gen-builtins.c: Moved to... * config/rs6000/rs6000-gen-builtins.cc: ...here. * config/rs6000/rs6000-linux.c: Moved to... * config/rs6000/rs6000-linux.cc: ...here. * config/rs6000/rs6000-logue.c: Moved to... * config/rs6000/rs6000-logue.cc: ...here. * config/rs6000/rs6000-p8swap.c: Moved to... * config/rs6000/rs6000-p8swap.cc: ...here. * config/rs6000/rs6000-pcrel-opt.c: Moved to... * config/rs6000/rs6000-pcrel-opt.cc: ...here. * config/rs6000/rs6000-string.c: Moved to... * config/rs6000/rs6000-string.cc: ...here. * config/rs6000/rs6000.c: Moved to... * config/rs6000/rs6000.cc: ...here. * config/rx/rx.c: Moved to... * config/rx/rx.cc: ...here. * config/s390/driver-native.c: Moved to... * config/s390/driver-native.cc: ...here. * config/s390/s390-c.c: Moved to... * config/s390/s390-c.cc: ...here. * config/s390/s390-d.c: Moved to... * config/s390/s390-d.cc: ...here. * config/s390/s390.c: Moved to... * config/s390/s390.cc: ...here. * config/sh/divtab-sh4-300.c: Moved to... * config/sh/divtab-sh4-300.cc: ...here. * config/sh/divtab-sh4.c: Moved to... * config/sh/divtab-sh4.cc: ...here. * config/sh/divtab.c: Moved to... * config/sh/divtab.cc: ...here. * config/sh/sh-c.c: Moved to... * config/sh/sh-c.cc: ...here. * config/sh/sh.c: Moved to... * config/sh/sh.cc: ...here. * config/sol2-c.c: Moved to... * config/sol2-c.cc: ...here. * config/sol2-cxx.c: Moved to... * config/sol2-cxx.cc: ...here. * config/sol2-d.c: Moved to... * config/sol2-d.cc: ...here. * config/sol2-stubs.c: Moved to... * config/sol2-stubs.cc: ...here. * config/sol2.c: Moved to... * config/sol2.cc: ...here. * config/sparc/driver-sparc.c: Moved to... * config/sparc/driver-sparc.cc: ...here. * config/sparc/sparc-c.c: Moved to... * config/sparc/sparc-c.cc: ...here. * config/sparc/sparc-d.c: Moved to... * config/sparc/sparc-d.cc: ...here. * config/sparc/sparc.c: Moved to... * config/sparc/sparc.cc: ...here. * config/stormy16/stormy16.c: Moved to... * config/stormy16/stormy16.cc: ...here. * config/tilegx/mul-tables.c: Moved to... * config/tilegx/mul-tables.cc: ...here. * config/tilegx/tilegx-c.c: Moved to... * config/tilegx/tilegx-c.cc: ...here. * config/tilegx/tilegx.c: Moved to... * config/tilegx/tilegx.cc: ...here. * config/tilepro/mul-tables.c: Moved to... * config/tilepro/mul-tables.cc: ...here. * config/tilepro/tilepro-c.c: Moved to... * config/tilepro/tilepro-c.cc: ...here. * config/tilepro/tilepro.c: Moved to... * config/tilepro/tilepro.cc: ...here. * config/v850/v850-c.c: Moved to... * config/v850/v850-c.cc: ...here. * config/v850/v850.c: Moved to... * config/v850/v850.cc: ...here. * config/vax/vax.c: Moved to... * config/vax/vax.cc: ...here. * config/visium/visium.c: Moved to... * config/visium/visium.cc: ...here. * config/vms/vms-c.c: Moved to... * config/vms/vms-c.cc: ...here. * config/vms/vms-f.c: Moved to... * config/vms/vms-f.cc: ...here. * config/vms/vms.c: Moved to... * config/vms/vms.cc: ...here. * config/vxworks-c.c: Moved to... * config/vxworks-c.cc: ...here. * config/vxworks.c: Moved to... * config/vxworks.cc: ...here. * config/winnt-c.c: Moved to... * config/winnt-c.cc: ...here. * config/xtensa/xtensa.c: Moved to... * config/xtensa/xtensa.cc: ...here. * context.c: Moved to... * context.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * coverage.c: Moved to... * coverage.cc: ...here. * cppbuiltin.c: Moved to... * cppbuiltin.cc: ...here. * cppdefault.c: Moved to... * cppdefault.cc: ...here. * cprop.c: Moved to... * cprop.cc: ...here. * cse.c: Moved to... * cse.cc: ...here. * cselib.c: Moved to... * cselib.cc: ...here. * ctfc.c: Moved to... * ctfc.cc: ...here. * ctfout.c: Moved to... * ctfout.cc: ...here. * data-streamer-in.c: Moved to... * data-streamer-in.cc: ...here. * data-streamer-out.c: Moved to... * data-streamer-out.cc: ...here. * data-streamer.c: Moved to... * data-streamer.cc: ...here. * dbgcnt.c: Moved to... * dbgcnt.cc: ...here. * dbxout.c: Moved to... * dbxout.cc: ...here. * dce.c: Moved to... * dce.cc: ...here. * ddg.c: Moved to... * ddg.cc: ...here. * debug.c: Moved to... * debug.cc: ...here. * df-core.c: Moved to... * df-core.cc: ...here. * df-problems.c: Moved to... * df-problems.cc: ...here. * df-scan.c: Moved to... * df-scan.cc: ...here. * dfp.c: Moved to... * dfp.cc: ...here. * diagnostic-color.c: Moved to... * diagnostic-color.cc: ...here. * diagnostic-show-locus.c: Moved to... * diagnostic-show-locus.cc: ...here. * diagnostic-spec.c: Moved to... * diagnostic-spec.cc: ...here. * diagnostic.c: Moved to... * diagnostic.cc: ...here. * dojump.c: Moved to... * dojump.cc: ...here. * dominance.c: Moved to... * dominance.cc: ...here. * domwalk.c: Moved to... * domwalk.cc: ...here. * double-int.c: Moved to... * double-int.cc: ...here. * dse.c: Moved to... * dse.cc: ...here. * dumpfile.c: Moved to... * dumpfile.cc: ...here. * dwarf2asm.c: Moved to... * dwarf2asm.cc: ...here. * dwarf2cfi.c: Moved to... * dwarf2cfi.cc: ...here. * dwarf2ctf.c: Moved to... * dwarf2ctf.cc: ...here. * dwarf2out.c: Moved to... * dwarf2out.cc: ...here. * early-remat.c: Moved to... * early-remat.cc: ...here. * edit-context.c: Moved to... * edit-context.cc: ...here. * emit-rtl.c: Moved to... * emit-rtl.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * et-forest.c: Moved to... * et-forest.cc: ...here. * except.c: Moved to... * except.cc: ...here. * explow.c: Moved to... * explow.cc: ...here. * expmed.c: Moved to... * expmed.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * fibonacci_heap.c: Moved to... * fibonacci_heap.cc: ...here. * file-find.c: Moved to... * file-find.cc: ...here. * file-prefix-map.c: Moved to... * file-prefix-map.cc: ...here. * final.c: Moved to... * final.cc: ...here. * fixed-value.c: Moved to... * fixed-value.cc: ...here. * fold-const-call.c: Moved to... * fold-const-call.cc: ...here. * fold-const.c: Moved to... * fold-const.cc: ...here. * fp-test.c: Moved to... * fp-test.cc: ...here. * function-tests.c: Moved to... * function-tests.cc: ...here. * function.c: Moved to... * function.cc: ...here. * fwprop.c: Moved to... * fwprop.cc: ...here. * gcc-ar.c: Moved to... * gcc-ar.cc: ...here. * gcc-main.c: Moved to... * gcc-main.cc: ...here. * gcc-rich-location.c: Moved to... * gcc-rich-location.cc: ...here. * gcc.c: Moved to... * gcc.cc: ...here. * gcov-dump.c: Moved to... * gcov-dump.cc: ...here. * gcov-io.c: Moved to... * gcov-io.cc: ...here. * gcov-tool.c: Moved to... * gcov-tool.cc: ...here. * gcov.c: Moved to... * gcov.cc: ...here. * gcse-common.c: Moved to... * gcse-common.cc: ...here. * gcse.c: Moved to... * gcse.cc: ...here. * genattr-common.c: Moved to... * genattr-common.cc: ...here. * genattr.c: Moved to... * genattr.cc: ...here. * genattrtab.c: Moved to... * genattrtab.cc: ...here. * genautomata.c: Moved to... * genautomata.cc: ...here. * gencfn-macros.c: Moved to... * gencfn-macros.cc: ...here. * gencheck.c: Moved to... * gencheck.cc: ...here. * genchecksum.c: Moved to... * genchecksum.cc: ...here. * gencodes.c: Moved to... * gencodes.cc: ...here. * genconditions.c: Moved to... * genconditions.cc: ...here. * genconfig.c: Moved to... * genconfig.cc: ...here. * genconstants.c: Moved to... * genconstants.cc: ...here. * genemit.c: Moved to... * genemit.cc: ...here. * genenums.c: Moved to... * genenums.cc: ...here. * generic-match-head.c: Moved to... * generic-match-head.cc: ...here. * genextract.c: Moved to... * genextract.cc: ...here. * genflags.c: Moved to... * genflags.cc: ...here. * gengenrtl.c: Moved to... * gengenrtl.cc: ...here. * gengtype-parse.c: Moved to... * gengtype-parse.cc: ...here. * gengtype-state.c: Moved to... * gengtype-state.cc: ...here. * gengtype.c: Moved to... * gengtype.cc: ...here. * genhooks.c: Moved to... * genhooks.cc: ...here. * genmatch.c: Moved to... * genmatch.cc: ...here. * genmddeps.c: Moved to... * genmddeps.cc: ...here. * genmddump.c: Moved to... * genmddump.cc: ...here. * genmodes.c: Moved to... * genmodes.cc: ...here. * genopinit.c: Moved to... * genopinit.cc: ...here. * genoutput.c: Moved to... * genoutput.cc: ...here. * genpeep.c: Moved to... * genpeep.cc: ...here. * genpreds.c: Moved to... * genpreds.cc: ...here. * genrecog.c: Moved to... * genrecog.cc: ...here. * gensupport.c: Moved to... * gensupport.cc: ...here. * gentarget-def.c: Moved to... * gentarget-def.cc: ...here. * genversion.c: Moved to... * genversion.cc: ...here. * ggc-common.c: Moved to... * ggc-common.cc: ...here. * ggc-none.c: Moved to... * ggc-none.cc: ...here. * ggc-page.c: Moved to... * ggc-page.cc: ...here. * ggc-tests.c: Moved to... * ggc-tests.cc: ...here. * gimple-builder.c: Moved to... * gimple-builder.cc: ...here. * gimple-expr.c: Moved to... * gimple-expr.cc: ...here. * gimple-fold.c: Moved to... * gimple-fold.cc: ...here. * gimple-iterator.c: Moved to... * gimple-iterator.cc: ...here. * gimple-laddress.c: Moved to... * gimple-laddress.cc: ...here. * gimple-loop-jam.c: Moved to... * gimple-loop-jam.cc: ...here. * gimple-low.c: Moved to... * gimple-low.cc: ...here. * gimple-match-head.c: Moved to... * gimple-match-head.cc: ...here. * gimple-pretty-print.c: Moved to... * gimple-pretty-print.cc: ...here. * gimple-ssa-backprop.c: Moved to... * gimple-ssa-backprop.cc: ...here. * gimple-ssa-evrp-analyze.c: Moved to... * gimple-ssa-evrp-analyze.cc: ...here. * gimple-ssa-evrp.c: Moved to... * gimple-ssa-evrp.cc: ...here. * gimple-ssa-isolate-paths.c: Moved to... * gimple-ssa-isolate-paths.cc: ...here. * gimple-ssa-nonnull-compare.c: Moved to... * gimple-ssa-nonnull-compare.cc: ...here. * gimple-ssa-split-paths.c: Moved to... * gimple-ssa-split-paths.cc: ...here. * gimple-ssa-sprintf.c: Moved to... * gimple-ssa-sprintf.cc: ...here. * gimple-ssa-store-merging.c: Moved to... * gimple-ssa-store-merging.cc: ...here. * gimple-ssa-strength-reduction.c: Moved to... * gimple-ssa-strength-reduction.cc: ...here. * gimple-ssa-warn-alloca.c: Moved to... * gimple-ssa-warn-alloca.cc: ...here. * gimple-ssa-warn-restrict.c: Moved to... * gimple-ssa-warn-restrict.cc: ...here. * gimple-streamer-in.c: Moved to... * gimple-streamer-in.cc: ...here. * gimple-streamer-out.c: Moved to... * gimple-streamer-out.cc: ...here. * gimple-walk.c: Moved to... * gimple-walk.cc: ...here. * gimple-warn-recursion.c: Moved to... * gimple-warn-recursion.cc: ...here. * gimple.c: Moved to... * gimple.cc: ...here. * gimplify-me.c: Moved to... * gimplify-me.cc: ...here. * gimplify.c: Moved to... * gimplify.cc: ...here. * godump.c: Moved to... * godump.cc: ...here. * graph.c: Moved to... * graph.cc: ...here. * graphds.c: Moved to... * graphds.cc: ...here. * graphite-dependences.c: Moved to... * graphite-dependences.cc: ...here. * graphite-isl-ast-to-gimple.c: Moved to... * graphite-isl-ast-to-gimple.cc: ...here. * graphite-optimize-isl.c: Moved to... * graphite-optimize-isl.cc: ...here. * graphite-poly.c: Moved to... * graphite-poly.cc: ...here. * graphite-scop-detection.c: Moved to... * graphite-scop-detection.cc: ...here. * graphite-sese-to-poly.c: Moved to... * graphite-sese-to-poly.cc: ...here. * graphite.c: Moved to... * graphite.cc: ...here. * haifa-sched.c: Moved to... * haifa-sched.cc: ...here. * hash-map-tests.c: Moved to... * hash-map-tests.cc: ...here. * hash-set-tests.c: Moved to... * hash-set-tests.cc: ...here. * hash-table.c: Moved to... * hash-table.cc: ...here. * hooks.c: Moved to... * hooks.cc: ...here. * host-default.c: Moved to... * host-default.cc: ...here. * hw-doloop.c: Moved to... * hw-doloop.cc: ...here. * hwint.c: Moved to... * hwint.cc: ...here. * ifcvt.c: Moved to... * ifcvt.cc: ...here. * inchash.c: Moved to... * inchash.cc: ...here. * incpath.c: Moved to... * incpath.cc: ...here. * init-regs.c: Moved to... * init-regs.cc: ...here. * input.c: Moved to... * input.cc: ...here. * internal-fn.c: Moved to... * internal-fn.cc: ...here. * intl.c: Moved to... * intl.cc: ...here. * ipa-comdats.c: Moved to... * ipa-comdats.cc: ...here. * ipa-cp.c: Moved to... * ipa-cp.cc: ...here. * ipa-devirt.c: Moved to... * ipa-devirt.cc: ...here. * ipa-fnsummary.c: Moved to... * ipa-fnsummary.cc: ...here. * ipa-icf-gimple.c: Moved to... * ipa-icf-gimple.cc: ...here. * ipa-icf.c: Moved to... * ipa-icf.cc: ...here. * ipa-inline-analysis.c: Moved to... * ipa-inline-analysis.cc: ...here. * ipa-inline-transform.c: Moved to... * ipa-inline-transform.cc: ...here. * ipa-inline.c: Moved to... * ipa-inline.cc: ...here. * ipa-modref-tree.c: Moved to... * ipa-modref-tree.cc: ...here. * ipa-modref.c: Moved to... * ipa-modref.cc: ...here. * ipa-param-manipulation.c: Moved to... * ipa-param-manipulation.cc: ...here. * ipa-polymorphic-call.c: Moved to... * ipa-polymorphic-call.cc: ...here. * ipa-predicate.c: Moved to... * ipa-predicate.cc: ...here. * ipa-profile.c: Moved to... * ipa-profile.cc: ...here. * ipa-prop.c: Moved to... * ipa-prop.cc: ...here. * ipa-pure-const.c: Moved to... * ipa-pure-const.cc: ...here. * ipa-ref.c: Moved to... * ipa-ref.cc: ...here. * ipa-reference.c: Moved to... * ipa-reference.cc: ...here. * ipa-split.c: Moved to... * ipa-split.cc: ...here. * ipa-sra.c: Moved to... * ipa-sra.cc: ...here. * ipa-utils.c: Moved to... * ipa-utils.cc: ...here. * ipa-visibility.c: Moved to... * ipa-visibility.cc: ...here. * ipa.c: Moved to... * ipa.cc: ...here. * ira-build.c: Moved to... * ira-build.cc: ...here. * ira-color.c: Moved to... * ira-color.cc: ...here. * ira-conflicts.c: Moved to... * ira-conflicts.cc: ...here. * ira-costs.c: Moved to... * ira-costs.cc: ...here. * ira-emit.c: Moved to... * ira-emit.cc: ...here. * ira-lives.c: Moved to... * ira-lives.cc: ...here. * ira.c: Moved to... * ira.cc: ...here. * jump.c: Moved to... * jump.cc: ...here. * langhooks.c: Moved to... * langhooks.cc: ...here. * lcm.c: Moved to... * lcm.cc: ...here. * lists.c: Moved to... * lists.cc: ...here. * loop-doloop.c: Moved to... * loop-doloop.cc: ...here. * loop-init.c: Moved to... * loop-init.cc: ...here. * loop-invariant.c: Moved to... * loop-invariant.cc: ...here. * loop-iv.c: Moved to... * loop-iv.cc: ...here. * loop-unroll.c: Moved to... * loop-unroll.cc: ...here. * lower-subreg.c: Moved to... * lower-subreg.cc: ...here. * lra-assigns.c: Moved to... * lra-assigns.cc: ...here. * lra-coalesce.c: Moved to... * lra-coalesce.cc: ...here. * lra-constraints.c: Moved to... * lra-constraints.cc: ...here. * lra-eliminations.c: Moved to... * lra-eliminations.cc: ...here. * lra-lives.c: Moved to... * lra-lives.cc: ...here. * lra-remat.c: Moved to... * lra-remat.cc: ...here. * lra-spills.c: Moved to... * lra-spills.cc: ...here. * lra.c: Moved to... * lra.cc: ...here. * lto-cgraph.c: Moved to... * lto-cgraph.cc: ...here. * lto-compress.c: Moved to... * lto-compress.cc: ...here. * lto-opts.c: Moved to... * lto-opts.cc: ...here. * lto-section-in.c: Moved to... * lto-section-in.cc: ...here. * lto-section-out.c: Moved to... * lto-section-out.cc: ...here. * lto-streamer-in.c: Moved to... * lto-streamer-in.cc: ...here. * lto-streamer-out.c: Moved to... * lto-streamer-out.cc: ...here. * lto-streamer.c: Moved to... * lto-streamer.cc: ...here. * lto-wrapper.c: Moved to... * lto-wrapper.cc: ...here. * main.c: Moved to... * main.cc: ...here. * mcf.c: Moved to... * mcf.cc: ...here. * mode-switching.c: Moved to... * mode-switching.cc: ...here. * modulo-sched.c: Moved to... * modulo-sched.cc: ...here. * multiple_target.c: Moved to... * multiple_target.cc: ...here. * omp-expand.c: Moved to... * omp-expand.cc: ...here. * omp-general.c: Moved to... * omp-general.cc: ...here. * omp-low.c: Moved to... * omp-low.cc: ...here. * omp-offload.c: Moved to... * omp-offload.cc: ...here. * omp-simd-clone.c: Moved to... * omp-simd-clone.cc: ...here. * opt-suggestions.c: Moved to... * opt-suggestions.cc: ...here. * optabs-libfuncs.c: Moved to... * optabs-libfuncs.cc: ...here. * optabs-query.c: Moved to... * optabs-query.cc: ...here. * optabs-tree.c: Moved to... * optabs-tree.cc: ...here. * optabs.c: Moved to... * optabs.cc: ...here. * opts-common.c: Moved to... * opts-common.cc: ...here. * opts-global.c: Moved to... * opts-global.cc: ...here. * opts.c: Moved to... * opts.cc: ...here. * passes.c: Moved to... * passes.cc: ...here. * plugin.c: Moved to... * plugin.cc: ...here. * postreload-gcse.c: Moved to... * postreload-gcse.cc: ...here. * postreload.c: Moved to... * postreload.cc: ...here. * predict.c: Moved to... * predict.cc: ...here. * prefix.c: Moved to... * prefix.cc: ...here. * pretty-print.c: Moved to... * pretty-print.cc: ...here. * print-rtl-function.c: Moved to... * print-rtl-function.cc: ...here. * print-rtl.c: Moved to... * print-rtl.cc: ...here. * print-tree.c: Moved to... * print-tree.cc: ...here. * profile-count.c: Moved to... * profile-count.cc: ...here. * profile.c: Moved to... * profile.cc: ...here. * read-md.c: Moved to... * read-md.cc: ...here. * read-rtl-function.c: Moved to... * read-rtl-function.cc: ...here. * read-rtl.c: Moved to... * read-rtl.cc: ...here. * real.c: Moved to... * real.cc: ...here. * realmpfr.c: Moved to... * realmpfr.cc: ...here. * recog.c: Moved to... * recog.cc: ...here. * ree.c: Moved to... * ree.cc: ...here. * reg-stack.c: Moved to... * reg-stack.cc: ...here. * regcprop.c: Moved to... * regcprop.cc: ...here. * reginfo.c: Moved to... * reginfo.cc: ...here. * regrename.c: Moved to... * regrename.cc: ...here. * regstat.c: Moved to... * regstat.cc: ...here. * reload.c: Moved to... * reload.cc: ...here. * reload1.c: Moved to... * reload1.cc: ...here. * reorg.c: Moved to... * reorg.cc: ...here. * resource.c: Moved to... * resource.cc: ...here. * rtl-error.c: Moved to... * rtl-error.cc: ...here. * rtl-tests.c: Moved to... * rtl-tests.cc: ...here. * rtl.c: Moved to... * rtl.cc: ...here. * rtlanal.c: Moved to... * rtlanal.cc: ...here. * rtlhash.c: Moved to... * rtlhash.cc: ...here. * rtlhooks.c: Moved to... * rtlhooks.cc: ...here. * rtx-vector-builder.c: Moved to... * rtx-vector-builder.cc: ...here. * run-rtl-passes.c: Moved to... * run-rtl-passes.cc: ...here. * sancov.c: Moved to... * sancov.cc: ...here. * sanopt.c: Moved to... * sanopt.cc: ...here. * sbitmap.c: Moved to... * sbitmap.cc: ...here. * sched-deps.c: Moved to... * sched-deps.cc: ...here. * sched-ebb.c: Moved to... * sched-ebb.cc: ...here. * sched-rgn.c: Moved to... * sched-rgn.cc: ...here. * sel-sched-dump.c: Moved to... * sel-sched-dump.cc: ...here. * sel-sched-ir.c: Moved to... * sel-sched-ir.cc: ...here. * sel-sched.c: Moved to... * sel-sched.cc: ...here. * selftest-diagnostic.c: Moved to... * selftest-diagnostic.cc: ...here. * selftest-rtl.c: Moved to... * selftest-rtl.cc: ...here. * selftest-run-tests.c: Moved to... * selftest-run-tests.cc: ...here. * selftest.c: Moved to... * selftest.cc: ...here. * sese.c: Moved to... * sese.cc: ...here. * shrink-wrap.c: Moved to... * shrink-wrap.cc: ...here. * simplify-rtx.c: Moved to... * simplify-rtx.cc: ...here. * sparseset.c: Moved to... * sparseset.cc: ...here. * spellcheck-tree.c: Moved to... * spellcheck-tree.cc: ...here. * spellcheck.c: Moved to... * spellcheck.cc: ...here. * sreal.c: Moved to... * sreal.cc: ...here. * stack-ptr-mod.c: Moved to... * stack-ptr-mod.cc: ...here. * statistics.c: Moved to... * statistics.cc: ...here. * stmt.c: Moved to... * stmt.cc: ...here. * stor-layout.c: Moved to... * stor-layout.cc: ...here. * store-motion.c: Moved to... * store-motion.cc: ...here. * streamer-hooks.c: Moved to... * streamer-hooks.cc: ...here. * stringpool.c: Moved to... * stringpool.cc: ...here. * substring-locations.c: Moved to... * substring-locations.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * target-globals.c: Moved to... * target-globals.cc: ...here. * targhooks.c: Moved to... * targhooks.cc: ...here. * timevar.c: Moved to... * timevar.cc: ...here. * toplev.c: Moved to... * toplev.cc: ...here. * tracer.c: Moved to... * tracer.cc: ...here. * trans-mem.c: Moved to... * trans-mem.cc: ...here. * tree-affine.c: Moved to... * tree-affine.cc: ...here. * tree-call-cdce.c: Moved to... * tree-call-cdce.cc: ...here. * tree-cfg.c: Moved to... * tree-cfg.cc: ...here. * tree-cfgcleanup.c: Moved to... * tree-cfgcleanup.cc: ...here. * tree-chrec.c: Moved to... * tree-chrec.cc: ...here. * tree-complex.c: Moved to... * tree-complex.cc: ...here. * tree-data-ref.c: Moved to... * tree-data-ref.cc: ...here. * tree-dfa.c: Moved to... * tree-dfa.cc: ...here. * tree-diagnostic.c: Moved to... * tree-diagnostic.cc: ...here. * tree-dump.c: Moved to... * tree-dump.cc: ...here. * tree-eh.c: Moved to... * tree-eh.cc: ...here. * tree-emutls.c: Moved to... * tree-emutls.cc: ...here. * tree-if-conv.c: Moved to... * tree-if-conv.cc: ...here. * tree-inline.c: Moved to... * tree-inline.cc: ...here. * tree-into-ssa.c: Moved to... * tree-into-ssa.cc: ...here. * tree-iterator.c: Moved to... * tree-iterator.cc: ...here. * tree-loop-distribution.c: Moved to... * tree-loop-distribution.cc: ...here. * tree-nested.c: Moved to... * tree-nested.cc: ...here. * tree-nrv.c: Moved to... * tree-nrv.cc: ...here. * tree-object-size.c: Moved to... * tree-object-size.cc: ...here. * tree-outof-ssa.c: Moved to... * tree-outof-ssa.cc: ...here. * tree-parloops.c: Moved to... * tree-parloops.cc: ...here. * tree-phinodes.c: Moved to... * tree-phinodes.cc: ...here. * tree-predcom.c: Moved to... * tree-predcom.cc: ...here. * tree-pretty-print.c: Moved to... * tree-pretty-print.cc: ...here. * tree-profile.c: Moved to... * tree-profile.cc: ...here. * tree-scalar-evolution.c: Moved to... * tree-scalar-evolution.cc: ...here. * tree-sra.c: Moved to... * tree-sra.cc: ...here. * tree-ssa-address.c: Moved to... * tree-ssa-address.cc: ...here. * tree-ssa-alias.c: Moved to... * tree-ssa-alias.cc: ...here. * tree-ssa-ccp.c: Moved to... * tree-ssa-ccp.cc: ...here. * tree-ssa-coalesce.c: Moved to... * tree-ssa-coalesce.cc: ...here. * tree-ssa-copy.c: Moved to... * tree-ssa-copy.cc: ...here. * tree-ssa-dce.c: Moved to... * tree-ssa-dce.cc: ...here. * tree-ssa-dom.c: Moved to... * tree-ssa-dom.cc: ...here. * tree-ssa-dse.c: Moved to... * tree-ssa-dse.cc: ...here. * tree-ssa-forwprop.c: Moved to... * tree-ssa-forwprop.cc: ...here. * tree-ssa-ifcombine.c: Moved to... * tree-ssa-ifcombine.cc: ...here. * tree-ssa-live.c: Moved to... * tree-ssa-live.cc: ...here. * tree-ssa-loop-ch.c: Moved to... * tree-ssa-loop-ch.cc: ...here. * tree-ssa-loop-im.c: Moved to... * tree-ssa-loop-im.cc: ...here. * tree-ssa-loop-ivcanon.c: Moved to... * tree-ssa-loop-ivcanon.cc: ...here. * tree-ssa-loop-ivopts.c: Moved to... * tree-ssa-loop-ivopts.cc: ...here. * tree-ssa-loop-manip.c: Moved to... * tree-ssa-loop-manip.cc: ...here. * tree-ssa-loop-niter.c: Moved to... * tree-ssa-loop-niter.cc: ...here. * tree-ssa-loop-prefetch.c: Moved to... * tree-ssa-loop-prefetch.cc: ...here. * tree-ssa-loop-split.c: Moved to... * tree-ssa-loop-split.cc: ...here. * tree-ssa-loop-unswitch.c: Moved to... * tree-ssa-loop-unswitch.cc: ...here. * tree-ssa-loop.c: Moved to... * tree-ssa-loop.cc: ...here. * tree-ssa-math-opts.c: Moved to... * tree-ssa-math-opts.cc: ...here. * tree-ssa-operands.c: Moved to... * tree-ssa-operands.cc: ...here. * tree-ssa-phiopt.c: Moved to... * tree-ssa-phiopt.cc: ...here. * tree-ssa-phiprop.c: Moved to... * tree-ssa-phiprop.cc: ...here. * tree-ssa-pre.c: Moved to... * tree-ssa-pre.cc: ...here. * tree-ssa-propagate.c: Moved to... * tree-ssa-propagate.cc: ...here. * tree-ssa-reassoc.c: Moved to... * tree-ssa-reassoc.cc: ...here. * tree-ssa-sccvn.c: Moved to... * tree-ssa-sccvn.cc: ...here. * tree-ssa-scopedtables.c: Moved to... * tree-ssa-scopedtables.cc: ...here. * tree-ssa-sink.c: Moved to... * tree-ssa-sink.cc: ...here. * tree-ssa-strlen.c: Moved to... * tree-ssa-strlen.cc: ...here. * tree-ssa-structalias.c: Moved to... * tree-ssa-structalias.cc: ...here. * tree-ssa-tail-merge.c: Moved to... * tree-ssa-tail-merge.cc: ...here. * tree-ssa-ter.c: Moved to... * tree-ssa-ter.cc: ...here. * tree-ssa-threadbackward.c: Moved to... * tree-ssa-threadbackward.cc: ...here. * tree-ssa-threadedge.c: Moved to... * tree-ssa-threadedge.cc: ...here. * tree-ssa-threadupdate.c: Moved to... * tree-ssa-threadupdate.cc: ...here. * tree-ssa-uncprop.c: Moved to... * tree-ssa-uncprop.cc: ...here. * tree-ssa-uninit.c: Moved to... * tree-ssa-uninit.cc: ...here. * tree-ssa.c: Moved to... * tree-ssa.cc: ...here. * tree-ssanames.c: Moved to... * tree-ssanames.cc: ...here. * tree-stdarg.c: Moved to... * tree-stdarg.cc: ...here. * tree-streamer-in.c: Moved to... * tree-streamer-in.cc: ...here. * tree-streamer-out.c: Moved to... * tree-streamer-out.cc: ...here. * tree-streamer.c: Moved to... * tree-streamer.cc: ...here. * tree-switch-conversion.c: Moved to... * tree-switch-conversion.cc: ...here. * tree-tailcall.c: Moved to... * tree-tailcall.cc: ...here. * tree-vect-data-refs.c: Moved to... * tree-vect-data-refs.cc: ...here. * tree-vect-generic.c: Moved to... * tree-vect-generic.cc: ...here. * tree-vect-loop-manip.c: Moved to... * tree-vect-loop-manip.cc: ...here. * tree-vect-loop.c: Moved to... * tree-vect-loop.cc: ...here. * tree-vect-patterns.c: Moved to... * tree-vect-patterns.cc: ...here. * tree-vect-slp-patterns.c: Moved to... * tree-vect-slp-patterns.cc: ...here. * tree-vect-slp.c: Moved to... * tree-vect-slp.cc: ...here. * tree-vect-stmts.c: Moved to... * tree-vect-stmts.cc: ...here. * tree-vector-builder.c: Moved to... * tree-vector-builder.cc: ...here. * tree-vectorizer.c: Moved to... * tree-vectorizer.cc: ...here. * tree-vrp.c: Moved to... * tree-vrp.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * tsan.c: Moved to... * tsan.cc: ...here. * typed-splay-tree.c: Moved to... * typed-splay-tree.cc: ...here. * ubsan.c: Moved to... * ubsan.cc: ...here. * valtrack.c: Moved to... * valtrack.cc: ...here. * value-prof.c: Moved to... * value-prof.cc: ...here. * var-tracking.c: Moved to... * var-tracking.cc: ...here. * varasm.c: Moved to... * varasm.cc: ...here. * varpool.c: Moved to... * varpool.cc: ...here. * vec-perm-indices.c: Moved to... * vec-perm-indices.cc: ...here. * vec.c: Moved to... * vec.cc: ...here. * vmsdbgout.c: Moved to... * vmsdbgout.cc: ...here. * vr-values.c: Moved to... * vr-values.cc: ...here. * vtable-verify.c: Moved to... * vtable-verify.cc: ...here. * web.c: Moved to... * web.cc: ...here. * xcoffout.c: Moved to... * xcoffout.cc: ...here. gcc/c-family/ChangeLog: * c-ada-spec.c: Moved to... * c-ada-spec.cc: ...here. * c-attribs.c: Moved to... * c-attribs.cc: ...here. * c-common.c: Moved to... * c-common.cc: ...here. * c-cppbuiltin.c: Moved to... * c-cppbuiltin.cc: ...here. * c-dump.c: Moved to... * c-dump.cc: ...here. * c-format.c: Moved to... * c-format.cc: ...here. * c-gimplify.c: Moved to... * c-gimplify.cc: ...here. * c-indentation.c: Moved to... * c-indentation.cc: ...here. * c-lex.c: Moved to... * c-lex.cc: ...here. * c-omp.c: Moved to... * c-omp.cc: ...here. * c-opts.c: Moved to... * c-opts.cc: ...here. * c-pch.c: Moved to... * c-pch.cc: ...here. * c-ppoutput.c: Moved to... * c-ppoutput.cc: ...here. * c-pragma.c: Moved to... * c-pragma.cc: ...here. * c-pretty-print.c: Moved to... * c-pretty-print.cc: ...here. * c-semantics.c: Moved to... * c-semantics.cc: ...here. * c-ubsan.c: Moved to... * c-ubsan.cc: ...here. * c-warn.c: Moved to... * c-warn.cc: ...here. * cppspec.c: Moved to... * cppspec.cc: ...here. * stub-objc.c: Moved to... * stub-objc.cc: ...here. gcc/c/ChangeLog: * c-aux-info.c: Moved to... * c-aux-info.cc: ...here. * c-convert.c: Moved to... * c-convert.cc: ...here. * c-decl.c: Moved to... * c-decl.cc: ...here. * c-errors.c: Moved to... * c-errors.cc: ...here. * c-fold.c: Moved to... * c-fold.cc: ...here. * c-lang.c: Moved to... * c-lang.cc: ...here. * c-objc-common.c: Moved to... * c-objc-common.cc: ...here. * c-parser.c: Moved to... * c-parser.cc: ...here. * c-typeck.c: Moved to... * c-typeck.cc: ...here. * gccspec.c: Moved to... * gccspec.cc: ...here. * gimple-parser.c: Moved to... * gimple-parser.cc: ...here. gcc/cp/ChangeLog: * call.c: Moved to... * call.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constexpr.c: Moved to... * constexpr.cc: ...here. * cp-gimplify.c: Moved to... * cp-gimplify.cc: ...here. * cp-lang.c: Moved to... * cp-lang.cc: ...here. * cp-objcp-common.c: Moved to... * cp-objcp-common.cc: ...here. * cp-ubsan.c: Moved to... * cp-ubsan.cc: ...here. * cvt.c: Moved to... * cvt.cc: ...here. * cxx-pretty-print.c: Moved to... * cxx-pretty-print.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * decl2.c: Moved to... * decl2.cc: ...here. * dump.c: Moved to... * dump.cc: ...here. * error.c: Moved to... * error.cc: ...here. * except.c: Moved to... * except.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * friend.c: Moved to... * friend.cc: ...here. * g++spec.c: Moved to... * g++spec.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lambda.c: Moved to... * lambda.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * mangle.c: Moved to... * mangle.cc: ...here. * method.c: Moved to... * method.cc: ...here. * name-lookup.c: Moved to... * name-lookup.cc: ...here. * optimize.c: Moved to... * optimize.cc: ...here. * parser.c: Moved to... * parser.cc: ...here. * pt.c: Moved to... * pt.cc: ...here. * ptree.c: Moved to... * ptree.cc: ...here. * rtti.c: Moved to... * rtti.cc: ...here. * search.c: Moved to... * search.cc: ...here. * semantics.c: Moved to... * semantics.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * typeck.c: Moved to... * typeck.cc: ...here. * typeck2.c: Moved to... * typeck2.cc: ...here. * vtable-class-hierarchy.c: Moved to... * vtable-class-hierarchy.cc: ...here. gcc/fortran/ChangeLog: * arith.c: Moved to... * arith.cc: ...here. * array.c: Moved to... * array.cc: ...here. * bbt.c: Moved to... * bbt.cc: ...here. * check.c: Moved to... * check.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constructor.c: Moved to... * constructor.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * cpp.c: Moved to... * cpp.cc: ...here. * data.c: Moved to... * data.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * dependency.c: Moved to... * dependency.cc: ...here. * dump-parse-tree.c: Moved to... * dump-parse-tree.cc: ...here. * error.c: Moved to... * error.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * f95-lang.c: Moved to... * f95-lang.cc: ...here. * frontend-passes.c: Moved to... * frontend-passes.cc: ...here. * gfortranspec.c: Moved to... * gfortranspec.cc: ...here. * interface.c: Moved to... * interface.cc: ...here. * intrinsic.c: Moved to... * intrinsic.cc: ...here. * io.c: Moved to... * io.cc: ...here. * iresolve.c: Moved to... * iresolve.cc: ...here. * match.c: Moved to... * match.cc: ...here. * matchexp.c: Moved to... * matchexp.cc: ...here. * misc.c: Moved to... * misc.cc: ...here. * module.c: Moved to... * module.cc: ...here. * openmp.c: Moved to... * openmp.cc: ...here. * options.c: Moved to... * options.cc: ...here. * parse.c: Moved to... * parse.cc: ...here. * primary.c: Moved to... * primary.cc: ...here. * resolve.c: Moved to... * resolve.cc: ...here. * scanner.c: Moved to... * scanner.cc: ...here. * simplify.c: Moved to... * simplify.cc: ...here. * st.c: Moved to... * st.cc: ...here. * symbol.c: Moved to... * symbol.cc: ...here. * target-memory.c: Moved to... * target-memory.cc: ...here. * trans-array.c: Moved to... * trans-array.cc: ...here. * trans-common.c: Moved to... * trans-common.cc: ...here. * trans-const.c: Moved to... * trans-const.cc: ...here. * trans-decl.c: Moved to... * trans-decl.cc: ...here. * trans-expr.c: Moved to... * trans-expr.cc: ...here. * trans-intrinsic.c: Moved to... * trans-intrinsic.cc: ...here. * trans-io.c: Moved to... * trans-io.cc: ...here. * trans-openmp.c: Moved to... * trans-openmp.cc: ...here. * trans-stmt.c: Moved to... * trans-stmt.cc: ...here. * trans-types.c: Moved to... * trans-types.cc: ...here. * trans.c: Moved to... * trans.cc: ...here. gcc/go/ChangeLog: * go-backend.c: Moved to... * go-backend.cc: ...here. * go-lang.c: Moved to... * go-lang.cc: ...here. * gospec.c: Moved to... * gospec.cc: ...here. gcc/jit/ChangeLog: * dummy-frontend.c: Moved to... * dummy-frontend.cc: ...here. * jit-builtins.c: Moved to... * jit-builtins.cc: ...here. * jit-logging.c: Moved to... * jit-logging.cc: ...here. * jit-playback.c: Moved to... * jit-playback.cc: ...here. * jit-recording.c: Moved to... * jit-recording.cc: ...here. * jit-result.c: Moved to... * jit-result.cc: ...here. * jit-spec.c: Moved to... * jit-spec.cc: ...here. * jit-tempdir.c: Moved to... * jit-tempdir.cc: ...here. * jit-w32.c: Moved to... * jit-w32.cc: ...here. * libgccjit.c: Moved to... * libgccjit.cc: ...here. gcc/lto/ChangeLog: * common.c: Moved to... * common.cc: ...here. * lto-common.c: Moved to... * lto-common.cc: ...here. * lto-dump.c: Moved to... * lto-dump.cc: ...here. * lto-lang.c: Moved to... * lto-lang.cc: ...here. * lto-object.c: Moved to... * lto-object.cc: ...here. * lto-partition.c: Moved to... * lto-partition.cc: ...here. * lto-symtab.c: Moved to... * lto-symtab.cc: ...here. * lto.c: Moved to... * lto.cc: ...here. gcc/objc/ChangeLog: * objc-act.c: Moved to... * objc-act.cc: ...here. * objc-encoding.c: Moved to... * objc-encoding.cc: ...here. * objc-gnu-runtime-abi-01.c: Moved to... * objc-gnu-runtime-abi-01.cc: ...here. * objc-lang.c: Moved to... * objc-lang.cc: ...here. * objc-map.c: Moved to... * objc-map.cc: ...here. * objc-next-runtime-abi-01.c: Moved to... * objc-next-runtime-abi-01.cc: ...here. * objc-next-runtime-abi-02.c: Moved to... * objc-next-runtime-abi-02.cc: ...here. * objc-runtime-shared-support.c: Moved to... * objc-runtime-shared-support.cc: ...here. gcc/objcp/ChangeLog: * objcp-decl.c: Moved to... * objcp-decl.cc: ...here. * objcp-lang.c: Moved to... * objcp-lang.cc: ...here. libcpp/ChangeLog: * charset.c: Moved to... * charset.cc: ...here. * directives.c: Moved to... * directives.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * files.c: Moved to... * files.cc: ...here. * identifiers.c: Moved to... * identifiers.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * line-map.c: Moved to... * line-map.cc: ...here. * macro.c: Moved to... * macro.cc: ...here. * makeucnid.c: Moved to... * makeucnid.cc: ...here. * mkdeps.c: Moved to... * mkdeps.cc: ...here. * pch.c: Moved to... * pch.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * traditional.c: Moved to... * traditional.cc: ...here.
Diffstat (limited to 'gcc/lra.cc')
-rw-r--r--gcc/lra.cc2523
1 files changed, 2523 insertions, 0 deletions
diff --git a/gcc/lra.cc b/gcc/lra.cc
new file mode 100644
index 0000000..55ba970
--- /dev/null
+++ b/gcc/lra.cc
@@ -0,0 +1,2523 @@
+/* LRA (local register allocator) driver and LRA utilities.
+ Copyright (C) 2010-2022 Free Software Foundation, Inc.
+ Contributed by Vladimir Makarov <vmakarov@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* The Local Register Allocator (LRA) is a replacement of former
+ reload pass. It is focused to simplify code solving the reload
+ pass tasks, to make the code maintenance easier, and to implement new
+ perspective optimizations.
+
+ The major LRA design solutions are:
+ o division small manageable, separated sub-tasks
+ o reflection of all transformations and decisions in RTL as more
+ as possible
+ o insn constraints as a primary source of the info (minimizing
+ number of target-depended macros/hooks)
+
+ In brief LRA works by iterative insn process with the final goal is
+ to satisfy all insn and address constraints:
+ o New reload insns (in brief reloads) and reload pseudos might be
+ generated;
+ o Some pseudos might be spilled to assign hard registers to
+ new reload pseudos;
+ o Recalculating spilled pseudo values (rematerialization);
+ o Changing spilled pseudos to stack memory or their equivalences;
+ o Allocation stack memory changes the address displacement and
+ new iteration is needed.
+
+ Here is block diagram of LRA passes:
+
+ ------------------------
+ --------------- | Undo inheritance for | ---------------
+ | Memory-memory | | spilled pseudos, | | New (and old) |
+ | move coalesce |<---| splits for pseudos got |<-- | pseudos |
+ --------------- | the same hard regs, | | assignment |
+ Start | | and optional reloads | ---------------
+ | | ------------------------ ^
+ V | ---------------- |
+ ----------- V | Update virtual | |
+| Remove |----> ------------>| register | |
+| scratches | ^ | displacements | |
+ ----------- | ---------------- |
+ | | |
+ | V New |
+ | ------------ pseudos -------------------
+ | |Constraints:| or insns | Inheritance/split |
+ | | RTL |--------->| transformations |
+ | | transfor- | | in EBB scope |
+ | substi- | mations | -------------------
+ | tutions ------------
+ | | No change
+ ---------------- V
+ | Spilled pseudo | -------------------
+ | to memory |<----| Rematerialization |
+ | substitution | -------------------
+ ----------------
+ | No susbtitions
+ V
+ -------------------------
+ | Hard regs substitution, |
+ | devirtalization, and |------> Finish
+ | restoring scratches got |
+ | memory |
+ -------------------------
+
+ To speed up the process:
+ o We process only insns affected by changes on previous
+ iterations;
+ o We don't use DFA-infrastructure because it results in much slower
+ compiler speed than a special IR described below does;
+ o We use a special insn representation for quick access to insn
+ info which is always *synchronized* with the current RTL;
+ o Insn IR is minimized by memory. It is divided on three parts:
+ o one specific for each insn in RTL (only operand locations);
+ o one common for all insns in RTL with the same insn code
+ (different operand attributes from machine descriptions);
+ o one oriented for maintenance of live info (list of pseudos).
+ o Pseudo data:
+ o all insns where the pseudo is referenced;
+ o live info (conflicting hard regs, live ranges, # of
+ references etc);
+ o data used for assigning (preferred hard regs, costs etc).
+
+ This file contains LRA driver, LRA utility functions and data, and
+ code for dealing with scratches. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
+#include "tree.h"
+#include "predict.h"
+#include "df.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "optabs.h"
+#include "regs.h"
+#include "ira.h"
+#include "recog.h"
+#include "expr.h"
+#include "cfgrtl.h"
+#include "cfgbuild.h"
+#include "lra.h"
+#include "lra-int.h"
+#include "print-rtl.h"
+#include "function-abi.h"
+
+/* Dump bitmap SET with TITLE and BB INDEX. */
+void
+lra_dump_bitmap_with_title (const char *title, bitmap set, int index)
+{
+ unsigned int i;
+ int count;
+ bitmap_iterator bi;
+ static const int max_nums_on_line = 10;
+
+ if (bitmap_empty_p (set))
+ return;
+ fprintf (lra_dump_file, " %s %d:", title, index);
+ fprintf (lra_dump_file, "\n");
+ count = max_nums_on_line + 1;
+ EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
+ {
+ if (count > max_nums_on_line)
+ {
+ fprintf (lra_dump_file, "\n ");
+ count = 0;
+ }
+ fprintf (lra_dump_file, " %4u", i);
+ count++;
+ }
+ fprintf (lra_dump_file, "\n");
+}
+
+/* Hard registers currently not available for allocation. It can
+ changed after some hard registers become not eliminable. */
+HARD_REG_SET lra_no_alloc_regs;
+
+static int get_new_reg_value (void);
+static void expand_reg_info (void);
+static void invalidate_insn_recog_data (int);
+static int get_insn_freq (rtx_insn *);
+static void invalidate_insn_data_regno_info (lra_insn_recog_data_t,
+ rtx_insn *, int);
+/* Expand all regno related info needed for LRA. */
+static void
+expand_reg_data (int old)
+{
+ resize_reg_info ();
+ expand_reg_info ();
+ ira_expand_reg_equiv ();
+ for (int i = (int) max_reg_num () - 1; i >= old; i--)
+ lra_change_class (i, ALL_REGS, " Set", true);
+}
+
+/* Create and return a new reg of ORIGINAL mode. If ORIGINAL is NULL
+ or of VOIDmode, use MD_MODE for the new reg. Initialize its
+ register class to RCLASS. Print message about assigning class
+ RCLASS containing new register name TITLE unless it is NULL. Use
+ attributes of ORIGINAL if it is a register. The created register
+ will have unique held value. */
+rtx
+lra_create_new_reg_with_unique_value (machine_mode md_mode, rtx original,
+ enum reg_class rclass, const char *title)
+{
+ machine_mode mode;
+ rtx new_reg;
+
+ if (original == NULL_RTX || (mode = GET_MODE (original)) == VOIDmode)
+ mode = md_mode;
+ lra_assert (mode != VOIDmode);
+ new_reg = gen_reg_rtx (mode);
+ if (original == NULL_RTX || ! REG_P (original))
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, " Creating newreg=%i", REGNO (new_reg));
+ }
+ else
+ {
+ if (ORIGINAL_REGNO (original) >= FIRST_PSEUDO_REGISTER)
+ ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original);
+ REG_USERVAR_P (new_reg) = REG_USERVAR_P (original);
+ REG_POINTER (new_reg) = REG_POINTER (original);
+ REG_ATTRS (new_reg) = REG_ATTRS (original);
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, " Creating newreg=%i from oldreg=%i",
+ REGNO (new_reg), REGNO (original));
+ }
+ if (lra_dump_file != NULL)
+ {
+ if (title != NULL)
+ fprintf (lra_dump_file, ", assigning class %s to%s%s r%d",
+ reg_class_names[rclass], *title == '\0' ? "" : " ",
+ title, REGNO (new_reg));
+ fprintf (lra_dump_file, "\n");
+ }
+ expand_reg_data (max_reg_num ());
+ setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
+ return new_reg;
+}
+
+/* Analogous to the previous function but also inherits value of
+ ORIGINAL. */
+rtx
+lra_create_new_reg (machine_mode md_mode, rtx original,
+ enum reg_class rclass, const char *title)
+{
+ rtx new_reg;
+
+ new_reg
+ = lra_create_new_reg_with_unique_value (md_mode, original, rclass, title);
+ if (original != NULL_RTX && REG_P (original))
+ lra_assign_reg_val (REGNO (original), REGNO (new_reg));
+ return new_reg;
+}
+
+/* Set up for REGNO unique hold value. */
+void
+lra_set_regno_unique_value (int regno)
+{
+ lra_reg_info[regno].val = get_new_reg_value ();
+}
+
+/* Invalidate INSN related info used by LRA. The info should never be
+ used after that. */
+void
+lra_invalidate_insn_data (rtx_insn *insn)
+{
+ lra_invalidate_insn_regno_info (insn);
+ invalidate_insn_recog_data (INSN_UID (insn));
+}
+
+/* Mark INSN deleted and invalidate the insn related info used by
+ LRA. */
+void
+lra_set_insn_deleted (rtx_insn *insn)
+{
+ lra_invalidate_insn_data (insn);
+ SET_INSN_DELETED (insn);
+}
+
+/* Delete an unneeded INSN and any previous insns who sole purpose is
+ loading data that is dead in INSN. */
+void
+lra_delete_dead_insn (rtx_insn *insn)
+{
+ rtx_insn *prev = prev_real_insn (insn);
+ rtx prev_dest;
+
+ /* If the previous insn sets a register that dies in our insn,
+ delete it too. */
+ if (prev && GET_CODE (PATTERN (prev)) == SET
+ && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
+ && reg_mentioned_p (prev_dest, PATTERN (insn))
+ && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
+ && ! side_effects_p (SET_SRC (PATTERN (prev))))
+ lra_delete_dead_insn (prev);
+
+ lra_set_insn_deleted (insn);
+}
+
+/* Emit insn x = y + z. Return NULL if we failed to do it.
+ Otherwise, return the insn. We don't use gen_add3_insn as it might
+ clobber CC. */
+static rtx_insn *
+emit_add3_insn (rtx x, rtx y, rtx z)
+{
+ rtx_insn *last;
+
+ last = get_last_insn ();
+
+ if (have_addptr3_insn (x, y, z))
+ {
+ rtx_insn *insn = gen_addptr3_insn (x, y, z);
+
+ /* If the target provides an "addptr" pattern it hopefully does
+ for a reason. So falling back to the normal add would be
+ a bug. */
+ lra_assert (insn != NULL_RTX);
+ emit_insn (insn);
+ return insn;
+ }
+
+ rtx_insn *insn = emit_insn (gen_rtx_SET (x, gen_rtx_PLUS (GET_MODE (y),
+ y, z)));
+ if (recog_memoized (insn) < 0)
+ {
+ delete_insns_since (last);
+ insn = NULL;
+ }
+ return insn;
+}
+
+/* Emit insn x = x + y. Return the insn. We use gen_add2_insn as the
+ last resort. */
+static rtx_insn *
+emit_add2_insn (rtx x, rtx y)
+{
+ rtx_insn *insn = emit_add3_insn (x, x, y);
+ if (insn == NULL_RTX)
+ {
+ insn = gen_add2_insn (x, y);
+ if (insn != NULL_RTX)
+ emit_insn (insn);
+ }
+ return insn;
+}
+
+/* Target checks operands through operand predicates to recognize an
+ insn. We should have a special precaution to generate add insns
+ which are frequent results of elimination.
+
+ Emit insns for x = y + z. X can be used to store intermediate
+ values and should be not in Y and Z when we use X to store an
+ intermediate value. Y + Z should form [base] [+ index[ * scale]] [
+ + disp] where base and index are registers, disp and scale are
+ constants. Y should contain base if it is present, Z should
+ contain disp if any. index[*scale] can be part of Y or Z. */
+void
+lra_emit_add (rtx x, rtx y, rtx z)
+{
+ int old;
+ rtx_insn *last;
+ rtx a1, a2, base, index, disp, scale, index_scale;
+ bool ok_p;
+
+ rtx_insn *add3_insn = emit_add3_insn (x, y, z);
+ old = max_reg_num ();
+ if (add3_insn != NULL)
+ ;
+ else
+ {
+ disp = a2 = NULL_RTX;
+ if (GET_CODE (y) == PLUS)
+ {
+ a1 = XEXP (y, 0);
+ a2 = XEXP (y, 1);
+ disp = z;
+ }
+ else
+ {
+ a1 = y;
+ if (CONSTANT_P (z))
+ disp = z;
+ else
+ a2 = z;
+ }
+ index_scale = scale = NULL_RTX;
+ if (GET_CODE (a1) == MULT)
+ {
+ index_scale = a1;
+ index = XEXP (a1, 0);
+ scale = XEXP (a1, 1);
+ base = a2;
+ }
+ else if (a2 != NULL_RTX && GET_CODE (a2) == MULT)
+ {
+ index_scale = a2;
+ index = XEXP (a2, 0);
+ scale = XEXP (a2, 1);
+ base = a1;
+ }
+ else
+ {
+ base = a1;
+ index = a2;
+ }
+ if ((base != NULL_RTX && ! (REG_P (base) || GET_CODE (base) == SUBREG))
+ || (index != NULL_RTX
+ && ! (REG_P (index) || GET_CODE (index) == SUBREG))
+ || (disp != NULL_RTX && ! CONSTANT_P (disp))
+ || (scale != NULL_RTX && ! CONSTANT_P (scale)))
+ {
+ /* Probably we have no 3 op add. Last chance is to use 2-op
+ add insn. To succeed, don't move Z to X as an address
+ segment always comes in Y. Otherwise, we might fail when
+ adding the address segment to register. */
+ lra_assert (x != y && x != z);
+ emit_move_insn (x, y);
+ rtx_insn *insn = emit_add2_insn (x, z);
+ lra_assert (insn != NULL_RTX);
+ }
+ else
+ {
+ if (index_scale == NULL_RTX)
+ index_scale = index;
+ if (disp == NULL_RTX)
+ {
+ /* Generate x = index_scale; x = x + base. */
+ lra_assert (index_scale != NULL_RTX && base != NULL_RTX);
+ emit_move_insn (x, index_scale);
+ rtx_insn *insn = emit_add2_insn (x, base);
+ lra_assert (insn != NULL_RTX);
+ }
+ else if (scale == NULL_RTX)
+ {
+ /* Try x = base + disp. */
+ lra_assert (base != NULL_RTX);
+ last = get_last_insn ();
+ rtx_insn *move_insn =
+ emit_move_insn (x, gen_rtx_PLUS (GET_MODE (base), base, disp));
+ if (recog_memoized (move_insn) < 0)
+ {
+ delete_insns_since (last);
+ /* Generate x = disp; x = x + base. */
+ emit_move_insn (x, disp);
+ rtx_insn *add2_insn = emit_add2_insn (x, base);
+ lra_assert (add2_insn != NULL_RTX);
+ }
+ /* Generate x = x + index. */
+ if (index != NULL_RTX)
+ {
+ rtx_insn *insn = emit_add2_insn (x, index);
+ lra_assert (insn != NULL_RTX);
+ }
+ }
+ else
+ {
+ /* Try x = index_scale; x = x + disp; x = x + base. */
+ last = get_last_insn ();
+ rtx_insn *move_insn = emit_move_insn (x, index_scale);
+ ok_p = false;
+ if (recog_memoized (move_insn) >= 0)
+ {
+ rtx_insn *insn = emit_add2_insn (x, disp);
+ if (insn != NULL_RTX)
+ {
+ if (base == NULL_RTX)
+ ok_p = true;
+ else
+ {
+ insn = emit_add2_insn (x, base);
+ if (insn != NULL_RTX)
+ ok_p = true;
+ }
+ }
+ }
+ if (! ok_p)
+ {
+ rtx_insn *insn;
+
+ delete_insns_since (last);
+ /* Generate x = disp; x = x + base; x = x + index_scale. */
+ emit_move_insn (x, disp);
+ if (base != NULL_RTX)
+ {
+ insn = emit_add2_insn (x, base);
+ lra_assert (insn != NULL_RTX);
+ }
+ insn = emit_add2_insn (x, index_scale);
+ lra_assert (insn != NULL_RTX);
+ }
+ }
+ }
+ }
+ /* Functions emit_... can create pseudos -- so expand the pseudo
+ data. */
+ if (old != max_reg_num ())
+ expand_reg_data (old);
+}
+
+/* The number of emitted reload insns so far. */
+int lra_curr_reload_num;
+
+static void remove_insn_scratches (rtx_insn *insn);
+
+/* Emit x := y, processing special case when y = u + v or y = u + v *
+ scale + w through emit_add (Y can be an address which is base +
+ index reg * scale + displacement in general case). X may be used
+ as intermediate result therefore it should be not in Y. */
+void
+lra_emit_move (rtx x, rtx y)
+{
+ int old;
+ rtx_insn *insn;
+
+ if (GET_CODE (y) != PLUS)
+ {
+ if (rtx_equal_p (x, y))
+ return;
+ old = max_reg_num ();
+
+ insn = (GET_CODE (x) != STRICT_LOW_PART
+ ? emit_move_insn (x, y) : emit_insn (gen_rtx_SET (x, y)));
+ /* The move pattern may require scratch registers, so convert them
+ into real registers now. */
+ if (insn != NULL_RTX)
+ remove_insn_scratches (insn);
+ if (REG_P (x))
+ lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
+ /* Function emit_move can create pseudos -- so expand the pseudo
+ data. */
+ if (old != max_reg_num ())
+ expand_reg_data (old);
+ return;
+ }
+ lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
+}
+
+/* Update insn operands which are duplication of operands whose
+ numbers are in array of NOPS (with end marker -1). The insn is
+ represented by its LRA internal representation ID. */
+void
+lra_update_dups (lra_insn_recog_data_t id, signed char *nops)
+{
+ int i, j, nop;
+ struct lra_static_insn_data *static_id = id->insn_static_data;
+
+ for (i = 0; i < static_id->n_dups; i++)
+ for (j = 0; (nop = nops[j]) >= 0; j++)
+ if (static_id->dup_num[i] == nop)
+ *id->dup_loc[i] = *id->operand_loc[nop];
+}
+
+
+
+/* This page contains code dealing with info about registers in the
+ insns. */
+
+/* Pools for insn reg info. */
+object_allocator<lra_insn_reg> lra_insn_reg_pool ("insn regs");
+
+/* Create LRA insn related info about a reference to REGNO in INSN
+ with TYPE (in/out/inout), biggest reference mode MODE, flag that it
+ is reference through subreg (SUBREG_P), and reference to the next
+ insn reg info (NEXT). If REGNO can be early clobbered,
+ alternatives in which it can be early clobbered are given by
+ EARLY_CLOBBER_ALTS. */
+static struct lra_insn_reg *
+new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
+ machine_mode mode, bool subreg_p,
+ alternative_mask early_clobber_alts,
+ struct lra_insn_reg *next)
+{
+ lra_insn_reg *ir = lra_insn_reg_pool.allocate ();
+ ir->type = type;
+ ir->biggest_mode = mode;
+ if (NONDEBUG_INSN_P (insn)
+ && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
+ lra_reg_info[regno].biggest_mode = mode;
+ ir->subreg_p = subreg_p;
+ ir->early_clobber_alts = early_clobber_alts;
+ ir->regno = regno;
+ ir->next = next;
+ return ir;
+}
+
+/* Free insn reg info list IR. */
+static void
+free_insn_regs (struct lra_insn_reg *ir)
+{
+ struct lra_insn_reg *next_ir;
+
+ for (; ir != NULL; ir = next_ir)
+ {
+ next_ir = ir->next;
+ lra_insn_reg_pool.remove (ir);
+ }
+}
+
+/* Finish pool for insn reg info. */
+static void
+finish_insn_regs (void)
+{
+ lra_insn_reg_pool.release ();
+}
+
+
+
+/* This page contains code dealing LRA insn info (or in other words
+ LRA internal insn representation). */
+
+/* Map INSN_CODE -> the static insn data. This info is valid during
+ all translation unit. */
+struct lra_static_insn_data *insn_code_data[NUM_INSN_CODES];
+
+/* Debug insns are represented as a special insn with one input
+ operand which is RTL expression in var_location. */
+
+/* The following data are used as static insn operand data for all
+ debug insns. If structure lra_operand_data is changed, the
+ initializer should be changed too. */
+static struct lra_operand_data debug_operand_data =
+ {
+ NULL, /* alternative */
+ 0, /* early_clobber_alts */
+ E_VOIDmode, /* We are not interesting in the operand mode. */
+ OP_IN,
+ 0, 0, 0
+ };
+
+/* The following data are used as static insn data for all debug
+ bind insns. If structure lra_static_insn_data is changed, the
+ initializer should be changed too. */
+static struct lra_static_insn_data debug_bind_static_data =
+ {
+ &debug_operand_data,
+ 0, /* Duplication operands #. */
+ -1, /* Commutative operand #. */
+ 1, /* Operands #. There is only one operand which is debug RTL
+ expression. */
+ 0, /* Duplications #. */
+ 0, /* Alternatives #. We are not interesting in alternatives
+ because we does not proceed debug_insns for reloads. */
+ NULL, /* Hard registers referenced in machine description. */
+ NULL /* Descriptions of operands in alternatives. */
+ };
+
+/* The following data are used as static insn data for all debug
+ marker insns. If structure lra_static_insn_data is changed, the
+ initializer should be changed too. */
+static struct lra_static_insn_data debug_marker_static_data =
+ {
+ &debug_operand_data,
+ 0, /* Duplication operands #. */
+ -1, /* Commutative operand #. */
+ 0, /* Operands #. There isn't any operand. */
+ 0, /* Duplications #. */
+ 0, /* Alternatives #. We are not interesting in alternatives
+ because we does not proceed debug_insns for reloads. */
+ NULL, /* Hard registers referenced in machine description. */
+ NULL /* Descriptions of operands in alternatives. */
+ };
+
+/* Called once per compiler work to initialize some LRA data related
+ to insns. */
+static void
+init_insn_code_data_once (void)
+{
+ memset (insn_code_data, 0, sizeof (insn_code_data));
+}
+
+/* Called once per compiler work to finalize some LRA data related to
+ insns. */
+static void
+finish_insn_code_data_once (void)
+{
+ for (unsigned int i = 0; i < NUM_INSN_CODES; i++)
+ {
+ if (insn_code_data[i] != NULL)
+ {
+ free (insn_code_data[i]);
+ insn_code_data[i] = NULL;
+ }
+ }
+}
+
+/* Return static insn data, allocate and setup if necessary. Although
+ dup_num is static data (it depends only on icode), to set it up we
+ need to extract insn first. So recog_data should be valid for
+ normal insn (ICODE >= 0) before the call. */
+static struct lra_static_insn_data *
+get_static_insn_data (int icode, int nop, int ndup, int nalt)
+{
+ struct lra_static_insn_data *data;
+ size_t n_bytes;
+
+ lra_assert (icode < (int) NUM_INSN_CODES);
+ if (icode >= 0 && (data = insn_code_data[icode]) != NULL)
+ return data;
+ lra_assert (nop >= 0 && ndup >= 0 && nalt >= 0);
+ n_bytes = sizeof (struct lra_static_insn_data)
+ + sizeof (struct lra_operand_data) * nop
+ + sizeof (int) * ndup;
+ data = XNEWVAR (struct lra_static_insn_data, n_bytes);
+ data->operand_alternative = NULL;
+ data->n_operands = nop;
+ data->n_dups = ndup;
+ data->n_alternatives = nalt;
+ data->operand = ((struct lra_operand_data *)
+ ((char *) data + sizeof (struct lra_static_insn_data)));
+ data->dup_num = ((int *) ((char *) data->operand
+ + sizeof (struct lra_operand_data) * nop));
+ if (icode >= 0)
+ {
+ int i;
+
+ insn_code_data[icode] = data;
+ for (i = 0; i < nop; i++)
+ {
+ data->operand[i].constraint
+ = insn_data[icode].operand[i].constraint;
+ data->operand[i].mode = insn_data[icode].operand[i].mode;
+ data->operand[i].strict_low = insn_data[icode].operand[i].strict_low;
+ data->operand[i].is_operator
+ = insn_data[icode].operand[i].is_operator;
+ data->operand[i].type
+ = (data->operand[i].constraint[0] == '=' ? OP_OUT
+ : data->operand[i].constraint[0] == '+' ? OP_INOUT
+ : OP_IN);
+ data->operand[i].is_address = false;
+ }
+ for (i = 0; i < ndup; i++)
+ data->dup_num[i] = recog_data.dup_num[i];
+ }
+ return data;
+}
+
+/* The current length of the following array. */
+int lra_insn_recog_data_len;
+
+/* Map INSN_UID -> the insn recog data (NULL if unknown). */
+lra_insn_recog_data_t *lra_insn_recog_data;
+
+/* Alloc pool we allocate entries for lra_insn_recog_data from. */
+static object_allocator<class lra_insn_recog_data>
+ lra_insn_recog_data_pool ("insn recog data pool");
+
+/* Initialize LRA data about insns. */
+static void
+init_insn_recog_data (void)
+{
+ lra_insn_recog_data_len = 0;
+ lra_insn_recog_data = NULL;
+}
+
+/* Expand, if necessary, LRA data about insns. */
+static void
+check_and_expand_insn_recog_data (int index)
+{
+ int i, old;
+
+ if (lra_insn_recog_data_len > index)
+ return;
+ old = lra_insn_recog_data_len;
+ lra_insn_recog_data_len = index * 3 / 2 + 1;
+ lra_insn_recog_data = XRESIZEVEC (lra_insn_recog_data_t,
+ lra_insn_recog_data,
+ lra_insn_recog_data_len);
+ for (i = old; i < lra_insn_recog_data_len; i++)
+ lra_insn_recog_data[i] = NULL;
+}
+
+/* Finish LRA DATA about insn. */
+static void
+free_insn_recog_data (lra_insn_recog_data_t data)
+{
+ if (data->operand_loc != NULL)
+ free (data->operand_loc);
+ if (data->dup_loc != NULL)
+ free (data->dup_loc);
+ if (data->arg_hard_regs != NULL)
+ free (data->arg_hard_regs);
+ if (data->icode < 0 && NONDEBUG_INSN_P (data->insn))
+ {
+ if (data->insn_static_data->operand_alternative != NULL)
+ free (const_cast <operand_alternative *>
+ (data->insn_static_data->operand_alternative));
+ free_insn_regs (data->insn_static_data->hard_regs);
+ free (data->insn_static_data);
+ }
+ free_insn_regs (data->regs);
+ data->regs = NULL;
+ lra_insn_recog_data_pool.remove (data);
+}
+
+/* Pools for copies. */
+static object_allocator<lra_copy> lra_copy_pool ("lra copies");
+
+/* Finish LRA data about all insns. */
+static void
+finish_insn_recog_data (void)
+{
+ int i;
+ lra_insn_recog_data_t data;
+
+ for (i = 0; i < lra_insn_recog_data_len; i++)
+ if ((data = lra_insn_recog_data[i]) != NULL)
+ free_insn_recog_data (data);
+ finish_insn_regs ();
+ lra_copy_pool.release ();
+ lra_insn_reg_pool.release ();
+ lra_insn_recog_data_pool.release ();
+ free (lra_insn_recog_data);
+}
+
+/* Setup info about operands in alternatives of LRA DATA of insn. */
+static void
+setup_operand_alternative (lra_insn_recog_data_t data,
+ const operand_alternative *op_alt)
+{
+ int i, j, nop, nalt;
+ int icode = data->icode;
+ struct lra_static_insn_data *static_data = data->insn_static_data;
+
+ static_data->commutative = -1;
+ nop = static_data->n_operands;
+ nalt = static_data->n_alternatives;
+ static_data->operand_alternative = op_alt;
+ for (i = 0; i < nop; i++)
+ {
+ static_data->operand[i].early_clobber_alts = 0;
+ static_data->operand[i].is_address = false;
+ if (static_data->operand[i].constraint[0] == '%')
+ {
+ /* We currently only support one commutative pair of operands. */
+ if (static_data->commutative < 0)
+ static_data->commutative = i;
+ else
+ lra_assert (icode < 0); /* Asm */
+ /* The last operand should not be marked commutative. */
+ lra_assert (i != nop - 1);
+ }
+ }
+ for (j = 0; j < nalt; j++)
+ for (i = 0; i < nop; i++, op_alt++)
+ {
+ if (op_alt->earlyclobber)
+ static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j;
+ static_data->operand[i].is_address |= op_alt->is_address;
+ }
+}
+
+/* Recursively process X and collect info about registers, which are
+ not the insn operands, in X with TYPE (in/out/inout) and flag that
+ it is early clobbered in the insn (EARLY_CLOBBER) and add the info
+ to LIST. X is a part of insn given by DATA. Return the result
+ list. */
+static struct lra_insn_reg *
+collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
+ lra_insn_recog_data_t data,
+ struct lra_insn_reg *list,
+ enum op_type type, bool early_clobber)
+{
+ int i, j, regno, last;
+ bool subreg_p;
+ machine_mode mode;
+ struct lra_insn_reg *curr;
+ rtx op = *x;
+ enum rtx_code code = GET_CODE (op);
+ const char *fmt = GET_RTX_FORMAT (code);
+
+ for (i = 0; i < data->insn_static_data->n_operands; i++)
+ if (! data->insn_static_data->operand[i].is_operator
+ && x == data->operand_loc[i])
+ /* It is an operand loc. Stop here. */
+ return list;
+ for (i = 0; i < data->insn_static_data->n_dups; i++)
+ if (x == data->dup_loc[i])
+ /* It is a dup loc. Stop here. */
+ return list;
+ mode = GET_MODE (op);
+ subreg_p = false;
+ if (code == SUBREG)
+ {
+ mode = wider_subreg_mode (op);
+ if (read_modify_subreg_p (op))
+ subreg_p = true;
+ op = SUBREG_REG (op);
+ code = GET_CODE (op);
+ }
+ if (REG_P (op))
+ {
+ if ((regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER)
+ return list;
+ /* Process all regs even unallocatable ones as we need info
+ about all regs for rematerialization pass. */
+ for (last = end_hard_regno (mode, regno); regno < last; regno++)
+ {
+ for (curr = list; curr != NULL; curr = curr->next)
+ if (curr->regno == regno && curr->subreg_p == subreg_p
+ && curr->biggest_mode == mode)
+ {
+ if (curr->type != type)
+ curr->type = OP_INOUT;
+ if (early_clobber)
+ curr->early_clobber_alts = ALL_ALTERNATIVES;
+ break;
+ }
+ if (curr == NULL)
+ {
+ /* This is a new hard regno or the info cannot be
+ integrated into the found structure. */
+#ifdef STACK_REGS
+ early_clobber
+ = (early_clobber
+ /* This clobber is to inform popping floating
+ point stack only. */
+ && ! (FIRST_STACK_REG <= regno
+ && regno <= LAST_STACK_REG));
+#endif
+ list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
+ early_clobber ? ALL_ALTERNATIVES : 0, list);
+ }
+ }
+ return list;
+ }
+ switch (code)
+ {
+ case SET:
+ list = collect_non_operand_hard_regs (insn, &SET_DEST (op), data,
+ list, OP_OUT, false);
+ list = collect_non_operand_hard_regs (insn, &SET_SRC (op), data,
+ list, OP_IN, false);
+ break;
+ case CLOBBER:
+ /* We treat clobber of non-operand hard registers as early clobber. */
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
+ list, OP_OUT, true);
+ break;
+ case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
+ list, OP_INOUT, false);
+ break;
+ case PRE_MODIFY: case POST_MODIFY:
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
+ list, OP_INOUT, false);
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 1), data,
+ list, OP_IN, false);
+ break;
+ default:
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, i), data,
+ list, OP_IN, false);
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (op, i) - 1; j >= 0; j--)
+ list = collect_non_operand_hard_regs (insn, &XVECEXP (op, i, j),
+ data, list, OP_IN, false);
+ }
+ }
+ return list;
+}
+
+/* Set up and return info about INSN. Set up the info if it is not set up
+ yet. */
+lra_insn_recog_data_t
+lra_set_insn_recog_data (rtx_insn *insn)
+{
+ lra_insn_recog_data_t data;
+ int i, n, icode;
+ rtx **locs;
+ unsigned int uid = INSN_UID (insn);
+ struct lra_static_insn_data *insn_static_data;
+
+ check_and_expand_insn_recog_data (uid);
+ if (DEBUG_INSN_P (insn))
+ icode = -1;
+ else
+ {
+ icode = INSN_CODE (insn);
+ if (icode < 0)
+ /* It might be a new simple insn which is not recognized yet. */
+ INSN_CODE (insn) = icode = recog_memoized (insn);
+ }
+ data = lra_insn_recog_data_pool.allocate ();
+ lra_insn_recog_data[uid] = data;
+ data->insn = insn;
+ data->used_insn_alternative = LRA_UNKNOWN_ALT;
+ data->icode = icode;
+ data->regs = NULL;
+ if (DEBUG_INSN_P (insn))
+ {
+ data->dup_loc = NULL;
+ data->arg_hard_regs = NULL;
+ data->preferred_alternatives = ALL_ALTERNATIVES;
+ if (DEBUG_BIND_INSN_P (insn))
+ {
+ data->insn_static_data = &debug_bind_static_data;
+ data->operand_loc = XNEWVEC (rtx *, 1);
+ data->operand_loc[0] = &INSN_VAR_LOCATION_LOC (insn);
+ }
+ else if (DEBUG_MARKER_INSN_P (insn))
+ {
+ data->insn_static_data = &debug_marker_static_data;
+ data->operand_loc = NULL;
+ }
+ return data;
+ }
+ if (icode < 0)
+ {
+ int nop, nalt;
+ machine_mode operand_mode[MAX_RECOG_OPERANDS];
+ const char *constraints[MAX_RECOG_OPERANDS];
+
+ nop = asm_noperands (PATTERN (insn));
+ data->operand_loc = data->dup_loc = NULL;
+ nalt = 1;
+ if (nop < 0)
+ {
+ /* It is a special insn like USE or CLOBBER. We should
+ recognize any regular insn otherwise LRA can do nothing
+ with this insn. */
+ gcc_assert (GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER
+ || GET_CODE (PATTERN (insn)) == ASM_INPUT);
+ data->insn_static_data = insn_static_data
+ = get_static_insn_data (-1, 0, 0, nalt);
+ }
+ else
+ {
+ /* expand_asm_operands makes sure there aren't too many
+ operands. */
+ lra_assert (nop <= MAX_RECOG_OPERANDS);
+ if (nop != 0)
+ data->operand_loc = XNEWVEC (rtx *, nop);
+ /* Now get the operand values and constraints out of the
+ insn. */
+ decode_asm_operands (PATTERN (insn), NULL,
+ data->operand_loc,
+ constraints, operand_mode, NULL);
+ if (nop > 0)
+ for (const char *p =constraints[0]; *p; p++)
+ nalt += *p == ',';
+ data->insn_static_data = insn_static_data
+ = get_static_insn_data (-1, nop, 0, nalt);
+ for (i = 0; i < nop; i++)
+ {
+ insn_static_data->operand[i].mode = operand_mode[i];
+ insn_static_data->operand[i].constraint = constraints[i];
+ insn_static_data->operand[i].strict_low = false;
+ insn_static_data->operand[i].is_operator = false;
+ insn_static_data->operand[i].is_address = false;
+ }
+ }
+ for (i = 0; i < insn_static_data->n_operands; i++)
+ insn_static_data->operand[i].type
+ = (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
+ : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
+ : OP_IN);
+ data->preferred_alternatives = ALL_ALTERNATIVES;
+ if (nop > 0)
+ {
+ operand_alternative *op_alt = XCNEWVEC (operand_alternative,
+ nalt * nop);
+ preprocess_constraints (nop, nalt, constraints, op_alt,
+ data->operand_loc);
+ setup_operand_alternative (data, op_alt);
+ }
+ }
+ else
+ {
+ insn_extract (insn);
+ data->insn_static_data = insn_static_data
+ = get_static_insn_data (icode, insn_data[icode].n_operands,
+ insn_data[icode].n_dups,
+ insn_data[icode].n_alternatives);
+ n = insn_static_data->n_operands;
+ if (n == 0)
+ locs = NULL;
+ else
+ {
+ locs = XNEWVEC (rtx *, n);
+ memcpy (locs, recog_data.operand_loc, n * sizeof (rtx *));
+ }
+ data->operand_loc = locs;
+ n = insn_static_data->n_dups;
+ if (n == 0)
+ locs = NULL;
+ else
+ {
+ locs = XNEWVEC (rtx *, n);
+ memcpy (locs, recog_data.dup_loc, n * sizeof (rtx *));
+ }
+ data->dup_loc = locs;
+ data->preferred_alternatives = get_preferred_alternatives (insn);
+ const operand_alternative *op_alt = preprocess_insn_constraints (icode);
+ if (!insn_static_data->operand_alternative)
+ setup_operand_alternative (data, op_alt);
+ else if (op_alt != insn_static_data->operand_alternative)
+ insn_static_data->operand_alternative = op_alt;
+ }
+ if (GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == USE)
+ insn_static_data->hard_regs = NULL;
+ else
+ insn_static_data->hard_regs
+ = collect_non_operand_hard_regs (insn, &PATTERN (insn), data,
+ NULL, OP_IN, false);
+ data->arg_hard_regs = NULL;
+ if (CALL_P (insn))
+ {
+ bool use_p;
+ rtx link;
+ int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER];
+
+ n_hard_regs = 0;
+ /* Finding implicit hard register usage. We believe it will be
+ not changed whatever transformations are used. Call insns
+ are such example. */
+ for (link = CALL_INSN_FUNCTION_USAGE (insn);
+ link != NULL_RTX;
+ link = XEXP (link, 1))
+ if (((use_p = GET_CODE (XEXP (link, 0)) == USE)
+ || GET_CODE (XEXP (link, 0)) == CLOBBER)
+ && REG_P (XEXP (XEXP (link, 0), 0)))
+ {
+ regno = REGNO (XEXP (XEXP (link, 0), 0));
+ lra_assert (regno < FIRST_PSEUDO_REGISTER);
+ /* It is an argument register. */
+ for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--)
+ arg_hard_regs[n_hard_regs++]
+ = regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER);
+ }
+
+ if (n_hard_regs != 0)
+ {
+ arg_hard_regs[n_hard_regs++] = -1;
+ data->arg_hard_regs = XNEWVEC (int, n_hard_regs);
+ memcpy (data->arg_hard_regs, arg_hard_regs,
+ sizeof (int) * n_hard_regs);
+ }
+ }
+ /* Some output operand can be recognized only from the context not
+ from the constraints which are empty in this case. Call insn may
+ contain a hard register in set destination with empty constraint
+ and extract_insn treats them as an input. */
+ for (i = 0; i < insn_static_data->n_operands; i++)
+ {
+ int j;
+ rtx pat, set;
+ struct lra_operand_data *operand = &insn_static_data->operand[i];
+
+ /* ??? Should we treat 'X' the same way. It looks to me that
+ 'X' means anything and empty constraint means we do not
+ care. */
+ if (operand->type != OP_IN || *operand->constraint != '\0'
+ || operand->is_operator)
+ continue;
+ pat = PATTERN (insn);
+ if (GET_CODE (pat) == SET)
+ {
+ if (data->operand_loc[i] != &SET_DEST (pat))
+ continue;
+ }
+ else if (GET_CODE (pat) == PARALLEL)
+ {
+ for (j = XVECLEN (pat, 0) - 1; j >= 0; j--)
+ {
+ set = XVECEXP (PATTERN (insn), 0, j);
+ if (GET_CODE (set) == SET
+ && &SET_DEST (set) == data->operand_loc[i])
+ break;
+ }
+ if (j < 0)
+ continue;
+ }
+ else
+ continue;
+ operand->type = OP_OUT;
+ }
+ return data;
+}
+
+/* Return info about insn give by UID. The info should be already set
+ up. */
+static lra_insn_recog_data_t
+get_insn_recog_data_by_uid (int uid)
+{
+ lra_insn_recog_data_t data;
+
+ data = lra_insn_recog_data[uid];
+ lra_assert (data != NULL);
+ return data;
+}
+
+/* Invalidate all info about insn given by its UID. */
+static void
+invalidate_insn_recog_data (int uid)
+{
+ lra_insn_recog_data_t data;
+
+ data = lra_insn_recog_data[uid];
+ lra_assert (data != NULL);
+ free_insn_recog_data (data);
+ lra_insn_recog_data[uid] = NULL;
+}
+
+/* Update all the insn info about INSN. It is usually called when
+ something in the insn was changed. Return the updated info. */
+lra_insn_recog_data_t
+lra_update_insn_recog_data (rtx_insn *insn)
+{
+ lra_insn_recog_data_t data;
+ int n;
+ unsigned int uid = INSN_UID (insn);
+ struct lra_static_insn_data *insn_static_data;
+ poly_int64 sp_offset = 0;
+
+ check_and_expand_insn_recog_data (uid);
+ if ((data = lra_insn_recog_data[uid]) != NULL
+ && data->icode != INSN_CODE (insn))
+ {
+ sp_offset = data->sp_offset;
+ invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn));
+ invalidate_insn_recog_data (uid);
+ data = NULL;
+ }
+ if (data == NULL)
+ {
+ data = lra_get_insn_recog_data (insn);
+ /* Initiate or restore SP offset. */
+ data->sp_offset = sp_offset;
+ return data;
+ }
+ insn_static_data = data->insn_static_data;
+ data->used_insn_alternative = LRA_UNKNOWN_ALT;
+ if (DEBUG_INSN_P (insn))
+ return data;
+ if (data->icode < 0)
+ {
+ int nop;
+ machine_mode operand_mode[MAX_RECOG_OPERANDS];
+ const char *constraints[MAX_RECOG_OPERANDS];
+
+ nop = asm_noperands (PATTERN (insn));
+ if (nop >= 0)
+ {
+ lra_assert (nop == data->insn_static_data->n_operands);
+ /* Now get the operand values and constraints out of the
+ insn. */
+ decode_asm_operands (PATTERN (insn), NULL,
+ data->operand_loc,
+ constraints, operand_mode, NULL);
+
+ if (flag_checking)
+ for (int i = 0; i < nop; i++)
+ lra_assert
+ (insn_static_data->operand[i].mode == operand_mode[i]
+ && insn_static_data->operand[i].constraint == constraints[i]
+ && ! insn_static_data->operand[i].is_operator);
+ }
+
+ if (flag_checking)
+ for (int i = 0; i < insn_static_data->n_operands; i++)
+ lra_assert
+ (insn_static_data->operand[i].type
+ == (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
+ : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
+ : OP_IN));
+ }
+ else
+ {
+ insn_extract (insn);
+ n = insn_static_data->n_operands;
+ if (n != 0)
+ memcpy (data->operand_loc, recog_data.operand_loc, n * sizeof (rtx *));
+ n = insn_static_data->n_dups;
+ if (n != 0)
+ memcpy (data->dup_loc, recog_data.dup_loc, n * sizeof (rtx *));
+ lra_assert (check_bool_attrs (insn));
+ }
+ return data;
+}
+
+/* Set up that INSN is using alternative ALT now. */
+void
+lra_set_used_insn_alternative (rtx_insn *insn, int alt)
+{
+ lra_insn_recog_data_t data;
+
+ data = lra_get_insn_recog_data (insn);
+ data->used_insn_alternative = alt;
+}
+
+/* Set up that insn with UID is using alternative ALT now. The insn
+ info should be already set up. */
+void
+lra_set_used_insn_alternative_by_uid (int uid, int alt)
+{
+ lra_insn_recog_data_t data;
+
+ check_and_expand_insn_recog_data (uid);
+ data = lra_insn_recog_data[uid];
+ lra_assert (data != NULL);
+ data->used_insn_alternative = alt;
+}
+
+
+
+/* This page contains code dealing with common register info and
+ pseudo copies. */
+
+/* The size of the following array. */
+static int reg_info_size;
+/* Common info about each register. */
+class lra_reg *lra_reg_info;
+
+HARD_REG_SET hard_regs_spilled_into;
+
+/* Last register value. */
+static int last_reg_value;
+
+/* Return new register value. */
+static int
+get_new_reg_value (void)
+{
+ return ++last_reg_value;
+}
+
+/* Vec referring to pseudo copies. */
+static vec<lra_copy_t> copy_vec;
+
+/* Initialize I-th element of lra_reg_info. */
+static inline void
+initialize_lra_reg_info_element (int i)
+{
+ bitmap_initialize (&lra_reg_info[i].insn_bitmap, &reg_obstack);
+#ifdef STACK_REGS
+ lra_reg_info[i].no_stack_p = false;
+#endif
+ CLEAR_HARD_REG_SET (lra_reg_info[i].conflict_hard_regs);
+ lra_reg_info[i].preferred_hard_regno1 = -1;
+ lra_reg_info[i].preferred_hard_regno2 = -1;
+ lra_reg_info[i].preferred_hard_regno_profit1 = 0;
+ lra_reg_info[i].preferred_hard_regno_profit2 = 0;
+ lra_reg_info[i].biggest_mode = VOIDmode;
+ lra_reg_info[i].live_ranges = NULL;
+ lra_reg_info[i].nrefs = lra_reg_info[i].freq = 0;
+ lra_reg_info[i].last_reload = 0;
+ lra_reg_info[i].restore_rtx = NULL_RTX;
+ lra_reg_info[i].val = get_new_reg_value ();
+ lra_reg_info[i].offset = 0;
+ lra_reg_info[i].copies = NULL;
+}
+
+/* Initialize common reg info and copies. */
+static void
+init_reg_info (void)
+{
+ int i;
+
+ last_reg_value = 0;
+ reg_info_size = max_reg_num () * 3 / 2 + 1;
+ lra_reg_info = XNEWVEC (class lra_reg, reg_info_size);
+ for (i = 0; i < reg_info_size; i++)
+ initialize_lra_reg_info_element (i);
+ copy_vec.truncate (0);
+ CLEAR_HARD_REG_SET (hard_regs_spilled_into);
+}
+
+
+/* Finish common reg info and copies. */
+static void
+finish_reg_info (void)
+{
+ int i;
+
+ for (i = 0; i < reg_info_size; i++)
+ bitmap_clear (&lra_reg_info[i].insn_bitmap);
+ free (lra_reg_info);
+ reg_info_size = 0;
+}
+
+/* Expand common reg info if it is necessary. */
+static void
+expand_reg_info (void)
+{
+ int i, old = reg_info_size;
+
+ if (reg_info_size > max_reg_num ())
+ return;
+ reg_info_size = max_reg_num () * 3 / 2 + 1;
+ lra_reg_info = XRESIZEVEC (class lra_reg, lra_reg_info, reg_info_size);
+ for (i = old; i < reg_info_size; i++)
+ initialize_lra_reg_info_element (i);
+}
+
+/* Free all copies. */
+void
+lra_free_copies (void)
+{
+ lra_copy_t cp;
+
+ while (copy_vec.length () != 0)
+ {
+ cp = copy_vec.pop ();
+ lra_reg_info[cp->regno1].copies = lra_reg_info[cp->regno2].copies = NULL;
+ lra_copy_pool.remove (cp);
+ }
+}
+
+/* Create copy of two pseudos REGNO1 and REGNO2. The copy execution
+ frequency is FREQ. */
+void
+lra_create_copy (int regno1, int regno2, int freq)
+{
+ bool regno1_dest_p;
+ lra_copy_t cp;
+
+ lra_assert (regno1 != regno2);
+ regno1_dest_p = true;
+ if (regno1 > regno2)
+ {
+ std::swap (regno1, regno2);
+ regno1_dest_p = false;
+ }
+ cp = lra_copy_pool.allocate ();
+ copy_vec.safe_push (cp);
+ cp->regno1_dest_p = regno1_dest_p;
+ cp->freq = freq;
+ cp->regno1 = regno1;
+ cp->regno2 = regno2;
+ cp->regno1_next = lra_reg_info[regno1].copies;
+ lra_reg_info[regno1].copies = cp;
+ cp->regno2_next = lra_reg_info[regno2].copies;
+ lra_reg_info[regno2].copies = cp;
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, " Creating copy r%d%sr%d@%d\n",
+ regno1, regno1_dest_p ? "<-" : "->", regno2, freq);
+}
+
+/* Return N-th (0, 1, ...) copy. If there is no copy, return
+ NULL. */
+lra_copy_t
+lra_get_copy (int n)
+{
+ if (n >= (int) copy_vec.length ())
+ return NULL;
+ return copy_vec[n];
+}
+
+
+
+/* This page contains code dealing with info about registers in
+ insns. */
+
+/* Process X of INSN recursively and add info (operand type is given
+ by TYPE) about registers in X to the insn DATA. If X can be early
+ clobbered, alternatives in which it can be early clobbered are given
+ by EARLY_CLOBBER_ALTS. */
+static void
+add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
+ rtx_insn *insn, enum op_type type,
+ alternative_mask early_clobber_alts)
+{
+ int i, j, regno;
+ bool subreg_p;
+ machine_mode mode;
+ const char *fmt;
+ enum rtx_code code;
+ struct lra_insn_reg *curr;
+
+ code = GET_CODE (x);
+ mode = GET_MODE (x);
+ subreg_p = false;
+ if (GET_CODE (x) == SUBREG)
+ {
+ mode = wider_subreg_mode (x);
+ if (read_modify_subreg_p (x))
+ subreg_p = true;
+ x = SUBREG_REG (x);
+ code = GET_CODE (x);
+ }
+ if (REG_P (x))
+ {
+ regno = REGNO (x);
+ /* Process all regs even unallocatable ones as we need info about
+ all regs for rematerialization pass. */
+ expand_reg_info ();
+ if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
+ {
+ data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
+ early_clobber_alts, data->regs);
+ return;
+ }
+ else
+ {
+ for (curr = data->regs; curr != NULL; curr = curr->next)
+ if (curr->regno == regno)
+ {
+ if (curr->subreg_p != subreg_p || curr->biggest_mode != mode)
+ /* The info cannot be integrated into the found
+ structure. */
+ data->regs = new_insn_reg (data->insn, regno, type, mode,
+ subreg_p, early_clobber_alts,
+ data->regs);
+ else
+ {
+ if (curr->type != type)
+ curr->type = OP_INOUT;
+ curr->early_clobber_alts |= early_clobber_alts;
+ }
+ return;
+ }
+ gcc_unreachable ();
+ }
+ }
+
+ switch (code)
+ {
+ case SET:
+ add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, 0);
+ add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, 0);
+ break;
+ case CLOBBER:
+ /* We treat clobber of non-operand hard registers as early
+ clobber. */
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
+ ALL_ALTERNATIVES);
+ break;
+ case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
+ break;
+ case PRE_MODIFY: case POST_MODIFY:
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, 0);
+ break;
+ default:
+ if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
+ /* Some targets place small structures in registers for return
+ values of functions, and those registers are wrapped in
+ PARALLEL that we may see as the destination of a SET. Here
+ is an example:
+
+ (call_insn 13 12 14 2 (set (parallel:BLK [
+ (expr_list:REG_DEP_TRUE (reg:DI 0 ax)
+ (const_int 0 [0]))
+ (expr_list:REG_DEP_TRUE (reg:DI 1 dx)
+ (const_int 8 [0x8]))
+ ])
+ (call (mem:QI (symbol_ref:DI (... */
+ type = OP_IN;
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, 0);
+ else if (fmt[i] == 'E')
+ {
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
+ type, 0);
+ }
+ }
+ }
+}
+
+/* Return execution frequency of INSN. */
+static int
+get_insn_freq (rtx_insn *insn)
+{
+ basic_block bb = BLOCK_FOR_INSN (insn);
+
+ gcc_checking_assert (bb != NULL);
+ return REG_FREQ_FROM_BB (bb);
+}
+
+/* Invalidate all reg info of INSN with DATA and execution frequency
+ FREQ. Update common info about the invalidated registers. */
+static void
+invalidate_insn_data_regno_info (lra_insn_recog_data_t data, rtx_insn *insn,
+ int freq)
+{
+ int uid;
+ bool debug_p;
+ unsigned int i;
+ struct lra_insn_reg *ir, *next_ir;
+
+ uid = INSN_UID (insn);
+ debug_p = DEBUG_INSN_P (insn);
+ for (ir = data->regs; ir != NULL; ir = next_ir)
+ {
+ i = ir->regno;
+ next_ir = ir->next;
+ lra_insn_reg_pool.remove (ir);
+ bitmap_clear_bit (&lra_reg_info[i].insn_bitmap, uid);
+ if (i >= FIRST_PSEUDO_REGISTER && ! debug_p)
+ {
+ lra_reg_info[i].nrefs--;
+ lra_reg_info[i].freq -= freq;
+ lra_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0);
+ }
+ }
+ data->regs = NULL;
+}
+
+/* Invalidate all reg info of INSN. Update common info about the
+ invalidated registers. */
+void
+lra_invalidate_insn_regno_info (rtx_insn *insn)
+{
+ invalidate_insn_data_regno_info (lra_get_insn_recog_data (insn), insn,
+ get_insn_freq (insn));
+}
+
+/* Update common reg info from reg info of insn given by its DATA and
+ execution frequency FREQ. */
+static void
+setup_insn_reg_info (lra_insn_recog_data_t data, int freq)
+{
+ unsigned int i;
+ struct lra_insn_reg *ir;
+
+ for (ir = data->regs; ir != NULL; ir = ir->next)
+ if ((i = ir->regno) >= FIRST_PSEUDO_REGISTER)
+ {
+ lra_reg_info[i].nrefs++;
+ lra_reg_info[i].freq += freq;
+ }
+}
+
+/* Set up insn reg info of INSN. Update common reg info from reg info
+ of INSN. */
+void
+lra_update_insn_regno_info (rtx_insn *insn)
+{
+ int i, freq;
+ lra_insn_recog_data_t data;
+ struct lra_static_insn_data *static_data;
+ enum rtx_code code;
+ rtx link;
+
+ if (! INSN_P (insn))
+ return;
+ data = lra_get_insn_recog_data (insn);
+ static_data = data->insn_static_data;
+ freq = NONDEBUG_INSN_P (insn) ? get_insn_freq (insn) : 0;
+ invalidate_insn_data_regno_info (data, insn, freq);
+ for (i = static_data->n_operands - 1; i >= 0; i--)
+ add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
+ static_data->operand[i].type,
+ static_data->operand[i].early_clobber_alts);
+ if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
+ add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
+ code == USE ? OP_IN : OP_OUT, 0);
+ if (CALL_P (insn))
+ /* On some targets call insns can refer to pseudos in memory in
+ CALL_INSN_FUNCTION_USAGE list. Process them in order to
+ consider their occurrences in calls for different
+ transformations (e.g. inheritance) with given pseudos. */
+ for (link = CALL_INSN_FUNCTION_USAGE (insn);
+ link != NULL_RTX;
+ link = XEXP (link, 1))
+ {
+ code = GET_CODE (XEXP (link, 0));
+ if ((code == USE || code == CLOBBER)
+ && MEM_P (XEXP (XEXP (link, 0), 0)))
+ add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
+ code == USE ? OP_IN : OP_OUT, 0);
+ }
+ if (NONDEBUG_INSN_P (insn))
+ setup_insn_reg_info (data, freq);
+}
+
+/* Return reg info of insn given by it UID. */
+struct lra_insn_reg *
+lra_get_insn_regs (int uid)
+{
+ lra_insn_recog_data_t data;
+
+ data = get_insn_recog_data_by_uid (uid);
+ return data->regs;
+}
+
+
+
+/* Recursive hash function for RTL X. */
+hashval_t
+lra_rtx_hash (rtx x)
+{
+ int i, j;
+ enum rtx_code code;
+ const char *fmt;
+ hashval_t val = 0;
+
+ if (x == 0)
+ return val;
+
+ code = GET_CODE (x);
+ val += (int) code + 4095;
+
+ /* Some RTL can be compared nonrecursively. */
+ switch (code)
+ {
+ case REG:
+ return val + REGNO (x);
+
+ case LABEL_REF:
+ return iterative_hash_object (XEXP (x, 0), val);
+
+ case SYMBOL_REF:
+ return iterative_hash_object (XSTR (x, 0), val);
+
+ case SCRATCH:
+ case CONST_DOUBLE:
+ case CONST_VECTOR:
+ return val;
+
+ case CONST_INT:
+ return val + UINTVAL (x);
+
+ default:
+ break;
+ }
+
+ /* Hash the elements. */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ switch (fmt[i])
+ {
+ case 'w':
+ val += XWINT (x, i);
+ break;
+
+ case 'n':
+ case 'i':
+ val += XINT (x, i);
+ break;
+
+ case 'V':
+ case 'E':
+ val += XVECLEN (x, i);
+
+ for (j = 0; j < XVECLEN (x, i); j++)
+ val += lra_rtx_hash (XVECEXP (x, i, j));
+ break;
+
+ case 'e':
+ val += lra_rtx_hash (XEXP (x, i));
+ break;
+
+ case 'S':
+ case 's':
+ val += htab_hash_string (XSTR (x, i));
+ break;
+
+ case 'u':
+ case '0':
+ case 't':
+ break;
+
+ /* It is believed that rtx's at this level will never
+ contain anything but integers and other rtx's, except for
+ within LABEL_REFs and SYMBOL_REFs. */
+ default:
+ abort ();
+ }
+ }
+ return val;
+}
+
+
+
+/* This page contains code dealing with stack of the insns which
+ should be processed by the next constraint pass. */
+
+/* Bitmap used to put an insn on the stack only in one exemplar. */
+static sbitmap lra_constraint_insn_stack_bitmap;
+
+/* The stack itself. */
+vec<rtx_insn *> lra_constraint_insn_stack;
+
+/* Put INSN on the stack. If ALWAYS_UPDATE is true, always update the reg
+ info for INSN, otherwise only update it if INSN is not already on the
+ stack. */
+static inline void
+lra_push_insn_1 (rtx_insn *insn, bool always_update)
+{
+ unsigned int uid = INSN_UID (insn);
+ if (always_update)
+ lra_update_insn_regno_info (insn);
+ if (uid >= SBITMAP_SIZE (lra_constraint_insn_stack_bitmap))
+ lra_constraint_insn_stack_bitmap =
+ sbitmap_resize (lra_constraint_insn_stack_bitmap, 3 * uid / 2, 0);
+ if (bitmap_bit_p (lra_constraint_insn_stack_bitmap, uid))
+ return;
+ bitmap_set_bit (lra_constraint_insn_stack_bitmap, uid);
+ if (! always_update)
+ lra_update_insn_regno_info (insn);
+ lra_constraint_insn_stack.safe_push (insn);
+}
+
+/* Put INSN on the stack. */
+void
+lra_push_insn (rtx_insn *insn)
+{
+ lra_push_insn_1 (insn, false);
+}
+
+/* Put INSN on the stack and update its reg info. */
+void
+lra_push_insn_and_update_insn_regno_info (rtx_insn *insn)
+{
+ lra_push_insn_1 (insn, true);
+}
+
+/* Put insn with UID on the stack. */
+void
+lra_push_insn_by_uid (unsigned int uid)
+{
+ lra_push_insn (lra_insn_recog_data[uid]->insn);
+}
+
+/* Take the last-inserted insns off the stack and return it. */
+rtx_insn *
+lra_pop_insn (void)
+{
+ rtx_insn *insn = lra_constraint_insn_stack.pop ();
+ bitmap_clear_bit (lra_constraint_insn_stack_bitmap, INSN_UID (insn));
+ return insn;
+}
+
+/* Return the current size of the insn stack. */
+unsigned int
+lra_insn_stack_length (void)
+{
+ return lra_constraint_insn_stack.length ();
+}
+
+/* Push insns FROM to TO (excluding it) going in reverse order. */
+static void
+push_insns (rtx_insn *from, rtx_insn *to)
+{
+ rtx_insn *insn;
+
+ if (from == NULL_RTX)
+ return;
+ for (insn = from; insn != to; insn = PREV_INSN (insn))
+ if (INSN_P (insn))
+ lra_push_insn (insn);
+}
+
+/* Set up sp offset for insn in range [FROM, LAST]. The offset is
+ taken from the next BB insn after LAST or zero if there in such
+ insn. */
+static void
+setup_sp_offset (rtx_insn *from, rtx_insn *last)
+{
+ rtx_insn *before = next_nonnote_nondebug_insn_bb (last);
+ poly_int64 offset = (before == NULL_RTX || ! INSN_P (before)
+ ? 0 : lra_get_insn_recog_data (before)->sp_offset);
+
+ for (rtx_insn *insn = from; insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
+ lra_get_insn_recog_data (insn)->sp_offset = offset;
+}
+
+/* Emit insns BEFORE before INSN and insns AFTER after INSN. Put the
+ insns onto the stack. Print about emitting the insns with
+ TITLE. */
+void
+lra_process_new_insns (rtx_insn *insn, rtx_insn *before, rtx_insn *after,
+ const char *title)
+{
+ if (before == NULL_RTX && after == NULL_RTX)
+ return;
+ if (lra_dump_file != NULL)
+ {
+ dump_insn_slim (lra_dump_file, insn);
+ if (before != NULL_RTX)
+ {
+ fprintf (lra_dump_file," %s before:\n", title);
+ dump_rtl_slim (lra_dump_file, before, NULL, -1, 0);
+ }
+ }
+ if (before != NULL_RTX)
+ {
+ if (cfun->can_throw_non_call_exceptions)
+ copy_reg_eh_region_note_forward (insn, before, NULL);
+ emit_insn_before (before, insn);
+ push_insns (PREV_INSN (insn), PREV_INSN (before));
+ setup_sp_offset (before, PREV_INSN (insn));
+ }
+ if (after != NULL_RTX)
+ {
+ if (cfun->can_throw_non_call_exceptions)
+ copy_reg_eh_region_note_forward (insn, after, NULL);
+ if (! JUMP_P (insn))
+ {
+ rtx_insn *last;
+
+ if (lra_dump_file != NULL)
+ {
+ fprintf (lra_dump_file, " %s after:\n", title);
+ dump_rtl_slim (lra_dump_file, after, NULL, -1, 0);
+ }
+ for (last = after;
+ NEXT_INSN (last) != NULL_RTX;
+ last = NEXT_INSN (last))
+ ;
+ emit_insn_after (after, insn);
+ push_insns (last, insn);
+ setup_sp_offset (after, last);
+ }
+ else
+ {
+ /* Put output reload insns on successor BBs: */
+ edge_iterator ei;
+ edge e;
+
+ FOR_EACH_EDGE (e, ei, BLOCK_FOR_INSN (insn)->succs)
+ if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
+ {
+ /* We already made the edge no-critical in ira.c::ira */
+ lra_assert (!EDGE_CRITICAL_P (e));
+ rtx_insn *curr, *tmp = BB_HEAD (e->dest);
+ if (LABEL_P (tmp))
+ tmp = NEXT_INSN (tmp);
+ if (NOTE_INSN_BASIC_BLOCK_P (tmp))
+ tmp = NEXT_INSN (tmp);
+ /* Do not put reload insns if it is the last BB
+ without actual insns. */
+ if (tmp == NULL)
+ continue;
+ start_sequence ();
+ for (curr = after; curr != NULL_RTX; curr = NEXT_INSN (curr))
+ emit_insn (copy_insn (PATTERN (curr)));
+ rtx_insn *copy = get_insns (), *last = get_last_insn ();
+ end_sequence ();
+ if (lra_dump_file != NULL)
+ {
+ fprintf (lra_dump_file, " %s after in bb%d:\n", title,
+ e->dest->index);
+ dump_rtl_slim (lra_dump_file, copy, NULL, -1, 0);
+ }
+ /* Use the right emit func for setting up BB_END/BB_HEAD: */
+ if (BB_END (e->dest) == PREV_INSN (tmp))
+ emit_insn_after_noloc (copy, PREV_INSN (tmp), e->dest);
+ else
+ emit_insn_before_noloc (copy, tmp, e->dest);
+ push_insns (last, PREV_INSN (copy));
+ setup_sp_offset (copy, last);
+ /* We can ignore BB live info here as it and reg notes
+ will be updated before the next assignment
+ sub-pass. */
+ }
+ }
+ }
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file, "\n");
+ if (cfun->can_throw_non_call_exceptions)
+ {
+ rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ if (note && !insn_could_throw_p (insn))
+ remove_note (insn, note);
+ }
+}
+
+
+/* Replace all references to register OLD_REGNO in *LOC with pseudo
+ register NEW_REG. Try to simplify subreg of constant if SUBREG_P.
+ DEBUG_P is if LOC is within a DEBUG_INSN. Return true if any
+ change was made. */
+bool
+lra_substitute_pseudo (rtx *loc, int old_regno, rtx new_reg, bool subreg_p,
+ bool debug_p)
+{
+ rtx x = *loc;
+ bool result = false;
+ enum rtx_code code;
+ const char *fmt;
+ int i, j;
+
+ if (x == NULL_RTX)
+ return false;
+
+ code = GET_CODE (x);
+ if (code == SUBREG && subreg_p)
+ {
+ rtx subst, inner = SUBREG_REG (x);
+ /* Transform subreg of constant while we still have inner mode
+ of the subreg. The subreg internal should not be an insn
+ operand. */
+ if (REG_P (inner) && (int) REGNO (inner) == old_regno
+ && CONSTANT_P (new_reg)
+ && (subst = simplify_subreg (GET_MODE (x), new_reg, GET_MODE (inner),
+ SUBREG_BYTE (x))) != NULL_RTX)
+ {
+ *loc = subst;
+ return true;
+ }
+
+ }
+ else if (code == REG && (int) REGNO (x) == old_regno)
+ {
+ machine_mode mode = GET_MODE (x);
+ machine_mode inner_mode = GET_MODE (new_reg);
+
+ if (mode != inner_mode
+ && ! (CONST_SCALAR_INT_P (new_reg) && SCALAR_INT_MODE_P (mode)))
+ {
+ poly_uint64 offset = 0;
+ if (partial_subreg_p (mode, inner_mode)
+ && SCALAR_INT_MODE_P (inner_mode))
+ offset = subreg_lowpart_offset (mode, inner_mode);
+ if (debug_p)
+ new_reg = gen_rtx_raw_SUBREG (mode, new_reg, offset);
+ else
+ new_reg = gen_rtx_SUBREG (mode, new_reg, offset);
+ }
+ *loc = new_reg;
+ return true;
+ }
+
+ /* Scan all the operand sub-expressions. */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ if (lra_substitute_pseudo (&XEXP (x, i), old_regno,
+ new_reg, subreg_p, debug_p))
+ result = true;
+ }
+ else if (fmt[i] == 'E')
+ {
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ if (lra_substitute_pseudo (&XVECEXP (x, i, j), old_regno,
+ new_reg, subreg_p, debug_p))
+ result = true;
+ }
+ }
+ return result;
+}
+
+/* Call lra_substitute_pseudo within an insn. Try to simplify subreg
+ of constant if SUBREG_P. This won't update the insn ptr, just the
+ contents of the insn. */
+bool
+lra_substitute_pseudo_within_insn (rtx_insn *insn, int old_regno,
+ rtx new_reg, bool subreg_p)
+{
+ rtx loc = insn;
+ return lra_substitute_pseudo (&loc, old_regno, new_reg, subreg_p,
+ DEBUG_INSN_P (insn));
+}
+
+
+
+/* Return new register of the same mode as ORIGINAL of class ALL_REGS.
+ Used in ira_remove_scratches. */
+static rtx
+get_scratch_reg (rtx original)
+{
+ return lra_create_new_reg (GET_MODE (original), original, ALL_REGS, NULL);
+}
+
+/* Remove all insn scratches in INSN. */
+static void
+remove_insn_scratches (rtx_insn *insn)
+{
+ if (ira_remove_insn_scratches (insn, true, lra_dump_file, get_scratch_reg))
+ df_insn_rescan (insn);
+}
+
+/* Remove all insn scratches in the current function. */
+static void
+remove_scratches (void)
+{
+ basic_block bb;
+ rtx_insn *insn;
+
+ FOR_EACH_BB_FN (bb, cfun)
+ FOR_BB_INSNS (bb, insn)
+ if (INSN_P (insn))
+ remove_insn_scratches (insn);
+}
+
+/* Function checks RTL for correctness. If FINAL_P is true, it is
+ done at the end of LRA and the check is more rigorous. */
+static void
+check_rtl (bool final_p)
+{
+ basic_block bb;
+ rtx_insn *insn;
+
+ lra_assert (! final_p || reload_completed);
+ FOR_EACH_BB_FN (bb, cfun)
+ FOR_BB_INSNS (bb, insn)
+ if (NONDEBUG_INSN_P (insn)
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT)
+ {
+ if (final_p)
+ {
+ extract_constrain_insn (insn);
+ continue;
+ }
+ /* LRA code is based on assumption that all addresses can be
+ correctly decomposed. LRA can generate reloads for
+ decomposable addresses. The decomposition code checks the
+ correctness of the addresses. So we don't need to check
+ the addresses here. Don't call insn_invalid_p here, it can
+ change the code at this stage. */
+ if (recog_memoized (insn) < 0 && asm_noperands (PATTERN (insn)) < 0)
+ fatal_insn_not_found (insn);
+ }
+}
+
+/* Determine if the current function has an exception receiver block
+ that reaches the exit block via non-exceptional edges */
+static bool
+has_nonexceptional_receiver (void)
+{
+ edge e;
+ edge_iterator ei;
+ basic_block *tos, *worklist, bb;
+
+ /* If we're not optimizing, then just err on the safe side. */
+ if (!optimize)
+ return true;
+
+ /* First determine which blocks can reach exit via normal paths. */
+ tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1);
+
+ FOR_EACH_BB_FN (bb, cfun)
+ bb->flags &= ~BB_REACHABLE;
+
+ /* Place the exit block on our worklist. */
+ EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_REACHABLE;
+ *tos++ = EXIT_BLOCK_PTR_FOR_FN (cfun);
+
+ /* Iterate: find everything reachable from what we've already seen. */
+ while (tos != worklist)
+ {
+ bb = *--tos;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->flags & EDGE_ABNORMAL)
+ {
+ free (worklist);
+ return true;
+ }
+ else
+ {
+ basic_block src = e->src;
+
+ if (!(src->flags & BB_REACHABLE))
+ {
+ src->flags |= BB_REACHABLE;
+ *tos++ = src;
+ }
+ }
+ }
+ free (worklist);
+ /* No exceptional block reached exit unexceptionally. */
+ return false;
+}
+
+/* Remove all REG_DEAD and REG_UNUSED notes and regenerate REG_INC.
+ We change pseudos by hard registers without notification of DF and
+ that can make the notes obsolete. DF-infrastructure does not deal
+ with REG_INC notes -- so we should regenerate them here. */
+static void
+update_inc_notes (void)
+{
+ rtx *pnote;
+ basic_block bb;
+ rtx_insn *insn;
+
+ FOR_EACH_BB_FN (bb, cfun)
+ FOR_BB_INSNS (bb, insn)
+ if (NONDEBUG_INSN_P (insn))
+ {
+ pnote = &REG_NOTES (insn);
+ while (*pnote != 0)
+ {
+ if (REG_NOTE_KIND (*pnote) == REG_DEAD
+ || REG_NOTE_KIND (*pnote) == REG_UNUSED
+ || REG_NOTE_KIND (*pnote) == REG_INC)
+ *pnote = XEXP (*pnote, 1);
+ else
+ pnote = &XEXP (*pnote, 1);
+ }
+
+ if (AUTO_INC_DEC)
+ add_auto_inc_notes (insn, PATTERN (insn));
+ }
+}
+
+/* Set to 1 while in lra. */
+int lra_in_progress;
+
+/* Start of pseudo regnos before the LRA. */
+int lra_new_regno_start;
+
+/* Start of reload pseudo regnos before the new spill pass. */
+int lra_constraint_new_regno_start;
+
+/* Avoid spilling pseudos with regno more than the following value if
+ it is possible. */
+int lra_bad_spill_regno_start;
+
+/* A pseudo of Pmode. */
+rtx lra_pmode_pseudo;
+
+/* Inheritance pseudo regnos before the new spill pass. */
+bitmap_head lra_inheritance_pseudos;
+
+/* Split regnos before the new spill pass. */
+bitmap_head lra_split_regs;
+
+/* Reload pseudo regnos before the new assignment pass which still can
+ be spilled after the assignment pass as memory is also accepted in
+ insns for the reload pseudos. */
+bitmap_head lra_optional_reload_pseudos;
+
+/* Pseudo regnos used for subreg reloads before the new assignment
+ pass. Such pseudos still can be spilled after the assignment
+ pass. */
+bitmap_head lra_subreg_reload_pseudos;
+
+/* File used for output of LRA debug information. */
+FILE *lra_dump_file;
+
+/* True if we split hard reg after the last constraint sub-pass. */
+bool lra_hard_reg_split_p;
+
+/* True if we found an asm error. */
+bool lra_asm_error_p;
+
+/* True if we should try spill into registers of different classes
+ instead of memory. */
+bool lra_reg_spill_p;
+
+/* Set up value LRA_REG_SPILL_P. */
+static void
+setup_reg_spill_flag (void)
+{
+ int cl, mode;
+
+ if (targetm.spill_class != NULL)
+ for (cl = 0; cl < (int) LIM_REG_CLASSES; cl++)
+ for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
+ if (targetm.spill_class ((enum reg_class) cl,
+ (machine_mode) mode) != NO_REGS)
+ {
+ lra_reg_spill_p = true;
+ return;
+ }
+ lra_reg_spill_p = false;
+}
+
+/* True if the current function is too big to use regular algorithms
+ in LRA. In other words, we should use simpler and faster algorithms
+ in LRA. It also means we should not worry about generation code
+ for caller saves. The value is set up in IRA. */
+bool lra_simple_p;
+
+/* Major LRA entry function. F is a file should be used to dump LRA
+ debug info. */
+void
+lra (FILE *f)
+{
+ int i;
+ bool live_p, inserted_p;
+
+ lra_dump_file = f;
+ lra_asm_error_p = false;
+ lra_pmode_pseudo = gen_reg_rtx (Pmode);
+
+ timevar_push (TV_LRA);
+
+ /* Make sure that the last insn is a note. Some subsequent passes
+ need it. */
+ emit_note (NOTE_INSN_DELETED);
+
+ lra_no_alloc_regs = ira_no_alloc_regs;
+
+ init_reg_info ();
+ expand_reg_info ();
+
+ init_insn_recog_data ();
+
+ /* Some quick check on RTL generated by previous passes. */
+ if (flag_checking)
+ check_rtl (false);
+
+ lra_in_progress = 1;
+
+ lra_live_range_iter = lra_coalesce_iter = lra_constraint_iter = 0;
+ lra_assignment_iter = lra_assignment_iter_after_spill = 0;
+ lra_inheritance_iter = lra_undo_inheritance_iter = 0;
+ lra_rematerialization_iter = 0;
+
+ setup_reg_spill_flag ();
+
+ /* Function remove_scratches can creates new pseudos for clobbers --
+ so set up lra_constraint_new_regno_start before its call to
+ permit changing reg classes for pseudos created by this
+ simplification. */
+ lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num ();
+ lra_bad_spill_regno_start = INT_MAX;
+ remove_scratches ();
+
+ /* A function that has a non-local label that can reach the exit
+ block via non-exceptional paths must save all call-saved
+ registers. */
+ if (cfun->has_nonlocal_label && has_nonexceptional_receiver ())
+ crtl->saves_all_registers = 1;
+
+ if (crtl->saves_all_registers)
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (!crtl->abi->clobbers_full_reg_p (i)
+ && !fixed_regs[i]
+ && !LOCAL_REGNO (i))
+ df_set_regs_ever_live (i, true);
+
+ /* We don't DF from now and avoid its using because it is to
+ expensive when a lot of RTL changes are made. */
+ df_set_flags (DF_NO_INSN_RESCAN);
+ lra_constraint_insn_stack.create (get_max_uid ());
+ lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ());
+ bitmap_clear (lra_constraint_insn_stack_bitmap);
+ lra_live_ranges_init ();
+ lra_constraints_init ();
+ lra_curr_reload_num = 0;
+ push_insns (get_last_insn (), NULL);
+ /* It is needed for the 1st coalescing. */
+ bitmap_initialize (&lra_inheritance_pseudos, &reg_obstack);
+ bitmap_initialize (&lra_split_regs, &reg_obstack);
+ bitmap_initialize (&lra_optional_reload_pseudos, &reg_obstack);
+ bitmap_initialize (&lra_subreg_reload_pseudos, &reg_obstack);
+ live_p = false;
+ if (maybe_ne (get_frame_size (), 0) && crtl->stack_alignment_needed)
+ /* If we have a stack frame, we must align it now. The stack size
+ may be a part of the offset computation for register
+ elimination. */
+ assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
+ lra_init_equiv ();
+ for (;;)
+ {
+ for (;;)
+ {
+ bool reloads_p = lra_constraints (lra_constraint_iter == 0);
+ /* Constraint transformations may result in that eliminable
+ hard regs become uneliminable and pseudos which use them
+ should be spilled. It is better to do it before pseudo
+ assignments.
+
+ For example, rs6000 can make
+ RS6000_PIC_OFFSET_TABLE_REGNUM uneliminable if we started
+ to use a constant pool. */
+ lra_eliminate (false, false);
+ /* We should try to assign hard registers to scratches even
+ if there were no RTL transformations in lra_constraints.
+ Also we should check IRA assignments on the first
+ iteration as they can be wrong because of early clobbers
+ operands which are ignored in IRA. */
+ if (! reloads_p && lra_constraint_iter > 1)
+ {
+ /* Stack is not empty here only when there are changes
+ during the elimination sub-pass. */
+ if (bitmap_empty_p (lra_constraint_insn_stack_bitmap))
+ break;
+ else
+ /* If there are no reloads but changing due
+ elimination, restart the constraint sub-pass
+ first. */
+ continue;
+ }
+ /* Do inheritance only for regular algorithms. */
+ if (! lra_simple_p)
+ lra_inheritance ();
+ if (live_p)
+ lra_clear_live_ranges ();
+ bool fails_p;
+ lra_hard_reg_split_p = false;
+ do
+ {
+ /* We need live ranges for lra_assign -- so build them.
+ But don't remove dead insns or change global live
+ info as we can undo inheritance transformations after
+ inheritance pseudo assigning. */
+ lra_create_live_ranges (true, !lra_simple_p);
+ live_p = true;
+ /* If we don't spill non-reload and non-inheritance
+ pseudos, there is no sense to run memory-memory move
+ coalescing. If inheritance pseudos were spilled, the
+ memory-memory moves involving them will be removed by
+ pass undoing inheritance. */
+ if (lra_simple_p)
+ lra_assign (fails_p);
+ else
+ {
+ bool spill_p = !lra_assign (fails_p);
+
+ if (lra_undo_inheritance ())
+ live_p = false;
+ if (spill_p && ! fails_p)
+ {
+ if (! live_p)
+ {
+ lra_create_live_ranges (true, true);
+ live_p = true;
+ }
+ if (lra_coalesce ())
+ live_p = false;
+ }
+ if (! live_p)
+ lra_clear_live_ranges ();
+ }
+ if (fails_p)
+ {
+ /* It is a very rare case. It is the last hope to
+ split a hard regno live range for a reload
+ pseudo. */
+ if (live_p)
+ lra_clear_live_ranges ();
+ live_p = false;
+ if (! lra_split_hard_reg_for ())
+ break;
+ lra_hard_reg_split_p = true;
+ }
+ }
+ while (fails_p);
+ if (! live_p) {
+ /* We need the correct reg notes for work of constraint sub-pass. */
+ lra_create_live_ranges (true, true);
+ live_p = true;
+ }
+ }
+ /* Don't clear optional reloads bitmap until all constraints are
+ satisfied as we need to differ them from regular reloads. */
+ bitmap_clear (&lra_optional_reload_pseudos);
+ bitmap_clear (&lra_subreg_reload_pseudos);
+ bitmap_clear (&lra_inheritance_pseudos);
+ bitmap_clear (&lra_split_regs);
+ if (! live_p)
+ {
+ /* We need full live info for spilling pseudos into
+ registers instead of memory. */
+ lra_create_live_ranges (lra_reg_spill_p, true);
+ live_p = true;
+ }
+ /* We should check necessity for spilling here as the above live
+ range pass can remove spilled pseudos. */
+ if (! lra_need_for_spills_p ())
+ break;
+ /* Now we know what pseudos should be spilled. Try to
+ rematerialize them first. */
+ if (lra_remat ())
+ {
+ /* We need full live info -- see the comment above. */
+ lra_create_live_ranges (lra_reg_spill_p, true);
+ live_p = true;
+ if (! lra_need_for_spills_p ())
+ {
+ if (lra_need_for_scratch_reg_p ())
+ continue;
+ break;
+ }
+ }
+ lra_spill ();
+ /* Assignment of stack slots changes elimination offsets for
+ some eliminations. So update the offsets here. */
+ lra_eliminate (false, false);
+ lra_constraint_new_regno_start = max_reg_num ();
+ if (lra_bad_spill_regno_start == INT_MAX
+ && lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES
+ && lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES)
+ /* After switching off inheritance and rematerialization
+ passes, avoid spilling reload pseudos will be created to
+ prevent LRA cycling in some complicated cases. */
+ lra_bad_spill_regno_start = lra_constraint_new_regno_start;
+ lra_assignment_iter_after_spill = 0;
+ }
+ ira_restore_scratches (lra_dump_file);
+ lra_eliminate (true, false);
+ lra_final_code_change ();
+ lra_in_progress = 0;
+ if (live_p)
+ lra_clear_live_ranges ();
+ lra_live_ranges_finish ();
+ lra_constraints_finish ();
+ finish_reg_info ();
+ sbitmap_free (lra_constraint_insn_stack_bitmap);
+ lra_constraint_insn_stack.release ();
+ finish_insn_recog_data ();
+ regstat_free_n_sets_and_refs ();
+ regstat_free_ri ();
+ reload_completed = 1;
+ update_inc_notes ();
+
+ inserted_p = fixup_abnormal_edges ();
+
+ /* We've possibly turned single trapping insn into multiple ones. */
+ if (cfun->can_throw_non_call_exceptions)
+ {
+ auto_sbitmap blocks (last_basic_block_for_fn (cfun));
+ bitmap_ones (blocks);
+ find_many_sub_basic_blocks (blocks);
+ }
+
+ if (inserted_p)
+ commit_edge_insertions ();
+
+ /* Replacing pseudos with their memory equivalents might have
+ created shared rtx. Subsequent passes would get confused
+ by this, so unshare everything here. */
+ unshare_all_rtl_again (get_insns ());
+
+ if (flag_checking)
+ check_rtl (true);
+
+ timevar_pop (TV_LRA);
+}
+
+/* Called once per compiler to initialize LRA data once. */
+void
+lra_init_once (void)
+{
+ init_insn_code_data_once ();
+}
+
+/* Called once per compiler to finish LRA data which are initialize
+ once. */
+void
+lra_finish_once (void)
+{
+ finish_insn_code_data_once ();
+}