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/alias.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/alias.c')
-rw-r--r-- | gcc/alias.c | 3584 |
1 files changed, 0 insertions, 3584 deletions
diff --git a/gcc/alias.c b/gcc/alias.c deleted file mode 100644 index 3fd71cf..0000000 --- a/gcc/alias.c +++ /dev/null @@ -1,3584 +0,0 @@ -/* Alias analysis for GNU C - Copyright (C) 1997-2022 Free Software Foundation, Inc. - Contributed by John Carr (jfc@mit.edu). - -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 "gimple.h" -#include "df.h" -#include "memmodel.h" -#include "tm_p.h" -#include "gimple-ssa.h" -#include "emit-rtl.h" -#include "alias.h" -#include "fold-const.h" -#include "varasm.h" -#include "cselib.h" -#include "langhooks.h" -#include "cfganal.h" -#include "rtl-iter.h" -#include "cgraph.h" -#include "ipa-utils.h" - -/* The aliasing API provided here solves related but different problems: - - Say there exists (in c) - - struct X { - struct Y y1; - struct Z z2; - } x1, *px1, *px2; - - struct Y y2, *py; - struct Z z2, *pz; - - - py = &x1.y1; - px2 = &x1; - - Consider the four questions: - - Can a store to x1 interfere with px2->y1? - Can a store to x1 interfere with px2->z2? - Can a store to x1 change the value pointed to by with py? - Can a store to x1 change the value pointed to by with pz? - - The answer to these questions can be yes, yes, yes, and maybe. - - The first two questions can be answered with a simple examination - of the type system. If structure X contains a field of type Y then - a store through a pointer to an X can overwrite any field that is - contained (recursively) in an X (unless we know that px1 != px2). - - The last two questions can be solved in the same way as the first - two questions but this is too conservative. The observation is - that in some cases we can know which (if any) fields are addressed - and if those addresses are used in bad ways. This analysis may be - language specific. In C, arbitrary operations may be applied to - pointers. However, there is some indication that this may be too - conservative for some C++ types. - - The pass ipa-type-escape does this analysis for the types whose - instances do not escape across the compilation boundary. - - Historically in GCC, these two problems were combined and a single - data structure that was used to represent the solution to these - problems. We now have two similar but different data structures, - The data structure to solve the last two questions is similar to - the first, but does not contain the fields whose address are never - taken. For types that do escape the compilation unit, the data - structures will have identical information. -*/ - -/* The alias sets assigned to MEMs assist the back-end in determining - which MEMs can alias which other MEMs. In general, two MEMs in - different alias sets cannot alias each other, with one important - exception. Consider something like: - - struct S { int i; double d; }; - - a store to an `S' can alias something of either type `int' or type - `double'. (However, a store to an `int' cannot alias a `double' - and vice versa.) We indicate this via a tree structure that looks - like: - struct S - / \ - / \ - |/_ _\| - int double - - (The arrows are directed and point downwards.) - In this situation we say the alias set for `struct S' is the - `superset' and that those for `int' and `double' are `subsets'. - - To see whether two alias sets can point to the same memory, we must - see if either alias set is a subset of the other. We need not trace - past immediate descendants, however, since we propagate all - grandchildren up one level. - - Alias set zero is implicitly a superset of all other alias sets. - However, this is no actual entry for alias set zero. It is an - error to attempt to explicitly construct a subset of zero. */ - -struct alias_set_hash : int_hash <int, INT_MIN, INT_MIN + 1> {}; - -struct GTY(()) alias_set_entry { - /* The alias set number, as stored in MEM_ALIAS_SET. */ - alias_set_type alias_set; - - /* Nonzero if would have a child of zero: this effectively makes this - alias set the same as alias set zero. */ - bool has_zero_child; - /* Nonzero if alias set corresponds to pointer type itself (i.e. not to - aggregate contaiing pointer. - This is used for a special case where we need an universal pointer type - compatible with all other pointer types. */ - bool is_pointer; - /* Nonzero if is_pointer or if one of childs have has_pointer set. */ - bool has_pointer; - - /* The children of the alias set. These are not just the immediate - children, but, in fact, all descendants. So, if we have: - - struct T { struct S s; float f; } - - continuing our example above, the children here will be all of - `int', `double', `float', and `struct S'. */ - hash_map<alias_set_hash, int> *children; -}; - -static int rtx_equal_for_memref_p (const_rtx, const_rtx); -static void record_set (rtx, const_rtx, void *); -static int base_alias_check (rtx, rtx, rtx, rtx, machine_mode, - machine_mode); -static rtx find_base_value (rtx); -static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx); -static alias_set_entry *get_alias_set_entry (alias_set_type); -static tree decl_for_component_ref (tree); -static int write_dependence_p (const_rtx, - const_rtx, machine_mode, rtx, - bool, bool, bool); -static int compare_base_symbol_refs (const_rtx, const_rtx, - HOST_WIDE_INT * = NULL); - -static void memory_modified_1 (rtx, const_rtx, void *); - -/* Query statistics for the different low-level disambiguators. - A high-level query may trigger multiple of them. */ - -static struct { - unsigned long long num_alias_zero; - unsigned long long num_same_alias_set; - unsigned long long num_same_objects; - unsigned long long num_volatile; - unsigned long long num_dag; - unsigned long long num_universal; - unsigned long long num_disambiguated; -} alias_stats; - - -/* Set up all info needed to perform alias analysis on memory references. */ - -/* Returns the size in bytes of the mode of X. */ -#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) - -/* Cap the number of passes we make over the insns propagating alias - information through set chains. - ??? 10 is a completely arbitrary choice. This should be based on the - maximum loop depth in the CFG, but we do not have this information - available (even if current_loops _is_ available). */ -#define MAX_ALIAS_LOOP_PASSES 10 - -/* reg_base_value[N] gives an address to which register N is related. - If all sets after the first add or subtract to the current value - or otherwise modify it so it does not point to a different top level - object, reg_base_value[N] is equal to the address part of the source - of the first set. - - A base address can be an ADDRESS, SYMBOL_REF, or LABEL_REF. ADDRESS - expressions represent three types of base: - - 1. incoming arguments. There is just one ADDRESS to represent all - arguments, since we do not know at this level whether accesses - based on different arguments can alias. The ADDRESS has id 0. - - 2. stack_pointer_rtx, frame_pointer_rtx, hard_frame_pointer_rtx - (if distinct from frame_pointer_rtx) and arg_pointer_rtx. - Each of these rtxes has a separate ADDRESS associated with it, - each with a negative id. - - GCC is (and is required to be) precise in which register it - chooses to access a particular region of stack. We can therefore - assume that accesses based on one of these rtxes do not alias - accesses based on another of these rtxes. - - 3. bases that are derived from malloc()ed memory (REG_NOALIAS). - Each such piece of memory has a separate ADDRESS associated - with it, each with an id greater than 0. - - Accesses based on one ADDRESS do not alias accesses based on other - ADDRESSes. Accesses based on ADDRESSes in groups (2) and (3) do not - alias globals either; the ADDRESSes have Pmode to indicate this. - The ADDRESS in group (1) _may_ alias globals; it has VOIDmode to - indicate this. */ - -static GTY(()) vec<rtx, va_gc> *reg_base_value; -static rtx *new_reg_base_value; - -/* The single VOIDmode ADDRESS that represents all argument bases. - It has id 0. */ -static GTY(()) rtx arg_base_value; - -/* Used to allocate unique ids to each REG_NOALIAS ADDRESS. */ -static int unique_id; - -/* We preserve the copy of old array around to avoid amount of garbage - produced. About 8% of garbage produced were attributed to this - array. */ -static GTY((deletable)) vec<rtx, va_gc> *old_reg_base_value; - -/* Values of XINT (address, 0) of Pmode ADDRESS rtxes for special - registers. */ -#define UNIQUE_BASE_VALUE_SP -1 -#define UNIQUE_BASE_VALUE_ARGP -2 -#define UNIQUE_BASE_VALUE_FP -3 -#define UNIQUE_BASE_VALUE_HFP -4 - -#define static_reg_base_value \ - (this_target_rtl->x_static_reg_base_value) - -#define REG_BASE_VALUE(X) \ - (REGNO (X) < vec_safe_length (reg_base_value) \ - ? (*reg_base_value)[REGNO (X)] : 0) - -/* Vector indexed by N giving the initial (unchanging) value known for - pseudo-register N. This vector is initialized in init_alias_analysis, - and does not change until end_alias_analysis is called. */ -static GTY(()) vec<rtx, va_gc> *reg_known_value; - -/* Vector recording for each reg_known_value whether it is due to a - REG_EQUIV note. Future passes (viz., reload) may replace the - pseudo with the equivalent expression and so we account for the - dependences that would be introduced if that happens. - - The REG_EQUIV notes created in assign_parms may mention the arg - pointer, and there are explicit insns in the RTL that modify the - arg pointer. Thus we must ensure that such insns don't get - scheduled across each other because that would invalidate the - REG_EQUIV notes. One could argue that the REG_EQUIV notes are - wrong, but solving the problem in the scheduler will likely give - better code, so we do it here. */ -static sbitmap reg_known_equiv_p; - -/* True when scanning insns from the start of the rtl to the - NOTE_INSN_FUNCTION_BEG note. */ -static bool copying_arguments; - - -/* The splay-tree used to store the various alias set entries. */ -static GTY (()) vec<alias_set_entry *, va_gc> *alias_sets; - -/* Build a decomposed reference object for querying the alias-oracle - from the MEM rtx and store it in *REF. - Returns false if MEM is not suitable for the alias-oracle. */ - -static bool -ao_ref_from_mem (ao_ref *ref, const_rtx mem) -{ - tree expr = MEM_EXPR (mem); - tree base; - - if (!expr) - return false; - - ao_ref_init (ref, expr); - - /* Get the base of the reference and see if we have to reject or - adjust it. */ - base = ao_ref_base (ref); - if (base == NULL_TREE) - return false; - - /* The tree oracle doesn't like bases that are neither decls - nor indirect references of SSA names. */ - if (!(DECL_P (base) - || (TREE_CODE (base) == MEM_REF - && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME) - || (TREE_CODE (base) == TARGET_MEM_REF - && TREE_CODE (TMR_BASE (base)) == SSA_NAME))) - return false; - - ref->ref_alias_set = MEM_ALIAS_SET (mem); - - /* If MEM_OFFSET or MEM_SIZE are unknown what we got from MEM_EXPR - is conservative, so trust it. */ - if (!MEM_OFFSET_KNOWN_P (mem) - || !MEM_SIZE_KNOWN_P (mem)) - return true; - - /* If MEM_OFFSET/MEM_SIZE get us outside of ref->offset/ref->max_size - drop ref->ref. */ - if (maybe_lt (MEM_OFFSET (mem), 0) - || (ref->max_size_known_p () - && maybe_gt ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT, - ref->max_size))) - ref->ref = NULL_TREE; - - /* Refine size and offset we got from analyzing MEM_EXPR by using - MEM_SIZE and MEM_OFFSET. */ - - ref->offset += MEM_OFFSET (mem) * BITS_PER_UNIT; - ref->size = MEM_SIZE (mem) * BITS_PER_UNIT; - - /* The MEM may extend into adjacent fields, so adjust max_size if - necessary. */ - if (ref->max_size_known_p ()) - ref->max_size = upper_bound (ref->max_size, ref->size); - - /* If MEM_OFFSET and MEM_SIZE might get us outside of the base object of - the MEM_EXPR punt. This happens for STRICT_ALIGNMENT targets a lot. */ - if (MEM_EXPR (mem) != get_spill_slot_decl (false) - && (maybe_lt (ref->offset, 0) - || (DECL_P (ref->base) - && (DECL_SIZE (ref->base) == NULL_TREE - || !poly_int_tree_p (DECL_SIZE (ref->base)) - || maybe_lt (wi::to_poly_offset (DECL_SIZE (ref->base)), - ref->offset + ref->size))))) - return false; - - return true; -} - -/* Query the alias-oracle on whether the two memory rtx X and MEM may - alias. If TBAA_P is set also apply TBAA. Returns true if the - two rtxen may alias, false otherwise. */ - -static bool -rtx_refs_may_alias_p (const_rtx x, const_rtx mem, bool tbaa_p) -{ - ao_ref ref1, ref2; - - if (!ao_ref_from_mem (&ref1, x) - || !ao_ref_from_mem (&ref2, mem)) - return true; - - return refs_may_alias_p_1 (&ref1, &ref2, - tbaa_p - && MEM_ALIAS_SET (x) != 0 - && MEM_ALIAS_SET (mem) != 0); -} - -/* Return true if the ref EARLIER behaves the same as LATER with respect - to TBAA for every memory reference that might follow LATER. */ - -bool -refs_same_for_tbaa_p (tree earlier, tree later) -{ - ao_ref earlier_ref, later_ref; - ao_ref_init (&earlier_ref, earlier); - ao_ref_init (&later_ref, later); - alias_set_type earlier_set = ao_ref_alias_set (&earlier_ref); - alias_set_type later_set = ao_ref_alias_set (&later_ref); - if (!(earlier_set == later_set - || alias_set_subset_of (later_set, earlier_set))) - return false; - alias_set_type later_base_set = ao_ref_base_alias_set (&later_ref); - alias_set_type earlier_base_set = ao_ref_base_alias_set (&earlier_ref); - return (earlier_base_set == later_base_set - || alias_set_subset_of (later_base_set, earlier_base_set)); -} - -/* Returns a pointer to the alias set entry for ALIAS_SET, if there is - such an entry, or NULL otherwise. */ - -static inline alias_set_entry * -get_alias_set_entry (alias_set_type alias_set) -{ - return (*alias_sets)[alias_set]; -} - -/* Returns nonzero if the alias sets for MEM1 and MEM2 are such that - the two MEMs cannot alias each other. */ - -static inline int -mems_in_disjoint_alias_sets_p (const_rtx mem1, const_rtx mem2) -{ - return (flag_strict_aliasing - && ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), - MEM_ALIAS_SET (mem2))); -} - -/* Return true if the first alias set is a subset of the second. */ - -bool -alias_set_subset_of (alias_set_type set1, alias_set_type set2) -{ - alias_set_entry *ase2; - - /* Disable TBAA oracle with !flag_strict_aliasing. */ - if (!flag_strict_aliasing) - return true; - - /* Everything is a subset of the "aliases everything" set. */ - if (set2 == 0) - return true; - - /* Check if set1 is a subset of set2. */ - ase2 = get_alias_set_entry (set2); - if (ase2 != 0 - && (ase2->has_zero_child - || (ase2->children && ase2->children->get (set1)))) - return true; - - /* As a special case we consider alias set of "void *" to be both subset - and superset of every alias set of a pointer. This extra symmetry does - not matter for alias_sets_conflict_p but it makes aliasing_component_refs_p - to return true on the following testcase: - - void *ptr; - char **ptr2=(char **)&ptr; - *ptr2 = ... - - Additionally if a set contains universal pointer, we consider every pointer - to be a subset of it, but we do not represent this explicitely - doing so - would require us to update transitive closure each time we introduce new - pointer type. This makes aliasing_component_refs_p to return true - on the following testcase: - - struct a {void *ptr;} - char **ptr = (char **)&a.ptr; - ptr = ... - - This makes void * truly universal pointer type. See pointer handling in - get_alias_set for more details. */ - if (ase2 && ase2->has_pointer) - { - alias_set_entry *ase1 = get_alias_set_entry (set1); - - if (ase1 && ase1->is_pointer) - { - alias_set_type voidptr_set = TYPE_ALIAS_SET (ptr_type_node); - /* If one is ptr_type_node and other is pointer, then we consider - them subset of each other. */ - if (set1 == voidptr_set || set2 == voidptr_set) - return true; - /* If SET2 contains universal pointer's alias set, then we consdier - every (non-universal) pointer. */ - if (ase2->children && set1 != voidptr_set - && ase2->children->get (voidptr_set)) - return true; - } - } - return false; -} - -/* Return 1 if the two specified alias sets may conflict. */ - -int -alias_sets_conflict_p (alias_set_type set1, alias_set_type set2) -{ - alias_set_entry *ase1; - alias_set_entry *ase2; - - /* The easy case. */ - if (alias_sets_must_conflict_p (set1, set2)) - return 1; - - /* See if the first alias set is a subset of the second. */ - ase1 = get_alias_set_entry (set1); - if (ase1 != 0 - && ase1->children && ase1->children->get (set2)) - { - ++alias_stats.num_dag; - return 1; - } - - /* Now do the same, but with the alias sets reversed. */ - ase2 = get_alias_set_entry (set2); - if (ase2 != 0 - && ase2->children && ase2->children->get (set1)) - { - ++alias_stats.num_dag; - return 1; - } - - /* We want void * to be compatible with any other pointer without - really dropping it to alias set 0. Doing so would make it - compatible with all non-pointer types too. - - This is not strictly necessary by the C/C++ language - standards, but avoids common type punning mistakes. In - addition to that, we need the existence of such universal - pointer to implement Fortran's C_PTR type (which is defined as - type compatible with all C pointers). */ - if (ase1 && ase2 && ase1->has_pointer && ase2->has_pointer) - { - alias_set_type voidptr_set = TYPE_ALIAS_SET (ptr_type_node); - - /* If one of the sets corresponds to universal pointer, - we consider it to conflict with anything that is - or contains pointer. */ - if (set1 == voidptr_set || set2 == voidptr_set) - { - ++alias_stats.num_universal; - return true; - } - /* If one of sets is (non-universal) pointer and the other - contains universal pointer, we also get conflict. */ - if (ase1->is_pointer && set2 != voidptr_set - && ase2->children && ase2->children->get (voidptr_set)) - { - ++alias_stats.num_universal; - return true; - } - if (ase2->is_pointer && set1 != voidptr_set - && ase1->children && ase1->children->get (voidptr_set)) - { - ++alias_stats.num_universal; - return true; - } - } - - ++alias_stats.num_disambiguated; - - /* The two alias sets are distinct and neither one is the - child of the other. Therefore, they cannot conflict. */ - return 0; -} - -/* Return 1 if the two specified alias sets will always conflict. */ - -int -alias_sets_must_conflict_p (alias_set_type set1, alias_set_type set2) -{ - /* Disable TBAA oracle with !flag_strict_aliasing. */ - if (!flag_strict_aliasing) - return 1; - if (set1 == 0 || set2 == 0) - { - ++alias_stats.num_alias_zero; - return 1; - } - if (set1 == set2) - { - ++alias_stats.num_same_alias_set; - return 1; - } - - return 0; -} - -/* Return 1 if any MEM object of type T1 will always conflict (using the - dependency routines in this file) with any MEM object of type T2. - This is used when allocating temporary storage. If T1 and/or T2 are - NULL_TREE, it means we know nothing about the storage. */ - -int -objects_must_conflict_p (tree t1, tree t2) -{ - alias_set_type set1, set2; - - /* If neither has a type specified, we don't know if they'll conflict - because we may be using them to store objects of various types, for - example the argument and local variables areas of inlined functions. */ - if (t1 == 0 && t2 == 0) - return 0; - - /* If they are the same type, they must conflict. */ - if (t1 == t2) - { - ++alias_stats.num_same_objects; - return 1; - } - /* Likewise if both are volatile. */ - if (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)) - { - ++alias_stats.num_volatile; - return 1; - } - - set1 = t1 ? get_alias_set (t1) : 0; - set2 = t2 ? get_alias_set (t2) : 0; - - /* We can't use alias_sets_conflict_p because we must make sure - that every subtype of t1 will conflict with every subtype of - t2 for which a pair of subobjects of these respective subtypes - overlaps on the stack. */ - return alias_sets_must_conflict_p (set1, set2); -} - -/* Return true if T is an end of the access path which can be used - by type based alias oracle. */ - -bool -ends_tbaa_access_path_p (const_tree t) -{ - switch (TREE_CODE (t)) - { - case COMPONENT_REF: - if (DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1))) - return true; - /* Permit type-punning when accessing a union, provided the access - is directly through the union. For example, this code does not - permit taking the address of a union member and then storing - through it. Even the type-punning allowed here is a GCC - extension, albeit a common and useful one; the C standard says - that such accesses have implementation-defined behavior. */ - else if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE) - return true; - break; - - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0)))) - return true; - break; - - case REALPART_EXPR: - case IMAGPART_EXPR: - break; - - case BIT_FIELD_REF: - case VIEW_CONVERT_EXPR: - /* Bitfields and casts are never addressable. */ - return true; - break; - - default: - gcc_unreachable (); - } - return false; -} - -/* Return the outermost parent of component present in the chain of - component references handled by get_inner_reference in T with the - following property: - - the component is non-addressable - or NULL_TREE if no such parent exists. In the former cases, the alias - set of this parent is the alias set that must be used for T itself. */ - -tree -component_uses_parent_alias_set_from (const_tree t) -{ - const_tree found = NULL_TREE; - - while (handled_component_p (t)) - { - if (ends_tbaa_access_path_p (t)) - found = t; - - t = TREE_OPERAND (t, 0); - } - - if (found) - return TREE_OPERAND (found, 0); - - return NULL_TREE; -} - - -/* Return whether the pointer-type T effective for aliasing may - access everything and thus the reference has to be assigned - alias-set zero. */ - -static bool -ref_all_alias_ptr_type_p (const_tree t) -{ - return (TREE_CODE (TREE_TYPE (t)) == VOID_TYPE - || TYPE_REF_CAN_ALIAS_ALL (t)); -} - -/* Return the alias set for the memory pointed to by T, which may be - either a type or an expression. Return -1 if there is nothing - special about dereferencing T. */ - -static alias_set_type -get_deref_alias_set_1 (tree t) -{ - /* All we care about is the type. */ - if (! TYPE_P (t)) - t = TREE_TYPE (t); - - /* If we have an INDIRECT_REF via a void pointer, we don't - know anything about what that might alias. Likewise if the - pointer is marked that way. */ - if (ref_all_alias_ptr_type_p (t)) - return 0; - - return -1; -} - -/* Return the alias set for the memory pointed to by T, which may be - either a type or an expression. */ - -alias_set_type -get_deref_alias_set (tree t) -{ - /* If we're not doing any alias analysis, just assume everything - aliases everything else. */ - if (!flag_strict_aliasing) - return 0; - - alias_set_type set = get_deref_alias_set_1 (t); - - /* Fall back to the alias-set of the pointed-to type. */ - if (set == -1) - { - if (! TYPE_P (t)) - t = TREE_TYPE (t); - set = get_alias_set (TREE_TYPE (t)); - } - - return set; -} - -/* Return the pointer-type relevant for TBAA purposes from the - memory reference tree *T or NULL_TREE in which case *T is - adjusted to point to the outermost component reference that - can be used for assigning an alias set. */ - -tree -reference_alias_ptr_type_1 (tree *t) -{ - tree inner; - - /* Get the base object of the reference. */ - inner = *t; - while (handled_component_p (inner)) - { - /* If there is a VIEW_CONVERT_EXPR in the chain we cannot use - the type of any component references that wrap it to - determine the alias-set. */ - if (TREE_CODE (inner) == VIEW_CONVERT_EXPR) - *t = TREE_OPERAND (inner, 0); - inner = TREE_OPERAND (inner, 0); - } - - /* Handle pointer dereferences here, they can override the - alias-set. */ - if (INDIRECT_REF_P (inner) - && ref_all_alias_ptr_type_p (TREE_TYPE (TREE_OPERAND (inner, 0)))) - return TREE_TYPE (TREE_OPERAND (inner, 0)); - else if (TREE_CODE (inner) == TARGET_MEM_REF) - return TREE_TYPE (TMR_OFFSET (inner)); - else if (TREE_CODE (inner) == MEM_REF - && ref_all_alias_ptr_type_p (TREE_TYPE (TREE_OPERAND (inner, 1)))) - return TREE_TYPE (TREE_OPERAND (inner, 1)); - - /* If the innermost reference is a MEM_REF that has a - conversion embedded treat it like a VIEW_CONVERT_EXPR above, - using the memory access type for determining the alias-set. */ - if (TREE_CODE (inner) == MEM_REF - && (TYPE_MAIN_VARIANT (TREE_TYPE (inner)) - != TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1)))))) - return TREE_TYPE (TREE_OPERAND (inner, 1)); - - /* Otherwise, pick up the outermost object that we could have - a pointer to. */ - tree tem = component_uses_parent_alias_set_from (*t); - if (tem) - *t = tem; - - return NULL_TREE; -} - -/* Return the pointer-type relevant for TBAA purposes from the - gimple memory reference tree T. This is the type to be used for - the offset operand of MEM_REF or TARGET_MEM_REF replacements of T - and guarantees that get_alias_set will return the same alias - set for T and the replacement. */ - -tree -reference_alias_ptr_type (tree t) -{ - /* If the frontend assigns this alias-set zero, preserve that. */ - if (lang_hooks.get_alias_set (t) == 0) - return ptr_type_node; - - tree ptype = reference_alias_ptr_type_1 (&t); - /* If there is a given pointer type for aliasing purposes, return it. */ - if (ptype != NULL_TREE) - return ptype; - - /* Otherwise build one from the outermost component reference we - may use. */ - if (TREE_CODE (t) == MEM_REF - || TREE_CODE (t) == TARGET_MEM_REF) - return TREE_TYPE (TREE_OPERAND (t, 1)); - else - return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (t))); -} - -/* Return whether the pointer-types T1 and T2 used to determine - two alias sets of two references will yield the same answer - from get_deref_alias_set. */ - -bool -alias_ptr_types_compatible_p (tree t1, tree t2) -{ - if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return true; - - if (ref_all_alias_ptr_type_p (t1) - || ref_all_alias_ptr_type_p (t2)) - return false; - - /* This function originally abstracts from simply comparing - get_deref_alias_set so that we are sure this still computes - the same result after LTO type merging is applied. - When in LTO type merging is done we can actually do this compare. - */ - if (in_lto_p) - return get_deref_alias_set (t1) == get_deref_alias_set (t2); - else - return (TYPE_MAIN_VARIANT (TREE_TYPE (t1)) - == TYPE_MAIN_VARIANT (TREE_TYPE (t2))); -} - -/* Create emptry alias set entry. */ - -alias_set_entry * -init_alias_set_entry (alias_set_type set) -{ - alias_set_entry *ase = ggc_alloc<alias_set_entry> (); - ase->alias_set = set; - ase->children = NULL; - ase->has_zero_child = false; - ase->is_pointer = false; - ase->has_pointer = false; - gcc_checking_assert (!get_alias_set_entry (set)); - (*alias_sets)[set] = ase; - return ase; -} - -/* Return the alias set for T, which may be either a type or an - expression. Call language-specific routine for help, if needed. */ - -alias_set_type -get_alias_set (tree t) -{ - alias_set_type set; - - /* We cannot give up with -fno-strict-aliasing because we need to build - proper type representations for possible functions which are built with - -fstrict-aliasing. */ - - /* return 0 if this or its type is an error. */ - if (t == error_mark_node - || (! TYPE_P (t) - && (TREE_TYPE (t) == 0 || TREE_TYPE (t) == error_mark_node))) - return 0; - - /* We can be passed either an expression or a type. This and the - language-specific routine may make mutually-recursive calls to each other - to figure out what to do. At each juncture, we see if this is a tree - that the language may need to handle specially. First handle things that - aren't types. */ - if (! TYPE_P (t)) - { - /* Give the language a chance to do something with this tree - before we look at it. */ - STRIP_NOPS (t); - set = lang_hooks.get_alias_set (t); - if (set != -1) - return set; - - /* Get the alias pointer-type to use or the outermost object - that we could have a pointer to. */ - tree ptype = reference_alias_ptr_type_1 (&t); - if (ptype != NULL) - return get_deref_alias_set (ptype); - - /* If we've already determined the alias set for a decl, just return - it. This is necessary for C++ anonymous unions, whose component - variables don't look like union members (boo!). */ - if (VAR_P (t) - && DECL_RTL_SET_P (t) && MEM_P (DECL_RTL (t))) - return MEM_ALIAS_SET (DECL_RTL (t)); - - /* Now all we care about is the type. */ - t = TREE_TYPE (t); - } - - /* Variant qualifiers don't affect the alias set, so get the main - variant. */ - t = TYPE_MAIN_VARIANT (t); - - if (AGGREGATE_TYPE_P (t) - && TYPE_TYPELESS_STORAGE (t)) - return 0; - - /* Always use the canonical type as well. If this is a type that - requires structural comparisons to identify compatible types - use alias set zero. */ - if (TYPE_STRUCTURAL_EQUALITY_P (t)) - { - /* Allow the language to specify another alias set for this - type. */ - set = lang_hooks.get_alias_set (t); - if (set != -1) - return set; - /* Handle structure type equality for pointer types, arrays and vectors. - This is easy to do, because the code below ignores canonical types on - these anyway. This is important for LTO, where TYPE_CANONICAL for - pointers cannot be meaningfully computed by the frontend. */ - if (canonical_type_used_p (t)) - { - /* In LTO we set canonical types for all types where it makes - sense to do so. Double check we did not miss some type. */ - gcc_checking_assert (!in_lto_p || !type_with_alias_set_p (t)); - return 0; - } - } - else - { - t = TYPE_CANONICAL (t); - gcc_checking_assert (!TYPE_STRUCTURAL_EQUALITY_P (t)); - } - - /* If this is a type with a known alias set, return it. */ - gcc_checking_assert (t == TYPE_MAIN_VARIANT (t)); - if (TYPE_ALIAS_SET_KNOWN_P (t)) - return TYPE_ALIAS_SET (t); - - /* We don't want to set TYPE_ALIAS_SET for incomplete types. */ - if (!COMPLETE_TYPE_P (t)) - { - /* For arrays with unknown size the conservative answer is the - alias set of the element type. */ - if (TREE_CODE (t) == ARRAY_TYPE) - return get_alias_set (TREE_TYPE (t)); - - /* But return zero as a conservative answer for incomplete types. */ - return 0; - } - - /* See if the language has special handling for this type. */ - set = lang_hooks.get_alias_set (t); - if (set != -1) - return set; - - /* There are no objects of FUNCTION_TYPE, so there's no point in - using up an alias set for them. (There are, of course, pointers - and references to functions, but that's different.) */ - else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE) - set = 0; - - /* Unless the language specifies otherwise, let vector types alias - their components. This avoids some nasty type punning issues in - normal usage. And indeed lets vectors be treated more like an - array slice. */ - else if (TREE_CODE (t) == VECTOR_TYPE) - set = get_alias_set (TREE_TYPE (t)); - - /* Unless the language specifies otherwise, treat array types the - same as their components. This avoids the asymmetry we get - through recording the components. Consider accessing a - character(kind=1) through a reference to a character(kind=1)[1:1]. - Or consider if we want to assign integer(kind=4)[0:D.1387] and - integer(kind=4)[4] the same alias set or not. - Just be pragmatic here and make sure the array and its element - type get the same alias set assigned. */ - else if (TREE_CODE (t) == ARRAY_TYPE - && (!TYPE_NONALIASED_COMPONENT (t) - || TYPE_STRUCTURAL_EQUALITY_P (t))) - set = get_alias_set (TREE_TYPE (t)); - - /* From the former common C and C++ langhook implementation: - - Unfortunately, there is no canonical form of a pointer type. - In particular, if we have `typedef int I', then `int *', and - `I *' are different types. So, we have to pick a canonical - representative. We do this below. - - Technically, this approach is actually more conservative that - it needs to be. In particular, `const int *' and `int *' - should be in different alias sets, according to the C and C++ - standard, since their types are not the same, and so, - technically, an `int **' and `const int **' cannot point at - the same thing. - - But, the standard is wrong. In particular, this code is - legal C++: - - int *ip; - int **ipp = &ip; - const int* const* cipp = ipp; - And, it doesn't make sense for that to be legal unless you - can dereference IPP and CIPP. So, we ignore cv-qualifiers on - the pointed-to types. This issue has been reported to the - C++ committee. - - For this reason go to canonical type of the unqalified pointer type. - Until GCC 6 this code set all pointers sets to have alias set of - ptr_type_node but that is a bad idea, because it prevents disabiguations - in between pointers. For Firefox this accounts about 20% of all - disambiguations in the program. */ - else if (POINTER_TYPE_P (t) && t != ptr_type_node) - { - tree p; - auto_vec <bool, 8> reference; - - /* Unnest all pointers and references. - We also want to make pointer to array/vector equivalent to pointer to - its element (see the reasoning above). Skip all those types, too. */ - for (p = t; POINTER_TYPE_P (p) - || (TREE_CODE (p) == ARRAY_TYPE - && (!TYPE_NONALIASED_COMPONENT (p) - || !COMPLETE_TYPE_P (p) - || TYPE_STRUCTURAL_EQUALITY_P (p))) - || TREE_CODE (p) == VECTOR_TYPE; - p = TREE_TYPE (p)) - { - /* Ada supports recursive pointers. Instead of doing recursion - check, just give up once the preallocated space of 8 elements - is up. In this case just punt to void * alias set. */ - if (reference.length () == 8) - { - p = ptr_type_node; - break; - } - if (TREE_CODE (p) == REFERENCE_TYPE) - /* In LTO we want languages that use references to be compatible - with languages that use pointers. */ - reference.safe_push (true && !in_lto_p); - if (TREE_CODE (p) == POINTER_TYPE) - reference.safe_push (false); - } - p = TYPE_MAIN_VARIANT (p); - - /* In LTO for C++ programs we can turn incomplete types to complete - using ODR name lookup. */ - if (in_lto_p && TYPE_STRUCTURAL_EQUALITY_P (p) && odr_type_p (p)) - { - p = prevailing_odr_type (p); - gcc_checking_assert (TYPE_MAIN_VARIANT (p) == p); - } - - /* Make void * compatible with char * and also void **. - Programs are commonly violating TBAA by this. - - We also make void * to conflict with every pointer - (see record_component_aliases) and thus it is safe it to use it for - pointers to types with TYPE_STRUCTURAL_EQUALITY_P. */ - if (TREE_CODE (p) == VOID_TYPE || TYPE_STRUCTURAL_EQUALITY_P (p)) - set = get_alias_set (ptr_type_node); - else - { - /* Rebuild pointer type starting from canonical types using - unqualified pointers and references only. This way all such - pointers will have the same alias set and will conflict with - each other. - - Most of time we already have pointers or references of a given type. - If not we build new one just to be sure that if someone later - (probably only middle-end can, as we should assign all alias - classes only after finishing translation unit) builds the pointer - type, the canonical type will match. */ - p = TYPE_CANONICAL (p); - while (!reference.is_empty ()) - { - if (reference.pop ()) - p = build_reference_type (p); - else - p = build_pointer_type (p); - gcc_checking_assert (p == TYPE_MAIN_VARIANT (p)); - /* build_pointer_type should always return the canonical type. - For LTO TYPE_CANOINCAL may be NULL, because we do not compute - them. Be sure that frontends do not glob canonical types of - pointers in unexpected way and that p == TYPE_CANONICAL (p) - in all other cases. */ - gcc_checking_assert (!TYPE_CANONICAL (p) - || p == TYPE_CANONICAL (p)); - } - - /* Assign the alias set to both p and t. - We cannot call get_alias_set (p) here as that would trigger - infinite recursion when p == t. In other cases it would just - trigger unnecesary legwork of rebuilding the pointer again. */ - gcc_checking_assert (p == TYPE_MAIN_VARIANT (p)); - if (TYPE_ALIAS_SET_KNOWN_P (p)) - set = TYPE_ALIAS_SET (p); - else - { - set = new_alias_set (); - TYPE_ALIAS_SET (p) = set; - } - } - } - /* Alias set of ptr_type_node is special and serve as universal pointer which - is TBAA compatible with every other pointer type. Be sure we have the - alias set built even for LTO which otherwise keeps all TYPE_CANONICAL - of pointer types NULL. */ - else if (t == ptr_type_node) - set = new_alias_set (); - - /* Otherwise make a new alias set for this type. */ - else - { - /* Each canonical type gets its own alias set, so canonical types - shouldn't form a tree. It doesn't really matter for types - we handle specially above, so only check it where it possibly - would result in a bogus alias set. */ - gcc_checking_assert (TYPE_CANONICAL (t) == t); - - set = new_alias_set (); - } - - TYPE_ALIAS_SET (t) = set; - - /* If this is an aggregate type or a complex type, we must record any - component aliasing information. */ - if (AGGREGATE_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE) - record_component_aliases (t); - - /* We treat pointer types specially in alias_set_subset_of. */ - if (POINTER_TYPE_P (t) && set) - { - alias_set_entry *ase = get_alias_set_entry (set); - if (!ase) - ase = init_alias_set_entry (set); - ase->is_pointer = true; - ase->has_pointer = true; - } - - return set; -} - -/* Return a brand-new alias set. */ - -alias_set_type -new_alias_set (void) -{ - if (alias_sets == 0) - vec_safe_push (alias_sets, (alias_set_entry *) NULL); - vec_safe_push (alias_sets, (alias_set_entry *) NULL); - return alias_sets->length () - 1; -} - -/* Indicate that things in SUBSET can alias things in SUPERSET, but that - not everything that aliases SUPERSET also aliases SUBSET. For example, - in C, a store to an `int' can alias a load of a structure containing an - `int', and vice versa. But it can't alias a load of a 'double' member - of the same structure. Here, the structure would be the SUPERSET and - `int' the SUBSET. This relationship is also described in the comment at - the beginning of this file. - - This function should be called only once per SUPERSET/SUBSET pair. - - It is illegal for SUPERSET to be zero; everything is implicitly a - subset of alias set zero. */ - -void -record_alias_subset (alias_set_type superset, alias_set_type subset) -{ - alias_set_entry *superset_entry; - alias_set_entry *subset_entry; - - /* It is possible in complex type situations for both sets to be the same, - in which case we can ignore this operation. */ - if (superset == subset) - return; - - gcc_assert (superset); - - superset_entry = get_alias_set_entry (superset); - if (superset_entry == 0) - { - /* Create an entry for the SUPERSET, so that we have a place to - attach the SUBSET. */ - superset_entry = init_alias_set_entry (superset); - } - - if (subset == 0) - superset_entry->has_zero_child = 1; - else - { - if (!superset_entry->children) - superset_entry->children - = hash_map<alias_set_hash, int>::create_ggc (64); - - /* Enter the SUBSET itself as a child of the SUPERSET. If it was - already there we're done. */ - if (superset_entry->children->put (subset, 0)) - return; - - subset_entry = get_alias_set_entry (subset); - /* If there is an entry for the subset, enter all of its children - (if they are not already present) as children of the SUPERSET. */ - if (subset_entry) - { - if (subset_entry->has_zero_child) - superset_entry->has_zero_child = true; - if (subset_entry->has_pointer) - superset_entry->has_pointer = true; - - if (subset_entry->children) - { - hash_map<alias_set_hash, int>::iterator iter - = subset_entry->children->begin (); - for (; iter != subset_entry->children->end (); ++iter) - superset_entry->children->put ((*iter).first, (*iter).second); - } - } - } -} - -/* Record that component types of TYPE, if any, are part of SUPERSET for - aliasing purposes. For record types, we only record component types - for fields that are not marked non-addressable. For array types, we - only record the component type if it is not marked non-aliased. */ - -void -record_component_aliases (tree type, alias_set_type superset) -{ - tree field; - - if (superset == 0) - return; - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - { - /* LTO non-ODR type merging does not make any difference between - component pointer types. We may have - - struct foo {int *a;}; - - as TYPE_CANONICAL of - - struct bar {float *a;}; - - Because accesses to int * and float * do not alias, we would get - false negative when accessing the same memory location by - float ** and bar *. We thus record the canonical type as: - - struct {void *a;}; - - void * is special cased and works as a universal pointer type. - Accesses to it conflicts with accesses to any other pointer - type. */ - bool void_pointers = in_lto_p - && (!odr_type_p (type) - || !odr_based_tbaa_p (type)); - for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field)) - { - tree t = TREE_TYPE (field); - if (void_pointers) - { - /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their - element type and that type has to be normalized to void *, - too, in the case it is a pointer. */ - while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t)) - { - gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t)); - t = TREE_TYPE (t); - } - if (POINTER_TYPE_P (t)) - t = ptr_type_node; - else if (flag_checking) - gcc_checking_assert (get_alias_set (t) - == get_alias_set (TREE_TYPE (field))); - } - - alias_set_type set = get_alias_set (t); - record_alias_subset (superset, set); - /* If the field has alias-set zero make sure to still record - any componets of it. This makes sure that for - struct A { - struct B { - int i; - char c[4]; - } b; - }; - in C++ even though 'B' has alias-set zero because - TYPE_TYPELESS_STORAGE is set, 'A' has the alias-set of - 'int' as subset. */ - if (set == 0) - record_component_aliases (t, superset); - } - } - break; - - case COMPLEX_TYPE: - record_alias_subset (superset, get_alias_set (TREE_TYPE (type))); - break; - - /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their - element type. */ - - default: - break; - } -} - -/* Record that component types of TYPE, if any, are part of that type for - aliasing purposes. For record types, we only record component types - for fields that are not marked non-addressable. For array types, we - only record the component type if it is not marked non-aliased. */ - -void -record_component_aliases (tree type) -{ - alias_set_type superset = get_alias_set (type); - record_component_aliases (type, superset); -} - - -/* Allocate an alias set for use in storing and reading from the varargs - spill area. */ - -static GTY(()) alias_set_type varargs_set = -1; - -alias_set_type -get_varargs_alias_set (void) -{ -#if 1 - /* We now lower VA_ARG_EXPR, and there's currently no way to attach the - varargs alias set to an INDIRECT_REF (FIXME!), so we can't - consistently use the varargs alias set for loads from the varargs - area. So don't use it anywhere. */ - return 0; -#else - if (varargs_set == -1) - varargs_set = new_alias_set (); - - return varargs_set; -#endif -} - -/* Likewise, but used for the fixed portions of the frame, e.g., register - save areas. */ - -static GTY(()) alias_set_type frame_set = -1; - -alias_set_type -get_frame_alias_set (void) -{ - if (frame_set == -1) - frame_set = new_alias_set (); - - return frame_set; -} - -/* Create a new, unique base with id ID. */ - -static rtx -unique_base_value (HOST_WIDE_INT id) -{ - return gen_rtx_ADDRESS (Pmode, id); -} - -/* Return true if accesses based on any other base value cannot alias - those based on X. */ - -static bool -unique_base_value_p (rtx x) -{ - return GET_CODE (x) == ADDRESS && GET_MODE (x) == Pmode; -} - -/* Return true if X is known to be a base value. */ - -static bool -known_base_value_p (rtx x) -{ - switch (GET_CODE (x)) - { - case LABEL_REF: - case SYMBOL_REF: - return true; - - case ADDRESS: - /* Arguments may or may not be bases; we don't know for sure. */ - return GET_MODE (x) != VOIDmode; - - default: - return false; - } -} - -/* Inside SRC, the source of a SET, find a base address. */ - -static rtx -find_base_value (rtx src) -{ - unsigned int regno; - scalar_int_mode int_mode; - -#if defined (FIND_BASE_TERM) - /* Try machine-dependent ways to find the base term. */ - src = FIND_BASE_TERM (src); -#endif - - switch (GET_CODE (src)) - { - case SYMBOL_REF: - case LABEL_REF: - return src; - - case REG: - regno = REGNO (src); - /* At the start of a function, argument registers have known base - values which may be lost later. Returning an ADDRESS - expression here allows optimization based on argument values - even when the argument registers are used for other purposes. */ - if (regno < FIRST_PSEUDO_REGISTER && copying_arguments) - return new_reg_base_value[regno]; - - /* If a pseudo has a known base value, return it. Do not do this - for non-fixed hard regs since it can result in a circular - dependency chain for registers which have values at function entry. - - The test above is not sufficient because the scheduler may move - a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */ - if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno]) - && regno < vec_safe_length (reg_base_value)) - { - /* If we're inside init_alias_analysis, use new_reg_base_value - to reduce the number of relaxation iterations. */ - if (new_reg_base_value && new_reg_base_value[regno] - && DF_REG_DEF_COUNT (regno) == 1) - return new_reg_base_value[regno]; - - if ((*reg_base_value)[regno]) - return (*reg_base_value)[regno]; - } - - return 0; - - case MEM: - /* Check for an argument passed in memory. Only record in the - copying-arguments block; it is too hard to track changes - otherwise. */ - if (copying_arguments - && (XEXP (src, 0) == arg_pointer_rtx - || (GET_CODE (XEXP (src, 0)) == PLUS - && XEXP (XEXP (src, 0), 0) == arg_pointer_rtx))) - return arg_base_value; - return 0; - - case CONST: - src = XEXP (src, 0); - if (GET_CODE (src) != PLUS && GET_CODE (src) != MINUS) - break; - - /* fall through */ - - case PLUS: - case MINUS: - { - rtx temp, src_0 = XEXP (src, 0), src_1 = XEXP (src, 1); - - /* If either operand is a REG that is a known pointer, then it - is the base. */ - if (REG_P (src_0) && REG_POINTER (src_0)) - return find_base_value (src_0); - if (REG_P (src_1) && REG_POINTER (src_1)) - return find_base_value (src_1); - - /* If either operand is a REG, then see if we already have - a known value for it. */ - if (REG_P (src_0)) - { - temp = find_base_value (src_0); - if (temp != 0) - src_0 = temp; - } - - if (REG_P (src_1)) - { - temp = find_base_value (src_1); - if (temp!= 0) - src_1 = temp; - } - - /* If either base is named object or a special address - (like an argument or stack reference), then use it for the - base term. */ - if (src_0 != 0 && known_base_value_p (src_0)) - return src_0; - - if (src_1 != 0 && known_base_value_p (src_1)) - return src_1; - - /* Guess which operand is the base address: - If either operand is a symbol, then it is the base. If - either operand is a CONST_INT, then the other is the base. */ - if (CONST_INT_P (src_1) || CONSTANT_P (src_0)) - return find_base_value (src_0); - else if (CONST_INT_P (src_0) || CONSTANT_P (src_1)) - return find_base_value (src_1); - - return 0; - } - - case LO_SUM: - /* The standard form is (lo_sum reg sym) so look only at the - second operand. */ - return find_base_value (XEXP (src, 1)); - - case AND: - /* Look through aligning ANDs. And AND with zero or one with - the LSB set isn't one (see for example PR92462). */ - if (CONST_INT_P (XEXP (src, 1)) - && INTVAL (XEXP (src, 1)) != 0 - && (INTVAL (XEXP (src, 1)) & 1) == 0) - return find_base_value (XEXP (src, 0)); - return 0; - - case TRUNCATE: - /* As we do not know which address space the pointer is referring to, we can - handle this only if the target does not support different pointer or - address modes depending on the address space. */ - if (!target_default_pointer_address_modes_p ()) - break; - if (!is_a <scalar_int_mode> (GET_MODE (src), &int_mode) - || GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (Pmode)) - break; - /* Fall through. */ - case HIGH: - case PRE_INC: - case PRE_DEC: - case POST_INC: - case POST_DEC: - case PRE_MODIFY: - case POST_MODIFY: - return find_base_value (XEXP (src, 0)); - - case ZERO_EXTEND: - case SIGN_EXTEND: /* used for NT/Alpha pointers */ - /* As we do not know which address space the pointer is referring to, we can - handle this only if the target does not support different pointer or - address modes depending on the address space. */ - if (!target_default_pointer_address_modes_p ()) - break; - - { - rtx temp = find_base_value (XEXP (src, 0)); - - if (temp != 0 && CONSTANT_P (temp)) - temp = convert_memory_address (Pmode, temp); - - return temp; - } - - default: - break; - } - - return 0; -} - -/* Called from init_alias_analysis indirectly through note_stores, - or directly if DEST is a register with a REG_NOALIAS note attached. - SET is null in the latter case. */ - -/* While scanning insns to find base values, reg_seen[N] is nonzero if - register N has been set in this function. */ -static sbitmap reg_seen; - -static void -record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED) -{ - unsigned regno; - rtx src; - int n; - - if (!REG_P (dest)) - return; - - regno = REGNO (dest); - - gcc_checking_assert (regno < reg_base_value->length ()); - - n = REG_NREGS (dest); - if (n != 1) - { - while (--n >= 0) - { - bitmap_set_bit (reg_seen, regno + n); - new_reg_base_value[regno + n] = 0; - } - return; - } - - if (set) - { - /* A CLOBBER wipes out any old value but does not prevent a previously - unset register from acquiring a base address (i.e. reg_seen is not - set). */ - if (GET_CODE (set) == CLOBBER) - { - new_reg_base_value[regno] = 0; - return; - } - - src = SET_SRC (set); - } - else - { - /* There's a REG_NOALIAS note against DEST. */ - if (bitmap_bit_p (reg_seen, regno)) - { - new_reg_base_value[regno] = 0; - return; - } - bitmap_set_bit (reg_seen, regno); - new_reg_base_value[regno] = unique_base_value (unique_id++); - return; - } - - /* If this is not the first set of REGNO, see whether the new value - is related to the old one. There are two cases of interest: - - (1) The register might be assigned an entirely new value - that has the same base term as the original set. - - (2) The set might be a simple self-modification that - cannot change REGNO's base value. - - If neither case holds, reject the original base value as invalid. - Note that the following situation is not detected: - - extern int x, y; int *p = &x; p += (&y-&x); - - ANSI C does not allow computing the difference of addresses - of distinct top level objects. */ - if (new_reg_base_value[regno] != 0 - && find_base_value (src) != new_reg_base_value[regno]) - switch (GET_CODE (src)) - { - case LO_SUM: - case MINUS: - if (XEXP (src, 0) != dest && XEXP (src, 1) != dest) - new_reg_base_value[regno] = 0; - break; - case PLUS: - /* If the value we add in the PLUS is also a valid base value, - this might be the actual base value, and the original value - an index. */ - { - rtx other = NULL_RTX; - - if (XEXP (src, 0) == dest) - other = XEXP (src, 1); - else if (XEXP (src, 1) == dest) - other = XEXP (src, 0); - - if (! other || find_base_value (other)) - new_reg_base_value[regno] = 0; - break; - } - case AND: - if (XEXP (src, 0) != dest || !CONST_INT_P (XEXP (src, 1))) - new_reg_base_value[regno] = 0; - break; - default: - new_reg_base_value[regno] = 0; - break; - } - /* If this is the first set of a register, record the value. */ - else if ((regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno]) - && ! bitmap_bit_p (reg_seen, regno) && new_reg_base_value[regno] == 0) - new_reg_base_value[regno] = find_base_value (src); - - bitmap_set_bit (reg_seen, regno); -} - -/* Return REG_BASE_VALUE for REGNO. Selective scheduler uses this to avoid - using hard registers with non-null REG_BASE_VALUE for renaming. */ -rtx -get_reg_base_value (unsigned int regno) -{ - return (*reg_base_value)[regno]; -} - -/* If a value is known for REGNO, return it. */ - -rtx -get_reg_known_value (unsigned int regno) -{ - if (regno >= FIRST_PSEUDO_REGISTER) - { - regno -= FIRST_PSEUDO_REGISTER; - if (regno < vec_safe_length (reg_known_value)) - return (*reg_known_value)[regno]; - } - return NULL; -} - -/* Set it. */ - -static void -set_reg_known_value (unsigned int regno, rtx val) -{ - if (regno >= FIRST_PSEUDO_REGISTER) - { - regno -= FIRST_PSEUDO_REGISTER; - if (regno < vec_safe_length (reg_known_value)) - (*reg_known_value)[regno] = val; - } -} - -/* Similarly for reg_known_equiv_p. */ - -bool -get_reg_known_equiv_p (unsigned int regno) -{ - if (regno >= FIRST_PSEUDO_REGISTER) - { - regno -= FIRST_PSEUDO_REGISTER; - if (regno < vec_safe_length (reg_known_value)) - return bitmap_bit_p (reg_known_equiv_p, regno); - } - return false; -} - -static void -set_reg_known_equiv_p (unsigned int regno, bool val) -{ - if (regno >= FIRST_PSEUDO_REGISTER) - { - regno -= FIRST_PSEUDO_REGISTER; - if (regno < vec_safe_length (reg_known_value)) - { - if (val) - bitmap_set_bit (reg_known_equiv_p, regno); - else - bitmap_clear_bit (reg_known_equiv_p, regno); - } - } -} - - -/* Returns a canonical version of X, from the point of view alias - analysis. (For example, if X is a MEM whose address is a register, - and the register has a known value (say a SYMBOL_REF), then a MEM - whose address is the SYMBOL_REF is returned.) */ - -rtx -canon_rtx (rtx x) -{ - /* Recursively look for equivalences. */ - if (REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER) - { - rtx t = get_reg_known_value (REGNO (x)); - if (t == x) - return x; - if (t) - return canon_rtx (t); - } - - if (GET_CODE (x) == PLUS) - { - rtx x0 = canon_rtx (XEXP (x, 0)); - rtx x1 = canon_rtx (XEXP (x, 1)); - - if (x0 != XEXP (x, 0) || x1 != XEXP (x, 1)) - return simplify_gen_binary (PLUS, GET_MODE (x), x0, x1); - } - - /* This gives us much better alias analysis when called from - the loop optimizer. Note we want to leave the original - MEM alone, but need to return the canonicalized MEM with - all the flags with their original values. */ - else if (MEM_P (x)) - x = replace_equiv_address_nv (x, canon_rtx (XEXP (x, 0))); - - return x; -} - -/* Return 1 if X and Y are identical-looking rtx's. - Expect that X and Y has been already canonicalized. - - We use the data in reg_known_value above to see if two registers with - different numbers are, in fact, equivalent. */ - -static int -rtx_equal_for_memref_p (const_rtx x, const_rtx y) -{ - int i; - int j; - enum rtx_code code; - const char *fmt; - - if (x == 0 && y == 0) - return 1; - if (x == 0 || y == 0) - return 0; - - if (x == y) - return 1; - - code = GET_CODE (x); - /* Rtx's of different codes cannot be equal. */ - if (code != GET_CODE (y)) - return 0; - - /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. - (REG:SI x) and (REG:HI x) are NOT equivalent. */ - - if (GET_MODE (x) != GET_MODE (y)) - return 0; - - /* Some RTL can be compared without a recursive examination. */ - switch (code) - { - case REG: - return REGNO (x) == REGNO (y); - - case LABEL_REF: - return label_ref_label (x) == label_ref_label (y); - - case SYMBOL_REF: - { - HOST_WIDE_INT distance = 0; - return (compare_base_symbol_refs (x, y, &distance) == 1 - && distance == 0); - } - - case ENTRY_VALUE: - /* This is magic, don't go through canonicalization et al. */ - return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y)); - - case VALUE: - CASE_CONST_UNIQUE: - /* Pointer equality guarantees equality for these nodes. */ - return 0; - - default: - break; - } - - /* canon_rtx knows how to handle plus. No need to canonicalize. */ - if (code == PLUS) - return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)) - && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1))) - || (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1)) - && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0)))); - /* For commutative operations, the RTX match if the operand match in any - order. Also handle the simple binary and unary cases without a loop. */ - if (COMMUTATIVE_P (x)) - { - rtx xop0 = canon_rtx (XEXP (x, 0)); - rtx yop0 = canon_rtx (XEXP (y, 0)); - rtx yop1 = canon_rtx (XEXP (y, 1)); - - return ((rtx_equal_for_memref_p (xop0, yop0) - && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop1)) - || (rtx_equal_for_memref_p (xop0, yop1) - && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop0))); - } - else if (NON_COMMUTATIVE_P (x)) - { - return (rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)), - canon_rtx (XEXP (y, 0))) - && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), - canon_rtx (XEXP (y, 1)))); - } - else if (UNARY_P (x)) - return rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)), - canon_rtx (XEXP (y, 0))); - - /* Compare the elements. If any pair of corresponding elements - fail to match, return 0 for the whole things. - - Limit cases to types which actually appear in addresses. */ - - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - { - switch (fmt[i]) - { - case 'i': - if (XINT (x, i) != XINT (y, i)) - return 0; - break; - - case 'p': - if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y))) - return 0; - break; - - case 'E': - /* Two vectors must have the same length. */ - if (XVECLEN (x, i) != XVECLEN (y, i)) - return 0; - - /* And the corresponding elements must match. */ - for (j = 0; j < XVECLEN (x, i); j++) - if (rtx_equal_for_memref_p (canon_rtx (XVECEXP (x, i, j)), - canon_rtx (XVECEXP (y, i, j))) == 0) - return 0; - break; - - case 'e': - if (rtx_equal_for_memref_p (canon_rtx (XEXP (x, i)), - canon_rtx (XEXP (y, i))) == 0) - return 0; - break; - - /* This can happen for asm operands. */ - case 's': - if (strcmp (XSTR (x, i), XSTR (y, i))) - return 0; - break; - - /* This can happen for an asm which clobbers memory. */ - case '0': - break; - - /* It is believed that rtx's at this level will never - contain anything but integers and other rtx's, - except for within LABEL_REFs and SYMBOL_REFs. */ - default: - gcc_unreachable (); - } - } - return 1; -} - -static rtx -find_base_term (rtx x, vec<std::pair<cselib_val *, - struct elt_loc_list *> > &visited_vals) -{ - cselib_val *val; - struct elt_loc_list *l, *f; - rtx ret; - scalar_int_mode int_mode; - -#if defined (FIND_BASE_TERM) - /* Try machine-dependent ways to find the base term. */ - x = FIND_BASE_TERM (x); -#endif - - switch (GET_CODE (x)) - { - case REG: - return REG_BASE_VALUE (x); - - case TRUNCATE: - /* As we do not know which address space the pointer is referring to, we can - handle this only if the target does not support different pointer or - address modes depending on the address space. */ - if (!target_default_pointer_address_modes_p ()) - return 0; - if (!is_a <scalar_int_mode> (GET_MODE (x), &int_mode) - || GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (Pmode)) - return 0; - /* Fall through. */ - case HIGH: - case PRE_INC: - case PRE_DEC: - case POST_INC: - case POST_DEC: - case PRE_MODIFY: - case POST_MODIFY: - return find_base_term (XEXP (x, 0), visited_vals); - - case ZERO_EXTEND: - case SIGN_EXTEND: /* Used for Alpha/NT pointers */ - /* As we do not know which address space the pointer is referring to, we can - handle this only if the target does not support different pointer or - address modes depending on the address space. */ - if (!target_default_pointer_address_modes_p ()) - return 0; - - { - rtx temp = find_base_term (XEXP (x, 0), visited_vals); - - if (temp != 0 && CONSTANT_P (temp)) - temp = convert_memory_address (Pmode, temp); - - return temp; - } - - case VALUE: - val = CSELIB_VAL_PTR (x); - ret = NULL_RTX; - - if (!val) - return ret; - - if (cselib_sp_based_value_p (val)) - return static_reg_base_value[STACK_POINTER_REGNUM]; - - if (visited_vals.length () > (unsigned) param_max_find_base_term_values) - return ret; - - f = val->locs; - /* Reset val->locs to avoid infinite recursion. */ - if (f) - visited_vals.safe_push (std::make_pair (val, f)); - val->locs = NULL; - - for (l = f; l; l = l->next) - if (GET_CODE (l->loc) == VALUE - && CSELIB_VAL_PTR (l->loc)->locs - && !CSELIB_VAL_PTR (l->loc)->locs->next - && CSELIB_VAL_PTR (l->loc)->locs->loc == x) - continue; - else if ((ret = find_base_term (l->loc, visited_vals)) != 0) - break; - - return ret; - - case LO_SUM: - /* The standard form is (lo_sum reg sym) so look only at the - second operand. */ - return find_base_term (XEXP (x, 1), visited_vals); - - case CONST: - x = XEXP (x, 0); - if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS) - return 0; - /* Fall through. */ - case PLUS: - case MINUS: - { - rtx tmp1 = XEXP (x, 0); - rtx tmp2 = XEXP (x, 1); - - /* This is a little bit tricky since we have to determine which of - the two operands represents the real base address. Otherwise this - routine may return the index register instead of the base register. - - That may cause us to believe no aliasing was possible, when in - fact aliasing is possible. - - We use a few simple tests to guess the base register. Additional - tests can certainly be added. For example, if one of the operands - is a shift or multiply, then it must be the index register and the - other operand is the base register. */ - - if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2)) - return find_base_term (tmp2, visited_vals); - - /* If either operand is known to be a pointer, then prefer it - to determine the base term. */ - if (REG_P (tmp1) && REG_POINTER (tmp1)) - ; - else if (REG_P (tmp2) && REG_POINTER (tmp2)) - std::swap (tmp1, tmp2); - /* If second argument is constant which has base term, prefer it - over variable tmp1. See PR64025. */ - else if (CONSTANT_P (tmp2) && !CONST_INT_P (tmp2)) - std::swap (tmp1, tmp2); - - /* Go ahead and find the base term for both operands. If either base - term is from a pointer or is a named object or a special address - (like an argument or stack reference), then use it for the - base term. */ - rtx base = find_base_term (tmp1, visited_vals); - if (base != NULL_RTX - && ((REG_P (tmp1) && REG_POINTER (tmp1)) - || known_base_value_p (base))) - return base; - base = find_base_term (tmp2, visited_vals); - if (base != NULL_RTX - && ((REG_P (tmp2) && REG_POINTER (tmp2)) - || known_base_value_p (base))) - return base; - - /* We could not determine which of the two operands was the - base register and which was the index. So we can determine - nothing from the base alias check. */ - return 0; - } - - case AND: - /* Look through aligning ANDs. And AND with zero or one with - the LSB set isn't one (see for example PR92462). */ - if (CONST_INT_P (XEXP (x, 1)) - && INTVAL (XEXP (x, 1)) != 0 - && (INTVAL (XEXP (x, 1)) & 1) == 0) - return find_base_term (XEXP (x, 0), visited_vals); - return 0; - - case SYMBOL_REF: - case LABEL_REF: - return x; - - default: - return 0; - } -} - -/* Wrapper around the worker above which removes locs from visited VALUEs - to avoid visiting them multiple times. We unwind that changes here. */ - -static rtx -find_base_term (rtx x) -{ - auto_vec<std::pair<cselib_val *, struct elt_loc_list *>, 32> visited_vals; - rtx res = find_base_term (x, visited_vals); - for (unsigned i = 0; i < visited_vals.length (); ++i) - visited_vals[i].first->locs = visited_vals[i].second; - return res; -} - -/* Return true if accesses to address X may alias accesses based - on the stack pointer. */ - -bool -may_be_sp_based_p (rtx x) -{ - rtx base = find_base_term (x); - return !base || base == static_reg_base_value[STACK_POINTER_REGNUM]; -} - -/* BASE1 and BASE2 are decls. Return 1 if they refer to same object, 0 - if they refer to different objects and -1 if we cannot decide. */ - -int -compare_base_decls (tree base1, tree base2) -{ - int ret; - gcc_checking_assert (DECL_P (base1) && DECL_P (base2)); - if (base1 == base2) - return 1; - - /* If we have two register decls with register specification we - cannot decide unless their assembler names are the same. */ - if (VAR_P (base1) - && VAR_P (base2) - && DECL_HARD_REGISTER (base1) - && DECL_HARD_REGISTER (base2) - && DECL_ASSEMBLER_NAME_SET_P (base1) - && DECL_ASSEMBLER_NAME_SET_P (base2)) - { - if (DECL_ASSEMBLER_NAME_RAW (base1) == DECL_ASSEMBLER_NAME_RAW (base2)) - return 1; - return -1; - } - - /* Declarations of non-automatic variables may have aliases. All other - decls are unique. */ - if (!decl_in_symtab_p (base1) - || !decl_in_symtab_p (base2)) - return 0; - - /* Don't cause symbols to be inserted by the act of checking. */ - symtab_node *node1 = symtab_node::get (base1); - if (!node1) - return 0; - symtab_node *node2 = symtab_node::get (base2); - if (!node2) - return 0; - - ret = node1->equal_address_to (node2, true); - return ret; -} - -/* Compare SYMBOL_REFs X_BASE and Y_BASE. - - - Return 1 if Y_BASE - X_BASE is constant, adding that constant - to *DISTANCE if DISTANCE is nonnull. - - - Return 0 if no accesses based on X_BASE can alias Y_BASE. - - - Return -1 if one of the two results applies, but we can't tell - which at compile time. Update DISTANCE in the same way as - for a return value of 1, for the case in which that holds. */ - -static int -compare_base_symbol_refs (const_rtx x_base, const_rtx y_base, - HOST_WIDE_INT *distance) -{ - tree x_decl = SYMBOL_REF_DECL (x_base); - tree y_decl = SYMBOL_REF_DECL (y_base); - bool binds_def = true; - - if (XSTR (x_base, 0) == XSTR (y_base, 0)) - return 1; - if (x_decl && y_decl) - return compare_base_decls (x_decl, y_decl); - if (x_decl || y_decl) - { - if (!x_decl) - { - std::swap (x_decl, y_decl); - std::swap (x_base, y_base); - } - /* We handle specially only section anchors. Other symbols are - either equal (via aliasing) or refer to different objects. */ - if (!SYMBOL_REF_HAS_BLOCK_INFO_P (y_base)) - return -1; - /* Anchors contains static VAR_DECLs and CONST_DECLs. We are safe - to ignore CONST_DECLs because they are readonly. */ - if (!VAR_P (x_decl) - || (!TREE_STATIC (x_decl) && !TREE_PUBLIC (x_decl))) - return 0; - - symtab_node *x_node = symtab_node::get_create (x_decl) - ->ultimate_alias_target (); - /* External variable cannot be in section anchor. */ - if (!x_node->definition) - return 0; - x_base = XEXP (DECL_RTL (x_node->decl), 0); - /* If not in anchor, we can disambiguate. */ - if (!SYMBOL_REF_HAS_BLOCK_INFO_P (x_base)) - return 0; - - /* We have an alias of anchored variable. If it can be interposed; - we must assume it may or may not alias its anchor. */ - binds_def = decl_binds_to_current_def_p (x_decl); - } - /* If we have variable in section anchor, we can compare by offset. */ - if (SYMBOL_REF_HAS_BLOCK_INFO_P (x_base) - && SYMBOL_REF_HAS_BLOCK_INFO_P (y_base)) - { - if (SYMBOL_REF_BLOCK (x_base) != SYMBOL_REF_BLOCK (y_base)) - return 0; - if (distance) - *distance += (SYMBOL_REF_BLOCK_OFFSET (y_base) - - SYMBOL_REF_BLOCK_OFFSET (x_base)); - return binds_def ? 1 : -1; - } - /* Either the symbols are equal (via aliasing) or they refer to - different objects. */ - return -1; -} - -/* Return 0 if the addresses X and Y are known to point to different - objects, 1 if they might be pointers to the same object. */ - -static int -base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base, - machine_mode x_mode, machine_mode y_mode) -{ - /* If the address itself has no known base see if a known equivalent - value has one. If either address still has no known base, nothing - is known about aliasing. */ - if (x_base == 0) - { - rtx x_c; - - if (! flag_expensive_optimizations || (x_c = canon_rtx (x)) == x) - return 1; - - x_base = find_base_term (x_c); - if (x_base == 0) - return 1; - } - - if (y_base == 0) - { - rtx y_c; - if (! flag_expensive_optimizations || (y_c = canon_rtx (y)) == y) - return 1; - - y_base = find_base_term (y_c); - if (y_base == 0) - return 1; - } - - /* If the base addresses are equal nothing is known about aliasing. */ - if (rtx_equal_p (x_base, y_base)) - return 1; - - /* The base addresses are different expressions. If they are not accessed - via AND, there is no conflict. We can bring knowledge of object - alignment into play here. For example, on alpha, "char a, b;" can - alias one another, though "char a; long b;" cannot. AND addresses may - implicitly alias surrounding objects; i.e. unaligned access in DImode - via AND address can alias all surrounding object types except those - with aligment 8 or higher. */ - if (GET_CODE (x) == AND && GET_CODE (y) == AND) - return 1; - if (GET_CODE (x) == AND - && (!CONST_INT_P (XEXP (x, 1)) - || (int) GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1)))) - return 1; - if (GET_CODE (y) == AND - && (!CONST_INT_P (XEXP (y, 1)) - || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1)))) - return 1; - - /* Differing symbols not accessed via AND never alias. */ - if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF) - return compare_base_symbol_refs (x_base, y_base) != 0; - - if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS) - return 0; - - if (unique_base_value_p (x_base) || unique_base_value_p (y_base)) - return 0; - - return 1; -} - -/* Return TRUE if EXPR refers to a VALUE whose uid is greater than - (or equal to) that of V. */ - -static bool -refs_newer_value_p (const_rtx expr, rtx v) -{ - int minuid = CSELIB_VAL_PTR (v)->uid; - subrtx_iterator::array_type array; - FOR_EACH_SUBRTX (iter, array, expr, NONCONST) - if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid >= minuid) - return true; - return false; -} - -/* Convert the address X into something we can use. This is done by returning - it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE - we call cselib to get a more useful rtx. */ - -rtx -get_addr (rtx x) -{ - cselib_val *v; - struct elt_loc_list *l; - - if (GET_CODE (x) != VALUE) - { - if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS) - && GET_CODE (XEXP (x, 0)) == VALUE - && CONST_SCALAR_INT_P (XEXP (x, 1))) - { - rtx op0 = get_addr (XEXP (x, 0)); - if (op0 != XEXP (x, 0)) - { - poly_int64 c; - if (GET_CODE (x) == PLUS - && poly_int_rtx_p (XEXP (x, 1), &c)) - return plus_constant (GET_MODE (x), op0, c); - return simplify_gen_binary (GET_CODE (x), GET_MODE (x), - op0, XEXP (x, 1)); - } - } - return x; - } - v = CSELIB_VAL_PTR (x); - if (v) - { - bool have_equivs = cselib_have_permanent_equivalences (); - if (have_equivs) - v = canonical_cselib_val (v); - for (l = v->locs; l; l = l->next) - if (CONSTANT_P (l->loc)) - return l->loc; - for (l = v->locs; l; l = l->next) - if (!REG_P (l->loc) && !MEM_P (l->loc) - /* Avoid infinite recursion when potentially dealing with - var-tracking artificial equivalences, by skipping the - equivalences themselves, and not choosing expressions - that refer to newer VALUEs. */ - && (!have_equivs - || (GET_CODE (l->loc) != VALUE - && !refs_newer_value_p (l->loc, x)))) - return l->loc; - if (have_equivs) - { - for (l = v->locs; l; l = l->next) - if (REG_P (l->loc) - || (GET_CODE (l->loc) != VALUE - && !refs_newer_value_p (l->loc, x))) - return l->loc; - /* Return the canonical value. */ - return v->val_rtx; - } - if (v->locs) - return v->locs->loc; - } - return x; -} - -/* Return the address of the (N_REFS + 1)th memory reference to ADDR - where SIZE is the size in bytes of the memory reference. If ADDR - is not modified by the memory reference then ADDR is returned. */ - -static rtx -addr_side_effect_eval (rtx addr, poly_int64 size, int n_refs) -{ - poly_int64 offset = 0; - - switch (GET_CODE (addr)) - { - case PRE_INC: - offset = (n_refs + 1) * size; - break; - case PRE_DEC: - offset = -(n_refs + 1) * size; - break; - case POST_INC: - offset = n_refs * size; - break; - case POST_DEC: - offset = -n_refs * size; - break; - - default: - return addr; - } - - addr = plus_constant (GET_MODE (addr), XEXP (addr, 0), offset); - addr = canon_rtx (addr); - - return addr; -} - -/* Return TRUE if an object X sized at XSIZE bytes and another object - Y sized at YSIZE bytes, starting C bytes after X, may overlap. If - any of the sizes is zero, assume an overlap, otherwise use the - absolute value of the sizes as the actual sizes. */ - -static inline bool -offset_overlap_p (poly_int64 c, poly_int64 xsize, poly_int64 ysize) -{ - if (known_eq (xsize, 0) || known_eq (ysize, 0)) - return true; - - if (maybe_ge (c, 0)) - return maybe_gt (maybe_lt (xsize, 0) ? -xsize : xsize, c); - else - return maybe_gt (maybe_lt (ysize, 0) ? -ysize : ysize, -c); -} - -/* Return one if X and Y (memory addresses) reference the - same location in memory or if the references overlap. - Return zero if they do not overlap, else return - minus one in which case they still might reference the same location. - - C is an offset accumulator. When - C is nonzero, we are testing aliases between X and Y + C. - XSIZE is the size in bytes of the X reference, - similarly YSIZE is the size in bytes for Y. - Expect that canon_rtx has been already called for X and Y. - - If XSIZE or YSIZE is zero, we do not know the amount of memory being - referenced (the reference was BLKmode), so make the most pessimistic - assumptions. - - If XSIZE or YSIZE is negative, we may access memory outside the object - being referenced as a side effect. This can happen when using AND to - align memory references, as is done on the Alpha. - - Nice to notice that varying addresses cannot conflict with fp if no - local variables had their addresses taken, but that's too hard now. - - ??? Contrary to the tree alias oracle this does not return - one for X + non-constant and Y + non-constant when X and Y are equal. - If that is fixed the TBAA hack for union type-punning can be removed. */ - -static int -memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, - poly_int64 c) -{ - if (GET_CODE (x) == VALUE) - { - if (REG_P (y)) - { - struct elt_loc_list *l = NULL; - if (CSELIB_VAL_PTR (x)) - for (l = canonical_cselib_val (CSELIB_VAL_PTR (x))->locs; - l; l = l->next) - if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, y)) - break; - if (l) - x = y; - else - x = get_addr (x); - } - /* Don't call get_addr if y is the same VALUE. */ - else if (x != y) - x = get_addr (x); - } - if (GET_CODE (y) == VALUE) - { - if (REG_P (x)) - { - struct elt_loc_list *l = NULL; - if (CSELIB_VAL_PTR (y)) - for (l = canonical_cselib_val (CSELIB_VAL_PTR (y))->locs; - l; l = l->next) - if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, x)) - break; - if (l) - y = x; - else - y = get_addr (y); - } - /* Don't call get_addr if x is the same VALUE. */ - else if (y != x) - y = get_addr (y); - } - if (GET_CODE (x) == HIGH) - x = XEXP (x, 0); - else if (GET_CODE (x) == LO_SUM) - x = XEXP (x, 1); - else - x = addr_side_effect_eval (x, maybe_lt (xsize, 0) ? -xsize : xsize, 0); - if (GET_CODE (y) == HIGH) - y = XEXP (y, 0); - else if (GET_CODE (y) == LO_SUM) - y = XEXP (y, 1); - else - y = addr_side_effect_eval (y, maybe_lt (ysize, 0) ? -ysize : ysize, 0); - - if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF) - { - HOST_WIDE_INT distance = 0; - int cmp = compare_base_symbol_refs (x, y, &distance); - - /* If both decls are the same, decide by offsets. */ - if (cmp == 1) - return offset_overlap_p (c + distance, xsize, ysize); - /* Assume a potential overlap for symbolic addresses that went - through alignment adjustments (i.e., that have negative - sizes), because we can't know how far they are from each - other. */ - if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0)) - return -1; - /* If decls are different or we know by offsets that there is no overlap, - we win. */ - if (!cmp || !offset_overlap_p (c + distance, xsize, ysize)) - return 0; - /* Decls may or may not be different and offsets overlap....*/ - return -1; - } - else if (rtx_equal_for_memref_p (x, y)) - { - return offset_overlap_p (c, xsize, ysize); - } - - /* This code used to check for conflicts involving stack references and - globals but the base address alias code now handles these cases. */ - - if (GET_CODE (x) == PLUS) - { - /* The fact that X is canonicalized means that this - PLUS rtx is canonicalized. */ - rtx x0 = XEXP (x, 0); - rtx x1 = XEXP (x, 1); - - /* However, VALUEs might end up in different positions even in - canonical PLUSes. Comparing their addresses is enough. */ - if (x0 == y) - return memrefs_conflict_p (xsize, x1, ysize, const0_rtx, c); - else if (x1 == y) - return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c); - - poly_int64 cx1, cy1; - if (GET_CODE (y) == PLUS) - { - /* The fact that Y is canonicalized means that this - PLUS rtx is canonicalized. */ - rtx y0 = XEXP (y, 0); - rtx y1 = XEXP (y, 1); - - if (x0 == y1) - return memrefs_conflict_p (xsize, x1, ysize, y0, c); - if (x1 == y0) - return memrefs_conflict_p (xsize, x0, ysize, y1, c); - - if (rtx_equal_for_memref_p (x1, y1)) - return memrefs_conflict_p (xsize, x0, ysize, y0, c); - if (rtx_equal_for_memref_p (x0, y0)) - return memrefs_conflict_p (xsize, x1, ysize, y1, c); - if (poly_int_rtx_p (x1, &cx1)) - { - if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x0, ysize, y0, - c - cx1 + cy1); - else - return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); - } - else if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); - - return -1; - } - else if (poly_int_rtx_p (x1, &cx1)) - return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); - } - else if (GET_CODE (y) == PLUS) - { - /* The fact that Y is canonicalized means that this - PLUS rtx is canonicalized. */ - rtx y0 = XEXP (y, 0); - rtx y1 = XEXP (y, 1); - - if (x == y0) - return memrefs_conflict_p (xsize, const0_rtx, ysize, y1, c); - if (x == y1) - return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c); - - poly_int64 cy1; - if (poly_int_rtx_p (y1, &cy1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); - else - return -1; - } - - if (GET_CODE (x) == GET_CODE (y)) - switch (GET_CODE (x)) - { - case MULT: - { - /* Handle cases where we expect the second operands to be the - same, and check only whether the first operand would conflict - or not. */ - rtx x0, y0; - rtx x1 = canon_rtx (XEXP (x, 1)); - rtx y1 = canon_rtx (XEXP (y, 1)); - if (! rtx_equal_for_memref_p (x1, y1)) - return -1; - x0 = canon_rtx (XEXP (x, 0)); - y0 = canon_rtx (XEXP (y, 0)); - if (rtx_equal_for_memref_p (x0, y0)) - return offset_overlap_p (c, xsize, ysize); - - /* Can't properly adjust our sizes. */ - poly_int64 c1; - if (!poly_int_rtx_p (x1, &c1) - || !can_div_trunc_p (xsize, c1, &xsize) - || !can_div_trunc_p (ysize, c1, &ysize) - || !can_div_trunc_p (c, c1, &c)) - return -1; - return memrefs_conflict_p (xsize, x0, ysize, y0, c); - } - - default: - break; - } - - /* Deal with alignment ANDs by adjusting offset and size so as to - cover the maximum range, without taking any previously known - alignment into account. Make a size negative after such an - adjustments, so that, if we end up with e.g. two SYMBOL_REFs, we - assume a potential overlap, because they may end up in contiguous - memory locations and the stricter-alignment access may span over - part of both. */ - if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))) - { - HOST_WIDE_INT sc = INTVAL (XEXP (x, 1)); - unsigned HOST_WIDE_INT uc = sc; - if (sc < 0 && pow2_or_zerop (-uc)) - { - if (maybe_gt (xsize, 0)) - xsize = -xsize; - if (maybe_ne (xsize, 0)) - xsize += sc + 1; - c -= sc + 1; - return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), - ysize, y, c); - } - } - if (GET_CODE (y) == AND && CONST_INT_P (XEXP (y, 1))) - { - HOST_WIDE_INT sc = INTVAL (XEXP (y, 1)); - unsigned HOST_WIDE_INT uc = sc; - if (sc < 0 && pow2_or_zerop (-uc)) - { - if (maybe_gt (ysize, 0)) - ysize = -ysize; - if (maybe_ne (ysize, 0)) - ysize += sc + 1; - c += sc + 1; - return memrefs_conflict_p (xsize, x, - ysize, canon_rtx (XEXP (y, 0)), c); - } - } - - if (CONSTANT_P (x)) - { - poly_int64 cx, cy; - if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy)) - { - c += cy - cx; - return offset_overlap_p (c, xsize, ysize); - } - - if (GET_CODE (x) == CONST) - { - if (GET_CODE (y) == CONST) - return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), - ysize, canon_rtx (XEXP (y, 0)), c); - else - return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), - ysize, y, c); - } - if (GET_CODE (y) == CONST) - return memrefs_conflict_p (xsize, x, ysize, - canon_rtx (XEXP (y, 0)), c); - - /* Assume a potential overlap for symbolic addresses that went - through alignment adjustments (i.e., that have negative - sizes), because we can't know how far they are from each - other. */ - if (CONSTANT_P (y)) - return (maybe_lt (xsize, 0) - || maybe_lt (ysize, 0) - || offset_overlap_p (c, xsize, ysize)); - - return -1; - } - - return -1; -} - -/* Functions to compute memory dependencies. - - Since we process the insns in execution order, we can build tables - to keep track of what registers are fixed (and not aliased), what registers - are varying in known ways, and what registers are varying in unknown - ways. - - If both memory references are volatile, then there must always be a - dependence between the two references, since their order cannot be - changed. A volatile and non-volatile reference can be interchanged - though. - - We also must allow AND addresses, because they may generate accesses - outside the object being referenced. This is used to generate aligned - addresses from unaligned addresses, for instance, the alpha - storeqi_unaligned pattern. */ - -/* Read dependence: X is read after read in MEM takes place. There can - only be a dependence here if both reads are volatile, or if either is - an explicit barrier. */ - -int -read_dependence (const_rtx mem, const_rtx x) -{ - if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - return true; - if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER - || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) - return true; - return false; -} - -/* Look at the bottom of the COMPONENT_REF list for a DECL, and return it. */ - -static tree -decl_for_component_ref (tree x) -{ - do - { - x = TREE_OPERAND (x, 0); - } - while (x && TREE_CODE (x) == COMPONENT_REF); - - return x && DECL_P (x) ? x : NULL_TREE; -} - -/* Walk up the COMPONENT_REF list in X and adjust *OFFSET to compensate - for the offset of the field reference. *KNOWN_P says whether the - offset is known. */ - -static void -adjust_offset_for_component_ref (tree x, bool *known_p, - poly_int64 *offset) -{ - if (!*known_p) - return; - do - { - tree xoffset = component_ref_field_offset (x); - tree field = TREE_OPERAND (x, 1); - if (!poly_int_tree_p (xoffset)) - { - *known_p = false; - return; - } - - poly_offset_int woffset - = (wi::to_poly_offset (xoffset) - + (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)) - >> LOG2_BITS_PER_UNIT) - + *offset); - if (!woffset.to_shwi (offset)) - { - *known_p = false; - return; - } - - x = TREE_OPERAND (x, 0); - } - while (x && TREE_CODE (x) == COMPONENT_REF); -} - -/* Return nonzero if we can determine the exprs corresponding to memrefs - X and Y and they do not overlap. - If LOOP_VARIANT is set, skip offset-based disambiguation */ - -int -nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant) -{ - tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y); - rtx rtlx, rtly; - rtx basex, basey; - bool moffsetx_known_p, moffsety_known_p; - poly_int64 moffsetx = 0, moffsety = 0; - poly_int64 offsetx = 0, offsety = 0, sizex, sizey; - - /* Unless both have exprs, we can't tell anything. */ - if (exprx == 0 || expry == 0) - return 0; - - /* For spill-slot accesses make sure we have valid offsets. */ - if ((exprx == get_spill_slot_decl (false) - && ! MEM_OFFSET_KNOWN_P (x)) - || (expry == get_spill_slot_decl (false) - && ! MEM_OFFSET_KNOWN_P (y))) - return 0; - - /* If the field reference test failed, look at the DECLs involved. */ - moffsetx_known_p = MEM_OFFSET_KNOWN_P (x); - if (moffsetx_known_p) - moffsetx = MEM_OFFSET (x); - if (TREE_CODE (exprx) == COMPONENT_REF) - { - tree t = decl_for_component_ref (exprx); - if (! t) - return 0; - adjust_offset_for_component_ref (exprx, &moffsetx_known_p, &moffsetx); - exprx = t; - } - - moffsety_known_p = MEM_OFFSET_KNOWN_P (y); - if (moffsety_known_p) - moffsety = MEM_OFFSET (y); - if (TREE_CODE (expry) == COMPONENT_REF) - { - tree t = decl_for_component_ref (expry); - if (! t) - return 0; - adjust_offset_for_component_ref (expry, &moffsety_known_p, &moffsety); - expry = t; - } - - if (! DECL_P (exprx) || ! DECL_P (expry)) - return 0; - - /* If we refer to different gimple registers, or one gimple register - and one non-gimple-register, we know they can't overlap. First, - gimple registers don't have their addresses taken. Now, there - could be more than one stack slot for (different versions of) the - same gimple register, but we can presumably tell they don't - overlap based on offsets from stack base addresses elsewhere. - It's important that we don't proceed to DECL_RTL, because gimple - registers may not pass DECL_RTL_SET_P, and make_decl_rtl won't be - able to do anything about them since no SSA information will have - remained to guide it. */ - if (is_gimple_reg (exprx) || is_gimple_reg (expry)) - return exprx != expry - || (moffsetx_known_p && moffsety_known_p - && MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y) - && !offset_overlap_p (moffsety - moffsetx, - MEM_SIZE (x), MEM_SIZE (y))); - - /* With invalid code we can end up storing into the constant pool. - Bail out to avoid ICEing when creating RTL for this. - See gfortran.dg/lto/20091028-2_0.f90. */ - if (TREE_CODE (exprx) == CONST_DECL - || TREE_CODE (expry) == CONST_DECL) - return 1; - - /* If one decl is known to be a function or label in a function and - the other is some kind of data, they can't overlap. */ - if ((TREE_CODE (exprx) == FUNCTION_DECL - || TREE_CODE (exprx) == LABEL_DECL) - != (TREE_CODE (expry) == FUNCTION_DECL - || TREE_CODE (expry) == LABEL_DECL)) - return 1; - - /* If either of the decls doesn't have DECL_RTL set (e.g. marked as - living in multiple places), we can't tell anything. Exception - are FUNCTION_DECLs for which we can create DECL_RTL on demand. */ - if ((!DECL_RTL_SET_P (exprx) && TREE_CODE (exprx) != FUNCTION_DECL) - || (!DECL_RTL_SET_P (expry) && TREE_CODE (expry) != FUNCTION_DECL)) - return 0; - - rtlx = DECL_RTL (exprx); - rtly = DECL_RTL (expry); - - /* If either RTL is not a MEM, it must be a REG or CONCAT, meaning they - can't overlap unless they are the same because we never reuse that part - of the stack frame used for locals for spilled pseudos. */ - if ((!MEM_P (rtlx) || !MEM_P (rtly)) - && ! rtx_equal_p (rtlx, rtly)) - return 1; - - /* If we have MEMs referring to different address spaces (which can - potentially overlap), we cannot easily tell from the addresses - whether the references overlap. */ - if (MEM_P (rtlx) && MEM_P (rtly) - && MEM_ADDR_SPACE (rtlx) != MEM_ADDR_SPACE (rtly)) - return 0; - - /* Get the base and offsets of both decls. If either is a register, we - know both are and are the same, so use that as the base. The only - we can avoid overlap is if we can deduce that they are nonoverlapping - pieces of that decl, which is very rare. */ - basex = MEM_P (rtlx) ? XEXP (rtlx, 0) : rtlx; - basex = strip_offset_and_add (basex, &offsetx); - - basey = MEM_P (rtly) ? XEXP (rtly, 0) : rtly; - basey = strip_offset_and_add (basey, &offsety); - - /* If the bases are different, we know they do not overlap if both - are constants or if one is a constant and the other a pointer into the - stack frame. Otherwise a different base means we can't tell if they - overlap or not. */ - if (compare_base_decls (exprx, expry) == 0) - return ((CONSTANT_P (basex) && CONSTANT_P (basey)) - || (CONSTANT_P (basex) && REG_P (basey) - && REGNO_PTR_FRAME_P (REGNO (basey))) - || (CONSTANT_P (basey) && REG_P (basex) - && REGNO_PTR_FRAME_P (REGNO (basex)))); - - /* Offset based disambiguation not appropriate for loop invariant */ - if (loop_invariant) - return 0; - - /* Offset based disambiguation is OK even if we do not know that the - declarations are necessarily different - (i.e. compare_base_decls (exprx, expry) == -1) */ - - sizex = (!MEM_P (rtlx) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtlx))) - : MEM_SIZE_KNOWN_P (rtlx) ? MEM_SIZE (rtlx) - : -1); - sizey = (!MEM_P (rtly) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtly))) - : MEM_SIZE_KNOWN_P (rtly) ? MEM_SIZE (rtly) - : -1); - - /* If we have an offset for either memref, it can update the values computed - above. */ - if (moffsetx_known_p) - offsetx += moffsetx, sizex -= moffsetx; - if (moffsety_known_p) - offsety += moffsety, sizey -= moffsety; - - /* If a memref has both a size and an offset, we can use the smaller size. - We can't do this if the offset isn't known because we must view this - memref as being anywhere inside the DECL's MEM. */ - if (MEM_SIZE_KNOWN_P (x) && moffsetx_known_p) - sizex = MEM_SIZE (x); - if (MEM_SIZE_KNOWN_P (y) && moffsety_known_p) - sizey = MEM_SIZE (y); - - return !ranges_maybe_overlap_p (offsetx, sizex, offsety, sizey); -} - -/* Helper for true_dependence and canon_true_dependence. - Checks for true dependence: X is read after store in MEM takes place. - - If MEM_CANONICALIZED is FALSE, then X_ADDR and MEM_ADDR should be - NULL_RTX, and the canonical addresses of MEM and X are both computed - here. If MEM_CANONICALIZED, then MEM must be already canonicalized. - - If X_ADDR is non-NULL, it is used in preference of XEXP (x, 0). - - Returns 1 if there is a true dependence, 0 otherwise. */ - -static int -true_dependence_1 (const_rtx mem, machine_mode mem_mode, rtx mem_addr, - const_rtx x, rtx x_addr, bool mem_canonicalized) -{ - rtx true_mem_addr; - rtx base; - int ret; - - gcc_checking_assert (mem_canonicalized ? (mem_addr != NULL_RTX) - : (mem_addr == NULL_RTX && x_addr == NULL_RTX)); - - if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - return 1; - - /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. - This is used in epilogue deallocation functions, and in cselib. */ - if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) - return 1; - if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) - return 1; - if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER - || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) - return 1; - - if (! x_addr) - x_addr = XEXP (x, 0); - x_addr = get_addr (x_addr); - - if (! mem_addr) - { - mem_addr = XEXP (mem, 0); - if (mem_mode == VOIDmode) - mem_mode = GET_MODE (mem); - } - true_mem_addr = get_addr (mem_addr); - - /* Read-only memory is by definition never modified, and therefore can't - conflict with anything. However, don't assume anything when AND - addresses are involved and leave to the code below to determine - dependence. We don't expect to find read-only set on MEM, but - stupid user tricks can produce them, so don't die. */ - if (MEM_READONLY_P (x) - && GET_CODE (x_addr) != AND - && GET_CODE (true_mem_addr) != AND) - return 0; - - /* If we have MEMs referring to different address spaces (which can - potentially overlap), we cannot easily tell from the addresses - whether the references overlap. */ - if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) - return 1; - - base = find_base_term (x_addr); - if (base && (GET_CODE (base) == LABEL_REF - || (GET_CODE (base) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (base)))) - return 0; - - rtx mem_base = find_base_term (true_mem_addr); - if (! base_alias_check (x_addr, base, true_mem_addr, mem_base, - GET_MODE (x), mem_mode)) - return 0; - - x_addr = canon_rtx (x_addr); - if (!mem_canonicalized) - mem_addr = canon_rtx (true_mem_addr); - - if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0)) != -1) - return ret; - - if (mems_in_disjoint_alias_sets_p (x, mem)) - return 0; - - if (nonoverlapping_memrefs_p (mem, x, false)) - return 0; - - return rtx_refs_may_alias_p (x, mem, true); -} - -/* True dependence: X is read after store in MEM takes place. */ - -int -true_dependence (const_rtx mem, machine_mode mem_mode, const_rtx x) -{ - return true_dependence_1 (mem, mem_mode, NULL_RTX, - x, NULL_RTX, /*mem_canonicalized=*/false); -} - -/* Canonical true dependence: X is read after store in MEM takes place. - Variant of true_dependence which assumes MEM has already been - canonicalized (hence we no longer do that here). - The mem_addr argument has been added, since true_dependence_1 computed - this value prior to canonicalizing. */ - -int -canon_true_dependence (const_rtx mem, machine_mode mem_mode, rtx mem_addr, - const_rtx x, rtx x_addr) -{ - return true_dependence_1 (mem, mem_mode, mem_addr, - x, x_addr, /*mem_canonicalized=*/true); -} - -/* Returns nonzero if a write to X might alias a previous read from - (or, if WRITEP is true, a write to) MEM. - If X_CANONCALIZED is true, then X_ADDR is the canonicalized address of X, - and X_MODE the mode for that access. - If MEM_CANONICALIZED is true, MEM is canonicalized. */ - -static int -write_dependence_p (const_rtx mem, - const_rtx x, machine_mode x_mode, rtx x_addr, - bool mem_canonicalized, bool x_canonicalized, bool writep) -{ - rtx mem_addr; - rtx true_mem_addr, true_x_addr; - rtx base; - int ret; - - gcc_checking_assert (x_canonicalized - ? (x_addr != NULL_RTX - && (x_mode != VOIDmode || GET_MODE (x) == VOIDmode)) - : (x_addr == NULL_RTX && x_mode == VOIDmode)); - - if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - return 1; - - /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. - This is used in epilogue deallocation functions. */ - if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) - return 1; - if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) - return 1; - if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER - || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) - return 1; - - if (!x_addr) - x_addr = XEXP (x, 0); - true_x_addr = get_addr (x_addr); - - mem_addr = XEXP (mem, 0); - true_mem_addr = get_addr (mem_addr); - - /* A read from read-only memory can't conflict with read-write memory. - Don't assume anything when AND addresses are involved and leave to - the code below to determine dependence. */ - if (!writep - && MEM_READONLY_P (mem) - && GET_CODE (true_x_addr) != AND - && GET_CODE (true_mem_addr) != AND) - return 0; - - /* If we have MEMs referring to different address spaces (which can - potentially overlap), we cannot easily tell from the addresses - whether the references overlap. */ - if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) - return 1; - - base = find_base_term (true_mem_addr); - if (! writep - && base - && (GET_CODE (base) == LABEL_REF - || (GET_CODE (base) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (base)))) - return 0; - - rtx x_base = find_base_term (true_x_addr); - if (! base_alias_check (true_x_addr, x_base, true_mem_addr, base, - GET_MODE (x), GET_MODE (mem))) - return 0; - - if (!x_canonicalized) - { - x_addr = canon_rtx (true_x_addr); - x_mode = GET_MODE (x); - } - if (!mem_canonicalized) - mem_addr = canon_rtx (true_mem_addr); - - if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, - GET_MODE_SIZE (x_mode), x_addr, 0)) != -1) - return ret; - - if (nonoverlapping_memrefs_p (x, mem, false)) - return 0; - - return rtx_refs_may_alias_p (x, mem, false); -} - -/* Anti dependence: X is written after read in MEM takes place. */ - -int -anti_dependence (const_rtx mem, const_rtx x) -{ - return write_dependence_p (mem, x, VOIDmode, NULL_RTX, - /*mem_canonicalized=*/false, - /*x_canonicalized*/false, /*writep=*/false); -} - -/* Likewise, but we already have a canonicalized MEM, and X_ADDR for X. - Also, consider X in X_MODE (which might be from an enclosing - STRICT_LOW_PART / ZERO_EXTRACT). - If MEM_CANONICALIZED is true, MEM is canonicalized. */ - -int -canon_anti_dependence (const_rtx mem, bool mem_canonicalized, - const_rtx x, machine_mode x_mode, rtx x_addr) -{ - return write_dependence_p (mem, x, x_mode, x_addr, - mem_canonicalized, /*x_canonicalized=*/true, - /*writep=*/false); -} - -/* Output dependence: X is written after store in MEM takes place. */ - -int -output_dependence (const_rtx mem, const_rtx x) -{ - return write_dependence_p (mem, x, VOIDmode, NULL_RTX, - /*mem_canonicalized=*/false, - /*x_canonicalized*/false, /*writep=*/true); -} - -/* Likewise, but we already have a canonicalized MEM, and X_ADDR for X. - Also, consider X in X_MODE (which might be from an enclosing - STRICT_LOW_PART / ZERO_EXTRACT). - If MEM_CANONICALIZED is true, MEM is canonicalized. */ - -int -canon_output_dependence (const_rtx mem, bool mem_canonicalized, - const_rtx x, machine_mode x_mode, rtx x_addr) -{ - return write_dependence_p (mem, x, x_mode, x_addr, - mem_canonicalized, /*x_canonicalized=*/true, - /*writep=*/true); -} - - - -/* Check whether X may be aliased with MEM. Don't do offset-based - memory disambiguation & TBAA. */ -int -may_alias_p (const_rtx mem, const_rtx x) -{ - rtx x_addr, mem_addr; - - if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - return 1; - - /* (mem:BLK (scratch)) is a special mechanism to conflict with everything. - This is used in epilogue deallocation functions. */ - if (GET_MODE (x) == BLKmode && GET_CODE (XEXP (x, 0)) == SCRATCH) - return 1; - if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) - return 1; - if (MEM_ALIAS_SET (x) == ALIAS_SET_MEMORY_BARRIER - || MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) - return 1; - - x_addr = XEXP (x, 0); - x_addr = get_addr (x_addr); - - mem_addr = XEXP (mem, 0); - mem_addr = get_addr (mem_addr); - - /* Read-only memory is by definition never modified, and therefore can't - conflict with anything. However, don't assume anything when AND - addresses are involved and leave to the code below to determine - dependence. We don't expect to find read-only set on MEM, but - stupid user tricks can produce them, so don't die. */ - if (MEM_READONLY_P (x) - && GET_CODE (x_addr) != AND - && GET_CODE (mem_addr) != AND) - return 0; - - /* If we have MEMs referring to different address spaces (which can - potentially overlap), we cannot easily tell from the addresses - whether the references overlap. */ - if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x)) - return 1; - - rtx x_base = find_base_term (x_addr); - rtx mem_base = find_base_term (mem_addr); - if (! base_alias_check (x_addr, x_base, mem_addr, mem_base, - GET_MODE (x), GET_MODE (mem_addr))) - return 0; - - if (nonoverlapping_memrefs_p (mem, x, true)) - return 0; - - /* TBAA not valid for loop_invarint */ - return rtx_refs_may_alias_p (x, mem, false); -} - -void -init_alias_target (void) -{ - int i; - - if (!arg_base_value) - arg_base_value = gen_rtx_ADDRESS (VOIDmode, 0); - - memset (static_reg_base_value, 0, sizeof static_reg_base_value); - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - /* Check whether this register can hold an incoming pointer - argument. FUNCTION_ARG_REGNO_P tests outgoing register - numbers, so translate if necessary due to register windows. */ - if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i)) - && targetm.hard_regno_mode_ok (i, Pmode)) - static_reg_base_value[i] = arg_base_value; - - /* RTL code is required to be consistent about whether it uses the - stack pointer, the frame pointer or the argument pointer to - access a given area of the frame. We can therefore use the - base address to distinguish between the different areas. */ - static_reg_base_value[STACK_POINTER_REGNUM] - = unique_base_value (UNIQUE_BASE_VALUE_SP); - static_reg_base_value[ARG_POINTER_REGNUM] - = unique_base_value (UNIQUE_BASE_VALUE_ARGP); - static_reg_base_value[FRAME_POINTER_REGNUM] - = unique_base_value (UNIQUE_BASE_VALUE_FP); - - /* The above rules extend post-reload, with eliminations applying - consistently to each of the three pointers. Cope with cases in - which the frame pointer is eliminated to the hard frame pointer - rather than the stack pointer. */ - if (!HARD_FRAME_POINTER_IS_FRAME_POINTER) - static_reg_base_value[HARD_FRAME_POINTER_REGNUM] - = unique_base_value (UNIQUE_BASE_VALUE_HFP); -} - -/* Set MEMORY_MODIFIED when X modifies DATA (that is assumed - to be memory reference. */ -static bool memory_modified; -static void -memory_modified_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) -{ - if (MEM_P (x)) - { - if (anti_dependence (x, (const_rtx)data) || output_dependence (x, (const_rtx)data)) - memory_modified = true; - } -} - - -/* Return true when INSN possibly modify memory contents of MEM - (i.e. address can be modified). */ -bool -memory_modified_in_insn_p (const_rtx mem, const_rtx insn) -{ - if (!INSN_P (insn)) - return false; - /* Conservatively assume all non-readonly MEMs might be modified in - calls. */ - if (CALL_P (insn)) - return true; - memory_modified = false; - note_stores (as_a<const rtx_insn *> (insn), memory_modified_1, - CONST_CAST_RTX(mem)); - return memory_modified; -} - -/* Initialize the aliasing machinery. Initialize the REG_KNOWN_VALUE - array. */ - -void -init_alias_analysis (void) -{ - unsigned int maxreg = max_reg_num (); - int changed, pass; - int i; - unsigned int ui; - rtx_insn *insn; - rtx val; - int rpo_cnt; - int *rpo; - - timevar_push (TV_ALIAS_ANALYSIS); - - vec_safe_grow_cleared (reg_known_value, maxreg - FIRST_PSEUDO_REGISTER, - true); - reg_known_equiv_p = sbitmap_alloc (maxreg - FIRST_PSEUDO_REGISTER); - bitmap_clear (reg_known_equiv_p); - - /* If we have memory allocated from the previous run, use it. */ - if (old_reg_base_value) - reg_base_value = old_reg_base_value; - - if (reg_base_value) - reg_base_value->truncate (0); - - vec_safe_grow_cleared (reg_base_value, maxreg, true); - - new_reg_base_value = XNEWVEC (rtx, maxreg); - reg_seen = sbitmap_alloc (maxreg); - - /* The basic idea is that each pass through this loop will use the - "constant" information from the previous pass to propagate alias - information through another level of assignments. - - The propagation is done on the CFG in reverse post-order, to propagate - things forward as far as possible in each iteration. - - This could get expensive if the assignment chains are long. Maybe - we should throttle the number of iterations, possibly based on - the optimization level or flag_expensive_optimizations. - - We could propagate more information in the first pass by making use - of DF_REG_DEF_COUNT to determine immediately that the alias information - for a pseudo is "constant". - - A program with an uninitialized variable can cause an infinite loop - here. Instead of doing a full dataflow analysis to detect such problems - we just cap the number of iterations for the loop. - - The state of the arrays for the set chain in question does not matter - since the program has undefined behavior. */ - - rpo = XNEWVEC (int, n_basic_blocks_for_fn (cfun)); - rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false); - - pass = 0; - do - { - /* Assume nothing will change this iteration of the loop. */ - changed = 0; - - /* We want to assign the same IDs each iteration of this loop, so - start counting from one each iteration of the loop. */ - unique_id = 1; - - /* We're at the start of the function each iteration through the - loop, so we're copying arguments. */ - copying_arguments = true; - - /* Wipe the potential alias information clean for this pass. */ - memset (new_reg_base_value, 0, maxreg * sizeof (rtx)); - - /* Wipe the reg_seen array clean. */ - bitmap_clear (reg_seen); - - /* Initialize the alias information for this pass. */ - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (static_reg_base_value[i] - /* Don't treat the hard frame pointer as special if we - eliminated the frame pointer to the stack pointer instead. */ - && !(i == HARD_FRAME_POINTER_REGNUM - && reload_completed - && !frame_pointer_needed - && targetm.can_eliminate (FRAME_POINTER_REGNUM, - STACK_POINTER_REGNUM))) - { - new_reg_base_value[i] = static_reg_base_value[i]; - bitmap_set_bit (reg_seen, i); - } - - /* Walk the insns adding values to the new_reg_base_value array. */ - for (i = 0; i < rpo_cnt; i++) - { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]); - FOR_BB_INSNS (bb, insn) - { - if (NONDEBUG_INSN_P (insn)) - { - rtx note, set; - - /* If this insn has a noalias note, process it, Otherwise, - scan for sets. A simple set will have no side effects - which could change the base value of any other register. */ - - if (GET_CODE (PATTERN (insn)) == SET - && REG_NOTES (insn) != 0 - && find_reg_note (insn, REG_NOALIAS, NULL_RTX)) - record_set (SET_DEST (PATTERN (insn)), NULL_RTX, NULL); - else - note_stores (insn, record_set, NULL); - - set = single_set (insn); - - if (set != 0 - && REG_P (SET_DEST (set)) - && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) - { - unsigned int regno = REGNO (SET_DEST (set)); - rtx src = SET_SRC (set); - rtx t; - - note = find_reg_equal_equiv_note (insn); - if (note && REG_NOTE_KIND (note) == REG_EQUAL - && DF_REG_DEF_COUNT (regno) != 1) - note = NULL_RTX; - - poly_int64 offset; - if (note != NULL_RTX - && GET_CODE (XEXP (note, 0)) != EXPR_LIST - && ! rtx_varies_p (XEXP (note, 0), 1) - && ! reg_overlap_mentioned_p (SET_DEST (set), - XEXP (note, 0))) - { - set_reg_known_value (regno, XEXP (note, 0)); - set_reg_known_equiv_p (regno, - REG_NOTE_KIND (note) == REG_EQUIV); - } - else if (DF_REG_DEF_COUNT (regno) == 1 - && GET_CODE (src) == PLUS - && REG_P (XEXP (src, 0)) - && (t = get_reg_known_value (REGNO (XEXP (src, 0)))) - && poly_int_rtx_p (XEXP (src, 1), &offset)) - { - t = plus_constant (GET_MODE (src), t, offset); - set_reg_known_value (regno, t); - set_reg_known_equiv_p (regno, false); - } - else if (DF_REG_DEF_COUNT (regno) == 1 - && ! rtx_varies_p (src, 1)) - { - set_reg_known_value (regno, src); - set_reg_known_equiv_p (regno, false); - } - } - } - else if (NOTE_P (insn) - && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) - copying_arguments = false; - } - } - - /* Now propagate values from new_reg_base_value to reg_base_value. */ - gcc_assert (maxreg == (unsigned int) max_reg_num ()); - - for (ui = 0; ui < maxreg; ui++) - { - if (new_reg_base_value[ui] - && new_reg_base_value[ui] != (*reg_base_value)[ui] - && ! rtx_equal_p (new_reg_base_value[ui], (*reg_base_value)[ui])) - { - (*reg_base_value)[ui] = new_reg_base_value[ui]; - changed = 1; - } - } - } - while (changed && ++pass < MAX_ALIAS_LOOP_PASSES); - XDELETEVEC (rpo); - - /* Fill in the remaining entries. */ - FOR_EACH_VEC_ELT (*reg_known_value, i, val) - { - int regno = i + FIRST_PSEUDO_REGISTER; - if (! val) - set_reg_known_value (regno, regno_reg_rtx[regno]); - } - - /* Clean up. */ - free (new_reg_base_value); - new_reg_base_value = 0; - sbitmap_free (reg_seen); - reg_seen = 0; - timevar_pop (TV_ALIAS_ANALYSIS); -} - -/* Equate REG_BASE_VALUE (reg1) to REG_BASE_VALUE (reg2). - Special API for var-tracking pass purposes. */ - -void -vt_equate_reg_base_value (const_rtx reg1, const_rtx reg2) -{ - (*reg_base_value)[REGNO (reg1)] = REG_BASE_VALUE (reg2); -} - -void -end_alias_analysis (void) -{ - old_reg_base_value = reg_base_value; - vec_free (reg_known_value); - sbitmap_free (reg_known_equiv_p); -} - -void -dump_alias_stats_in_alias_c (FILE *s) -{ - fprintf (s, " TBAA oracle: %llu disambiguations %llu queries\n" - " %llu are in alias set 0\n" - " %llu queries asked about the same object\n" - " %llu queries asked about the same alias set\n" - " %llu access volatile\n" - " %llu are dependent in the DAG\n" - " %llu are aritificially in conflict with void *\n", - alias_stats.num_disambiguated, - alias_stats.num_alias_zero + alias_stats.num_same_alias_set - + alias_stats.num_same_objects + alias_stats.num_volatile - + alias_stats.num_dag + alias_stats.num_disambiguated - + alias_stats.num_universal, - alias_stats.num_alias_zero, alias_stats.num_same_alias_set, - alias_stats.num_same_objects, alias_stats.num_volatile, - alias_stats.num_dag, alias_stats.num_universal); -} -#include "gt-alias.h" |