diff options
author | Martin Liska <mliska@suse.cz> | 2022-01-14 16:56:44 +0100 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-01-17 22:12:04 +0100 |
commit | 5c69acb32329d49e58c26fa41ae74229a52b9106 (patch) | |
tree | ddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/sched-deps.c | |
parent | 490e23032baaece71f2ec09fa1805064b150fbc2 (diff) | |
download | gcc-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/sched-deps.c')
-rw-r--r-- | gcc/sched-deps.c | 4954 |
1 files changed, 0 insertions, 4954 deletions
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c deleted file mode 100644 index 5b717ce..0000000 --- a/gcc/sched-deps.c +++ /dev/null @@ -1,4954 +0,0 @@ -/* Instruction scheduling pass. This file computes dependencies between - instructions. - Copyright (C) 1992-2022 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by, - and currently maintained by, Jim Wilson (wilson@cygnus.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/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "backend.h" -#include "target.h" -#include "rtl.h" -#include "tree.h" -#include "df.h" -#include "insn-config.h" -#include "regs.h" -#include "memmodel.h" -#include "ira.h" -#include "ira-int.h" -#include "insn-attr.h" -#include "cfgbuild.h" -#include "sched-int.h" -#include "cselib.h" -#include "function-abi.h" - -#ifdef INSN_SCHEDULING - -/* Holds current parameters for the dependency analyzer. */ -struct sched_deps_info_def *sched_deps_info; - -/* The data is specific to the Haifa scheduler. */ -vec<haifa_deps_insn_data_def> - h_d_i_d = vNULL; - -/* Return the major type present in the DS. */ -enum reg_note -ds_to_dk (ds_t ds) -{ - if (ds & DEP_TRUE) - return REG_DEP_TRUE; - - if (ds & DEP_OUTPUT) - return REG_DEP_OUTPUT; - - if (ds & DEP_CONTROL) - return REG_DEP_CONTROL; - - gcc_assert (ds & DEP_ANTI); - - return REG_DEP_ANTI; -} - -/* Return equivalent dep_status. */ -ds_t -dk_to_ds (enum reg_note dk) -{ - switch (dk) - { - case REG_DEP_TRUE: - return DEP_TRUE; - - case REG_DEP_OUTPUT: - return DEP_OUTPUT; - - case REG_DEP_CONTROL: - return DEP_CONTROL; - - default: - gcc_assert (dk == REG_DEP_ANTI); - return DEP_ANTI; - } -} - -/* Functions to operate with dependence information container - dep_t. */ - -/* Init DEP with the arguments. */ -void -init_dep_1 (dep_t dep, rtx_insn *pro, rtx_insn *con, enum reg_note type, ds_t ds) -{ - DEP_PRO (dep) = pro; - DEP_CON (dep) = con; - DEP_TYPE (dep) = type; - DEP_STATUS (dep) = ds; - DEP_COST (dep) = UNKNOWN_DEP_COST; - DEP_NONREG (dep) = 0; - DEP_MULTIPLE (dep) = 0; - DEP_REPLACE (dep) = NULL; - dep->unused = 0; -} - -/* Init DEP with the arguments. - While most of the scheduler (including targets) only need the major type - of the dependency, it is convenient to hide full dep_status from them. */ -void -init_dep (dep_t dep, rtx_insn *pro, rtx_insn *con, enum reg_note kind) -{ - ds_t ds; - - if ((current_sched_info->flags & USE_DEPS_LIST)) - ds = dk_to_ds (kind); - else - ds = 0; - - init_dep_1 (dep, pro, con, kind, ds); -} - -/* Make a copy of FROM in TO. */ -static void -copy_dep (dep_t to, dep_t from) -{ - memcpy (to, from, sizeof (*to)); -} - -static void dump_ds (FILE *, ds_t); - -/* Define flags for dump_dep (). */ - -/* Dump producer of the dependence. */ -#define DUMP_DEP_PRO (2) - -/* Dump consumer of the dependence. */ -#define DUMP_DEP_CON (4) - -/* Dump type of the dependence. */ -#define DUMP_DEP_TYPE (8) - -/* Dump status of the dependence. */ -#define DUMP_DEP_STATUS (16) - -/* Dump all information about the dependence. */ -#define DUMP_DEP_ALL (DUMP_DEP_PRO | DUMP_DEP_CON | DUMP_DEP_TYPE \ - |DUMP_DEP_STATUS) - -/* Dump DEP to DUMP. - FLAGS is a bit mask specifying what information about DEP needs - to be printed. - If FLAGS has the very first bit set, then dump all information about DEP - and propagate this bit into the callee dump functions. */ -static void -dump_dep (FILE *dump, dep_t dep, int flags) -{ - if (flags & 1) - flags |= DUMP_DEP_ALL; - - fprintf (dump, "<"); - - if (flags & DUMP_DEP_PRO) - fprintf (dump, "%d; ", INSN_UID (DEP_PRO (dep))); - - if (flags & DUMP_DEP_CON) - fprintf (dump, "%d; ", INSN_UID (DEP_CON (dep))); - - if (flags & DUMP_DEP_TYPE) - { - char t; - enum reg_note type = DEP_TYPE (dep); - - switch (type) - { - case REG_DEP_TRUE: - t = 't'; - break; - - case REG_DEP_OUTPUT: - t = 'o'; - break; - - case REG_DEP_CONTROL: - t = 'c'; - break; - - case REG_DEP_ANTI: - t = 'a'; - break; - - default: - gcc_unreachable (); - break; - } - - fprintf (dump, "%c; ", t); - } - - if (flags & DUMP_DEP_STATUS) - { - if (current_sched_info->flags & USE_DEPS_LIST) - dump_ds (dump, DEP_STATUS (dep)); - } - - fprintf (dump, ">"); -} - -/* Default flags for dump_dep (). */ -static int dump_dep_flags = (DUMP_DEP_PRO | DUMP_DEP_CON); - -/* Dump all fields of DEP to STDERR. */ -void -sd_debug_dep (dep_t dep) -{ - dump_dep (stderr, dep, 1); - fprintf (stderr, "\n"); -} - -/* Determine whether DEP is a dependency link of a non-debug insn on a - debug insn. */ - -static inline bool -depl_on_debug_p (dep_link_t dep) -{ - return (DEBUG_INSN_P (DEP_LINK_PRO (dep)) - && !DEBUG_INSN_P (DEP_LINK_CON (dep))); -} - -/* Functions to operate with a single link from the dependencies lists - - dep_link_t. */ - -/* Attach L to appear after link X whose &DEP_LINK_NEXT (X) is given by - PREV_NEXT_P. */ -static void -attach_dep_link (dep_link_t l, dep_link_t *prev_nextp) -{ - dep_link_t next = *prev_nextp; - - gcc_assert (DEP_LINK_PREV_NEXTP (l) == NULL - && DEP_LINK_NEXT (l) == NULL); - - /* Init node being inserted. */ - DEP_LINK_PREV_NEXTP (l) = prev_nextp; - DEP_LINK_NEXT (l) = next; - - /* Fix next node. */ - if (next != NULL) - { - gcc_assert (DEP_LINK_PREV_NEXTP (next) == prev_nextp); - - DEP_LINK_PREV_NEXTP (next) = &DEP_LINK_NEXT (l); - } - - /* Fix prev node. */ - *prev_nextp = l; -} - -/* Add dep_link LINK to deps_list L. */ -static void -add_to_deps_list (dep_link_t link, deps_list_t l) -{ - attach_dep_link (link, &DEPS_LIST_FIRST (l)); - - /* Don't count debug deps. */ - if (!depl_on_debug_p (link)) - ++DEPS_LIST_N_LINKS (l); -} - -/* Detach dep_link L from the list. */ -static void -detach_dep_link (dep_link_t l) -{ - dep_link_t *prev_nextp = DEP_LINK_PREV_NEXTP (l); - dep_link_t next = DEP_LINK_NEXT (l); - - *prev_nextp = next; - - if (next != NULL) - DEP_LINK_PREV_NEXTP (next) = prev_nextp; - - DEP_LINK_PREV_NEXTP (l) = NULL; - DEP_LINK_NEXT (l) = NULL; -} - -/* Remove link LINK from list LIST. */ -static void -remove_from_deps_list (dep_link_t link, deps_list_t list) -{ - detach_dep_link (link); - - /* Don't count debug deps. */ - if (!depl_on_debug_p (link)) - --DEPS_LIST_N_LINKS (list); -} - -/* Move link LINK from list FROM to list TO. */ -static void -move_dep_link (dep_link_t link, deps_list_t from, deps_list_t to) -{ - remove_from_deps_list (link, from); - add_to_deps_list (link, to); -} - -/* Return true of LINK is not attached to any list. */ -static bool -dep_link_is_detached_p (dep_link_t link) -{ - return DEP_LINK_PREV_NEXTP (link) == NULL; -} - -/* Pool to hold all dependency nodes (dep_node_t). */ -static object_allocator<_dep_node> *dn_pool; - -/* Number of dep_nodes out there. */ -static int dn_pool_diff = 0; - -/* Create a dep_node. */ -static dep_node_t -create_dep_node (void) -{ - dep_node_t n = dn_pool->allocate (); - dep_link_t back = DEP_NODE_BACK (n); - dep_link_t forw = DEP_NODE_FORW (n); - - DEP_LINK_NODE (back) = n; - DEP_LINK_NEXT (back) = NULL; - DEP_LINK_PREV_NEXTP (back) = NULL; - - DEP_LINK_NODE (forw) = n; - DEP_LINK_NEXT (forw) = NULL; - DEP_LINK_PREV_NEXTP (forw) = NULL; - - ++dn_pool_diff; - - return n; -} - -/* Delete dep_node N. N must not be connected to any deps_list. */ -static void -delete_dep_node (dep_node_t n) -{ - gcc_assert (dep_link_is_detached_p (DEP_NODE_BACK (n)) - && dep_link_is_detached_p (DEP_NODE_FORW (n))); - - XDELETE (DEP_REPLACE (DEP_NODE_DEP (n))); - - --dn_pool_diff; - - dn_pool->remove (n); -} - -/* Pool to hold dependencies lists (deps_list_t). */ -static object_allocator<_deps_list> *dl_pool; - -/* Number of deps_lists out there. */ -static int dl_pool_diff = 0; - -/* Functions to operate with dependences lists - deps_list_t. */ - -/* Return true if list L is empty. */ -static bool -deps_list_empty_p (deps_list_t l) -{ - return DEPS_LIST_N_LINKS (l) == 0; -} - -/* Create a new deps_list. */ -static deps_list_t -create_deps_list (void) -{ - deps_list_t l = dl_pool->allocate (); - - DEPS_LIST_FIRST (l) = NULL; - DEPS_LIST_N_LINKS (l) = 0; - - ++dl_pool_diff; - return l; -} - -/* Free deps_list L. */ -static void -free_deps_list (deps_list_t l) -{ - gcc_assert (deps_list_empty_p (l)); - - --dl_pool_diff; - - dl_pool->remove (l); -} - -/* Return true if there is no dep_nodes and deps_lists out there. - After the region is scheduled all the dependency nodes and lists - should [generally] be returned to pool. */ -bool -deps_pools_are_empty_p (void) -{ - return dn_pool_diff == 0 && dl_pool_diff == 0; -} - -/* Remove all elements from L. */ -static void -clear_deps_list (deps_list_t l) -{ - do - { - dep_link_t link = DEPS_LIST_FIRST (l); - - if (link == NULL) - break; - - remove_from_deps_list (link, l); - } - while (1); -} - -/* Decide whether a dependency should be treated as a hard or a speculative - dependency. */ -static bool -dep_spec_p (dep_t dep) -{ - if (current_sched_info->flags & DO_SPECULATION) - { - if (DEP_STATUS (dep) & SPECULATIVE) - return true; - } - if (current_sched_info->flags & DO_PREDICATION) - { - if (DEP_TYPE (dep) == REG_DEP_CONTROL) - return true; - } - if (DEP_REPLACE (dep) != NULL) - return true; - return false; -} - -static regset reg_pending_sets; -static regset reg_pending_clobbers; -static regset reg_pending_uses; -static regset reg_pending_control_uses; -static enum reg_pending_barrier_mode reg_pending_barrier; - -/* Hard registers implicitly clobbered or used (or may be implicitly - clobbered or used) by the currently analyzed insn. For example, - insn in its constraint has one register class. Even if there is - currently no hard register in the insn, the particular hard - register will be in the insn after reload pass because the - constraint requires it. */ -static HARD_REG_SET implicit_reg_pending_clobbers; -static HARD_REG_SET implicit_reg_pending_uses; - -/* To speed up the test for duplicate dependency links we keep a - record of dependencies created by add_dependence when the average - number of instructions in a basic block is very large. - - Studies have shown that there is typically around 5 instructions between - branches for typical C code. So we can make a guess that the average - basic block is approximately 5 instructions long; we will choose 100X - the average size as a very large basic block. - - Each insn has associated bitmaps for its dependencies. Each bitmap - has enough entries to represent a dependency on any other insn in - the insn chain. All bitmap for true dependencies cache is - allocated then the rest two ones are also allocated. */ -static bitmap true_dependency_cache = NULL; -static bitmap output_dependency_cache = NULL; -static bitmap anti_dependency_cache = NULL; -static bitmap control_dependency_cache = NULL; -static bitmap spec_dependency_cache = NULL; -static int cache_size; - -/* True if we should mark added dependencies as a non-register deps. */ -static bool mark_as_hard; - -static int deps_may_trap_p (const_rtx); -static void add_dependence_1 (rtx_insn *, rtx_insn *, enum reg_note); -static void add_dependence_list (rtx_insn *, rtx_insn_list *, int, - enum reg_note, bool); -static void add_dependence_list_and_free (class deps_desc *, rtx_insn *, - rtx_insn_list **, int, enum reg_note, - bool); -static void delete_all_dependences (rtx_insn *); -static void chain_to_prev_insn (rtx_insn *); - -static void flush_pending_lists (class deps_desc *, rtx_insn *, int, int); -static void sched_analyze_1 (class deps_desc *, rtx, rtx_insn *); -static void sched_analyze_2 (class deps_desc *, rtx, rtx_insn *); -static void sched_analyze_insn (class deps_desc *, rtx, rtx_insn *); - -static bool sched_has_condition_p (const rtx_insn *); -static int conditions_mutex_p (const_rtx, const_rtx, bool, bool); - -static enum DEPS_ADJUST_RESULT maybe_add_or_update_dep_1 (dep_t, bool, - rtx, rtx); -static enum DEPS_ADJUST_RESULT add_or_update_dep_1 (dep_t, bool, rtx, rtx); - -static void check_dep (dep_t, bool); - - -/* Return nonzero if a load of the memory reference MEM can cause a trap. */ - -static int -deps_may_trap_p (const_rtx mem) -{ - const_rtx addr = XEXP (mem, 0); - - if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER) - { - const_rtx t = get_reg_known_value (REGNO (addr)); - if (t) - addr = t; - } - return rtx_addr_can_trap_p (addr); -} - - -/* Find the condition under which INSN is executed. If REV is not NULL, - it is set to TRUE when the returned comparison should be reversed - to get the actual condition. */ -static rtx -sched_get_condition_with_rev_uncached (const rtx_insn *insn, bool *rev) -{ - rtx pat = PATTERN (insn); - rtx src; - - if (rev) - *rev = false; - - if (GET_CODE (pat) == COND_EXEC) - return COND_EXEC_TEST (pat); - - if (!any_condjump_p (insn) || !onlyjump_p (insn)) - return 0; - - src = SET_SRC (pc_set (insn)); - - if (XEXP (src, 2) == pc_rtx) - return XEXP (src, 0); - else if (XEXP (src, 1) == pc_rtx) - { - rtx cond = XEXP (src, 0); - enum rtx_code revcode = reversed_comparison_code (cond, insn); - - if (revcode == UNKNOWN) - return 0; - - if (rev) - *rev = true; - return cond; - } - - return 0; -} - -/* Return the condition under which INSN does not execute (i.e. the - not-taken condition for a conditional branch), or NULL if we cannot - find such a condition. The caller should make a copy of the condition - before using it. */ -rtx -sched_get_reverse_condition_uncached (const rtx_insn *insn) -{ - bool rev; - rtx cond = sched_get_condition_with_rev_uncached (insn, &rev); - if (cond == NULL_RTX) - return cond; - if (!rev) - { - enum rtx_code revcode = reversed_comparison_code (cond, insn); - cond = gen_rtx_fmt_ee (revcode, GET_MODE (cond), - XEXP (cond, 0), - XEXP (cond, 1)); - } - return cond; -} - -/* Caching variant of sched_get_condition_with_rev_uncached. - We only do actual work the first time we come here for an insn; the - results are cached in INSN_CACHED_COND and INSN_REVERSE_COND. */ -static rtx -sched_get_condition_with_rev (const rtx_insn *insn, bool *rev) -{ - bool tmp; - - if (INSN_LUID (insn) == 0) - return sched_get_condition_with_rev_uncached (insn, rev); - - if (INSN_CACHED_COND (insn) == const_true_rtx) - return NULL_RTX; - - if (INSN_CACHED_COND (insn) != NULL_RTX) - { - if (rev) - *rev = INSN_REVERSE_COND (insn); - return INSN_CACHED_COND (insn); - } - - INSN_CACHED_COND (insn) = sched_get_condition_with_rev_uncached (insn, &tmp); - INSN_REVERSE_COND (insn) = tmp; - - if (INSN_CACHED_COND (insn) == NULL_RTX) - { - INSN_CACHED_COND (insn) = const_true_rtx; - return NULL_RTX; - } - - if (rev) - *rev = INSN_REVERSE_COND (insn); - return INSN_CACHED_COND (insn); -} - -/* True when we can find a condition under which INSN is executed. */ -static bool -sched_has_condition_p (const rtx_insn *insn) -{ - return !! sched_get_condition_with_rev (insn, NULL); -} - - - -/* Return nonzero if conditions COND1 and COND2 can never be both true. */ -static int -conditions_mutex_p (const_rtx cond1, const_rtx cond2, bool rev1, bool rev2) -{ - if (COMPARISON_P (cond1) - && COMPARISON_P (cond2) - && GET_CODE (cond1) == - (rev1==rev2 - ? reversed_comparison_code (cond2, NULL) - : GET_CODE (cond2)) - && rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0)) - && XEXP (cond1, 1) == XEXP (cond2, 1)) - return 1; - return 0; -} - -/* Return true if insn1 and insn2 can never depend on one another because - the conditions under which they are executed are mutually exclusive. */ -bool -sched_insns_conditions_mutex_p (const rtx_insn *insn1, const rtx_insn *insn2) -{ - rtx cond1, cond2; - bool rev1 = false, rev2 = false; - - /* df doesn't handle conditional lifetimes entirely correctly; - calls mess up the conditional lifetimes. */ - if (!CALL_P (insn1) && !CALL_P (insn2)) - { - cond1 = sched_get_condition_with_rev (insn1, &rev1); - cond2 = sched_get_condition_with_rev (insn2, &rev2); - if (cond1 && cond2 - && conditions_mutex_p (cond1, cond2, rev1, rev2) - /* Make sure first instruction doesn't affect condition of second - instruction if switched. */ - && !modified_in_p (cond1, insn2) - /* Make sure second instruction doesn't affect condition of first - instruction if switched. */ - && !modified_in_p (cond2, insn1)) - return true; - } - return false; -} - - -/* Return true if INSN can potentially be speculated with type DS. */ -bool -sched_insn_is_legitimate_for_speculation_p (const rtx_insn *insn, ds_t ds) -{ - if (HAS_INTERNAL_DEP (insn)) - return false; - - if (!NONJUMP_INSN_P (insn)) - return false; - - if (SCHED_GROUP_P (insn)) - return false; - - if (IS_SPECULATION_CHECK_P (CONST_CAST_RTX_INSN (insn))) - return false; - - if (side_effects_p (PATTERN (insn))) - return false; - - if (ds & BE_IN_SPEC) - /* The following instructions, which depend on a speculatively scheduled - instruction, cannot be speculatively scheduled along. */ - { - if (may_trap_or_fault_p (PATTERN (insn))) - /* If instruction might fault, it cannot be speculatively scheduled. - For control speculation it's obvious why and for data speculation - it's because the insn might get wrong input if speculation - wasn't successful. */ - return false; - - if ((ds & BE_IN_DATA) - && sched_has_condition_p (insn)) - /* If this is a predicated instruction, then it cannot be - speculatively scheduled. See PR35659. */ - return false; - } - - return true; -} - -/* Initialize LIST_PTR to point to one of the lists present in TYPES_PTR, - initialize RESOLVED_P_PTR with true if that list consists of resolved deps, - and remove the type of returned [through LIST_PTR] list from TYPES_PTR. - This function is used to switch sd_iterator to the next list. - !!! For internal use only. Might consider moving it to sched-int.h. */ -void -sd_next_list (const_rtx insn, sd_list_types_def *types_ptr, - deps_list_t *list_ptr, bool *resolved_p_ptr) -{ - sd_list_types_def types = *types_ptr; - - if (types & SD_LIST_HARD_BACK) - { - *list_ptr = INSN_HARD_BACK_DEPS (insn); - *resolved_p_ptr = false; - *types_ptr = types & ~SD_LIST_HARD_BACK; - } - else if (types & SD_LIST_SPEC_BACK) - { - *list_ptr = INSN_SPEC_BACK_DEPS (insn); - *resolved_p_ptr = false; - *types_ptr = types & ~SD_LIST_SPEC_BACK; - } - else if (types & SD_LIST_FORW) - { - *list_ptr = INSN_FORW_DEPS (insn); - *resolved_p_ptr = false; - *types_ptr = types & ~SD_LIST_FORW; - } - else if (types & SD_LIST_RES_BACK) - { - *list_ptr = INSN_RESOLVED_BACK_DEPS (insn); - *resolved_p_ptr = true; - *types_ptr = types & ~SD_LIST_RES_BACK; - } - else if (types & SD_LIST_RES_FORW) - { - *list_ptr = INSN_RESOLVED_FORW_DEPS (insn); - *resolved_p_ptr = true; - *types_ptr = types & ~SD_LIST_RES_FORW; - } - else - { - *list_ptr = NULL; - *resolved_p_ptr = false; - *types_ptr = SD_LIST_NONE; - } -} - -/* Return the summary size of INSN's lists defined by LIST_TYPES. */ -int -sd_lists_size (const_rtx insn, sd_list_types_def list_types) -{ - int size = 0; - - while (list_types != SD_LIST_NONE) - { - deps_list_t list; - bool resolved_p; - - sd_next_list (insn, &list_types, &list, &resolved_p); - if (list) - size += DEPS_LIST_N_LINKS (list); - } - - return size; -} - -/* Return true if INSN's lists defined by LIST_TYPES are all empty. */ - -bool -sd_lists_empty_p (const_rtx insn, sd_list_types_def list_types) -{ - while (list_types != SD_LIST_NONE) - { - deps_list_t list; - bool resolved_p; - - sd_next_list (insn, &list_types, &list, &resolved_p); - if (!deps_list_empty_p (list)) - return false; - } - - return true; -} - -/* Initialize data for INSN. */ -void -sd_init_insn (rtx_insn *insn) -{ - INSN_HARD_BACK_DEPS (insn) = create_deps_list (); - INSN_SPEC_BACK_DEPS (insn) = create_deps_list (); - INSN_RESOLVED_BACK_DEPS (insn) = create_deps_list (); - INSN_FORW_DEPS (insn) = create_deps_list (); - INSN_RESOLVED_FORW_DEPS (insn) = create_deps_list (); - - /* ??? It would be nice to allocate dependency caches here. */ -} - -/* Free data for INSN. */ -void -sd_finish_insn (rtx_insn *insn) -{ - /* ??? It would be nice to deallocate dependency caches here. */ - - free_deps_list (INSN_HARD_BACK_DEPS (insn)); - INSN_HARD_BACK_DEPS (insn) = NULL; - - free_deps_list (INSN_SPEC_BACK_DEPS (insn)); - INSN_SPEC_BACK_DEPS (insn) = NULL; - - free_deps_list (INSN_RESOLVED_BACK_DEPS (insn)); - INSN_RESOLVED_BACK_DEPS (insn) = NULL; - - free_deps_list (INSN_FORW_DEPS (insn)); - INSN_FORW_DEPS (insn) = NULL; - - free_deps_list (INSN_RESOLVED_FORW_DEPS (insn)); - INSN_RESOLVED_FORW_DEPS (insn) = NULL; -} - -/* Find a dependency between producer PRO and consumer CON. - Search through resolved dependency lists if RESOLVED_P is true. - If no such dependency is found return NULL, - otherwise return the dependency and initialize SD_IT_PTR [if it is nonnull] - with an iterator pointing to it. */ -static dep_t -sd_find_dep_between_no_cache (rtx pro, rtx con, bool resolved_p, - sd_iterator_def *sd_it_ptr) -{ - sd_list_types_def pro_list_type; - sd_list_types_def con_list_type; - sd_iterator_def sd_it; - dep_t dep; - bool found_p = false; - - if (resolved_p) - { - pro_list_type = SD_LIST_RES_FORW; - con_list_type = SD_LIST_RES_BACK; - } - else - { - pro_list_type = SD_LIST_FORW; - con_list_type = SD_LIST_BACK; - } - - /* Walk through either back list of INSN or forw list of ELEM - depending on which one is shorter. */ - if (sd_lists_size (con, con_list_type) < sd_lists_size (pro, pro_list_type)) - { - /* Find the dep_link with producer PRO in consumer's back_deps. */ - FOR_EACH_DEP (con, con_list_type, sd_it, dep) - if (DEP_PRO (dep) == pro) - { - found_p = true; - break; - } - } - else - { - /* Find the dep_link with consumer CON in producer's forw_deps. */ - FOR_EACH_DEP (pro, pro_list_type, sd_it, dep) - if (DEP_CON (dep) == con) - { - found_p = true; - break; - } - } - - if (found_p) - { - if (sd_it_ptr != NULL) - *sd_it_ptr = sd_it; - - return dep; - } - - return NULL; -} - -/* Find a dependency between producer PRO and consumer CON. - Use dependency [if available] to check if dependency is present at all. - Search through resolved dependency lists if RESOLVED_P is true. - If the dependency or NULL if none found. */ -dep_t -sd_find_dep_between (rtx pro, rtx con, bool resolved_p) -{ - if (true_dependency_cache != NULL) - /* Avoiding the list walk below can cut compile times dramatically - for some code. */ - { - int elem_luid = INSN_LUID (pro); - int insn_luid = INSN_LUID (con); - - if (!bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid) - && !bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid) - && !bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid) - && !bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid)) - return NULL; - } - - return sd_find_dep_between_no_cache (pro, con, resolved_p, NULL); -} - -/* Add or update a dependence described by DEP. - MEM1 and MEM2, if non-null, correspond to memory locations in case of - data speculation. - - The function returns a value indicating if an old entry has been changed - or a new entry has been added to insn's backward deps. - - This function merely checks if producer and consumer is the same insn - and doesn't create a dep in this case. Actual manipulation of - dependence data structures is performed in add_or_update_dep_1. */ -static enum DEPS_ADJUST_RESULT -maybe_add_or_update_dep_1 (dep_t dep, bool resolved_p, rtx mem1, rtx mem2) -{ - rtx_insn *elem = DEP_PRO (dep); - rtx_insn *insn = DEP_CON (dep); - - gcc_assert (INSN_P (insn) && INSN_P (elem)); - - /* Don't depend an insn on itself. */ - if (insn == elem) - { - if (sched_deps_info->generate_spec_deps) - /* INSN has an internal dependence, which we can't overcome. */ - HAS_INTERNAL_DEP (insn) = 1; - - return DEP_NODEP; - } - - return add_or_update_dep_1 (dep, resolved_p, mem1, mem2); -} - -/* Ask dependency caches what needs to be done for dependence DEP. - Return DEP_CREATED if new dependence should be created and there is no - need to try to find one searching the dependencies lists. - Return DEP_PRESENT if there already is a dependence described by DEP and - hence nothing is to be done. - Return DEP_CHANGED if there already is a dependence, but it should be - updated to incorporate additional information from DEP. */ -static enum DEPS_ADJUST_RESULT -ask_dependency_caches (dep_t dep) -{ - int elem_luid = INSN_LUID (DEP_PRO (dep)); - int insn_luid = INSN_LUID (DEP_CON (dep)); - - gcc_assert (true_dependency_cache != NULL - && output_dependency_cache != NULL - && anti_dependency_cache != NULL - && control_dependency_cache != NULL); - - if (!(current_sched_info->flags & USE_DEPS_LIST)) - { - enum reg_note present_dep_type; - - if (bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid)) - present_dep_type = REG_DEP_TRUE; - else if (bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid)) - present_dep_type = REG_DEP_OUTPUT; - else if (bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid)) - present_dep_type = REG_DEP_ANTI; - else if (bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid)) - present_dep_type = REG_DEP_CONTROL; - else - /* There is no existing dep so it should be created. */ - return DEP_CREATED; - - if ((int) DEP_TYPE (dep) >= (int) present_dep_type) - /* DEP does not add anything to the existing dependence. */ - return DEP_PRESENT; - } - else - { - ds_t present_dep_types = 0; - - if (bitmap_bit_p (&true_dependency_cache[insn_luid], elem_luid)) - present_dep_types |= DEP_TRUE; - if (bitmap_bit_p (&output_dependency_cache[insn_luid], elem_luid)) - present_dep_types |= DEP_OUTPUT; - if (bitmap_bit_p (&anti_dependency_cache[insn_luid], elem_luid)) - present_dep_types |= DEP_ANTI; - if (bitmap_bit_p (&control_dependency_cache[insn_luid], elem_luid)) - present_dep_types |= DEP_CONTROL; - - if (present_dep_types == 0) - /* There is no existing dep so it should be created. */ - return DEP_CREATED; - - if (!(current_sched_info->flags & DO_SPECULATION) - || !bitmap_bit_p (&spec_dependency_cache[insn_luid], elem_luid)) - { - if ((present_dep_types | (DEP_STATUS (dep) & DEP_TYPES)) - == present_dep_types) - /* DEP does not add anything to the existing dependence. */ - return DEP_PRESENT; - } - else - { - /* Only true dependencies can be data speculative and - only anti dependencies can be control speculative. */ - gcc_assert ((present_dep_types & (DEP_TRUE | DEP_ANTI)) - == present_dep_types); - - /* if (DEP is SPECULATIVE) then - ..we should update DEP_STATUS - else - ..we should reset existing dep to non-speculative. */ - } - } - - return DEP_CHANGED; -} - -/* Set dependency caches according to DEP. */ -static void -set_dependency_caches (dep_t dep) -{ - int elem_luid = INSN_LUID (DEP_PRO (dep)); - int insn_luid = INSN_LUID (DEP_CON (dep)); - - if (!(current_sched_info->flags & USE_DEPS_LIST)) - { - switch (DEP_TYPE (dep)) - { - case REG_DEP_TRUE: - bitmap_set_bit (&true_dependency_cache[insn_luid], elem_luid); - break; - - case REG_DEP_OUTPUT: - bitmap_set_bit (&output_dependency_cache[insn_luid], elem_luid); - break; - - case REG_DEP_ANTI: - bitmap_set_bit (&anti_dependency_cache[insn_luid], elem_luid); - break; - - case REG_DEP_CONTROL: - bitmap_set_bit (&control_dependency_cache[insn_luid], elem_luid); - break; - - default: - gcc_unreachable (); - } - } - else - { - ds_t ds = DEP_STATUS (dep); - - if (ds & DEP_TRUE) - bitmap_set_bit (&true_dependency_cache[insn_luid], elem_luid); - if (ds & DEP_OUTPUT) - bitmap_set_bit (&output_dependency_cache[insn_luid], elem_luid); - if (ds & DEP_ANTI) - bitmap_set_bit (&anti_dependency_cache[insn_luid], elem_luid); - if (ds & DEP_CONTROL) - bitmap_set_bit (&control_dependency_cache[insn_luid], elem_luid); - - if (ds & SPECULATIVE) - { - gcc_assert (current_sched_info->flags & DO_SPECULATION); - bitmap_set_bit (&spec_dependency_cache[insn_luid], elem_luid); - } - } -} - -/* Type of dependence DEP have changed from OLD_TYPE. Update dependency - caches accordingly. */ -static void -update_dependency_caches (dep_t dep, enum reg_note old_type) -{ - int elem_luid = INSN_LUID (DEP_PRO (dep)); - int insn_luid = INSN_LUID (DEP_CON (dep)); - - /* Clear corresponding cache entry because type of the link - may have changed. Keep them if we use_deps_list. */ - if (!(current_sched_info->flags & USE_DEPS_LIST)) - { - switch (old_type) - { - case REG_DEP_OUTPUT: - bitmap_clear_bit (&output_dependency_cache[insn_luid], elem_luid); - break; - - case REG_DEP_ANTI: - bitmap_clear_bit (&anti_dependency_cache[insn_luid], elem_luid); - break; - - case REG_DEP_CONTROL: - bitmap_clear_bit (&control_dependency_cache[insn_luid], elem_luid); - break; - - default: - gcc_unreachable (); - } - } - - set_dependency_caches (dep); -} - -/* Convert a dependence pointed to by SD_IT to be non-speculative. */ -static void -change_spec_dep_to_hard (sd_iterator_def sd_it) -{ - dep_node_t node = DEP_LINK_NODE (*sd_it.linkp); - dep_link_t link = DEP_NODE_BACK (node); - dep_t dep = DEP_NODE_DEP (node); - rtx_insn *elem = DEP_PRO (dep); - rtx_insn *insn = DEP_CON (dep); - - move_dep_link (link, INSN_SPEC_BACK_DEPS (insn), INSN_HARD_BACK_DEPS (insn)); - - DEP_STATUS (dep) &= ~SPECULATIVE; - - if (true_dependency_cache != NULL) - /* Clear the cache entry. */ - bitmap_clear_bit (&spec_dependency_cache[INSN_LUID (insn)], - INSN_LUID (elem)); -} - -/* Update DEP to incorporate information from NEW_DEP. - SD_IT points to DEP in case it should be moved to another list. - MEM1 and MEM2, if nonnull, correspond to memory locations in case if - data-speculative dependence should be updated. */ -static enum DEPS_ADJUST_RESULT -update_dep (dep_t dep, dep_t new_dep, - sd_iterator_def sd_it ATTRIBUTE_UNUSED, - rtx mem1 ATTRIBUTE_UNUSED, - rtx mem2 ATTRIBUTE_UNUSED) -{ - enum DEPS_ADJUST_RESULT res = DEP_PRESENT; - enum reg_note old_type = DEP_TYPE (dep); - bool was_spec = dep_spec_p (dep); - - DEP_NONREG (dep) |= DEP_NONREG (new_dep); - DEP_MULTIPLE (dep) = 1; - - /* If this is a more restrictive type of dependence than the - existing one, then change the existing dependence to this - type. */ - if ((int) DEP_TYPE (new_dep) < (int) old_type) - { - DEP_TYPE (dep) = DEP_TYPE (new_dep); - res = DEP_CHANGED; - } - - if (current_sched_info->flags & USE_DEPS_LIST) - /* Update DEP_STATUS. */ - { - ds_t dep_status = DEP_STATUS (dep); - ds_t ds = DEP_STATUS (new_dep); - ds_t new_status = ds | dep_status; - - if (new_status & SPECULATIVE) - { - /* Either existing dep or a dep we're adding or both are - speculative. */ - if (!(ds & SPECULATIVE) - || !(dep_status & SPECULATIVE)) - /* The new dep can't be speculative. */ - new_status &= ~SPECULATIVE; - else - { - /* Both are speculative. Merge probabilities. */ - if (mem1 != NULL) - { - dw_t dw; - - dw = estimate_dep_weak (mem1, mem2); - ds = set_dep_weak (ds, BEGIN_DATA, dw); - } - - new_status = ds_merge (dep_status, ds); - } - } - - ds = new_status; - - if (dep_status != ds) - { - DEP_STATUS (dep) = ds; - res = DEP_CHANGED; - } - } - - if (was_spec && !dep_spec_p (dep)) - /* The old dep was speculative, but now it isn't. */ - change_spec_dep_to_hard (sd_it); - - if (true_dependency_cache != NULL - && res == DEP_CHANGED) - update_dependency_caches (dep, old_type); - - return res; -} - -/* Add or update a dependence described by DEP. - MEM1 and MEM2, if non-null, correspond to memory locations in case of - data speculation. - - The function returns a value indicating if an old entry has been changed - or a new entry has been added to insn's backward deps or nothing has - been updated at all. */ -static enum DEPS_ADJUST_RESULT -add_or_update_dep_1 (dep_t new_dep, bool resolved_p, - rtx mem1 ATTRIBUTE_UNUSED, rtx mem2 ATTRIBUTE_UNUSED) -{ - bool maybe_present_p = true; - bool present_p = false; - - gcc_assert (INSN_P (DEP_PRO (new_dep)) && INSN_P (DEP_CON (new_dep)) - && DEP_PRO (new_dep) != DEP_CON (new_dep)); - - if (flag_checking) - check_dep (new_dep, mem1 != NULL); - - if (true_dependency_cache != NULL) - { - switch (ask_dependency_caches (new_dep)) - { - case DEP_PRESENT: - dep_t present_dep; - sd_iterator_def sd_it; - - present_dep = sd_find_dep_between_no_cache (DEP_PRO (new_dep), - DEP_CON (new_dep), - resolved_p, &sd_it); - DEP_MULTIPLE (present_dep) = 1; - return DEP_PRESENT; - - case DEP_CHANGED: - maybe_present_p = true; - present_p = true; - break; - - case DEP_CREATED: - maybe_present_p = false; - present_p = false; - break; - - default: - gcc_unreachable (); - break; - } - } - - /* Check that we don't already have this dependence. */ - if (maybe_present_p) - { - dep_t present_dep; - sd_iterator_def sd_it; - - gcc_assert (true_dependency_cache == NULL || present_p); - - present_dep = sd_find_dep_between_no_cache (DEP_PRO (new_dep), - DEP_CON (new_dep), - resolved_p, &sd_it); - - if (present_dep != NULL) - /* We found an existing dependency between ELEM and INSN. */ - return update_dep (present_dep, new_dep, sd_it, mem1, mem2); - else - /* We didn't find a dep, it shouldn't present in the cache. */ - gcc_assert (!present_p); - } - - /* Might want to check one level of transitivity to save conses. - This check should be done in maybe_add_or_update_dep_1. - Since we made it to add_or_update_dep_1, we must create - (or update) a link. */ - - if (mem1 != NULL_RTX) - { - gcc_assert (sched_deps_info->generate_spec_deps); - DEP_STATUS (new_dep) = set_dep_weak (DEP_STATUS (new_dep), BEGIN_DATA, - estimate_dep_weak (mem1, mem2)); - } - - sd_add_dep (new_dep, resolved_p); - - return DEP_CREATED; -} - -/* Initialize BACK_LIST_PTR with consumer's backward list and - FORW_LIST_PTR with producer's forward list. If RESOLVED_P is true - initialize with lists that hold resolved deps. */ -static void -get_back_and_forw_lists (dep_t dep, bool resolved_p, - deps_list_t *back_list_ptr, - deps_list_t *forw_list_ptr) -{ - rtx_insn *con = DEP_CON (dep); - - if (!resolved_p) - { - if (dep_spec_p (dep)) - *back_list_ptr = INSN_SPEC_BACK_DEPS (con); - else - *back_list_ptr = INSN_HARD_BACK_DEPS (con); - - *forw_list_ptr = INSN_FORW_DEPS (DEP_PRO (dep)); - } - else - { - *back_list_ptr = INSN_RESOLVED_BACK_DEPS (con); - *forw_list_ptr = INSN_RESOLVED_FORW_DEPS (DEP_PRO (dep)); - } -} - -/* Add dependence described by DEP. - If RESOLVED_P is true treat the dependence as a resolved one. */ -void -sd_add_dep (dep_t dep, bool resolved_p) -{ - dep_node_t n = create_dep_node (); - deps_list_t con_back_deps; - deps_list_t pro_forw_deps; - rtx_insn *elem = DEP_PRO (dep); - rtx_insn *insn = DEP_CON (dep); - - gcc_assert (INSN_P (insn) && INSN_P (elem) && insn != elem); - - if ((current_sched_info->flags & DO_SPECULATION) == 0 - || !sched_insn_is_legitimate_for_speculation_p (insn, DEP_STATUS (dep))) - DEP_STATUS (dep) &= ~SPECULATIVE; - - copy_dep (DEP_NODE_DEP (n), dep); - - get_back_and_forw_lists (dep, resolved_p, &con_back_deps, &pro_forw_deps); - - add_to_deps_list (DEP_NODE_BACK (n), con_back_deps); - - if (flag_checking) - check_dep (dep, false); - - add_to_deps_list (DEP_NODE_FORW (n), pro_forw_deps); - - /* If we are adding a dependency to INSN's LOG_LINKs, then note that - in the bitmap caches of dependency information. */ - if (true_dependency_cache != NULL) - set_dependency_caches (dep); -} - -/* Add or update backward dependence between INSN and ELEM - with given type DEP_TYPE and dep_status DS. - This function is a convenience wrapper. */ -enum DEPS_ADJUST_RESULT -sd_add_or_update_dep (dep_t dep, bool resolved_p) -{ - return add_or_update_dep_1 (dep, resolved_p, NULL_RTX, NULL_RTX); -} - -/* Resolved dependence pointed to by SD_IT. - SD_IT will advance to the next element. */ -void -sd_resolve_dep (sd_iterator_def sd_it) -{ - dep_node_t node = DEP_LINK_NODE (*sd_it.linkp); - dep_t dep = DEP_NODE_DEP (node); - rtx_insn *pro = DEP_PRO (dep); - rtx_insn *con = DEP_CON (dep); - - if (dep_spec_p (dep)) - move_dep_link (DEP_NODE_BACK (node), INSN_SPEC_BACK_DEPS (con), - INSN_RESOLVED_BACK_DEPS (con)); - else - move_dep_link (DEP_NODE_BACK (node), INSN_HARD_BACK_DEPS (con), - INSN_RESOLVED_BACK_DEPS (con)); - - move_dep_link (DEP_NODE_FORW (node), INSN_FORW_DEPS (pro), - INSN_RESOLVED_FORW_DEPS (pro)); -} - -/* Perform the inverse operation of sd_resolve_dep. Restore the dependence - pointed to by SD_IT to unresolved state. */ -void -sd_unresolve_dep (sd_iterator_def sd_it) -{ - dep_node_t node = DEP_LINK_NODE (*sd_it.linkp); - dep_t dep = DEP_NODE_DEP (node); - rtx_insn *pro = DEP_PRO (dep); - rtx_insn *con = DEP_CON (dep); - - if (dep_spec_p (dep)) - move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con), - INSN_SPEC_BACK_DEPS (con)); - else - move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con), - INSN_HARD_BACK_DEPS (con)); - - move_dep_link (DEP_NODE_FORW (node), INSN_RESOLVED_FORW_DEPS (pro), - INSN_FORW_DEPS (pro)); -} - -/* Make TO depend on all the FROM's producers. - If RESOLVED_P is true add dependencies to the resolved lists. */ -void -sd_copy_back_deps (rtx_insn *to, rtx_insn *from, bool resolved_p) -{ - sd_list_types_def list_type; - sd_iterator_def sd_it; - dep_t dep; - - list_type = resolved_p ? SD_LIST_RES_BACK : SD_LIST_BACK; - - FOR_EACH_DEP (from, list_type, sd_it, dep) - { - dep_def _new_dep, *new_dep = &_new_dep; - - copy_dep (new_dep, dep); - DEP_CON (new_dep) = to; - sd_add_dep (new_dep, resolved_p); - } -} - -/* Remove a dependency referred to by SD_IT. - SD_IT will point to the next dependence after removal. */ -void -sd_delete_dep (sd_iterator_def sd_it) -{ - dep_node_t n = DEP_LINK_NODE (*sd_it.linkp); - dep_t dep = DEP_NODE_DEP (n); - rtx_insn *pro = DEP_PRO (dep); - rtx_insn *con = DEP_CON (dep); - deps_list_t con_back_deps; - deps_list_t pro_forw_deps; - - if (true_dependency_cache != NULL) - { - int elem_luid = INSN_LUID (pro); - int insn_luid = INSN_LUID (con); - - bitmap_clear_bit (&true_dependency_cache[insn_luid], elem_luid); - bitmap_clear_bit (&anti_dependency_cache[insn_luid], elem_luid); - bitmap_clear_bit (&control_dependency_cache[insn_luid], elem_luid); - bitmap_clear_bit (&output_dependency_cache[insn_luid], elem_luid); - - if (current_sched_info->flags & DO_SPECULATION) - bitmap_clear_bit (&spec_dependency_cache[insn_luid], elem_luid); - } - - get_back_and_forw_lists (dep, sd_it.resolved_p, - &con_back_deps, &pro_forw_deps); - - remove_from_deps_list (DEP_NODE_BACK (n), con_back_deps); - remove_from_deps_list (DEP_NODE_FORW (n), pro_forw_deps); - - delete_dep_node (n); -} - -/* Dump size of the lists. */ -#define DUMP_LISTS_SIZE (2) - -/* Dump dependencies of the lists. */ -#define DUMP_LISTS_DEPS (4) - -/* Dump all information about the lists. */ -#define DUMP_LISTS_ALL (DUMP_LISTS_SIZE | DUMP_LISTS_DEPS) - -/* Dump deps_lists of INSN specified by TYPES to DUMP. - FLAGS is a bit mask specifying what information about the lists needs - to be printed. - If FLAGS has the very first bit set, then dump all information about - the lists and propagate this bit into the callee dump functions. */ -static void -dump_lists (FILE *dump, rtx insn, sd_list_types_def types, int flags) -{ - sd_iterator_def sd_it; - dep_t dep; - int all; - - all = (flags & 1); - - if (all) - flags |= DUMP_LISTS_ALL; - - fprintf (dump, "["); - - if (flags & DUMP_LISTS_SIZE) - fprintf (dump, "%d; ", sd_lists_size (insn, types)); - - if (flags & DUMP_LISTS_DEPS) - { - FOR_EACH_DEP (insn, types, sd_it, dep) - { - dump_dep (dump, dep, dump_dep_flags | all); - fprintf (dump, " "); - } - } -} - -/* Dump all information about deps_lists of INSN specified by TYPES - to STDERR. */ -void -sd_debug_lists (rtx insn, sd_list_types_def types) -{ - dump_lists (stderr, insn, types, 1); - fprintf (stderr, "\n"); -} - -/* A wrapper around add_dependence_1, to add a dependence of CON on - PRO, with type DEP_TYPE. This function implements special handling - for REG_DEP_CONTROL dependencies. For these, we optionally promote - the type to REG_DEP_ANTI if we can determine that predication is - impossible; otherwise we add additional true dependencies on the - INSN_COND_DEPS list of the jump (which PRO must be). */ -void -add_dependence (rtx_insn *con, rtx_insn *pro, enum reg_note dep_type) -{ - if (dep_type == REG_DEP_CONTROL - && !(current_sched_info->flags & DO_PREDICATION)) - dep_type = REG_DEP_ANTI; - - /* A REG_DEP_CONTROL dependence may be eliminated through predication, - so we must also make the insn dependent on the setter of the - condition. */ - if (dep_type == REG_DEP_CONTROL) - { - rtx_insn *real_pro = pro; - rtx_insn *other = real_insn_for_shadow (real_pro); - rtx cond; - - if (other != NULL_RTX) - real_pro = other; - cond = sched_get_reverse_condition_uncached (real_pro); - /* Verify that the insn does not use a different value in - the condition register than the one that was present at - the jump. */ - if (cond == NULL_RTX) - dep_type = REG_DEP_ANTI; - else if (INSN_CACHED_COND (real_pro) == const_true_rtx) - { - HARD_REG_SET uses; - CLEAR_HARD_REG_SET (uses); - note_uses (&PATTERN (con), record_hard_reg_uses, &uses); - if (TEST_HARD_REG_BIT (uses, REGNO (XEXP (cond, 0)))) - dep_type = REG_DEP_ANTI; - } - if (dep_type == REG_DEP_CONTROL) - { - if (sched_verbose >= 5) - fprintf (sched_dump, "making DEP_CONTROL for %d\n", - INSN_UID (real_pro)); - add_dependence_list (con, INSN_COND_DEPS (real_pro), 0, - REG_DEP_TRUE, false); - } - } - - add_dependence_1 (con, pro, dep_type); -} - -/* A convenience wrapper to operate on an entire list. HARD should be - true if DEP_NONREG should be set on newly created dependencies. */ - -static void -add_dependence_list (rtx_insn *insn, rtx_insn_list *list, int uncond, - enum reg_note dep_type, bool hard) -{ - mark_as_hard = hard; - for (; list; list = list->next ()) - { - if (uncond || ! sched_insns_conditions_mutex_p (insn, list->insn ())) - add_dependence (insn, list->insn (), dep_type); - } - mark_as_hard = false; -} - -/* Similar, but free *LISTP at the same time, when the context - is not readonly. HARD should be true if DEP_NONREG should be set on - newly created dependencies. */ - -static void -add_dependence_list_and_free (class deps_desc *deps, rtx_insn *insn, - rtx_insn_list **listp, - int uncond, enum reg_note dep_type, bool hard) -{ - add_dependence_list (insn, *listp, uncond, dep_type, hard); - - /* We don't want to short-circuit dependencies involving debug - insns, because they may cause actual dependencies to be - disregarded. */ - if (deps->readonly || DEBUG_INSN_P (insn)) - return; - - free_INSN_LIST_list (listp); -} - -/* Remove all occurrences of INSN from LIST. Return the number of - occurrences removed. */ - -static int -remove_from_dependence_list (rtx_insn *insn, rtx_insn_list **listp) -{ - int removed = 0; - - while (*listp) - { - if ((*listp)->insn () == insn) - { - remove_free_INSN_LIST_node (listp); - removed++; - continue; - } - - listp = (rtx_insn_list **)&XEXP (*listp, 1); - } - - return removed; -} - -/* Same as above, but process two lists at once. */ -static int -remove_from_both_dependence_lists (rtx_insn *insn, - rtx_insn_list **listp, - rtx_expr_list **exprp) -{ - int removed = 0; - - while (*listp) - { - if (XEXP (*listp, 0) == insn) - { - remove_free_INSN_LIST_node (listp); - remove_free_EXPR_LIST_node (exprp); - removed++; - continue; - } - - listp = (rtx_insn_list **)&XEXP (*listp, 1); - exprp = (rtx_expr_list **)&XEXP (*exprp, 1); - } - - return removed; -} - -/* Clear all dependencies for an insn. */ -static void -delete_all_dependences (rtx_insn *insn) -{ - sd_iterator_def sd_it; - dep_t dep; - - /* The below cycle can be optimized to clear the caches and back_deps - in one call but that would provoke duplication of code from - delete_dep (). */ - - for (sd_it = sd_iterator_start (insn, SD_LIST_BACK); - sd_iterator_cond (&sd_it, &dep);) - sd_delete_dep (sd_it); -} - -/* All insns in a scheduling group except the first should only have - dependencies on the previous insn in the group. So we find the - first instruction in the scheduling group by walking the dependence - chains backwards. Then we add the dependencies for the group to - the previous nonnote insn. */ - -static void -chain_to_prev_insn (rtx_insn *insn) -{ - sd_iterator_def sd_it; - dep_t dep; - rtx_insn *prev_nonnote; - - FOR_EACH_DEP (insn, SD_LIST_BACK, sd_it, dep) - { - rtx_insn *i = insn; - rtx_insn *pro = DEP_PRO (dep); - - do - { - i = prev_nonnote_insn (i); - - if (pro == i) - goto next_link; - } while (SCHED_GROUP_P (i) || DEBUG_INSN_P (i)); - - if (! sched_insns_conditions_mutex_p (i, pro)) - add_dependence (i, pro, DEP_TYPE (dep)); - next_link:; - } - - delete_all_dependences (insn); - - prev_nonnote = prev_nonnote_nondebug_insn (insn); - if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote) - && ! sched_insns_conditions_mutex_p (insn, prev_nonnote)) - add_dependence (insn, prev_nonnote, REG_DEP_ANTI); -} - -/* Process an insn's memory dependencies. There are four kinds of - dependencies: - - (0) read dependence: read follows read - (1) true dependence: read follows write - (2) output dependence: write follows write - (3) anti dependence: write follows read - - We are careful to build only dependencies which actually exist, and - use transitivity to avoid building too many links. */ - -/* Add an INSN and MEM reference pair to a pending INSN_LIST and MEM_LIST. - The MEM is a memory reference contained within INSN, which we are saving - so that we can do memory aliasing on it. */ - -static void -add_insn_mem_dependence (class deps_desc *deps, bool read_p, - rtx_insn *insn, rtx mem) -{ - rtx_insn_list **insn_list; - rtx_insn_list *insn_node; - rtx_expr_list **mem_list; - rtx_expr_list *mem_node; - - gcc_assert (!deps->readonly); - if (read_p) - { - insn_list = &deps->pending_read_insns; - mem_list = &deps->pending_read_mems; - if (!DEBUG_INSN_P (insn)) - deps->pending_read_list_length++; - } - else - { - insn_list = &deps->pending_write_insns; - mem_list = &deps->pending_write_mems; - deps->pending_write_list_length++; - } - - insn_node = alloc_INSN_LIST (insn, *insn_list); - *insn_list = insn_node; - - if (sched_deps_info->use_cselib) - { - mem = shallow_copy_rtx (mem); - XEXP (mem, 0) = cselib_subst_to_values_from_insn (XEXP (mem, 0), - GET_MODE (mem), insn); - } - mem_node = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list); - *mem_list = mem_node; -} - -/* Make a dependency between every memory reference on the pending lists - and INSN, thus flushing the pending lists. FOR_READ is true if emitting - dependencies for a read operation, similarly with FOR_WRITE. */ - -static void -flush_pending_lists (class deps_desc *deps, rtx_insn *insn, int for_read, - int for_write) -{ - if (for_write) - { - add_dependence_list_and_free (deps, insn, &deps->pending_read_insns, - 1, REG_DEP_ANTI, true); - if (!deps->readonly) - { - free_EXPR_LIST_list (&deps->pending_read_mems); - deps->pending_read_list_length = 0; - } - } - - add_dependence_list_and_free (deps, insn, &deps->pending_write_insns, 1, - for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT, - true); - - add_dependence_list_and_free (deps, insn, - &deps->last_pending_memory_flush, 1, - for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT, - true); - - add_dependence_list_and_free (deps, insn, &deps->pending_jump_insns, 1, - REG_DEP_ANTI, true); - - if (DEBUG_INSN_P (insn)) - { - if (for_write) - free_INSN_LIST_list (&deps->pending_read_insns); - free_INSN_LIST_list (&deps->pending_write_insns); - free_INSN_LIST_list (&deps->last_pending_memory_flush); - free_INSN_LIST_list (&deps->pending_jump_insns); - } - - if (!deps->readonly) - { - free_EXPR_LIST_list (&deps->pending_write_mems); - deps->pending_write_list_length = 0; - - deps->last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX); - deps->pending_flush_length = 1; - } - mark_as_hard = false; -} - -/* Instruction which dependencies we are analyzing. */ -static rtx_insn *cur_insn = NULL; - -/* Implement hooks for haifa scheduler. */ - -static void -haifa_start_insn (rtx_insn *insn) -{ - gcc_assert (insn && !cur_insn); - - cur_insn = insn; -} - -static void -haifa_finish_insn (void) -{ - cur_insn = NULL; -} - -void -haifa_note_reg_set (int regno) -{ - SET_REGNO_REG_SET (reg_pending_sets, regno); -} - -void -haifa_note_reg_clobber (int regno) -{ - SET_REGNO_REG_SET (reg_pending_clobbers, regno); -} - -void -haifa_note_reg_use (int regno) -{ - SET_REGNO_REG_SET (reg_pending_uses, regno); -} - -static void -haifa_note_mem_dep (rtx mem, rtx pending_mem, rtx_insn *pending_insn, ds_t ds) -{ - if (!(ds & SPECULATIVE)) - { - mem = NULL_RTX; - pending_mem = NULL_RTX; - } - else - gcc_assert (ds & BEGIN_DATA); - - { - dep_def _dep, *dep = &_dep; - - init_dep_1 (dep, pending_insn, cur_insn, ds_to_dt (ds), - current_sched_info->flags & USE_DEPS_LIST ? ds : 0); - DEP_NONREG (dep) = 1; - maybe_add_or_update_dep_1 (dep, false, pending_mem, mem); - } - -} - -static void -haifa_note_dep (rtx_insn *elem, ds_t ds) -{ - dep_def _dep; - dep_t dep = &_dep; - - init_dep (dep, elem, cur_insn, ds_to_dt (ds)); - if (mark_as_hard) - DEP_NONREG (dep) = 1; - maybe_add_or_update_dep_1 (dep, false, NULL_RTX, NULL_RTX); -} - -static void -note_reg_use (int r) -{ - if (sched_deps_info->note_reg_use) - sched_deps_info->note_reg_use (r); -} - -static void -note_reg_set (int r) -{ - if (sched_deps_info->note_reg_set) - sched_deps_info->note_reg_set (r); -} - -static void -note_reg_clobber (int r) -{ - if (sched_deps_info->note_reg_clobber) - sched_deps_info->note_reg_clobber (r); -} - -static void -note_mem_dep (rtx m1, rtx m2, rtx_insn *e, ds_t ds) -{ - if (sched_deps_info->note_mem_dep) - sched_deps_info->note_mem_dep (m1, m2, e, ds); -} - -static void -note_dep (rtx_insn *e, ds_t ds) -{ - if (sched_deps_info->note_dep) - sched_deps_info->note_dep (e, ds); -} - -/* Return corresponding to DS reg_note. */ -enum reg_note -ds_to_dt (ds_t ds) -{ - if (ds & DEP_TRUE) - return REG_DEP_TRUE; - else if (ds & DEP_OUTPUT) - return REG_DEP_OUTPUT; - else if (ds & DEP_ANTI) - return REG_DEP_ANTI; - else - { - gcc_assert (ds & DEP_CONTROL); - return REG_DEP_CONTROL; - } -} - - - -/* Functions for computation of info needed for register pressure - sensitive insn scheduling. */ - - -/* Allocate and return reg_use_data structure for REGNO and INSN. */ -static struct reg_use_data * -create_insn_reg_use (int regno, rtx_insn *insn) -{ - struct reg_use_data *use; - - use = (struct reg_use_data *) xmalloc (sizeof (struct reg_use_data)); - use->regno = regno; - use->insn = insn; - use->next_insn_use = INSN_REG_USE_LIST (insn); - INSN_REG_USE_LIST (insn) = use; - return use; -} - -/* Allocate reg_set_data structure for REGNO and INSN. */ -static void -create_insn_reg_set (int regno, rtx insn) -{ - struct reg_set_data *set; - - set = (struct reg_set_data *) xmalloc (sizeof (struct reg_set_data)); - set->regno = regno; - set->insn = insn; - set->next_insn_set = INSN_REG_SET_LIST (insn); - INSN_REG_SET_LIST (insn) = set; -} - -/* Set up insn register uses for INSN and dependency context DEPS. */ -static void -setup_insn_reg_uses (class deps_desc *deps, rtx_insn *insn) -{ - unsigned i; - reg_set_iterator rsi; - struct reg_use_data *use, *use2, *next; - struct deps_reg *reg_last; - - EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi) - { - if (i < FIRST_PSEUDO_REGISTER - && TEST_HARD_REG_BIT (ira_no_alloc_regs, i)) - continue; - - if (find_regno_note (insn, REG_DEAD, i) == NULL_RTX - && ! REGNO_REG_SET_P (reg_pending_sets, i) - && ! REGNO_REG_SET_P (reg_pending_clobbers, i)) - /* Ignore use which is not dying. */ - continue; - - use = create_insn_reg_use (i, insn); - use->next_regno_use = use; - reg_last = &deps->reg_last[i]; - - /* Create the cycle list of uses. */ - for (rtx_insn_list *list = reg_last->uses; list; list = list->next ()) - { - use2 = create_insn_reg_use (i, list->insn ()); - next = use->next_regno_use; - use->next_regno_use = use2; - use2->next_regno_use = next; - } - } -} - -/* Register pressure info for the currently processed insn. */ -static struct reg_pressure_data reg_pressure_info[N_REG_CLASSES]; - -/* Return TRUE if INSN has the use structure for REGNO. */ -static bool -insn_use_p (rtx insn, int regno) -{ - struct reg_use_data *use; - - for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use) - if (use->regno == regno) - return true; - return false; -} - -/* Update the register pressure info after birth of pseudo register REGNO - in INSN. Arguments CLOBBER_P and UNUSED_P say correspondingly that - the register is in clobber or unused after the insn. */ -static void -mark_insn_pseudo_birth (rtx insn, int regno, bool clobber_p, bool unused_p) -{ - int incr, new_incr; - enum reg_class cl; - - gcc_assert (regno >= FIRST_PSEUDO_REGISTER); - cl = sched_regno_pressure_class[regno]; - if (cl != NO_REGS) - { - incr = ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (regno)]; - if (clobber_p) - { - new_incr = reg_pressure_info[cl].clobber_increase + incr; - reg_pressure_info[cl].clobber_increase = new_incr; - } - else if (unused_p) - { - new_incr = reg_pressure_info[cl].unused_set_increase + incr; - reg_pressure_info[cl].unused_set_increase = new_incr; - } - else - { - new_incr = reg_pressure_info[cl].set_increase + incr; - reg_pressure_info[cl].set_increase = new_incr; - if (! insn_use_p (insn, regno)) - reg_pressure_info[cl].change += incr; - create_insn_reg_set (regno, insn); - } - gcc_assert (new_incr < (1 << INCREASE_BITS)); - } -} - -/* Like mark_insn_pseudo_regno_birth except that NREGS saying how many - hard registers involved in the birth. */ -static void -mark_insn_hard_regno_birth (rtx insn, int regno, int nregs, - bool clobber_p, bool unused_p) -{ - enum reg_class cl; - int new_incr, last = regno + nregs; - - while (regno < last) - { - gcc_assert (regno < FIRST_PSEUDO_REGISTER); - if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) - { - cl = sched_regno_pressure_class[regno]; - if (cl != NO_REGS) - { - if (clobber_p) - { - new_incr = reg_pressure_info[cl].clobber_increase + 1; - reg_pressure_info[cl].clobber_increase = new_incr; - } - else if (unused_p) - { - new_incr = reg_pressure_info[cl].unused_set_increase + 1; - reg_pressure_info[cl].unused_set_increase = new_incr; - } - else - { - new_incr = reg_pressure_info[cl].set_increase + 1; - reg_pressure_info[cl].set_increase = new_incr; - if (! insn_use_p (insn, regno)) - reg_pressure_info[cl].change += 1; - create_insn_reg_set (regno, insn); - } - gcc_assert (new_incr < (1 << INCREASE_BITS)); - } - } - regno++; - } -} - -/* Update the register pressure info after birth of pseudo or hard - register REG in INSN. Arguments CLOBBER_P and UNUSED_P say - correspondingly that the register is in clobber or unused after the - insn. */ -static void -mark_insn_reg_birth (rtx insn, rtx reg, bool clobber_p, bool unused_p) -{ - int regno; - - if (GET_CODE (reg) == SUBREG) - reg = SUBREG_REG (reg); - - if (! REG_P (reg)) - return; - - regno = REGNO (reg); - if (regno < FIRST_PSEUDO_REGISTER) - mark_insn_hard_regno_birth (insn, regno, REG_NREGS (reg), - clobber_p, unused_p); - else - mark_insn_pseudo_birth (insn, regno, clobber_p, unused_p); -} - -/* Update the register pressure info after death of pseudo register - REGNO. */ -static void -mark_pseudo_death (int regno) -{ - int incr; - enum reg_class cl; - - gcc_assert (regno >= FIRST_PSEUDO_REGISTER); - cl = sched_regno_pressure_class[regno]; - if (cl != NO_REGS) - { - incr = ira_reg_class_max_nregs[cl][PSEUDO_REGNO_MODE (regno)]; - reg_pressure_info[cl].change -= incr; - } -} - -/* Like mark_pseudo_death except that NREGS saying how many hard - registers involved in the death. */ -static void -mark_hard_regno_death (int regno, int nregs) -{ - enum reg_class cl; - int last = regno + nregs; - - while (regno < last) - { - gcc_assert (regno < FIRST_PSEUDO_REGISTER); - if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) - { - cl = sched_regno_pressure_class[regno]; - if (cl != NO_REGS) - reg_pressure_info[cl].change -= 1; - } - regno++; - } -} - -/* Update the register pressure info after death of pseudo or hard - register REG. */ -static void -mark_reg_death (rtx reg) -{ - int regno; - - if (GET_CODE (reg) == SUBREG) - reg = SUBREG_REG (reg); - - if (! REG_P (reg)) - return; - - regno = REGNO (reg); - if (regno < FIRST_PSEUDO_REGISTER) - mark_hard_regno_death (regno, REG_NREGS (reg)); - else - mark_pseudo_death (regno); -} - -/* Process SETTER of REG. DATA is an insn containing the setter. */ -static void -mark_insn_reg_store (rtx reg, const_rtx setter, void *data) -{ - if (setter != NULL_RTX && GET_CODE (setter) != SET) - return; - mark_insn_reg_birth - ((rtx) data, reg, false, - find_reg_note ((const_rtx) data, REG_UNUSED, reg) != NULL_RTX); -} - -/* Like mark_insn_reg_store except notice just CLOBBERs; ignore SETs. */ -static void -mark_insn_reg_clobber (rtx reg, const_rtx setter, void *data) -{ - if (GET_CODE (setter) == CLOBBER) - mark_insn_reg_birth ((rtx) data, reg, true, false); -} - -/* Set up reg pressure info related to INSN. */ -void -init_insn_reg_pressure_info (rtx_insn *insn) -{ - int i, len; - enum reg_class cl; - static struct reg_pressure_data *pressure_info; - rtx link; - - gcc_assert (sched_pressure != SCHED_PRESSURE_NONE); - - if (! INSN_P (insn)) - return; - - for (i = 0; i < ira_pressure_classes_num; i++) - { - cl = ira_pressure_classes[i]; - reg_pressure_info[cl].clobber_increase = 0; - reg_pressure_info[cl].set_increase = 0; - reg_pressure_info[cl].unused_set_increase = 0; - reg_pressure_info[cl].change = 0; - } - - note_stores (insn, mark_insn_reg_clobber, insn); - - note_stores (insn, mark_insn_reg_store, insn); - - if (AUTO_INC_DEC) - for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) == REG_INC) - mark_insn_reg_store (XEXP (link, 0), NULL_RTX, insn); - - for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) == REG_DEAD) - mark_reg_death (XEXP (link, 0)); - - len = sizeof (struct reg_pressure_data) * ira_pressure_classes_num; - pressure_info - = INSN_REG_PRESSURE (insn) = (struct reg_pressure_data *) xmalloc (len); - if (sched_pressure == SCHED_PRESSURE_WEIGHTED) - INSN_MAX_REG_PRESSURE (insn) = (int *) xcalloc (ira_pressure_classes_num - * sizeof (int), 1); - for (i = 0; i < ira_pressure_classes_num; i++) - { - cl = ira_pressure_classes[i]; - pressure_info[i].clobber_increase - = reg_pressure_info[cl].clobber_increase; - pressure_info[i].set_increase = reg_pressure_info[cl].set_increase; - pressure_info[i].unused_set_increase - = reg_pressure_info[cl].unused_set_increase; - pressure_info[i].change = reg_pressure_info[cl].change; - } -} - - - - -/* Internal variable for sched_analyze_[12] () functions. - If it is nonzero, this means that sched_analyze_[12] looks - at the most toplevel SET. */ -static bool can_start_lhs_rhs_p; - -/* Extend reg info for the deps context DEPS given that - we have just generated a register numbered REGNO. */ -static void -extend_deps_reg_info (class deps_desc *deps, int regno) -{ - int max_regno = regno + 1; - - gcc_assert (!reload_completed); - - /* In a readonly context, it would not hurt to extend info, - but it should not be needed. */ - if (reload_completed && deps->readonly) - { - deps->max_reg = max_regno; - return; - } - - if (max_regno > deps->max_reg) - { - deps->reg_last = XRESIZEVEC (struct deps_reg, deps->reg_last, - max_regno); - memset (&deps->reg_last[deps->max_reg], - 0, (max_regno - deps->max_reg) - * sizeof (struct deps_reg)); - deps->max_reg = max_regno; - } -} - -/* Extends REG_INFO_P if needed. */ -void -maybe_extend_reg_info_p (void) -{ - /* Extend REG_INFO_P, if needed. */ - if ((unsigned int)max_regno - 1 >= reg_info_p_size) - { - size_t new_reg_info_p_size = max_regno + 128; - - gcc_assert (!reload_completed && sel_sched_p ()); - - reg_info_p = (struct reg_info_t *) xrecalloc (reg_info_p, - new_reg_info_p_size, - reg_info_p_size, - sizeof (*reg_info_p)); - reg_info_p_size = new_reg_info_p_size; - } -} - -/* Analyze a single reference to register (reg:MODE REGNO) in INSN. - The type of the reference is specified by REF and can be SET, - CLOBBER, PRE_DEC, POST_DEC, PRE_INC, POST_INC or USE. */ - -static void -sched_analyze_reg (class deps_desc *deps, int regno, machine_mode mode, - enum rtx_code ref, rtx_insn *insn) -{ - /* We could emit new pseudos in renaming. Extend the reg structures. */ - if (!reload_completed && sel_sched_p () - && (regno >= max_reg_num () - 1 || regno >= deps->max_reg)) - extend_deps_reg_info (deps, regno); - - maybe_extend_reg_info_p (); - - /* A hard reg in a wide mode may really be multiple registers. - If so, mark all of them just like the first. */ - if (regno < FIRST_PSEUDO_REGISTER) - { - int i = hard_regno_nregs (regno, mode); - if (ref == SET) - { - while (--i >= 0) - note_reg_set (regno + i); - } - else if (ref == USE) - { - while (--i >= 0) - note_reg_use (regno + i); - } - else - { - while (--i >= 0) - note_reg_clobber (regno + i); - } - } - - /* ??? Reload sometimes emits USEs and CLOBBERs of pseudos that - it does not reload. Ignore these as they have served their - purpose already. */ - else if (regno >= deps->max_reg) - { - enum rtx_code code = GET_CODE (PATTERN (insn)); - gcc_assert (code == USE || code == CLOBBER); - } - - else - { - if (ref == SET) - note_reg_set (regno); - else if (ref == USE) - note_reg_use (regno); - else - note_reg_clobber (regno); - - /* Pseudos that are REG_EQUIV to something may be replaced - by that during reloading. We need only add dependencies for - the address in the REG_EQUIV note. */ - if (!reload_completed && get_reg_known_equiv_p (regno)) - { - rtx t = get_reg_known_value (regno); - if (MEM_P (t)) - sched_analyze_2 (deps, XEXP (t, 0), insn); - } - - /* Don't let it cross a call after scheduling if it doesn't - already cross one. */ - if (REG_N_CALLS_CROSSED (regno) == 0) - { - if (!deps->readonly && ref == USE && !DEBUG_INSN_P (insn)) - deps->sched_before_next_call - = alloc_INSN_LIST (insn, deps->sched_before_next_call); - else - add_dependence_list (insn, deps->last_function_call, 1, - REG_DEP_ANTI, false); - } - } -} - -/* Analyze a single SET, CLOBBER, PRE_DEC, POST_DEC, PRE_INC or POST_INC - rtx, X, creating all dependencies generated by the write to the - destination of X, and reads of everything mentioned. */ - -static void -sched_analyze_1 (class deps_desc *deps, rtx x, rtx_insn *insn) -{ - rtx dest = XEXP (x, 0); - enum rtx_code code = GET_CODE (x); - bool cslr_p = can_start_lhs_rhs_p; - - can_start_lhs_rhs_p = false; - - gcc_assert (dest); - if (dest == 0) - return; - - if (cslr_p && sched_deps_info->start_lhs) - sched_deps_info->start_lhs (dest); - - if (GET_CODE (dest) == PARALLEL) - { - int i; - - for (i = XVECLEN (dest, 0) - 1; i >= 0; i--) - if (XEXP (XVECEXP (dest, 0, i), 0) != 0) - sched_analyze_1 (deps, - gen_rtx_CLOBBER (VOIDmode, - XEXP (XVECEXP (dest, 0, i), 0)), - insn); - - if (cslr_p && sched_deps_info->finish_lhs) - sched_deps_info->finish_lhs (); - - if (code == SET) - { - can_start_lhs_rhs_p = cslr_p; - - sched_analyze_2 (deps, SET_SRC (x), insn); - - can_start_lhs_rhs_p = false; - } - - return; - } - - while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG - || GET_CODE (dest) == ZERO_EXTRACT) - { - if (GET_CODE (dest) == STRICT_LOW_PART - || GET_CODE (dest) == ZERO_EXTRACT - || read_modify_subreg_p (dest)) - { - /* These both read and modify the result. We must handle - them as writes to get proper dependencies for following - instructions. We must handle them as reads to get proper - dependencies from this to previous instructions. - Thus we need to call sched_analyze_2. */ - - sched_analyze_2 (deps, XEXP (dest, 0), insn); - } - if (GET_CODE (dest) == ZERO_EXTRACT) - { - /* The second and third arguments are values read by this insn. */ - sched_analyze_2 (deps, XEXP (dest, 1), insn); - sched_analyze_2 (deps, XEXP (dest, 2), insn); - } - dest = XEXP (dest, 0); - } - - if (REG_P (dest)) - { - int regno = REGNO (dest); - machine_mode mode = GET_MODE (dest); - - sched_analyze_reg (deps, regno, mode, code, insn); - -#ifdef STACK_REGS - /* Treat all writes to a stack register as modifying the TOS. */ - if (regno >= FIRST_STACK_REG && regno <= LAST_STACK_REG) - { - /* Avoid analyzing the same register twice. */ - if (regno != FIRST_STACK_REG) - sched_analyze_reg (deps, FIRST_STACK_REG, mode, code, insn); - - add_to_hard_reg_set (&implicit_reg_pending_uses, mode, - FIRST_STACK_REG); - } -#endif - } - else if (MEM_P (dest)) - { - /* Writing memory. */ - rtx t = dest; - - if (sched_deps_info->use_cselib) - { - machine_mode address_mode = get_address_mode (dest); - - t = shallow_copy_rtx (dest); - cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1, - GET_MODE (t), insn); - XEXP (t, 0) - = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t), - insn); - } - t = canon_rtx (t); - - /* Pending lists can't get larger with a readonly context. */ - if (!deps->readonly - && ((deps->pending_read_list_length + deps->pending_write_list_length) - >= param_max_pending_list_length)) - { - /* Flush all pending reads and writes to prevent the pending lists - from getting any larger. Insn scheduling runs too slowly when - these lists get long. When compiling GCC with itself, - this flush occurs 8 times for sparc, and 10 times for m88k using - the default value of 32. */ - flush_pending_lists (deps, insn, false, true); - } - else - { - rtx_insn_list *pending; - rtx_expr_list *pending_mem; - - pending = deps->pending_read_insns; - pending_mem = deps->pending_read_mems; - while (pending) - { - if (anti_dependence (pending_mem->element (), t) - && ! sched_insns_conditions_mutex_p (insn, pending->insn ())) - note_mem_dep (t, pending_mem->element (), pending->insn (), - DEP_ANTI); - - pending = pending->next (); - pending_mem = pending_mem->next (); - } - - pending = deps->pending_write_insns; - pending_mem = deps->pending_write_mems; - while (pending) - { - if (output_dependence (pending_mem->element (), t) - && ! sched_insns_conditions_mutex_p (insn, pending->insn ())) - note_mem_dep (t, pending_mem->element (), - pending->insn (), - DEP_OUTPUT); - - pending = pending->next (); - pending_mem = pending_mem-> next (); - } - - add_dependence_list (insn, deps->last_pending_memory_flush, 1, - REG_DEP_ANTI, true); - add_dependence_list (insn, deps->pending_jump_insns, 1, - REG_DEP_CONTROL, true); - - if (!deps->readonly) - add_insn_mem_dependence (deps, false, insn, dest); - } - sched_analyze_2 (deps, XEXP (dest, 0), insn); - } - - if (cslr_p && sched_deps_info->finish_lhs) - sched_deps_info->finish_lhs (); - - /* Analyze reads. */ - if (GET_CODE (x) == SET) - { - can_start_lhs_rhs_p = cslr_p; - - sched_analyze_2 (deps, SET_SRC (x), insn); - - can_start_lhs_rhs_p = false; - } -} - -/* Analyze the uses of memory and registers in rtx X in INSN. */ -static void -sched_analyze_2 (class deps_desc *deps, rtx x, rtx_insn *insn) -{ - int i; - int j; - enum rtx_code code; - const char *fmt; - bool cslr_p = can_start_lhs_rhs_p; - - can_start_lhs_rhs_p = false; - - gcc_assert (x); - if (x == 0) - return; - - if (cslr_p && sched_deps_info->start_rhs) - sched_deps_info->start_rhs (x); - - code = GET_CODE (x); - - switch (code) - { - CASE_CONST_ANY: - case SYMBOL_REF: - case CONST: - case LABEL_REF: - /* Ignore constants. */ - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); - - return; - - case REG: - { - int regno = REGNO (x); - machine_mode mode = GET_MODE (x); - - sched_analyze_reg (deps, regno, mode, USE, insn); - -#ifdef STACK_REGS - /* Treat all reads of a stack register as modifying the TOS. */ - if (regno >= FIRST_STACK_REG && regno <= LAST_STACK_REG) - { - /* Avoid analyzing the same register twice. */ - if (regno != FIRST_STACK_REG) - sched_analyze_reg (deps, FIRST_STACK_REG, mode, USE, insn); - sched_analyze_reg (deps, FIRST_STACK_REG, mode, SET, insn); - } -#endif - - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); - - return; - } - - case MEM: - { - /* Reading memory. */ - rtx_insn_list *u; - rtx_insn_list *pending; - rtx_expr_list *pending_mem; - rtx t = x; - - if (sched_deps_info->use_cselib) - { - machine_mode address_mode = get_address_mode (t); - - t = shallow_copy_rtx (t); - cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1, - GET_MODE (t), insn); - XEXP (t, 0) - = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t), - insn); - } - - if (!DEBUG_INSN_P (insn)) - { - t = canon_rtx (t); - pending = deps->pending_read_insns; - pending_mem = deps->pending_read_mems; - while (pending) - { - if (read_dependence (pending_mem->element (), t) - && ! sched_insns_conditions_mutex_p (insn, - pending->insn ())) - note_mem_dep (t, pending_mem->element (), - pending->insn (), - DEP_ANTI); - - pending = pending->next (); - pending_mem = pending_mem->next (); - } - - pending = deps->pending_write_insns; - pending_mem = deps->pending_write_mems; - while (pending) - { - if (true_dependence (pending_mem->element (), VOIDmode, t) - && ! sched_insns_conditions_mutex_p (insn, - pending->insn ())) - note_mem_dep (t, pending_mem->element (), - pending->insn (), - sched_deps_info->generate_spec_deps - ? BEGIN_DATA | DEP_TRUE : DEP_TRUE); - - pending = pending->next (); - pending_mem = pending_mem->next (); - } - - for (u = deps->last_pending_memory_flush; u; u = u->next ()) - add_dependence (insn, u->insn (), REG_DEP_ANTI); - - for (u = deps->pending_jump_insns; u; u = u->next ()) - if (deps_may_trap_p (x)) - { - if ((sched_deps_info->generate_spec_deps) - && sel_sched_p () && (spec_info->mask & BEGIN_CONTROL)) - { - ds_t ds = set_dep_weak (DEP_ANTI, BEGIN_CONTROL, - MAX_DEP_WEAK); - - note_dep (u->insn (), ds); - } - else - add_dependence (insn, u->insn (), REG_DEP_CONTROL); - } - } - - /* Always add these dependencies to pending_reads, since - this insn may be followed by a write. */ - if (!deps->readonly) - { - if ((deps->pending_read_list_length - + deps->pending_write_list_length) - >= param_max_pending_list_length - && !DEBUG_INSN_P (insn)) - flush_pending_lists (deps, insn, true, true); - add_insn_mem_dependence (deps, true, insn, x); - } - - sched_analyze_2 (deps, XEXP (x, 0), insn); - - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); - - return; - } - - /* Force pending stores to memory in case a trap handler needs them. - Also force pending loads from memory; loads and stores can segfault - and the signal handler won't be triggered if the trap insn was moved - above load or store insn. */ - case TRAP_IF: - flush_pending_lists (deps, insn, true, true); - break; - - case PREFETCH: - if (PREFETCH_SCHEDULE_BARRIER_P (x)) - reg_pending_barrier = TRUE_BARRIER; - /* Prefetch insn contains addresses only. So if the prefetch - address has no registers, there will be no dependencies on - the prefetch insn. This is wrong with result code - correctness point of view as such prefetch can be moved below - a jump insn which usually generates MOVE_BARRIER preventing - to move insns containing registers or memories through the - barrier. It is also wrong with generated code performance - point of view as prefetch withouth dependecies will have a - tendency to be issued later instead of earlier. It is hard - to generate accurate dependencies for prefetch insns as - prefetch has only the start address but it is better to have - something than nothing. */ - if (!deps->readonly) - { - rtx x = gen_rtx_MEM (Pmode, XEXP (PATTERN (insn), 0)); - if (sched_deps_info->use_cselib) - cselib_lookup_from_insn (x, Pmode, true, VOIDmode, insn); - add_insn_mem_dependence (deps, true, insn, x); - } - break; - - case UNSPEC_VOLATILE: - flush_pending_lists (deps, insn, true, true); - /* FALLTHRU */ - - case ASM_OPERANDS: - case ASM_INPUT: - { - /* Traditional and volatile asm instructions must be considered to use - and clobber all hard registers, all pseudo-registers and all of - memory. So must TRAP_IF and UNSPEC_VOLATILE operations. - - Consider for instance a volatile asm that changes the fpu rounding - mode. An insn should not be moved across this even if it only uses - pseudo-regs because it might give an incorrectly rounded result. */ - if ((code != ASM_OPERANDS || MEM_VOLATILE_P (x)) - && !DEBUG_INSN_P (insn)) - reg_pending_barrier = TRUE_BARRIER; - - /* For all ASM_OPERANDS, we must traverse the vector of input operands. - We cannot just fall through here since then we would be confused - by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate - traditional asms unlike their normal usage. */ - - if (code == ASM_OPERANDS) - { - for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++) - sched_analyze_2 (deps, ASM_OPERANDS_INPUT (x, j), insn); - - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); - - return; - } - break; - } - - case PRE_DEC: - case POST_DEC: - case PRE_INC: - case POST_INC: - /* These both read and modify the result. We must handle them as writes - to get proper dependencies for following instructions. We must handle - them as reads to get proper dependencies from this to previous - instructions. Thus we need to pass them to both sched_analyze_1 - and sched_analyze_2. We must call sched_analyze_2 first in order - to get the proper antecedent for the read. */ - sched_analyze_2 (deps, XEXP (x, 0), insn); - sched_analyze_1 (deps, x, insn); - - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); - - return; - - case POST_MODIFY: - case PRE_MODIFY: - /* op0 = op0 + op1 */ - sched_analyze_2 (deps, XEXP (x, 0), insn); - sched_analyze_2 (deps, XEXP (x, 1), insn); - sched_analyze_1 (deps, x, insn); - - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); - - return; - - default: - break; - } - - /* Other cases: walk the insn. */ - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - sched_analyze_2 (deps, XEXP (x, i), insn); - else if (fmt[i] == 'E') - for (j = 0; j < XVECLEN (x, i); j++) - sched_analyze_2 (deps, XVECEXP (x, i, j), insn); - } - - if (cslr_p && sched_deps_info->finish_rhs) - sched_deps_info->finish_rhs (); -} - -/* Try to group two fusible insns together to prevent scheduler - from scheduling them apart. */ - -static void -sched_macro_fuse_insns (rtx_insn *insn) -{ - rtx_insn *prev; - /* No target hook would return true for debug insn as any of the - hook operand, and with very large sequences of only debug insns - where on each we call sched_macro_fuse_insns it has quadratic - compile time complexity. */ - if (DEBUG_INSN_P (insn)) - return; - prev = prev_nonnote_nondebug_insn (insn); - if (!prev) - return; - - if (any_condjump_p (insn)) - { - unsigned int condreg1, condreg2; - rtx cc_reg_1; - if (targetm.fixed_condition_code_regs (&condreg1, &condreg2)) - { - cc_reg_1 = gen_rtx_REG (CCmode, condreg1); - if (reg_referenced_p (cc_reg_1, PATTERN (insn)) - && modified_in_p (cc_reg_1, prev)) - { - if (targetm.sched.macro_fusion_pair_p (prev, insn)) - SCHED_GROUP_P (insn) = 1; - return; - } - } - } - - if (single_set (insn) && single_set (prev)) - { - if (targetm.sched.macro_fusion_pair_p (prev, insn)) - SCHED_GROUP_P (insn) = 1; - } -} - -/* Get the implicit reg pending clobbers for INSN and save them in TEMP. */ -void -get_implicit_reg_pending_clobbers (HARD_REG_SET *temp, rtx_insn *insn) -{ - extract_insn (insn); - preprocess_constraints (insn); - alternative_mask preferred = get_preferred_alternatives (insn); - ira_implicitly_set_insn_hard_regs (temp, preferred); - *temp &= ~ira_no_alloc_regs; -} - -/* Analyze an INSN with pattern X to find all dependencies. */ -static void -sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn) -{ - RTX_CODE code = GET_CODE (x); - rtx link; - unsigned i; - reg_set_iterator rsi; - - if (! reload_completed) - { - HARD_REG_SET temp; - get_implicit_reg_pending_clobbers (&temp, insn); - implicit_reg_pending_clobbers |= temp; - } - - can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn) - && code == SET); - - /* Group compare and branch insns for macro-fusion. */ - if (!deps->readonly - && targetm.sched.macro_fusion_p - && targetm.sched.macro_fusion_p ()) - sched_macro_fuse_insns (insn); - - if (may_trap_p (x)) - /* Avoid moving trapping instructions across function calls that might - not always return. */ - add_dependence_list (insn, deps->last_function_call_may_noreturn, - 1, REG_DEP_ANTI, true); - - /* We must avoid creating a situation in which two successors of the - current block have different unwind info after scheduling. If at any - point the two paths re-join this leads to incorrect unwind info. */ - /* ??? There are certain situations involving a forced frame pointer in - which, with extra effort, we could fix up the unwind info at a later - CFG join. However, it seems better to notice these cases earlier - during prologue generation and avoid marking the frame pointer setup - as frame-related at all. */ - if (RTX_FRAME_RELATED_P (insn)) - { - /* Make sure prologue insn is scheduled before next jump. */ - deps->sched_before_next_jump - = alloc_INSN_LIST (insn, deps->sched_before_next_jump); - - /* Make sure epilogue insn is scheduled after preceding jumps. */ - add_dependence_list (insn, deps->last_pending_memory_flush, 1, - REG_DEP_ANTI, true); - add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI, - true); - } - - if (code == COND_EXEC) - { - sched_analyze_2 (deps, COND_EXEC_TEST (x), insn); - - /* ??? Should be recording conditions so we reduce the number of - false dependencies. */ - x = COND_EXEC_CODE (x); - code = GET_CODE (x); - } - if (code == SET || code == CLOBBER) - { - sched_analyze_1 (deps, x, insn); - - /* Bare clobber insns are used for letting life analysis, reg-stack - and others know that a value is dead. Depend on the last call - instruction so that reg-stack won't get confused. */ - if (code == CLOBBER) - add_dependence_list (insn, deps->last_function_call, 1, - REG_DEP_OUTPUT, true); - } - else if (code == PARALLEL) - { - for (i = XVECLEN (x, 0); i--;) - { - rtx sub = XVECEXP (x, 0, i); - code = GET_CODE (sub); - - if (code == COND_EXEC) - { - sched_analyze_2 (deps, COND_EXEC_TEST (sub), insn); - sub = COND_EXEC_CODE (sub); - code = GET_CODE (sub); - } - else if (code == SET || code == CLOBBER) - sched_analyze_1 (deps, sub, insn); - else - sched_analyze_2 (deps, sub, insn); - } - } - else - sched_analyze_2 (deps, x, insn); - - /* Mark registers CLOBBERED or used by called function. */ - if (CALL_P (insn)) - { - for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1)) - { - if (GET_CODE (XEXP (link, 0)) == CLOBBER) - sched_analyze_1 (deps, XEXP (link, 0), insn); - else if (GET_CODE (XEXP (link, 0)) != SET) - sched_analyze_2 (deps, XEXP (link, 0), insn); - } - /* Don't schedule anything after a tail call, tail call needs - to use at least all call-saved registers. */ - if (SIBLING_CALL_P (insn)) - reg_pending_barrier = TRUE_BARRIER; - else if (find_reg_note (insn, REG_SETJMP, NULL)) - reg_pending_barrier = MOVE_BARRIER; - } - - if (JUMP_P (insn)) - { - rtx_insn *next = next_nonnote_nondebug_insn (insn); - /* ??? For tablejumps, the barrier may appear not immediately after - the jump, but after a label and a jump_table_data insn. */ - if (next && LABEL_P (next) && NEXT_INSN (next) - && JUMP_TABLE_DATA_P (NEXT_INSN (next))) - next = NEXT_INSN (NEXT_INSN (next)); - if (next && BARRIER_P (next)) - reg_pending_barrier = MOVE_BARRIER; - else - { - rtx_insn_list *pending; - rtx_expr_list *pending_mem; - - if (sched_deps_info->compute_jump_reg_dependencies) - { - (*sched_deps_info->compute_jump_reg_dependencies) - (insn, reg_pending_control_uses); - - /* Make latency of jump equal to 0 by using anti-dependence. */ - EXECUTE_IF_SET_IN_REG_SET (reg_pending_control_uses, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI, - false); - add_dependence_list (insn, reg_last->implicit_sets, - 0, REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->clobbers, 0, - REG_DEP_ANTI, false); - } - } - - /* All memory writes and volatile reads must happen before the - jump. Non-volatile reads must happen before the jump iff - the result is needed by the above register used mask. */ - - pending = deps->pending_write_insns; - pending_mem = deps->pending_write_mems; - while (pending) - { - if (! sched_insns_conditions_mutex_p (insn, pending->insn ())) - add_dependence (insn, pending->insn (), - REG_DEP_OUTPUT); - pending = pending->next (); - pending_mem = pending_mem->next (); - } - - pending = deps->pending_read_insns; - pending_mem = deps->pending_read_mems; - while (pending) - { - if (MEM_VOLATILE_P (pending_mem->element ()) - && ! sched_insns_conditions_mutex_p (insn, pending->insn ())) - add_dependence (insn, pending->insn (), - REG_DEP_OUTPUT); - pending = pending->next (); - pending_mem = pending_mem->next (); - } - - add_dependence_list (insn, deps->last_pending_memory_flush, 1, - REG_DEP_ANTI, true); - add_dependence_list (insn, deps->pending_jump_insns, 1, - REG_DEP_ANTI, true); - } - } - - /* If this instruction can throw an exception, then moving it changes - where block boundaries fall. This is mighty confusing elsewhere. - Therefore, prevent such an instruction from being moved. Same for - non-jump instructions that define block boundaries. - ??? Unclear whether this is still necessary in EBB mode. If not, - add_branch_dependences should be adjusted for RGN mode instead. */ - if (((CALL_P (insn) || JUMP_P (insn)) && can_throw_internal (insn)) - || (NONJUMP_INSN_P (insn) && control_flow_insn_p (insn))) - reg_pending_barrier = MOVE_BARRIER; - - if (sched_pressure != SCHED_PRESSURE_NONE) - { - setup_insn_reg_uses (deps, insn); - init_insn_reg_pressure_info (insn); - } - - /* Add register dependencies for insn. */ - if (DEBUG_INSN_P (insn)) - { - rtx_insn *prev = deps->last_debug_insn; - rtx_insn_list *u; - - if (!deps->readonly) - deps->last_debug_insn = insn; - - if (prev) - add_dependence (insn, prev, REG_DEP_ANTI); - - add_dependence_list (insn, deps->last_function_call, 1, - REG_DEP_ANTI, false); - - if (!sel_sched_p ()) - for (u = deps->last_pending_memory_flush; u; u = u->next ()) - add_dependence (insn, u->insn (), REG_DEP_ANTI); - - EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 1, REG_DEP_ANTI, false); - /* There's no point in making REG_DEP_CONTROL dependencies for - debug insns. */ - add_dependence_list (insn, reg_last->clobbers, 1, REG_DEP_ANTI, - false); - - if (!deps->readonly) - reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses); - } - CLEAR_REG_SET (reg_pending_uses); - - /* Quite often, a debug insn will refer to stuff in the - previous instruction, but the reason we want this - dependency here is to make sure the scheduler doesn't - gratuitously move a debug insn ahead. This could dirty - DF flags and cause additional analysis that wouldn't have - occurred in compilation without debug insns, and such - additional analysis can modify the generated code. */ - prev = PREV_INSN (insn); - - if (prev && NONDEBUG_INSN_P (prev)) - add_dependence (insn, prev, REG_DEP_ANTI); - } - else - { - regset_head set_or_clobbered; - - EXECUTE_IF_SET_IN_REG_SET (reg_pending_uses, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE, false); - add_dependence_list (insn, reg_last->implicit_sets, 0, REG_DEP_ANTI, - false); - add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE, - false); - - if (!deps->readonly) - { - reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses); - reg_last->uses_length++; - } - } - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i)) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_TRUE, false); - add_dependence_list (insn, reg_last->implicit_sets, 0, - REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_TRUE, - false); - - if (!deps->readonly) - { - reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses); - reg_last->uses_length++; - } - } - - if (targetm.sched.exposed_pipeline) - { - INIT_REG_SET (&set_or_clobbered); - bitmap_ior (&set_or_clobbered, reg_pending_clobbers, - reg_pending_sets); - EXECUTE_IF_SET_IN_REG_SET (&set_or_clobbered, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - rtx list; - for (list = reg_last->uses; list; list = XEXP (list, 1)) - { - rtx other = XEXP (list, 0); - if (INSN_CACHED_COND (other) != const_true_rtx - && refers_to_regno_p (i, INSN_CACHED_COND (other))) - INSN_CACHED_COND (other) = const_true_rtx; - } - } - } - - /* If the current insn is conditional, we can't free any - of the lists. */ - if (sched_has_condition_p (insn)) - { - EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT, - false); - add_dependence_list (insn, reg_last->implicit_sets, 0, - REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, - false); - add_dependence_list (insn, reg_last->control_uses, 0, - REG_DEP_CONTROL, false); - - if (!deps->readonly) - { - reg_last->clobbers - = alloc_INSN_LIST (insn, reg_last->clobbers); - reg_last->clobbers_length++; - } - } - EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT, - false); - add_dependence_list (insn, reg_last->implicit_sets, 0, - REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_OUTPUT, - false); - add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, - false); - add_dependence_list (insn, reg_last->control_uses, 0, - REG_DEP_CONTROL, false); - - if (!deps->readonly) - reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets); - } - } - else - { - EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - if (reg_last->uses_length >= param_max_pending_list_length - || reg_last->clobbers_length >= param_max_pending_list_length) - { - add_dependence_list_and_free (deps, insn, ®_last->sets, 0, - REG_DEP_OUTPUT, false); - add_dependence_list_and_free (deps, insn, - ®_last->implicit_sets, 0, - REG_DEP_ANTI, false); - add_dependence_list_and_free (deps, insn, ®_last->uses, 0, - REG_DEP_ANTI, false); - add_dependence_list_and_free (deps, insn, - ®_last->control_uses, 0, - REG_DEP_ANTI, false); - add_dependence_list_and_free (deps, insn, - ®_last->clobbers, 0, - REG_DEP_OUTPUT, false); - - if (!deps->readonly) - { - reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets); - reg_last->clobbers_length = 0; - reg_last->uses_length = 0; - } - } - else - { - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_OUTPUT, - false); - add_dependence_list (insn, reg_last->implicit_sets, 0, - REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, - false); - add_dependence_list (insn, reg_last->control_uses, 0, - REG_DEP_CONTROL, false); - } - - if (!deps->readonly) - { - reg_last->clobbers_length++; - reg_last->clobbers - = alloc_INSN_LIST (insn, reg_last->clobbers); - } - } - EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - - add_dependence_list_and_free (deps, insn, ®_last->sets, 0, - REG_DEP_OUTPUT, false); - add_dependence_list_and_free (deps, insn, - ®_last->implicit_sets, - 0, REG_DEP_ANTI, false); - add_dependence_list_and_free (deps, insn, ®_last->clobbers, 0, - REG_DEP_OUTPUT, false); - add_dependence_list_and_free (deps, insn, ®_last->uses, 0, - REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->control_uses, 0, - REG_DEP_CONTROL, false); - - if (!deps->readonly) - { - reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets); - reg_last->uses_length = 0; - reg_last->clobbers_length = 0; - } - } - } - if (!deps->readonly) - { - EXECUTE_IF_SET_IN_REG_SET (reg_pending_control_uses, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - reg_last->control_uses - = alloc_INSN_LIST (insn, reg_last->control_uses); - } - } - } - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i)) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->sets, 0, REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->clobbers, 0, REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, false); - add_dependence_list (insn, reg_last->control_uses, 0, REG_DEP_ANTI, - false); - - if (!deps->readonly) - reg_last->implicit_sets - = alloc_INSN_LIST (insn, reg_last->implicit_sets); - } - - if (!deps->readonly) - { - IOR_REG_SET (&deps->reg_last_in_use, reg_pending_uses); - IOR_REG_SET (&deps->reg_last_in_use, reg_pending_clobbers); - IOR_REG_SET (&deps->reg_last_in_use, reg_pending_sets); - IOR_REG_SET_HRS (&deps->reg_last_in_use, - implicit_reg_pending_uses - | implicit_reg_pending_clobbers); - - /* Set up the pending barrier found. */ - deps->last_reg_pending_barrier = reg_pending_barrier; - } - - CLEAR_REG_SET (reg_pending_uses); - CLEAR_REG_SET (reg_pending_clobbers); - CLEAR_REG_SET (reg_pending_sets); - CLEAR_REG_SET (reg_pending_control_uses); - CLEAR_HARD_REG_SET (implicit_reg_pending_clobbers); - CLEAR_HARD_REG_SET (implicit_reg_pending_uses); - - /* Add dependencies if a scheduling barrier was found. */ - if (reg_pending_barrier) - { - /* In the case of barrier the most added dependencies are not - real, so we use anti-dependence here. */ - if (sched_has_condition_p (insn)) - { - EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list (insn, reg_last->uses, 0, REG_DEP_ANTI, - true); - add_dependence_list (insn, reg_last->sets, 0, - reg_pending_barrier == TRUE_BARRIER - ? REG_DEP_TRUE : REG_DEP_ANTI, true); - add_dependence_list (insn, reg_last->implicit_sets, 0, - REG_DEP_ANTI, true); - add_dependence_list (insn, reg_last->clobbers, 0, - reg_pending_barrier == TRUE_BARRIER - ? REG_DEP_TRUE : REG_DEP_ANTI, true); - } - } - else - { - EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - add_dependence_list_and_free (deps, insn, ®_last->uses, 0, - REG_DEP_ANTI, true); - add_dependence_list_and_free (deps, insn, - ®_last->control_uses, 0, - REG_DEP_CONTROL, true); - add_dependence_list_and_free (deps, insn, ®_last->sets, 0, - reg_pending_barrier == TRUE_BARRIER - ? REG_DEP_TRUE : REG_DEP_ANTI, - true); - add_dependence_list_and_free (deps, insn, - ®_last->implicit_sets, 0, - REG_DEP_ANTI, true); - add_dependence_list_and_free (deps, insn, ®_last->clobbers, 0, - reg_pending_barrier == TRUE_BARRIER - ? REG_DEP_TRUE : REG_DEP_ANTI, - true); - - if (!deps->readonly) - { - reg_last->uses_length = 0; - reg_last->clobbers_length = 0; - } - } - } - - if (!deps->readonly) - for (i = 0; i < (unsigned)deps->max_reg; i++) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets); - SET_REGNO_REG_SET (&deps->reg_last_in_use, i); - } - - /* Don't flush pending lists on speculative checks for - selective scheduling. */ - if (!sel_sched_p () || !sel_insn_is_speculation_check (insn)) - flush_pending_lists (deps, insn, true, true); - - reg_pending_barrier = NOT_A_BARRIER; - } - - /* If a post-call group is still open, see if it should remain so. - This insn must be a simple move of a hard reg to a pseudo or - vice-versa. - - We must avoid moving these insns for correctness on targets - with small register classes, and for special registers like - PIC_OFFSET_TABLE_REGNUM. For simplicity, extend this to all - hard regs for all targets. */ - - if (deps->in_post_call_group_p) - { - rtx tmp, set = single_set (insn); - int src_regno, dest_regno; - - if (set == NULL) - { - if (DEBUG_INSN_P (insn)) - /* We don't want to mark debug insns as part of the same - sched group. We know they really aren't, but if we use - debug insns to tell that a call group is over, we'll - get different code if debug insns are not there and - instructions that follow seem like they should be part - of the call group. - - Also, if we did, chain_to_prev_insn would move the - deps of the debug insn to the call insn, modifying - non-debug post-dependency counts of the debug insn - dependencies and otherwise messing with the scheduling - order. - - Instead, let such debug insns be scheduled freely, but - keep the call group open in case there are insns that - should be part of it afterwards. Since we grant debug - insns higher priority than even sched group insns, it - will all turn out all right. */ - goto debug_dont_end_call_group; - else - goto end_call_group; - } - - tmp = SET_DEST (set); - if (GET_CODE (tmp) == SUBREG) - tmp = SUBREG_REG (tmp); - if (REG_P (tmp)) - dest_regno = REGNO (tmp); - else - goto end_call_group; - - tmp = SET_SRC (set); - if (GET_CODE (tmp) == SUBREG) - tmp = SUBREG_REG (tmp); - if ((GET_CODE (tmp) == PLUS - || GET_CODE (tmp) == MINUS) - && REG_P (XEXP (tmp, 0)) - && REGNO (XEXP (tmp, 0)) == STACK_POINTER_REGNUM - && dest_regno == STACK_POINTER_REGNUM) - src_regno = STACK_POINTER_REGNUM; - else if (REG_P (tmp)) - src_regno = REGNO (tmp); - else - goto end_call_group; - - if (src_regno < FIRST_PSEUDO_REGISTER - || dest_regno < FIRST_PSEUDO_REGISTER) - { - if (!deps->readonly - && deps->in_post_call_group_p == post_call_initial) - deps->in_post_call_group_p = post_call; - - if (!sel_sched_p () || sched_emulate_haifa_p) - { - SCHED_GROUP_P (insn) = 1; - CANT_MOVE (insn) = 1; - } - } - else - { - end_call_group: - if (!deps->readonly) - deps->in_post_call_group_p = not_post_call; - } - } - - debug_dont_end_call_group: - if ((current_sched_info->flags & DO_SPECULATION) - && !sched_insn_is_legitimate_for_speculation_p (insn, 0)) - /* INSN has an internal dependency (e.g. r14 = [r14]) and thus cannot - be speculated. */ - { - if (sel_sched_p ()) - sel_mark_hard_insn (insn); - else - { - sd_iterator_def sd_it; - dep_t dep; - - for (sd_it = sd_iterator_start (insn, SD_LIST_SPEC_BACK); - sd_iterator_cond (&sd_it, &dep);) - change_spec_dep_to_hard (sd_it); - } - } - - /* We do not yet have code to adjust REG_ARGS_SIZE, therefore we must - honor their original ordering. */ - if (find_reg_note (insn, REG_ARGS_SIZE, NULL)) - { - if (deps->last_args_size) - add_dependence (insn, deps->last_args_size, REG_DEP_OUTPUT); - if (!deps->readonly) - deps->last_args_size = insn; - } - - /* We must not mix prologue and epilogue insns. See PR78029. */ - if (prologue_contains (insn)) - { - add_dependence_list (insn, deps->last_epilogue, true, REG_DEP_ANTI, true); - if (!deps->readonly) - { - if (deps->last_logue_was_epilogue) - free_INSN_LIST_list (&deps->last_prologue); - deps->last_prologue = alloc_INSN_LIST (insn, deps->last_prologue); - deps->last_logue_was_epilogue = false; - } - } - - if (epilogue_contains (insn)) - { - add_dependence_list (insn, deps->last_prologue, true, REG_DEP_ANTI, true); - if (!deps->readonly) - { - if (!deps->last_logue_was_epilogue) - free_INSN_LIST_list (&deps->last_epilogue); - deps->last_epilogue = alloc_INSN_LIST (insn, deps->last_epilogue); - deps->last_logue_was_epilogue = true; - } - } -} - -/* Return TRUE if INSN might not always return normally (e.g. call exit, - longjmp, loop forever, ...). */ -/* FIXME: Why can't this function just use flags_from_decl_or_type and - test for ECF_NORETURN? */ -static bool -call_may_noreturn_p (rtx_insn *insn) -{ - rtx call; - - /* const or pure calls that aren't looping will always return. */ - if (RTL_CONST_OR_PURE_CALL_P (insn) - && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)) - return false; - - call = get_call_rtx_from (insn); - if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF) - { - rtx symbol = XEXP (XEXP (call, 0), 0); - if (SYMBOL_REF_DECL (symbol) - && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL) - { - if (DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol)) - == BUILT_IN_NORMAL) - switch (DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))) - { - case BUILT_IN_BCMP: - case BUILT_IN_BCOPY: - case BUILT_IN_BZERO: - case BUILT_IN_INDEX: - case BUILT_IN_MEMCHR: - case BUILT_IN_MEMCMP: - case BUILT_IN_MEMCPY: - case BUILT_IN_MEMMOVE: - case BUILT_IN_MEMPCPY: - case BUILT_IN_MEMSET: - case BUILT_IN_RINDEX: - case BUILT_IN_STPCPY: - case BUILT_IN_STPNCPY: - case BUILT_IN_STRCAT: - case BUILT_IN_STRCHR: - case BUILT_IN_STRCMP: - case BUILT_IN_STRCPY: - case BUILT_IN_STRCSPN: - case BUILT_IN_STRLEN: - case BUILT_IN_STRNCAT: - case BUILT_IN_STRNCMP: - case BUILT_IN_STRNCPY: - case BUILT_IN_STRPBRK: - case BUILT_IN_STRRCHR: - case BUILT_IN_STRSPN: - case BUILT_IN_STRSTR: - /* Assume certain string/memory builtins always return. */ - return false; - default: - break; - } - } - } - - /* For all other calls assume that they might not always return. */ - return true; -} - -/* Return true if INSN should be made dependent on the previous instruction - group, and if all INSN's dependencies should be moved to the first - instruction of that group. */ - -static bool -chain_to_prev_insn_p (rtx_insn *insn) -{ - /* INSN forms a group with the previous instruction. */ - if (SCHED_GROUP_P (insn)) - return true; - - /* If the previous instruction clobbers a register R and this one sets - part of R, the clobber was added specifically to help us track the - liveness of R. There's no point scheduling the clobber and leaving - INSN behind, especially if we move the clobber to another block. */ - rtx_insn *prev = prev_nonnote_nondebug_insn (insn); - if (prev - && INSN_P (prev) - && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn) - && GET_CODE (PATTERN (prev)) == CLOBBER) - { - rtx x = XEXP (PATTERN (prev), 0); - if (set_of (x, insn)) - return true; - } - - return false; -} - -/* Analyze INSN with DEPS as a context. */ -void -deps_analyze_insn (class deps_desc *deps, rtx_insn *insn) -{ - if (sched_deps_info->start_insn) - sched_deps_info->start_insn (insn); - - /* Record the condition for this insn. */ - if (NONDEBUG_INSN_P (insn)) - { - rtx t; - sched_get_condition_with_rev (insn, NULL); - t = INSN_CACHED_COND (insn); - INSN_COND_DEPS (insn) = NULL; - if (reload_completed - && (current_sched_info->flags & DO_PREDICATION) - && COMPARISON_P (t) - && REG_P (XEXP (t, 0)) - && CONSTANT_P (XEXP (t, 1))) - { - unsigned int regno; - int nregs; - rtx_insn_list *cond_deps = NULL; - t = XEXP (t, 0); - regno = REGNO (t); - nregs = REG_NREGS (t); - while (nregs-- > 0) - { - struct deps_reg *reg_last = &deps->reg_last[regno + nregs]; - cond_deps = concat_INSN_LIST (reg_last->sets, cond_deps); - cond_deps = concat_INSN_LIST (reg_last->clobbers, cond_deps); - cond_deps = concat_INSN_LIST (reg_last->implicit_sets, cond_deps); - } - INSN_COND_DEPS (insn) = cond_deps; - } - } - - if (JUMP_P (insn)) - { - /* Make each JUMP_INSN (but not a speculative check) - a scheduling barrier for memory references. */ - if (!deps->readonly - && !(sel_sched_p () - && sel_insn_is_speculation_check (insn))) - { - /* Keep the list a reasonable size. */ - if (deps->pending_flush_length++ >= param_max_pending_list_length) - flush_pending_lists (deps, insn, true, true); - else - deps->pending_jump_insns - = alloc_INSN_LIST (insn, deps->pending_jump_insns); - } - - /* For each insn which shouldn't cross a jump, add a dependence. */ - add_dependence_list_and_free (deps, insn, - &deps->sched_before_next_jump, 1, - REG_DEP_ANTI, true); - - sched_analyze_insn (deps, PATTERN (insn), insn); - } - else if (NONJUMP_INSN_P (insn) || DEBUG_INSN_P (insn)) - { - sched_analyze_insn (deps, PATTERN (insn), insn); - } - else if (CALL_P (insn)) - { - int i; - - CANT_MOVE (insn) = 1; - - if (find_reg_note (insn, REG_SETJMP, NULL)) - { - /* This is setjmp. Assume that all registers, not just - hard registers, may be clobbered by this call. */ - reg_pending_barrier = MOVE_BARRIER; - } - else - { - function_abi callee_abi = insn_callee_abi (insn); - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - /* A call may read and modify global register variables. */ - if (global_regs[i]) - { - SET_REGNO_REG_SET (reg_pending_sets, i); - SET_HARD_REG_BIT (implicit_reg_pending_uses, i); - } - /* Other call-clobbered hard regs may be clobbered. - Since we only have a choice between 'might be clobbered' - and 'definitely not clobbered', we must include all - partly call-clobbered registers here. */ - else if (callee_abi.clobbers_at_least_part_of_reg_p (i)) - SET_REGNO_REG_SET (reg_pending_clobbers, i); - /* We don't know what set of fixed registers might be used - by the function, but it is certain that the stack pointer - is among them, but be conservative. */ - else if (fixed_regs[i]) - SET_HARD_REG_BIT (implicit_reg_pending_uses, i); - /* The frame pointer is normally not used by the function - itself, but by the debugger. */ - /* ??? MIPS o32 is an exception. It uses the frame pointer - in the macro expansion of jal but does not represent this - fact in the call_insn rtl. */ - else if (i == FRAME_POINTER_REGNUM - || (i == HARD_FRAME_POINTER_REGNUM - && (! reload_completed || frame_pointer_needed))) - SET_HARD_REG_BIT (implicit_reg_pending_uses, i); - } - - /* For each insn which shouldn't cross a call, add a dependence - between that insn and this call insn. */ - add_dependence_list_and_free (deps, insn, - &deps->sched_before_next_call, 1, - REG_DEP_ANTI, true); - - sched_analyze_insn (deps, PATTERN (insn), insn); - - /* If CALL would be in a sched group, then this will violate - convention that sched group insns have dependencies only on the - previous instruction. - - Of course one can say: "Hey! What about head of the sched group?" - And I will answer: "Basic principles (one dep per insn) are always - the same." */ - gcc_assert (!SCHED_GROUP_P (insn)); - - /* In the absence of interprocedural alias analysis, we must flush - all pending reads and writes, and start new dependencies starting - from here. But only flush writes for constant calls (which may - be passed a pointer to something we haven't written yet). */ - flush_pending_lists (deps, insn, true, ! RTL_CONST_OR_PURE_CALL_P (insn)); - - if (!deps->readonly) - { - /* Remember the last function call for limiting lifetimes. */ - free_INSN_LIST_list (&deps->last_function_call); - deps->last_function_call = alloc_INSN_LIST (insn, NULL_RTX); - - if (call_may_noreturn_p (insn)) - { - /* Remember the last function call that might not always return - normally for limiting moves of trapping insns. */ - free_INSN_LIST_list (&deps->last_function_call_may_noreturn); - deps->last_function_call_may_noreturn - = alloc_INSN_LIST (insn, NULL_RTX); - } - - /* Before reload, begin a post-call group, so as to keep the - lifetimes of hard registers correct. */ - if (! reload_completed) - deps->in_post_call_group_p = post_call; - } - } - - if (sched_deps_info->use_cselib) - cselib_process_insn (insn); - - if (sched_deps_info->finish_insn) - sched_deps_info->finish_insn (); - - /* Fixup the dependencies in the sched group. */ - if ((NONJUMP_INSN_P (insn) || JUMP_P (insn)) - && chain_to_prev_insn_p (insn) - && !sel_sched_p ()) - chain_to_prev_insn (insn); -} - -/* Initialize DEPS for the new block beginning with HEAD. */ -void -deps_start_bb (class deps_desc *deps, rtx_insn *head) -{ - gcc_assert (!deps->readonly); - - /* Before reload, if the previous block ended in a call, show that - we are inside a post-call group, so as to keep the lifetimes of - hard registers correct. */ - if (! reload_completed && !LABEL_P (head)) - { - rtx_insn *insn = prev_nonnote_nondebug_insn (head); - - if (insn && CALL_P (insn)) - deps->in_post_call_group_p = post_call_initial; - } -} - -/* Analyze every insn between HEAD and TAIL inclusive, creating backward - dependencies for each insn. */ -void -sched_analyze (class deps_desc *deps, rtx_insn *head, rtx_insn *tail) -{ - rtx_insn *insn; - - if (sched_deps_info->use_cselib) - cselib_init (CSELIB_RECORD_MEMORY); - - deps_start_bb (deps, head); - - for (insn = head;; insn = NEXT_INSN (insn)) - { - if (INSN_P (insn)) - { - /* And initialize deps_lists. */ - sd_init_insn (insn); - /* Clean up SCHED_GROUP_P which may be set by last - scheduler pass. */ - if (SCHED_GROUP_P (insn)) - SCHED_GROUP_P (insn) = 0; - } - - deps_analyze_insn (deps, insn); - - if (insn == tail) - { - if (sched_deps_info->use_cselib) - cselib_finish (); - return; - } - } -} - -/* Helper for sched_free_deps (). - Delete INSN's (RESOLVED_P) backward dependencies. */ -static void -delete_dep_nodes_in_back_deps (rtx_insn *insn, bool resolved_p) -{ - sd_iterator_def sd_it; - dep_t dep; - sd_list_types_def types; - - if (resolved_p) - types = SD_LIST_RES_BACK; - else - types = SD_LIST_BACK; - - for (sd_it = sd_iterator_start (insn, types); - sd_iterator_cond (&sd_it, &dep);) - { - dep_link_t link = *sd_it.linkp; - dep_node_t node = DEP_LINK_NODE (link); - deps_list_t back_list; - deps_list_t forw_list; - - get_back_and_forw_lists (dep, resolved_p, &back_list, &forw_list); - remove_from_deps_list (link, back_list); - delete_dep_node (node); - } -} - -/* Delete (RESOLVED_P) dependencies between HEAD and TAIL together with - deps_lists. */ -void -sched_free_deps (rtx_insn *head, rtx_insn *tail, bool resolved_p) -{ - rtx_insn *insn; - rtx_insn *next_tail = NEXT_INSN (tail); - - /* We make two passes since some insns may be scheduled before their - dependencies are resolved. */ - for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) - if (INSN_P (insn) && INSN_LUID (insn) > 0) - { - /* Clear forward deps and leave the dep_nodes to the - corresponding back_deps list. */ - if (resolved_p) - clear_deps_list (INSN_RESOLVED_FORW_DEPS (insn)); - else - clear_deps_list (INSN_FORW_DEPS (insn)); - } - for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) - if (INSN_P (insn) && INSN_LUID (insn) > 0) - { - /* Clear resolved back deps together with its dep_nodes. */ - delete_dep_nodes_in_back_deps (insn, resolved_p); - - sd_finish_insn (insn); - } -} - -/* Initialize variables for region data dependence analysis. - When LAZY_REG_LAST is true, do not allocate reg_last array - of class deps_desc immediately. */ - -void -init_deps (class deps_desc *deps, bool lazy_reg_last) -{ - int max_reg = (reload_completed ? FIRST_PSEUDO_REGISTER : max_reg_num ()); - - deps->max_reg = max_reg; - if (lazy_reg_last) - deps->reg_last = NULL; - else - deps->reg_last = XCNEWVEC (struct deps_reg, max_reg); - INIT_REG_SET (&deps->reg_last_in_use); - - deps->pending_read_insns = 0; - deps->pending_read_mems = 0; - deps->pending_write_insns = 0; - deps->pending_write_mems = 0; - deps->pending_jump_insns = 0; - deps->pending_read_list_length = 0; - deps->pending_write_list_length = 0; - deps->pending_flush_length = 0; - deps->last_pending_memory_flush = 0; - deps->last_function_call = 0; - deps->last_function_call_may_noreturn = 0; - deps->sched_before_next_call = 0; - deps->sched_before_next_jump = 0; - deps->in_post_call_group_p = not_post_call; - deps->last_debug_insn = 0; - deps->last_args_size = 0; - deps->last_prologue = 0; - deps->last_epilogue = 0; - deps->last_logue_was_epilogue = false; - deps->last_reg_pending_barrier = NOT_A_BARRIER; - deps->readonly = 0; -} - -/* Init only reg_last field of DEPS, which was not allocated before as - we inited DEPS lazily. */ -void -init_deps_reg_last (class deps_desc *deps) -{ - gcc_assert (deps && deps->max_reg > 0); - gcc_assert (deps->reg_last == NULL); - - deps->reg_last = XCNEWVEC (struct deps_reg, deps->max_reg); -} - - -/* Free insn lists found in DEPS. */ - -void -free_deps (class deps_desc *deps) -{ - unsigned i; - reg_set_iterator rsi; - - /* We set max_reg to 0 when this context was already freed. */ - if (deps->max_reg == 0) - { - gcc_assert (deps->reg_last == NULL); - return; - } - deps->max_reg = 0; - - free_INSN_LIST_list (&deps->pending_read_insns); - free_EXPR_LIST_list (&deps->pending_read_mems); - free_INSN_LIST_list (&deps->pending_write_insns); - free_EXPR_LIST_list (&deps->pending_write_mems); - free_INSN_LIST_list (&deps->last_pending_memory_flush); - - /* Without the EXECUTE_IF_SET, this loop is executed max_reg * nr_regions - times. For a testcase with 42000 regs and 8000 small basic blocks, - this loop accounted for nearly 60% (84 sec) of the total -O2 runtime. */ - EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi) - { - struct deps_reg *reg_last = &deps->reg_last[i]; - if (reg_last->uses) - free_INSN_LIST_list (®_last->uses); - if (reg_last->sets) - free_INSN_LIST_list (®_last->sets); - if (reg_last->implicit_sets) - free_INSN_LIST_list (®_last->implicit_sets); - if (reg_last->control_uses) - free_INSN_LIST_list (®_last->control_uses); - if (reg_last->clobbers) - free_INSN_LIST_list (®_last->clobbers); - } - CLEAR_REG_SET (&deps->reg_last_in_use); - - /* As we initialize reg_last lazily, it is possible that we didn't allocate - it at all. */ - free (deps->reg_last); - deps->reg_last = NULL; - - deps = NULL; -} - -/* Remove INSN from dependence contexts DEPS. */ -void -remove_from_deps (class deps_desc *deps, rtx_insn *insn) -{ - int removed; - unsigned i; - reg_set_iterator rsi; - - removed = remove_from_both_dependence_lists (insn, &deps->pending_read_insns, - &deps->pending_read_mems); - if (!DEBUG_INSN_P (insn)) - deps->pending_read_list_length -= removed; - removed = remove_from_both_dependence_lists (insn, &deps->pending_write_insns, - &deps->pending_write_mems); - deps->pending_write_list_length -= removed; - - removed = remove_from_dependence_list (insn, &deps->pending_jump_insns); - deps->pending_flush_length -= removed; - removed = remove_from_dependence_list (insn, &deps->last_pending_memory_flush); - deps->pending_flush_length -= removed; - - unsigned to_clear = -1U; - EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i, rsi) - { - if (to_clear != -1U) - { - CLEAR_REGNO_REG_SET (&deps->reg_last_in_use, to_clear); - to_clear = -1U; - } - struct deps_reg *reg_last = &deps->reg_last[i]; - if (reg_last->uses) - remove_from_dependence_list (insn, ®_last->uses); - if (reg_last->sets) - remove_from_dependence_list (insn, ®_last->sets); - if (reg_last->implicit_sets) - remove_from_dependence_list (insn, ®_last->implicit_sets); - if (reg_last->clobbers) - remove_from_dependence_list (insn, ®_last->clobbers); - if (!reg_last->uses && !reg_last->sets && !reg_last->implicit_sets - && !reg_last->clobbers) - to_clear = i; - } - if (to_clear != -1U) - CLEAR_REGNO_REG_SET (&deps->reg_last_in_use, to_clear); - - if (CALL_P (insn)) - { - remove_from_dependence_list (insn, &deps->last_function_call); - remove_from_dependence_list (insn, - &deps->last_function_call_may_noreturn); - } - remove_from_dependence_list (insn, &deps->sched_before_next_call); -} - -/* Init deps data vector. */ -static void -init_deps_data_vector (void) -{ - int reserve = (sched_max_luid + 1 - h_d_i_d.length ()); - if (reserve > 0 && ! h_d_i_d.space (reserve)) - h_d_i_d.safe_grow_cleared (3 * sched_max_luid / 2, true); -} - -/* If it is profitable to use them, initialize or extend (depending on - GLOBAL_P) dependency data. */ -void -sched_deps_init (bool global_p) -{ - /* Average number of insns in the basic block. - '+ 1' is used to make it nonzero. */ - int insns_in_block = sched_max_luid / n_basic_blocks_for_fn (cfun) + 1; - - init_deps_data_vector (); - - /* We use another caching mechanism for selective scheduling, so - we don't use this one. */ - if (!sel_sched_p () && global_p && insns_in_block > 100 * 5) - { - /* ?!? We could save some memory by computing a per-region luid mapping - which could reduce both the number of vectors in the cache and the - size of each vector. Instead we just avoid the cache entirely unless - the average number of instructions in a basic block is very high. See - the comment before the declaration of true_dependency_cache for - what we consider "very high". */ - cache_size = 0; - extend_dependency_caches (sched_max_luid, true); - } - - if (global_p) - { - dl_pool = new object_allocator<_deps_list> ("deps_list"); - /* Allocate lists for one block at a time. */ - dn_pool = new object_allocator<_dep_node> ("dep_node"); - /* Allocate nodes for one block at a time. */ - } -} - - -/* Create or extend (depending on CREATE_P) dependency caches to - size N. */ -void -extend_dependency_caches (int n, bool create_p) -{ - if (create_p || true_dependency_cache) - { - int i, luid = cache_size + n; - - true_dependency_cache = XRESIZEVEC (bitmap_head, true_dependency_cache, - luid); - output_dependency_cache = XRESIZEVEC (bitmap_head, - output_dependency_cache, luid); - anti_dependency_cache = XRESIZEVEC (bitmap_head, anti_dependency_cache, - luid); - control_dependency_cache = XRESIZEVEC (bitmap_head, control_dependency_cache, - luid); - - if (current_sched_info->flags & DO_SPECULATION) - spec_dependency_cache = XRESIZEVEC (bitmap_head, spec_dependency_cache, - luid); - - for (i = cache_size; i < luid; i++) - { - bitmap_initialize (&true_dependency_cache[i], 0); - bitmap_initialize (&output_dependency_cache[i], 0); - bitmap_initialize (&anti_dependency_cache[i], 0); - bitmap_initialize (&control_dependency_cache[i], 0); - - if (current_sched_info->flags & DO_SPECULATION) - bitmap_initialize (&spec_dependency_cache[i], 0); - } - cache_size = luid; - } -} - -/* Finalize dependency information for the whole function. */ -void -sched_deps_finish (void) -{ - gcc_assert (deps_pools_are_empty_p ()); - delete dn_pool; - delete dl_pool; - dn_pool = NULL; - dl_pool = NULL; - - h_d_i_d.release (); - cache_size = 0; - - if (true_dependency_cache) - { - int i; - - for (i = 0; i < cache_size; i++) - { - bitmap_clear (&true_dependency_cache[i]); - bitmap_clear (&output_dependency_cache[i]); - bitmap_clear (&anti_dependency_cache[i]); - bitmap_clear (&control_dependency_cache[i]); - - if (sched_deps_info->generate_spec_deps) - bitmap_clear (&spec_dependency_cache[i]); - } - free (true_dependency_cache); - true_dependency_cache = NULL; - free (output_dependency_cache); - output_dependency_cache = NULL; - free (anti_dependency_cache); - anti_dependency_cache = NULL; - free (control_dependency_cache); - control_dependency_cache = NULL; - - if (sched_deps_info->generate_spec_deps) - { - free (spec_dependency_cache); - spec_dependency_cache = NULL; - } - - } -} - -/* Initialize some global variables needed by the dependency analysis - code. */ - -void -init_deps_global (void) -{ - CLEAR_HARD_REG_SET (implicit_reg_pending_clobbers); - CLEAR_HARD_REG_SET (implicit_reg_pending_uses); - reg_pending_sets = ALLOC_REG_SET (®_obstack); - reg_pending_clobbers = ALLOC_REG_SET (®_obstack); - reg_pending_uses = ALLOC_REG_SET (®_obstack); - reg_pending_control_uses = ALLOC_REG_SET (®_obstack); - reg_pending_barrier = NOT_A_BARRIER; - - if (!sel_sched_p () || sched_emulate_haifa_p) - { - sched_deps_info->start_insn = haifa_start_insn; - sched_deps_info->finish_insn = haifa_finish_insn; - - sched_deps_info->note_reg_set = haifa_note_reg_set; - sched_deps_info->note_reg_clobber = haifa_note_reg_clobber; - sched_deps_info->note_reg_use = haifa_note_reg_use; - - sched_deps_info->note_mem_dep = haifa_note_mem_dep; - sched_deps_info->note_dep = haifa_note_dep; - } -} - -/* Free everything used by the dependency analysis code. */ - -void -finish_deps_global (void) -{ - FREE_REG_SET (reg_pending_sets); - FREE_REG_SET (reg_pending_clobbers); - FREE_REG_SET (reg_pending_uses); - FREE_REG_SET (reg_pending_control_uses); -} - -/* Estimate the weakness of dependence between MEM1 and MEM2. */ -dw_t -estimate_dep_weak (rtx mem1, rtx mem2) -{ - if (mem1 == mem2) - /* MEMs are the same - don't speculate. */ - return MIN_DEP_WEAK; - - rtx r1 = XEXP (mem1, 0); - rtx r2 = XEXP (mem2, 0); - - if (sched_deps_info->use_cselib) - { - /* We cannot call rtx_equal_for_cselib_p because the VALUEs might be - dangling at this point, since we never preserve them. Instead we - canonicalize manually to get stable VALUEs out of hashing. */ - if (GET_CODE (r1) == VALUE && CSELIB_VAL_PTR (r1)) - r1 = canonical_cselib_val (CSELIB_VAL_PTR (r1))->val_rtx; - if (GET_CODE (r2) == VALUE && CSELIB_VAL_PTR (r2)) - r2 = canonical_cselib_val (CSELIB_VAL_PTR (r2))->val_rtx; - } - - if (r1 == r2 - || (REG_P (r1) && REG_P (r2) && REGNO (r1) == REGNO (r2))) - /* Again, MEMs are the same. */ - return MIN_DEP_WEAK; - else if ((REG_P (r1) && !REG_P (r2)) || (!REG_P (r1) && REG_P (r2))) - /* Different addressing modes - reason to be more speculative, - than usual. */ - return NO_DEP_WEAK - (NO_DEP_WEAK - UNCERTAIN_DEP_WEAK) / 2; - else - /* We can't say anything about the dependence. */ - return UNCERTAIN_DEP_WEAK; -} - -/* Add or update backward dependence between INSN and ELEM with type DEP_TYPE. - This function can handle same INSN and ELEM (INSN == ELEM). - It is a convenience wrapper. */ -static void -add_dependence_1 (rtx_insn *insn, rtx_insn *elem, enum reg_note dep_type) -{ - ds_t ds; - bool internal; - - if (dep_type == REG_DEP_TRUE) - ds = DEP_TRUE; - else if (dep_type == REG_DEP_OUTPUT) - ds = DEP_OUTPUT; - else if (dep_type == REG_DEP_CONTROL) - ds = DEP_CONTROL; - else - { - gcc_assert (dep_type == REG_DEP_ANTI); - ds = DEP_ANTI; - } - - /* When add_dependence is called from inside sched-deps.c, we expect - cur_insn to be non-null. */ - internal = cur_insn != NULL; - if (internal) - gcc_assert (insn == cur_insn); - else - cur_insn = insn; - - note_dep (elem, ds); - if (!internal) - cur_insn = NULL; -} - -/* Return weakness of speculative type TYPE in the dep_status DS, - without checking to prevent ICEs on malformed input. */ -static dw_t -get_dep_weak_1 (ds_t ds, ds_t type) -{ - ds = ds & type; - - switch (type) - { - case BEGIN_DATA: ds >>= BEGIN_DATA_BITS_OFFSET; break; - case BE_IN_DATA: ds >>= BE_IN_DATA_BITS_OFFSET; break; - case BEGIN_CONTROL: ds >>= BEGIN_CONTROL_BITS_OFFSET; break; - case BE_IN_CONTROL: ds >>= BE_IN_CONTROL_BITS_OFFSET; break; - default: gcc_unreachable (); - } - - return (dw_t) ds; -} - -/* Return weakness of speculative type TYPE in the dep_status DS. */ -dw_t -get_dep_weak (ds_t ds, ds_t type) -{ - dw_t dw = get_dep_weak_1 (ds, type); - - gcc_assert (MIN_DEP_WEAK <= dw && dw <= MAX_DEP_WEAK); - return dw; -} - -/* Return the dep_status, which has the same parameters as DS, except for - speculative type TYPE, that will have weakness DW. */ -ds_t -set_dep_weak (ds_t ds, ds_t type, dw_t dw) -{ - gcc_assert (MIN_DEP_WEAK <= dw && dw <= MAX_DEP_WEAK); - - ds &= ~type; - switch (type) - { - case BEGIN_DATA: ds |= ((ds_t) dw) << BEGIN_DATA_BITS_OFFSET; break; - case BE_IN_DATA: ds |= ((ds_t) dw) << BE_IN_DATA_BITS_OFFSET; break; - case BEGIN_CONTROL: ds |= ((ds_t) dw) << BEGIN_CONTROL_BITS_OFFSET; break; - case BE_IN_CONTROL: ds |= ((ds_t) dw) << BE_IN_CONTROL_BITS_OFFSET; break; - default: gcc_unreachable (); - } - return ds; -} - -/* Return the join of two dep_statuses DS1 and DS2. - If MAX_P is true then choose the greater probability, - otherwise multiply probabilities. - This function assumes that both DS1 and DS2 contain speculative bits. */ -static ds_t -ds_merge_1 (ds_t ds1, ds_t ds2, bool max_p) -{ - ds_t ds, t; - - gcc_assert ((ds1 & SPECULATIVE) && (ds2 & SPECULATIVE)); - - ds = (ds1 & DEP_TYPES) | (ds2 & DEP_TYPES); - - t = FIRST_SPEC_TYPE; - do - { - if ((ds1 & t) && !(ds2 & t)) - ds |= ds1 & t; - else if (!(ds1 & t) && (ds2 & t)) - ds |= ds2 & t; - else if ((ds1 & t) && (ds2 & t)) - { - dw_t dw1 = get_dep_weak (ds1, t); - dw_t dw2 = get_dep_weak (ds2, t); - ds_t dw; - - if (!max_p) - { - dw = ((ds_t) dw1) * ((ds_t) dw2); - dw /= MAX_DEP_WEAK; - if (dw < MIN_DEP_WEAK) - dw = MIN_DEP_WEAK; - } - else - { - if (dw1 >= dw2) - dw = dw1; - else - dw = dw2; - } - - ds = set_dep_weak (ds, t, (dw_t) dw); - } - - if (t == LAST_SPEC_TYPE) - break; - t <<= SPEC_TYPE_SHIFT; - } - while (1); - - return ds; -} - -/* Return the join of two dep_statuses DS1 and DS2. - This function assumes that both DS1 and DS2 contain speculative bits. */ -ds_t -ds_merge (ds_t ds1, ds_t ds2) -{ - return ds_merge_1 (ds1, ds2, false); -} - -/* Return the join of two dep_statuses DS1 and DS2. */ -ds_t -ds_full_merge (ds_t ds, ds_t ds2, rtx mem1, rtx mem2) -{ - ds_t new_status = ds | ds2; - - if (new_status & SPECULATIVE) - { - if ((ds && !(ds & SPECULATIVE)) - || (ds2 && !(ds2 & SPECULATIVE))) - /* Then this dep can't be speculative. */ - new_status &= ~SPECULATIVE; - else - { - /* Both are speculative. Merging probabilities. */ - if (mem1) - { - dw_t dw; - - dw = estimate_dep_weak (mem1, mem2); - ds = set_dep_weak (ds, BEGIN_DATA, dw); - } - - if (!ds) - new_status = ds2; - else if (!ds2) - new_status = ds; - else - new_status = ds_merge (ds2, ds); - } - } - - return new_status; -} - -/* Return the join of DS1 and DS2. Use maximum instead of multiplying - probabilities. */ -ds_t -ds_max_merge (ds_t ds1, ds_t ds2) -{ - if (ds1 == 0 && ds2 == 0) - return 0; - - if (ds1 == 0 && ds2 != 0) - return ds2; - - if (ds1 != 0 && ds2 == 0) - return ds1; - - return ds_merge_1 (ds1, ds2, true); -} - -/* Return the probability of speculation success for the speculation - status DS. */ -dw_t -ds_weak (ds_t ds) -{ - ds_t res = 1, dt; - int n = 0; - - dt = FIRST_SPEC_TYPE; - do - { - if (ds & dt) - { - res *= (ds_t) get_dep_weak (ds, dt); - n++; - } - - if (dt == LAST_SPEC_TYPE) - break; - dt <<= SPEC_TYPE_SHIFT; - } - while (1); - - gcc_assert (n); - while (--n) - res /= MAX_DEP_WEAK; - - if (res < MIN_DEP_WEAK) - res = MIN_DEP_WEAK; - - gcc_assert (res <= MAX_DEP_WEAK); - - return (dw_t) res; -} - -/* Return a dep status that contains all speculation types of DS. */ -ds_t -ds_get_speculation_types (ds_t ds) -{ - if (ds & BEGIN_DATA) - ds |= BEGIN_DATA; - if (ds & BE_IN_DATA) - ds |= BE_IN_DATA; - if (ds & BEGIN_CONTROL) - ds |= BEGIN_CONTROL; - if (ds & BE_IN_CONTROL) - ds |= BE_IN_CONTROL; - - return ds & SPECULATIVE; -} - -/* Return a dep status that contains maximal weakness for each speculation - type present in DS. */ -ds_t -ds_get_max_dep_weak (ds_t ds) -{ - if (ds & BEGIN_DATA) - ds = set_dep_weak (ds, BEGIN_DATA, MAX_DEP_WEAK); - if (ds & BE_IN_DATA) - ds = set_dep_weak (ds, BE_IN_DATA, MAX_DEP_WEAK); - if (ds & BEGIN_CONTROL) - ds = set_dep_weak (ds, BEGIN_CONTROL, MAX_DEP_WEAK); - if (ds & BE_IN_CONTROL) - ds = set_dep_weak (ds, BE_IN_CONTROL, MAX_DEP_WEAK); - - return ds; -} - -/* Dump information about the dependence status S. */ -static void -dump_ds (FILE *f, ds_t s) -{ - fprintf (f, "{"); - - if (s & BEGIN_DATA) - fprintf (f, "BEGIN_DATA: %d; ", get_dep_weak_1 (s, BEGIN_DATA)); - if (s & BE_IN_DATA) - fprintf (f, "BE_IN_DATA: %d; ", get_dep_weak_1 (s, BE_IN_DATA)); - if (s & BEGIN_CONTROL) - fprintf (f, "BEGIN_CONTROL: %d; ", get_dep_weak_1 (s, BEGIN_CONTROL)); - if (s & BE_IN_CONTROL) - fprintf (f, "BE_IN_CONTROL: %d; ", get_dep_weak_1 (s, BE_IN_CONTROL)); - - if (s & HARD_DEP) - fprintf (f, "HARD_DEP; "); - - if (s & DEP_TRUE) - fprintf (f, "DEP_TRUE; "); - if (s & DEP_OUTPUT) - fprintf (f, "DEP_OUTPUT; "); - if (s & DEP_ANTI) - fprintf (f, "DEP_ANTI; "); - if (s & DEP_CONTROL) - fprintf (f, "DEP_CONTROL; "); - - fprintf (f, "}"); -} - -DEBUG_FUNCTION void -debug_ds (ds_t s) -{ - dump_ds (stderr, s); - fprintf (stderr, "\n"); -} - -/* Verify that dependence type and status are consistent. - If RELAXED_P is true, then skip dep_weakness checks. */ -static void -check_dep (dep_t dep, bool relaxed_p) -{ - enum reg_note dt = DEP_TYPE (dep); - ds_t ds = DEP_STATUS (dep); - - gcc_assert (DEP_PRO (dep) != DEP_CON (dep)); - - if (!(current_sched_info->flags & USE_DEPS_LIST)) - { - gcc_assert (ds == 0); - return; - } - - /* Check that dependence type contains the same bits as the status. */ - if (dt == REG_DEP_TRUE) - gcc_assert (ds & DEP_TRUE); - else if (dt == REG_DEP_OUTPUT) - gcc_assert ((ds & DEP_OUTPUT) - && !(ds & DEP_TRUE)); - else if (dt == REG_DEP_ANTI) - gcc_assert ((ds & DEP_ANTI) - && !(ds & (DEP_OUTPUT | DEP_TRUE))); - else - gcc_assert (dt == REG_DEP_CONTROL - && (ds & DEP_CONTROL) - && !(ds & (DEP_OUTPUT | DEP_ANTI | DEP_TRUE))); - - /* HARD_DEP cannot appear in dep_status of a link. */ - gcc_assert (!(ds & HARD_DEP)); - - /* Check that dependence status is set correctly when speculation is not - supported. */ - if (!sched_deps_info->generate_spec_deps) - gcc_assert (!(ds & SPECULATIVE)); - else if (ds & SPECULATIVE) - { - if (!relaxed_p) - { - ds_t type = FIRST_SPEC_TYPE; - - /* Check that dependence weakness is in proper range. */ - do - { - if (ds & type) - get_dep_weak (ds, type); - - if (type == LAST_SPEC_TYPE) - break; - type <<= SPEC_TYPE_SHIFT; - } - while (1); - } - - if (ds & BEGIN_SPEC) - { - /* Only true dependence can be data speculative. */ - if (ds & BEGIN_DATA) - gcc_assert (ds & DEP_TRUE); - - /* Control dependencies in the insn scheduler are represented by - anti-dependencies, therefore only anti dependence can be - control speculative. */ - if (ds & BEGIN_CONTROL) - gcc_assert (ds & DEP_ANTI); - } - else - { - /* Subsequent speculations should resolve true dependencies. */ - gcc_assert ((ds & DEP_TYPES) == DEP_TRUE); - } - - /* Check that true and anti dependencies can't have other speculative - statuses. */ - if (ds & DEP_TRUE) - gcc_assert (ds & (BEGIN_DATA | BE_IN_SPEC)); - /* An output dependence can't be speculative at all. */ - gcc_assert (!(ds & DEP_OUTPUT)); - if (ds & DEP_ANTI) - gcc_assert (ds & BEGIN_CONTROL); - } -} - -/* The following code discovers opportunities to switch a memory reference - and an increment by modifying the address. We ensure that this is done - only for dependencies that are only used to show a single register - dependence (using DEP_NONREG and DEP_MULTIPLE), and so that every memory - instruction involved is subject to only one dep that can cause a pattern - change. - - When we discover a suitable dependency, we fill in the dep_replacement - structure to show how to modify the memory reference. */ - -/* Holds information about a pair of memory reference and register increment - insns which depend on each other, but could possibly be interchanged. */ -struct mem_inc_info -{ - rtx_insn *inc_insn; - rtx_insn *mem_insn; - - rtx *mem_loc; - /* A register occurring in the memory address for which we wish to break - the dependence. This must be identical to the destination register of - the increment. */ - rtx mem_reg0; - /* Any kind of index that is added to that register. */ - rtx mem_index; - /* The constant offset used in the memory address. */ - HOST_WIDE_INT mem_constant; - /* The constant added in the increment insn. Negated if the increment is - after the memory address. */ - HOST_WIDE_INT inc_constant; - /* The source register used in the increment. May be different from mem_reg0 - if the increment occurs before the memory address. */ - rtx inc_input; -}; - -/* Verify that the memory location described in MII can be replaced with - one using NEW_ADDR. Return the new memory reference or NULL_RTX. The - insn remains unchanged by this function. */ - -static rtx -attempt_change (struct mem_inc_info *mii, rtx new_addr) -{ - rtx mem = *mii->mem_loc; - rtx new_mem; - - if (!targetm.new_address_profitable_p (mem, mii->mem_insn, new_addr)) - return NULL_RTX; - - /* Jump through a lot of hoops to keep the attributes up to date. We - do not want to call one of the change address variants that take - an offset even though we know the offset in many cases. These - assume you are changing where the address is pointing by the - offset. */ - new_mem = replace_equiv_address_nv (mem, new_addr); - if (! validate_change (mii->mem_insn, mii->mem_loc, new_mem, 0)) - { - if (sched_verbose >= 5) - fprintf (sched_dump, "validation failure\n"); - return NULL_RTX; - } - - /* Put back the old one. */ - validate_change (mii->mem_insn, mii->mem_loc, mem, 0); - - return new_mem; -} - -/* Return true if INSN is of a form "a = b op c" where a and b are - regs. op is + if c is a reg and +|- if c is a const. Fill in - informantion in MII about what is found. - BEFORE_MEM indicates whether the increment is found before or after - a corresponding memory reference. */ - -static bool -parse_add_or_inc (struct mem_inc_info *mii, rtx_insn *insn, bool before_mem) -{ - rtx pat = single_set (insn); - rtx src, cst; - bool regs_equal; - - if (RTX_FRAME_RELATED_P (insn) || !pat) - return false; - - /* Do not allow breaking data dependencies for insns that are marked - with REG_STACK_CHECK. */ - if (find_reg_note (insn, REG_STACK_CHECK, NULL)) - return false; - - /* Result must be single reg. */ - if (!REG_P (SET_DEST (pat))) - return false; - - if (GET_CODE (SET_SRC (pat)) != PLUS) - return false; - - mii->inc_insn = insn; - src = SET_SRC (pat); - mii->inc_input = XEXP (src, 0); - - if (!REG_P (XEXP (src, 0))) - return false; - - if (!rtx_equal_p (SET_DEST (pat), mii->mem_reg0)) - return false; - - cst = XEXP (src, 1); - if (!CONST_INT_P (cst)) - return false; - mii->inc_constant = INTVAL (cst); - - regs_equal = rtx_equal_p (mii->inc_input, mii->mem_reg0); - - if (!before_mem) - { - mii->inc_constant = -mii->inc_constant; - if (!regs_equal) - return false; - } - - if (regs_equal && REGNO (SET_DEST (pat)) == STACK_POINTER_REGNUM) - { - /* Note that the sign has already been reversed for !before_mem. */ - if (STACK_GROWS_DOWNWARD) - return mii->inc_constant > 0; - else - return mii->inc_constant < 0; - } - return true; -} - -/* Once a suitable mem reference has been found and the corresponding data - in MII has been filled in, this function is called to find a suitable - add or inc insn involving the register we found in the memory - reference. */ - -static bool -find_inc (struct mem_inc_info *mii, bool backwards) -{ - sd_iterator_def sd_it; - dep_t dep; - - sd_it = sd_iterator_start (mii->mem_insn, - backwards ? SD_LIST_HARD_BACK : SD_LIST_FORW); - while (sd_iterator_cond (&sd_it, &dep)) - { - dep_node_t node = DEP_LINK_NODE (*sd_it.linkp); - rtx_insn *pro = DEP_PRO (dep); - rtx_insn *con = DEP_CON (dep); - rtx_insn *inc_cand = backwards ? pro : con; - if (DEP_NONREG (dep) || DEP_MULTIPLE (dep)) - goto next; - if (parse_add_or_inc (mii, inc_cand, backwards)) - { - struct dep_replacement *desc; - df_ref def; - rtx newaddr, newmem; - - if (sched_verbose >= 5) - fprintf (sched_dump, "candidate mem/inc pair: %d %d\n", - INSN_UID (mii->mem_insn), INSN_UID (inc_cand)); - - /* Need to assure that none of the operands of the inc - instruction are assigned to by the mem insn. */ - FOR_EACH_INSN_DEF (def, mii->mem_insn) - if (reg_overlap_mentioned_p (DF_REF_REG (def), mii->inc_input) - || reg_overlap_mentioned_p (DF_REF_REG (def), mii->mem_reg0)) - { - if (sched_verbose >= 5) - fprintf (sched_dump, - "inc conflicts with store failure.\n"); - goto next; - } - - newaddr = mii->inc_input; - if (mii->mem_index != NULL_RTX) - newaddr = gen_rtx_PLUS (GET_MODE (newaddr), newaddr, - mii->mem_index); - newaddr = plus_constant (GET_MODE (newaddr), newaddr, - mii->mem_constant + mii->inc_constant); - newmem = attempt_change (mii, newaddr); - if (newmem == NULL_RTX) - goto next; - if (sched_verbose >= 5) - fprintf (sched_dump, "successful address replacement\n"); - desc = XCNEW (struct dep_replacement); - DEP_REPLACE (dep) = desc; - desc->loc = mii->mem_loc; - desc->newval = newmem; - desc->orig = *desc->loc; - desc->insn = mii->mem_insn; - move_dep_link (DEP_NODE_BACK (node), INSN_HARD_BACK_DEPS (con), - INSN_SPEC_BACK_DEPS (con)); - if (backwards) - { - FOR_EACH_DEP (mii->inc_insn, SD_LIST_BACK, sd_it, dep) - add_dependence_1 (mii->mem_insn, DEP_PRO (dep), - REG_DEP_TRUE); - } - else - { - FOR_EACH_DEP (mii->inc_insn, SD_LIST_FORW, sd_it, dep) - add_dependence_1 (DEP_CON (dep), mii->mem_insn, - REG_DEP_ANTI); - } - return true; - } - next: - sd_iterator_next (&sd_it); - } - return false; -} - -/* A recursive function that walks ADDRESS_OF_X to find memory references - which could be modified during scheduling. We call find_inc for each - one we find that has a recognizable form. MII holds information about - the pair of memory/increment instructions. - We ensure that every instruction with a memory reference (which will be - the location of the replacement) is assigned at most one breakable - dependency. */ - -static bool -find_mem (struct mem_inc_info *mii, rtx *address_of_x) -{ - rtx x = *address_of_x; - enum rtx_code code = GET_CODE (x); - const char *const fmt = GET_RTX_FORMAT (code); - int i; - - if (code == MEM) - { - rtx reg0 = XEXP (x, 0); - - mii->mem_loc = address_of_x; - mii->mem_index = NULL_RTX; - mii->mem_constant = 0; - if (GET_CODE (reg0) == PLUS && CONST_INT_P (XEXP (reg0, 1))) - { - mii->mem_constant = INTVAL (XEXP (reg0, 1)); - reg0 = XEXP (reg0, 0); - } - if (GET_CODE (reg0) == PLUS) - { - mii->mem_index = XEXP (reg0, 1); - reg0 = XEXP (reg0, 0); - } - if (REG_P (reg0)) - { - df_ref use; - int occurrences = 0; - - /* Make sure this reg appears only once in this insn. Can't use - count_occurrences since that only works for pseudos. */ - FOR_EACH_INSN_USE (use, mii->mem_insn) - if (reg_overlap_mentioned_p (reg0, DF_REF_REG (use))) - if (++occurrences > 1) - { - if (sched_verbose >= 5) - fprintf (sched_dump, "mem count failure\n"); - return false; - } - - mii->mem_reg0 = reg0; - return find_inc (mii, true) || find_inc (mii, false); - } - return false; - } - - if (code == SIGN_EXTRACT || code == ZERO_EXTRACT) - { - /* If REG occurs inside a MEM used in a bit-field reference, - that is unacceptable. */ - return false; - } - - /* Time for some deep diving. */ - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - { - if (find_mem (mii, &XEXP (x, i))) - return true; - } - else if (fmt[i] == 'E') - { - int j; - for (j = XVECLEN (x, i) - 1; j >= 0; j--) - if (find_mem (mii, &XVECEXP (x, i, j))) - return true; - } - } - return false; -} - - -/* Examine the instructions between HEAD and TAIL and try to find - dependencies that can be broken by modifying one of the patterns. */ - -void -find_modifiable_mems (rtx_insn *head, rtx_insn *tail) -{ - rtx_insn *insn, *next_tail = NEXT_INSN (tail); - int success_in_block = 0; - - for (insn = head; insn != next_tail; insn = NEXT_INSN (insn)) - { - struct mem_inc_info mii; - - if (!NONDEBUG_INSN_P (insn) || RTX_FRAME_RELATED_P (insn)) - continue; - - mii.mem_insn = insn; - if (find_mem (&mii, &PATTERN (insn))) - success_in_block++; - } - if (success_in_block && sched_verbose >= 5) - fprintf (sched_dump, "%d candidates for address modification found.\n", - success_in_block); -} - -#endif /* INSN_SCHEDULING */ |