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/genautomata.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/genautomata.c')
-rw-r--r-- | gcc/genautomata.c | 9685 |
1 files changed, 0 insertions, 9685 deletions
diff --git a/gcc/genautomata.c b/gcc/genautomata.c deleted file mode 100644 index 5872aca..0000000 --- a/gcc/genautomata.c +++ /dev/null @@ -1,9685 +0,0 @@ -/* Pipeline hazard description translator. - Copyright (C) 2000-2022 Free Software Foundation, Inc. - - Written by Vladimir Makarov <vmakarov@redhat.com> - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -GCC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* References: - - 1. The finite state automaton based pipeline hazard recognizer and - instruction scheduler in GCC. V. Makarov. Proceedings of GCC - summit, 2003. - - 2. Detecting pipeline structural hazards quickly. T. Proebsting, - C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on - Principles of Programming Languages, pages 280--286, 1994. - - This article is a good start point to understand usage of finite - state automata for pipeline hazard recognizers. But I'd - recommend the 1st and 3rd article for more deep understanding. - - 3. Efficient Instruction Scheduling Using Finite State Automata: - V. Bala and N. Rubin, Proceedings of MICRO-28. This is the best - article about usage of finite state automata for pipeline hazard - recognizers. - - The current implementation is described in the 1st article and it - is different from the 3rd article in the following: - - 1. New operator `|' (alternative) is permitted in functional unit - reservation which can be treated deterministically and - non-deterministically. - - 2. Possibility of usage of nondeterministic automata too. - - 3. Possibility to query functional unit reservations for given - automaton state. - - 4. Several constructions to describe impossible reservations - (`exclusion_set', `presence_set', `final_presence_set', - `absence_set', and `final_absence_set'). - - 5. No reverse automata are generated. Trace instruction scheduling - requires this. It can be easily added in the future if we - really need this. - - 6. Union of automaton states are not generated yet. It is planned - to be implemented. Such feature is needed to make more accurate - interlock insn scheduling to get state describing functional - unit reservation in a joint CFG point. */ - -/* This file code processes constructions of machine description file - which describes automaton used for recognition of processor pipeline - hazards by insn scheduler and can be used for other tasks (such as - VLIW insn packing. - - The translator functions `gen_cpu_unit', `gen_query_cpu_unit', - `gen_bypass', `gen_excl_set', `gen_presence_set', - `gen_final_presence_set', `gen_absence_set', - `gen_final_absence_set', `gen_automaton', `gen_automata_option', - `gen_reserv', `gen_insn_reserv' are called from file - `genattrtab.c'. They transform RTL constructions describing - automata in .md file into internal representation convenient for - further processing. - - The translator major function `expand_automata' processes the - description internal representation into finite state automaton. - It can be divided on: - - o checking correctness of the automaton pipeline description - (major function is `check_all_description'). - - o generating automaton (automata) from the description (major - function is `make_automaton'). - - o optional transformation of nondeterministic finite state - automata into deterministic ones if the alternative operator - `|' is treated nondeterministically in the description (major - function is NDFA_to_DFA). - - o optional minimization of the finite state automata by merging - equivalent automaton states (major function is `minimize_DFA'). - - o forming tables (some as comb vectors) and attributes - representing the automata (functions output_..._table). - - Function `write_automata' outputs the created finite state - automaton as different tables and functions which works with the - automata to inquire automaton state and to change its state. These - function are used by gcc instruction scheduler and may be some - other gcc code. */ - -#include "bconfig.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "obstack.h" -#include "errors.h" -#include "gensupport.h" - -#include <math.h> -#include "fnmatch.h" - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -/* Positions in machine description file. Now they are not used. But - they could be used in the future for better diagnostic messages. */ -typedef int pos_t; - -/* The following is element of vector of current (and planned in the - future) functional unit reservations. */ -typedef unsigned HOST_WIDE_INT set_el_t; - -/* Reservations of function units are represented by value of the following - type. */ -typedef set_el_t *reserv_sets_t; -typedef const set_el_t *const_reserv_sets_t; - -/* The following structure describes a ticker. */ -struct ticker -{ - /* The following member value is time of the ticker creation with - taking into account time when the ticker is off. Active time of - the ticker is current time minus the value. */ - int modified_creation_time; - /* The following member value is time (incremented by one) when the - ticker was off. Zero value means that now the ticker is on. */ - int incremented_off_time; -}; - -/* The ticker is represented by the following type. */ -typedef struct ticker ticker_t; - -/* The following type describes elements of output vectors. */ -typedef HOST_WIDE_INT vect_el_t; - -/* Forward declaration of structures of internal representation of - pipeline description based on NDFA. */ - -struct unit_decl; -struct bypass_decl; -struct result_decl; -struct automaton_decl; -struct unit_pattern_rel_decl; -struct reserv_decl; -struct insn_reserv_decl; -struct decl; -struct unit_regexp; -struct result_regexp; -struct reserv_regexp; -struct nothing_regexp; -struct sequence_regexp; -struct repeat_regexp; -struct allof_regexp; -struct oneof_regexp; -struct regexp; -struct description; -struct unit_set_el; -struct pattern_set_el; -struct pattern_reserv; -struct state; -struct alt_state; -struct arc; -struct ainsn; -struct automaton; -struct state_ainsn_table; - -/* The following typedefs are for brevity. */ -typedef struct unit_decl *unit_decl_t; -typedef const struct unit_decl *const_unit_decl_t; -typedef struct decl *decl_t; -typedef const struct decl *const_decl_t; -typedef struct regexp *regexp_t; -typedef struct unit_set_el *unit_set_el_t; -typedef struct pattern_set_el *pattern_set_el_t; -typedef struct pattern_reserv *pattern_reserv_t; -typedef struct alt_state *alt_state_t; -typedef struct state *state_t; -typedef const struct state *const_state_t; -typedef struct arc *arc_t; -typedef struct ainsn *ainsn_t; -typedef struct automaton *automaton_t; -typedef struct automata_list_el *automata_list_el_t; -typedef const struct automata_list_el *const_automata_list_el_t; -typedef struct state_ainsn_table *state_ainsn_table_t; - -/* Undefined position. */ -static pos_t no_pos = 0; - -/* All IR is stored in the following obstack. */ -static struct obstack irp; - - -/* Declare vector types for various data structures: */ - - -typedef vec<vect_el_t> vla_hwint_t; - -/* Forward declarations of functions used before their definitions, only. */ -static regexp_t gen_regexp_sequence (const char *); -static void reserv_sets_or (reserv_sets_t, reserv_sets_t, - reserv_sets_t); -static reserv_sets_t get_excl_set (reserv_sets_t); -static int check_presence_pattern_sets (reserv_sets_t, - reserv_sets_t, int); -static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t, - int); -static arc_t first_out_arc (const_state_t); -static arc_t next_out_arc (arc_t); - - - -/* Options with the following names can be set up in automata_option - construction. Because the strings occur more one time we use the - macros. */ - -#define NO_MINIMIZATION_OPTION "-no-minimization" -#define TIME_OPTION "-time" -#define STATS_OPTION "-stats" -#define V_OPTION "-v" -#define W_OPTION "-w" -#define NDFA_OPTION "-ndfa" -#define COLLAPSE_OPTION "-collapse-ndfa" -#define NO_COMB_OPTION "-no-comb-vect" -#define PROGRESS_OPTION "-progress" - -/* The following flags are set up by function `initiate_automaton_gen'. */ - -/* Make automata with nondeterministic reservation by insns (`-ndfa'). */ -static int ndfa_flag; - -/* When making an NDFA, produce additional transitions that collapse - NDFA state into a deterministic one suitable for querying CPU units. - Provide advance-state transitions only for deterministic states. */ -static int collapse_flag; - -/* Do not make minimization of DFA (`-no-minimization'). */ -static int no_minimization_flag; - -/* Do not try to generate a comb vector (`-no-comb-vect'). */ -static int no_comb_flag; - -/* Value of this variable is number of automata being generated. The - actual number of automata may be less this value if there is not - sufficient number of units. This value is defined by argument of - option `-split' or by constructions automaton if the value is zero - (it is default value of the argument). */ -static int split_argument; - -/* Flag of output time statistics (`-time'). */ -static int time_flag; - -/* Flag of automata statistics (`-stats'). */ -static int stats_flag; - -/* Flag of creation of description file which contains description of - result automaton and statistics information (`-v'). */ -static int v_flag; - -/* Flag of output of a progress bar showing how many states were - generated so far for automaton being processed (`-progress'). */ -static int progress_flag; - -/* Flag of generating warning instead of error for non-critical errors - (`-w'). */ -static int w_flag; - - -/* Output file for pipeline hazard recognizer (PHR) being generated. - The value is NULL if the file is not defined. */ -static FILE *output_file; - -/* Description file of PHR. The value is NULL if the file is not - created. */ -static FILE *output_description_file; - -/* PHR description file name. */ -static char *output_description_file_name; - -/* Value of the following variable is node representing description - being processed. This is start point of IR. */ -static struct description *description; - - - -/* This page contains description of IR structure (nodes). */ - -enum decl_mode -{ - dm_unit, - dm_bypass, - dm_automaton, - dm_excl, - dm_presence, - dm_absence, - dm_reserv, - dm_insn_reserv -}; - -/* This describes define_cpu_unit and define_query_cpu_unit (see file - rtl.def). */ -struct unit_decl -{ - const char *name; - /* NULL if the automaton name is absent. */ - const char *automaton_name; - /* If the following value is not zero, the cpu unit reservation is - described in define_query_cpu_unit. */ - char query_p; - - /* The following fields are defined by checker. */ - - /* The following field value is nonzero if the unit is used in an - regexp. */ - char unit_is_used; - - /* The following field value is order number (0, 1, ...) of given - unit. */ - int unit_num; - /* The following field value is corresponding declaration of - automaton which was given in description. If the field value is - NULL then automaton in the unit declaration was absent. */ - struct automaton_decl *automaton_decl; - /* The following field value is maximal cycle number (1, ...) on - which given unit occurs in insns. Zero value means that given - unit is not used in insns. */ - int max_occ_cycle_num; - /* The following field value is minimal cycle number (0, ...) on - which given unit occurs in insns. -1 value means that given - unit is not used in insns. */ - int min_occ_cycle_num; - /* The following list contains units which conflict with given - unit. */ - unit_set_el_t excl_list; - /* The following list contains patterns which are required to - reservation of given unit. */ - pattern_set_el_t presence_list; - pattern_set_el_t final_presence_list; - /* The following list contains patterns which should be not present - in reservation for given unit. */ - pattern_set_el_t absence_list; - pattern_set_el_t final_absence_list; - /* The following is used only when `query_p' has nonzero value. - This is query number for the unit. */ - int query_num; - /* The following is the last cycle on which the unit was checked for - correct distributions of units to automata in a regexp. */ - int last_distribution_check_cycle; - - /* The following fields are defined by automaton generator. */ - - /* The following field value is number of the automaton to which - given unit belongs. */ - int corresponding_automaton_num; - /* If the following value is not zero, the cpu unit is present in a - `exclusion_set' or in right part of a `presence_set', - `final_presence_set', `absence_set', and - `final_absence_set'define_query_cpu_unit. */ - char in_set_p; -}; - -/* This describes define_bypass (see file rtl.def). */ -struct bypass_decl -{ - int latency; - const char *out_pattern; - const char *in_pattern; - const char *bypass_guard_name; - - /* The following fields are defined by checker. */ - - /* output and input insns of given bypass. */ - struct insn_reserv_decl *out_insn_reserv; - struct insn_reserv_decl *in_insn_reserv; - /* The next bypass for given output insn. */ - struct bypass_decl *next; -}; - -/* This describes define_automaton (see file rtl.def). */ -struct automaton_decl -{ - const char *name; - - /* The following fields are defined by automaton generator. */ - - /* The following field value is nonzero if the automaton is used in - an regexp definition. */ - char automaton_is_used; - - /* The following fields are defined by checker. */ - - /* The following field value is the corresponding automaton. This - field is not NULL only if the automaton is present in unit - declarations and the automatic partition on automata is not - used. */ - automaton_t corresponding_automaton; -}; - -/* This describes exclusion relations: exclusion_set (see file - rtl.def). */ -struct excl_rel_decl -{ - int all_names_num; - int first_list_length; - char *names [1]; -}; - -/* This describes unit relations: [final_]presence_set or - [final_]absence_set (see file rtl.def). */ -struct unit_pattern_rel_decl -{ - int final_p; - int names_num; - int patterns_num; - char **names; - char ***patterns; -}; - -/* This describes define_reservation (see file rtl.def). */ -struct reserv_decl -{ - const char *name; - regexp_t regexp; - - /* The following fields are defined by checker. */ - - /* The following field value is nonzero if the unit is used in an - regexp. */ - char reserv_is_used; - /* The following field is used to check up cycle in expression - definition. */ - int loop_pass_num; -}; - -/* This describes define_insn_reservation (see file rtl.def). */ -struct insn_reserv_decl -{ - rtx condexp; - int default_latency; - regexp_t regexp; - const char *name; - - /* The following fields are defined by checker. */ - - /* The following field value is order number (0, 1, ...) of given - insn. */ - int insn_num; - /* The following field value is list of bypasses in which given insn - is output insn. Bypasses with the same input insn stay one after - another in the list in the same order as their occurrences in the - description but the bypass without a guard stays always the last - in a row of bypasses with the same input insn. */ - struct bypass_decl *bypass_list; - - /* The following fields are defined by automaton generator. */ - - /* The following field is the insn regexp transformed that - the regexp has not optional regexp, repetition regexp, and an - reservation name (i.e. reservation identifiers are changed by the - corresponding regexp) and all alternations are the top level - of the regexp. The value can be NULL only if it is special - insn `cycle advancing'. */ - regexp_t transformed_regexp; - /* The following field value is list of arcs marked given - insn. The field is used in transformation NDFA -> DFA. */ - arc_t arcs_marked_by_insn; - /* The two following fields are used during minimization of a finite state - automaton. */ - /* The field value is number of equivalence class of state into - which arc marked by given insn enters from a state (fixed during - an automaton minimization). */ - int equiv_class_num; - /* The following member value is the list to automata which can be - changed by the insn issue. */ - automata_list_el_t important_automata_list; - /* The following member is used to process insn once for output. */ - int processed_p; -}; - -/* This contains a declaration mentioned above. */ -struct decl -{ - /* What node in the union? */ - enum decl_mode mode; - pos_t pos; - union - { - struct unit_decl unit; - struct bypass_decl bypass; - struct automaton_decl automaton; - struct excl_rel_decl excl; - struct unit_pattern_rel_decl presence; - struct unit_pattern_rel_decl absence; - struct reserv_decl reserv; - struct insn_reserv_decl insn_reserv; - } decl; -}; - -/* The following structures represent parsed reservation strings. */ -enum regexp_mode -{ - rm_unit, - rm_reserv, - rm_nothing, - rm_sequence, - rm_repeat, - rm_allof, - rm_oneof -}; - -/* Cpu unit in reservation. */ -struct unit_regexp -{ - const char *name; - unit_decl_t unit_decl; -}; - -/* Define_reservation in a reservation. */ -struct reserv_regexp -{ - const char *name; - struct reserv_decl *reserv_decl; -}; - -/* Absence of reservation (represented by string `nothing'). */ -struct nothing_regexp -{ - /* This used to be empty but ISO C doesn't allow that. */ - char unused; -}; - -/* Representation of reservations separated by ',' (see file - rtl.def). */ -struct sequence_regexp -{ - int regexps_num; - regexp_t regexps [1]; -}; - -/* Representation of construction `repeat' (see file rtl.def). */ -struct repeat_regexp -{ - int repeat_num; - regexp_t regexp; -}; - -/* Representation of reservations separated by '+' (see file - rtl.def). */ -struct allof_regexp -{ - int regexps_num; - regexp_t regexps [1]; -}; - -/* Representation of reservations separated by '|' (see file - rtl.def). */ -struct oneof_regexp -{ - int regexps_num; - regexp_t regexps [1]; -}; - -/* Representation of a reservation string. */ -struct regexp -{ - /* What node in the union? */ - enum regexp_mode mode; - pos_t pos; - union - { - struct unit_regexp unit; - struct reserv_regexp reserv; - struct nothing_regexp nothing; - struct sequence_regexp sequence; - struct repeat_regexp repeat; - struct allof_regexp allof; - struct oneof_regexp oneof; - } regexp; -}; - -/* Represents description of pipeline hazard description based on - NDFA. */ -struct description -{ - int decls_num, normal_decls_num; - - /* The following fields are defined by checker. */ - - /* The following fields values are correspondingly number of all - units, query units, and insns in the description. */ - int units_num; - int query_units_num; - int insns_num; - /* The following field value is max length (in cycles) of - reservations of insns. The field value is defined only for - correct programs. */ - int max_insn_reserv_cycles; - - /* The following fields are defined by automaton generator. */ - - /* The following field value is the first automaton. */ - automaton_t first_automaton; - - /* The following field is created by pipeline hazard parser and - contains all declarations. We allocate additional entries for - two special insns which are added by the automaton generator. */ - decl_t decls [1]; -}; - - -/* The following nodes are created in automaton checker. */ - -/* The following nodes represent exclusion set for cpu units. Each - element is accessed through only one excl_list. */ -struct unit_set_el -{ - unit_decl_t unit_decl; - unit_set_el_t next_unit_set_el; -}; - -/* The following nodes represent presence or absence pattern for cpu - units. Each element is accessed through only one presence_list or - absence_list. */ -struct pattern_set_el -{ - /* The number of units in unit_decls. */ - int units_num; - /* The units forming the pattern. */ - struct unit_decl **unit_decls; - pattern_set_el_t next_pattern_set_el; -}; - - -/* The following nodes are created in automaton generator. */ - - -/* The following nodes represent presence or absence pattern for cpu - units. Each element is accessed through only one element of - unit_presence_set_table or unit_absence_set_table. */ -struct pattern_reserv -{ - reserv_sets_t reserv; - pattern_reserv_t next_pattern_reserv; -}; - -/* The following node type describes state automaton. The state may - be deterministic or non-deterministic. Non-deterministic state has - several component states which represent alternative cpu units - reservations. The state also is used for describing a - deterministic reservation of automaton insn. */ -struct state -{ - /* The following member value is nonzero if there is a transition by - cycle advancing. */ - int new_cycle_p; - /* The following field is list of processor unit reservations on - each cycle. */ - reserv_sets_t reservs; - /* The following field is unique number of given state between other - states. */ - int unique_num; - /* The following field value is automaton to which given state - belongs. */ - automaton_t automaton; - /* The following field value is the first arc output from given - state. */ - arc_t first_out_arc; - unsigned int num_out_arcs; - /* The following field is used to form NDFA. */ - char it_was_placed_in_stack_for_NDFA_forming; - /* The following field is used to form DFA. */ - char it_was_placed_in_stack_for_DFA_forming; - /* The following field is used to transform NDFA to DFA and DFA - minimization. The field value is not NULL if the state is a - compound state. In this case the value of field `unit_sets_list' - is NULL. All states in the list are in the hash table. The list - is formed through field `next_sorted_alt_state'. We should - support only one level of nesting state. */ - alt_state_t component_states; - /* The following field is used for passing graph of states. */ - int pass_num; - /* The list of states belonging to one equivalence class is formed - with the aid of the following field. */ - state_t next_equiv_class_state; - /* The two following fields are used during minimization of a finite - state automaton. */ - int equiv_class_num_1, equiv_class_num_2; - /* The following field is used during minimization of a finite state - automaton. The field value is state corresponding to equivalence - class to which given state belongs. */ - state_t equiv_class_state; - unsigned int *presence_signature; - /* The following field value is the order number of given state. - The states in final DFA is enumerated with the aid of the - following field. */ - int order_state_num; - /* This member is used for passing states for searching minimal - delay time. */ - int state_pass_num; - /* The following member is used to evaluate min issue delay of insn - for a state. */ - int min_insn_issue_delay; -}; - -/* Automaton arc. */ -struct arc -{ - /* The following field refers for the state into which given arc - enters. */ - state_t to_state; - /* The following field describes that the insn issue (with cycle - advancing for special insn `cycle advancing' and without cycle - advancing for others) makes transition from given state to - another given state. */ - ainsn_t insn; - /* The following field value is the next arc output from the same - state. */ - arc_t next_out_arc; - /* List of arcs marked given insn is formed with the following - field. The field is used in transformation NDFA -> DFA. */ - arc_t next_arc_marked_by_insn; -}; - -/* The following node type describes a deterministic alternative in - non-deterministic state which characterizes cpu unit reservations - of automaton insn or which is part of NDFA. */ -struct alt_state -{ - /* The following field is a deterministic state which characterizes - unit reservations of the instruction. */ - state_t state; - /* The following field refers to the next state which characterizes - unit reservations of the instruction. */ - alt_state_t next_alt_state; - /* The following field refers to the next state in sorted list. */ - alt_state_t next_sorted_alt_state; -}; - -/* The following node type describes insn of automaton. They are - labels of FA arcs. */ -struct ainsn -{ - /* The following field value is the corresponding insn declaration - of description. */ - struct insn_reserv_decl *insn_reserv_decl; - /* The following field value is the next insn declaration for an - automaton. */ - ainsn_t next_ainsn; - /* The following field is states which characterize automaton unit - reservations of the instruction. The value can be NULL only if it - is special insn `cycle advancing'. */ - alt_state_t alt_states; - /* The following field is sorted list of states which characterize - automaton unit reservations of the instruction. The value can be - NULL only if it is special insn `cycle advancing'. */ - alt_state_t sorted_alt_states; - /* The following field refers the next automaton insn with - the same reservations. */ - ainsn_t next_same_reservs_insn; - /* The following field is flag of the first automaton insn with the - same reservations in the declaration list. Only arcs marked such - insn is present in the automaton. This significantly decreases - memory requirements especially when several automata are - formed. */ - char first_insn_with_same_reservs; - /* The following member has nonzero value if there is arc from state of - the automaton marked by the ainsn. */ - char arc_exists_p; - /* Cyclic list of insns of an equivalence class is formed with the - aid of the following field. */ - ainsn_t next_equiv_class_insn; - /* The following field value is nonzero if the insn declaration is - the first insn declaration with given equivalence number. */ - char first_ainsn_with_given_equivalence_num; - /* The following field is number of class of equivalence of insns. - It is necessary because many insns may be equivalent with the - point of view of pipeline hazards. */ - int insn_equiv_class_num; - /* The following member value is TRUE if there is an arc in the - automaton marked by the insn into another state. In other - words, the insn can change the state of the automaton. */ - int important_p; -}; - -/* The following describes an automaton for PHR. */ -struct automaton -{ - /* The following field value is the list of insn declarations for - given automaton. */ - ainsn_t ainsn_list; - /* Pointers to the ainsns corresponding to the special reservations. */ - ainsn_t advance_ainsn, collapse_ainsn; - - /* The following field value is the corresponding automaton - declaration. This field is not NULL only if the automatic - partition on automata is not used. */ - struct automaton_decl *corresponding_automaton_decl; - /* The following field value is the next automaton. */ - automaton_t next_automaton; - /* The following field is start state of FA. There are not unit - reservations in the state. */ - state_t start_state; - /* The following field value is number of equivalence classes of - insns (see field `insn_equiv_class_num' in - `insn_reserv_decl'). */ - int insn_equiv_classes_num; - /* The following field value is number of states of final DFA. */ - int achieved_states_num; - /* The following field value is the order number (0, 1, ...) of - given automaton. */ - int automaton_order_num; - /* The following fields contain statistics information about - building automaton. */ - int NDFA_states_num, DFA_states_num; - /* The following field value is defined only if minimization of DFA - is used. */ - int minimal_DFA_states_num; - int NDFA_arcs_num, DFA_arcs_num; - /* The following field value is defined only if minimization of DFA - is used. */ - int minimal_DFA_arcs_num; - /* The following member refers for two table state x ainsn -> int. - ??? Above sentence is incomprehensible. */ - state_ainsn_table_t trans_table; - /* The following member value is maximal value of min issue delay - for insns of the automaton. */ - int max_min_delay; - /* Usually min issue delay is small and we can place several (2, 4, - 8) elements in one vector element. So the compression factor can - be 1 (no compression), 2, 4, 8. */ - int min_issue_delay_table_compression_factor; - /* Total number of locked states in this automaton. */ - int locked_states; -}; - -/* The following is the element of the list of automata. */ -struct automata_list_el -{ - /* The automaton itself. */ - automaton_t automaton; - /* The next automata set element. */ - automata_list_el_t next_automata_list_el; -}; - -/* The following structure describes a table state X ainsn -> int(>= 0). */ -struct state_ainsn_table -{ - /* Automaton to which given table belongs. */ - automaton_t automaton; - /* The following tree vectors for comb vector implementation of the - table. */ - vla_hwint_t comb_vect; - vla_hwint_t check_vect; - vla_hwint_t base_vect; - /* This is simple implementation of the table. */ - vla_hwint_t full_vect; - /* Minimal and maximal values of the previous vectors. */ - int min_comb_vect_el_value, max_comb_vect_el_value; - int min_base_vect_el_value, max_base_vect_el_value; -}; - -/* Macros to access members of unions. Use only them for access to - union members of declarations and regexps. */ - -#if CHECKING_P && (GCC_VERSION >= 2007) - -#define DECL_UNIT(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_unit) \ - decl_mode_check_failed (_decl->mode, "dm_unit", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.unit; })) - -#define DECL_BYPASS(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_bypass) \ - decl_mode_check_failed (_decl->mode, "dm_bypass", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.bypass; })) - -#define DECL_AUTOMATON(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_automaton) \ - decl_mode_check_failed (_decl->mode, "dm_automaton", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.automaton; })) - -#define DECL_EXCL(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_excl) \ - decl_mode_check_failed (_decl->mode, "dm_excl", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.excl; })) - -#define DECL_PRESENCE(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_presence) \ - decl_mode_check_failed (_decl->mode, "dm_presence", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.presence; })) - -#define DECL_ABSENCE(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_absence) \ - decl_mode_check_failed (_decl->mode, "dm_absence", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.absence; })) - -#define DECL_RESERV(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_reserv) \ - decl_mode_check_failed (_decl->mode, "dm_reserv", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.reserv; })) - -#define DECL_INSN_RESERV(d) __extension__ \ -(({ __typeof (d) const _decl = (d); \ - if (_decl->mode != dm_insn_reserv) \ - decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_decl)->decl.insn_reserv; })) - -static const char *decl_name (enum decl_mode); -static void decl_mode_check_failed (enum decl_mode, const char *, - const char *, int, const char *) - ATTRIBUTE_NORETURN; - -/* Return string representation of declaration mode MODE. */ -static const char * -decl_name (enum decl_mode mode) -{ - static char str [100]; - - if (mode == dm_unit) - return "dm_unit"; - else if (mode == dm_bypass) - return "dm_bypass"; - else if (mode == dm_automaton) - return "dm_automaton"; - else if (mode == dm_excl) - return "dm_excl"; - else if (mode == dm_presence) - return "dm_presence"; - else if (mode == dm_absence) - return "dm_absence"; - else if (mode == dm_reserv) - return "dm_reserv"; - else if (mode == dm_insn_reserv) - return "dm_insn_reserv"; - else - sprintf (str, "unknown (%d)", (int) mode); - return str; -} - -/* The function prints message about unexpected declaration and finish - the program. */ -static void -decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str, - const char *file, int line, const char *func) -{ - fprintf - (stderr, - "\n%s: %d: error in %s: DECL check: expected decl %s, have %s\n", - file, line, func, expected_mode_str, decl_name (mode)); - exit (1); -} - - -#define REGEXP_UNIT(r) __extension__ \ -(({ struct regexp *const _regexp = (r); \ - if (_regexp->mode != rm_unit) \ - regexp_mode_check_failed (_regexp->mode, "rm_unit", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_regexp)->regexp.unit; })) - -#define REGEXP_RESERV(r) __extension__ \ -(({ struct regexp *const _regexp = (r); \ - if (_regexp->mode != rm_reserv) \ - regexp_mode_check_failed (_regexp->mode, "rm_reserv", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_regexp)->regexp.reserv; })) - -#define REGEXP_SEQUENCE(r) __extension__ \ -(({ struct regexp *const _regexp = (r); \ - if (_regexp->mode != rm_sequence) \ - regexp_mode_check_failed (_regexp->mode, "rm_sequence", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_regexp)->regexp.sequence; })) - -#define REGEXP_REPEAT(r) __extension__ \ -(({ struct regexp *const _regexp = (r); \ - if (_regexp->mode != rm_repeat) \ - regexp_mode_check_failed (_regexp->mode, "rm_repeat", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_regexp)->regexp.repeat; })) - -#define REGEXP_ALLOF(r) __extension__ \ -(({ struct regexp *const _regexp = (r); \ - if (_regexp->mode != rm_allof) \ - regexp_mode_check_failed (_regexp->mode, "rm_allof", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_regexp)->regexp.allof; })) - -#define REGEXP_ONEOF(r) __extension__ \ -(({ struct regexp *const _regexp = (r); \ - if (_regexp->mode != rm_oneof) \ - regexp_mode_check_failed (_regexp->mode, "rm_oneof", \ - __FILE__, __LINE__, __FUNCTION__); \ - &(_regexp)->regexp.oneof; })) - -static const char *regexp_name (enum regexp_mode); -static void regexp_mode_check_failed (enum regexp_mode, const char *, - const char *, int, - const char *) ATTRIBUTE_NORETURN; - - -/* Return string representation of regexp mode MODE. */ -static const char * -regexp_name (enum regexp_mode mode) -{ - switch (mode) - { - case rm_unit: - return "rm_unit"; - case rm_reserv: - return "rm_reserv"; - case rm_nothing: - return "rm_nothing"; - case rm_sequence: - return "rm_sequence"; - case rm_repeat: - return "rm_repeat"; - case rm_allof: - return "rm_allof"; - case rm_oneof: - return "rm_oneof"; - default: - gcc_unreachable (); - } -} - -/* The function prints message about unexpected regexp and finish the - program. */ -static void -regexp_mode_check_failed (enum regexp_mode mode, - const char *expected_mode_str, - const char *file, int line, const char *func) -{ - fprintf - (stderr, - "\n%s: %d: error in %s: REGEXP check: expected decl %s, have %s\n", - file, line, func, expected_mode_str, regexp_name (mode)); - exit (1); -} - -#else /* #if CHECKING_P && (GCC_VERSION >= 2007) */ - -#define DECL_UNIT(d) (&(d)->decl.unit) -#define DECL_BYPASS(d) (&(d)->decl.bypass) -#define DECL_AUTOMATON(d) (&(d)->decl.automaton) -#define DECL_EXCL(d) (&(d)->decl.excl) -#define DECL_PRESENCE(d) (&(d)->decl.presence) -#define DECL_ABSENCE(d) (&(d)->decl.absence) -#define DECL_RESERV(d) (&(d)->decl.reserv) -#define DECL_INSN_RESERV(d) (&(d)->decl.insn_reserv) - -#define REGEXP_UNIT(r) (&(r)->regexp.unit) -#define REGEXP_RESERV(r) (&(r)->regexp.reserv) -#define REGEXP_SEQUENCE(r) (&(r)->regexp.sequence) -#define REGEXP_REPEAT(r) (&(r)->regexp.repeat) -#define REGEXP_ALLOF(r) (&(r)->regexp.allof) -#define REGEXP_ONEOF(r) (&(r)->regexp.oneof) - -#endif /* #if CHECKING_P && (GCC_VERSION >= 2007) */ - -#define XCREATENODE(T) ((T *) create_node (sizeof (T))) -#define XCREATENODEVEC(T, N) ((T *) create_node (sizeof (T) * (N))) -#define XCREATENODEVAR(T, S) ((T *) create_node ((S))) - -#define XCOPYNODE(T, P) ((T *) copy_node ((P), sizeof (T))) -#define XCOPYNODEVEC(T, P, N) ((T *) copy_node ((P), sizeof (T) * (N))) -#define XCOPYNODEVAR(T, P, S) ((T *) copy_node ((P), (S))) - -/* Create IR structure (node). */ -static void * -create_node (size_t size) -{ - void *result; - - obstack_blank (&irp, size); - result = obstack_base (&irp); - obstack_finish (&irp); - /* Default values of members are NULL and zero. */ - memset (result, 0, size); - return result; -} - -/* Copy IR structure (node). */ -static void * -copy_node (const void *from, size_t size) -{ - void *const result = create_node (size); - memcpy (result, from, size); - return result; -} - -/* The function checks that NAME does not contain quotes (`"'). */ -static const char * -check_name (const char * name, pos_t pos ATTRIBUTE_UNUSED) -{ - const char *str; - - for (str = name; *str != '\0'; str++) - if (*str == '\"') - error ("Name `%s' contains quotes", name); - return name; -} - -/* Pointers to all declarations during IR generation are stored in the - following. */ -static vec<decl_t> decls; - -/* Given a pointer to a (char *) and a separator, return an alloc'ed - string containing the next separated element, taking parentheses - into account if PAR_FLAG has nonzero value. Advance the pointer to - after the string scanned, or the end-of-string. Return NULL if at - end of string. */ -static char * -next_sep_el (const char **pstr, int sep, int par_flag) -{ - char *out_str; - const char *p; - int pars_num; - int n_spaces; - - /* Remove leading whitespaces. */ - while (ISSPACE ((int) **pstr)) - (*pstr)++; - - if (**pstr == '\0') - return NULL; - - n_spaces = 0; - for (pars_num = 0, p = *pstr; *p != '\0'; p++) - { - if (par_flag && *p == '(') - pars_num++; - else if (par_flag && *p == ')') - pars_num--; - else if (pars_num == 0 && *p == sep) - break; - if (pars_num == 0 && ISSPACE ((int) *p)) - n_spaces++; - else - { - for (; n_spaces != 0; n_spaces--) - obstack_1grow (&irp, p [-n_spaces]); - obstack_1grow (&irp, *p); - } - } - obstack_1grow (&irp, '\0'); - out_str = (char *) obstack_base (&irp); - obstack_finish (&irp); - - *pstr = p; - if (**pstr == sep) - (*pstr)++; - - return out_str; -} - -/* Given a string and a separator, return the number of separated - elements in it, taking parentheses into account if PAR_FLAG has - nonzero value. Return 0 for the null string, -1 if parentheses is - not balanced. */ -static int -n_sep_els (const char *s, int sep, int par_flag) -{ - int n; - int pars_num; - - if (*s == '\0') - return 0; - - for (pars_num = 0, n = 1; *s; s++) - if (par_flag && *s == '(') - pars_num++; - else if (par_flag && *s == ')') - pars_num--; - else if (pars_num == 0 && *s == sep) - n++; - - return (pars_num != 0 ? -1 : n); -} - -/* Given a string and a separator, return vector of strings which are - elements in the string and number of elements through els_num. - Take parentheses into account if PAREN_P has nonzero value. The - function also inserts the end marker NULL at the end of vector. - Return 0 for the null string, -1 if parentheses are not balanced. */ -static char ** -get_str_vect (const char *str, int *els_num, int sep, int paren_p) -{ - int i; - char **vect; - const char **pstr; - char *trail; - - *els_num = n_sep_els (str, sep, paren_p); - if (*els_num <= 0) - return NULL; - obstack_blank (&irp, sizeof (char *) * (*els_num + 1)); - vect = (char **) obstack_base (&irp); - obstack_finish (&irp); - pstr = &str; - for (i = 0; i < *els_num; i++) - vect [i] = next_sep_el (pstr, sep, paren_p); - trail = next_sep_el (pstr, sep, paren_p); - gcc_assert (!trail); - vect [i] = NULL; - return vect; -} - -/* Process a DEFINE_CPU_UNIT. - - This gives information about a unit contained in CPU. We fill a - struct unit_decl with information used later by `expand_automata'. */ -static void -gen_cpu_unit (md_rtx_info *info) -{ - decl_t decl; - char **str_cpu_units; - int vect_length; - int i; - - rtx def = info->def; - str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE); - if (str_cpu_units == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 0), GET_RTX_NAME (GET_CODE (def))); - for (i = 0; i < vect_length; i++) - { - decl = XCREATENODE (struct decl); - decl->mode = dm_unit; - decl->pos = 0; - DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos); - DECL_UNIT (decl)->automaton_name = XSTR (def, 1); - DECL_UNIT (decl)->query_p = 0; - DECL_UNIT (decl)->min_occ_cycle_num = -1; - DECL_UNIT (decl)->in_set_p = 0; - decls.safe_push (decl); - } -} - -/* Process a DEFINE_QUERY_CPU_UNIT. - - This gives information about a unit contained in CPU. We fill a - struct unit_decl with information used later by `expand_automata'. */ -static void -gen_query_cpu_unit (md_rtx_info *info) -{ - decl_t decl; - char **str_cpu_units; - int vect_length; - int i; - - rtx def = info->def; - str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', - FALSE); - if (str_cpu_units == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 0), GET_RTX_NAME (GET_CODE (def))); - for (i = 0; i < vect_length; i++) - { - decl = XCREATENODE (struct decl); - decl->mode = dm_unit; - decl->pos = 0; - DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos); - DECL_UNIT (decl)->automaton_name = XSTR (def, 1); - DECL_UNIT (decl)->query_p = 1; - decls.safe_push (decl); - } -} - -/* Process a DEFINE_BYPASS. - - This gives information about a unit contained in the CPU. We fill - in a struct bypass_decl with information used later by - `expand_automata'. */ -static void -gen_bypass (md_rtx_info *info) -{ - decl_t decl; - char **out_patterns; - int out_length; - char **in_patterns; - int in_length; - int i, j; - - rtx def = info->def; - out_patterns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE); - if (out_patterns == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 1), GET_RTX_NAME (GET_CODE (def))); - in_patterns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE); - if (in_patterns == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 2), GET_RTX_NAME (GET_CODE (def))); - for (i = 0; i < out_length; i++) - for (j = 0; j < in_length; j++) - { - decl = XCREATENODE (struct decl); - decl->mode = dm_bypass; - decl->pos = 0; - DECL_BYPASS (decl)->latency = XINT (def, 0); - DECL_BYPASS (decl)->out_pattern = out_patterns[i]; - DECL_BYPASS (decl)->in_pattern = in_patterns[j]; - DECL_BYPASS (decl)->bypass_guard_name = XSTR (def, 3); - decls.safe_push (decl); - } -} - -/* Process an EXCLUSION_SET. - - This gives information about a cpu unit conflicts. We fill a - struct excl_rel_decl (excl) with information used later by - `expand_automata'. */ -static void -gen_excl_set (md_rtx_info *info) -{ - decl_t decl; - char **first_str_cpu_units; - char **second_str_cpu_units; - int first_vect_length; - int length; - int i; - - rtx def = info->def; - first_str_cpu_units - = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE); - if (first_str_cpu_units == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 0), GET_RTX_NAME (GET_CODE (def))); - second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',', - FALSE); - if (second_str_cpu_units == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 1), GET_RTX_NAME (GET_CODE (def))); - length += first_vect_length; - decl = XCREATENODEVAR (struct decl, (sizeof (struct decl) - + (length - 1) * sizeof (char *))); - decl->mode = dm_excl; - decl->pos = 0; - DECL_EXCL (decl)->all_names_num = length; - DECL_EXCL (decl)->first_list_length = first_vect_length; - for (i = 0; i < length; i++) - if (i < first_vect_length) - DECL_EXCL (decl)->names [i] = first_str_cpu_units [i]; - else - DECL_EXCL (decl)->names [i] - = second_str_cpu_units [i - first_vect_length]; - decls.safe_push (decl); -} - -/* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET, - FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P). - - This gives information about a cpu unit reservation requirements. - We fill a struct unit_pattern_rel_decl with information used later - by `expand_automata'. */ -static void -gen_presence_absence_set (md_rtx_info *info, int presence_p, int final_p) -{ - decl_t decl; - char **str_cpu_units; - char **str_pattern_lists; - char ***str_patterns; - int cpu_units_length; - int length; - int patterns_length; - int i; - - rtx def = info->def; - str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',', - FALSE); - if (str_cpu_units == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 0), GET_RTX_NAME (GET_CODE (def))); - str_pattern_lists = get_str_vect (XSTR (def, 1), - &patterns_length, ',', FALSE); - if (str_pattern_lists == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 1), GET_RTX_NAME (GET_CODE (def))); - str_patterns = XOBNEWVEC (&irp, char **, patterns_length); - for (i = 0; i < patterns_length; i++) - { - str_patterns [i] = get_str_vect (str_pattern_lists [i], - &length, ' ', FALSE); - gcc_assert (str_patterns [i]); - } - decl = XCREATENODE (struct decl); - decl->pos = 0; - if (presence_p) - { - decl->mode = dm_presence; - DECL_PRESENCE (decl)->names_num = cpu_units_length; - DECL_PRESENCE (decl)->names = str_cpu_units; - DECL_PRESENCE (decl)->patterns = str_patterns; - DECL_PRESENCE (decl)->patterns_num = patterns_length; - DECL_PRESENCE (decl)->final_p = final_p; - } - else - { - decl->mode = dm_absence; - DECL_ABSENCE (decl)->names_num = cpu_units_length; - DECL_ABSENCE (decl)->names = str_cpu_units; - DECL_ABSENCE (decl)->patterns = str_patterns; - DECL_ABSENCE (decl)->patterns_num = patterns_length; - DECL_ABSENCE (decl)->final_p = final_p; - } - decls.safe_push (decl); -} - -/* Process a PRESENCE_SET. - - This gives information about a cpu unit reservation requirements. - We fill a struct unit_pattern_rel_decl (presence) with information - used later by `expand_automata'. */ -static void -gen_presence_set (md_rtx_info *info) -{ - gen_presence_absence_set (info, TRUE, FALSE); -} - -/* Process a FINAL_PRESENCE_SET. - - This gives information about a cpu unit reservation requirements. - We fill a struct unit_pattern_rel_decl (presence) with information - used later by `expand_automata'. */ -static void -gen_final_presence_set (md_rtx_info *info) -{ - gen_presence_absence_set (info, TRUE, TRUE); -} - -/* Process an ABSENCE_SET. - - This gives information about a cpu unit reservation requirements. - We fill a struct unit_pattern_rel_decl (absence) with information - used later by `expand_automata'. */ -static void -gen_absence_set (md_rtx_info *info) -{ - gen_presence_absence_set (info, FALSE, FALSE); -} - -/* Process a FINAL_ABSENCE_SET. - - This gives information about a cpu unit reservation requirements. - We fill a struct unit_pattern_rel_decl (absence) with information - used later by `expand_automata'. */ -static void -gen_final_absence_set (md_rtx_info *info) -{ - gen_presence_absence_set (info, FALSE, TRUE); -} - -/* Process a DEFINE_AUTOMATON. - - This gives information about a finite state automaton used for - recognizing pipeline hazards. We fill a struct automaton_decl - with information used later by `expand_automata'. */ -static void -gen_automaton (md_rtx_info *info) -{ - decl_t decl; - char **str_automata; - int vect_length; - int i; - - rtx def = info->def; - str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE); - if (str_automata == NULL) - fatal_at (info->loc, "invalid string `%s' in %s", - XSTR (def, 0), GET_RTX_NAME (GET_CODE (def))); - for (i = 0; i < vect_length; i++) - { - decl = XCREATENODE (struct decl); - decl->mode = dm_automaton; - decl->pos = 0; - DECL_AUTOMATON (decl)->name = check_name (str_automata [i], decl->pos); - decls.safe_push (decl); - } -} - -/* Process an AUTOMATA_OPTION. - - This gives information how to generate finite state automaton used - for recognizing pipeline hazards. */ -static void -gen_automata_option (md_rtx_info *info) -{ - const char *option = XSTR (info->def, 0); - if (strcmp (option, NO_MINIMIZATION_OPTION + 1) == 0) - no_minimization_flag = 1; - else if (strcmp (option, TIME_OPTION + 1) == 0) - time_flag = 1; - else if (strcmp (option, STATS_OPTION + 1) == 0) - stats_flag = 1; - else if (strcmp (option, V_OPTION + 1) == 0) - v_flag = 1; - else if (strcmp (option, W_OPTION + 1) == 0) - w_flag = 1; - else if (strcmp (option, NDFA_OPTION + 1) == 0) - ndfa_flag = 1; - else if (strcmp (option, COLLAPSE_OPTION + 1) == 0) - collapse_flag = 1; - else if (strcmp (option, NO_COMB_OPTION + 1) == 0) - no_comb_flag = 1; - else if (strcmp (option, PROGRESS_OPTION + 1) == 0) - progress_flag = 1; - else - fatal_at (info->loc, "invalid option `%s' in %s", - option, GET_RTX_NAME (GET_CODE (info->def))); -} - -/* Name in reservation to denote absence reservation. */ -#define NOTHING_NAME "nothing" - -/* The following string contains original reservation string being - parsed. */ -static const char *reserv_str; - -/* Parse an element in STR. */ -static regexp_t -gen_regexp_el (const char *str) -{ - regexp_t regexp; - char *dstr; - int len; - - if (*str == '(') - { - len = strlen (str); - if (str [len - 1] != ')') - fatal ("garbage after ) in reservation `%s'", reserv_str); - dstr = XALLOCAVAR (char, len - 1); - memcpy (dstr, str + 1, len - 2); - dstr [len-2] = '\0'; - regexp = gen_regexp_sequence (dstr); - } - else if (strcmp (str, NOTHING_NAME) == 0) - { - regexp = XCREATENODE (struct regexp); - regexp->mode = rm_nothing; - } - else - { - regexp = XCREATENODE (struct regexp); - regexp->mode = rm_unit; - REGEXP_UNIT (regexp)->name = str; - } - return regexp; -} - -/* Parse construction `repeat' in STR. */ -static regexp_t -gen_regexp_repeat (const char *str) -{ - regexp_t regexp; - regexp_t repeat; - char **repeat_vect; - int els_num; - int i; - - repeat_vect = get_str_vect (str, &els_num, '*', TRUE); - if (repeat_vect == NULL) - fatal ("invalid `%s' in reservation `%s'", str, reserv_str); - if (els_num > 1) - { - regexp = gen_regexp_el (repeat_vect [0]); - for (i = 1; i < els_num; i++) - { - repeat = XCREATENODE (struct regexp); - repeat->mode = rm_repeat; - REGEXP_REPEAT (repeat)->regexp = regexp; - REGEXP_REPEAT (repeat)->repeat_num = atoi (repeat_vect [i]); - if (REGEXP_REPEAT (repeat)->repeat_num <= 1) - fatal ("repetition `%s' <= 1 in reservation `%s'", - str, reserv_str); - regexp = repeat; - } - return regexp; - } - else - return gen_regexp_el (repeat_vect[0]); -} - -/* Parse reservation STR which possibly contains separator '+'. */ -static regexp_t -gen_regexp_allof (const char *str) -{ - regexp_t allof; - char **allof_vect; - int els_num; - int i; - - allof_vect = get_str_vect (str, &els_num, '+', TRUE); - if (allof_vect == NULL) - fatal ("invalid `%s' in reservation `%s'", str, reserv_str); - if (els_num > 1) - { - allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) * (els_num - 1)); - allof->mode = rm_allof; - REGEXP_ALLOF (allof)->regexps_num = els_num; - for (i = 0; i < els_num; i++) - REGEXP_ALLOF (allof)->regexps [i] = gen_regexp_repeat (allof_vect [i]); - return allof; - } - else - return gen_regexp_repeat (allof_vect[0]); -} - -/* Parse reservation STR which possibly contains separator '|'. */ -static regexp_t -gen_regexp_oneof (const char *str) -{ - regexp_t oneof; - char **oneof_vect; - int els_num; - int i; - - oneof_vect = get_str_vect (str, &els_num, '|', TRUE); - if (oneof_vect == NULL) - fatal ("invalid `%s' in reservation `%s'", str, reserv_str); - if (els_num > 1) - { - oneof = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) * (els_num - 1)); - oneof->mode = rm_oneof; - REGEXP_ONEOF (oneof)->regexps_num = els_num; - for (i = 0; i < els_num; i++) - REGEXP_ONEOF (oneof)->regexps [i] = gen_regexp_allof (oneof_vect [i]); - return oneof; - } - else - return gen_regexp_allof (oneof_vect[0]); -} - -/* Parse reservation STR which possibly contains separator ','. */ -static regexp_t -gen_regexp_sequence (const char *str) -{ - regexp_t sequence; - char **sequence_vect; - int els_num; - int i; - - sequence_vect = get_str_vect (str, &els_num, ',', TRUE); - if (els_num == -1) - fatal ("unbalanced parentheses in reservation `%s'", str); - if (sequence_vect == NULL) - fatal ("invalid reservation `%s'", str); - if (els_num > 1) - { - sequence = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) * (els_num - 1)); - sequence->mode = rm_sequence; - REGEXP_SEQUENCE (sequence)->regexps_num = els_num; - for (i = 0; i < els_num; i++) - REGEXP_SEQUENCE (sequence)->regexps [i] - = gen_regexp_oneof (sequence_vect [i]); - return sequence; - } - else - return gen_regexp_oneof (sequence_vect[0]); -} - -/* Parse construction reservation STR. */ -static regexp_t -gen_regexp (const char *str) -{ - reserv_str = str; - return gen_regexp_sequence (str); -} - -/* Process a DEFINE_RESERVATION. - - This gives information about a reservation of cpu units. We fill - in a struct reserv_decl with information used later by - `expand_automata'. */ -static void -gen_reserv (md_rtx_info *info) -{ - decl_t decl; - - rtx def = info->def; - decl = XCREATENODE (struct decl); - decl->mode = dm_reserv; - decl->pos = 0; - DECL_RESERV (decl)->name = check_name (XSTR (def, 0), decl->pos); - DECL_RESERV (decl)->regexp = gen_regexp (XSTR (def, 1)); - decls.safe_push (decl); -} - -/* Process a DEFINE_INSN_RESERVATION. - - This gives information about the reservation of cpu units by an - insn. We fill a struct insn_reserv_decl with information used - later by `expand_automata'. */ -static void -gen_insn_reserv (md_rtx_info *info) -{ - decl_t decl; - - rtx def = info->def; - decl = XCREATENODE (struct decl); - decl->mode = dm_insn_reserv; - decl->pos = 0; - DECL_INSN_RESERV (decl)->name - = check_name (XSTR (def, 0), decl->pos); - DECL_INSN_RESERV (decl)->default_latency = XINT (def, 1); - DECL_INSN_RESERV (decl)->condexp = XEXP (def, 2); - DECL_INSN_RESERV (decl)->regexp = gen_regexp (XSTR (def, 3)); - decls.safe_push (decl); -} - - - -/* The function evaluates hash value (0..UINT_MAX) of string. */ -static unsigned -string_hash (const char *string) -{ - unsigned result, i; - - for (result = i = 0;*string++ != '\0'; i++) - result += ((unsigned char) *string << (i % CHAR_BIT)); - return result; -} - - - -/* This page contains abstract data `table of automaton declarations'. - Elements of the table is nodes representing automaton declarations. - Key of the table elements is name of given automaton. Remember - that automaton names have own space. */ - -/* The function evaluates hash value of an automaton declaration. The - function is used by abstract data `hashtab'. The function returns - hash value (0..UINT_MAX) of given automaton declaration. */ -static hashval_t -automaton_decl_hash (const void *automaton_decl) -{ - const_decl_t const decl = (const_decl_t) automaton_decl; - - gcc_assert (decl->mode != dm_automaton - || DECL_AUTOMATON (decl)->name); - return string_hash (DECL_AUTOMATON (decl)->name); -} - -/* The function tests automaton declarations on equality of their - keys. The function is used by abstract data `hashtab'. The - function returns 1 if the declarations have the same key, 0 - otherwise. */ -static int -automaton_decl_eq_p (const void* automaton_decl_1, - const void* automaton_decl_2) -{ - const_decl_t const decl1 = (const_decl_t) automaton_decl_1; - const_decl_t const decl2 = (const_decl_t) automaton_decl_2; - - gcc_assert (decl1->mode == dm_automaton - && DECL_AUTOMATON (decl1)->name - && decl2->mode == dm_automaton - && DECL_AUTOMATON (decl2)->name); - return strcmp (DECL_AUTOMATON (decl1)->name, - DECL_AUTOMATON (decl2)->name) == 0; -} - -/* The automaton declaration table itself is represented by the - following variable. */ -static htab_t automaton_decl_table; - -/* The function inserts automaton declaration into the table. The - function does nothing if an automaton declaration with the same key - exists already in the table. The function returns automaton - declaration node in the table with the same key as given automaton - declaration node. */ -static decl_t -insert_automaton_decl (decl_t automaton_decl) -{ - void **entry_ptr; - - entry_ptr = htab_find_slot (automaton_decl_table, automaton_decl, INSERT); - if (*entry_ptr == NULL) - *entry_ptr = (void *) automaton_decl; - return (decl_t) *entry_ptr; -} - -/* The following variable value is node representing automaton - declaration. The node used for searching automaton declaration - with given name. */ -static struct decl work_automaton_decl; - -/* The function searches for automaton declaration in the table with - the same key as node representing name of the automaton - declaration. The function returns node found in the table, NULL if - such node does not exist in the table. */ -static decl_t -find_automaton_decl (const char *name) -{ - void *entry; - - work_automaton_decl.mode = dm_automaton; - DECL_AUTOMATON (&work_automaton_decl)->name = name; - entry = htab_find (automaton_decl_table, &work_automaton_decl); - return (decl_t) entry; -} - -/* The function creates empty automaton declaration table and node - representing automaton declaration and used for searching automaton - declaration with given name. The function must be called only once - before any work with the automaton declaration table. */ -static void -initiate_automaton_decl_table (void) -{ - work_automaton_decl.mode = dm_automaton; - automaton_decl_table = htab_create (10, automaton_decl_hash, - automaton_decl_eq_p, (htab_del) 0); -} - -/* The function deletes the automaton declaration table. Only call of - function `initiate_automaton_decl_table' is possible immediately - after this function call. */ -static void -finish_automaton_decl_table (void) -{ - htab_delete (automaton_decl_table); -} - - - -/* This page contains abstract data `table of insn declarations'. - Elements of the table is nodes representing insn declarations. Key - of the table elements is name of given insn (in corresponding - define_insn_reservation). Remember that insn names have own - space. */ - -/* The function evaluates hash value of an insn declaration. The - function is used by abstract data `hashtab'. The function returns - hash value (0..UINT_MAX) of given insn declaration. */ -static hashval_t -insn_decl_hash (const void *insn_decl) -{ - const_decl_t const decl = (const_decl_t) insn_decl; - - gcc_assert (decl->mode == dm_insn_reserv - && DECL_INSN_RESERV (decl)->name); - return string_hash (DECL_INSN_RESERV (decl)->name); -} - -/* The function tests insn declarations on equality of their keys. - The function is used by abstract data `hashtab'. The function - returns 1 if declarations have the same key, 0 otherwise. */ -static int -insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2) -{ - const_decl_t const decl1 = (const_decl_t) insn_decl_1; - const_decl_t const decl2 = (const_decl_t) insn_decl_2; - - gcc_assert (decl1->mode == dm_insn_reserv - && DECL_INSN_RESERV (decl1)->name - && decl2->mode == dm_insn_reserv - && DECL_INSN_RESERV (decl2)->name); - return strcmp (DECL_INSN_RESERV (decl1)->name, - DECL_INSN_RESERV (decl2)->name) == 0; -} - -/* The insn declaration table itself is represented by the following - variable. The table does not contain insn reservation - declarations. */ -static htab_t insn_decl_table; - -/* The function inserts insn declaration into the table. The function - does nothing if an insn declaration with the same key exists - already in the table. The function returns insn declaration node - in the table with the same key as given insn declaration node. */ -static decl_t -insert_insn_decl (decl_t insn_decl) -{ - void **entry_ptr; - - entry_ptr = htab_find_slot (insn_decl_table, insn_decl, INSERT); - if (*entry_ptr == NULL) - *entry_ptr = (void *) insn_decl; - return (decl_t) *entry_ptr; -} - -/* The following variable value is node representing insn reservation - declaration. The node used for searching insn reservation - declaration with given name. */ -static struct decl work_insn_decl; - -/* The function searches for insn reservation declaration in the table - with the same key as node representing name of the insn reservation - declaration. The function returns node found in the table, NULL if - such node does not exist in the table. */ -static decl_t -find_insn_decl (const char *name) -{ - void *entry; - - work_insn_decl.mode = dm_insn_reserv; - DECL_INSN_RESERV (&work_insn_decl)->name = name; - entry = htab_find (insn_decl_table, &work_insn_decl); - return (decl_t) entry; -} - -/* The function creates empty insn declaration table and node - representing insn declaration and used for searching insn - declaration with given name. The function must be called only once - before any work with the insn declaration table. */ -static void -initiate_insn_decl_table (void) -{ - work_insn_decl.mode = dm_insn_reserv; - insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p, - (htab_del) 0); -} - -/* The function deletes the insn declaration table. Only call of - function `initiate_insn_decl_table' is possible immediately after - this function call. */ -static void -finish_insn_decl_table (void) -{ - htab_delete (insn_decl_table); -} - - - -/* This page contains abstract data `table of declarations'. Elements - of the table is nodes representing declarations (of units and - reservations). Key of the table elements is names of given - declarations. */ - -/* The function evaluates hash value of a declaration. The function - is used by abstract data `hashtab'. The function returns hash - value (0..UINT_MAX) of given declaration. */ -static hashval_t -decl_hash (const void *decl) -{ - const_decl_t const d = (const_decl_t) decl; - - gcc_assert ((d->mode == dm_unit && DECL_UNIT (d)->name) - || (d->mode == dm_reserv && DECL_RESERV (d)->name)); - return string_hash (d->mode == dm_unit - ? DECL_UNIT (d)->name : DECL_RESERV (d)->name); -} - -/* The function tests declarations on equality of their keys. The - function is used by abstract data 'hashtab'. The function - returns 1 if the declarations have the same key, 0 otherwise. */ -static int -decl_eq_p (const void *decl_1, const void *decl_2) -{ - const_decl_t const d1 = (const_decl_t) decl_1; - const_decl_t const d2 = (const_decl_t) decl_2; - - gcc_assert ((d1->mode == dm_unit && DECL_UNIT (d1)->name) - || (d1->mode == dm_reserv && DECL_RESERV (d1)->name)); - gcc_assert ((d2->mode == dm_unit && DECL_UNIT (d2)->name) - || (d2->mode == dm_reserv && DECL_RESERV (d2)->name)); - return strcmp ((d1->mode == dm_unit - ? DECL_UNIT (d1)->name : DECL_RESERV (d1)->name), - (d2->mode == dm_unit - ? DECL_UNIT (d2)->name : DECL_RESERV (d2)->name)) == 0; -} - -/* The declaration table itself is represented by the following - variable. */ -static htab_t decl_table; - -/* The function inserts declaration into the table. The function does - nothing if a declaration with the same key exists already in the - table. The function returns declaration node in the table with the - same key as given declaration node. */ - -static decl_t -insert_decl (decl_t decl) -{ - void **entry_ptr; - - entry_ptr = htab_find_slot (decl_table, decl, INSERT); - if (*entry_ptr == NULL) - *entry_ptr = (void *) decl; - return (decl_t) *entry_ptr; -} - -/* The following variable value is node representing declaration. The - node used for searching declaration with given name. */ -static struct decl work_decl; - -/* The function searches for declaration in the table with the same - key as node representing name of the declaration. The function - returns node found in the table, NULL if such node does not exist - in the table. */ -static decl_t -find_decl (const char *name) -{ - void *entry; - - work_decl.mode = dm_unit; - DECL_UNIT (&work_decl)->name = name; - entry = htab_find (decl_table, &work_decl); - return (decl_t) entry; -} - -/* The function creates empty declaration table and node representing - declaration and used for searching declaration with given name. - The function must be called only once before any work with the - declaration table. */ -static void -initiate_decl_table (void) -{ - work_decl.mode = dm_unit; - decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0); -} - -/* The function deletes the declaration table. Only call of function - `initiate_declaration_table' is possible immediately after this - function call. */ -static void -finish_decl_table (void) -{ - htab_delete (decl_table); -} - - - -/* This page contains checker of pipeline hazard description. */ - -/* Checking NAMES in an exclusion clause vector and returning formed - unit_set_el_list. */ -static unit_set_el_t -process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED) -{ - unit_set_el_t el_list; - unit_set_el_t last_el; - unit_set_el_t new_el; - decl_t decl_in_table; - int i; - - el_list = NULL; - last_el = NULL; - for (i = 0; i < num; i++) - { - decl_in_table = find_decl (names [i]); - if (decl_in_table == NULL) - error ("unit `%s' in exclusion is not declared", names [i]); - else if (decl_in_table->mode != dm_unit) - error ("`%s' in exclusion is not unit", names [i]); - else - { - new_el = XCREATENODE (struct unit_set_el); - new_el->unit_decl = DECL_UNIT (decl_in_table); - new_el->next_unit_set_el = NULL; - if (last_el == NULL) - el_list = last_el = new_el; - else - { - last_el->next_unit_set_el = new_el; - last_el = last_el->next_unit_set_el; - } - } - } - return el_list; -} - -/* The function adds each element from SOURCE_LIST to the exclusion - list of the each element from DEST_LIST. Checking situation "unit - excludes itself". */ -static void -add_excls (unit_set_el_t dest_list, unit_set_el_t source_list, - pos_t excl_pos ATTRIBUTE_UNUSED) -{ - unit_set_el_t dst; - unit_set_el_t src; - unit_set_el_t curr_el; - unit_set_el_t prev_el; - unit_set_el_t copy; - - for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el) - for (src = source_list; src != NULL; src = src->next_unit_set_el) - { - if (dst->unit_decl == src->unit_decl) - { - error ("unit `%s' excludes itself", src->unit_decl->name); - continue; - } - if (dst->unit_decl->automaton_name != NULL - && src->unit_decl->automaton_name != NULL - && strcmp (dst->unit_decl->automaton_name, - src->unit_decl->automaton_name) != 0) - { - error ("units `%s' and `%s' in exclusion set belong to different automata", - src->unit_decl->name, dst->unit_decl->name); - continue; - } - for (curr_el = dst->unit_decl->excl_list, prev_el = NULL; - curr_el != NULL; - prev_el = curr_el, curr_el = curr_el->next_unit_set_el) - if (curr_el->unit_decl == src->unit_decl) - break; - if (curr_el == NULL) - { - /* Element not found - insert. */ - copy = XCOPYNODE (struct unit_set_el, src); - copy->next_unit_set_el = NULL; - if (prev_el == NULL) - dst->unit_decl->excl_list = copy; - else - prev_el->next_unit_set_el = copy; - } - } -} - -/* Checking NAMES in presence/absence clause and returning the - formed unit_set_el_list. The function is called only after - processing all exclusion sets. */ -static unit_set_el_t -process_presence_absence_names (char **names, int num, - pos_t req_pos ATTRIBUTE_UNUSED, - int presence_p, int final_p) -{ - unit_set_el_t el_list; - unit_set_el_t last_el; - unit_set_el_t new_el; - decl_t decl_in_table; - int i; - - el_list = NULL; - last_el = NULL; - for (i = 0; i < num; i++) - { - decl_in_table = find_decl (names [i]); - if (decl_in_table == NULL) - error ((presence_p - ? (final_p - ? "unit `%s' in final presence set is not declared" - : "unit `%s' in presence set is not declared") - : (final_p - ? "unit `%s' in final absence set is not declared" - : "unit `%s' in absence set is not declared")), names [i]); - else if (decl_in_table->mode != dm_unit) - error ((presence_p - ? (final_p - ? "`%s' in final presence set is not unit" - : "`%s' in presence set is not unit") - : (final_p - ? "`%s' in final absence set is not unit" - : "`%s' in absence set is not unit")), names [i]); - else - { - new_el = XCREATENODE (struct unit_set_el); - new_el->unit_decl = DECL_UNIT (decl_in_table); - new_el->next_unit_set_el = NULL; - if (last_el == NULL) - el_list = last_el = new_el; - else - { - last_el->next_unit_set_el = new_el; - last_el = last_el->next_unit_set_el; - } - } - } - return el_list; -} - -/* Checking NAMES in patterns of a presence/absence clause and - returning the formed pattern_set_el_list. The function is called - only after processing all exclusion sets. */ -static pattern_set_el_t -process_presence_absence_patterns (char ***patterns, int num, - pos_t req_pos ATTRIBUTE_UNUSED, - int presence_p, int final_p) -{ - pattern_set_el_t el_list; - pattern_set_el_t last_el; - pattern_set_el_t new_el; - decl_t decl_in_table; - int i, j; - - el_list = NULL; - last_el = NULL; - for (i = 0; i < num; i++) - { - for (j = 0; patterns [i] [j] != NULL; j++) - ; - new_el = XCREATENODEVAR (struct pattern_set_el, - sizeof (struct pattern_set_el) - + sizeof (struct unit_decl *) * j); - new_el->unit_decls - = (struct unit_decl **) ((char *) new_el - + sizeof (struct pattern_set_el)); - new_el->next_pattern_set_el = NULL; - if (last_el == NULL) - el_list = last_el = new_el; - else - { - last_el->next_pattern_set_el = new_el; - last_el = last_el->next_pattern_set_el; - } - new_el->units_num = 0; - for (j = 0; patterns [i] [j] != NULL; j++) - { - decl_in_table = find_decl (patterns [i] [j]); - if (decl_in_table == NULL) - error ((presence_p - ? (final_p - ? "unit `%s' in final presence set is not declared" - : "unit `%s' in presence set is not declared") - : (final_p - ? "unit `%s' in final absence set is not declared" - : "unit `%s' in absence set is not declared")), - patterns [i] [j]); - else if (decl_in_table->mode != dm_unit) - error ((presence_p - ? (final_p - ? "`%s' in final presence set is not unit" - : "`%s' in presence set is not unit") - : (final_p - ? "`%s' in final absence set is not unit" - : "`%s' in absence set is not unit")), - patterns [i] [j]); - else - { - new_el->unit_decls [new_el->units_num] - = DECL_UNIT (decl_in_table); - new_el->units_num++; - } - } - } - return el_list; -} - -/* The function adds each element from PATTERN_LIST to presence (if - PRESENCE_P) or absence list of the each element from DEST_LIST. - Checking situations "unit requires own absence", and "unit excludes - and requires presence of ...", "unit requires absence and presence - of ...", "units in (final) presence set belong to different - automata", and "units in (final) absence set belong to different - automata". Remember that we process absence sets only after all - presence sets. */ -static void -add_presence_absence (unit_set_el_t dest_list, - pattern_set_el_t pattern_list, - pos_t req_pos ATTRIBUTE_UNUSED, - int presence_p, int final_p) -{ - unit_set_el_t dst; - pattern_set_el_t pat; - struct unit_decl *unit; - unit_set_el_t curr_excl_el; - pattern_set_el_t curr_pat_el; - pattern_set_el_t prev_el; - pattern_set_el_t copy; - int i; - int no_error_flag; - - for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el) - for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el) - { - for (i = 0; i < pat->units_num; i++) - { - unit = pat->unit_decls [i]; - if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p) - { - error ("unit `%s' requires own absence", unit->name); - continue; - } - if (dst->unit_decl->automaton_name != NULL - && unit->automaton_name != NULL - && strcmp (dst->unit_decl->automaton_name, - unit->automaton_name) != 0) - { - error ((presence_p - ? (final_p - ? "units `%s' and `%s' in final presence set belong to different automata" - : "units `%s' and `%s' in presence set belong to different automata") - : (final_p - ? "units `%s' and `%s' in final absence set belong to different automata" - : "units `%s' and `%s' in absence set belong to different automata")), - unit->name, dst->unit_decl->name); - continue; - } - no_error_flag = 1; - if (presence_p) - for (curr_excl_el = dst->unit_decl->excl_list; - curr_excl_el != NULL; - curr_excl_el = curr_excl_el->next_unit_set_el) - { - if (unit == curr_excl_el->unit_decl && pat->units_num == 1) - { - if (!w_flag) - { - error ("unit `%s' excludes and requires presence of `%s'", - dst->unit_decl->name, unit->name); - no_error_flag = 0; - } - else - warning ("unit `%s' excludes and requires presence of `%s'", - dst->unit_decl->name, unit->name); - } - } - else if (pat->units_num == 1) - for (curr_pat_el = dst->unit_decl->presence_list; - curr_pat_el != NULL; - curr_pat_el = curr_pat_el->next_pattern_set_el) - if (curr_pat_el->units_num == 1 - && unit == curr_pat_el->unit_decls [0]) - { - if (!w_flag) - { - error ("unit `%s' requires absence and presence of `%s'", - dst->unit_decl->name, unit->name); - no_error_flag = 0; - } - else - warning ("unit `%s' requires absence and presence of `%s'", - dst->unit_decl->name, unit->name); - } - if (no_error_flag) - { - for (prev_el = (presence_p - ? (final_p - ? dst->unit_decl->final_presence_list - : dst->unit_decl->presence_list) - : (final_p - ? dst->unit_decl->final_absence_list - : dst->unit_decl->absence_list)); - prev_el != NULL && prev_el->next_pattern_set_el != NULL; - prev_el = prev_el->next_pattern_set_el) - ; - copy = XCOPYNODE (struct pattern_set_el, pat); - copy->next_pattern_set_el = NULL; - if (prev_el == NULL) - { - if (presence_p) - { - if (final_p) - dst->unit_decl->final_presence_list = copy; - else - dst->unit_decl->presence_list = copy; - } - else if (final_p) - dst->unit_decl->final_absence_list = copy; - else - dst->unit_decl->absence_list = copy; - } - else - prev_el->next_pattern_set_el = copy; - } - } - } -} - - -/* The function inserts BYPASS in the list of bypasses of the - corresponding output insn. The order of bypasses in the list is - described in a comment for member `bypass_list' (see above). If - there is already the same bypass in the list the function reports - this and does nothing. */ -static void -insert_bypass (struct bypass_decl *bypass) -{ - struct bypass_decl *curr, *last; - struct insn_reserv_decl *out_insn_reserv = bypass->out_insn_reserv; - struct insn_reserv_decl *in_insn_reserv = bypass->in_insn_reserv; - - for (curr = out_insn_reserv->bypass_list, last = NULL; - curr != NULL; - last = curr, curr = curr->next) - if (curr->in_insn_reserv == in_insn_reserv) - { - if ((bypass->bypass_guard_name != NULL - && curr->bypass_guard_name != NULL - && ! strcmp (bypass->bypass_guard_name, curr->bypass_guard_name)) - || bypass->bypass_guard_name == curr->bypass_guard_name) - { - if (bypass->bypass_guard_name == NULL) - { - if (!w_flag) - error ("the same bypass `%s - %s' is already defined", - bypass->out_pattern, bypass->in_pattern); - else - warning ("the same bypass `%s - %s' is already defined", - bypass->out_pattern, bypass->in_pattern); - } - else if (!w_flag) - error ("the same bypass `%s - %s' (guard %s) is already defined", - bypass->out_pattern, bypass->in_pattern, - bypass->bypass_guard_name); - else - warning - ("the same bypass `%s - %s' (guard %s) is already defined", - bypass->out_pattern, bypass->in_pattern, - bypass->bypass_guard_name); - return; - } - if (curr->bypass_guard_name == NULL) - break; - if (curr->next == NULL || curr->next->in_insn_reserv != in_insn_reserv) - { - last = curr; - break; - } - - } - if (last == NULL) - { - bypass->next = out_insn_reserv->bypass_list; - out_insn_reserv->bypass_list = bypass; - } - else - { - bypass->next = last->next; - last->next = bypass; - } -} - -/* BYPASS is a define_bypass decl that includes glob pattern PATTERN. - Call FN (BYPASS, INSN, DATA) for each matching instruction INSN. */ - -static void -for_each_matching_insn (decl_t bypass, const char *pattern, - void (*fn) (decl_t, decl_t, void *), void *data) -{ - decl_t insn_reserv; - bool matched_p; - int i; - - matched_p = false; - if (strpbrk (pattern, "*?[")) - for (i = 0; i < description->decls_num; i++) - { - insn_reserv = description->decls[i]; - if (insn_reserv->mode == dm_insn_reserv - && fnmatch (pattern, DECL_INSN_RESERV (insn_reserv)->name, 0) == 0) - { - fn (bypass, insn_reserv, data); - matched_p = true; - } - } - else - { - insn_reserv = find_insn_decl (pattern); - if (insn_reserv) - { - fn (bypass, insn_reserv, data); - matched_p = true; - } - } - if (!matched_p) - error ("there is no insn reservation that matches `%s'", pattern); -} - -/* A subroutine of process_bypass that is called for each pair - of matching instructions. OUT_INSN_RESERV is the output - instruction and DATA is the input instruction. */ - -static void -process_bypass_2 (decl_t model, decl_t out_insn_reserv, void *data) -{ - struct bypass_decl *bypass; - decl_t in_insn_reserv; - - in_insn_reserv = (decl_t) data; - if (strcmp (DECL_INSN_RESERV (in_insn_reserv)->name, - DECL_BYPASS (model)->in_pattern) == 0 - && strcmp (DECL_INSN_RESERV (out_insn_reserv)->name, - DECL_BYPASS (model)->out_pattern) == 0) - bypass = DECL_BYPASS (model); - else - { - bypass = XCNEW (struct bypass_decl); - bypass->latency = DECL_BYPASS (model)->latency; - bypass->out_pattern = DECL_INSN_RESERV (out_insn_reserv)->name; - bypass->in_pattern = DECL_INSN_RESERV (in_insn_reserv)->name; - bypass->bypass_guard_name = DECL_BYPASS (model)->bypass_guard_name; - } - bypass->out_insn_reserv = DECL_INSN_RESERV (out_insn_reserv); - bypass->in_insn_reserv = DECL_INSN_RESERV (in_insn_reserv); - insert_bypass (bypass); -} - -/* A subroutine of process_bypass that is called for each input - instruction IN_INSN_RESERV. */ - -static void -process_bypass_1 (decl_t bypass, decl_t in_insn_reserv, - void *data ATTRIBUTE_UNUSED) -{ - for_each_matching_insn (bypass, DECL_BYPASS (bypass)->out_pattern, - process_bypass_2, in_insn_reserv); -} - -/* Process define_bypass decl BYPASS, inserting a bypass for each specific - pair of insn reservations. */ - -static void -process_bypass (decl_t bypass) -{ - for_each_matching_insn (bypass, DECL_BYPASS (bypass)->in_pattern, - process_bypass_1, NULL); -} - -/* The function processes pipeline description declarations, checks - their correctness, and forms exclusion/presence/absence sets. */ -static void -process_decls (void) -{ - decl_t decl; - decl_t automaton_decl; - decl_t decl_in_table; - int automaton_presence; - int i; - - /* Checking repeated automata declarations. */ - automaton_presence = 0; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_automaton) - { - automaton_presence = 1; - decl_in_table = insert_automaton_decl (decl); - if (decl_in_table != decl) - { - if (!w_flag) - error ("repeated declaration of automaton `%s'", - DECL_AUTOMATON (decl)->name); - else - warning ("repeated declaration of automaton `%s'", - DECL_AUTOMATON (decl)->name); - } - } - } - /* Checking undeclared automata, repeated declarations (except for - automata) and correctness of their attributes (insn latency times - etc.). */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - { - if (DECL_INSN_RESERV (decl)->default_latency < 0) - error ("define_insn_reservation `%s' has negative latency time", - DECL_INSN_RESERV (decl)->name); - DECL_INSN_RESERV (decl)->insn_num = description->insns_num; - description->insns_num++; - decl_in_table = insert_insn_decl (decl); - if (decl_in_table != decl) - error ("`%s' is already used as insn reservation name", - DECL_INSN_RESERV (decl)->name); - } - else if (decl->mode == dm_bypass) - { - if (DECL_BYPASS (decl)->latency < 0) - error ("define_bypass `%s - %s' has negative latency time", - DECL_BYPASS (decl)->out_pattern, - DECL_BYPASS (decl)->in_pattern); - } - else if (decl->mode == dm_unit || decl->mode == dm_reserv) - { - if (decl->mode == dm_unit) - { - DECL_UNIT (decl)->automaton_decl = NULL; - if (DECL_UNIT (decl)->automaton_name != NULL) - { - automaton_decl - = find_automaton_decl (DECL_UNIT (decl)->automaton_name); - if (automaton_decl == NULL) - error ("automaton `%s' is not declared", - DECL_UNIT (decl)->automaton_name); - else - { - DECL_AUTOMATON (automaton_decl)->automaton_is_used = 1; - DECL_UNIT (decl)->automaton_decl - = DECL_AUTOMATON (automaton_decl); - } - } - else if (automaton_presence) - error ("define_unit `%s' without automaton when one defined", - DECL_UNIT (decl)->name); - DECL_UNIT (decl)->unit_num = description->units_num; - description->units_num++; - if (strcmp (DECL_UNIT (decl)->name, NOTHING_NAME) == 0) - { - error ("`%s' is declared as cpu unit", NOTHING_NAME); - continue; - } - decl_in_table = find_decl (DECL_UNIT (decl)->name); - } - else - { - if (strcmp (DECL_RESERV (decl)->name, NOTHING_NAME) == 0) - { - error ("`%s' is declared as cpu reservation", NOTHING_NAME); - continue; - } - decl_in_table = find_decl (DECL_RESERV (decl)->name); - } - if (decl_in_table == NULL) - decl_in_table = insert_decl (decl); - else - { - if (decl->mode == dm_unit) - error ("repeated declaration of unit `%s'", - DECL_UNIT (decl)->name); - else - error ("repeated declaration of reservation `%s'", - DECL_RESERV (decl)->name); - } - } - } - /* Check bypasses and form list of bypasses for each (output) - insn. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_bypass) - process_bypass (decl); - } - - /* Check exclusion set declarations and form exclusion sets. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_excl) - { - unit_set_el_t unit_set_el_list; - unit_set_el_t unit_set_el_list_2; - - unit_set_el_list - = process_excls (DECL_EXCL (decl)->names, - DECL_EXCL (decl)->first_list_length, decl->pos); - unit_set_el_list_2 - = process_excls (&DECL_EXCL (decl)->names - [DECL_EXCL (decl)->first_list_length], - DECL_EXCL (decl)->all_names_num - - DECL_EXCL (decl)->first_list_length, - decl->pos); - add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos); - add_excls (unit_set_el_list_2, unit_set_el_list, decl->pos); - } - } - - /* Check presence set declarations and form presence sets. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_presence) - { - unit_set_el_t unit_set_el_list; - pattern_set_el_t pattern_set_el_list; - - unit_set_el_list - = process_presence_absence_names - (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num, - decl->pos, TRUE, DECL_PRESENCE (decl)->final_p); - pattern_set_el_list - = process_presence_absence_patterns - (DECL_PRESENCE (decl)->patterns, - DECL_PRESENCE (decl)->patterns_num, - decl->pos, TRUE, DECL_PRESENCE (decl)->final_p); - add_presence_absence (unit_set_el_list, pattern_set_el_list, - decl->pos, TRUE, - DECL_PRESENCE (decl)->final_p); - } - } - - /* Check absence set declarations and form absence sets. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_absence) - { - unit_set_el_t unit_set_el_list; - pattern_set_el_t pattern_set_el_list; - - unit_set_el_list - = process_presence_absence_names - (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num, - decl->pos, FALSE, DECL_ABSENCE (decl)->final_p); - pattern_set_el_list - = process_presence_absence_patterns - (DECL_ABSENCE (decl)->patterns, - DECL_ABSENCE (decl)->patterns_num, - decl->pos, FALSE, DECL_ABSENCE (decl)->final_p); - add_presence_absence (unit_set_el_list, pattern_set_el_list, - decl->pos, FALSE, - DECL_ABSENCE (decl)->final_p); - } - } -} - -/* The following function checks that declared automaton is used. If - the automaton is not used, the function fixes error/warning. The - following function must be called only after `process_decls'. */ -static void -check_automaton_usage (void) -{ - decl_t decl; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_automaton - && !DECL_AUTOMATON (decl)->automaton_is_used) - { - if (!w_flag) - error ("automaton `%s' is not used", DECL_AUTOMATON (decl)->name); - else - warning ("automaton `%s' is not used", - DECL_AUTOMATON (decl)->name); - } - } -} - -/* The following recursive function processes all regexp in order to - fix usage of units or reservations and to fix errors of undeclared - name. The function may change unit_regexp onto reserv_regexp. - Remember that reserv_regexp does not exist before the function - call. */ -static regexp_t -process_regexp (regexp_t regexp) -{ - decl_t decl_in_table; - regexp_t new_regexp; - int i; - - switch (regexp->mode) - { - case rm_unit: - decl_in_table = find_decl (REGEXP_UNIT (regexp)->name); - if (decl_in_table == NULL) - error ("undeclared unit or reservation `%s'", - REGEXP_UNIT (regexp)->name); - else - switch (decl_in_table->mode) - { - case dm_unit: - DECL_UNIT (decl_in_table)->unit_is_used = 1; - REGEXP_UNIT (regexp)->unit_decl = DECL_UNIT (decl_in_table); - break; - - case dm_reserv: - DECL_RESERV (decl_in_table)->reserv_is_used = 1; - new_regexp = XCREATENODE (struct regexp); - new_regexp->mode = rm_reserv; - new_regexp->pos = regexp->pos; - REGEXP_RESERV (new_regexp)->name = REGEXP_UNIT (regexp)->name; - REGEXP_RESERV (new_regexp)->reserv_decl - = DECL_RESERV (decl_in_table); - regexp = new_regexp; - break; - - default: - gcc_unreachable (); - } - break; - case rm_sequence: - for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++) - REGEXP_SEQUENCE (regexp)->regexps [i] - = process_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]); - break; - case rm_allof: - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - REGEXP_ALLOF (regexp)->regexps [i] - = process_regexp (REGEXP_ALLOF (regexp)->regexps [i]); - break; - case rm_oneof: - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - REGEXP_ONEOF (regexp)->regexps [i] - = process_regexp (REGEXP_ONEOF (regexp)->regexps [i]); - break; - case rm_repeat: - REGEXP_REPEAT (regexp)->regexp - = process_regexp (REGEXP_REPEAT (regexp)->regexp); - break; - case rm_nothing: - break; - default: - gcc_unreachable (); - } - return regexp; -} - -/* The following function processes regexp of define_reservation and - define_insn_reservation with the aid of function - `process_regexp'. */ -static void -process_regexp_decls (void) -{ - decl_t decl; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_reserv) - DECL_RESERV (decl)->regexp - = process_regexp (DECL_RESERV (decl)->regexp); - else if (decl->mode == dm_insn_reserv) - DECL_INSN_RESERV (decl)->regexp - = process_regexp (DECL_INSN_RESERV (decl)->regexp); - } -} - -/* The following function checks that declared unit is used. If the - unit is not used, the function fixes errors/warnings. The - following function must be called only after `process_decls', - `process_regexp_decls'. */ -static void -check_usage (void) -{ - decl_t decl; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit && !DECL_UNIT (decl)->unit_is_used) - { - if (!w_flag) - error ("unit `%s' is not used", DECL_UNIT (decl)->name); - else - warning ("unit `%s' is not used", DECL_UNIT (decl)->name); - } - else if (decl->mode == dm_reserv && !DECL_RESERV (decl)->reserv_is_used) - { - if (!w_flag) - error ("reservation `%s' is not used", DECL_RESERV (decl)->name); - else - warning ("reservation `%s' is not used", DECL_RESERV (decl)->name); - } - } -} - -/* The following variable value is number of reservation being - processed on loop recognition. */ -static int curr_loop_pass_num; - -/* The following recursive function returns nonzero value if REGEXP - contains given decl or reservations in given regexp refers for - given decl. */ -static int -loop_in_regexp (regexp_t regexp, decl_t start_decl) -{ - int i; - - if (regexp == NULL) - return 0; - switch (regexp->mode) - { - case rm_unit: - return 0; - - case rm_reserv: - if (start_decl->mode == dm_reserv - && REGEXP_RESERV (regexp)->reserv_decl == DECL_RESERV (start_decl)) - return 1; - else if (REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num - == curr_loop_pass_num) - /* declaration has been processed. */ - return 0; - else - { - REGEXP_RESERV (regexp)->reserv_decl->loop_pass_num - = curr_loop_pass_num; - return loop_in_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp, - start_decl); - } - - case rm_sequence: - for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++) - if (loop_in_regexp (REGEXP_SEQUENCE (regexp)->regexps [i], start_decl)) - return 1; - return 0; - - case rm_allof: - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - if (loop_in_regexp (REGEXP_ALLOF (regexp)->regexps [i], start_decl)) - return 1; - return 0; - - case rm_oneof: - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - if (loop_in_regexp (REGEXP_ONEOF (regexp)->regexps [i], start_decl)) - return 1; - return 0; - - case rm_repeat: - return loop_in_regexp (REGEXP_REPEAT (regexp)->regexp, start_decl); - - case rm_nothing: - return 0; - - default: - gcc_unreachable (); - } -} - -/* The following function fixes errors "cycle in definition ...". The - function uses function `loop_in_regexp' for that. */ -static void -check_loops_in_regexps (void) -{ - decl_t decl; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_reserv) - DECL_RESERV (decl)->loop_pass_num = 0; - } - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - curr_loop_pass_num = i; - - if (decl->mode == dm_reserv) - { - DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num; - if (loop_in_regexp (DECL_RESERV (decl)->regexp, decl)) - { - gcc_assert (DECL_RESERV (decl)->regexp); - error ("cycle in definition of reservation `%s'", - DECL_RESERV (decl)->name); - } - } - } -} - -/* The function recursively processes IR of reservation and defines - max and min cycle for reservation of unit. */ -static void -process_regexp_cycles (regexp_t regexp, int max_start_cycle, - int min_start_cycle, int *max_finish_cycle, - int *min_finish_cycle) -{ - int i; - - switch (regexp->mode) - { - case rm_unit: - if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle) - REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle; - if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle - || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1) - REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle; - *max_finish_cycle = max_start_cycle; - *min_finish_cycle = min_start_cycle; - break; - - case rm_reserv: - process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp, - max_start_cycle, min_start_cycle, - max_finish_cycle, min_finish_cycle); - break; - - case rm_repeat: - for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++) - { - process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp, - max_start_cycle, min_start_cycle, - max_finish_cycle, min_finish_cycle); - max_start_cycle = *max_finish_cycle + 1; - min_start_cycle = *min_finish_cycle + 1; - } - break; - - case rm_sequence: - for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++) - { - process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i], - max_start_cycle, min_start_cycle, - max_finish_cycle, min_finish_cycle); - max_start_cycle = *max_finish_cycle + 1; - min_start_cycle = *min_finish_cycle + 1; - } - break; - - case rm_allof: - { - int max_cycle = 0; - int min_cycle = 0; - - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - { - process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i], - max_start_cycle, min_start_cycle, - max_finish_cycle, min_finish_cycle); - if (max_cycle < *max_finish_cycle) - max_cycle = *max_finish_cycle; - if (i == 0 || min_cycle > *min_finish_cycle) - min_cycle = *min_finish_cycle; - } - *max_finish_cycle = max_cycle; - *min_finish_cycle = min_cycle; - } - break; - - case rm_oneof: - { - int max_cycle = 0; - int min_cycle = 0; - - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - { - process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i], - max_start_cycle, min_start_cycle, - max_finish_cycle, min_finish_cycle); - if (max_cycle < *max_finish_cycle) - max_cycle = *max_finish_cycle; - if (i == 0 || min_cycle > *min_finish_cycle) - min_cycle = *min_finish_cycle; - } - *max_finish_cycle = max_cycle; - *min_finish_cycle = min_cycle; - } - break; - - case rm_nothing: - *max_finish_cycle = max_start_cycle; - *min_finish_cycle = min_start_cycle; - break; - - default: - gcc_unreachable (); - } -} - -/* The following function is called only for correct program. The - function defines max reservation of insns in cycles. */ -static void -evaluate_max_reserv_cycles (void) -{ - int max_insn_cycles_num; - int min_insn_cycles_num; - decl_t decl; - int i; - - description->max_insn_reserv_cycles = 0; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - { - process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0, - &max_insn_cycles_num, &min_insn_cycles_num); - if (description->max_insn_reserv_cycles < max_insn_cycles_num) - description->max_insn_reserv_cycles = max_insn_cycles_num; - } - } - description->max_insn_reserv_cycles++; -} - -/* The following function calls functions for checking all - description. */ -static void -check_all_description (void) -{ - process_decls (); - check_automaton_usage (); - process_regexp_decls (); - check_usage (); - check_loops_in_regexps (); - if (!have_error) - evaluate_max_reserv_cycles (); -} - - - -/* The page contains abstract data `ticker'. This data is used to - report time of different phases of building automata. It is - possibly to write a description for which automata will be built - during several minutes even on fast machine. */ - -/* The following function creates ticker and makes it active. */ -static ticker_t -create_ticker (void) -{ - ticker_t ticker; - - ticker.modified_creation_time = get_run_time (); - ticker.incremented_off_time = 0; - return ticker; -} - -/* The following function switches off given ticker. */ -static void -ticker_off (ticker_t *ticker) -{ - if (ticker->incremented_off_time == 0) - ticker->incremented_off_time = get_run_time () + 1; -} - -/* The following function switches on given ticker. */ -static void -ticker_on (ticker_t *ticker) -{ - if (ticker->incremented_off_time != 0) - { - ticker->modified_creation_time - += get_run_time () - ticker->incremented_off_time + 1; - ticker->incremented_off_time = 0; - } -} - -/* The following function returns current time in milliseconds since - the moment when given ticker was created. */ -static int -active_time (ticker_t ticker) -{ - if (ticker.incremented_off_time != 0) - return ticker.incremented_off_time - 1 - ticker.modified_creation_time; - else - return get_run_time () - ticker.modified_creation_time; -} - -/* The following function returns string representation of active time - of given ticker. The result is string representation of seconds - with accuracy of 1/100 second. Only result of the last call of the - function exists. Therefore the following code is not correct - - printf ("parser time: %s\ngeneration time: %s\n", - active_time_string (parser_ticker), - active_time_string (generation_ticker)); - - Correct code has to be the following - - printf ("parser time: %s\n", active_time_string (parser_ticker)); - printf ("generation time: %s\n", - active_time_string (generation_ticker)); - -*/ -static void -print_active_time (FILE *f, ticker_t ticker) -{ - int msecs; - - msecs = active_time (ticker); - fprintf (f, "%d.%06d", msecs / 1000000, msecs % 1000000); -} - - - -/* The following variable value is number of automaton which are - really being created. This value is defined on the base of - argument of option `-split'. If the variable has zero value the - number of automata is defined by the constructions `%automaton'. - This case occurs when option `-split' is absent or has zero - argument. If constructions `define_automaton' is absent only one - automaton is created. */ -static int automata_num; - -/* The following variable values are times of - o transformation of regular expressions - o building NDFA (DFA if !ndfa_flag) - o NDFA -> DFA (simply the same automaton if !ndfa_flag) - o DFA minimization - o building insn equivalence classes - o all previous ones - o code output */ -static ticker_t transform_time; -static ticker_t NDFA_time; -static ticker_t NDFA_to_DFA_time; -static ticker_t minimize_time; -static ticker_t equiv_time; -static ticker_t automaton_generation_time; -static ticker_t output_time; - -/* The following variable values are times of - all checking - all generation - all pipeline hazard translator work */ -static ticker_t check_time; -static ticker_t generation_time; -static ticker_t all_time; - - - -/* Pseudo insn decl which denotes advancing cycle. */ -static decl_t advance_cycle_insn_decl; -/* Pseudo insn decl which denotes collapsing the NDFA state. */ -static decl_t collapse_ndfa_insn_decl; - -/* Create and record a decl for the special advance-cycle transition. */ -static void -add_advance_cycle_insn_decl (void) -{ - advance_cycle_insn_decl = XCREATENODE (struct decl); - advance_cycle_insn_decl->mode = dm_insn_reserv; - advance_cycle_insn_decl->pos = no_pos; - DECL_INSN_RESERV (advance_cycle_insn_decl)->regexp = NULL; - DECL_INSN_RESERV (advance_cycle_insn_decl)->name = "$advance_cycle"; - DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num - = description->insns_num; - description->decls [description->decls_num] = advance_cycle_insn_decl; - description->decls_num++; - description->insns_num++; -} - -/* Create and record a decl for the special collapse-NDFA transition. */ -static void -add_collapse_ndfa_insn_decl (void) -{ - collapse_ndfa_insn_decl = XCREATENODE (struct decl); - collapse_ndfa_insn_decl->mode = dm_insn_reserv; - collapse_ndfa_insn_decl->pos = no_pos; - DECL_INSN_RESERV (collapse_ndfa_insn_decl)->regexp = NULL; - DECL_INSN_RESERV (collapse_ndfa_insn_decl)->name = "$collapse_ndfa"; - DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num - = description->insns_num; - description->decls [description->decls_num] = collapse_ndfa_insn_decl; - description->decls_num++; - description->insns_num++; -} - -/* True if DECL is either of the two special decls we created. */ -static bool -special_decl_p (struct insn_reserv_decl *decl) -{ - return (decl == DECL_INSN_RESERV (advance_cycle_insn_decl) - || (collapse_flag - && decl == DECL_INSN_RESERV (collapse_ndfa_insn_decl))); -} - - -/* Abstract data `alternative states' which represents - nondeterministic nature of the description (see comments for - structures alt_state and state). */ - -/* List of free states. */ -static alt_state_t first_free_alt_state; - -#ifndef NDEBUG -/* The following variables is maximal number of allocated nodes - alt_state. */ -static int allocated_alt_states_num = 0; -#endif - -/* The following function returns free node alt_state. It may be new - allocated node or node freed earlier. */ -static alt_state_t -get_free_alt_state (void) -{ - alt_state_t result; - - if (first_free_alt_state != NULL) - { - result = first_free_alt_state; - first_free_alt_state = first_free_alt_state->next_alt_state; - } - else - { -#ifndef NDEBUG - allocated_alt_states_num++; -#endif - result = XCREATENODE (struct alt_state); - } - result->state = NULL; - result->next_alt_state = NULL; - result->next_sorted_alt_state = NULL; - return result; -} - -/* The function frees node ALT_STATE. */ -static void -free_alt_state (alt_state_t alt_state) -{ - if (alt_state == NULL) - return; - alt_state->next_alt_state = first_free_alt_state; - first_free_alt_state = alt_state; -} - -/* The function frees list started with node ALT_STATE_LIST. */ -static void -free_alt_states (alt_state_t alt_states_list) -{ - alt_state_t curr_alt_state; - alt_state_t next_alt_state; - - for (curr_alt_state = alt_states_list; - curr_alt_state != NULL; - curr_alt_state = next_alt_state) - { - next_alt_state = curr_alt_state->next_alt_state; - free_alt_state (curr_alt_state); - } -} - -/* The function compares unique numbers of alt states. */ -static int -alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2) -{ - if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num - == (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num) - return 0; - else if ((*(const alt_state_t *) alt_state_ptr_1)->state->unique_num - < (*(const alt_state_t *) alt_state_ptr_2)->state->unique_num) - return -1; - else - return 1; -} - -/* The function sorts ALT_STATES_LIST and removes duplicated alt - states from the list. The comparison key is alt state unique - number. */ - -static alt_state_t -uniq_sort_alt_states (alt_state_t alt_states_list) -{ - alt_state_t curr_alt_state; - size_t i; - size_t prev_unique_state_ind; - alt_state_t result; - - if (alt_states_list == 0) - return 0; - if (alt_states_list->next_alt_state == 0) - return alt_states_list; - - auto_vec<alt_state_t, 150> alt_states; - for (curr_alt_state = alt_states_list; - curr_alt_state != NULL; - curr_alt_state = curr_alt_state->next_alt_state) - alt_states.safe_push (curr_alt_state); - - alt_states.qsort (alt_state_cmp); - - prev_unique_state_ind = 0; - for (i = 1; i < alt_states.length (); i++) - if (alt_states[prev_unique_state_ind]->state != alt_states[i]->state) - { - prev_unique_state_ind++; - alt_states[prev_unique_state_ind] = alt_states[i]; - } - alt_states.truncate (prev_unique_state_ind + 1); - - for (i = 1; i < alt_states.length (); i++) - alt_states[i-1]->next_sorted_alt_state - = alt_states[i]; - alt_states.last ()->next_sorted_alt_state = 0; - - result = alt_states[0]; - - return result; -} - -/* The function checks equality of alt state lists. Remember that the - lists must be already sorted by the previous function. */ -static int -alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2) -{ - while (alt_states_1 != NULL && alt_states_2 != NULL - && alt_state_cmp (&alt_states_1, &alt_states_2) == 0) - { - alt_states_1 = alt_states_1->next_sorted_alt_state; - alt_states_2 = alt_states_2->next_sorted_alt_state; - } - return alt_states_1 == alt_states_2; -} - -/* Initialization of the abstract data. */ -static void -initiate_alt_states (void) -{ - first_free_alt_state = NULL; -} - -/* Finishing work with the abstract data. */ -static void -finish_alt_states (void) -{ -} - - - -/* The page contains macros for work with bits strings. We could use - standard gcc bitmap or sbitmap but it would result in difficulties - of building canadian cross. */ - -/* Set bit number bitno in the bit string. The macro is not side - effect proof. */ -#define bitmap_set_bit(bitstring, bitno) \ - ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] |= \ - (HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT)) - -#define CLEAR_BIT(bitstring, bitno) \ - ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] &= \ - ~((HOST_WIDE_INT)1 << (bitno) % (sizeof (*(bitstring)) * CHAR_BIT))) - -/* Test if bit number bitno in the bitstring is set. The macro is not - side effect proof. */ -#define bitmap_bit_p(bitstring, bitno) \ - ((bitstring)[(bitno) / (sizeof (*(bitstring)) * CHAR_BIT)] >> \ - (bitno) % (sizeof (*(bitstring)) * CHAR_BIT) & 1) - - - -/* This page contains abstract data `state'. */ - -/* Maximal length of reservations in cycles (>= 1). */ -static int max_cycles_num; - -/* Number of set elements (see type set_el_t) needed for - representation of one cycle reservation. It is depended on units - number. */ -static int els_in_cycle_reserv; - -/* Number of set elements (see type set_el_t) needed for - representation of maximal length reservation. Deterministic - reservation is stored as set (bit string) of length equal to the - variable value * number of bits in set_el_t. */ -static int els_in_reservs; - -/* Array of pointers to unit declarations. */ -static unit_decl_t *units_array; - -/* Temporary reservation of maximal length. */ -static reserv_sets_t temp_reserv; - -/* The state table itself is represented by the following variable. */ -static htab_t state_table; - -/* Linked list of free 'state' structures to be recycled. The - next_equiv_class_state pointer is borrowed for a free list. */ -static state_t first_free_state; - -static int curr_unique_state_num; - -#ifndef NDEBUG -/* The following variables is maximal number of allocated nodes - `state'. */ -static int allocated_states_num = 0; -#endif - -/* Allocate new reservation set. */ -static reserv_sets_t -alloc_empty_reserv_sets (void) -{ - reserv_sets_t result; - - obstack_blank (&irp, els_in_reservs * sizeof (set_el_t)); - result = (reserv_sets_t) obstack_base (&irp); - obstack_finish (&irp); - memset (result, 0, els_in_reservs * sizeof (set_el_t)); - return result; -} - -/* Hash value of reservation set. */ -static unsigned -reserv_sets_hash_value (reserv_sets_t reservs) -{ - set_el_t hash_value; - unsigned result; - int reservs_num, i; - set_el_t *reserv_ptr; - - hash_value = 0; - reservs_num = els_in_reservs; - reserv_ptr = reservs; - i = 0; - while (reservs_num != 0) - { - reservs_num--; - hash_value += ((*reserv_ptr >> i) - | (*reserv_ptr << (((sizeof (set_el_t) * CHAR_BIT) - 1) & -i))); - i++; - if (i == sizeof (set_el_t) * CHAR_BIT) - i = 0; - reserv_ptr++; - } - if (sizeof (set_el_t) <= sizeof (unsigned)) - return hash_value; - result = 0; - for (i = sizeof (set_el_t); i > 0; i -= sizeof (unsigned) - 1) - { - result += (unsigned) hash_value; - hash_value >>= (sizeof (unsigned) - 1) * CHAR_BIT; - } - return result; -} - -/* Comparison of given reservation sets. */ -static int -reserv_sets_cmp (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2) -{ - int reservs_num; - const set_el_t *reserv_ptr_1; - const set_el_t *reserv_ptr_2; - - gcc_assert (reservs_1 && reservs_2); - reservs_num = els_in_reservs; - reserv_ptr_1 = reservs_1; - reserv_ptr_2 = reservs_2; - while (reservs_num != 0 && *reserv_ptr_1 == *reserv_ptr_2) - { - reservs_num--; - reserv_ptr_1++; - reserv_ptr_2++; - } - if (reservs_num == 0) - return 0; - else if (*reserv_ptr_1 < *reserv_ptr_2) - return -1; - else - return 1; -} - -/* The function checks equality of the reservation sets. */ -static int -reserv_sets_eq (const_reserv_sets_t reservs_1, const_reserv_sets_t reservs_2) -{ - return reserv_sets_cmp (reservs_1, reservs_2) == 0; -} - -/* Set up in the reservation set that unit with UNIT_NUM is used on - CYCLE_NUM. */ -static void -set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num) -{ - gcc_assert (cycle_num < max_cycles_num); - bitmap_set_bit (reservs, cycle_num * els_in_cycle_reserv - * sizeof (set_el_t) * CHAR_BIT + unit_num); -} - -/* Set up in the reservation set RESERVS that unit with UNIT_NUM is - used on CYCLE_NUM. */ -static int -test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num) -{ - gcc_assert (cycle_num < max_cycles_num); - return bitmap_bit_p (reservs, cycle_num * els_in_cycle_reserv - * sizeof (set_el_t) * CHAR_BIT + unit_num); -} - -/* The function checks that the reservation sets are intersected, - i.e. there is a unit reservation on a cycle in both reservation - sets. */ -static int -reserv_sets_are_intersected (reserv_sets_t operand_1, - reserv_sets_t operand_2) -{ - set_el_t *el_ptr_1; - set_el_t *el_ptr_2; - set_el_t *cycle_ptr_1; - set_el_t *cycle_ptr_2; - - gcc_assert (operand_1 && operand_2); - for (el_ptr_1 = operand_1, el_ptr_2 = operand_2; - el_ptr_1 < operand_1 + els_in_reservs; - el_ptr_1++, el_ptr_2++) - if (*el_ptr_1 & *el_ptr_2) - return 1; - reserv_sets_or (temp_reserv, operand_1, operand_2); - for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2; - cycle_ptr_1 < operand_1 + els_in_reservs; - cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv) - { - for (el_ptr_1 = cycle_ptr_1, el_ptr_2 = get_excl_set (cycle_ptr_2); - el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv; - el_ptr_1++, el_ptr_2++) - if (*el_ptr_1 & *el_ptr_2) - return 1; - if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE)) - return 1; - if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2 - - operand_2), - cycle_ptr_2, TRUE)) - return 1; - if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE)) - return 1; - if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2), - cycle_ptr_2, TRUE)) - return 1; - } - return 0; -} - -/* The function sets up RESULT bits by bits of OPERAND shifted on one - cpu cycle. The remaining bits of OPERAND (representing the last - cycle unit reservations) are not changed. */ -static void -reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand) -{ - int i; - - gcc_assert (result && operand && result != operand); - for (i = els_in_cycle_reserv; i < els_in_reservs; i++) - result [i - els_in_cycle_reserv] = operand [i]; -} - -/* OR of the reservation sets. */ -static void -reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1, - reserv_sets_t operand_2) -{ - set_el_t *el_ptr_1; - set_el_t *el_ptr_2; - set_el_t *result_set_el_ptr; - - gcc_assert (result && operand_1 && operand_2); - for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result; - el_ptr_1 < operand_1 + els_in_reservs; - el_ptr_1++, el_ptr_2++, result_set_el_ptr++) - *result_set_el_ptr = *el_ptr_1 | *el_ptr_2; -} - -/* AND of the reservation sets. */ -static void -reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1, - reserv_sets_t operand_2) -{ - set_el_t *el_ptr_1; - set_el_t *el_ptr_2; - set_el_t *result_set_el_ptr; - - gcc_assert (result && operand_1 && operand_2); - for (el_ptr_1 = operand_1, el_ptr_2 = operand_2, result_set_el_ptr = result; - el_ptr_1 < operand_1 + els_in_reservs; - el_ptr_1++, el_ptr_2++, result_set_el_ptr++) - *result_set_el_ptr = *el_ptr_1 & *el_ptr_2; -} - -/* The function outputs string representation of units reservation on - cycle START_CYCLE in the reservation set. The function uses repeat - construction if REPETITION_NUM > 1. */ -static void -output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle, - int repetition_num) -{ - int unit_num; - int reserved_units_num; - - reserved_units_num = 0; - for (unit_num = 0; unit_num < description->units_num; unit_num++) - if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv - * sizeof (set_el_t) * CHAR_BIT + unit_num)) - reserved_units_num++; - gcc_assert (repetition_num > 0); - if (repetition_num != 1 && reserved_units_num > 1) - fprintf (f, "("); - reserved_units_num = 0; - for (unit_num = 0; - unit_num < description->units_num; - unit_num++) - if (bitmap_bit_p (reservs, start_cycle * els_in_cycle_reserv - * sizeof (set_el_t) * CHAR_BIT + unit_num)) - { - if (reserved_units_num != 0) - fprintf (f, "+"); - reserved_units_num++; - fprintf (f, "%s", units_array [unit_num]->name); - } - if (reserved_units_num == 0) - fprintf (f, NOTHING_NAME); - gcc_assert (repetition_num > 0); - if (repetition_num != 1 && reserved_units_num > 1) - fprintf (f, ")"); - if (repetition_num != 1) - fprintf (f, "*%d", repetition_num); -} - -/* The function outputs string representation of units reservation in - the reservation set. */ -static void -output_reserv_sets (FILE *f, reserv_sets_t reservs) -{ - int start_cycle = 0; - int cycle; - int repetition_num; - - repetition_num = 0; - for (cycle = 0; cycle < max_cycles_num; cycle++) - if (repetition_num == 0) - { - repetition_num++; - start_cycle = cycle; - } - else if (memcmp - ((char *) reservs + start_cycle * els_in_cycle_reserv - * sizeof (set_el_t), - (char *) reservs + cycle * els_in_cycle_reserv - * sizeof (set_el_t), - els_in_cycle_reserv * sizeof (set_el_t)) == 0) - repetition_num++; - else - { - if (start_cycle != 0) - fprintf (f, ", "); - output_cycle_reservs (f, reservs, start_cycle, repetition_num); - repetition_num = 1; - start_cycle = cycle; - } - if (start_cycle < max_cycles_num) - { - if (start_cycle != 0) - fprintf (f, ", "); - output_cycle_reservs (f, reservs, start_cycle, repetition_num); - } -} - -/* The following function returns free node state for AUTOMATON. It - may be new allocated node or node freed earlier. The function also - allocates reservation set if WITH_RESERVS has nonzero value. */ -static state_t -get_free_state (int with_reservs, automaton_t automaton) -{ - state_t result; - - gcc_assert (max_cycles_num > 0 && automaton); - if (first_free_state) - { - result = first_free_state; - first_free_state = result->next_equiv_class_state; - - result->next_equiv_class_state = NULL; - result->automaton = automaton; - result->first_out_arc = NULL; - result->it_was_placed_in_stack_for_NDFA_forming = 0; - result->it_was_placed_in_stack_for_DFA_forming = 0; - result->component_states = NULL; - } - else - { -#ifndef NDEBUG - allocated_states_num++; -#endif - result = XCREATENODE (struct state); - result->automaton = automaton; - result->first_out_arc = NULL; - result->unique_num = curr_unique_state_num; - curr_unique_state_num++; - } - if (with_reservs) - { - if (result->reservs == NULL) - result->reservs = alloc_empty_reserv_sets (); - else - memset (result->reservs, 0, els_in_reservs * sizeof (set_el_t)); - } - return result; -} - -/* The function frees node STATE. */ -static void -free_state (state_t state) -{ - free_alt_states (state->component_states); - state->next_equiv_class_state = first_free_state; - first_free_state = state; -} - -/* Hash value of STATE. If STATE represents deterministic state it is - simply hash value of the corresponding reservation set. Otherwise - it is formed from hash values of the component deterministic - states. One more key is order number of state automaton. */ -static hashval_t -state_hash (const void *state) -{ - unsigned int hash_value; - alt_state_t alt_state; - - if (((const_state_t) state)->component_states == NULL) - hash_value = reserv_sets_hash_value (((const_state_t) state)->reservs); - else - { - hash_value = 0; - for (alt_state = ((const_state_t) state)->component_states; - alt_state != NULL; - alt_state = alt_state->next_sorted_alt_state) - hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT) - | (hash_value << CHAR_BIT)) - + alt_state->state->unique_num); - } - hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT) - | (hash_value << CHAR_BIT)) - + ((const_state_t) state)->automaton->automaton_order_num); - return hash_value; -} - -/* Return nonzero value if the states are the same. */ -static int -state_eq_p (const void *state_1, const void *state_2) -{ - alt_state_t alt_state_1; - alt_state_t alt_state_2; - - if (((const_state_t) state_1)->automaton != ((const_state_t) state_2)->automaton) - return 0; - else if (((const_state_t) state_1)->component_states == NULL - && ((const_state_t) state_2)->component_states == NULL) - return reserv_sets_eq (((const_state_t) state_1)->reservs, - ((const_state_t) state_2)->reservs); - else if (((const_state_t) state_1)->component_states != NULL - && ((const_state_t) state_2)->component_states != NULL) - { - for (alt_state_1 = ((const_state_t) state_1)->component_states, - alt_state_2 = ((const_state_t) state_2)->component_states; - alt_state_1 != NULL && alt_state_2 != NULL; - alt_state_1 = alt_state_1->next_sorted_alt_state, - alt_state_2 = alt_state_2->next_sorted_alt_state) - /* All state in the list must be already in the hash table. - Also the lists must be sorted. */ - if (alt_state_1->state != alt_state_2->state) - return 0; - return alt_state_1 == alt_state_2; - } - else - return 0; -} - -/* Insert STATE into the state table. */ -static state_t -insert_state (state_t state) -{ - void **entry_ptr; - - entry_ptr = htab_find_slot (state_table, (void *) state, INSERT); - if (*entry_ptr == NULL) - *entry_ptr = (void *) state; - return (state_t) *entry_ptr; -} - -/* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to - deterministic STATE. */ -static void -set_state_reserv (state_t state, int cycle_num, int unit_num) -{ - set_unit_reserv (state->reservs, cycle_num, unit_num); -} - -/* Return nonzero value if the deterministic states contains a - reservation of the same cpu unit on the same cpu cycle. */ -static int -intersected_state_reservs_p (state_t state1, state_t state2) -{ - gcc_assert (state1->automaton == state2->automaton); - return reserv_sets_are_intersected (state1->reservs, state2->reservs); -} - -/* Return deterministic state (inserted into the table) which - representing the automaton state which is union of reservations of - the deterministic states masked by RESERVS. */ -static state_t -states_union (state_t state1, state_t state2, reserv_sets_t reservs) -{ - state_t result; - state_t state_in_table; - - gcc_assert (state1->automaton == state2->automaton); - result = get_free_state (1, state1->automaton); - reserv_sets_or (result->reservs, state1->reservs, state2->reservs); - reserv_sets_and (result->reservs, result->reservs, reservs); - state_in_table = insert_state (result); - if (result != state_in_table) - { - free_state (result); - result = state_in_table; - } - return result; -} - -/* Return deterministic state (inserted into the table) which - represent the automaton state is obtained from deterministic STATE - by advancing cpu cycle and masking by RESERVS. */ -static state_t -state_shift (state_t state, reserv_sets_t reservs) -{ - state_t result; - state_t state_in_table; - - result = get_free_state (1, state->automaton); - reserv_sets_shift (result->reservs, state->reservs); - reserv_sets_and (result->reservs, result->reservs, reservs); - state_in_table = insert_state (result); - if (result != state_in_table) - { - free_state (result); - result = state_in_table; - } - return result; -} - -/* Initialization of the abstract data. */ -static void -initiate_states (void) -{ - decl_t decl; - int i; - - if (description->units_num) - units_array = XNEWVEC (unit_decl_t, description->units_num); - else - units_array = 0; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit) - units_array [DECL_UNIT (decl)->unit_num] = DECL_UNIT (decl); - } - max_cycles_num = description->max_insn_reserv_cycles; - els_in_cycle_reserv - = ((description->units_num + sizeof (set_el_t) * CHAR_BIT - 1) - / (sizeof (set_el_t) * CHAR_BIT)); - els_in_reservs = els_in_cycle_reserv * max_cycles_num; - curr_unique_state_num = 0; - initiate_alt_states (); - state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0); - temp_reserv = alloc_empty_reserv_sets (); -} - -/* Finishing work with the abstract data. */ -static void -finish_states (void) -{ - free (units_array); - units_array = 0; - htab_delete (state_table); - first_free_state = NULL; - finish_alt_states (); -} - - - -/* Abstract data `arcs'. */ - -/* List of free arcs. */ -static arc_t first_free_arc; - -#ifndef NDEBUG -/* The following variables is maximal number of allocated nodes - `arc'. */ -static int allocated_arcs_num = 0; -#endif - -/* The function frees node ARC. */ -static void -free_arc (arc_t arc) -{ - arc->next_out_arc = first_free_arc; - first_free_arc = arc; -} - -/* The function removes and frees ARC staring from FROM_STATE. */ -static void -remove_arc (state_t from_state, arc_t arc) -{ - arc_t prev_arc; - arc_t curr_arc; - - gcc_assert (arc); - for (prev_arc = NULL, curr_arc = from_state->first_out_arc; - curr_arc != NULL; - prev_arc = curr_arc, curr_arc = curr_arc->next_out_arc) - if (curr_arc == arc) - break; - gcc_assert (curr_arc); - if (prev_arc == NULL) - from_state->first_out_arc = arc->next_out_arc; - else - prev_arc->next_out_arc = arc->next_out_arc; - from_state->num_out_arcs--; - free_arc (arc); -} - -/* The functions returns arc with given characteristics (or NULL if - the arc does not exist). */ -static arc_t -find_arc (state_t from_state, state_t to_state, ainsn_t insn) -{ - arc_t arc; - - for (arc = first_out_arc (from_state); arc != NULL; arc = next_out_arc (arc)) - if (arc->insn == insn - && (arc->to_state == to_state - || (collapse_flag - /* Any arc is good enough for a collapse-ndfa transition. */ - && (insn->insn_reserv_decl - == DECL_INSN_RESERV (collapse_ndfa_insn_decl))))) - return arc; - return NULL; -} - -/* The function adds arc from FROM_STATE to TO_STATE marked by AINSN, - unless such an arc already exists. */ -static void -add_arc (state_t from_state, state_t to_state, ainsn_t ainsn) -{ - arc_t new_arc; - - new_arc = find_arc (from_state, to_state, ainsn); - if (new_arc != NULL) - return; - if (first_free_arc == NULL) - { -#ifndef NDEBUG - allocated_arcs_num++; -#endif - new_arc = XCREATENODE (struct arc); - new_arc->to_state = NULL; - new_arc->insn = NULL; - new_arc->next_out_arc = NULL; - } - else - { - new_arc = first_free_arc; - first_free_arc = first_free_arc->next_out_arc; - } - new_arc->to_state = to_state; - new_arc->insn = ainsn; - ainsn->arc_exists_p = 1; - new_arc->next_out_arc = from_state->first_out_arc; - from_state->first_out_arc = new_arc; - from_state->num_out_arcs++; - new_arc->next_arc_marked_by_insn = NULL; -} - -/* The function returns the first arc starting from STATE. */ -static arc_t -first_out_arc (const_state_t state) -{ - return state->first_out_arc; -} - -/* The function returns next out arc after ARC. */ -static arc_t -next_out_arc (arc_t arc) -{ - return arc->next_out_arc; -} - -/* Initialization of the abstract data. */ -static void -initiate_arcs (void) -{ - first_free_arc = NULL; -} - -/* Finishing work with the abstract data. */ -static void -finish_arcs (void) -{ -} - - - -/* Abstract data `automata lists'. */ - -/* List of free states. */ -static automata_list_el_t first_free_automata_list_el; - -/* The list being formed. */ -static automata_list_el_t current_automata_list; - -/* Hash table of automata lists. */ -static htab_t automata_list_table; - -/* The following function returns free automata list el. It may be - new allocated node or node freed earlier. */ -static automata_list_el_t -get_free_automata_list_el (void) -{ - automata_list_el_t result; - - if (first_free_automata_list_el != NULL) - { - result = first_free_automata_list_el; - first_free_automata_list_el - = first_free_automata_list_el->next_automata_list_el; - } - else - result = XCREATENODE (struct automata_list_el); - result->automaton = NULL; - result->next_automata_list_el = NULL; - return result; -} - -/* The function frees node AUTOMATA_LIST_EL. */ -static void -free_automata_list_el (automata_list_el_t automata_list_el) -{ - if (automata_list_el == NULL) - return; - automata_list_el->next_automata_list_el = first_free_automata_list_el; - first_free_automata_list_el = automata_list_el; -} - -/* The function frees list AUTOMATA_LIST. */ -static void -free_automata_list (automata_list_el_t automata_list) -{ - automata_list_el_t curr_automata_list_el; - automata_list_el_t next_automata_list_el; - - for (curr_automata_list_el = automata_list; - curr_automata_list_el != NULL; - curr_automata_list_el = next_automata_list_el) - { - next_automata_list_el = curr_automata_list_el->next_automata_list_el; - free_automata_list_el (curr_automata_list_el); - } -} - -/* Hash value of AUTOMATA_LIST. */ -static hashval_t -automata_list_hash (const void *automata_list) -{ - unsigned int hash_value; - const_automata_list_el_t curr_automata_list_el; - - hash_value = 0; - for (curr_automata_list_el = (const_automata_list_el_t) automata_list; - curr_automata_list_el != NULL; - curr_automata_list_el = curr_automata_list_el->next_automata_list_el) - hash_value = (((hash_value >> (sizeof (unsigned) - 1) * CHAR_BIT) - | (hash_value << CHAR_BIT)) - + curr_automata_list_el->automaton->automaton_order_num); - return hash_value; -} - -/* Return nonzero value if the automata_lists are the same. */ -static int -automata_list_eq_p (const void *automata_list_1, const void *automata_list_2) -{ - const_automata_list_el_t automata_list_el_1; - const_automata_list_el_t automata_list_el_2; - - for (automata_list_el_1 = (const_automata_list_el_t) automata_list_1, - automata_list_el_2 = (const_automata_list_el_t) automata_list_2; - automata_list_el_1 != NULL && automata_list_el_2 != NULL; - automata_list_el_1 = automata_list_el_1->next_automata_list_el, - automata_list_el_2 = automata_list_el_2->next_automata_list_el) - if (automata_list_el_1->automaton != automata_list_el_2->automaton) - return 0; - return automata_list_el_1 == automata_list_el_2; -} - -/* Initialization of the abstract data. */ -static void -initiate_automata_lists (void) -{ - first_free_automata_list_el = NULL; - automata_list_table = htab_create (1500, automata_list_hash, - automata_list_eq_p, (htab_del) 0); -} - -/* The following function starts new automata list and makes it the - current one. */ -static void -automata_list_start (void) -{ - current_automata_list = NULL; -} - -/* The following function adds AUTOMATON to the current list. */ -static void -automata_list_add (automaton_t automaton) -{ - automata_list_el_t el; - - el = get_free_automata_list_el (); - el->automaton = automaton; - el->next_automata_list_el = current_automata_list; - current_automata_list = el; -} - -/* The following function finishes forming the current list, inserts - it into the table and returns it. */ -static automata_list_el_t -automata_list_finish (void) -{ - void **entry_ptr; - - if (current_automata_list == NULL) - return NULL; - entry_ptr = htab_find_slot (automata_list_table, - (void *) current_automata_list, INSERT); - if (*entry_ptr == NULL) - *entry_ptr = (void *) current_automata_list; - else - free_automata_list (current_automata_list); - current_automata_list = NULL; - return (automata_list_el_t) *entry_ptr; -} - -/* Finishing work with the abstract data. */ -static void -finish_automata_lists (void) -{ - htab_delete (automata_list_table); -} - - - -/* The page contains abstract data for work with exclusion sets (see - exclusion_set in file rtl.def). */ - -/* The following variable refers to an exclusion set returned by - get_excl_set. This is bit string of length equal to cpu units - number. If exclusion set for given unit contains 1 for a unit, - then simultaneous reservation of the units is prohibited. */ -static reserv_sets_t excl_set; - -/* The array contains exclusion sets for each unit. */ -static reserv_sets_t *unit_excl_set_table; - -/* The following function forms the array containing exclusion sets - for each unit. */ -static void -initiate_excl_sets (void) -{ - decl_t decl; - reserv_sets_t unit_excl_set; - unit_set_el_t el; - int i; - - obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t)); - excl_set = (reserv_sets_t) obstack_base (&irp); - obstack_finish (&irp); - obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t)); - unit_excl_set_table = (reserv_sets_t *) obstack_base (&irp); - obstack_finish (&irp); - /* Evaluate unit exclusion sets. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit) - { - obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t)); - unit_excl_set = (reserv_sets_t) obstack_base (&irp); - obstack_finish (&irp); - memset (unit_excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t)); - for (el = DECL_UNIT (decl)->excl_list; - el != NULL; - el = el->next_unit_set_el) - { - bitmap_set_bit (unit_excl_set, el->unit_decl->unit_num); - el->unit_decl->in_set_p = TRUE; - } - unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set; - } - } -} - -/* The function sets up and return EXCL_SET which is union of - exclusion sets for each unit in IN_SET. */ -static reserv_sets_t -get_excl_set (reserv_sets_t in_set) -{ - int el; - unsigned int i; - int start_unit_num; - int unit_num; - - memset (excl_set, 0, els_in_cycle_reserv * sizeof (set_el_t)); - for (el = 0; el < els_in_cycle_reserv; el++) - if (in_set[el]) - for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++) - if ((in_set[el] >> i) & 1) - { - start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i; - if (start_unit_num >= description->units_num) - return excl_set; - for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++) - { - excl_set [unit_num] - |= unit_excl_set_table [start_unit_num] [unit_num]; - } - } - return excl_set; -} - - - -/* The page contains abstract data for work with presence/absence - pattern sets (see presence_set/absence_set in file rtl.def). */ - -/* The following arrays contain correspondingly presence, final - presence, absence, and final absence patterns for each unit. */ -static pattern_reserv_t *unit_presence_set_table; -static pattern_reserv_t *unit_final_presence_set_table; -static pattern_reserv_t *unit_absence_set_table; -static pattern_reserv_t *unit_final_absence_set_table; - -/* The following function forms list of reservation sets for given - PATTERN_LIST. */ -static pattern_reserv_t -form_reserv_sets_list (pattern_set_el_t pattern_list) -{ - pattern_set_el_t el; - pattern_reserv_t first, curr, prev; - int i; - - prev = first = NULL; - for (el = pattern_list; el != NULL; el = el->next_pattern_set_el) - { - curr = XCREATENODE (struct pattern_reserv); - curr->reserv = alloc_empty_reserv_sets (); - curr->next_pattern_reserv = NULL; - for (i = 0; i < el->units_num; i++) - { - bitmap_set_bit (curr->reserv, el->unit_decls [i]->unit_num); - el->unit_decls [i]->in_set_p = TRUE; - } - if (prev != NULL) - prev->next_pattern_reserv = curr; - else - first = curr; - prev = curr; - } - return first; -} - - /* The following function forms the array containing presence and - absence pattern sets for each unit. */ -static void -initiate_presence_absence_pattern_sets (void) -{ - decl_t decl; - int i; - - obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t)); - unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp); - obstack_finish (&irp); - obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t)); - unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp); - obstack_finish (&irp); - obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t)); - unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp); - obstack_finish (&irp); - obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t)); - unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp); - obstack_finish (&irp); - /* Evaluate unit presence/absence sets. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit) - { - unit_presence_set_table [DECL_UNIT (decl)->unit_num] - = form_reserv_sets_list (DECL_UNIT (decl)->presence_list); - unit_final_presence_set_table [DECL_UNIT (decl)->unit_num] - = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list); - unit_absence_set_table [DECL_UNIT (decl)->unit_num] - = form_reserv_sets_list (DECL_UNIT (decl)->absence_list); - unit_final_absence_set_table [DECL_UNIT (decl)->unit_num] - = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list); - } - } -} - -/* The function checks that CHECKED_SET satisfies all presence pattern - sets for units in ORIGINAL_SET. The function returns TRUE if it - is ok. */ -static int -check_presence_pattern_sets (reserv_sets_t checked_set, - reserv_sets_t original_set, - int final_p) -{ - int el; - unsigned int i; - int start_unit_num; - int unit_num; - int presence_p; - pattern_reserv_t pat_reserv; - - for (el = 0; el < els_in_cycle_reserv; el++) - if (original_set[el]) - for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++) - if ((original_set[el] >> i) & 1) - { - start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i; - if (start_unit_num >= description->units_num) - break; - if ((final_p - && unit_final_presence_set_table [start_unit_num] == NULL) - || (!final_p - && unit_presence_set_table [start_unit_num] == NULL)) - continue; - presence_p = FALSE; - for (pat_reserv = (final_p - ? unit_final_presence_set_table [start_unit_num] - : unit_presence_set_table [start_unit_num]); - pat_reserv != NULL; - pat_reserv = pat_reserv->next_pattern_reserv) - { - for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++) - if ((checked_set [unit_num] & pat_reserv->reserv [unit_num]) - != pat_reserv->reserv [unit_num]) - break; - presence_p = presence_p || unit_num >= els_in_cycle_reserv; - } - if (!presence_p) - return FALSE; - } - return TRUE; -} - -/* The function checks that CHECKED_SET satisfies all absence pattern - sets for units in ORIGINAL_SET. The function returns TRUE if it - is ok. */ -static int -check_absence_pattern_sets (reserv_sets_t checked_set, - reserv_sets_t original_set, - int final_p) -{ - int el; - unsigned int i; - int start_unit_num; - int unit_num; - pattern_reserv_t pat_reserv; - - for (el = 0; el < els_in_cycle_reserv; el++) - if (original_set[el]) - for (i = 0; i < CHAR_BIT * sizeof (set_el_t); i++) - if ((original_set[el] >> i) & 1) - { - start_unit_num = el * CHAR_BIT * sizeof (set_el_t) + i; - if (start_unit_num >= description->units_num) - break; - for (pat_reserv = (final_p - ? unit_final_absence_set_table [start_unit_num] - : unit_absence_set_table [start_unit_num]); - pat_reserv != NULL; - pat_reserv = pat_reserv->next_pattern_reserv) - { - for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++) - if ((checked_set [unit_num] & pat_reserv->reserv [unit_num]) - != pat_reserv->reserv [unit_num] - && pat_reserv->reserv [unit_num]) - break; - if (unit_num >= els_in_cycle_reserv) - return FALSE; - } - } - return TRUE; -} - - - -/* This page contains code for transformation of original reservations - described in .md file. The main goal of transformations is - simplifying reservation and lifting up all `|' on the top of IR - reservation representation. */ - - -/* The following function makes copy of IR representation of - reservation. The function also substitutes all reservations - defined by define_reservation by corresponding value during making - the copy. */ -static regexp_t -copy_insn_regexp (regexp_t regexp) -{ - regexp_t result; - int i; - - switch (regexp->mode) - { - case rm_reserv: - result = copy_insn_regexp (REGEXP_RESERV (regexp)->reserv_decl->regexp); - break; - - case rm_unit: - result = XCOPYNODE (struct regexp, regexp); - break; - - case rm_repeat: - result = XCOPYNODE (struct regexp, regexp); - REGEXP_REPEAT (result)->regexp - = copy_insn_regexp (REGEXP_REPEAT (regexp)->regexp); - break; - - case rm_sequence: - result = XCOPYNODEVAR (struct regexp, regexp, - sizeof (struct regexp) + sizeof (regexp_t) - * (REGEXP_SEQUENCE (regexp)->regexps_num - 1)); - for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++) - REGEXP_SEQUENCE (result)->regexps [i] - = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]); - break; - - case rm_allof: - result = XCOPYNODEVAR (struct regexp, regexp, - sizeof (struct regexp) + sizeof (regexp_t) - * (REGEXP_ALLOF (regexp)->regexps_num - 1)); - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - REGEXP_ALLOF (result)->regexps [i] - = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]); - break; - - case rm_oneof: - result = XCOPYNODEVAR (struct regexp, regexp, - sizeof (struct regexp) + sizeof (regexp_t) - * (REGEXP_ONEOF (regexp)->regexps_num - 1)); - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - REGEXP_ONEOF (result)->regexps [i] - = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]); - break; - - case rm_nothing: - result = XCOPYNODE (struct regexp, regexp); - break; - - default: - gcc_unreachable (); - } - return result; -} - -/* The following variable is set up 1 if a transformation has been - applied. */ -static int regexp_transformed_p; - -/* The function makes transformation - A*N -> A, A, ... */ -static regexp_t -transform_1 (regexp_t regexp) -{ - int i; - int repeat_num; - regexp_t operand; - pos_t pos; - - if (regexp->mode == rm_repeat) - { - repeat_num = REGEXP_REPEAT (regexp)->repeat_num; - gcc_assert (repeat_num > 1); - operand = REGEXP_REPEAT (regexp)->regexp; - pos = regexp->mode; - regexp = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) * (repeat_num - 1)); - regexp->mode = rm_sequence; - regexp->pos = pos; - REGEXP_SEQUENCE (regexp)->regexps_num = repeat_num; - for (i = 0; i < repeat_num; i++) - REGEXP_SEQUENCE (regexp)->regexps [i] = copy_insn_regexp (operand); - regexp_transformed_p = 1; - } - return regexp; -} - -/* The function makes transformations - ...,(A,B,...),C,... -> ...,A,B,...,C,... - ...+(A+B+...)+C+... -> ...+A+B+...+C+... - ...|(A|B|...)|C|... -> ...|A|B|...|C|... */ -static regexp_t -transform_2 (regexp_t regexp) -{ - if (regexp->mode == rm_sequence) - { - regexp_t sequence = NULL; - regexp_t result; - int sequence_index = 0; - int i, j; - - for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) - if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_sequence) - { - sequence_index = i; - sequence = REGEXP_SEQUENCE (regexp)->regexps [i]; - break; - } - if (i < REGEXP_SEQUENCE (regexp)->regexps_num) - { - gcc_assert (REGEXP_SEQUENCE (sequence)->regexps_num > 1 - && REGEXP_SEQUENCE (regexp)->regexps_num > 1); - result = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_SEQUENCE (regexp)->regexps_num - + REGEXP_SEQUENCE (sequence)->regexps_num - - 2)); - result->mode = rm_sequence; - result->pos = regexp->pos; - REGEXP_SEQUENCE (result)->regexps_num - = (REGEXP_SEQUENCE (regexp)->regexps_num - + REGEXP_SEQUENCE (sequence)->regexps_num - 1); - for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) - if (i < sequence_index) - REGEXP_SEQUENCE (result)->regexps [i] - = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]); - else if (i > sequence_index) - REGEXP_SEQUENCE (result)->regexps - [i + REGEXP_SEQUENCE (sequence)->regexps_num - 1] - = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]); - else - for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++) - REGEXP_SEQUENCE (result)->regexps [i + j] - = copy_insn_regexp (REGEXP_SEQUENCE (sequence)->regexps [j]); - regexp_transformed_p = 1; - regexp = result; - } - } - else if (regexp->mode == rm_allof) - { - regexp_t allof = NULL; - regexp_t result; - int allof_index = 0; - int i, j; - - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_allof) - { - allof_index = i; - allof = REGEXP_ALLOF (regexp)->regexps [i]; - break; - } - if (i < REGEXP_ALLOF (regexp)->regexps_num) - { - gcc_assert (REGEXP_ALLOF (allof)->regexps_num > 1 - && REGEXP_ALLOF (regexp)->regexps_num > 1); - result = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_ALLOF (regexp)->regexps_num - + REGEXP_ALLOF (allof)->regexps_num - 2)); - result->mode = rm_allof; - result->pos = regexp->pos; - REGEXP_ALLOF (result)->regexps_num - = (REGEXP_ALLOF (regexp)->regexps_num - + REGEXP_ALLOF (allof)->regexps_num - 1); - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - if (i < allof_index) - REGEXP_ALLOF (result)->regexps [i] - = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]); - else if (i > allof_index) - REGEXP_ALLOF (result)->regexps - [i + REGEXP_ALLOF (allof)->regexps_num - 1] - = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [i]); - else - for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++) - REGEXP_ALLOF (result)->regexps [i + j] - = copy_insn_regexp (REGEXP_ALLOF (allof)->regexps [j]); - regexp_transformed_p = 1; - regexp = result; - } - } - else if (regexp->mode == rm_oneof) - { - regexp_t oneof = NULL; - regexp_t result; - int oneof_index = 0; - int i, j; - - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - if (REGEXP_ONEOF (regexp)->regexps [i]->mode == rm_oneof) - { - oneof_index = i; - oneof = REGEXP_ONEOF (regexp)->regexps [i]; - break; - } - if (i < REGEXP_ONEOF (regexp)->regexps_num) - { - gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1 - && REGEXP_ONEOF (regexp)->regexps_num > 1); - result = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_ONEOF (regexp)->regexps_num - + REGEXP_ONEOF (oneof)->regexps_num - 2)); - result->mode = rm_oneof; - result->pos = regexp->pos; - REGEXP_ONEOF (result)->regexps_num - = (REGEXP_ONEOF (regexp)->regexps_num - + REGEXP_ONEOF (oneof)->regexps_num - 1); - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - if (i < oneof_index) - REGEXP_ONEOF (result)->regexps [i] - = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]); - else if (i > oneof_index) - REGEXP_ONEOF (result)->regexps - [i + REGEXP_ONEOF (oneof)->regexps_num - 1] - = copy_insn_regexp (REGEXP_ONEOF (regexp)->regexps [i]); - else - for (j = 0; j < REGEXP_ONEOF (oneof)->regexps_num; j++) - REGEXP_ONEOF (result)->regexps [i + j] - = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [j]); - regexp_transformed_p = 1; - regexp = result; - } - } - return regexp; -} - -/* The function makes transformations - ...,A|B|...,C,... -> (...,A,C,...)|(...,B,C,...)|... - ...+(A|B|...)+C+... -> (...+A+C+...)|(...+B+C+...)|... - ...+(A,B,...)+C+... -> (...+A+C+...),B,... - ...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */ -static regexp_t -transform_3 (regexp_t regexp) -{ - if (regexp->mode == rm_sequence) - { - regexp_t oneof = NULL; - int oneof_index = 0; - regexp_t result; - regexp_t sequence; - int i, j; - - for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++) - if (REGEXP_SEQUENCE (regexp)->regexps [i]->mode == rm_oneof) - { - oneof_index = i; - oneof = REGEXP_SEQUENCE (regexp)->regexps [i]; - break; - } - if (i < REGEXP_SEQUENCE (regexp)->regexps_num) - { - gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1 - && REGEXP_SEQUENCE (regexp)->regexps_num > 1); - result = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_ONEOF (oneof)->regexps_num - 1)); - result->mode = rm_oneof; - result->pos = regexp->pos; - REGEXP_ONEOF (result)->regexps_num - = REGEXP_ONEOF (oneof)->regexps_num; - for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++) - { - sequence - = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_SEQUENCE (regexp)->regexps_num - 1)); - sequence->mode = rm_sequence; - sequence->pos = regexp->pos; - REGEXP_SEQUENCE (sequence)->regexps_num - = REGEXP_SEQUENCE (regexp)->regexps_num; - REGEXP_ONEOF (result)->regexps [i] = sequence; - for (j = 0; j < REGEXP_SEQUENCE (sequence)->regexps_num; j++) - if (j != oneof_index) - REGEXP_SEQUENCE (sequence)->regexps [j] - = copy_insn_regexp (REGEXP_SEQUENCE (regexp)->regexps [j]); - else - REGEXP_SEQUENCE (sequence)->regexps [j] - = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]); - } - regexp_transformed_p = 1; - regexp = result; - } - } - else if (regexp->mode == rm_allof) - { - regexp_t oneof = NULL; - regexp_t seq; - int oneof_index = 0; - int max_seq_length, allof_length; - regexp_t result; - regexp_t allof = NULL; - regexp_t allof_op = NULL; - int i, j; - - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - if (REGEXP_ALLOF (regexp)->regexps [i]->mode == rm_oneof) - { - oneof_index = i; - oneof = REGEXP_ALLOF (regexp)->regexps [i]; - break; - } - if (i < REGEXP_ALLOF (regexp)->regexps_num) - { - gcc_assert (REGEXP_ONEOF (oneof)->regexps_num > 1 - && REGEXP_ALLOF (regexp)->regexps_num > 1); - result = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_ONEOF (oneof)->regexps_num - 1)); - result->mode = rm_oneof; - result->pos = regexp->pos; - REGEXP_ONEOF (result)->regexps_num - = REGEXP_ONEOF (oneof)->regexps_num; - for (i = 0; i < REGEXP_ONEOF (result)->regexps_num; i++) - { - allof - = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (REGEXP_ALLOF (regexp)->regexps_num - 1)); - allof->mode = rm_allof; - allof->pos = regexp->pos; - REGEXP_ALLOF (allof)->regexps_num - = REGEXP_ALLOF (regexp)->regexps_num; - REGEXP_ONEOF (result)->regexps [i] = allof; - for (j = 0; j < REGEXP_ALLOF (allof)->regexps_num; j++) - if (j != oneof_index) - REGEXP_ALLOF (allof)->regexps [j] - = copy_insn_regexp (REGEXP_ALLOF (regexp)->regexps [j]); - else - REGEXP_ALLOF (allof)->regexps [j] - = copy_insn_regexp (REGEXP_ONEOF (oneof)->regexps [i]); - } - regexp_transformed_p = 1; - regexp = result; - } - max_seq_length = 0; - if (regexp->mode == rm_allof) - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - { - switch (REGEXP_ALLOF (regexp)->regexps [i]->mode) - { - case rm_sequence: - seq = REGEXP_ALLOF (regexp)->regexps [i]; - if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num) - max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num; - break; - - case rm_unit: - case rm_nothing: - break; - - default: - max_seq_length = 0; - goto break_for; - } - } - break_for: - if (max_seq_length != 0) - { - gcc_assert (max_seq_length != 1 - && REGEXP_ALLOF (regexp)->regexps_num > 1); - result = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) * (max_seq_length - 1)); - result->mode = rm_sequence; - result->pos = regexp->pos; - REGEXP_SEQUENCE (result)->regexps_num = max_seq_length; - for (i = 0; i < max_seq_length; i++) - { - allof_length = 0; - for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++) - switch (REGEXP_ALLOF (regexp)->regexps [j]->mode) - { - case rm_sequence: - if (i < (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp) - ->regexps [j])->regexps_num)) - { - allof_op - = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp) - ->regexps [j]) - ->regexps [i]); - allof_length++; - } - break; - case rm_unit: - case rm_nothing: - if (i == 0) - { - allof_op = REGEXP_ALLOF (regexp)->regexps [j]; - allof_length++; - } - break; - default: - break; - } - - if (allof_length == 1) - REGEXP_SEQUENCE (result)->regexps [i] = allof_op; - else - { - allof = XCREATENODEVAR (struct regexp, sizeof (struct regexp) - + sizeof (regexp_t) - * (allof_length - 1)); - allof->mode = rm_allof; - allof->pos = regexp->pos; - REGEXP_ALLOF (allof)->regexps_num = allof_length; - REGEXP_SEQUENCE (result)->regexps [i] = allof; - allof_length = 0; - for (j = 0; j < REGEXP_ALLOF (regexp)->regexps_num; j++) - if (REGEXP_ALLOF (regexp)->regexps [j]->mode == rm_sequence - && (i < - (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp) - ->regexps [j])->regexps_num))) - { - allof_op = (REGEXP_SEQUENCE (REGEXP_ALLOF (regexp) - ->regexps [j]) - ->regexps [i]); - REGEXP_ALLOF (allof)->regexps [allof_length] - = allof_op; - allof_length++; - } - else if (i == 0 - && (REGEXP_ALLOF (regexp)->regexps [j]->mode - == rm_unit - || (REGEXP_ALLOF (regexp)->regexps [j]->mode - == rm_nothing))) - { - allof_op = REGEXP_ALLOF (regexp)->regexps [j]; - REGEXP_ALLOF (allof)->regexps [allof_length] - = allof_op; - allof_length++; - } - } - } - regexp_transformed_p = 1; - regexp = result; - } - } - return regexp; -} - -/* The function traverses IR of reservation and applies transformations - implemented by FUNC. */ -static regexp_t -regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp)) -{ - int i; - - switch (regexp->mode) - { - case rm_sequence: - for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) - REGEXP_SEQUENCE (regexp)->regexps [i] - = regexp_transform_func (REGEXP_SEQUENCE (regexp)->regexps [i], - func); - break; - - case rm_allof: - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - REGEXP_ALLOF (regexp)->regexps [i] - = regexp_transform_func (REGEXP_ALLOF (regexp)->regexps [i], func); - break; - - case rm_oneof: - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - REGEXP_ONEOF (regexp)->regexps [i] - = regexp_transform_func (REGEXP_ONEOF (regexp)->regexps [i], func); - break; - - case rm_repeat: - REGEXP_REPEAT (regexp)->regexp - = regexp_transform_func (REGEXP_REPEAT (regexp)->regexp, func); - break; - - case rm_nothing: - case rm_unit: - break; - - default: - gcc_unreachable (); - } - return (*func) (regexp); -} - -/* The function applies all transformations for IR representation of - reservation REGEXP. */ -static regexp_t -transform_regexp (regexp_t regexp) -{ - regexp = regexp_transform_func (regexp, transform_1); - do - { - regexp_transformed_p = 0; - regexp = regexp_transform_func (regexp, transform_2); - regexp = regexp_transform_func (regexp, transform_3); - } - while (regexp_transformed_p); - return regexp; -} - -/* The function applies all transformations for reservations of all - insn declarations. */ -static void -transform_insn_regexps (void) -{ - decl_t decl; - int i; - - transform_time = create_ticker (); - add_advance_cycle_insn_decl (); - if (collapse_flag) - add_collapse_ndfa_insn_decl (); - if (progress_flag) - fprintf (stderr, "Reservation transformation..."); - for (i = 0; i < description->normal_decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - DECL_INSN_RESERV (decl)->transformed_regexp - = transform_regexp (copy_insn_regexp - (DECL_INSN_RESERV (decl)->regexp)); - } - if (progress_flag) - fprintf (stderr, "done\n"); - ticker_off (&transform_time); -} - - - -/* The following variable value is TRUE if the first annotated message - about units to automata distribution has been output. */ -static int annotation_message_reported_p; - -/* The vector contains all decls which are automata. */ -static vec<decl_t> automaton_decls; - -/* The following structure describes usage of a unit in a reservation. */ -struct unit_usage -{ - unit_decl_t unit_decl; - /* The following forms a list of units used on the same cycle in the - same alternative. The list is ordered by the correspdoning unit - declarations and there is no unit declaration duplication in the - list. */ - struct unit_usage *next; -}; -typedef struct unit_usage *unit_usage_t; - - -/* Obstack for unit_usage structures. */ -static struct obstack unit_usages; - -/* VLA for representation of array of pointers to unit usage - structures. There is an element for each combination of - (alternative number, cycle). Unit usages on given cycle in - alternative with given number are referred through element with - index equals to the cycle * number of all alternatives in the - regexp + the alternative number. */ -static vec<unit_usage_t> cycle_alt_unit_usages; - -/* The following function creates the structure unit_usage for UNIT on - CYCLE in REGEXP alternative with ALT_NUM. The structure is made - accessed through cycle_alt_unit_usages. */ -static void -store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle, - int alt_num) -{ - size_t length; - unit_decl_t unit_decl; - unit_usage_t unit_usage_ptr, curr, prev; - int index; - - gcc_assert (regexp && regexp->mode == rm_oneof - && alt_num < REGEXP_ONEOF (regexp)->regexps_num); - unit_decl = REGEXP_UNIT (unit)->unit_decl; - - length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num; - while (cycle_alt_unit_usages.length () < length) - cycle_alt_unit_usages.safe_push (NULL); - - index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num; - prev = NULL; - for (curr = cycle_alt_unit_usages[index]; - curr != NULL; - prev = curr, curr = curr->next) - if (curr->unit_decl >= unit_decl) - break; - if (curr != NULL && curr->unit_decl == unit_decl) - return; - obstack_blank (&unit_usages, sizeof (struct unit_usage)); - unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages); - obstack_finish (&unit_usages); - unit_usage_ptr->unit_decl = unit_decl; - unit_decl->last_distribution_check_cycle = -1; /* undefined */ - unit_usage_ptr->next = curr; - if (prev == NULL) - cycle_alt_unit_usages[index] = unit_usage_ptr; - else - prev->next = unit_usage_ptr; -} - -/* Return true if unit UNIT_DECL is present on the LIST. */ -static bool -unit_present_on_list_p (unit_usage_t list, unit_decl_t unit_decl) -{ - while (list != NULL) - { - if (list->unit_decl == unit_decl) - return true; - list = list->next; - } - return false; -} - -/* The function returns true if reservations of alternatives ALT1 and - ALT2 are equal after excluding reservations of units of - EXCLUDED_AUTOMATON_DECL. */ -static bool -equal_alternatives_p (int alt1, int alt2, int n_alts, - struct automaton_decl *excluded_automaton_decl) -{ - int i; - unit_usage_t list1, list2; - - for (i = 0; - i < (int) cycle_alt_unit_usages.length (); - i += n_alts) - { - for (list1 = cycle_alt_unit_usages[i + alt1], - list2 = cycle_alt_unit_usages[i + alt2];; - list1 = list1->next, list2 = list2->next) - { - while (list1 != NULL - && list1->unit_decl->automaton_decl == excluded_automaton_decl) - list1 = list1->next; - while (list2 != NULL - && list2->unit_decl->automaton_decl == excluded_automaton_decl) - list2 = list2->next; - if (list1 == NULL || list2 == NULL) - { - if (list1 != list2) - return false; - else - break; - } - if (list1->unit_decl != list2->unit_decl) - return false; - } - } - return true; -} - - -/* The function processes given REGEXP to find units with the wrong - distribution. */ -static void -check_regexp_units_distribution (const char *insn_reserv_name, - regexp_t regexp) -{ - int i, j, k, cycle, start, n_alts, alt, alt2; - bool annotation_reservation_message_reported_p; - regexp_t seq, allof, unit; - struct unit_usage *unit_usage_ptr; - - if (regexp == NULL || regexp->mode != rm_oneof) - return; - /* Store all unit usages in the regexp: */ - obstack_init (&unit_usages); - cycle_alt_unit_usages.create (10); - - for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--) - { - seq = REGEXP_ONEOF (regexp)->regexps [i]; - switch (seq->mode) - { - case rm_sequence: - for (j = 0; j < REGEXP_SEQUENCE (seq)->regexps_num; j++) - { - allof = REGEXP_SEQUENCE (seq)->regexps [j]; - switch (allof->mode) - { - case rm_allof: - for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++) - { - unit = REGEXP_ALLOF (allof)->regexps [k]; - if (unit->mode == rm_unit) - store_alt_unit_usage (regexp, unit, j, i); - else - gcc_assert (unit->mode == rm_nothing); - } - break; - - case rm_unit: - store_alt_unit_usage (regexp, allof, j, i); - break; - - case rm_nothing: - break; - - default: - gcc_unreachable (); - } - } - break; - - case rm_allof: - for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++) - { - unit = REGEXP_ALLOF (seq)->regexps [k]; - switch (unit->mode) - { - case rm_unit: - store_alt_unit_usage (regexp, unit, 0, i); - break; - - case rm_nothing: - break; - - default: - gcc_unreachable (); - } - } - break; - - case rm_unit: - store_alt_unit_usage (regexp, seq, 0, i); - break; - - case rm_nothing: - break; - - default: - gcc_unreachable (); - } - } - /* Check distribution: */ - for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++) - for (unit_usage_ptr = cycle_alt_unit_usages[i]; - unit_usage_ptr != NULL; - unit_usage_ptr = unit_usage_ptr->next) - unit_usage_ptr->unit_decl->last_distribution_check_cycle = -1; - n_alts = REGEXP_ONEOF (regexp)->regexps_num; - auto_vec<int> marked (n_alts); - for (i = 0; i < n_alts; i++) - marked.safe_push (0); - annotation_reservation_message_reported_p = false; - for (i = 0; i < (int) cycle_alt_unit_usages.length (); i++) - { - cycle = i / n_alts; - start = cycle * n_alts; - for (unit_usage_ptr = cycle_alt_unit_usages[i]; - unit_usage_ptr != NULL; - unit_usage_ptr = unit_usage_ptr->next) - { - if (unit_usage_ptr->unit_decl->last_distribution_check_cycle == cycle) - continue; - unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle; - for (alt = 0; alt < n_alts; alt++) - if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt], - unit_usage_ptr->unit_decl)) - break; - if (alt >= n_alts) - continue; - memset (marked.address (), 0, n_alts * sizeof (int)); - for (alt = 0; alt < n_alts; alt++) - { - if (! unit_present_on_list_p (cycle_alt_unit_usages[start + alt], - unit_usage_ptr->unit_decl)) - continue; - for (j = 0; - j < (int) cycle_alt_unit_usages.length (); - j++) - { - alt2 = j % n_alts; - if (! unit_present_on_list_p - (cycle_alt_unit_usages[start + alt2], - unit_usage_ptr->unit_decl) - && equal_alternatives_p (alt, alt2, n_alts, - unit_usage_ptr - ->unit_decl->automaton_decl)) - { - marked[alt] = 1; - marked[alt2] = 1; - } - } - } - for (alt = 0; alt < n_alts && marked[alt]; alt++) - ; - if (alt < n_alts && 0) - { - if (! annotation_message_reported_p) - { - fprintf (stderr, "\n"); - error ("The following units do not satisfy units-automata distribution rule"); - error ("(Unit presence on one alt and its absence on other alt\n"); - error (" result in different other automata reservations)"); - annotation_message_reported_p = TRUE; - } - if (! annotation_reservation_message_reported_p) - { - error ("Reserv %s:", insn_reserv_name); - annotation_reservation_message_reported_p = true; - } - error (" Unit %s, cycle %d, alt %d, another alt %d", - unit_usage_ptr->unit_decl->name, cycle, i % n_alts, alt); - } - } - } - cycle_alt_unit_usages.release (); - obstack_free (&unit_usages, NULL); -} - -/* The function finds units which violates units to automata - distribution rule. If the units exist, report about them. */ -static void -check_unit_distributions_to_automata (void) -{ - decl_t decl; - int i; - - if (progress_flag) - fprintf (stderr, "Check unit distributions to automata..."); - automaton_decls.create (0); - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_automaton) - automaton_decls.safe_push (decl); - } - if (automaton_decls.length () > 1) - { - annotation_message_reported_p = FALSE; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - check_regexp_units_distribution - (DECL_INSN_RESERV (decl)->name, - DECL_INSN_RESERV (decl)->transformed_regexp); - } - } - automaton_decls.release (); - if (progress_flag) - fprintf (stderr, "done\n"); -} - - - -/* The page contains code for building alt_states (see comments for - IR) describing all possible insns reservations of an automaton. */ - -/* Current state being formed for which the current alt_state - refers. */ -static state_t state_being_formed; - -/* Current alt_state being formed. */ -static alt_state_t alt_state_being_formed; - -/* This recursive function processes `,' and units in reservation - REGEXP for forming alt_states of AUTOMATON. It is believed that - CURR_CYCLE is start cycle of all reservation REGEXP. */ -static int -process_seq_for_forming_states (regexp_t regexp, automaton_t automaton, - int curr_cycle) -{ - int i; - - if (regexp == NULL) - return curr_cycle; - - switch (regexp->mode) - { - case rm_unit: - if (REGEXP_UNIT (regexp)->unit_decl->corresponding_automaton_num - == automaton->automaton_order_num) - set_state_reserv (state_being_formed, curr_cycle, - REGEXP_UNIT (regexp)->unit_decl->unit_num); - return curr_cycle; - - case rm_sequence: - for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) - curr_cycle - = process_seq_for_forming_states - (REGEXP_SEQUENCE (regexp)->regexps [i], automaton, curr_cycle) + 1; - return curr_cycle; - - case rm_allof: - { - int finish_cycle = 0; - int cycle; - - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - { - cycle = process_seq_for_forming_states (REGEXP_ALLOF (regexp) - ->regexps [i], - automaton, curr_cycle); - if (finish_cycle < cycle) - finish_cycle = cycle; - } - return finish_cycle; - } - - case rm_nothing: - return curr_cycle; - - default: - gcc_unreachable (); - } -} - -/* This recursive function finishes forming ALT_STATE of AUTOMATON and - inserts alt_state into the table. */ -static void -finish_forming_alt_state (alt_state_t alt_state, - automaton_t automaton ATTRIBUTE_UNUSED) -{ - state_t state_in_table; - state_t corresponding_state; - - corresponding_state = alt_state->state; - state_in_table = insert_state (corresponding_state); - if (state_in_table != corresponding_state) - { - free_state (corresponding_state); - alt_state->state = state_in_table; - } -} - -/* The following variable value is current automaton insn for whose - reservation the alt states are created. */ -static ainsn_t curr_ainsn; - -/* This recursive function processes `|' in reservation REGEXP for - forming alt_states of AUTOMATON. List of the alt states should - have the same order as in the description. */ -static void -process_alts_for_forming_states (regexp_t regexp, automaton_t automaton, - int inside_oneof_p) -{ - int i; - - if (regexp->mode != rm_oneof) - { - alt_state_being_formed = get_free_alt_state (); - state_being_formed = get_free_state (1, automaton); - alt_state_being_formed->state = state_being_formed; - /* We inserts in reverse order but we process alternatives also - in reverse order. So we have the same order of alternative - as in the description. */ - alt_state_being_formed->next_alt_state = curr_ainsn->alt_states; - curr_ainsn->alt_states = alt_state_being_formed; - (void) process_seq_for_forming_states (regexp, automaton, 0); - finish_forming_alt_state (alt_state_being_formed, automaton); - } - else - { - gcc_assert (!inside_oneof_p); - /* We processes it in reverse order to get list with the same - order as in the description. See also the previous - commentary. */ - for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--) - process_alts_for_forming_states (REGEXP_ONEOF (regexp)->regexps [i], - automaton, 1); - } -} - -/* Create nodes alt_state for all AUTOMATON insns. */ -static void -create_alt_states (automaton_t automaton) -{ - struct insn_reserv_decl *reserv_decl; - - for (curr_ainsn = automaton->ainsn_list; - curr_ainsn != NULL; - curr_ainsn = curr_ainsn->next_ainsn) - { - reserv_decl = curr_ainsn->insn_reserv_decl; - if (!special_decl_p (reserv_decl)) - { - curr_ainsn->alt_states = NULL; - process_alts_for_forming_states (reserv_decl->transformed_regexp, - automaton, 0); - curr_ainsn->sorted_alt_states - = uniq_sort_alt_states (curr_ainsn->alt_states); - } - } -} - - - -/* The page contains major code for building DFA(s) for fast pipeline - hazards recognition. */ - -/* The function forms list of ainsns of AUTOMATON with the same - reservation. */ - -static void -form_ainsn_with_same_reservs (automaton_t automaton) -{ - ainsn_t curr_ainsn; - size_t i; - auto_vec<ainsn_t, 150> last_insns; - - for (curr_ainsn = automaton->ainsn_list; - curr_ainsn != NULL; - curr_ainsn = curr_ainsn->next_ainsn) - if (special_decl_p (curr_ainsn->insn_reserv_decl)) - { - curr_ainsn->next_same_reservs_insn = NULL; - curr_ainsn->first_insn_with_same_reservs = 1; - } - else - { - for (i = 0; i < last_insns.length (); i++) - if (alt_states_eq - (curr_ainsn->sorted_alt_states, - last_insns[i]->sorted_alt_states)) - break; - curr_ainsn->next_same_reservs_insn = NULL; - if (i < last_insns.length ()) - { - curr_ainsn->first_insn_with_same_reservs = 0; - last_insns[i]->next_same_reservs_insn = curr_ainsn; - last_insns[i] = curr_ainsn; - } - else - { - last_insns.safe_push (curr_ainsn); - curr_ainsn->first_insn_with_same_reservs = 1; - } - } -} - -/* Forming unit reservations which can affect creating the automaton - states achieved from a given state. It permits to build smaller - automata in many cases. We would have the same automata after - the minimization without such optimization, but the automaton - right after the building could be huge. So in other words, usage - of reservs_matter means some minimization during building the - automaton. */ -static reserv_sets_t -form_reservs_matter (automaton_t automaton) -{ - int cycle, unit; - reserv_sets_t reservs_matter = alloc_empty_reserv_sets (); - - for (cycle = 0; cycle < max_cycles_num; cycle++) - for (unit = 0; unit < description->units_num; unit++) - if (units_array [unit]->automaton_decl - == automaton->corresponding_automaton_decl - && (cycle >= units_array [unit]->min_occ_cycle_num - /* We cannot remove queried unit from reservations. */ - || units_array [unit]->query_p - /* We cannot remove units which are used - `exclusion_set', `presence_set', - `final_presence_set', `absence_set', and - `final_absence_set'. */ - || units_array [unit]->in_set_p)) - set_unit_reserv (reservs_matter, cycle, unit); - return reservs_matter; -} - -/* The following function creates all states of nondeterministic AUTOMATON. */ -static void -make_automaton (automaton_t automaton) -{ - ainsn_t ainsn; - struct insn_reserv_decl *insn_reserv_decl; - alt_state_t alt_state; - state_t state; - state_t start_state; - state_t state2; - auto_vec<state_t, 150> state_stack; - int states_n; - reserv_sets_t reservs_matter = form_reservs_matter (automaton); - - /* Create the start state (empty state). */ - start_state = insert_state (get_free_state (1, automaton)); - automaton->start_state = start_state; - start_state->it_was_placed_in_stack_for_NDFA_forming = 1; - state_stack.safe_push (start_state); - states_n = 1; - while (state_stack.length () != 0) - { - state = state_stack.pop (); - for (ainsn = automaton->ainsn_list; - ainsn != NULL; - ainsn = ainsn->next_ainsn) - if (ainsn->first_insn_with_same_reservs) - { - insn_reserv_decl = ainsn->insn_reserv_decl; - if (!special_decl_p (insn_reserv_decl)) - { - /* We process alt_states in the same order as they are - present in the description. */ - for (alt_state = ainsn->alt_states; - alt_state != NULL; - alt_state = alt_state->next_alt_state) - { - state2 = alt_state->state; - if (!intersected_state_reservs_p (state, state2)) - { - state2 = states_union (state, state2, reservs_matter); - if (!state2->it_was_placed_in_stack_for_NDFA_forming) - { - state2->it_was_placed_in_stack_for_NDFA_forming - = 1; - state_stack.safe_push (state2); - states_n++; - if (progress_flag && states_n % 100 == 0) - fprintf (stderr, "."); - } - add_arc (state, state2, ainsn); - if (!ndfa_flag) - break; - } - } - } - } - /* Add transition to advance cycle. */ - state2 = state_shift (state, reservs_matter); - if (!state2->it_was_placed_in_stack_for_NDFA_forming) - { - state2->it_was_placed_in_stack_for_NDFA_forming = 1; - state_stack.safe_push (state2); - states_n++; - if (progress_flag && states_n % 100 == 0) - fprintf (stderr, "."); - } - add_arc (state, state2, automaton->advance_ainsn); - } -} - -/* Form lists of all arcs of STATE marked by the same ainsn. */ -static void -form_arcs_marked_by_insn (state_t state) -{ - decl_t decl; - arc_t arc; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - DECL_INSN_RESERV (decl)->arcs_marked_by_insn = NULL; - } - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - { - gcc_assert (arc->insn); - arc->next_arc_marked_by_insn - = arc->insn->insn_reserv_decl->arcs_marked_by_insn; - arc->insn->insn_reserv_decl->arcs_marked_by_insn = arc; - } -} - -/* The function creates composed state (see comments for IR) from - ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the - same insn. If the composed state is not in STATE_STACK yet, it is - pushed into STATE_STACK. */ - -static int -create_composed_state (state_t original_state, arc_t arcs_marked_by_insn, - vec<state_t> *state_stack) -{ - state_t state; - alt_state_t alt_state, curr_alt_state; - alt_state_t new_alt_state; - arc_t curr_arc; - arc_t next_arc; - state_t state_in_table; - state_t temp_state; - alt_state_t canonical_alt_states_list; - int alts_number; - int new_state_p = 0; - - if (arcs_marked_by_insn == NULL) - return new_state_p; - if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL) - state = arcs_marked_by_insn->to_state; - else - { - gcc_assert (ndfa_flag); - /* Create composed state. */ - state = get_free_state (0, arcs_marked_by_insn->to_state->automaton); - curr_alt_state = NULL; - for (curr_arc = arcs_marked_by_insn; - curr_arc != NULL; - curr_arc = curr_arc->next_arc_marked_by_insn) - if (curr_arc->to_state->component_states == NULL) - { - new_alt_state = get_free_alt_state (); - new_alt_state->next_alt_state = curr_alt_state; - new_alt_state->state = curr_arc->to_state; - curr_alt_state = new_alt_state; - } - else - for (alt_state = curr_arc->to_state->component_states; - alt_state != NULL; - alt_state = alt_state->next_sorted_alt_state) - { - new_alt_state = get_free_alt_state (); - new_alt_state->next_alt_state = curr_alt_state; - new_alt_state->state = alt_state->state; - gcc_assert (!alt_state->state->component_states); - curr_alt_state = new_alt_state; - } - /* There are not identical sets in the alt state list. */ - canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state); - if (canonical_alt_states_list->next_sorted_alt_state == NULL) - { - temp_state = state; - state = canonical_alt_states_list->state; - free_state (temp_state); - } - else - { - state->component_states = canonical_alt_states_list; - state_in_table = insert_state (state); - if (state_in_table != state) - { - gcc_assert - (state_in_table->it_was_placed_in_stack_for_DFA_forming); - free_state (state); - state = state_in_table; - } - else - { - gcc_assert (!state->it_was_placed_in_stack_for_DFA_forming); - new_state_p = 1; - for (curr_alt_state = state->component_states; - curr_alt_state != NULL; - curr_alt_state = curr_alt_state->next_sorted_alt_state) - for (curr_arc = first_out_arc (curr_alt_state->state); - curr_arc != NULL; - curr_arc = next_out_arc (curr_arc)) - if (!collapse_flag - /* When producing collapse-NDFA transitions, we - only add advance-cycle transitions to the - collapsed states. */ - || (curr_arc->insn->insn_reserv_decl - != DECL_INSN_RESERV (advance_cycle_insn_decl))) - add_arc (state, curr_arc->to_state, curr_arc->insn); - } - arcs_marked_by_insn->to_state = state; - for (alts_number = 0, - curr_arc = arcs_marked_by_insn->next_arc_marked_by_insn; - curr_arc != NULL; - curr_arc = next_arc) - { - next_arc = curr_arc->next_arc_marked_by_insn; - remove_arc (original_state, curr_arc); - alts_number++; - } - } - } - if (!state->it_was_placed_in_stack_for_DFA_forming) - { - state->it_was_placed_in_stack_for_DFA_forming = 1; - state_stack->safe_push (state); - } - return new_state_p; -} - -/* The function transforms nondeterministic AUTOMATON into - deterministic. */ - -static void -NDFA_to_DFA (automaton_t automaton) -{ - state_t start_state; - state_t state; - decl_t decl; - auto_vec<state_t> state_stack; - int i; - int states_n; - - /* Create the start state (empty state). */ - start_state = automaton->start_state; - start_state->it_was_placed_in_stack_for_DFA_forming = 1; - state_stack.safe_push (start_state); - states_n = 1; - while (state_stack.length () != 0) - { - state = state_stack.pop (); - form_arcs_marked_by_insn (state); - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv - && decl != collapse_ndfa_insn_decl - && create_composed_state - (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn, - &state_stack)) - { - states_n++; - if (progress_flag && states_n % 100 == 0) - fprintf (stderr, "."); - } - } - /* Add a transition to collapse the NDFA. */ - if (collapse_flag) - { - if (state->component_states != NULL) - { - state_t state2 = state->component_states->state; - if (!state2->it_was_placed_in_stack_for_DFA_forming) - { - state2->it_was_placed_in_stack_for_DFA_forming = 1; - state_stack.safe_push (state2); - } - add_arc (state, state2, automaton->collapse_ainsn); - } - else - add_arc (state, state, automaton->collapse_ainsn); - } - } -} - -/* The following variable value is current number (1, 2, ...) of passing - graph of states. */ -static int curr_state_graph_pass_num; - -/* This recursive function passes all states achieved from START_STATE - and applies APPLIED_FUNC to them. */ -static void -pass_state_graph (state_t start_state, void (*applied_func) (state_t state)) -{ - arc_t arc; - - if (start_state->pass_num == curr_state_graph_pass_num) - return; - start_state->pass_num = curr_state_graph_pass_num; - (*applied_func) (start_state); - for (arc = first_out_arc (start_state); - arc != NULL; - arc = next_out_arc (arc)) - pass_state_graph (arc->to_state, applied_func); -} - -/* This recursive function passes all states of AUTOMATON and applies - APPLIED_FUNC to them. */ -static void -pass_states (automaton_t automaton, void (*applied_func) (state_t state)) -{ - curr_state_graph_pass_num++; - pass_state_graph (automaton->start_state, applied_func); -} - -/* The function initializes code for passing of all states. */ -static void -initiate_pass_states (void) -{ - curr_state_graph_pass_num = 0; -} - -/* The following vla is used for storing pointers to all achieved - states. */ -static vec<state_t> all_achieved_states; - -/* This function is called by function pass_states to add an achieved - STATE. */ -static void -add_achieved_state (state_t state) -{ - all_achieved_states.safe_push (state); -} - -/* The function sets up equivalence numbers of insns which mark all - out arcs of STATE by equiv_class_num_1 (if ODD_ITERATION_FLAG has - nonzero value) or by equiv_class_num_2 of the destination state. */ -static void -set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag) -{ - arc_t arc; - - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - { - gcc_assert (!arc->insn->insn_reserv_decl->equiv_class_num); - arc->insn->insn_reserv_decl->equiv_class_num - = (odd_iteration_flag - ? arc->to_state->equiv_class_num_1 - : arc->to_state->equiv_class_num_2); - gcc_assert (arc->insn->insn_reserv_decl->equiv_class_num); - } -} - -/* The function clears equivalence numbers and alt_states in all insns - which mark all out arcs of STATE. */ -static void -clear_arc_insns_equiv_num (state_t state) -{ - arc_t arc; - - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - arc->insn->insn_reserv_decl->equiv_class_num = 0; -} - - -/* The following function returns TRUE if STATE reserves the unit with - UNIT_NUM on the first cycle. */ -static int -first_cycle_unit_presence (state_t state, int unit_num) -{ - alt_state_t alt_state; - - if (state->component_states == NULL) - return test_unit_reserv (state->reservs, 0, unit_num); - else - { - for (alt_state = state->component_states; - alt_state != NULL; - alt_state = alt_state->next_sorted_alt_state) - if (test_unit_reserv (alt_state->state->reservs, 0, unit_num)) - return true; - } - return false; -} - -/* This fills in the presence_signature[] member of STATE. */ -static void -cache_presence (state_t state) -{ - int i, num = 0; - unsigned int sz; - sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) - / (sizeof (int) * CHAR_BIT); - - state->presence_signature = XCREATENODEVEC (unsigned int, sz); - for (i = 0; i < description->units_num; i++) - if (units_array [i]->query_p) - { - int presence1_p = first_cycle_unit_presence (state, i); - state->presence_signature[num / (sizeof (int) * CHAR_BIT)] - |= (!!presence1_p) << (num % (sizeof (int) * CHAR_BIT)); - num++; - } -} - -/* The function returns nonzero value if STATE is not equivalent to - ANOTHER_STATE from the same current partition on equivalence - classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of - output arcs. Iteration of making equivalence partition is defined - by ODD_ITERATION_FLAG. */ -static int -state_is_differed (state_t state, state_t another_state, - int odd_iteration_flag) -{ - arc_t arc; - unsigned int sz, si; - - gcc_assert (state->num_out_arcs == another_state->num_out_arcs); - - sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) - / (sizeof (int) * CHAR_BIT); - - for (si = 0; si < sz; si++) - gcc_assert (state->presence_signature[si] - == another_state->presence_signature[si]); - - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - { - if ((odd_iteration_flag - ? arc->to_state->equiv_class_num_1 - : arc->to_state->equiv_class_num_2) - != arc->insn->insn_reserv_decl->equiv_class_num) - return 1; - } - - return 0; -} - -/* Compares two states pointed to by STATE_PTR_1 and STATE_PTR_2 - and return -1, 0 or 1. This function can be used as predicate for - qsort(). It requires the member presence_signature[] of both - states be filled. */ -static int -compare_states_for_equiv (const void *state_ptr_1, - const void *state_ptr_2) -{ - const_state_t const s1 = *(const_state_t const*)state_ptr_1; - const_state_t const s2 = *(const_state_t const*)state_ptr_2; - unsigned int sz, si; - if (s1->num_out_arcs < s2->num_out_arcs) - return -1; - else if (s1->num_out_arcs > s2->num_out_arcs) - return 1; - - sz = (description->query_units_num + sizeof (int) * CHAR_BIT - 1) - / (sizeof (int) * CHAR_BIT); - - for (si = 0; si < sz; si++) - if (s1->presence_signature[si] < s2->presence_signature[si]) - return -1; - else if (s1->presence_signature[si] > s2->presence_signature[si]) - return 1; - return 0; -} - -/* The function makes initial partition of STATES on equivalent - classes and saves it into CLASSES. This function requires the input - to be sorted via compare_states_for_equiv(). */ -static int -init_equiv_class (vec<state_t> states, vec<state_t> *classes) -{ - size_t i; - state_t prev = 0; - int class_num = 1; - - classes->create (150); - for (i = 0; i < states.length (); i++) - { - state_t state = states[i]; - if (prev) - { - if (compare_states_for_equiv (&prev, &state) != 0) - { - classes->safe_push (prev); - class_num++; - prev = NULL; - } - } - state->equiv_class_num_1 = class_num; - state->next_equiv_class_state = prev; - prev = state; - } - if (prev) - classes->safe_push (prev); - return class_num; -} - -/* The function copies pointers to equivalent states from vla FROM - into vla TO. */ -static void -copy_equiv_class (vec<state_t> *to, vec<state_t> from) -{ - to->release (); - *to = from.copy (); -} - -/* The function processes equivalence class given by its first state, - FIRST_STATE, on odd iteration if ODD_ITERATION_FLAG. If there - are not equivalent states, the function partitions the class - removing nonequivalent states and placing them in - *NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans - assigns it to the state equivalence number. If the class has been - partitioned, the function returns nonzero value. */ -static int -partition_equiv_class (state_t first_state, int odd_iteration_flag, - vec<state_t> *next_iteration_classes, - int *new_equiv_class_num_ptr) -{ - state_t new_equiv_class; - int partition_p; - state_t curr_state; - state_t prev_state; - state_t next_state; - - partition_p = 0; - - while (first_state != NULL) - { - new_equiv_class = NULL; - if (first_state->next_equiv_class_state != NULL) - { - /* There are more one states in the class equivalence. */ - set_out_arc_insns_equiv_num (first_state, odd_iteration_flag); - for (prev_state = first_state, - curr_state = first_state->next_equiv_class_state; - curr_state != NULL; - curr_state = next_state) - { - next_state = curr_state->next_equiv_class_state; - if (state_is_differed (curr_state, first_state, - odd_iteration_flag)) - { - /* Remove curr state from the class equivalence. */ - prev_state->next_equiv_class_state = next_state; - /* Add curr state to the new class equivalence. */ - curr_state->next_equiv_class_state = new_equiv_class; - if (new_equiv_class == NULL) - (*new_equiv_class_num_ptr)++; - if (odd_iteration_flag) - curr_state->equiv_class_num_2 = *new_equiv_class_num_ptr; - else - curr_state->equiv_class_num_1 = *new_equiv_class_num_ptr; - new_equiv_class = curr_state; - partition_p = 1; - } - else - prev_state = curr_state; - } - clear_arc_insns_equiv_num (first_state); - } - if (new_equiv_class != NULL) - next_iteration_classes->safe_push (new_equiv_class); - first_state = new_equiv_class; - } - return partition_p; -} - -/* The function finds equivalent states of AUTOMATON. */ -static void -evaluate_equiv_classes (automaton_t automaton, vec<state_t> *equiv_classes) -{ - int new_equiv_class_num; - int odd_iteration_flag; - int finish_flag; - vec<state_t> next_iteration_classes; - size_t i; - - all_achieved_states.create (1500); - pass_states (automaton, add_achieved_state); - pass_states (automaton, cache_presence); - all_achieved_states.qsort (compare_states_for_equiv); - - odd_iteration_flag = 0; - new_equiv_class_num = init_equiv_class (all_achieved_states, - &next_iteration_classes); - - do - { - odd_iteration_flag = !odd_iteration_flag; - finish_flag = 1; - copy_equiv_class (equiv_classes, next_iteration_classes); - - /* Transfer equiv numbers for the next iteration. */ - for (i = 0; i < all_achieved_states.length (); i++) - if (odd_iteration_flag) - all_achieved_states[i]->equiv_class_num_2 - = all_achieved_states[i]->equiv_class_num_1; - else - all_achieved_states[i]->equiv_class_num_1 - = all_achieved_states[i]->equiv_class_num_2; - - for (i = 0; i < equiv_classes->length (); i++) - if (partition_equiv_class ((*equiv_classes)[i], - odd_iteration_flag, - &next_iteration_classes, - &new_equiv_class_num)) - finish_flag = 0; - } - while (!finish_flag); - next_iteration_classes.release (); - all_achieved_states.release (); -} - -/* The function merges equivalent states of AUTOMATON. */ -static void -merge_states (automaton_t automaton, const vec<state_t> &equiv_classes) -{ - state_t curr_state; - state_t new_state; - state_t first_class_state; - alt_state_t alt_states; - alt_state_t alt_state, new_alt_state; - arc_t curr_arc; - arc_t next_arc; - size_t i; - - /* Create states corresponding to equivalence classes containing two - or more states. */ - for (i = 0; i < equiv_classes.length (); i++) - { - curr_state = equiv_classes[i]; - if (curr_state->next_equiv_class_state != NULL) - { - /* There are more one states in the class equivalence. */ - /* Create new compound state. */ - new_state = get_free_state (0, automaton); - alt_states = NULL; - first_class_state = curr_state; - for (curr_state = first_class_state; - curr_state != NULL; - curr_state = curr_state->next_equiv_class_state) - { - curr_state->equiv_class_state = new_state; - if (curr_state->component_states == NULL) - { - new_alt_state = get_free_alt_state (); - new_alt_state->state = curr_state; - new_alt_state->next_alt_state = alt_states; - alt_states = new_alt_state; - } - else - for (alt_state = curr_state->component_states; - alt_state != NULL; - alt_state = alt_state->next_sorted_alt_state) - { - new_alt_state = get_free_alt_state (); - new_alt_state->state = alt_state->state; - new_alt_state->next_alt_state = alt_states; - alt_states = new_alt_state; - } - } - /* It is important that alt states were sorted before and - after merging to have the same querying results. */ - new_state->component_states = uniq_sort_alt_states (alt_states); - } - else - curr_state->equiv_class_state = curr_state; - } - - for (i = 0; i < equiv_classes.length (); i++) - { - curr_state = equiv_classes[i]; - if (curr_state->next_equiv_class_state != NULL) - { - first_class_state = curr_state; - /* Create new arcs output from the state corresponding to - equiv class. */ - for (curr_arc = first_out_arc (first_class_state); - curr_arc != NULL; - curr_arc = next_out_arc (curr_arc)) - add_arc (first_class_state->equiv_class_state, - curr_arc->to_state->equiv_class_state, - curr_arc->insn); - /* Delete output arcs from states of given class equivalence. */ - for (curr_state = first_class_state; - curr_state != NULL; - curr_state = curr_state->next_equiv_class_state) - { - if (automaton->start_state == curr_state) - automaton->start_state = curr_state->equiv_class_state; - /* Delete the state and its output arcs. */ - for (curr_arc = first_out_arc (curr_state); - curr_arc != NULL; - curr_arc = next_arc) - { - next_arc = next_out_arc (curr_arc); - free_arc (curr_arc); - } - } - } - else - { - /* Change `to_state' of arcs output from the state of given - equivalence class. */ - for (curr_arc = first_out_arc (curr_state); - curr_arc != NULL; - curr_arc = next_out_arc (curr_arc)) - curr_arc->to_state = curr_arc->to_state->equiv_class_state; - } - } -} - -/* The function sets up new_cycle_p for states if there is arc to the - state marked by advance_cycle_insn_decl. */ -static void -set_new_cycle_flags (state_t state) -{ - arc_t arc; - - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - if (arc->insn->insn_reserv_decl - == DECL_INSN_RESERV (advance_cycle_insn_decl)) - arc->to_state->new_cycle_p = 1; -} - -/* The top level function for minimization of deterministic - AUTOMATON. */ -static void -minimize_DFA (automaton_t automaton) -{ - auto_vec<state_t> equiv_classes; - - evaluate_equiv_classes (automaton, &equiv_classes); - merge_states (automaton, equiv_classes); - pass_states (automaton, set_new_cycle_flags); -} - -/* Values of two variables are counted number of states and arcs in an - automaton. */ -static int curr_counted_states_num; -static int curr_counted_arcs_num; - -/* The function is called by function `pass_states' to count states - and arcs of an automaton. */ -static void -incr_states_and_arcs_nums (state_t state) -{ - arc_t arc; - - curr_counted_states_num++; - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - curr_counted_arcs_num++; -} - -/* The function counts states and arcs of AUTOMATON. */ -static void -count_states_and_arcs (automaton_t automaton, int *states_num, - int *arcs_num) -{ - curr_counted_states_num = 0; - curr_counted_arcs_num = 0; - pass_states (automaton, incr_states_and_arcs_nums); - *states_num = curr_counted_states_num; - *arcs_num = curr_counted_arcs_num; -} - -/* The function builds one DFA AUTOMATON for fast pipeline hazards - recognition after checking and simplifying IR of the - description. */ -static void -build_automaton (automaton_t automaton) -{ - int states_num; - int arcs_num; - - ticker_on (&NDFA_time); - if (progress_flag) - { - if (automaton->corresponding_automaton_decl == NULL) - fprintf (stderr, "Create anonymous automaton"); - else - fprintf (stderr, "Create automaton `%s'", - automaton->corresponding_automaton_decl->name); - fprintf (stderr, " (1 dot is 100 new states):"); - } - make_automaton (automaton); - if (progress_flag) - fprintf (stderr, " done\n"); - ticker_off (&NDFA_time); - count_states_and_arcs (automaton, &states_num, &arcs_num); - automaton->NDFA_states_num = states_num; - automaton->NDFA_arcs_num = arcs_num; - ticker_on (&NDFA_to_DFA_time); - if (progress_flag) - { - if (automaton->corresponding_automaton_decl == NULL) - fprintf (stderr, "Make anonymous DFA"); - else - fprintf (stderr, "Make DFA `%s'", - automaton->corresponding_automaton_decl->name); - fprintf (stderr, " (1 dot is 100 new states):"); - } - NDFA_to_DFA (automaton); - if (progress_flag) - fprintf (stderr, " done\n"); - ticker_off (&NDFA_to_DFA_time); - count_states_and_arcs (automaton, &states_num, &arcs_num); - automaton->DFA_states_num = states_num; - automaton->DFA_arcs_num = arcs_num; - if (!no_minimization_flag) - { - ticker_on (&minimize_time); - if (progress_flag) - { - if (automaton->corresponding_automaton_decl == NULL) - fprintf (stderr, "Minimize anonymous DFA..."); - else - fprintf (stderr, "Minimize DFA `%s'...", - automaton->corresponding_automaton_decl->name); - } - minimize_DFA (automaton); - if (progress_flag) - fprintf (stderr, "done\n"); - ticker_off (&minimize_time); - count_states_and_arcs (automaton, &states_num, &arcs_num); - automaton->minimal_DFA_states_num = states_num; - automaton->minimal_DFA_arcs_num = arcs_num; - } -} - - - -/* The page contains code for enumeration of all states of an automaton. */ - -/* Variable used for enumeration of all states of an automaton. Its - value is current number of automaton states. */ -static int curr_state_order_num; - -/* The function is called by function `pass_states' for enumerating - states. */ -static void -set_order_state_num (state_t state) -{ - state->order_state_num = curr_state_order_num; - curr_state_order_num++; -} - -/* The function enumerates all states of AUTOMATON. */ -static void -enumerate_states (automaton_t automaton) -{ - curr_state_order_num = 0; - pass_states (automaton, set_order_state_num); - automaton->achieved_states_num = curr_state_order_num; -} - - - -/* The page contains code for finding equivalent automaton insns - (ainsns). */ - -/* The function inserts AINSN into cyclic list - CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */ -static ainsn_t -insert_ainsn_into_equiv_class (ainsn_t ainsn, - ainsn_t cyclic_equiv_class_insn_list) -{ - if (cyclic_equiv_class_insn_list == NULL) - ainsn->next_equiv_class_insn = ainsn; - else - { - ainsn->next_equiv_class_insn - = cyclic_equiv_class_insn_list->next_equiv_class_insn; - cyclic_equiv_class_insn_list->next_equiv_class_insn = ainsn; - } - return ainsn; -} - -/* The function deletes equiv_class_insn into cyclic list of - equivalent ainsns. */ -static void -delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn) -{ - ainsn_t curr_equiv_class_insn; - ainsn_t prev_equiv_class_insn; - - prev_equiv_class_insn = equiv_class_insn; - for (curr_equiv_class_insn = equiv_class_insn->next_equiv_class_insn; - curr_equiv_class_insn != equiv_class_insn; - curr_equiv_class_insn = curr_equiv_class_insn->next_equiv_class_insn) - prev_equiv_class_insn = curr_equiv_class_insn; - if (prev_equiv_class_insn != equiv_class_insn) - prev_equiv_class_insn->next_equiv_class_insn - = equiv_class_insn->next_equiv_class_insn; -} - -/* The function processes AINSN of a state in order to find equivalent - ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the - state. */ -static void -process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array) -{ - ainsn_t next_insn; - ainsn_t curr_insn; - ainsn_t cyclic_insn_list; - arc_t arc; - - gcc_assert (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]); - curr_insn = ainsn; - /* New class of ainsns which are not equivalent to given ainsn. */ - cyclic_insn_list = NULL; - do - { - next_insn = curr_insn->next_equiv_class_insn; - arc = insn_arcs_array [curr_insn->insn_reserv_decl->insn_num]; - if (arc == NULL - || (insn_arcs_array [ainsn->insn_reserv_decl->insn_num]->to_state - != arc->to_state)) - { - delete_ainsn_from_equiv_class (curr_insn); - cyclic_insn_list = insert_ainsn_into_equiv_class (curr_insn, - cyclic_insn_list); - } - curr_insn = next_insn; - } - while (curr_insn != ainsn); -} - -/* The function processes STATE in order to find equivalent ainsns. */ -static void -process_state_for_insn_equiv_partition (state_t state) -{ - arc_t arc; - arc_t *insn_arcs_array = XCNEWVEC (arc_t, description->insns_num); - - /* Process insns of the arcs. */ - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - insn_arcs_array [arc->insn->insn_reserv_decl->insn_num] = arc; - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - process_insn_equiv_class (arc->insn, insn_arcs_array); - - free (insn_arcs_array); -} - -/* The function searches for equivalent ainsns of AUTOMATON. */ -static void -set_insn_equiv_classes (automaton_t automaton) -{ - ainsn_t ainsn; - ainsn_t first_insn; - ainsn_t curr_insn; - ainsn_t cyclic_insn_list; - ainsn_t insn_with_same_reservs; - int equiv_classes_num; - - /* All insns are included in one equivalence class. */ - cyclic_insn_list = NULL; - for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn) - if (ainsn->first_insn_with_same_reservs) - cyclic_insn_list = insert_ainsn_into_equiv_class (ainsn, - cyclic_insn_list); - /* Process insns in order to make equivalence partition. */ - pass_states (automaton, process_state_for_insn_equiv_partition); - /* Enumerate equiv classes. */ - for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn) - /* Set undefined value. */ - ainsn->insn_equiv_class_num = -1; - equiv_classes_num = 0; - for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn) - if (ainsn->insn_equiv_class_num < 0) - { - first_insn = ainsn; - gcc_assert (first_insn->first_insn_with_same_reservs); - first_insn->first_ainsn_with_given_equivalence_num = 1; - curr_insn = first_insn; - do - { - for (insn_with_same_reservs = curr_insn; - insn_with_same_reservs != NULL; - insn_with_same_reservs - = insn_with_same_reservs->next_same_reservs_insn) - insn_with_same_reservs->insn_equiv_class_num = equiv_classes_num; - curr_insn = curr_insn->next_equiv_class_insn; - } - while (curr_insn != first_insn); - equiv_classes_num++; - } - automaton->insn_equiv_classes_num = equiv_classes_num; -} - - - -/* This page contains code for creating DFA(s) and calls functions - building them. */ - - -/* The following value is used to prevent floating point overflow for - estimating an automaton bound. The value should be less DBL_MAX on - the host machine. We use here approximate minimum of maximal - double floating point value required by ANSI C standard. It - will work for non ANSI sun compiler too. */ - -#define MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND 1.0E37 - -/* The function estimate size of the single DFA used by PHR (pipeline - hazards recognizer). */ -static double -estimate_one_automaton_bound (void) -{ - decl_t decl; - double one_automaton_estimation_bound; - double root_value; - int i; - - one_automaton_estimation_bound = 1.0; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit) - { - root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num - - DECL_UNIT (decl)->min_occ_cycle_num + 1.0) - / automata_num); - if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value - > one_automaton_estimation_bound) - one_automaton_estimation_bound *= root_value; - } - } - return one_automaton_estimation_bound; -} - -/* The function compares unit declarations according to their maximal - cycle in reservations. */ -static int -compare_max_occ_cycle_nums (const void *unit_decl_1, - const void *unit_decl_2) -{ - if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num) - < (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num)) - return 1; - else if ((DECL_UNIT (*(const_decl_t const*) unit_decl_1)->max_occ_cycle_num) - == (DECL_UNIT (*(const_decl_t const*) unit_decl_2)->max_occ_cycle_num)) - return 0; - else - return -1; -} - -/* The function makes heuristic assigning automata to units. Actually - efficacy of the algorithm has been checked yet??? */ - -static void -units_to_automata_heuristic_distr (void) -{ - double estimation_bound; - int automaton_num; - int rest_units_num; - double bound_value; - unit_decl_t *unit_decls; - int i, j; - - if (description->units_num == 0) - return; - estimation_bound = estimate_one_automaton_bound (); - unit_decls = XNEWVEC (unit_decl_t, description->units_num); - - for (i = 0, j = 0; i < description->decls_num; i++) - if (description->decls[i]->mode == dm_unit) - unit_decls[j++] = DECL_UNIT (description->decls[i]); - gcc_assert (j == description->units_num); - - qsort (unit_decls, description->units_num, - sizeof (unit_decl_t), compare_max_occ_cycle_nums); - - automaton_num = 0; - bound_value = unit_decls[0]->max_occ_cycle_num; - unit_decls[0]->corresponding_automaton_num = automaton_num; - - for (i = 1; i < description->units_num; i++) - { - rest_units_num = description->units_num - i + 1; - gcc_assert (automata_num - automaton_num - 1 <= rest_units_num); - if (automaton_num < automata_num - 1 - && ((automata_num - automaton_num - 1 == rest_units_num) - || (bound_value - > (estimation_bound - / unit_decls[i]->max_occ_cycle_num)))) - { - bound_value = unit_decls[i]->max_occ_cycle_num; - automaton_num++; - } - else - bound_value *= unit_decls[i]->max_occ_cycle_num; - unit_decls[i]->corresponding_automaton_num = automaton_num; - } - gcc_assert (automaton_num == automata_num - 1); - free (unit_decls); -} - -/* The functions creates automaton insns for each automata. Automaton - insn is simply insn for given automaton which makes reservation - only of units of the automaton. */ -static void -create_ainsns (automaton_t automaton) -{ - decl_t decl; - ainsn_t first_ainsn; - ainsn_t curr_ainsn; - ainsn_t prev_ainsn; - int i; - - first_ainsn = NULL; - prev_ainsn = NULL; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - { - curr_ainsn = XCREATENODE (struct ainsn); - curr_ainsn->insn_reserv_decl = DECL_INSN_RESERV (decl); - curr_ainsn->important_p = FALSE; - curr_ainsn->next_ainsn = NULL; - if (prev_ainsn == NULL) - first_ainsn = curr_ainsn; - else - prev_ainsn->next_ainsn = curr_ainsn; - if (decl == advance_cycle_insn_decl) - automaton->advance_ainsn = curr_ainsn; - else if (decl == collapse_ndfa_insn_decl) - automaton->collapse_ainsn = curr_ainsn; - prev_ainsn = curr_ainsn; - } - } - automaton->ainsn_list = first_ainsn; -} - -/* The function assigns automata to units according to constructions - `define_automaton' in the description. */ -static void -units_to_automata_distr (void) -{ - decl_t decl; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit) - { - if (DECL_UNIT (decl)->automaton_decl == NULL - || (DECL_UNIT (decl)->automaton_decl->corresponding_automaton - == NULL)) - /* Distribute to the first automaton. */ - DECL_UNIT (decl)->corresponding_automaton_num = 0; - else - DECL_UNIT (decl)->corresponding_automaton_num - = (DECL_UNIT (decl)->automaton_decl - ->corresponding_automaton->automaton_order_num); - } - } -} - -/* The function creates DFA(s) for fast pipeline hazards recognition - after checking and simplifying IR of the description. */ -static void -create_automata (void) -{ - automaton_t curr_automaton; - automaton_t prev_automaton; - decl_t decl; - int curr_automaton_num; - int i; - - if (automata_num != 0) - { - units_to_automata_heuristic_distr (); - for (prev_automaton = NULL, curr_automaton_num = 0; - curr_automaton_num < automata_num; - curr_automaton_num++, prev_automaton = curr_automaton) - { - curr_automaton = XCREATENODE (struct automaton); - create_ainsns (curr_automaton); - curr_automaton->corresponding_automaton_decl = NULL; - curr_automaton->next_automaton = NULL; - curr_automaton->automaton_order_num = curr_automaton_num; - if (prev_automaton == NULL) - description->first_automaton = curr_automaton; - else - prev_automaton->next_automaton = curr_automaton; - } - } - else - { - curr_automaton_num = 0; - prev_automaton = NULL; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_automaton - && DECL_AUTOMATON (decl)->automaton_is_used) - { - curr_automaton = XCREATENODE (struct automaton); - create_ainsns (curr_automaton); - curr_automaton->corresponding_automaton_decl - = DECL_AUTOMATON (decl); - curr_automaton->next_automaton = NULL; - DECL_AUTOMATON (decl)->corresponding_automaton = curr_automaton; - curr_automaton->automaton_order_num = curr_automaton_num; - if (prev_automaton == NULL) - description->first_automaton = curr_automaton; - else - prev_automaton->next_automaton = curr_automaton; - curr_automaton_num++; - prev_automaton = curr_automaton; - } - } - if (curr_automaton_num == 0) - { - curr_automaton = XCREATENODE (struct automaton); - create_ainsns (curr_automaton); - curr_automaton->corresponding_automaton_decl = NULL; - curr_automaton->next_automaton = NULL; - description->first_automaton = curr_automaton; - } - units_to_automata_distr (); - } - NDFA_time = create_ticker (); - ticker_off (&NDFA_time); - NDFA_to_DFA_time = create_ticker (); - ticker_off (&NDFA_to_DFA_time); - minimize_time = create_ticker (); - ticker_off (&minimize_time); - equiv_time = create_ticker (); - ticker_off (&equiv_time); - for (curr_automaton = description->first_automaton; - curr_automaton != NULL; - curr_automaton = curr_automaton->next_automaton) - { - if (progress_flag) - { - if (curr_automaton->corresponding_automaton_decl == NULL) - fprintf (stderr, "Prepare anonymous automaton creation ... "); - else - fprintf (stderr, "Prepare automaton `%s' creation...", - curr_automaton->corresponding_automaton_decl->name); - } - create_alt_states (curr_automaton); - form_ainsn_with_same_reservs (curr_automaton); - if (progress_flag) - fprintf (stderr, "done\n"); - build_automaton (curr_automaton); - enumerate_states (curr_automaton); - ticker_on (&equiv_time); - set_insn_equiv_classes (curr_automaton); - ticker_off (&equiv_time); - } -} - - - -/* This page contains code for forming string representation of - regexp. The representation is formed on IR obstack. So you should - not work with IR obstack between regexp_representation and - finish_regexp_representation calls. */ - -/* This recursive function forms string representation of regexp - (without trailing '\0'). */ -static void -form_regexp (regexp_t regexp) -{ - int i; - - switch (regexp->mode) - { - case rm_unit: case rm_reserv: - { - const char *name = (regexp->mode == rm_unit - ? REGEXP_UNIT (regexp)->name - : REGEXP_RESERV (regexp)->name); - - obstack_grow (&irp, name, strlen (name)); - break; - } - - case rm_sequence: - for (i = 0; i < REGEXP_SEQUENCE (regexp)->regexps_num; i++) - { - if (i != 0) - obstack_1grow (&irp, ','); - form_regexp (REGEXP_SEQUENCE (regexp)->regexps [i]); - } - break; - - case rm_allof: - obstack_1grow (&irp, '('); - for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++) - { - if (i != 0) - obstack_1grow (&irp, '+'); - if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence - || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof) - obstack_1grow (&irp, '('); - form_regexp (REGEXP_ALLOF (regexp)->regexps [i]); - if (REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_sequence - || REGEXP_ALLOF (regexp)->regexps[i]->mode == rm_oneof) - obstack_1grow (&irp, ')'); - } - obstack_1grow (&irp, ')'); - break; - - case rm_oneof: - for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++) - { - if (i != 0) - obstack_1grow (&irp, '|'); - if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence) - obstack_1grow (&irp, '('); - form_regexp (REGEXP_ONEOF (regexp)->regexps [i]); - if (REGEXP_ONEOF (regexp)->regexps[i]->mode == rm_sequence) - obstack_1grow (&irp, ')'); - } - break; - - case rm_repeat: - { - char digits [30]; - - if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence - || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof - || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof) - obstack_1grow (&irp, '('); - form_regexp (REGEXP_REPEAT (regexp)->regexp); - if (REGEXP_REPEAT (regexp)->regexp->mode == rm_sequence - || REGEXP_REPEAT (regexp)->regexp->mode == rm_allof - || REGEXP_REPEAT (regexp)->regexp->mode == rm_oneof) - obstack_1grow (&irp, ')'); - sprintf (digits, "*%d", REGEXP_REPEAT (regexp)->repeat_num); - obstack_grow (&irp, digits, strlen (digits)); - break; - } - - case rm_nothing: - obstack_grow (&irp, NOTHING_NAME, strlen (NOTHING_NAME)); - break; - - default: - gcc_unreachable (); - } -} - -/* The function returns string representation of REGEXP on IR - obstack. */ -static const char * -regexp_representation (regexp_t regexp) -{ - form_regexp (regexp); - obstack_1grow (&irp, '\0'); - return (char *) obstack_base (&irp); -} - -/* The function frees memory allocated for last formed string - representation of regexp. */ -static void -finish_regexp_representation (void) -{ - int length = obstack_object_size (&irp); - - obstack_blank_fast (&irp, -length); -} - - - -/* This page contains code for output PHR (pipeline hazards recognizer). */ - -/* The function outputs minimal C type which is sufficient for - representation numbers in range min_range_value and - max_range_value. Because host machine and build machine may be - different, we use here minimal values required by ANSI C standard - instead of UCHAR_MAX, SHRT_MAX, SHRT_MIN, etc. This is a good - approximation. */ - -static void -output_range_type (FILE *f, long int min_range_value, - long int max_range_value) -{ - if (min_range_value >= 0 && max_range_value <= 255) - fprintf (f, "unsigned char"); - else if (min_range_value >= -127 && max_range_value <= 127) - fprintf (f, "signed char"); - else if (min_range_value >= 0 && max_range_value <= 65535) - fprintf (f, "unsigned short"); - else if (min_range_value >= -32767 && max_range_value <= 32767) - fprintf (f, "short"); - else - fprintf (f, "int"); -} - -/* The function outputs all initialization values of VECT. */ -static void -output_vect (vla_hwint_t vect) -{ - int els_on_line; - size_t vect_length = vect.length (); - size_t i; - - els_on_line = 1; - if (vect_length == 0) - fputs ("0 /* This is dummy el because the vect is empty */", output_file); - else - for (i = 0; i < vect_length; i++) - { - fprintf (output_file, "%5ld", (long) vect[i]); - if (els_on_line == 10) - { - els_on_line = 0; - fputs (",\n", output_file); - } - else if (i < vect_length-1) - fputs (", ", output_file); - els_on_line++; - } -} - -/* The following is name of the structure which represents DFA(s) for - PHR. */ -#define CHIP_NAME "DFA_chip" - -/* The following is name of member which represents state of a DFA for - PHR. */ -static void -output_chip_member_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "automaton_state_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_automaton_state", - automaton->corresponding_automaton_decl->name); -} - -/* The following is name of temporary variable which stores state of a - DFA for PHR. */ -static void -output_temp_chip_member_name (FILE *f, automaton_t automaton) -{ - fprintf (f, "_"); - output_chip_member_name (f, automaton); -} - -/* This is name of macro value which is code of pseudo_insns - representing advancing cpu cycle and collapsing the NDFA. - Its value is used as internal code unknown insn. */ -#define ADVANCE_CYCLE_VALUE_NAME "DFA__ADVANCE_CYCLE" -#define COLLAPSE_NDFA_VALUE_NAME "NDFA__COLLAPSE" - -/* Output name of translate vector for given automaton. */ -static void -output_translate_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "translate_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_translate", automaton->corresponding_automaton_decl->name); -} - -/* Output name for simple transition table representation. */ -static void -output_trans_full_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "transitions_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_transitions", - automaton->corresponding_automaton_decl->name); -} - -/* Output name of comb vector of the transition table for given - automaton. */ -static void -output_trans_comb_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "transitions_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_transitions", - automaton->corresponding_automaton_decl->name); -} - -/* Output name of check vector of the transition table for given - automaton. */ -static void -output_trans_check_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "check_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_check", automaton->corresponding_automaton_decl->name); -} - -/* Output name of base vector of the transition table for given - automaton. */ -static void -output_trans_base_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "base_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_base", automaton->corresponding_automaton_decl->name); -} - -/* Output name of simple min issue delay table representation. */ -static void -output_min_issue_delay_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_min_issue_delay", - automaton->corresponding_automaton_decl->name); -} - -/* Output name of deadlock vector for given automaton. */ -static void -output_dead_lock_vect_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "dead_lock_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_dead_lock", automaton->corresponding_automaton_decl->name); -} - -/* Output name of reserved units table for AUTOMATON into file F. */ -static void -output_reserved_units_table_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "reserved_units_%d", automaton->automaton_order_num); - else - fprintf (f, "%s_reserved_units", - automaton->corresponding_automaton_decl->name); -} - -/* Name of the PHR interface macro. */ -#define CPU_UNITS_QUERY_MACRO_NAME "CPU_UNITS_QUERY" - -/* Names of an internal functions: */ -#define INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME "internal_min_issue_delay" - -/* This is external type of DFA(s) state. */ -#define STATE_TYPE_NAME "state_t" - -#define INTERNAL_TRANSITION_FUNC_NAME "internal_state_transition" - -#define INTERNAL_RESET_FUNC_NAME "internal_reset" - -#define INTERNAL_DEAD_LOCK_FUNC_NAME "internal_state_dead_lock_p" - -#define INTERNAL_INSN_LATENCY_FUNC_NAME "internal_insn_latency" - -/* Name of cache of insn dfa codes. */ -#define DFA_INSN_CODES_VARIABLE_NAME "dfa_insn_codes" - -/* Name of length of cache of insn dfa codes. */ -#define DFA_INSN_CODES_LENGTH_VARIABLE_NAME "dfa_insn_codes_length" - -/* Names of the PHR interface functions: */ -#define SIZE_FUNC_NAME "state_size" - -#define TRANSITION_FUNC_NAME "state_transition" - -#define MIN_ISSUE_DELAY_FUNC_NAME "min_issue_delay" - -#define MIN_INSN_CONFLICT_DELAY_FUNC_NAME "min_insn_conflict_delay" - -#define DEAD_LOCK_FUNC_NAME "state_dead_lock_p" - -#define RESET_FUNC_NAME "state_reset" - -#define INSN_LATENCY_FUNC_NAME "insn_latency" - -#define PRINT_RESERVATION_FUNC_NAME "print_reservation" - -#define GET_CPU_UNIT_CODE_FUNC_NAME "get_cpu_unit_code" - -#define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p" - -#define INSN_HAS_DFA_RESERVATION_P_FUNC_NAME "insn_has_dfa_reservation_p" - -#define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache" - -#define DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME "dfa_clear_single_insn_cache" - -#define DFA_START_FUNC_NAME "dfa_start" - -#define DFA_FINISH_FUNC_NAME "dfa_finish" - -/* Names of parameters of the PHR interface functions. */ -#define STATE_NAME "state" - -#define INSN_PARAMETER_NAME "insn" - -#define INSN2_PARAMETER_NAME "insn2" - -#define CHIP_PARAMETER_NAME "chip" - -#define FILE_PARAMETER_NAME "f" - -#define CPU_UNIT_NAME_PARAMETER_NAME "cpu_unit_name" - -#define CPU_CODE_PARAMETER_NAME "cpu_unit_code" - -/* Names of the variables whose values are internal insn code of rtx - insn. */ -#define INTERNAL_INSN_CODE_NAME "insn_code" - -#define INTERNAL_INSN2_CODE_NAME "insn2_code" - -/* Names of temporary variables in some functions. */ -#define TEMPORARY_VARIABLE_NAME "temp" - -#define I_VARIABLE_NAME "i" - -/* Name of result variable in some functions. */ -#define RESULT_VARIABLE_NAME "res" - -/* Name of function (attribute) to translate insn into internal insn - code. */ -#define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code" - -/* Name of function (attribute) to translate insn into internal insn - code with caching. */ -#define DFA_INSN_CODE_FUNC_NAME "dfa_insn_code" - -/* Output C type which is used for representation of codes of states - of AUTOMATON. */ -static void -output_state_member_type (FILE *f, automaton_t automaton) -{ - output_range_type (f, 0, automaton->achieved_states_num); -} - -/* Output definition of the structure representing current DFA(s) - state(s). */ -static void -output_chip_definitions (void) -{ - automaton_t automaton; - - fprintf (output_file, "struct %s\n{\n", CHIP_NAME); - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - fprintf (output_file, " "); - output_state_member_type (output_file, automaton); - fprintf (output_file, " "); - output_chip_member_name (output_file, automaton); - fprintf (output_file, ";\n"); - } - fprintf (output_file, "};\n\n"); -#if 0 - fprintf (output_file, "static struct %s %s;\n\n", CHIP_NAME, CHIP_NAME); -#endif -} - - -/* The function outputs translate vector of internal insn code into - insn equivalence class number. The equivalence class number is - used to access to table and vectors representing DFA(s). */ -static void -output_translate_vect (automaton_t automaton) -{ - ainsn_t ainsn; - int insn_value; - vla_hwint_t translate_vect; - - translate_vect.create (description->insns_num); - - for (insn_value = 0; insn_value < description->insns_num; insn_value++) - /* Undefined value */ - translate_vect.quick_push (automaton->insn_equiv_classes_num); - - for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn) - translate_vect[ainsn->insn_reserv_decl->insn_num] = - ainsn->insn_equiv_class_num; - - fprintf (output_file, - "/* Vector translating external insn codes to internal ones.*/\n"); - fprintf (output_file, "static const "); - output_range_type (output_file, 0, automaton->insn_equiv_classes_num); - fprintf (output_file, " "); - output_translate_vect_name (output_file, automaton); - fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); - output_vect (translate_vect); - fprintf (output_file, "};\n\n"); - translate_vect.release (); -} - -/* The value in a table state x ainsn -> something which represents - undefined value. */ -static int undefined_vect_el_value; - -/* The following function returns nonzero value if the best - representation of the table is comb vector. */ -static int -comb_vect_p (state_ainsn_table_t tab) -{ - if (no_comb_flag) - return false; - return (2 * tab->full_vect.length () > 5 * tab->comb_vect.length ()); -} - -/* The following function creates new table for AUTOMATON. */ -static state_ainsn_table_t -create_state_ainsn_table (automaton_t automaton) -{ - state_ainsn_table_t tab; - int full_vect_length; - int i; - - tab = XCREATENODE (struct state_ainsn_table); - tab->automaton = automaton; - - tab->comb_vect.create (10000); - tab->check_vect.create (10000); - - tab->base_vect.create (0); - tab->base_vect.safe_grow (automaton->achieved_states_num, true); - - full_vect_length = (automaton->insn_equiv_classes_num - * automaton->achieved_states_num); - tab->full_vect.create (full_vect_length); - for (i = 0; i < full_vect_length; i++) - tab->full_vect.quick_push (undefined_vect_el_value); - - tab->min_base_vect_el_value = 0; - tab->max_base_vect_el_value = 0; - tab->min_comb_vect_el_value = 0; - tab->max_comb_vect_el_value = 0; - return tab; -} - -/* The following function outputs the best C representation of the - table TAB of given TABLE_NAME. */ -static void -output_state_ainsn_table (state_ainsn_table_t tab, const char *table_name, - void (*output_full_vect_name_func) (FILE *, automaton_t), - void (*output_comb_vect_name_func) (FILE *, automaton_t), - void (*output_check_vect_name_func) (FILE *, automaton_t), - void (*output_base_vect_name_func) (FILE *, automaton_t)) -{ - if (!comb_vect_p (tab)) - { - fprintf (output_file, "/* Vector for %s. */\n", table_name); - fprintf (output_file, "static const "); - output_range_type (output_file, tab->min_comb_vect_el_value, - tab->max_comb_vect_el_value); - fprintf (output_file, " "); - (*output_full_vect_name_func) (output_file, tab->automaton); - fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); - output_vect (tab->full_vect); - fprintf (output_file, "};\n\n"); - } - else - { - fprintf (output_file, "/* Comb vector for %s. */\n", table_name); - fprintf (output_file, "static const "); - output_range_type (output_file, tab->min_comb_vect_el_value, - tab->max_comb_vect_el_value); - fprintf (output_file, " "); - (*output_comb_vect_name_func) (output_file, tab->automaton); - fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); - output_vect (tab->comb_vect); - fprintf (output_file, "};\n\n"); - fprintf (output_file, "/* Check vector for %s. */\n", table_name); - fprintf (output_file, "static const "); - output_range_type (output_file, 0, tab->automaton->achieved_states_num); - fprintf (output_file, " "); - (*output_check_vect_name_func) (output_file, tab->automaton); - fprintf (output_file, "[] = {\n"); - output_vect (tab->check_vect); - fprintf (output_file, "};\n\n"); - fprintf (output_file, "/* Base vector for %s. */\n", table_name); - fprintf (output_file, "static const "); - output_range_type (output_file, tab->min_base_vect_el_value, - tab->max_base_vect_el_value); - fprintf (output_file, " "); - (*output_base_vect_name_func) (output_file, tab->automaton); - fprintf (output_file, "[] = {\n"); - output_vect (tab->base_vect); - fprintf (output_file, "};\n\n"); - } -} - -/* The following function adds vector VECT to table TAB as its line - with number VECT_NUM. */ -static void -add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect) -{ - int vect_length; - size_t real_vect_length; - int comb_vect_index; - int comb_vect_els_num; - int vect_index; - int first_unempty_vect_index; - int additional_els_num; - int no_state_value; - vect_el_t vect_el; - int i; - unsigned long vect_mask, comb_vect_mask; - - vect_length = vect.length (); - gcc_assert (vect_length); - gcc_assert (vect.last () != undefined_vect_el_value); - real_vect_length = tab->automaton->insn_equiv_classes_num; - /* Form full vector in the table: */ - { - size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num; - if (tab->full_vect.length () < full_base + vect_length) - tab->full_vect.safe_grow (full_base + vect_length, true); - for (i = 0; i < vect_length; i++) - tab->full_vect[full_base + i] = vect[i]; - } - - /* The comb_vect min/max values are also used for the full vector, so - compute them now. */ - for (vect_index = 0; vect_index < vect_length; vect_index++) - if (vect[vect_index] != undefined_vect_el_value) - { - vect_el_t x = vect[vect_index]; - gcc_assert (x >= 0); - if (tab->max_comb_vect_el_value < x) - tab->max_comb_vect_el_value = x; - if (tab->min_comb_vect_el_value > x) - tab->min_comb_vect_el_value = x; - } - if (no_comb_flag) - return; - - /* Form comb vector in the table: */ - gcc_assert (tab->comb_vect.length () == tab->check_vect.length ()); - - comb_vect_els_num = tab->comb_vect.length (); - for (first_unempty_vect_index = 0; - first_unempty_vect_index < vect_length; - first_unempty_vect_index++) - if (vect[first_unempty_vect_index] - != undefined_vect_el_value) - break; - - /* Search for the place in comb vect for the inserted vect. */ - - /* Slow case. */ - if (vect_length - first_unempty_vect_index >= SIZEOF_LONG * CHAR_BIT) - { - for (comb_vect_index = 0; - comb_vect_index < comb_vect_els_num; - comb_vect_index++) - { - for (vect_index = first_unempty_vect_index; - vect_index < vect_length - && vect_index + comb_vect_index < comb_vect_els_num; - vect_index++) - if (vect[vect_index] - != undefined_vect_el_value - && (tab->comb_vect[vect_index + comb_vect_index] - != undefined_vect_el_value)) - break; - if (vect_index >= vect_length - || vect_index + comb_vect_index >= comb_vect_els_num) - break; - } - goto found; - } - - /* Fast case. */ - vect_mask = 0; - for (vect_index = first_unempty_vect_index; - vect_index < vect_length; - vect_index++) - { - vect_mask = vect_mask << 1; - if (vect[vect_index] != undefined_vect_el_value) - vect_mask |= 1; - } - - /* Search for the place in comb vect for the inserted vect. */ - comb_vect_index = 0; - if (comb_vect_els_num == 0) - goto found; - - comb_vect_mask = 0; - for (vect_index = first_unempty_vect_index; - vect_index < vect_length && vect_index < comb_vect_els_num; - vect_index++) - { - comb_vect_mask <<= 1; - if (vect_index + comb_vect_index < comb_vect_els_num - && tab->comb_vect[vect_index + comb_vect_index] - != undefined_vect_el_value) - comb_vect_mask |= 1; - } - if ((vect_mask & comb_vect_mask) == 0) - goto found; - - for (comb_vect_index = 1, i = vect_length; i < comb_vect_els_num; - comb_vect_index++, i++) - { - comb_vect_mask = (comb_vect_mask << 1) | 1; - comb_vect_mask ^= (tab->comb_vect[i] - == undefined_vect_el_value); - if ((vect_mask & comb_vect_mask) == 0) - goto found; - } - for ( ; comb_vect_index < comb_vect_els_num; comb_vect_index++) - { - comb_vect_mask <<= 1; - if ((vect_mask & comb_vect_mask) == 0) - goto found; - } - - found: - /* Slot was found. */ - additional_els_num = comb_vect_index + real_vect_length - comb_vect_els_num; - if (additional_els_num < 0) - additional_els_num = 0; - /* Expand comb and check vectors. */ - vect_el = undefined_vect_el_value; - no_state_value = tab->automaton->achieved_states_num; - while (additional_els_num > 0) - { - tab->comb_vect.safe_push (vect_el); - tab->check_vect.safe_push (no_state_value); - additional_els_num--; - } - gcc_assert (tab->comb_vect.length () - >= comb_vect_index + real_vect_length); - /* Fill comb and check vectors. */ - for (vect_index = 0; vect_index < vect_length; vect_index++) - if (vect[vect_index] != undefined_vect_el_value) - { - vect_el_t x = vect[vect_index]; - gcc_assert (tab->comb_vect[comb_vect_index + vect_index] - == undefined_vect_el_value); - gcc_assert (x >= 0); - tab->comb_vect[comb_vect_index + vect_index] = x; - tab->check_vect[comb_vect_index + vect_index] = vect_num; - } - if (tab->max_comb_vect_el_value < undefined_vect_el_value) - tab->max_comb_vect_el_value = undefined_vect_el_value; - if (tab->min_comb_vect_el_value > undefined_vect_el_value) - tab->min_comb_vect_el_value = undefined_vect_el_value; - if (tab->max_base_vect_el_value < comb_vect_index) - tab->max_base_vect_el_value = comb_vect_index; - if (tab->min_base_vect_el_value > comb_vect_index) - tab->min_base_vect_el_value = comb_vect_index; - - tab->base_vect[vect_num] = comb_vect_index; -} - -/* Return number of out arcs of STATE. */ -static int -out_state_arcs_num (const_state_t state) -{ - int result; - arc_t arc; - - result = 0; - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - { - gcc_assert (arc->insn); - if (arc->insn->first_ainsn_with_given_equivalence_num) - result++; - } - return result; -} - -/* Compare number of possible transitions from the states. */ -static int -compare_transition_els_num (const void *state_ptr_1, - const void *state_ptr_2) -{ - const int transition_els_num_1 - = out_state_arcs_num (*(const_state_t const*) state_ptr_1); - const int transition_els_num_2 - = out_state_arcs_num (*(const_state_t const*) state_ptr_2); - - if (transition_els_num_1 < transition_els_num_2) - return 1; - else if (transition_els_num_1 == transition_els_num_2) - return 0; - else - return -1; -} - -/* The function adds element EL_VALUE to vector VECT for a table state - x AINSN. */ -static void -add_vect_el (vla_hwint_t &vect, ainsn_t ainsn, int el_value) -{ - int equiv_class_num; - int vect_index; - - gcc_assert (ainsn); - equiv_class_num = ainsn->insn_equiv_class_num; - for (vect_index = vect.length (); - vect_index <= equiv_class_num; - vect_index++) - vect.safe_push (undefined_vect_el_value); - vect[equiv_class_num] = el_value; -} - -/* This is for forming vector of states of an automaton. */ -static vec<state_t> output_states_vect; - -/* The function is called by function pass_states. The function adds - STATE to `output_states_vect'. */ -static void -add_states_vect_el (state_t state) -{ - output_states_vect.safe_push (state); -} - -/* Form and output vectors (comb, check, base or full vector) - representing transition table of AUTOMATON. */ -static void -output_trans_table (automaton_t automaton) -{ - size_t i; - arc_t arc; - vla_hwint_t transition_vect = vla_hwint_t (); - - undefined_vect_el_value = automaton->achieved_states_num; - automaton->trans_table = create_state_ainsn_table (automaton); - /* Create vect of pointers to states ordered by num of transitions - from the state (state with the maximum num is the first). */ - output_states_vect.create (0); - pass_states (automaton, add_states_vect_el); - output_states_vect.qsort (compare_transition_els_num); - - for (i = 0; i < output_states_vect.length (); i++) - { - transition_vect.truncate (0); - for (arc = first_out_arc (output_states_vect[i]); - arc != NULL; - arc = next_out_arc (arc)) - { - gcc_assert (arc->insn); - if (arc->insn->first_ainsn_with_given_equivalence_num) - add_vect_el (transition_vect, arc->insn, - arc->to_state->order_state_num); - } - add_vect (automaton->trans_table, - output_states_vect[i]->order_state_num, - transition_vect); - } - output_state_ainsn_table - (automaton->trans_table, "state transitions", - output_trans_full_vect_name, output_trans_comb_vect_name, - output_trans_check_vect_name, output_trans_base_vect_name); - - output_states_vect.release (); - transition_vect.release (); -} - -/* Form and output vectors representing minimal issue delay table of - AUTOMATON. The table is state x ainsn -> minimal issue delay of - the ainsn. */ -static void -output_min_issue_delay_table (automaton_t automaton) -{ - vla_hwint_t min_issue_delay_vect; - vla_hwint_t compressed_min_issue_delay_vect; - ainsn_t ainsn; - size_t i; - size_t min_issue_delay_len, compressed_min_issue_delay_len; - size_t cfactor; - int changed; - - /* Create vect of pointers to states ordered by num of transitions - from the state (state with the maximum num is the first). */ - output_states_vect.create (0); - pass_states (automaton, add_states_vect_el); - - min_issue_delay_len = (output_states_vect.length () - * automaton->insn_equiv_classes_num); - min_issue_delay_vect.create (min_issue_delay_len); - for (i = 0; i < min_issue_delay_len; i++) - min_issue_delay_vect.quick_push (-1); - - automaton->max_min_delay = 0; - - do - { - size_t state_no; - - changed = 0; - - for (state_no = 0; state_no < output_states_vect.length (); - state_no++) - { - state_t s = output_states_vect[state_no]; - arc_t arc; - - for (arc = first_out_arc (s); arc; arc = next_out_arc (arc)) - { - int k; - - size_t asn = s->order_state_num - * automaton->insn_equiv_classes_num - + arc->insn->insn_equiv_class_num; - - if (min_issue_delay_vect[asn]) - { - min_issue_delay_vect[asn] = (vect_el_t) 0; - changed = 1; - } - - for (k = 0; k < automaton->insn_equiv_classes_num; k++) - { - size_t n0, n1; - vect_el_t delay0, delay1; - - n0 = s->order_state_num - * automaton->insn_equiv_classes_num - + k; - n1 = arc->to_state->order_state_num - * automaton->insn_equiv_classes_num - + k; - delay0 = min_issue_delay_vect[n0]; - delay1 = min_issue_delay_vect[n1]; - if (delay1 != -1) - { - if (arc->insn->insn_reserv_decl - == DECL_INSN_RESERV (advance_cycle_insn_decl)) - delay1++; - if (delay1 < delay0 || delay0 == -1) - { - min_issue_delay_vect[n0] = delay1; - changed = 1; - } - } - } - } - } - } - while (changed); - - automaton->max_min_delay = 0; - - for (ainsn = automaton->ainsn_list; ainsn; ainsn = ainsn->next_ainsn) - if (ainsn->first_ainsn_with_given_equivalence_num) - { - for (i = 0; i < output_states_vect.length (); i++) - { - state_t s = output_states_vect[i]; - size_t np = s->order_state_num - * automaton->insn_equiv_classes_num - + ainsn->insn_equiv_class_num; - vect_el_t x = min_issue_delay_vect[np]; - - if (automaton->max_min_delay < x) - automaton->max_min_delay = x; - if (x == -1) - min_issue_delay_vect[np] = (vect_el_t) 0; - } - } - - fprintf (output_file, "/* Vector of min issue delay of insns. */\n"); - fprintf (output_file, "static const "); - output_range_type (output_file, 0, automaton->max_min_delay); - fprintf (output_file, " "); - output_min_issue_delay_vect_name (output_file, automaton); - fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n"); - /* Compress the vector. */ - if (automaton->max_min_delay < 2) - cfactor = 8; - else if (automaton->max_min_delay < 4) - cfactor = 4; - else if (automaton->max_min_delay < 16) - cfactor = 2; - else - cfactor = 1; - automaton->min_issue_delay_table_compression_factor = cfactor; - - compressed_min_issue_delay_len = (min_issue_delay_len+cfactor-1) / cfactor; - compressed_min_issue_delay_vect.create (compressed_min_issue_delay_len); - - for (i = 0; i < compressed_min_issue_delay_len; i++) - compressed_min_issue_delay_vect.quick_push (0); - - for (i = 0; i < min_issue_delay_len; i++) - { - size_t ci = i / cfactor; - vect_el_t x = min_issue_delay_vect[i]; - vect_el_t cx = compressed_min_issue_delay_vect[ci]; - - cx |= x << (8 - (i % cfactor + 1) * (8 / cfactor)); - compressed_min_issue_delay_vect[ci] = cx; - } - output_vect (compressed_min_issue_delay_vect); - fprintf (output_file, "};\n\n"); - output_states_vect.release (); - min_issue_delay_vect.release (); - compressed_min_issue_delay_vect.release (); -} - -/* Form and output vector representing the locked states of - AUTOMATON. */ -static void -output_dead_lock_vect (automaton_t automaton) -{ - size_t i; - arc_t arc; - vla_hwint_t dead_lock_vect = vla_hwint_t (); - - /* Create vect of pointers to states ordered by num of - transitions from the state (state with the maximum num is the - first). */ - automaton->locked_states = 0; - output_states_vect.create (0); - pass_states (automaton, add_states_vect_el); - - dead_lock_vect.safe_grow (output_states_vect.length (), true); - for (i = 0; i < output_states_vect.length (); i++) - { - state_t s = output_states_vect[i]; - arc = first_out_arc (s); - gcc_assert (arc); - if (next_out_arc (arc) == NULL - && (arc->insn->insn_reserv_decl - == DECL_INSN_RESERV (advance_cycle_insn_decl))) - { - dead_lock_vect[s->order_state_num] = 1; - automaton->locked_states++; - } - else - dead_lock_vect[s->order_state_num] = (vect_el_t) 0; - } - if (automaton->locked_states == 0) - return; - - fprintf (output_file, "/* Vector for locked state flags. */\n"); - fprintf (output_file, "static const "); - output_range_type (output_file, 0, 1); - fprintf (output_file, " "); - output_dead_lock_vect_name (output_file, automaton); - fprintf (output_file, "[] = {\n"); - output_vect (dead_lock_vect); - fprintf (output_file, "};\n\n"); - output_states_vect.release (); - dead_lock_vect.release (); -} - -/* Form and output vector representing reserved units of the states of - AUTOMATON. */ -static void -output_reserved_units_table (automaton_t automaton) -{ - vla_hwint_t reserved_units_table = vla_hwint_t (); - int state_byte_size; - int reserved_units_size; - size_t n; - int i; - - if (description->query_units_num == 0) - return; - - /* Create vect of pointers to states. */ - output_states_vect.create (0); - pass_states (automaton, add_states_vect_el); - /* Create vector. */ - state_byte_size = (description->query_units_num + 7) / 8; - reserved_units_size = (output_states_vect.length () - * state_byte_size); - - reserved_units_table.create (reserved_units_size); - - for (i = 0; i < reserved_units_size; i++) - reserved_units_table.quick_push (0); - for (n = 0; n < output_states_vect.length (); n++) - { - state_t s = output_states_vect[n]; - for (i = 0; i < description->units_num; i++) - if (units_array [i]->query_p - && first_cycle_unit_presence (s, i)) - { - int ri = (s->order_state_num * state_byte_size - + units_array [i]->query_num / 8); - vect_el_t x = reserved_units_table[ri]; - - x += 1 << (units_array [i]->query_num % 8); - reserved_units_table[ri] = x; - } - } - fprintf (output_file, "\n#if %s\n", CPU_UNITS_QUERY_MACRO_NAME); - fprintf (output_file, "/* Vector for reserved units of states. */\n"); - fprintf (output_file, "static const "); - output_range_type (output_file, 0, 255); - fprintf (output_file, " "); - output_reserved_units_table_name (output_file, automaton); - fprintf (output_file, "[] = {\n"); - output_vect (reserved_units_table); - fprintf (output_file, "};\n#endif /* #if %s */\n\n", - CPU_UNITS_QUERY_MACRO_NAME); - - output_states_vect.release (); - reserved_units_table.release (); -} - -/* The function outputs all tables representing DFA(s) used for fast - pipeline hazards recognition. */ -static void -output_tables (void) -{ - automaton_t automaton; - - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - output_translate_vect (automaton); - output_trans_table (automaton); - output_min_issue_delay_table (automaton); - output_dead_lock_vect (automaton); - output_reserved_units_table (automaton); - } - fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME, - DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num); - if (collapse_flag) - fprintf (output_file, "\n#define %s %d\n\n", COLLAPSE_NDFA_VALUE_NAME, - DECL_INSN_RESERV (collapse_ndfa_insn_decl)->insn_num); -} - -/* The function outputs definition and value of PHR interface variable - `max_insn_queue_index'. Its value is not less than maximal queue - length needed for the insn scheduler. */ -static void -output_max_insn_queue_index_def (void) -{ - int i, max, latency; - decl_t decl; - - max = description->max_insn_reserv_cycles; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl) - { - latency = DECL_INSN_RESERV (decl)->default_latency; - if (latency > max) - max = latency; - } - else if (decl->mode == dm_bypass) - { - latency = DECL_BYPASS (decl)->latency; - if (latency > max) - max = latency; - } - } - for (i = 0; (1 << i) <= max; i++) - ; - gcc_assert (i >= 0); - fprintf (output_file, "\nconst int max_insn_queue_index = %d;\n\n", - (1 << i) - 1); -} - -/* The function outputs switch cases for insn reservations using - function *output_automata_list_code. */ -static void -output_insn_code_cases (void (*output_automata_list_code) - (automata_list_el_t)) -{ - decl_t decl, decl2; - int i, j; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - DECL_INSN_RESERV (decl)->processed_p = FALSE; - } - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv - && !DECL_INSN_RESERV (decl)->processed_p) - { - for (j = i; j < description->decls_num; j++) - { - decl2 = description->decls [j]; - if (decl2->mode == dm_insn_reserv - && (DECL_INSN_RESERV (decl2)->important_automata_list - == DECL_INSN_RESERV (decl)->important_automata_list)) - { - DECL_INSN_RESERV (decl2)->processed_p = TRUE; - fprintf (output_file, " case %d: /* %s */\n", - DECL_INSN_RESERV (decl2)->insn_num, - DECL_INSN_RESERV (decl2)->name); - } - } - (*output_automata_list_code) - (DECL_INSN_RESERV (decl)->important_automata_list); - } - } -} - - -/* The function outputs a code for evaluation of a minimal delay of - issue of insns which have reservations in given AUTOMATA_LIST. */ -static void -output_automata_list_min_issue_delay_code (automata_list_el_t automata_list) -{ - automata_list_el_t el; - automaton_t automaton; - - for (el = automata_list; el != NULL; el = el->next_automata_list_el) - { - automaton = el->automaton; - fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME); - output_min_issue_delay_vect_name (output_file, automaton); - fprintf (output_file, - (automaton->min_issue_delay_table_compression_factor != 1 - ? " [(" : " [")); - output_translate_vect_name (output_file, automaton); - fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, "%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, automaton); - fprintf (output_file, " * %d", automaton->insn_equiv_classes_num); - if (automaton->min_issue_delay_table_compression_factor == 1) - fprintf (output_file, "];\n"); - else - { - fprintf (output_file, ") / %d];\n", - automaton->min_issue_delay_table_compression_factor); - fprintf (output_file, " %s = (%s >> (8 - ((", - TEMPORARY_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME); - output_translate_vect_name (output_file, automaton); - fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, "%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, automaton); - fprintf (output_file, " * %d)", automaton->insn_equiv_classes_num); - fprintf - (output_file, " %% %d + 1) * %d)) & %d;\n", - automaton->min_issue_delay_table_compression_factor, - 8 / automaton->min_issue_delay_table_compression_factor, - (1 << (8 / automaton->min_issue_delay_table_compression_factor)) - - 1); - } - if (el == automata_list) - fprintf (output_file, " %s = %s;\n", - RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME); - else - { - fprintf (output_file, " if (%s > %s)\n", - TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME); - fprintf (output_file, " %s = %s;\n", - RESULT_VARIABLE_NAME, TEMPORARY_VARIABLE_NAME); - } - } - fprintf (output_file, " break;\n\n"); -} - -/* Output function `internal_min_issue_delay'. */ -static void -output_internal_min_issue_delay_func (void) -{ - fprintf (output_file, - "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n", - INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME, - CHIP_NAME, CHIP_PARAMETER_NAME); - fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n", - TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME); - fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME); - output_insn_code_cases (output_automata_list_min_issue_delay_code); - fprintf (output_file, - "\n default:\n %s = -1;\n break;\n }\n", - RESULT_VARIABLE_NAME); - fprintf (output_file, " return %s;\n", RESULT_VARIABLE_NAME); - fprintf (output_file, "}\n\n"); -} - -/* The function outputs a code changing state after issue of insns - which have reservations in given AUTOMATA_LIST. */ -static void -output_automata_list_transition_code (automata_list_el_t automata_list) -{ - automata_list_el_t el, next_el; - - fprintf (output_file, " {\n"); - if (automata_list != NULL && automata_list->next_automata_list_el != NULL) - for (el = automata_list;; el = next_el) - { - next_el = el->next_automata_list_el; - if (next_el == NULL) - break; - fprintf (output_file, " "); - output_state_member_type (output_file, el->automaton); - fprintf (output_file, " "); - output_temp_chip_member_name (output_file, el->automaton); - fprintf (output_file, ";\n"); - } - for (el = automata_list; el != NULL; el = el->next_automata_list_el) - if (comb_vect_p (el->automaton->trans_table)) - { - fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME); - output_trans_base_vect_name (output_file, el->automaton); - fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, el->automaton); - fprintf (output_file, "] + "); - output_translate_vect_name (output_file, el->automaton); - fprintf (output_file, " [%s];\n", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, " if ("); - output_trans_check_vect_name (output_file, el->automaton); - fprintf (output_file, " [%s] != %s->", - TEMPORARY_VARIABLE_NAME, CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, el->automaton); - fprintf (output_file, ")\n"); - fprintf (output_file, " return %s (%s, %s);\n", - INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME, - CHIP_PARAMETER_NAME); - fprintf (output_file, " else\n"); - fprintf (output_file, " "); - if (el->next_automata_list_el != NULL) - output_temp_chip_member_name (output_file, el->automaton); - else - { - fprintf (output_file, "%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, el->automaton); - } - fprintf (output_file, " = "); - output_trans_comb_vect_name (output_file, el->automaton); - fprintf (output_file, " [%s];\n", TEMPORARY_VARIABLE_NAME); - } - else - { - fprintf (output_file, "\n %s = ", TEMPORARY_VARIABLE_NAME); - output_trans_full_vect_name (output_file, el->automaton); - fprintf (output_file, " ["); - output_translate_vect_name (output_file, el->automaton); - fprintf (output_file, " [%s] + ", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, "%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, el->automaton); - fprintf (output_file, " * %d];\n", - el->automaton->insn_equiv_classes_num); - fprintf (output_file, " if (%s >= %d)\n", - TEMPORARY_VARIABLE_NAME, el->automaton->achieved_states_num); - fprintf (output_file, " return %s (%s, %s);\n", - INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME, - CHIP_PARAMETER_NAME); - fprintf (output_file, " else\n "); - if (el->next_automata_list_el != NULL) - output_temp_chip_member_name (output_file, el->automaton); - else - { - fprintf (output_file, "%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, el->automaton); - } - fprintf (output_file, " = %s;\n", TEMPORARY_VARIABLE_NAME); - } - if (automata_list != NULL && automata_list->next_automata_list_el != NULL) - for (el = automata_list;; el = next_el) - { - next_el = el->next_automata_list_el; - if (next_el == NULL) - break; - fprintf (output_file, " %s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, el->automaton); - fprintf (output_file, " = "); - output_temp_chip_member_name (output_file, el->automaton); - fprintf (output_file, ";\n"); - } - fprintf (output_file, " return -1;\n"); - fprintf (output_file, " }\n"); -} - -/* Output function `internal_state_transition'. */ -static void -output_internal_trans_func (void) -{ - fprintf (output_file, - "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n", - INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, - CHIP_NAME, CHIP_PARAMETER_NAME); - fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME); - fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME); - output_insn_code_cases (output_automata_list_transition_code); - fprintf (output_file, "\n default:\n return -1;\n }\n"); - fprintf (output_file, "}\n\n"); -} - -/* Output code - - gcc_checking_assert (insn != 0); - insn_code = dfa_insn_code (insn); - if (insn_code >= DFA__ADVANCE_CYCLE) - return code; - - where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and - code denotes CODE. */ -static void -output_internal_insn_code_evaluation (const char *insn_name, - const char *insn_code_name, - int code) -{ - fprintf (output_file, " gcc_checking_assert (%s != 0);\n" - " %s = %s (%s);\n" - " if (%s >= %s)\n return %d;\n", - insn_name, - insn_code_name, DFA_INSN_CODE_FUNC_NAME, insn_name, - insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code); -} - - -/* This function outputs `dfa_insn_code' and its helper function - `dfa_insn_code_enlarge'. */ -static void -output_dfa_insn_code_func (void) -{ - /* Emacs c-mode gets really confused if there's a { or } in column 0 - inside a string, so don't do that. */ - fprintf (output_file, "\ -static void\n\ -dfa_insn_code_enlarge (int uid)\n\ -{\n\ - int i = %s;\n\ - %s = 2 * uid;\n\ - %s = XRESIZEVEC (int, %s,\n\ - %s);\n\ - for (; i < %s; i++)\n\ - %s[i] = -1;\n}\n\n", - DFA_INSN_CODES_LENGTH_VARIABLE_NAME, - DFA_INSN_CODES_LENGTH_VARIABLE_NAME, - DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME, - DFA_INSN_CODES_LENGTH_VARIABLE_NAME, - DFA_INSN_CODES_LENGTH_VARIABLE_NAME, - DFA_INSN_CODES_VARIABLE_NAME); - fprintf (output_file, "\ -static inline int\n%s (rtx_insn *%s)\n\ -{\n\ - int uid = INSN_UID (%s);\n\ - int %s;\n\n", - DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, - INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME); - - fprintf (output_file, - " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n", - DFA_INSN_CODES_LENGTH_VARIABLE_NAME); - fprintf (output_file, " %s = %s[uid];\n", - INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME); - fprintf (output_file, "\ - if (%s < 0)\n\ - {\n\ - %s = %s (%s);\n\ - %s[uid] = %s;\n\ - }\n", - INTERNAL_INSN_CODE_NAME, - INTERNAL_INSN_CODE_NAME, - INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, - DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME); - fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME); -} - -/* The function outputs PHR interface function `state_transition'. */ -static void -output_trans_func (void) -{ - fprintf (output_file, "int\n%s (%s %s, rtx %s)\n", - TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME, - INSN_PARAMETER_NAME); - fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, "\n if (%s == 0)\n", INSN_PARAMETER_NAME); - fprintf (output_file, " %s = %s;\n", - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - if (collapse_flag) - { - fprintf (output_file, " else if (%s == const0_rtx)\n", - INSN_PARAMETER_NAME); - fprintf (output_file, " %s = %s;\n", - INTERNAL_INSN_CODE_NAME, COLLAPSE_NDFA_VALUE_NAME); - } - fprintf (output_file, " else\n {\n"); - fprintf (output_file, " %s = %s (as_a <rtx_insn *> (%s));\n", - INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME, - INSN_PARAMETER_NAME); - fprintf (output_file, " if (%s > %s)\n return -1;\n }\n", - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - fprintf (output_file, " return %s (%s, (struct %s *) %s);\n}\n\n", - INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME); -} - -/* Output function `min_issue_delay'. */ -static void -output_min_issue_delay_func (void) -{ - fprintf (output_file, "int\n%s (%s %s, rtx_insn *%s)\n", - MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME, - INSN_PARAMETER_NAME); - fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME); - fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME, - DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME); - fprintf (output_file, " if (%s > %s)\n return 0;\n", - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - fprintf (output_file, " }\n else\n %s = %s;\n", - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - fprintf (output_file, "\n return %s (%s, (struct %s *) %s);\n", - INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME, - CHIP_NAME, STATE_NAME); - fprintf (output_file, "}\n\n"); -} - -/* Output function `internal_dead_lock'. */ -static void -output_internal_dead_lock_func (void) -{ - automaton_t automaton; - - fprintf (output_file, "static int\n%s (struct %s *ARG_UNUSED (%s))\n", - INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME); - fprintf (output_file, "{\n"); - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - if (automaton->locked_states) - { - fprintf (output_file, " if ("); - output_dead_lock_vect_name (output_file, automaton); - fprintf (output_file, " [%s->", CHIP_PARAMETER_NAME); - output_chip_member_name (output_file, automaton); - fprintf (output_file, "])\n return 1/* TRUE */;\n"); - } - fprintf (output_file, " return 0/* FALSE */;\n}\n\n"); -} - -/* The function outputs PHR interface function `state_dead_lock_p'. */ -static void -output_dead_lock_func (void) -{ - fprintf (output_file, "int\n%s (%s %s)\n", - DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME); - fprintf (output_file, "{\n return %s ((struct %s *) %s);\n}\n\n", - INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, STATE_NAME); -} - -/* Output function `internal_reset'. */ -static void -output_internal_reset_func (void) -{ - fprintf (output_file, "static inline void\n%s (struct %s *%s)\n", - INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME); - fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n", - CHIP_PARAMETER_NAME, CHIP_NAME); -} - -/* The function outputs PHR interface function `state_size'. */ -static void -output_size_func (void) -{ - fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME); - fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME); -} - -/* The function outputs PHR interface function `state_reset'. */ -static void -output_reset_func (void) -{ - fprintf (output_file, "void\n%s (%s %s)\n", - RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME); - fprintf (output_file, "{\n %s ((struct %s *) %s);\n}\n\n", INTERNAL_RESET_FUNC_NAME, - CHIP_NAME, STATE_NAME); -} - -/* Output function `min_insn_conflict_delay'. */ -static void -output_min_insn_conflict_delay_func (void) -{ - fprintf (output_file, - "int\n%s (%s %s, rtx_insn *%s, rtx_insn *%s)\n", - MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME, - STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME); - fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n", - CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME, - INTERNAL_INSN2_CODE_NAME); - output_internal_insn_code_evaluation (INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, 0); - output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME, - INTERNAL_INSN2_CODE_NAME, 0); - fprintf (output_file, " memcpy (&%s, %s, sizeof (%s));\n", - CHIP_NAME, STATE_NAME, CHIP_NAME); - fprintf (output_file, " %s (&%s);\n", INTERNAL_RESET_FUNC_NAME, CHIP_NAME); - fprintf (output_file, " transition = %s (%s, &%s);\n", - INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME); - fprintf (output_file, " gcc_assert (transition <= 0);\n"); - fprintf (output_file, " return %s (%s, &%s);\n", - INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN2_CODE_NAME, - CHIP_NAME); - fprintf (output_file, "}\n\n"); -} - -/* Output the array holding default latency values. These are used in - insn_latency and maximal_insn_latency function implementations. */ -static void -output_default_latencies (void) -{ - int i, j, col; - decl_t decl; - const char *tabletype = "unsigned char"; - - /* Find the smallest integer type that can hold all the default - latency values. */ - for (i = 0; i < description->decls_num; i++) - if (description->decls[i]->mode == dm_insn_reserv) - { - decl = description->decls[i]; - if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX - && tabletype[0] != 'i') /* Don't shrink it. */ - tabletype = "unsigned short"; - if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX) - tabletype = "int"; - } - - fprintf (output_file, " static const %s default_latencies[] =\n {", - tabletype); - - for (i = 0, j = 0, col = 7; i < description->normal_decls_num; i++) - if (description->decls[i]->mode == dm_insn_reserv) - { - if ((col = (col+1) % 8) == 0) - fputs ("\n ", output_file); - decl = description->decls[i]; - gcc_assert (j++ == DECL_INSN_RESERV (decl)->insn_num); - fprintf (output_file, "% 4d,", - DECL_INSN_RESERV (decl)->default_latency); - } - gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1)); - fputs ("\n };\n", output_file); -} - -/* Output function `internal_insn_latency'. */ -static void -output_internal_insn_latency_func (void) -{ - int i; - decl_t decl; - struct bypass_decl *bypass; - - fprintf (output_file, "static int\n" - "%s (int %s ATTRIBUTE_UNUSED, int %s ATTRIBUTE_UNUSED,\n" - "\trtx_insn *%s ATTRIBUTE_UNUSED, rtx_insn *%s ATTRIBUTE_UNUSED)\n", - INTERNAL_INSN_LATENCY_FUNC_NAME, - INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME, - INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME); - fprintf (output_file, "{\n"); - - if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0) - { - fputs (" return 0;\n}\n\n", output_file); - return; - } - - fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME); - for (i = 0; i < description->decls_num; i++) - if (description->decls[i]->mode == dm_insn_reserv - && DECL_INSN_RESERV (description->decls[i])->bypass_list) - { - decl = description->decls [i]; - fprintf (output_file, - " case %d:\n switch (%s)\n {\n", - DECL_INSN_RESERV (decl)->insn_num, - INTERNAL_INSN2_CODE_NAME); - for (bypass = DECL_INSN_RESERV (decl)->bypass_list; - bypass != NULL; - bypass = bypass->next) - { - gcc_assert (bypass->in_insn_reserv->insn_num - != (DECL_INSN_RESERV - (advance_cycle_insn_decl)->insn_num)); - fprintf (output_file, " case %d:\n", - bypass->in_insn_reserv->insn_num); - for (;;) - { - if (bypass->bypass_guard_name == NULL) - { - gcc_assert (bypass->next == NULL - || (bypass->in_insn_reserv - != bypass->next->in_insn_reserv)); - fprintf (output_file, " return %d;\n", - bypass->latency); - } - else - { - fprintf (output_file, - " if (%s (%s, %s))\n", - bypass->bypass_guard_name, INSN_PARAMETER_NAME, - INSN2_PARAMETER_NAME); - fprintf (output_file, " return %d;\n", - bypass->latency); - } - if (bypass->next == NULL - || bypass->in_insn_reserv != bypass->next->in_insn_reserv) - break; - bypass = bypass->next; - } - if (bypass->bypass_guard_name != NULL) - fprintf (output_file, " break;\n"); - } - fputs (" }\n break;\n", output_file); - } - - fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n", - INTERNAL_INSN_CODE_NAME); -} - -/* Output function `internal_maximum_insn_latency'. */ -static void -output_internal_maximal_insn_latency_func (void) -{ - decl_t decl; - struct bypass_decl *bypass; - int i; - int max; - - fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED)\n", - "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME); - fprintf (output_file, "{\n"); - - if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0) - { - fputs (" return 0;\n}\n\n", output_file); - return; - } - - fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME); - for (i = 0; i < description->decls_num; i++) - if (description->decls[i]->mode == dm_insn_reserv - && DECL_INSN_RESERV (description->decls[i])->bypass_list) - { - decl = description->decls [i]; - max = DECL_INSN_RESERV (decl)->default_latency; - fprintf (output_file, - " case %d: {", - DECL_INSN_RESERV (decl)->insn_num); - for (bypass = DECL_INSN_RESERV (decl)->bypass_list; - bypass != NULL; - bypass = bypass->next) - { - if (bypass->latency > max) - max = bypass->latency; - } - fprintf (output_file, " return %d; }\n break;\n", max); - } - - fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n", - INTERNAL_INSN_CODE_NAME); -} - -/* The function outputs PHR interface function `insn_latency'. */ -static void -output_insn_latency_func (void) -{ - fprintf (output_file, "int\n%s (rtx_insn *%s, rtx_insn *%s)\n", - INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME); - fprintf (output_file, "{\n int %s, %s;\n", - INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME); - output_internal_insn_code_evaluation (INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, 0); - output_internal_insn_code_evaluation (INSN2_PARAMETER_NAME, - INTERNAL_INSN2_CODE_NAME, 0); - fprintf (output_file, " return %s (%s, %s, %s, %s);\n}\n\n", - INTERNAL_INSN_LATENCY_FUNC_NAME, - INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME, - INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME); -} - -/* The function outputs PHR interface function `maximal_insn_latency'. */ -static void -output_maximal_insn_latency_func (void) -{ - fprintf (output_file, "int\n%s (rtx_insn *%s)\n", - "maximal_insn_latency", INSN_PARAMETER_NAME); - fprintf (output_file, "{\n int %s;\n", - INTERNAL_INSN_CODE_NAME); - output_internal_insn_code_evaluation (INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, 0); - fprintf (output_file, " return %s (%s);\n}\n\n", - "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME); -} - -/* The function outputs PHR interface function `print_reservation'. */ -static void -output_print_reservation_func (void) -{ - decl_t decl; - int i, j; - - fprintf (output_file, - "void\n%s (FILE *%s, rtx_insn *%s ATTRIBUTE_UNUSED)\n{\n", - PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME, - INSN_PARAMETER_NAME); - - if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0) - { - fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n", - NOTHING_NAME, FILE_PARAMETER_NAME); - return; - } - - - fputs (" static const char *const reservation_names[] =\n {", - output_file); - - for (i = 0, j = 0; i < description->normal_decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - { - gcc_assert (j == DECL_INSN_RESERV (decl)->insn_num); - j++; - - fprintf (output_file, "\n \"%s\",", - regexp_representation (DECL_INSN_RESERV (decl)->regexp)); - finish_regexp_representation (); - } - } - gcc_assert (j == description->insns_num - (collapse_flag ? 2 : 1)); - - fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n", - NOTHING_NAME, INTERNAL_INSN_CODE_NAME); - - fprintf (output_file, " if (%s == 0)\n %s = %s;\n", - INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - fprintf (output_file, " else\n\ - {\n\ - %s = %s (%s);\n\ - if (%s > %s)\n\ - %s = %s;\n\ - }\n", - INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME, - INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME, - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - - fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n", - INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME); -} - -/* The following function is used to sort unit declaration by their - names. */ -static int -units_cmp (const void *unit1, const void *unit2) -{ - const_unit_decl_t const u1 = *(const_unit_decl_t const*) unit1; - const_unit_decl_t const u2 = *(const_unit_decl_t const*) unit2; - - return strcmp (u1->name, u2->name); -} - -/* The following macro value is name of struct containing unit name - and unit code. */ -#define NAME_CODE_STRUCT_NAME "name_code" - -/* The following macro value is name of table of struct name_code. */ -#define NAME_CODE_TABLE_NAME "name_code_table" - -/* The following macro values are member names for struct name_code. */ -#define NAME_MEMBER_NAME "name" -#define CODE_MEMBER_NAME "code" - -/* The following macro values are local variable names for function - `get_cpu_unit_code'. */ -#define CMP_VARIABLE_NAME "cmp" -#define LOW_VARIABLE_NAME "l" -#define MIDDLE_VARIABLE_NAME "m" -#define HIGH_VARIABLE_NAME "h" - -/* The following function outputs function to obtain internal cpu unit - code by the cpu unit name. */ -static void -output_get_cpu_unit_code_func (void) -{ - int i; - unit_decl_t *units; - - fprintf (output_file, "int\n%s (const char *%s)\n", - GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME); - fprintf (output_file, "{\n struct %s {const char *%s; int %s;};\n", - NAME_CODE_STRUCT_NAME, NAME_MEMBER_NAME, CODE_MEMBER_NAME); - fprintf (output_file, " int %s, %s, %s, %s;\n", CMP_VARIABLE_NAME, - LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME); - fprintf (output_file, " static struct %s %s [] =\n {\n", - NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME); - units = XNEWVEC (unit_decl_t, description->units_num); - memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num); - qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp); - for (i = 0; i < description->units_num; i++) - if (units [i]->query_p) - fprintf (output_file, " {\"%s\", %d},\n", - units[i]->name, units[i]->query_num); - fprintf (output_file, " };\n\n"); - fprintf (output_file, " /* The following is binary search: */\n"); - fprintf (output_file, " %s = 0;\n", LOW_VARIABLE_NAME); - fprintf (output_file, " %s = sizeof (%s) / sizeof (struct %s) - 1;\n", - HIGH_VARIABLE_NAME, NAME_CODE_TABLE_NAME, NAME_CODE_STRUCT_NAME); - fprintf (output_file, " while (%s <= %s)\n {\n", - LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME); - fprintf (output_file, " %s = (%s + %s) / 2;\n", - MIDDLE_VARIABLE_NAME, LOW_VARIABLE_NAME, HIGH_VARIABLE_NAME); - fprintf (output_file, " %s = strcmp (%s, %s [%s].%s);\n", - CMP_VARIABLE_NAME, CPU_UNIT_NAME_PARAMETER_NAME, - NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, NAME_MEMBER_NAME); - fprintf (output_file, " if (%s < 0)\n", CMP_VARIABLE_NAME); - fprintf (output_file, " %s = %s - 1;\n", - HIGH_VARIABLE_NAME, MIDDLE_VARIABLE_NAME); - fprintf (output_file, " else if (%s > 0)\n", CMP_VARIABLE_NAME); - fprintf (output_file, " %s = %s + 1;\n", - LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME); - fprintf (output_file, " else\n"); - fprintf (output_file, " return %s [%s].%s;\n }\n", - NAME_CODE_TABLE_NAME, MIDDLE_VARIABLE_NAME, CODE_MEMBER_NAME); - fprintf (output_file, " return -1;\n}\n\n"); - free (units); -} - -/* The following function outputs function to check reservation of cpu - unit (its internal code will be passed as the function argument) in - given cpu state. */ -static void -output_cpu_unit_reservation_p (void) -{ - automaton_t automaton; - - fprintf (output_file, "int\n%s (%s %s, int %s)\n", - CPU_UNIT_RESERVATION_P_FUNC_NAME, - STATE_TYPE_NAME, STATE_NAME, - CPU_CODE_PARAMETER_NAME); - fprintf (output_file, "{\n gcc_assert (%s >= 0 && %s < %d);\n", - CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME, - description->query_units_num); - if (description->query_units_num > 0) - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - fprintf (output_file, " if (("); - output_reserved_units_table_name (output_file, automaton); - fprintf (output_file, " [((struct %s *) %s)->", CHIP_NAME, STATE_NAME); - output_chip_member_name (output_file, automaton); - fprintf (output_file, " * %d + %s / 8] >> (%s %% 8)) & 1)\n", - (description->query_units_num + 7) / 8, - CPU_CODE_PARAMETER_NAME, CPU_CODE_PARAMETER_NAME); - fprintf (output_file, " return 1;\n"); - } - fprintf (output_file, " return 0;\n}\n\n"); -} - -/* The following function outputs a function to check if insn - has a dfa reservation. */ -static void -output_insn_has_dfa_reservation_p (void) -{ - fprintf (output_file, - "bool\n%s (rtx_insn *%s ATTRIBUTE_UNUSED)\n{\n", - INSN_HAS_DFA_RESERVATION_P_FUNC_NAME, - INSN_PARAMETER_NAME); - - if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0) - { - fprintf (output_file, " return false;\n}\n\n"); - return; - } - - fprintf (output_file, " int %s;\n\n", INTERNAL_INSN_CODE_NAME); - - fprintf (output_file, " if (%s == 0)\n %s = %s;\n", - INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - fprintf (output_file, " else\n\ - {\n\ - %s = %s (%s);\n\ - if (%s > %s)\n\ - %s = %s;\n\ - }\n\n", - INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME, - INSN_PARAMETER_NAME, - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME, - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); - - fprintf (output_file, " return %s != %s;\n}\n\n", - INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME); -} - -/* The function outputs PHR interface functions `dfa_clean_insn_cache' - and 'dfa_clear_single_insn_cache'. */ -static void -output_dfa_clean_insn_cache_func (void) -{ - fprintf (output_file, - "void\n%s (void)\n{\n int %s;\n\n", - DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME); - fprintf (output_file, - " for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n", - I_VARIABLE_NAME, I_VARIABLE_NAME, - DFA_INSN_CODES_LENGTH_VARIABLE_NAME, I_VARIABLE_NAME, - DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME); - - fprintf (output_file, - "void\n%s (rtx_insn *%s)\n{\n int %s;\n\n", - DFA_CLEAR_SINGLE_INSN_CACHE_FUNC_NAME, INSN_PARAMETER_NAME, - I_VARIABLE_NAME); - fprintf (output_file, - " %s = INSN_UID (%s);\n if (%s < %s)\n %s [%s] = -1;\n}\n\n", - I_VARIABLE_NAME, INSN_PARAMETER_NAME, I_VARIABLE_NAME, - DFA_INSN_CODES_LENGTH_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME, - I_VARIABLE_NAME); -} - -/* The function outputs PHR interface function `dfa_start'. */ -static void -output_dfa_start_func (void) -{ - fprintf (output_file, - "void\n%s (void)\n{\n %s = get_max_uid ();\n", - DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME); - fprintf (output_file, " %s = XNEWVEC (int, %s);\n", - DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME); - fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME); -} - -/* The function outputs PHR interface function `dfa_finish'. */ -static void -output_dfa_finish_func (void) -{ - fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n", - DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME); -} - - - -/* The page contains code for output description file (readable - representation of original description and generated DFA(s). */ - -/* The function outputs string representation of IR reservation. */ -static void -output_regexp (regexp_t regexp) -{ - fprintf (output_description_file, "%s", regexp_representation (regexp)); - finish_regexp_representation (); -} - -/* Output names of units in LIST separated by comma. */ -static void -output_unit_set_el_list (unit_set_el_t list) -{ - unit_set_el_t el; - - for (el = list; el != NULL; el = el->next_unit_set_el) - { - if (el != list) - fprintf (output_description_file, ", "); - fprintf (output_description_file, "%s", el->unit_decl->name); - } -} - -/* Output patterns in LIST separated by comma. */ -static void -output_pattern_set_el_list (pattern_set_el_t list) -{ - pattern_set_el_t el; - int i; - - for (el = list; el != NULL; el = el->next_pattern_set_el) - { - if (el != list) - fprintf (output_description_file, ", "); - for (i = 0; i < el->units_num; i++) - fprintf (output_description_file, (i == 0 ? "%s" : " %s"), - el->unit_decls [i]->name); - } -} - -/* The function outputs string representation of IR define_reservation - and define_insn_reservation. */ -static void -output_description (void) -{ - decl_t decl; - int i; - - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit) - { - if (DECL_UNIT (decl)->excl_list != NULL) - { - fprintf (output_description_file, "unit %s exclusion_set: ", - DECL_UNIT (decl)->name); - output_unit_set_el_list (DECL_UNIT (decl)->excl_list); - fprintf (output_description_file, "\n"); - } - if (DECL_UNIT (decl)->presence_list != NULL) - { - fprintf (output_description_file, "unit %s presence_set: ", - DECL_UNIT (decl)->name); - output_pattern_set_el_list (DECL_UNIT (decl)->presence_list); - fprintf (output_description_file, "\n"); - } - if (DECL_UNIT (decl)->final_presence_list != NULL) - { - fprintf (output_description_file, "unit %s final_presence_set: ", - DECL_UNIT (decl)->name); - output_pattern_set_el_list - (DECL_UNIT (decl)->final_presence_list); - fprintf (output_description_file, "\n"); - } - if (DECL_UNIT (decl)->absence_list != NULL) - { - fprintf (output_description_file, "unit %s absence_set: ", - DECL_UNIT (decl)->name); - output_pattern_set_el_list (DECL_UNIT (decl)->absence_list); - fprintf (output_description_file, "\n"); - } - if (DECL_UNIT (decl)->final_absence_list != NULL) - { - fprintf (output_description_file, "unit %s final_absence_set: ", - DECL_UNIT (decl)->name); - output_pattern_set_el_list - (DECL_UNIT (decl)->final_absence_list); - fprintf (output_description_file, "\n"); - } - } - } - fprintf (output_description_file, "\n"); - for (i = 0; i < description->normal_decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_reserv) - { - fprintf (output_description_file, "reservation %s: ", - DECL_RESERV (decl)->name); - output_regexp (DECL_RESERV (decl)->regexp); - fprintf (output_description_file, "\n"); - } - else if (decl->mode == dm_insn_reserv) - { - fprintf (output_description_file, "insn reservation %s ", - DECL_INSN_RESERV (decl)->name); - print_rtl (output_description_file, - DECL_INSN_RESERV (decl)->condexp); - fprintf (output_description_file, ": "); - output_regexp (DECL_INSN_RESERV (decl)->regexp); - fprintf (output_description_file, "\n"); - } - else if (decl->mode == dm_bypass) - fprintf (output_description_file, "bypass %d %s %s\n", - DECL_BYPASS (decl)->latency, - DECL_BYPASS (decl)->out_pattern, - DECL_BYPASS (decl)->in_pattern); - } - fprintf (output_description_file, "\n\f\n"); -} - -/* The function outputs name of AUTOMATON. */ -static void -output_automaton_name (FILE *f, automaton_t automaton) -{ - if (automaton->corresponding_automaton_decl == NULL) - fprintf (f, "#%d", automaton->automaton_order_num); - else - fprintf (f, "`%s'", automaton->corresponding_automaton_decl->name); -} - -/* Maximal length of line for pretty printing into description - file. */ -#define MAX_LINE_LENGTH 70 - -/* The function outputs units name belonging to AUTOMATON. */ -static void -output_automaton_units (automaton_t automaton) -{ - decl_t decl; - const char *name; - int curr_line_length; - int there_is_an_automaton_unit; - int i; - - fprintf (output_description_file, "\n Corresponding units:\n"); - fprintf (output_description_file, " "); - curr_line_length = 4; - there_is_an_automaton_unit = 0; - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_unit - && (DECL_UNIT (decl)->corresponding_automaton_num - == automaton->automaton_order_num)) - { - there_is_an_automaton_unit = 1; - name = DECL_UNIT (decl)->name; - if (curr_line_length + strlen (name) + 1 > MAX_LINE_LENGTH ) - { - curr_line_length = strlen (name) + 4; - fprintf (output_description_file, "\n "); - } - else - { - curr_line_length += strlen (name) + 1; - fprintf (output_description_file, " "); - } - fprintf (output_description_file, "%s", name); - } - } - if (!there_is_an_automaton_unit) - fprintf (output_description_file, "<None>"); - fprintf (output_description_file, "\n\n"); -} - -/* The following variable is used for forming array of all possible cpu unit - reservations described by the current DFA state. */ -static vec<reserv_sets_t> state_reservs; - -/* The function forms `state_reservs' for STATE. */ -static void -add_state_reservs (state_t state) -{ - alt_state_t curr_alt_state; - - if (state->component_states != NULL) - for (curr_alt_state = state->component_states; - curr_alt_state != NULL; - curr_alt_state = curr_alt_state->next_sorted_alt_state) - add_state_reservs (curr_alt_state->state); - else - state_reservs.safe_push (state->reservs); -} - -/* The function outputs readable representation of all out arcs of - STATE. */ -static void -output_state_arcs (state_t state) -{ - arc_t arc; - ainsn_t ainsn; - const char *insn_name; - int curr_line_length; - - for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc)) - { - ainsn = arc->insn; - gcc_assert (ainsn->first_insn_with_same_reservs); - fprintf (output_description_file, " "); - curr_line_length = 7; - fprintf (output_description_file, "%2d: ", ainsn->insn_equiv_class_num); - do - { - insn_name = ainsn->insn_reserv_decl->name; - if (curr_line_length + strlen (insn_name) > MAX_LINE_LENGTH) - { - if (ainsn != arc->insn) - { - fprintf (output_description_file, ",\n "); - curr_line_length = strlen (insn_name) + 6; - } - else - curr_line_length += strlen (insn_name); - } - else - { - curr_line_length += strlen (insn_name); - if (ainsn != arc->insn) - { - curr_line_length += 2; - fprintf (output_description_file, ", "); - } - } - fprintf (output_description_file, "%s", insn_name); - ainsn = ainsn->next_same_reservs_insn; - } - while (ainsn != NULL); - fprintf (output_description_file, " %d \n", - arc->to_state->order_state_num); - } - fprintf (output_description_file, "\n"); -} - -/* The following function is used for sorting possible cpu unit - reservation of a DFA state. */ -static int -state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2) -{ - return reserv_sets_cmp (*(const_reserv_sets_t const*) reservs_ptr_1, - *(const_reserv_sets_t const*) reservs_ptr_2); -} - -/* The following function is used for sorting possible cpu unit - reservation of a DFA state. */ -static void -remove_state_duplicate_reservs (void) -{ - size_t i, j; - - for (i = 1, j = 0; i < state_reservs.length (); i++) - if (reserv_sets_cmp (state_reservs[j], state_reservs[i])) - { - j++; - state_reservs[j] = state_reservs[i]; - } - state_reservs.truncate (j + 1); -} - -/* The following function output readable representation of DFA(s) - state used for fast recognition of pipeline hazards. State is - described by possible (current and scheduled) cpu unit - reservations. */ -static void -output_state (state_t state) -{ - size_t i; - - state_reservs.create (0); - - fprintf (output_description_file, " State #%d", state->order_state_num); - fprintf (output_description_file, - state->new_cycle_p ? " (new cycle)\n" : "\n"); - add_state_reservs (state); - state_reservs.qsort (state_reservs_cmp); - remove_state_duplicate_reservs (); - for (i = 0; i < state_reservs.length (); i++) - { - fprintf (output_description_file, " "); - output_reserv_sets (output_description_file, state_reservs[i]); - fprintf (output_description_file, "\n"); - } - fprintf (output_description_file, "\n"); - output_state_arcs (state); - state_reservs.release (); -} - -/* The following function output readable representation of - DFAs used for fast recognition of pipeline hazards. */ -static void -output_automaton_descriptions (void) -{ - automaton_t automaton; - - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - fprintf (output_description_file, "\nAutomaton "); - output_automaton_name (output_description_file, automaton); - fprintf (output_description_file, "\n"); - output_automaton_units (automaton); - pass_states (automaton, output_state); - } -} - - - -/* The page contains top level function for generation DFA(s) used for - PHR. */ - -/* The function outputs statistics about work of different phases of - DFA generator. */ -static void -output_statistics (FILE *f) -{ - automaton_t automaton; - int states_num; -#ifndef NDEBUG - int transition_comb_vect_els = 0; - int transition_full_vect_els = 0; - int min_issue_delay_vect_els = 0; - int locked_states = 0; -#endif - - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - fprintf (f, "\nAutomaton "); - output_automaton_name (f, automaton); - fprintf (f, "\n %5d NDFA states, %5d NDFA arcs\n", - automaton->NDFA_states_num, automaton->NDFA_arcs_num); - fprintf (f, " %5d DFA states, %5d DFA arcs\n", - automaton->DFA_states_num, automaton->DFA_arcs_num); - states_num = automaton->DFA_states_num; - if (!no_minimization_flag) - { - fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n", - automaton->minimal_DFA_states_num, - automaton->minimal_DFA_arcs_num); - states_num = automaton->minimal_DFA_states_num; - } - fprintf (f, " %5d all insns %5d insn equivalence classes\n", - description->insns_num, automaton->insn_equiv_classes_num); - fprintf (f, " %d locked states\n", automaton->locked_states); -#ifndef NDEBUG - fprintf - (f, "%5ld transition comb vector els, %5ld trans table els: %s\n", - (long) automaton->trans_table->comb_vect.length (), - (long) automaton->trans_table->full_vect.length (), - (comb_vect_p (automaton->trans_table) - ? "use comb vect" : "use simple vect")); - fprintf - (f, "%5ld min delay table els, compression factor %d\n", - (long) states_num * automaton->insn_equiv_classes_num, - automaton->min_issue_delay_table_compression_factor); - transition_comb_vect_els - += automaton->trans_table->comb_vect.length (); - transition_full_vect_els - += automaton->trans_table->full_vect.length (); - min_issue_delay_vect_els - += states_num * automaton->insn_equiv_classes_num; - locked_states - += automaton->locked_states; -#endif - } -#ifndef NDEBUG - fprintf (f, "\n%5d all allocated states, %5d all allocated arcs\n", - allocated_states_num, allocated_arcs_num); - fprintf (f, "%5d all allocated alternative states\n", - allocated_alt_states_num); - fprintf (f, "%5d all transition comb vector els, %5d all trans table els\n", - transition_comb_vect_els, transition_full_vect_els); - fprintf (f, "%5d all min delay table els\n", min_issue_delay_vect_els); - fprintf (f, "%5d all locked states\n", locked_states); -#endif -} - -/* The function output times of work of different phases of DFA - generator. */ -static void -output_time_statistics (FILE *f) -{ - fprintf (f, "\n transformation: "); - print_active_time (f, transform_time); - fprintf (f, (!ndfa_flag ? ", building DFA: " : ", building NDFA: ")); - print_active_time (f, NDFA_time); - if (ndfa_flag) - { - fprintf (f, ", NDFA -> DFA: "); - print_active_time (f, NDFA_to_DFA_time); - } - fprintf (f, "\n DFA minimization: "); - print_active_time (f, minimize_time); - fprintf (f, ", making insn equivalence: "); - print_active_time (f, equiv_time); - fprintf (f, "\n all automaton generation: "); - print_active_time (f, automaton_generation_time); - fprintf (f, ", output: "); - print_active_time (f, output_time); - fprintf (f, "\n"); -} - -/* The function generates DFA (deterministic finite state automaton) - for fast recognition of pipeline hazards. No errors during - checking must be fixed before this function call. */ -static void -generate (void) -{ - automata_num = split_argument; - if (description->units_num < automata_num) - automata_num = description->units_num; - initiate_states (); - initiate_arcs (); - initiate_automata_lists (); - initiate_pass_states (); - initiate_excl_sets (); - initiate_presence_absence_pattern_sets (); - automaton_generation_time = create_ticker (); - create_automata (); - ticker_off (&automaton_generation_time); -} - - - -/* This page mainly contains top level functions of pipeline hazards - description translator. */ - -/* The following macro value is suffix of name of description file of - pipeline hazards description translator. */ -#define STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX ".dfa" - -/* The function returns suffix of given file name. The returned - string cannot be changed. */ -static const char * -file_name_suffix (const char *file_name) -{ - const char *last_period; - - for (last_period = NULL; *file_name != '\0'; file_name++) - if (*file_name == '.') - last_period = file_name; - return (last_period == NULL ? file_name : last_period); -} - -/* The function returns base name of given file name, i.e. pointer to - first char after last `/' (or `\' for WIN32) in given file name, - given file name itself if the directory name is absent. The - returned string cannot be changed. */ -static const char * -base_file_name (const char *file_name) -{ - int directory_name_length; - - directory_name_length = strlen (file_name); -#ifdef WIN32 - while (directory_name_length >= 0 && file_name[directory_name_length] != '/' - && file_name[directory_name_length] != '\\') -#else - while (directory_name_length >= 0 && file_name[directory_name_length] != '/') -#endif - directory_name_length--; - return file_name + directory_name_length + 1; -} - -/* A function passed as argument to init_rtx_reader_args_cb. It parses the - options available for genautomata. Returns true if the option was - recognized. */ -static bool -parse_automata_opt (const char *str) -{ - if (strcmp (str, NO_MINIMIZATION_OPTION) == 0) - no_minimization_flag = 1; - else if (strcmp (str, TIME_OPTION) == 0) - time_flag = 1; - else if (strcmp (str, STATS_OPTION) == 0) - stats_flag = 1; - else if (strcmp (str, V_OPTION) == 0) - v_flag = 1; - else if (strcmp (str, W_OPTION) == 0) - w_flag = 1; - else if (strcmp (str, NDFA_OPTION) == 0) - ndfa_flag = 1; - else if (strcmp (str, COLLAPSE_OPTION) == 0) - collapse_flag = 1; - else if (strcmp (str, PROGRESS_OPTION) == 0) - progress_flag = 1; - else if (strcmp (str, "-split") == 0) - { - fatal ("option `-split' has not been implemented yet\n"); - /* split_argument = atoi (argument_vect [i + 1]); */ - } - else - return false; - - return true; -} - -/* The following is top level function to initialize the work of - pipeline hazards description translator. */ -static void -initiate_automaton_gen (const char **argv) -{ - const char *base_name; - - /* Initialize IR storage. */ - obstack_init (&irp); - initiate_automaton_decl_table (); - initiate_insn_decl_table (); - initiate_decl_table (); - output_file = stdout; - output_description_file = NULL; - base_name = base_file_name (argv[1]); - obstack_grow (&irp, base_name, - strlen (base_name) - strlen (file_name_suffix (base_name))); - obstack_grow (&irp, STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX, - strlen (STANDARD_OUTPUT_DESCRIPTION_FILE_SUFFIX) + 1); - obstack_1grow (&irp, '\0'); - output_description_file_name = (char *) obstack_base (&irp); - obstack_finish (&irp); -} - -/* The following function checks existence at least one arc marked by - each insn. */ -static void -check_automata_insn_issues (void) -{ - automaton_t automaton; - ainsn_t ainsn, reserv_ainsn; - - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - for (ainsn = automaton->ainsn_list; - ainsn != NULL; - ainsn = ainsn->next_ainsn) - if (ainsn->first_insn_with_same_reservs && !ainsn->arc_exists_p - && ainsn != automaton->collapse_ainsn) - { - for (reserv_ainsn = ainsn; - reserv_ainsn != NULL; - reserv_ainsn = reserv_ainsn->next_same_reservs_insn) - if (automaton->corresponding_automaton_decl != NULL) - { - if (!w_flag) - error ("Automaton `%s': Insn `%s' will never be issued", - automaton->corresponding_automaton_decl->name, - reserv_ainsn->insn_reserv_decl->name); - else - warning ("Automaton `%s': Insn `%s' will never be issued", - automaton->corresponding_automaton_decl->name, - reserv_ainsn->insn_reserv_decl->name); - } - else - { - if (!w_flag) - error ("Insn `%s' will never be issued", - reserv_ainsn->insn_reserv_decl->name); - else - warning ("Insn `%s' will never be issued", - reserv_ainsn->insn_reserv_decl->name); - } - } - } -} - -/* The following vla is used for storing pointers to all achieved - states. */ -static vec<state_t> automaton_states; - -/* This function is called by function pass_states to add an achieved - STATE. */ -static void -add_automaton_state (state_t state) -{ - automaton_states.safe_push (state); -} - -/* The following function forms list of important automata (whose - states may be changed after the insn issue) for each insn. */ -static void -form_important_insn_automata_lists (void) -{ - automaton_t automaton; - decl_t decl; - ainsn_t ainsn; - arc_t arc; - int i; - size_t n; - - automaton_states.create (0); - /* Mark important ainsns. */ - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - { - automaton_states.truncate (0); - pass_states (automaton, add_automaton_state); - for (n = 0; n < automaton_states.length (); n++) - { - state_t s = automaton_states[n]; - for (arc = first_out_arc (s); - arc != NULL; - arc = next_out_arc (arc)) - if (arc->to_state != s) - { - gcc_assert (arc->insn->first_insn_with_same_reservs); - for (ainsn = arc->insn; - ainsn != NULL; - ainsn = ainsn->next_same_reservs_insn) - ainsn->important_p = TRUE; - } - } - } - automaton_states.release (); - - /* Create automata sets for the insns. */ - for (i = 0; i < description->decls_num; i++) - { - decl = description->decls [i]; - if (decl->mode == dm_insn_reserv) - { - automata_list_start (); - for (automaton = description->first_automaton; - automaton != NULL; - automaton = automaton->next_automaton) - for (ainsn = automaton->ainsn_list; - ainsn != NULL; - ainsn = ainsn->next_ainsn) - if (ainsn->important_p - && ainsn->insn_reserv_decl == DECL_INSN_RESERV (decl)) - { - automata_list_add (automaton); - break; - } - DECL_INSN_RESERV (decl)->important_automata_list - = automata_list_finish (); - } - } -} - - -/* The following is top level function to generate automat(a,on) for - fast recognition of pipeline hazards. */ -static void -expand_automata (void) -{ - int i; - - description = XCREATENODEVAR (struct description, - sizeof (struct description) - /* Two entries for special insns. */ - + sizeof (decl_t) * (decls.length () + 1)); - description->decls_num = decls.length (); - description->normal_decls_num = description->decls_num; - description->query_units_num = 0; - for (i = 0; i < description->decls_num; i++) - { - description->decls [i] = decls[i]; - if (description->decls [i]->mode == dm_unit - && DECL_UNIT (description->decls [i])->query_p) - DECL_UNIT (description->decls [i])->query_num - = description->query_units_num++; - } - all_time = create_ticker (); - check_time = create_ticker (); - if (progress_flag) - fprintf (stderr, "Check description..."); - check_all_description (); - if (progress_flag) - fprintf (stderr, "done\n"); - ticker_off (&check_time); - generation_time = create_ticker (); - if (!have_error) - { - transform_insn_regexps (); - check_unit_distributions_to_automata (); - } - if (!have_error) - { - generate (); - check_automata_insn_issues (); - } - if (!have_error) - { - form_important_insn_automata_lists (); - } - ticker_off (&generation_time); -} - -/* The following is top level function to output PHR and to finish - work with pipeline description translator. */ -static void -write_automata (void) -{ - output_time = create_ticker (); - if (progress_flag) - fprintf (stderr, "Forming and outputting automata tables..."); - output_tables (); - if (progress_flag) - { - fprintf (stderr, "done\n"); - fprintf (stderr, "Output functions to work with automata..."); - } - output_chip_definitions (); - output_max_insn_queue_index_def (); - output_internal_min_issue_delay_func (); - output_internal_trans_func (); - /* Cache of insn dfa codes: */ - fprintf (output_file, "\nstatic int *%s;\n", DFA_INSN_CODES_VARIABLE_NAME); - fprintf (output_file, "\nstatic int %s;\n\n", - DFA_INSN_CODES_LENGTH_VARIABLE_NAME); - output_dfa_insn_code_func (); - output_trans_func (); - output_min_issue_delay_func (); - output_internal_dead_lock_func (); - output_dead_lock_func (); - output_size_func (); - output_internal_reset_func (); - output_reset_func (); - output_min_insn_conflict_delay_func (); - output_default_latencies (); - output_internal_insn_latency_func (); - output_insn_latency_func (); - output_internal_maximal_insn_latency_func (); - output_maximal_insn_latency_func (); - output_print_reservation_func (); - /* Output function get_cpu_unit_code. */ - fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME); - output_get_cpu_unit_code_func (); - output_cpu_unit_reservation_p (); - output_insn_has_dfa_reservation_p (); - fprintf (output_file, "\n#endif /* #if %s */\n\n", - CPU_UNITS_QUERY_MACRO_NAME); - output_dfa_clean_insn_cache_func (); - output_dfa_start_func (); - output_dfa_finish_func (); - if (progress_flag) - fprintf (stderr, "done\n"); - if (v_flag) - { - output_description_file = fopen (output_description_file_name, "w"); - if (output_description_file == NULL) - { - perror (output_description_file_name); - exit (FATAL_EXIT_CODE); - } - if (progress_flag) - fprintf (stderr, "Output automata description..."); - output_description (); - output_automaton_descriptions (); - if (progress_flag) - fprintf (stderr, "done\n"); - output_statistics (output_description_file); - } - if (stats_flag) - output_statistics (stderr); - ticker_off (&output_time); - if (time_flag) - output_time_statistics (stderr); - finish_states (); - finish_arcs (); - finish_automata_lists (); - if (time_flag) - { - fprintf (stderr, "Summary:\n"); - fprintf (stderr, " check time "); - print_active_time (stderr, check_time); - fprintf (stderr, ", generation time "); - print_active_time (stderr, generation_time); - fprintf (stderr, ", all time "); - print_active_time (stderr, all_time); - fprintf (stderr, "\n"); - } - /* Finish all work. */ - if (output_description_file != NULL) - { - fflush (output_description_file); - if (ferror (stdout) != 0) - fatal ("Error in writing DFA description file %s: %s", - output_description_file_name, xstrerror (errno)); - fclose (output_description_file); - } - finish_automaton_decl_table (); - finish_insn_decl_table (); - finish_decl_table (); - obstack_free (&irp, NULL); - if (have_error && output_description_file != NULL) - remove (output_description_file_name); -} - -int -main (int argc, const char **argv) -{ - progname = "genautomata"; - - if (!init_rtx_reader_args_cb (argc, argv, parse_automata_opt)) - return (FATAL_EXIT_CODE); - - initiate_automaton_gen (argv); - md_rtx_info info; - while (read_md_rtx (&info)) - switch (GET_CODE (info.def)) - { - case DEFINE_CPU_UNIT: - gen_cpu_unit (&info); - break; - - case DEFINE_QUERY_CPU_UNIT: - gen_query_cpu_unit (&info); - break; - - case DEFINE_BYPASS: - gen_bypass (&info); - break; - - case EXCLUSION_SET: - gen_excl_set (&info); - break; - - case PRESENCE_SET: - gen_presence_set (&info); - break; - - case FINAL_PRESENCE_SET: - gen_final_presence_set (&info); - break; - - case ABSENCE_SET: - gen_absence_set (&info); - break; - - case FINAL_ABSENCE_SET: - gen_final_absence_set (&info); - break; - - case DEFINE_AUTOMATON: - gen_automaton (&info); - break; - - case AUTOMATA_OPTION: - gen_automata_option (&info); - break; - - case DEFINE_RESERVATION: - gen_reserv (&info); - break; - - case DEFINE_INSN_RESERVATION: - gen_insn_reserv (&info); - break; - - default: - break; - } - - if (have_error) - return FATAL_EXIT_CODE; - - if (decls.length () > 0) - { - expand_automata (); - if (!have_error) - { - puts ("/* Generated automatically by the program `genautomata'\n" - " from the machine description file `md'. */\n\n" - "#define IN_TARGET_CODE 1\n" - "#include \"config.h\"\n" - "#include \"system.h\"\n" - "#include \"coretypes.h\"\n" - "#include \"tm.h\"\n" - "#include \"alias.h\"\n" - "#include \"tree.h\"\n" - "#include \"varasm.h\"\n" - "#include \"stor-layout.h\"\n" - "#include \"calls.h\"\n" - "#include \"rtl.h\"\n" - "#include \"memmodel.h\"\n" - "#include \"tm_p.h\"\n" - "#include \"insn-config.h\"\n" - "#include \"recog.h\"\n" - "#include \"regs.h\"\n" - "#include \"output.h\"\n" - "#include \"insn-attr.h\"\n" - "#include \"diagnostic-core.h\"\n" - "#include \"flags.h\"\n" - "#include \"function.h\"\n" - "#include \"emit-rtl.h\"\n"); - /* FIXME: emit-rtl.h can go away once crtl is in rtl.h. */ - - write_automata (); - } - } - else - { - puts ("/* Generated automatically by the program `genautomata'\n" - " from the machine description file `md'. */\n\n" - "/* There is no automaton, but ISO C forbids empty\n" - " translation units, so include a header file with some\n" - " declarations, and its pre-requisite header file. */\n" - "#include \"config.h\"\n" - "#include \"system.h\"\n"); - } - - fflush (stdout); - return (ferror (stdout) != 0 || have_error - ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); -} |