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/tree-switch-conversion.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/tree-switch-conversion.c')
-rw-r--r-- | gcc/tree-switch-conversion.c | 2602 |
1 files changed, 0 insertions, 2602 deletions
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c deleted file mode 100644 index 670397c..0000000 --- a/gcc/tree-switch-conversion.c +++ /dev/null @@ -1,2602 +0,0 @@ -/* Lower GIMPLE_SWITCH expressions to something more efficient than - a jump table. - Copyright (C) 2006-2022 Free Software Foundation, Inc. - -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, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ - -/* This file handles the lowering of GIMPLE_SWITCH to an indexed - load, or a series of bit-test-and-branch expressions. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "backend.h" -#include "insn-codes.h" -#include "rtl.h" -#include "tree.h" -#include "gimple.h" -#include "cfghooks.h" -#include "tree-pass.h" -#include "ssa.h" -#include "optabs-tree.h" -#include "cgraph.h" -#include "gimple-pretty-print.h" -#include "fold-const.h" -#include "varasm.h" -#include "stor-layout.h" -#include "cfganal.h" -#include "gimplify.h" -#include "gimple-iterator.h" -#include "gimplify-me.h" -#include "gimple-fold.h" -#include "tree-cfg.h" -#include "cfgloop.h" -#include "alloc-pool.h" -#include "target.h" -#include "tree-into-ssa.h" -#include "omp-general.h" -#include "gimple-range.h" - -/* ??? For lang_hooks.types.type_for_mode, but is there a word_mode - type in the GIMPLE type system that is language-independent? */ -#include "langhooks.h" - -#include "tree-switch-conversion.h" - -using namespace tree_switch_conversion; - -/* Constructor. */ - -switch_conversion::switch_conversion (): m_final_bb (NULL), - m_constructors (NULL), m_default_values (NULL), - m_arr_ref_first (NULL), m_arr_ref_last (NULL), - m_reason (NULL), m_default_case_nonstandard (false), m_cfg_altered (false) -{ -} - -/* Collection information about SWTCH statement. */ - -void -switch_conversion::collect (gswitch *swtch) -{ - unsigned int branch_num = gimple_switch_num_labels (swtch); - tree min_case, max_case; - unsigned int i; - edge e, e_default, e_first; - edge_iterator ei; - - m_switch = swtch; - - /* The gimplifier has already sorted the cases by CASE_LOW and ensured there - is a default label which is the first in the vector. - Collect the bits we can deduce from the CFG. */ - m_index_expr = gimple_switch_index (swtch); - m_switch_bb = gimple_bb (swtch); - e_default = gimple_switch_default_edge (cfun, swtch); - m_default_bb = e_default->dest; - m_default_prob = e_default->probability; - - /* Get upper and lower bounds of case values, and the covered range. */ - min_case = gimple_switch_label (swtch, 1); - max_case = gimple_switch_label (swtch, branch_num - 1); - - m_range_min = CASE_LOW (min_case); - if (CASE_HIGH (max_case) != NULL_TREE) - m_range_max = CASE_HIGH (max_case); - else - m_range_max = CASE_LOW (max_case); - - m_contiguous_range = true; - tree last = CASE_HIGH (min_case) ? CASE_HIGH (min_case) : m_range_min; - for (i = 2; i < branch_num; i++) - { - tree elt = gimple_switch_label (swtch, i); - if (wi::to_wide (last) + 1 != wi::to_wide (CASE_LOW (elt))) - { - m_contiguous_range = false; - break; - } - last = CASE_HIGH (elt) ? CASE_HIGH (elt) : CASE_LOW (elt); - } - - if (m_contiguous_range) - e_first = gimple_switch_edge (cfun, swtch, 1); - else - e_first = e_default; - - /* See if there is one common successor block for all branch - targets. If it exists, record it in FINAL_BB. - Start with the destination of the first non-default case - if the range is contiguous and default case otherwise as - guess or its destination in case it is a forwarder block. */ - if (! single_pred_p (e_first->dest)) - m_final_bb = e_first->dest; - else if (single_succ_p (e_first->dest) - && ! single_pred_p (single_succ (e_first->dest))) - m_final_bb = single_succ (e_first->dest); - /* Require that all switch destinations are either that common - FINAL_BB or a forwarder to it, except for the default - case if contiguous range. */ - if (m_final_bb) - FOR_EACH_EDGE (e, ei, m_switch_bb->succs) - { - if (e->dest == m_final_bb) - continue; - - if (single_pred_p (e->dest) - && single_succ_p (e->dest) - && single_succ (e->dest) == m_final_bb) - continue; - - if (e == e_default && m_contiguous_range) - { - m_default_case_nonstandard = true; - continue; - } - - m_final_bb = NULL; - break; - } - - m_range_size - = int_const_binop (MINUS_EXPR, m_range_max, m_range_min); - - /* Get a count of the number of case labels. Single-valued case labels - simply count as one, but a case range counts double, since it may - require two compares if it gets lowered as a branching tree. */ - m_count = 0; - for (i = 1; i < branch_num; i++) - { - tree elt = gimple_switch_label (swtch, i); - m_count++; - if (CASE_HIGH (elt) - && ! tree_int_cst_equal (CASE_LOW (elt), CASE_HIGH (elt))) - m_count++; - } - - /* Get the number of unique non-default targets out of the GIMPLE_SWITCH - block. Assume a CFG cleanup would have already removed degenerate - switch statements, this allows us to just use EDGE_COUNT. */ - m_uniq = EDGE_COUNT (gimple_bb (swtch)->succs) - 1; -} - -/* Checks whether the range given by individual case statements of the switch - switch statement isn't too big and whether the number of branches actually - satisfies the size of the new array. */ - -bool -switch_conversion::check_range () -{ - gcc_assert (m_range_size); - if (!tree_fits_uhwi_p (m_range_size)) - { - m_reason = "index range way too large or otherwise unusable"; - return false; - } - - if (tree_to_uhwi (m_range_size) - > ((unsigned) m_count * param_switch_conversion_branch_ratio)) - { - m_reason = "the maximum range-branch ratio exceeded"; - return false; - } - - return true; -} - -/* Checks whether all but the final BB basic blocks are empty. */ - -bool -switch_conversion::check_all_empty_except_final () -{ - edge e, e_default = find_edge (m_switch_bb, m_default_bb); - edge_iterator ei; - - FOR_EACH_EDGE (e, ei, m_switch_bb->succs) - { - if (e->dest == m_final_bb) - continue; - - if (!empty_block_p (e->dest)) - { - if (m_contiguous_range && e == e_default) - { - m_default_case_nonstandard = true; - continue; - } - - m_reason = "bad case - a non-final BB not empty"; - return false; - } - } - - return true; -} - -/* This function checks whether all required values in phi nodes in final_bb - are constants. Required values are those that correspond to a basic block - which is a part of the examined switch statement. It returns true if the - phi nodes are OK, otherwise false. */ - -bool -switch_conversion::check_final_bb () -{ - gphi_iterator gsi; - - m_phi_count = 0; - for (gsi = gsi_start_phis (m_final_bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - unsigned int i; - - if (virtual_operand_p (gimple_phi_result (phi))) - continue; - - m_phi_count++; - - for (i = 0; i < gimple_phi_num_args (phi); i++) - { - basic_block bb = gimple_phi_arg_edge (phi, i)->src; - - if (bb == m_switch_bb - || (single_pred_p (bb) - && single_pred (bb) == m_switch_bb - && (!m_default_case_nonstandard - || empty_block_p (bb)))) - { - tree reloc, val; - const char *reason = NULL; - - val = gimple_phi_arg_def (phi, i); - if (!is_gimple_ip_invariant (val)) - reason = "non-invariant value from a case"; - else - { - reloc = initializer_constant_valid_p (val, TREE_TYPE (val)); - if ((flag_pic && reloc != null_pointer_node) - || (!flag_pic && reloc == NULL_TREE)) - { - if (reloc) - reason - = "value from a case would need runtime relocations"; - else - reason - = "value from a case is not a valid initializer"; - } - } - if (reason) - { - /* For contiguous range, we can allow non-constant - or one that needs relocation, as long as it is - only reachable from the default case. */ - if (bb == m_switch_bb) - bb = m_final_bb; - if (!m_contiguous_range || bb != m_default_bb) - { - m_reason = reason; - return false; - } - - unsigned int branch_num = gimple_switch_num_labels (m_switch); - for (unsigned int i = 1; i < branch_num; i++) - { - if (gimple_switch_label_bb (cfun, m_switch, i) == bb) - { - m_reason = reason; - return false; - } - } - m_default_case_nonstandard = true; - } - } - } - } - - return true; -} - -/* The following function allocates default_values, target_{in,out}_names and - constructors arrays. The last one is also populated with pointers to - vectors that will become constructors of new arrays. */ - -void -switch_conversion::create_temp_arrays () -{ - int i; - - m_default_values = XCNEWVEC (tree, m_phi_count * 3); - /* ??? Macros do not support multi argument templates in their - argument list. We create a typedef to work around that problem. */ - typedef vec<constructor_elt, va_gc> *vec_constructor_elt_gc; - m_constructors = XCNEWVEC (vec_constructor_elt_gc, m_phi_count); - m_target_inbound_names = m_default_values + m_phi_count; - m_target_outbound_names = m_target_inbound_names + m_phi_count; - for (i = 0; i < m_phi_count; i++) - vec_alloc (m_constructors[i], tree_to_uhwi (m_range_size) + 1); -} - -/* Populate the array of default values in the order of phi nodes. - DEFAULT_CASE is the CASE_LABEL_EXPR for the default switch branch - if the range is non-contiguous or the default case has standard - structure, otherwise it is the first non-default case instead. */ - -void -switch_conversion::gather_default_values (tree default_case) -{ - gphi_iterator gsi; - basic_block bb = label_to_block (cfun, CASE_LABEL (default_case)); - edge e; - int i = 0; - - gcc_assert (CASE_LOW (default_case) == NULL_TREE - || m_default_case_nonstandard); - - if (bb == m_final_bb) - e = find_edge (m_switch_bb, bb); - else - e = single_succ_edge (bb); - - for (gsi = gsi_start_phis (m_final_bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - if (virtual_operand_p (gimple_phi_result (phi))) - continue; - tree val = PHI_ARG_DEF_FROM_EDGE (phi, e); - gcc_assert (val); - m_default_values[i++] = val; - } -} - -/* The following function populates the vectors in the constructors array with - future contents of the static arrays. The vectors are populated in the - order of phi nodes. */ - -void -switch_conversion::build_constructors () -{ - unsigned i, branch_num = gimple_switch_num_labels (m_switch); - tree pos = m_range_min; - tree pos_one = build_int_cst (TREE_TYPE (pos), 1); - - for (i = 1; i < branch_num; i++) - { - tree cs = gimple_switch_label (m_switch, i); - basic_block bb = label_to_block (cfun, CASE_LABEL (cs)); - edge e; - tree high; - gphi_iterator gsi; - int j; - - if (bb == m_final_bb) - e = find_edge (m_switch_bb, bb); - else - e = single_succ_edge (bb); - gcc_assert (e); - - while (tree_int_cst_lt (pos, CASE_LOW (cs))) - { - int k; - for (k = 0; k < m_phi_count; k++) - { - constructor_elt elt; - - elt.index = int_const_binop (MINUS_EXPR, pos, m_range_min); - elt.value - = unshare_expr_without_location (m_default_values[k]); - m_constructors[k]->quick_push (elt); - } - - pos = int_const_binop (PLUS_EXPR, pos, pos_one); - } - gcc_assert (tree_int_cst_equal (pos, CASE_LOW (cs))); - - j = 0; - if (CASE_HIGH (cs)) - high = CASE_HIGH (cs); - else - high = CASE_LOW (cs); - for (gsi = gsi_start_phis (m_final_bb); - !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - if (virtual_operand_p (gimple_phi_result (phi))) - continue; - tree val = PHI_ARG_DEF_FROM_EDGE (phi, e); - tree low = CASE_LOW (cs); - pos = CASE_LOW (cs); - - do - { - constructor_elt elt; - - elt.index = int_const_binop (MINUS_EXPR, pos, m_range_min); - elt.value = unshare_expr_without_location (val); - m_constructors[j]->quick_push (elt); - - pos = int_const_binop (PLUS_EXPR, pos, pos_one); - } while (!tree_int_cst_lt (high, pos) - && tree_int_cst_lt (low, pos)); - j++; - } - } -} - -/* If all values in the constructor vector are products of a linear function - a * x + b, then return true. When true, COEFF_A and COEFF_B and - coefficients of the linear function. Note that equal values are special - case of a linear function with a and b equal to zero. */ - -bool -switch_conversion::contains_linear_function_p (vec<constructor_elt, va_gc> *vec, - wide_int *coeff_a, - wide_int *coeff_b) -{ - unsigned int i; - constructor_elt *elt; - - gcc_assert (vec->length () >= 2); - - /* Let's try to find any linear function a * x + y that can apply to - given values. 'a' can be calculated as follows: - - a = (y2 - y1) / (x2 - x1) where x2 - x1 = 1 (consecutive case indices) - a = y2 - y1 - - and - - b = y2 - a * x2 - - */ - - tree elt0 = (*vec)[0].value; - tree elt1 = (*vec)[1].value; - - if (TREE_CODE (elt0) != INTEGER_CST || TREE_CODE (elt1) != INTEGER_CST) - return false; - - wide_int range_min - = wide_int::from (wi::to_wide (m_range_min), - TYPE_PRECISION (TREE_TYPE (elt0)), - TYPE_SIGN (TREE_TYPE (m_range_min))); - wide_int y1 = wi::to_wide (elt0); - wide_int y2 = wi::to_wide (elt1); - wide_int a = y2 - y1; - wide_int b = y2 - a * (range_min + 1); - - /* Verify that all values fulfill the linear function. */ - FOR_EACH_VEC_SAFE_ELT (vec, i, elt) - { - if (TREE_CODE (elt->value) != INTEGER_CST) - return false; - - wide_int value = wi::to_wide (elt->value); - if (a * range_min + b != value) - return false; - - ++range_min; - } - - *coeff_a = a; - *coeff_b = b; - - return true; -} - -/* Return type which should be used for array elements, either TYPE's - main variant or, for integral types, some smaller integral type - that can still hold all the constants. */ - -tree -switch_conversion::array_value_type (tree type, int num) -{ - unsigned int i, len = vec_safe_length (m_constructors[num]); - constructor_elt *elt; - int sign = 0; - tree smaller_type; - - /* Types with alignments greater than their size can reach here, e.g. out of - SRA. We couldn't use these as an array component type so get back to the - main variant first, which, for our purposes, is fine for other types as - well. */ - - type = TYPE_MAIN_VARIANT (type); - - if (!INTEGRAL_TYPE_P (type)) - return type; - - scalar_int_mode type_mode = SCALAR_INT_TYPE_MODE (type); - scalar_int_mode mode = get_narrowest_mode (type_mode); - if (GET_MODE_SIZE (type_mode) <= GET_MODE_SIZE (mode)) - return type; - - if (len < (optimize_bb_for_size_p (gimple_bb (m_switch)) ? 2 : 32)) - return type; - - FOR_EACH_VEC_SAFE_ELT (m_constructors[num], i, elt) - { - wide_int cst; - - if (TREE_CODE (elt->value) != INTEGER_CST) - return type; - - cst = wi::to_wide (elt->value); - while (1) - { - unsigned int prec = GET_MODE_BITSIZE (mode); - if (prec > HOST_BITS_PER_WIDE_INT) - return type; - - if (sign >= 0 && cst == wi::zext (cst, prec)) - { - if (sign == 0 && cst == wi::sext (cst, prec)) - break; - sign = 1; - break; - } - if (sign <= 0 && cst == wi::sext (cst, prec)) - { - sign = -1; - break; - } - - if (sign == 1) - sign = 0; - - if (!GET_MODE_WIDER_MODE (mode).exists (&mode) - || GET_MODE_SIZE (mode) >= GET_MODE_SIZE (type_mode)) - return type; - } - } - - if (sign == 0) - sign = TYPE_UNSIGNED (type) ? 1 : -1; - smaller_type = lang_hooks.types.type_for_mode (mode, sign >= 0); - if (GET_MODE_SIZE (type_mode) - <= GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (smaller_type))) - return type; - - return smaller_type; -} - -/* Create an appropriate array type and declaration and assemble a static - array variable. Also create a load statement that initializes - the variable in question with a value from the static array. SWTCH is - the switch statement being converted, NUM is the index to - arrays of constructors, default values and target SSA names - for this particular array. ARR_INDEX_TYPE is the type of the index - of the new array, PHI is the phi node of the final BB that corresponds - to the value that will be loaded from the created array. TIDX - is an ssa name of a temporary variable holding the index for loads from the - new array. */ - -void -switch_conversion::build_one_array (int num, tree arr_index_type, - gphi *phi, tree tidx) -{ - tree name; - gimple *load; - gimple_stmt_iterator gsi = gsi_for_stmt (m_switch); - location_t loc = gimple_location (m_switch); - - gcc_assert (m_default_values[num]); - - name = copy_ssa_name (PHI_RESULT (phi)); - m_target_inbound_names[num] = name; - - vec<constructor_elt, va_gc> *constructor = m_constructors[num]; - wide_int coeff_a, coeff_b; - bool linear_p = contains_linear_function_p (constructor, &coeff_a, &coeff_b); - tree type; - if (linear_p - && (type = range_check_type (TREE_TYPE ((*constructor)[0].value)))) - { - if (dump_file && coeff_a.to_uhwi () > 0) - fprintf (dump_file, "Linear transformation with A = %" PRId64 - " and B = %" PRId64 "\n", coeff_a.to_shwi (), - coeff_b.to_shwi ()); - - /* We must use type of constructor values. */ - gimple_seq seq = NULL; - tree tmp = gimple_convert (&seq, type, m_index_expr); - tree tmp2 = gimple_build (&seq, MULT_EXPR, type, - wide_int_to_tree (type, coeff_a), tmp); - tree tmp3 = gimple_build (&seq, PLUS_EXPR, type, tmp2, - wide_int_to_tree (type, coeff_b)); - tree tmp4 = gimple_convert (&seq, TREE_TYPE (name), tmp3); - gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); - load = gimple_build_assign (name, tmp4); - } - else - { - tree array_type, ctor, decl, value_type, fetch, default_type; - - default_type = TREE_TYPE (m_default_values[num]); - value_type = array_value_type (default_type, num); - array_type = build_array_type (value_type, arr_index_type); - if (default_type != value_type) - { - unsigned int i; - constructor_elt *elt; - - FOR_EACH_VEC_SAFE_ELT (constructor, i, elt) - elt->value = fold_convert (value_type, elt->value); - } - ctor = build_constructor (array_type, constructor); - TREE_CONSTANT (ctor) = true; - TREE_STATIC (ctor) = true; - - decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type); - TREE_STATIC (decl) = 1; - DECL_INITIAL (decl) = ctor; - - DECL_NAME (decl) = create_tmp_var_name ("CSWTCH"); - DECL_ARTIFICIAL (decl) = 1; - DECL_IGNORED_P (decl) = 1; - TREE_CONSTANT (decl) = 1; - TREE_READONLY (decl) = 1; - DECL_IGNORED_P (decl) = 1; - if (offloading_function_p (cfun->decl)) - DECL_ATTRIBUTES (decl) - = tree_cons (get_identifier ("omp declare target"), NULL_TREE, - NULL_TREE); - varpool_node::finalize_decl (decl); - - fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE, - NULL_TREE); - if (default_type != value_type) - { - fetch = fold_convert (default_type, fetch); - fetch = force_gimple_operand_gsi (&gsi, fetch, true, NULL_TREE, - true, GSI_SAME_STMT); - } - load = gimple_build_assign (name, fetch); - } - - gsi_insert_before (&gsi, load, GSI_SAME_STMT); - update_stmt (load); - m_arr_ref_last = load; -} - -/* Builds and initializes static arrays initialized with values gathered from - the switch statement. Also creates statements that load values from - them. */ - -void -switch_conversion::build_arrays () -{ - tree arr_index_type; - tree tidx, sub, utype; - gimple *stmt; - gimple_stmt_iterator gsi; - gphi_iterator gpi; - int i; - location_t loc = gimple_location (m_switch); - - gsi = gsi_for_stmt (m_switch); - - /* Make sure we do not generate arithmetics in a subrange. */ - utype = TREE_TYPE (m_index_expr); - if (TREE_TYPE (utype)) - utype = lang_hooks.types.type_for_mode (TYPE_MODE (TREE_TYPE (utype)), 1); - else - utype = lang_hooks.types.type_for_mode (TYPE_MODE (utype), 1); - - arr_index_type = build_index_type (m_range_size); - tidx = make_ssa_name (utype); - sub = fold_build2_loc (loc, MINUS_EXPR, utype, - fold_convert_loc (loc, utype, m_index_expr), - fold_convert_loc (loc, utype, m_range_min)); - sub = force_gimple_operand_gsi (&gsi, sub, - false, NULL, true, GSI_SAME_STMT); - stmt = gimple_build_assign (tidx, sub); - - gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); - update_stmt (stmt); - m_arr_ref_first = stmt; - - for (gpi = gsi_start_phis (m_final_bb), i = 0; - !gsi_end_p (gpi); gsi_next (&gpi)) - { - gphi *phi = gpi.phi (); - if (!virtual_operand_p (gimple_phi_result (phi))) - build_one_array (i++, arr_index_type, phi, tidx); - else - { - edge e; - edge_iterator ei; - FOR_EACH_EDGE (e, ei, m_switch_bb->succs) - { - if (e->dest == m_final_bb) - break; - if (!m_default_case_nonstandard - || e->dest != m_default_bb) - { - e = single_succ_edge (e->dest); - break; - } - } - gcc_assert (e && e->dest == m_final_bb); - m_target_vop = PHI_ARG_DEF_FROM_EDGE (phi, e); - } - } -} - -/* Generates and appropriately inserts loads of default values at the position - given by GSI. Returns the last inserted statement. */ - -gassign * -switch_conversion::gen_def_assigns (gimple_stmt_iterator *gsi) -{ - int i; - gassign *assign = NULL; - - for (i = 0; i < m_phi_count; i++) - { - tree name = copy_ssa_name (m_target_inbound_names[i]); - m_target_outbound_names[i] = name; - assign = gimple_build_assign (name, m_default_values[i]); - gsi_insert_before (gsi, assign, GSI_SAME_STMT); - update_stmt (assign); - } - return assign; -} - -/* Deletes the unused bbs and edges that now contain the switch statement and - its empty branch bbs. BBD is the now dead BB containing - the original switch statement, FINAL is the last BB of the converted - switch statement (in terms of succession). */ - -void -switch_conversion::prune_bbs (basic_block bbd, basic_block final, - basic_block default_bb) -{ - edge_iterator ei; - edge e; - - for (ei = ei_start (bbd->succs); (e = ei_safe_edge (ei)); ) - { - basic_block bb; - bb = e->dest; - remove_edge (e); - if (bb != final && bb != default_bb) - delete_basic_block (bb); - } - delete_basic_block (bbd); -} - -/* Add values to phi nodes in final_bb for the two new edges. E1F is the edge - from the basic block loading values from an array and E2F from the basic - block loading default values. BBF is the last switch basic block (see the - bbf description in the comment below). */ - -void -switch_conversion::fix_phi_nodes (edge e1f, edge e2f, basic_block bbf) -{ - gphi_iterator gsi; - int i; - - for (gsi = gsi_start_phis (bbf), i = 0; - !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - tree inbound, outbound; - if (virtual_operand_p (gimple_phi_result (phi))) - inbound = outbound = m_target_vop; - else - { - inbound = m_target_inbound_names[i]; - outbound = m_target_outbound_names[i++]; - } - add_phi_arg (phi, inbound, e1f, UNKNOWN_LOCATION); - if (!m_default_case_nonstandard) - add_phi_arg (phi, outbound, e2f, UNKNOWN_LOCATION); - } -} - -/* Creates a check whether the switch expression value actually falls into the - range given by all the cases. If it does not, the temporaries are loaded - with default values instead. */ - -void -switch_conversion::gen_inbound_check () -{ - tree label_decl1 = create_artificial_label (UNKNOWN_LOCATION); - tree label_decl2 = create_artificial_label (UNKNOWN_LOCATION); - tree label_decl3 = create_artificial_label (UNKNOWN_LOCATION); - glabel *label1, *label2, *label3; - tree utype, tidx; - tree bound; - - gcond *cond_stmt; - - gassign *last_assign = NULL; - gimple_stmt_iterator gsi; - basic_block bb0, bb1, bb2, bbf, bbd; - edge e01 = NULL, e02, e21, e1d, e1f, e2f; - location_t loc = gimple_location (m_switch); - - gcc_assert (m_default_values); - - bb0 = gimple_bb (m_switch); - - tidx = gimple_assign_lhs (m_arr_ref_first); - utype = TREE_TYPE (tidx); - - /* (end of) block 0 */ - gsi = gsi_for_stmt (m_arr_ref_first); - gsi_next (&gsi); - - bound = fold_convert_loc (loc, utype, m_range_size); - cond_stmt = gimple_build_cond (LE_EXPR, tidx, bound, NULL_TREE, NULL_TREE); - gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); - update_stmt (cond_stmt); - - /* block 2 */ - if (!m_default_case_nonstandard) - { - label2 = gimple_build_label (label_decl2); - gsi_insert_before (&gsi, label2, GSI_SAME_STMT); - last_assign = gen_def_assigns (&gsi); - } - - /* block 1 */ - label1 = gimple_build_label (label_decl1); - gsi_insert_before (&gsi, label1, GSI_SAME_STMT); - - /* block F */ - gsi = gsi_start_bb (m_final_bb); - label3 = gimple_build_label (label_decl3); - gsi_insert_before (&gsi, label3, GSI_SAME_STMT); - - /* cfg fix */ - e02 = split_block (bb0, cond_stmt); - bb2 = e02->dest; - - if (m_default_case_nonstandard) - { - bb1 = bb2; - bb2 = m_default_bb; - e01 = e02; - e01->flags = EDGE_TRUE_VALUE; - e02 = make_edge (bb0, bb2, EDGE_FALSE_VALUE); - edge e_default = find_edge (bb1, bb2); - for (gphi_iterator gsi = gsi_start_phis (bb2); - !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e_default); - add_phi_arg (phi, arg, e02, - gimple_phi_arg_location_from_edge (phi, e_default)); - } - /* Partially fix the dominator tree, if it is available. */ - if (dom_info_available_p (CDI_DOMINATORS)) - redirect_immediate_dominators (CDI_DOMINATORS, bb1, bb0); - } - else - { - e21 = split_block (bb2, last_assign); - bb1 = e21->dest; - remove_edge (e21); - } - - e1d = split_block (bb1, m_arr_ref_last); - bbd = e1d->dest; - remove_edge (e1d); - - /* Flags and profiles of the edge for in-range values. */ - if (!m_default_case_nonstandard) - e01 = make_edge (bb0, bb1, EDGE_TRUE_VALUE); - e01->probability = m_default_prob.invert (); - - /* Flags and profiles of the edge taking care of out-of-range values. */ - e02->flags &= ~EDGE_FALLTHRU; - e02->flags |= EDGE_FALSE_VALUE; - e02->probability = m_default_prob; - - bbf = m_final_bb; - - e1f = make_edge (bb1, bbf, EDGE_FALLTHRU); - e1f->probability = profile_probability::always (); - - if (m_default_case_nonstandard) - e2f = NULL; - else - { - e2f = make_edge (bb2, bbf, EDGE_FALLTHRU); - e2f->probability = profile_probability::always (); - } - - /* frequencies of the new BBs */ - bb1->count = e01->count (); - bb2->count = e02->count (); - if (!m_default_case_nonstandard) - bbf->count = e1f->count () + e2f->count (); - - /* Tidy blocks that have become unreachable. */ - prune_bbs (bbd, m_final_bb, - m_default_case_nonstandard ? m_default_bb : NULL); - - /* Fixup the PHI nodes in bbF. */ - fix_phi_nodes (e1f, e2f, bbf); - - /* Fix the dominator tree, if it is available. */ - if (dom_info_available_p (CDI_DOMINATORS)) - { - vec<basic_block> bbs_to_fix_dom; - - set_immediate_dominator (CDI_DOMINATORS, bb1, bb0); - if (!m_default_case_nonstandard) - set_immediate_dominator (CDI_DOMINATORS, bb2, bb0); - if (! get_immediate_dominator (CDI_DOMINATORS, bbf)) - /* If bbD was the immediate dominator ... */ - set_immediate_dominator (CDI_DOMINATORS, bbf, bb0); - - bbs_to_fix_dom.create (3 + (bb2 != bbf)); - bbs_to_fix_dom.quick_push (bb0); - bbs_to_fix_dom.quick_push (bb1); - if (bb2 != bbf) - bbs_to_fix_dom.quick_push (bb2); - bbs_to_fix_dom.quick_push (bbf); - - iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true); - bbs_to_fix_dom.release (); - } -} - -/* The following function is invoked on every switch statement (the current - one is given in SWTCH) and runs the individual phases of switch - conversion on it one after another until one fails or the conversion - is completed. On success, NULL is in m_reason, otherwise points - to a string with the reason why the conversion failed. */ - -void -switch_conversion::expand (gswitch *swtch) -{ - /* Group case labels so that we get the right results from the heuristics - that decide on the code generation approach for this switch. */ - m_cfg_altered |= group_case_labels_stmt (swtch); - - /* If this switch is now a degenerate case with only a default label, - there is nothing left for us to do. */ - if (gimple_switch_num_labels (swtch) < 2) - { - m_reason = "switch is a degenerate case"; - return; - } - - collect (swtch); - - /* No error markers should reach here (they should be filtered out - during gimplification). */ - gcc_checking_assert (TREE_TYPE (m_index_expr) != error_mark_node); - - /* Prefer bit test if possible. */ - if (tree_fits_uhwi_p (m_range_size) - && bit_test_cluster::can_be_handled (tree_to_uhwi (m_range_size), m_uniq) - && bit_test_cluster::is_beneficial (m_count, m_uniq)) - { - m_reason = "expanding as bit test is preferable"; - return; - } - - if (m_uniq <= 2) - { - /* This will be expanded as a decision tree . */ - m_reason = "expanding as jumps is preferable"; - return; - } - - /* If there is no common successor, we cannot do the transformation. */ - if (!m_final_bb) - { - m_reason = "no common successor to all case label target blocks found"; - return; - } - - /* Check the case label values are within reasonable range: */ - if (!check_range ()) - { - gcc_assert (m_reason); - return; - } - - /* For all the cases, see whether they are empty, the assignments they - represent constant and so on... */ - if (!check_all_empty_except_final ()) - { - gcc_assert (m_reason); - return; - } - if (!check_final_bb ()) - { - gcc_assert (m_reason); - return; - } - - /* At this point all checks have passed and we can proceed with the - transformation. */ - - create_temp_arrays (); - gather_default_values (m_default_case_nonstandard - ? gimple_switch_label (swtch, 1) - : gimple_switch_default_label (swtch)); - build_constructors (); - - build_arrays (); /* Build the static arrays and assignments. */ - gen_inbound_check (); /* Build the bounds check. */ - - m_cfg_altered = true; -} - -/* Destructor. */ - -switch_conversion::~switch_conversion () -{ - XDELETEVEC (m_constructors); - XDELETEVEC (m_default_values); -} - -/* Constructor. */ - -group_cluster::group_cluster (vec<cluster *> &clusters, - unsigned start, unsigned end) -{ - gcc_checking_assert (end - start + 1 >= 1); - m_prob = profile_probability::never (); - m_cases.create (end - start + 1); - for (unsigned i = start; i <= end; i++) - { - m_cases.quick_push (static_cast<simple_cluster *> (clusters[i])); - m_prob += clusters[i]->m_prob; - } - m_subtree_prob = m_prob; -} - -/* Destructor. */ - -group_cluster::~group_cluster () -{ - for (unsigned i = 0; i < m_cases.length (); i++) - delete m_cases[i]; - - m_cases.release (); -} - -/* Dump content of a cluster. */ - -void -group_cluster::dump (FILE *f, bool details) -{ - unsigned total_values = 0; - for (unsigned i = 0; i < m_cases.length (); i++) - total_values += m_cases[i]->get_range (m_cases[i]->get_low (), - m_cases[i]->get_high ()); - - unsigned comparison_count = 0; - for (unsigned i = 0; i < m_cases.length (); i++) - { - simple_cluster *sc = static_cast<simple_cluster *> (m_cases[i]); - comparison_count += sc->get_comparison_count (); - } - - unsigned HOST_WIDE_INT range = get_range (get_low (), get_high ()); - fprintf (f, "%s", get_type () == JUMP_TABLE ? "JT" : "BT"); - - if (details) - fprintf (f, "(values:%d comparisons:%d range:" HOST_WIDE_INT_PRINT_DEC - " density: %.2f%%)", total_values, comparison_count, range, - 100.0f * comparison_count / range); - - fprintf (f, ":"); - PRINT_CASE (f, get_low ()); - fprintf (f, "-"); - PRINT_CASE (f, get_high ()); - fprintf (f, " "); -} - -/* Emit GIMPLE code to handle the cluster. */ - -void -jump_table_cluster::emit (tree index_expr, tree, - tree default_label_expr, basic_block default_bb, - location_t loc) -{ - unsigned HOST_WIDE_INT range = get_range (get_low (), get_high ()); - unsigned HOST_WIDE_INT nondefault_range = 0; - - /* For jump table we just emit a new gswitch statement that will - be latter lowered to jump table. */ - auto_vec <tree> labels; - labels.create (m_cases.length ()); - - make_edge (m_case_bb, default_bb, 0); - for (unsigned i = 0; i < m_cases.length (); i++) - { - labels.quick_push (unshare_expr (m_cases[i]->m_case_label_expr)); - make_edge (m_case_bb, m_cases[i]->m_case_bb, 0); - } - - gswitch *s = gimple_build_switch (index_expr, - unshare_expr (default_label_expr), labels); - gimple_set_location (s, loc); - gimple_stmt_iterator gsi = gsi_start_bb (m_case_bb); - gsi_insert_after (&gsi, s, GSI_NEW_STMT); - - /* Set up even probabilities for all cases. */ - for (unsigned i = 0; i < m_cases.length (); i++) - { - simple_cluster *sc = static_cast<simple_cluster *> (m_cases[i]); - edge case_edge = find_edge (m_case_bb, sc->m_case_bb); - unsigned HOST_WIDE_INT case_range - = sc->get_range (sc->get_low (), sc->get_high ()); - nondefault_range += case_range; - - /* case_edge->aux is number of values in a jump-table that are covered - by the case_edge. */ - case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + case_range); - } - - edge default_edge = gimple_switch_default_edge (cfun, s); - default_edge->probability = profile_probability::never (); - - for (unsigned i = 0; i < m_cases.length (); i++) - { - simple_cluster *sc = static_cast<simple_cluster *> (m_cases[i]); - edge case_edge = find_edge (m_case_bb, sc->m_case_bb); - case_edge->probability - = profile_probability::always ().apply_scale ((intptr_t)case_edge->aux, - range); - } - - /* Number of non-default values is probability of default edge. */ - default_edge->probability - += profile_probability::always ().apply_scale (nondefault_range, - range).invert (); - - switch_decision_tree::reset_out_edges_aux (s); -} - -/* Find jump tables of given CLUSTERS, where all members of the vector - are of type simple_cluster. New clusters are returned. */ - -vec<cluster *> -jump_table_cluster::find_jump_tables (vec<cluster *> &clusters) -{ - if (!is_enabled ()) - return clusters.copy (); - - unsigned l = clusters.length (); - auto_vec<min_cluster_item> min; - min.reserve (l + 1); - - min.quick_push (min_cluster_item (0, 0, 0)); - - unsigned HOST_WIDE_INT max_ratio - = (optimize_insn_for_size_p () - ? param_jump_table_max_growth_ratio_for_size - : param_jump_table_max_growth_ratio_for_speed); - - for (unsigned i = 1; i <= l; i++) - { - /* Set minimal # of clusters with i-th item to infinite. */ - min.quick_push (min_cluster_item (INT_MAX, INT_MAX, INT_MAX)); - - /* Pre-calculate number of comparisons for the clusters. */ - HOST_WIDE_INT comparison_count = 0; - for (unsigned k = 0; k <= i - 1; k++) - { - simple_cluster *sc = static_cast<simple_cluster *> (clusters[k]); - comparison_count += sc->get_comparison_count (); - } - - for (unsigned j = 0; j < i; j++) - { - unsigned HOST_WIDE_INT s = min[j].m_non_jt_cases; - if (i - j < case_values_threshold ()) - s += i - j; - - /* Prefer clusters with smaller number of numbers covered. */ - if ((min[j].m_count + 1 < min[i].m_count - || (min[j].m_count + 1 == min[i].m_count - && s < min[i].m_non_jt_cases)) - && can_be_handled (clusters, j, i - 1, max_ratio, - comparison_count)) - min[i] = min_cluster_item (min[j].m_count + 1, j, s); - - simple_cluster *sc = static_cast<simple_cluster *> (clusters[j]); - comparison_count -= sc->get_comparison_count (); - } - - gcc_checking_assert (comparison_count == 0); - gcc_checking_assert (min[i].m_count != INT_MAX); - } - - /* No result. */ - if (min[l].m_count == l) - return clusters.copy (); - - vec<cluster *> output; - output.create (4); - - /* Find and build the clusters. */ - for (unsigned int end = l;;) - { - int start = min[end].m_start; - - /* Do not allow clusters with small number of cases. */ - if (is_beneficial (clusters, start, end - 1)) - output.safe_push (new jump_table_cluster (clusters, start, end - 1)); - else - for (int i = end - 1; i >= start; i--) - output.safe_push (clusters[i]); - - end = start; - - if (start <= 0) - break; - } - - output.reverse (); - return output; -} - -/* Return true when cluster starting at START and ending at END (inclusive) - can build a jump-table. */ - -bool -jump_table_cluster::can_be_handled (const vec<cluster *> &clusters, - unsigned start, unsigned end, - unsigned HOST_WIDE_INT max_ratio, - unsigned HOST_WIDE_INT comparison_count) -{ - /* If the switch is relatively small such that the cost of one - indirect jump on the target are higher than the cost of a - decision tree, go with the decision tree. - - If range of values is much bigger than number of values, - or if it is too large to represent in a HOST_WIDE_INT, - make a sequence of conditional branches instead of a dispatch. - - The definition of "much bigger" depends on whether we are - optimizing for size or for speed. - - For algorithm correctness, jump table for a single case must return - true. We bail out in is_beneficial if it's called just for - a single case. */ - if (start == end) - return true; - - unsigned HOST_WIDE_INT range = get_range (clusters[start]->get_low (), - clusters[end]->get_high ()); - /* Check overflow. */ - if (range == 0) - return false; - - if (range > HOST_WIDE_INT_M1U / 100) - return false; - - unsigned HOST_WIDE_INT lhs = 100 * range; - if (lhs < range) - return false; - - return lhs <= max_ratio * comparison_count; -} - -/* Return true if cluster starting at START and ending at END (inclusive) - is profitable transformation. */ - -bool -jump_table_cluster::is_beneficial (const vec<cluster *> &, - unsigned start, unsigned end) -{ - /* Single case bail out. */ - if (start == end) - return false; - - return end - start + 1 >= case_values_threshold (); -} - -/* Find bit tests of given CLUSTERS, where all members of the vector - are of type simple_cluster. New clusters are returned. */ - -vec<cluster *> -bit_test_cluster::find_bit_tests (vec<cluster *> &clusters) -{ - if (!is_enabled ()) - return clusters.copy (); - - unsigned l = clusters.length (); - auto_vec<min_cluster_item> min; - min.reserve (l + 1); - - min.quick_push (min_cluster_item (0, 0, 0)); - - for (unsigned i = 1; i <= l; i++) - { - /* Set minimal # of clusters with i-th item to infinite. */ - min.quick_push (min_cluster_item (INT_MAX, INT_MAX, INT_MAX)); - - for (unsigned j = 0; j < i; j++) - { - if (min[j].m_count + 1 < min[i].m_count - && can_be_handled (clusters, j, i - 1)) - min[i] = min_cluster_item (min[j].m_count + 1, j, INT_MAX); - } - - gcc_checking_assert (min[i].m_count != INT_MAX); - } - - /* No result. */ - if (min[l].m_count == l) - return clusters.copy (); - - vec<cluster *> output; - output.create (4); - - /* Find and build the clusters. */ - for (unsigned end = l;;) - { - int start = min[end].m_start; - - if (is_beneficial (clusters, start, end - 1)) - { - bool entire = start == 0 && end == clusters.length (); - output.safe_push (new bit_test_cluster (clusters, start, end - 1, - entire)); - } - else - for (int i = end - 1; i >= start; i--) - output.safe_push (clusters[i]); - - end = start; - - if (start <= 0) - break; - } - - output.reverse (); - return output; -} - -/* Return true when RANGE of case values with UNIQ labels - can build a bit test. */ - -bool -bit_test_cluster::can_be_handled (unsigned HOST_WIDE_INT range, - unsigned int uniq) -{ - /* Check overflow. */ - if (range == 0) - return false; - - if (range >= GET_MODE_BITSIZE (word_mode)) - return false; - - return uniq <= m_max_case_bit_tests; -} - -/* Return true when cluster starting at START and ending at END (inclusive) - can build a bit test. */ - -bool -bit_test_cluster::can_be_handled (const vec<cluster *> &clusters, - unsigned start, unsigned end) -{ - auto_vec<int, m_max_case_bit_tests> dest_bbs; - /* For algorithm correctness, bit test for a single case must return - true. We bail out in is_beneficial if it's called just for - a single case. */ - if (start == end) - return true; - - unsigned HOST_WIDE_INT range = get_range (clusters[start]->get_low (), - clusters[end]->get_high ()); - - /* Make a guess first. */ - if (!can_be_handled (range, m_max_case_bit_tests)) - return false; - - for (unsigned i = start; i <= end; i++) - { - simple_cluster *sc = static_cast<simple_cluster *> (clusters[i]); - /* m_max_case_bit_tests is very small integer, thus the operation - is constant. */ - if (!dest_bbs.contains (sc->m_case_bb->index)) - { - if (dest_bbs.length () >= m_max_case_bit_tests) - return false; - dest_bbs.quick_push (sc->m_case_bb->index); - } - } - - return true; -} - -/* Return true when COUNT of cases of UNIQ labels is beneficial for bit test - transformation. */ - -bool -bit_test_cluster::is_beneficial (unsigned count, unsigned uniq) -{ - return (((uniq == 1 && count >= 3) - || (uniq == 2 && count >= 5) - || (uniq == 3 && count >= 6))); -} - -/* Return true if cluster starting at START and ending at END (inclusive) - is profitable transformation. */ - -bool -bit_test_cluster::is_beneficial (const vec<cluster *> &clusters, - unsigned start, unsigned end) -{ - /* Single case bail out. */ - if (start == end) - return false; - - auto_bitmap dest_bbs; - - for (unsigned i = start; i <= end; i++) - { - simple_cluster *sc = static_cast<simple_cluster *> (clusters[i]); - bitmap_set_bit (dest_bbs, sc->m_case_bb->index); - } - - unsigned uniq = bitmap_count_bits (dest_bbs); - unsigned count = end - start + 1; - return is_beneficial (count, uniq); -} - -/* Comparison function for qsort to order bit tests by decreasing - probability of execution. */ - -int -case_bit_test::cmp (const void *p1, const void *p2) -{ - const case_bit_test *const d1 = (const case_bit_test *) p1; - const case_bit_test *const d2 = (const case_bit_test *) p2; - - if (d2->bits != d1->bits) - return d2->bits - d1->bits; - - /* Stabilize the sort. */ - return (LABEL_DECL_UID (CASE_LABEL (d2->label)) - - LABEL_DECL_UID (CASE_LABEL (d1->label))); -} - -/* Expand a switch statement by a short sequence of bit-wise - comparisons. "switch(x)" is effectively converted into - "if ((1 << (x-MINVAL)) & CST)" where CST and MINVAL are - integer constants. - - INDEX_EXPR is the value being switched on. - - MINVAL is the lowest case value of in the case nodes, - and RANGE is highest value minus MINVAL. MINVAL and RANGE - are not guaranteed to be of the same type as INDEX_EXPR - (the gimplifier doesn't change the type of case label values, - and MINVAL and RANGE are derived from those values). - MAXVAL is MINVAL + RANGE. - - There *MUST* be max_case_bit_tests or less unique case - node targets. */ - -void -bit_test_cluster::emit (tree index_expr, tree index_type, - tree, basic_block default_bb, location_t) -{ - case_bit_test test[m_max_case_bit_tests] = { {} }; - unsigned int i, j, k; - unsigned int count; - - tree unsigned_index_type = range_check_type (index_type); - - gimple_stmt_iterator gsi; - gassign *shift_stmt; - - tree idx, tmp, csui; - tree word_type_node = lang_hooks.types.type_for_mode (word_mode, 1); - tree word_mode_zero = fold_convert (word_type_node, integer_zero_node); - tree word_mode_one = fold_convert (word_type_node, integer_one_node); - int prec = TYPE_PRECISION (word_type_node); - wide_int wone = wi::one (prec); - - tree minval = get_low (); - tree maxval = get_high (); - unsigned HOST_WIDE_INT bt_range = get_range (minval, maxval); - - /* Go through all case labels, and collect the case labels, profile - counts, and other information we need to build the branch tests. */ - count = 0; - for (i = 0; i < m_cases.length (); i++) - { - unsigned int lo, hi; - simple_cluster *n = static_cast<simple_cluster *> (m_cases[i]); - for (k = 0; k < count; k++) - if (n->m_case_bb == test[k].target_bb) - break; - - if (k == count) - { - gcc_checking_assert (count < m_max_case_bit_tests); - test[k].mask = wi::zero (prec); - test[k].target_bb = n->m_case_bb; - test[k].label = n->m_case_label_expr; - test[k].bits = 0; - count++; - } - - test[k].bits += n->get_range (n->get_low (), n->get_high ()); - - lo = tree_to_uhwi (int_const_binop (MINUS_EXPR, n->get_low (), minval)); - if (n->get_high () == NULL_TREE) - hi = lo; - else - hi = tree_to_uhwi (int_const_binop (MINUS_EXPR, n->get_high (), - minval)); - - for (j = lo; j <= hi; j++) - test[k].mask |= wi::lshift (wone, j); - } - - qsort (test, count, sizeof (*test), case_bit_test::cmp); - - /* If every possible relative value of the index expression is a valid shift - amount, then we can merge the entry test in the bit test. */ - bool entry_test_needed; - value_range r; - if (TREE_CODE (index_expr) == SSA_NAME - && get_range_query (cfun)->range_of_expr (r, index_expr) - && r.kind () == VR_RANGE - && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1)) - { - wide_int min = r.lower_bound (); - wide_int max = r.upper_bound (); - tree index_type = TREE_TYPE (index_expr); - minval = fold_convert (index_type, minval); - wide_int iminval = wi::to_wide (minval); - if (wi::lt_p (min, iminval, TYPE_SIGN (index_type))) - { - minval = wide_int_to_tree (index_type, min); - for (i = 0; i < count; i++) - test[i].mask = wi::lshift (test[i].mask, iminval - min); - } - else if (wi::gt_p (min, iminval, TYPE_SIGN (index_type))) - { - minval = wide_int_to_tree (index_type, min); - for (i = 0; i < count; i++) - test[i].mask = wi::lrshift (test[i].mask, min - iminval); - } - maxval = wide_int_to_tree (index_type, max); - entry_test_needed = false; - } - else - entry_test_needed = true; - - /* If all values are in the 0 .. BITS_PER_WORD-1 range, we can get rid of - the minval subtractions, but it might make the mask constants more - expensive. So, compare the costs. */ - if (compare_tree_int (minval, 0) > 0 && compare_tree_int (maxval, prec) < 0) - { - int cost_diff; - HOST_WIDE_INT m = tree_to_uhwi (minval); - rtx reg = gen_raw_REG (word_mode, 10000); - bool speed_p = optimize_insn_for_speed_p (); - cost_diff = set_src_cost (gen_rtx_PLUS (word_mode, reg, - GEN_INT (-m)), - word_mode, speed_p); - for (i = 0; i < count; i++) - { - rtx r = immed_wide_int_const (test[i].mask, word_mode); - cost_diff += set_src_cost (gen_rtx_AND (word_mode, reg, r), - word_mode, speed_p); - r = immed_wide_int_const (wi::lshift (test[i].mask, m), word_mode); - cost_diff -= set_src_cost (gen_rtx_AND (word_mode, reg, r), - word_mode, speed_p); - } - if (cost_diff > 0) - { - for (i = 0; i < count; i++) - test[i].mask = wi::lshift (test[i].mask, m); - minval = build_zero_cst (TREE_TYPE (minval)); - } - } - - /* Now build the test-and-branch code. */ - - gsi = gsi_last_bb (m_case_bb); - - /* idx = (unsigned)x - minval. */ - idx = fold_convert (unsigned_index_type, index_expr); - idx = fold_build2 (MINUS_EXPR, unsigned_index_type, idx, - fold_convert (unsigned_index_type, minval)); - idx = force_gimple_operand_gsi (&gsi, idx, - /*simple=*/true, NULL_TREE, - /*before=*/true, GSI_SAME_STMT); - - if (m_handles_entire_switch && entry_test_needed) - { - tree range = int_const_binop (MINUS_EXPR, maxval, minval); - /* if (idx > range) goto default */ - range - = force_gimple_operand_gsi (&gsi, - fold_convert (unsigned_index_type, range), - /*simple=*/true, NULL_TREE, - /*before=*/true, GSI_SAME_STMT); - tmp = fold_build2 (GT_EXPR, boolean_type_node, idx, range); - basic_block new_bb - = hoist_edge_and_branch_if_true (&gsi, tmp, default_bb, - profile_probability::unlikely ()); - gsi = gsi_last_bb (new_bb); - } - - tmp = fold_build2 (LSHIFT_EXPR, word_type_node, word_mode_one, - fold_convert (word_type_node, idx)); - - /* csui = (1 << (word_mode) idx) */ - if (count > 1) - { - csui = make_ssa_name (word_type_node); - tmp = force_gimple_operand_gsi (&gsi, tmp, - /*simple=*/false, NULL_TREE, - /*before=*/true, GSI_SAME_STMT); - shift_stmt = gimple_build_assign (csui, tmp); - gsi_insert_before (&gsi, shift_stmt, GSI_SAME_STMT); - update_stmt (shift_stmt); - } - else - csui = tmp; - - profile_probability prob = profile_probability::always (); - - /* for each unique set of cases: - if (const & csui) goto target */ - for (k = 0; k < count; k++) - { - prob = profile_probability::always ().apply_scale (test[k].bits, - bt_range); - bt_range -= test[k].bits; - tmp = wide_int_to_tree (word_type_node, test[k].mask); - tmp = fold_build2 (BIT_AND_EXPR, word_type_node, csui, tmp); - tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp, word_mode_zero); - tmp = force_gimple_operand_gsi (&gsi, tmp, - /*simple=*/true, NULL_TREE, - /*before=*/true, GSI_SAME_STMT); - basic_block new_bb - = hoist_edge_and_branch_if_true (&gsi, tmp, test[k].target_bb, prob); - gsi = gsi_last_bb (new_bb); - } - - /* We should have removed all edges now. */ - gcc_assert (EDGE_COUNT (gsi_bb (gsi)->succs) == 0); - - /* If nothing matched, go to the default label. */ - edge e = make_edge (gsi_bb (gsi), default_bb, EDGE_FALLTHRU); - e->probability = profile_probability::always (); -} - -/* Split the basic block at the statement pointed to by GSIP, and insert - a branch to the target basic block of E_TRUE conditional on tree - expression COND. - - It is assumed that there is already an edge from the to-be-split - basic block to E_TRUE->dest block. This edge is removed, and the - profile information on the edge is re-used for the new conditional - jump. - - The CFG is updated. The dominator tree will not be valid after - this transformation, but the immediate dominators are updated if - UPDATE_DOMINATORS is true. - - Returns the newly created basic block. */ - -basic_block -bit_test_cluster::hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip, - tree cond, basic_block case_bb, - profile_probability prob) -{ - tree tmp; - gcond *cond_stmt; - edge e_false; - basic_block new_bb, split_bb = gsi_bb (*gsip); - - edge e_true = make_edge (split_bb, case_bb, EDGE_TRUE_VALUE); - e_true->probability = prob; - gcc_assert (e_true->src == split_bb); - - tmp = force_gimple_operand_gsi (gsip, cond, /*simple=*/true, NULL, - /*before=*/true, GSI_SAME_STMT); - cond_stmt = gimple_build_cond_from_tree (tmp, NULL_TREE, NULL_TREE); - gsi_insert_before (gsip, cond_stmt, GSI_SAME_STMT); - - e_false = split_block (split_bb, cond_stmt); - new_bb = e_false->dest; - redirect_edge_pred (e_true, split_bb); - - e_false->flags &= ~EDGE_FALLTHRU; - e_false->flags |= EDGE_FALSE_VALUE; - e_false->probability = e_true->probability.invert (); - new_bb->count = e_false->count (); - - return new_bb; -} - -/* Compute the number of case labels that correspond to each outgoing edge of - switch statement. Record this information in the aux field of the edge. */ - -void -switch_decision_tree::compute_cases_per_edge () -{ - reset_out_edges_aux (m_switch); - int ncases = gimple_switch_num_labels (m_switch); - for (int i = ncases - 1; i >= 1; --i) - { - edge case_edge = gimple_switch_edge (cfun, m_switch, i); - case_edge->aux = (void *) ((intptr_t) (case_edge->aux) + 1); - } -} - -/* Analyze switch statement and return true when the statement is expanded - as decision tree. */ - -bool -switch_decision_tree::analyze_switch_statement () -{ - unsigned l = gimple_switch_num_labels (m_switch); - basic_block bb = gimple_bb (m_switch); - auto_vec<cluster *> clusters; - clusters.create (l - 1); - - basic_block default_bb = gimple_switch_default_bb (cfun, m_switch); - m_case_bbs.reserve (l); - m_case_bbs.quick_push (default_bb); - - compute_cases_per_edge (); - - for (unsigned i = 1; i < l; i++) - { - tree elt = gimple_switch_label (m_switch, i); - tree lab = CASE_LABEL (elt); - basic_block case_bb = label_to_block (cfun, lab); - edge case_edge = find_edge (bb, case_bb); - tree low = CASE_LOW (elt); - tree high = CASE_HIGH (elt); - - profile_probability p - = case_edge->probability.apply_scale (1, (intptr_t) (case_edge->aux)); - clusters.quick_push (new simple_cluster (low, high, elt, case_edge->dest, - p)); - m_case_bbs.quick_push (case_edge->dest); - } - - reset_out_edges_aux (m_switch); - - /* Find bit-test clusters. */ - vec<cluster *> output = bit_test_cluster::find_bit_tests (clusters); - - /* Find jump table clusters. */ - vec<cluster *> output2; - auto_vec<cluster *> tmp; - output2.create (1); - tmp.create (1); - - for (unsigned i = 0; i < output.length (); i++) - { - cluster *c = output[i]; - if (c->get_type () != SIMPLE_CASE) - { - if (!tmp.is_empty ()) - { - vec<cluster *> n = jump_table_cluster::find_jump_tables (tmp); - output2.safe_splice (n); - n.release (); - tmp.truncate (0); - } - output2.safe_push (c); - } - else - tmp.safe_push (c); - } - - /* We still can have a temporary vector to test. */ - if (!tmp.is_empty ()) - { - vec<cluster *> n = jump_table_cluster::find_jump_tables (tmp); - output2.safe_splice (n); - n.release (); - } - - if (dump_file) - { - fprintf (dump_file, ";; GIMPLE switch case clusters: "); - for (unsigned i = 0; i < output2.length (); i++) - output2[i]->dump (dump_file, dump_flags & TDF_DETAILS); - fprintf (dump_file, "\n"); - } - - output.release (); - - bool expanded = try_switch_expansion (output2); - release_clusters (output2); - return expanded; -} - -/* Attempt to expand CLUSTERS as a decision tree. Return true when - expanded. */ - -bool -switch_decision_tree::try_switch_expansion (vec<cluster *> &clusters) -{ - tree index_expr = gimple_switch_index (m_switch); - tree index_type = TREE_TYPE (index_expr); - basic_block bb = gimple_bb (m_switch); - - if (gimple_switch_num_labels (m_switch) == 1 - || range_check_type (index_type) == NULL_TREE) - return false; - - /* Find the default case target label. */ - edge default_edge = gimple_switch_default_edge (cfun, m_switch); - m_default_bb = default_edge->dest; - - /* Do the insertion of a case label into m_case_list. The labels are - fed to us in descending order from the sorted vector of case labels used - in the tree part of the middle end. So the list we construct is - sorted in ascending order. */ - - for (int i = clusters.length () - 1; i >= 0; i--) - { - case_tree_node *r = m_case_list; - m_case_list = m_case_node_pool.allocate (); - m_case_list->m_right = r; - m_case_list->m_c = clusters[i]; - } - - record_phi_operand_mapping (); - - /* Split basic block that contains the gswitch statement. */ - gimple_stmt_iterator gsi = gsi_last_bb (bb); - edge e; - if (gsi_end_p (gsi)) - e = split_block_after_labels (bb); - else - { - gsi_prev (&gsi); - e = split_block (bb, gsi_stmt (gsi)); - } - bb = split_edge (e); - - /* Create new basic blocks for non-case clusters where specific expansion - needs to happen. */ - for (unsigned i = 0; i < clusters.length (); i++) - if (clusters[i]->get_type () != SIMPLE_CASE) - { - clusters[i]->m_case_bb = create_empty_bb (bb); - clusters[i]->m_case_bb->count = bb->count; - clusters[i]->m_case_bb->loop_father = bb->loop_father; - } - - /* Do not do an extra work for a single cluster. */ - if (clusters.length () == 1 - && clusters[0]->get_type () != SIMPLE_CASE) - { - cluster *c = clusters[0]; - c->emit (index_expr, index_type, - gimple_switch_default_label (m_switch), m_default_bb, - gimple_location (m_switch)); - redirect_edge_succ (single_succ_edge (bb), c->m_case_bb); - } - else - { - emit (bb, index_expr, default_edge->probability, index_type); - - /* Emit cluster-specific switch handling. */ - for (unsigned i = 0; i < clusters.length (); i++) - if (clusters[i]->get_type () != SIMPLE_CASE) - clusters[i]->emit (index_expr, index_type, - gimple_switch_default_label (m_switch), - m_default_bb, gimple_location (m_switch)); - } - - fix_phi_operands_for_edges (); - - return true; -} - -/* Before switch transformation, record all SSA_NAMEs defined in switch BB - and used in a label basic block. */ - -void -switch_decision_tree::record_phi_operand_mapping () -{ - basic_block switch_bb = gimple_bb (m_switch); - /* Record all PHI nodes that have to be fixed after conversion. */ - for (unsigned i = 0; i < m_case_bbs.length (); i++) - { - gphi_iterator gsi; - basic_block bb = m_case_bbs[i]; - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - - for (unsigned i = 0; i < gimple_phi_num_args (phi); i++) - { - basic_block phi_src_bb = gimple_phi_arg_edge (phi, i)->src; - if (phi_src_bb == switch_bb) - { - tree def = gimple_phi_arg_def (phi, i); - tree result = gimple_phi_result (phi); - m_phi_mapping.put (result, def); - break; - } - } - } - } -} - -/* Append new operands to PHI statements that were introduced due to - addition of new edges to case labels. */ - -void -switch_decision_tree::fix_phi_operands_for_edges () -{ - gphi_iterator gsi; - - for (unsigned i = 0; i < m_case_bbs.length (); i++) - { - basic_block bb = m_case_bbs[i]; - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - for (unsigned j = 0; j < gimple_phi_num_args (phi); j++) - { - tree def = gimple_phi_arg_def (phi, j); - if (def == NULL_TREE) - { - edge e = gimple_phi_arg_edge (phi, j); - tree *definition - = m_phi_mapping.get (gimple_phi_result (phi)); - gcc_assert (definition); - add_phi_arg (phi, *definition, e, UNKNOWN_LOCATION); - } - } - } - } -} - -/* Generate a decision tree, switching on INDEX_EXPR and jumping to - one of the labels in CASE_LIST or to the DEFAULT_LABEL. - - We generate a binary decision tree to select the appropriate target - code. */ - -void -switch_decision_tree::emit (basic_block bb, tree index_expr, - profile_probability default_prob, tree index_type) -{ - balance_case_nodes (&m_case_list, NULL); - - if (dump_file) - dump_function_to_file (current_function_decl, dump_file, dump_flags); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - int indent_step = ceil_log2 (TYPE_PRECISION (index_type)) + 2; - fprintf (dump_file, ";; Expanding GIMPLE switch as decision tree:\n"); - gcc_assert (m_case_list != NULL); - dump_case_nodes (dump_file, m_case_list, indent_step, 0); - } - - bb = emit_case_nodes (bb, index_expr, m_case_list, default_prob, index_type, - gimple_location (m_switch)); - - if (bb) - emit_jump (bb, m_default_bb); - - /* Remove all edges and do just an edge that will reach default_bb. */ - bb = gimple_bb (m_switch); - gimple_stmt_iterator gsi = gsi_last_bb (bb); - gsi_remove (&gsi, true); - - delete_basic_block (bb); -} - -/* Take an ordered list of case nodes - and transform them into a near optimal binary tree, - on the assumption that any target code selection value is as - likely as any other. - - The transformation is performed by splitting the ordered - list into two equal sections plus a pivot. The parts are - then attached to the pivot as left and right branches. Each - branch is then transformed recursively. */ - -void -switch_decision_tree::balance_case_nodes (case_tree_node **head, - case_tree_node *parent) -{ - case_tree_node *np; - - np = *head; - if (np) - { - int i = 0; - int ranges = 0; - case_tree_node **npp; - case_tree_node *left; - profile_probability prob = profile_probability::never (); - - /* Count the number of entries on branch. Also count the ranges. */ - - while (np) - { - if (!tree_int_cst_equal (np->m_c->get_low (), np->m_c->get_high ())) - ranges++; - - i++; - prob += np->m_c->m_prob; - np = np->m_right; - } - - if (i > 2) - { - /* Split this list if it is long enough for that to help. */ - npp = head; - left = *npp; - profile_probability pivot_prob = prob.apply_scale (1, 2); - - /* Find the place in the list that bisects the list's total cost, - where ranges count as 2. */ - while (1) - { - /* Skip nodes while their probability does not reach - that amount. */ - prob -= (*npp)->m_c->m_prob; - if ((prob.initialized_p () && prob < pivot_prob) - || ! (*npp)->m_right) - break; - npp = &(*npp)->m_right; - } - - np = *npp; - *npp = 0; - *head = np; - np->m_parent = parent; - np->m_left = left == np ? NULL : left; - - /* Optimize each of the two split parts. */ - balance_case_nodes (&np->m_left, np); - balance_case_nodes (&np->m_right, np); - np->m_c->m_subtree_prob = np->m_c->m_prob; - if (np->m_left) - np->m_c->m_subtree_prob += np->m_left->m_c->m_subtree_prob; - if (np->m_right) - np->m_c->m_subtree_prob += np->m_right->m_c->m_subtree_prob; - } - else - { - /* Else leave this branch as one level, - but fill in `parent' fields. */ - np = *head; - np->m_parent = parent; - np->m_c->m_subtree_prob = np->m_c->m_prob; - for (; np->m_right; np = np->m_right) - { - np->m_right->m_parent = np; - (*head)->m_c->m_subtree_prob += np->m_right->m_c->m_subtree_prob; - } - } - } -} - -/* Dump ROOT, a list or tree of case nodes, to file. */ - -void -switch_decision_tree::dump_case_nodes (FILE *f, case_tree_node *root, - int indent_step, int indent_level) -{ - if (root == 0) - return; - indent_level++; - - dump_case_nodes (f, root->m_left, indent_step, indent_level); - - fputs (";; ", f); - fprintf (f, "%*s", indent_step * indent_level, ""); - root->m_c->dump (f); - root->m_c->m_prob.dump (f); - fputs (" subtree: ", f); - root->m_c->m_subtree_prob.dump (f); - fputs (")\n", f); - - dump_case_nodes (f, root->m_right, indent_step, indent_level); -} - - -/* Add an unconditional jump to CASE_BB that happens in basic block BB. */ - -void -switch_decision_tree::emit_jump (basic_block bb, basic_block case_bb) -{ - edge e = single_succ_edge (bb); - redirect_edge_succ (e, case_bb); -} - -/* Generate code to compare OP0 with OP1 so that the condition codes are - set and to jump to LABEL_BB if the condition is true. - COMPARISON is the GIMPLE comparison (EQ, NE, GT, etc.). - PROB is the probability of jumping to LABEL_BB. */ - -basic_block -switch_decision_tree::emit_cmp_and_jump_insns (basic_block bb, tree op0, - tree op1, tree_code comparison, - basic_block label_bb, - profile_probability prob, - location_t loc) -{ - // TODO: it's once called with lhs != index. - op1 = fold_convert (TREE_TYPE (op0), op1); - - gcond *cond = gimple_build_cond (comparison, op0, op1, NULL_TREE, NULL_TREE); - gimple_set_location (cond, loc); - gimple_stmt_iterator gsi = gsi_last_bb (bb); - gsi_insert_after (&gsi, cond, GSI_NEW_STMT); - - gcc_assert (single_succ_p (bb)); - - /* Make a new basic block where false branch will take place. */ - edge false_edge = split_block (bb, cond); - false_edge->flags = EDGE_FALSE_VALUE; - false_edge->probability = prob.invert (); - - edge true_edge = make_edge (bb, label_bb, EDGE_TRUE_VALUE); - true_edge->probability = prob; - - return false_edge->dest; -} - -/* Generate code to jump to LABEL if OP0 and OP1 are equal. - PROB is the probability of jumping to LABEL_BB. - BB is a basic block where the new condition will be placed. */ - -basic_block -switch_decision_tree::do_jump_if_equal (basic_block bb, tree op0, tree op1, - basic_block label_bb, - profile_probability prob, - location_t loc) -{ - op1 = fold_convert (TREE_TYPE (op0), op1); - - gcond *cond = gimple_build_cond (EQ_EXPR, op0, op1, NULL_TREE, NULL_TREE); - gimple_set_location (cond, loc); - gimple_stmt_iterator gsi = gsi_last_bb (bb); - gsi_insert_before (&gsi, cond, GSI_SAME_STMT); - - gcc_assert (single_succ_p (bb)); - - /* Make a new basic block where false branch will take place. */ - edge false_edge = split_block (bb, cond); - false_edge->flags = EDGE_FALSE_VALUE; - false_edge->probability = prob.invert (); - - edge true_edge = make_edge (bb, label_bb, EDGE_TRUE_VALUE); - true_edge->probability = prob; - - return false_edge->dest; -} - -/* Emit step-by-step code to select a case for the value of INDEX. - The thus generated decision tree follows the form of the - case-node binary tree NODE, whose nodes represent test conditions. - DEFAULT_PROB is probability of cases leading to default BB. - INDEX_TYPE is the type of the index of the switch. */ - -basic_block -switch_decision_tree::emit_case_nodes (basic_block bb, tree index, - case_tree_node *node, - profile_probability default_prob, - tree index_type, location_t loc) -{ - profile_probability p; - - /* If node is null, we are done. */ - if (node == NULL) - return bb; - - /* Single value case. */ - if (node->m_c->is_single_value_p ()) - { - /* Node is single valued. First see if the index expression matches - this node and then check our children, if any. */ - p = node->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob); - bb = do_jump_if_equal (bb, index, node->m_c->get_low (), - node->m_c->m_case_bb, p, loc); - /* Since this case is taken at this point, reduce its weight from - subtree_weight. */ - node->m_c->m_subtree_prob -= p; - - if (node->m_left != NULL && node->m_right != NULL) - { - /* 1) the node has both children - - If both children are single-valued cases with no - children, finish up all the work. This way, we can save - one ordered comparison. */ - - if (!node->m_left->has_child () - && node->m_left->m_c->is_single_value_p () - && !node->m_right->has_child () - && node->m_right->m_c->is_single_value_p ()) - { - p = (node->m_right->m_c->m_prob - / (node->m_c->m_subtree_prob + default_prob)); - bb = do_jump_if_equal (bb, index, node->m_right->m_c->get_low (), - node->m_right->m_c->m_case_bb, p, loc); - - p = (node->m_left->m_c->m_prob - / (node->m_c->m_subtree_prob + default_prob)); - bb = do_jump_if_equal (bb, index, node->m_left->m_c->get_low (), - node->m_left->m_c->m_case_bb, p, loc); - } - else - { - /* Branch to a label where we will handle it later. */ - basic_block test_bb = split_edge (single_succ_edge (bb)); - redirect_edge_succ (single_pred_edge (test_bb), - single_succ_edge (bb)->dest); - - p = ((node->m_right->m_c->m_subtree_prob - + default_prob.apply_scale (1, 2)) - / (node->m_c->m_subtree_prob + default_prob)); - bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (), - GT_EXPR, test_bb, p, loc); - default_prob = default_prob.apply_scale (1, 2); - - /* Handle the left-hand subtree. */ - bb = emit_case_nodes (bb, index, node->m_left, - default_prob, index_type, loc); - - /* If the left-hand subtree fell through, - don't let it fall into the right-hand subtree. */ - if (bb && m_default_bb) - emit_jump (bb, m_default_bb); - - bb = emit_case_nodes (test_bb, index, node->m_right, - default_prob, index_type, loc); - } - } - else if (node->m_left == NULL && node->m_right != NULL) - { - /* 2) the node has only right child. */ - - /* Here we have a right child but no left so we issue a conditional - branch to default and process the right child. - - Omit the conditional branch to default if the right child - does not have any children and is single valued; it would - cost too much space to save so little time. */ - - if (node->m_right->has_child () - || !node->m_right->m_c->is_single_value_p ()) - { - p = (default_prob.apply_scale (1, 2) - / (node->m_c->m_subtree_prob + default_prob)); - bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_low (), - LT_EXPR, m_default_bb, p, loc); - default_prob = default_prob.apply_scale (1, 2); - - bb = emit_case_nodes (bb, index, node->m_right, default_prob, - index_type, loc); - } - else - { - /* We cannot process node->right normally - since we haven't ruled out the numbers less than - this node's value. So handle node->right explicitly. */ - p = (node->m_right->m_c->m_subtree_prob - / (node->m_c->m_subtree_prob + default_prob)); - bb = do_jump_if_equal (bb, index, node->m_right->m_c->get_low (), - node->m_right->m_c->m_case_bb, p, loc); - } - } - else if (node->m_left != NULL && node->m_right == NULL) - { - /* 3) just one subtree, on the left. Similar case as previous. */ - - if (node->m_left->has_child () - || !node->m_left->m_c->is_single_value_p ()) - { - p = (default_prob.apply_scale (1, 2) - / (node->m_c->m_subtree_prob + default_prob)); - bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (), - GT_EXPR, m_default_bb, p, loc); - default_prob = default_prob.apply_scale (1, 2); - - bb = emit_case_nodes (bb, index, node->m_left, default_prob, - index_type, loc); - } - else - { - /* We cannot process node->left normally - since we haven't ruled out the numbers less than - this node's value. So handle node->left explicitly. */ - p = (node->m_left->m_c->m_subtree_prob - / (node->m_c->m_subtree_prob + default_prob)); - bb = do_jump_if_equal (bb, index, node->m_left->m_c->get_low (), - node->m_left->m_c->m_case_bb, p, loc); - } - } - } - else - { - /* Node is a range. These cases are very similar to those for a single - value, except that we do not start by testing whether this node - is the one to branch to. */ - if (node->has_child () || node->m_c->get_type () != SIMPLE_CASE) - { - /* Branch to a label where we will handle it later. */ - basic_block test_bb = split_edge (single_succ_edge (bb)); - redirect_edge_succ (single_pred_edge (test_bb), - single_succ_edge (bb)->dest); - - - profile_probability right_prob = profile_probability::never (); - if (node->m_right) - right_prob = node->m_right->m_c->m_subtree_prob; - p = ((right_prob + default_prob.apply_scale (1, 2)) - / (node->m_c->m_subtree_prob + default_prob)); - - bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_high (), - GT_EXPR, test_bb, p, loc); - default_prob = default_prob.apply_scale (1, 2); - - /* Value belongs to this node or to the left-hand subtree. */ - p = node->m_c->m_prob / (node->m_c->m_subtree_prob + default_prob); - bb = emit_cmp_and_jump_insns (bb, index, node->m_c->get_low (), - GE_EXPR, node->m_c->m_case_bb, p, loc); - - /* Handle the left-hand subtree. */ - bb = emit_case_nodes (bb, index, node->m_left, - default_prob, index_type, loc); - - /* If the left-hand subtree fell through, - don't let it fall into the right-hand subtree. */ - if (bb && m_default_bb) - emit_jump (bb, m_default_bb); - - bb = emit_case_nodes (test_bb, index, node->m_right, - default_prob, index_type, loc); - } - else - { - /* Node has no children so we check low and high bounds to remove - redundant tests. Only one of the bounds can exist, - since otherwise this node is bounded--a case tested already. */ - tree lhs, rhs; - generate_range_test (bb, index, node->m_c->get_low (), - node->m_c->get_high (), &lhs, &rhs); - p = default_prob / (node->m_c->m_subtree_prob + default_prob); - - bb = emit_cmp_and_jump_insns (bb, lhs, rhs, GT_EXPR, - m_default_bb, p, loc); - - emit_jump (bb, node->m_c->m_case_bb); - return NULL; - } - } - - return bb; -} - -/* The main function of the pass scans statements for switches and invokes - process_switch on them. */ - -namespace { - -const pass_data pass_data_convert_switch = -{ - GIMPLE_PASS, /* type */ - "switchconv", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - TV_TREE_SWITCH_CONVERSION, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_update_ssa, /* todo_flags_finish */ -}; - -class pass_convert_switch : public gimple_opt_pass -{ -public: - pass_convert_switch (gcc::context *ctxt) - : gimple_opt_pass (pass_data_convert_switch, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_tree_switch_conversion != 0; } - virtual unsigned int execute (function *); - -}; // class pass_convert_switch - -unsigned int -pass_convert_switch::execute (function *fun) -{ - basic_block bb; - bool cfg_altered = false; - - FOR_EACH_BB_FN (bb, fun) - { - gimple *stmt = last_stmt (bb); - if (stmt && gimple_code (stmt) == GIMPLE_SWITCH) - { - if (dump_file) - { - expanded_location loc = expand_location (gimple_location (stmt)); - - fprintf (dump_file, "beginning to process the following " - "SWITCH statement (%s:%d) : ------- \n", - loc.file, loc.line); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - putc ('\n', dump_file); - } - - switch_conversion sconv; - sconv.expand (as_a <gswitch *> (stmt)); - cfg_altered |= sconv.m_cfg_altered; - if (!sconv.m_reason) - { - if (dump_file) - { - fputs ("Switch converted\n", dump_file); - fputs ("--------------------------------\n", dump_file); - } - - /* Make no effort to update the post-dominator tree. - It is actually not that hard for the transformations - we have performed, but it is not supported - by iterate_fix_dominators. */ - free_dominance_info (CDI_POST_DOMINATORS); - } - else - { - if (dump_file) - { - fputs ("Bailing out - ", dump_file); - fputs (sconv.m_reason, dump_file); - fputs ("\n--------------------------------\n", dump_file); - } - } - } - } - - return cfg_altered ? TODO_cleanup_cfg : 0;; -} - -} // anon namespace - -gimple_opt_pass * -make_pass_convert_switch (gcc::context *ctxt) -{ - return new pass_convert_switch (ctxt); -} - -/* The main function of the pass scans statements for switches and invokes - process_switch on them. */ - -namespace { - -template <bool O0> class pass_lower_switch: public gimple_opt_pass -{ -public: - pass_lower_switch (gcc::context *ctxt) : gimple_opt_pass (data, ctxt) {} - - static const pass_data data; - opt_pass * - clone () - { - return new pass_lower_switch<O0> (m_ctxt); - } - - virtual bool - gate (function *) - { - return !O0 || !optimize; - } - - virtual unsigned int execute (function *fun); -}; // class pass_lower_switch - -template <bool O0> -const pass_data pass_lower_switch<O0>::data = { - GIMPLE_PASS, /* type */ - O0 ? "switchlower_O0" : "switchlower", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - TV_TREE_SWITCH_LOWERING, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_update_ssa | TODO_cleanup_cfg, /* todo_flags_finish */ -}; - -template <bool O0> -unsigned int -pass_lower_switch<O0>::execute (function *fun) -{ - basic_block bb; - bool expanded = false; - - auto_vec<gimple *> switch_statements; - switch_statements.create (1); - - FOR_EACH_BB_FN (bb, fun) - { - gimple *stmt = last_stmt (bb); - gswitch *swtch; - if (stmt && (swtch = dyn_cast<gswitch *> (stmt))) - { - if (!O0) - group_case_labels_stmt (swtch); - switch_statements.safe_push (swtch); - } - } - - for (unsigned i = 0; i < switch_statements.length (); i++) - { - gimple *stmt = switch_statements[i]; - if (dump_file) - { - expanded_location loc = expand_location (gimple_location (stmt)); - - fprintf (dump_file, "beginning to process the following " - "SWITCH statement (%s:%d) : ------- \n", - loc.file, loc.line); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - putc ('\n', dump_file); - } - - gswitch *swtch = dyn_cast<gswitch *> (stmt); - if (swtch) - { - switch_decision_tree dt (swtch); - expanded |= dt.analyze_switch_statement (); - } - } - - if (expanded) - { - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); - mark_virtual_operands_for_renaming (cfun); - } - - return 0; -} - -} // anon namespace - -gimple_opt_pass * -make_pass_lower_switch_O0 (gcc::context *ctxt) -{ - return new pass_lower_switch<true> (ctxt); -} -gimple_opt_pass * -make_pass_lower_switch (gcc::context *ctxt) -{ - return new pass_lower_switch<false> (ctxt); -} |